private void processPrimaryConstructor( @NotNull TopDownAnalysisContext c, @NotNull MutableClassDescriptor classDescriptor, @NotNull JetClass klass) { // TODO : not all the parameters are real properties JetScope memberScope = classDescriptor.getScopeForClassHeaderResolution(); ConstructorDescriptor constructorDescriptor = descriptorResolver.resolvePrimaryConstructorDescriptor( memberScope, classDescriptor, klass, trace); if (constructorDescriptor != null) { List<ValueParameterDescriptor> valueParameterDescriptors = constructorDescriptor.getValueParameters(); List<JetParameter> primaryConstructorParameters = klass.getPrimaryConstructorParameters(); assert valueParameterDescriptors.size() == primaryConstructorParameters.size(); List<ValueParameterDescriptor> notProperties = new ArrayList<ValueParameterDescriptor>(); for (ValueParameterDescriptor valueParameterDescriptor : valueParameterDescriptors) { JetParameter parameter = primaryConstructorParameters.get(valueParameterDescriptor.getIndex()); if (parameter.getValOrVarNode() != null) { PropertyDescriptor propertyDescriptor = descriptorResolver.resolvePrimaryConstructorParameterToAProperty( classDescriptor, valueParameterDescriptor, memberScope, parameter, trace); classDescriptor.getBuilder().addPropertyDescriptor(propertyDescriptor); c.getPrimaryConstructorParameterProperties().put(parameter, propertyDescriptor); } else { notProperties.add(valueParameterDescriptor); } } if (classDescriptor.getKind() != ClassKind.TRAIT) { classDescriptor.setPrimaryConstructor(constructorDescriptor); classDescriptor.addConstructorParametersToInitializersScope(notProperties); } } }
@NotNull private MutableClassDescriptor createClassDescriptorForClass( @NotNull JetClass klass, @NotNull DeclarationDescriptor containingDeclaration) { ClassKind kind = getClassKind(klass); // Kind check is needed in order to not consider enums as inner in any case // (otherwise it would be impossible to create a class object in the enum) boolean isInner = kind == ClassKind.CLASS && klass.isInner(); MutableClassDescriptor mutableClassDescriptor = new MutableClassDescriptor( containingDeclaration, outerScope, kind, isInner, JetPsiUtil.safeName(klass.getName())); c.getClasses().put(klass, mutableClassDescriptor); trace.record( FQNAME_TO_CLASS_DESCRIPTOR, JetPsiUtil.getUnsafeFQName(klass), mutableClassDescriptor); createClassObjectForEnumClass(mutableClassDescriptor); JetScope classScope = mutableClassDescriptor.getScopeForMemberDeclarationResolution(); prepareForDeferredCall(classScope, mutableClassDescriptor, klass); return mutableClassDescriptor; }
private void resolveFunctionAndPropertyHeaders(@NotNull TopDownAnalysisContext c) { for (Map.Entry<JetFile, WritableScope> entry : c.getFileScopes().entrySet()) { JetFile file = entry.getKey(); WritableScope fileScope = entry.getValue(); PackageLikeBuilder packageBuilder = c.getPackageFragments().get(file).getBuilder(); resolveFunctionAndPropertyHeaders( c, file.getDeclarations(), fileScope, fileScope, fileScope, packageBuilder); } for (Map.Entry<JetClassOrObject, ClassDescriptorWithResolutionScopes> entry : c.getDeclaredClasses().entrySet()) { JetClassOrObject classOrObject = entry.getKey(); MutableClassDescriptor classDescriptor = (MutableClassDescriptor) entry.getValue(); resolveFunctionAndPropertyHeaders( c, classOrObject.getDeclarations(), classDescriptor.getScopeForMemberDeclarationResolution(), classDescriptor.getScopeForInitializerResolution(), classDescriptor.getScopeForMemberDeclarationResolution(), classDescriptor.getBuilder()); } // TODO : Extensions }
@Override public void visitEnumEntry(@NotNull JetEnumEntry declaration) { MutableClassDescriptor descriptor = createClassDescriptorForSingleton( declaration, JetPsiUtil.safeName(declaration.getName()), ClassKind.ENUM_ENTRY); owner.addClassifierDescriptor(descriptor); descriptor.getBuilder().setClassObjectDescriptor(createSyntheticClassObject(descriptor)); }
private void resolveAnnotationStubsOnClassesAndConstructors(@NotNull TopDownAnalysisContext c) { for (Map.Entry<JetClassOrObject, ClassDescriptorWithResolutionScopes> entry : c.getDeclaredClasses().entrySet()) { JetModifierList modifierList = entry.getKey().getModifierList(); if (modifierList != null) { MutableClassDescriptor descriptor = (MutableClassDescriptor) entry.getValue(); descriptor.addAnnotations( annotationResolver.resolveAnnotationsWithoutArguments( descriptor.getScopeForClassHeaderResolution(), modifierList, trace)); } } }
private void createClassObjectForEnumClass( @NotNull MutableClassDescriptor mutableClassDescriptor) { if (mutableClassDescriptor.getKind() == ClassKind.ENUM_CLASS) { MutableClassDescriptor classObject = createSyntheticClassObject(mutableClassDescriptor); mutableClassDescriptor.getBuilder().setClassObjectDescriptor(classObject); classObject .getBuilder() .addFunctionDescriptor( DescriptorResolver.createEnumClassObjectValuesMethod(classObject, trace)); classObject .getBuilder() .addFunctionDescriptor( DescriptorResolver.createEnumClassObjectValueOfMethod(classObject, trace)); } }
@NotNull private MutableClassDescriptor createClassDescriptorForSingleton( @NotNull JetClassOrObject declaration, @NotNull Name name, @NotNull ClassKind kind) { MutableClassDescriptor descriptor = new MutableClassDescriptor(owner.getOwnerForChildren(), outerScope, kind, false, name); prepareForDeferredCall( descriptor.getScopeForMemberDeclarationResolution(), descriptor, declaration); createPrimaryConstructorForObject(declaration, descriptor); trace.record(BindingContext.CLASS, declaration, descriptor); c.getClasses().put(declaration, descriptor); return descriptor; }
@NotNull private MutableClassDescriptor createSyntheticClassObject( @NotNull ClassDescriptor classDescriptor) { MutableClassDescriptor classObject = new MutableClassDescriptor( classDescriptor, outerScope, ClassKind.CLASS_OBJECT, false, getClassObjectName(classDescriptor.getName())); classObject.setModality(Modality.FINAL); classObject.setVisibility(DescriptorUtils.getSyntheticClassObjectVisibility()); classObject.setTypeParameterDescriptors(Collections.<TypeParameterDescriptor>emptyList()); createPrimaryConstructorForObject(null, classObject); return classObject; }
@Override public void visitObjectDeclaration(@NotNull JetObjectDeclaration declaration) { if (declaration.isObjectLiteral()) { createClassDescriptorForSingleton( declaration, SpecialNames.NO_NAME_PROVIDED, ClassKind.CLASS); return; } MutableClassDescriptor descriptor = createClassDescriptorForSingleton( declaration, JetPsiUtil.safeName(declaration.getName()), ClassKind.OBJECT); owner.addClassifierDescriptor(descriptor); trace.record(FQNAME_TO_CLASS_DESCRIPTOR, JetPsiUtil.getUnsafeFQName(declaration), descriptor); descriptor.getBuilder().setClassObjectDescriptor(createSyntheticClassObject(descriptor)); }
public void lockScopes() { getScopeForMemberLookupAsWritableScope().changeLockLevel(WritableScope.LockLevel.READING); if (classObjectDescriptor != null) { classObjectDescriptor.lockScopes(); } scopeForSupertypeResolution.changeLockLevel(WritableScope.LockLevel.READING); scopeForMemberResolution.changeLockLevel(WritableScope.LockLevel.READING); getWritableScopeForInitializers().changeLockLevel(WritableScope.LockLevel.READING); }
@NotNull private ConstructorDescriptorImpl createPrimaryConstructorForObject( @Nullable PsiElement object, @NotNull MutableClassDescriptor mutableClassDescriptor) { ConstructorDescriptorImpl constructorDescriptor = DescriptorResolver.createAndRecordPrimaryConstructorForObject( object, mutableClassDescriptor, trace); mutableClassDescriptor.setPrimaryConstructor(constructorDescriptor); return constructorDescriptor; }
private void createCopyFunction( @NotNull MutableClassDescriptor classDescriptor, @NotNull ConstructorDescriptor constructorDescriptor) { SimpleFunctionDescriptor functionDescriptor = DescriptorResolver.createCopyFunctionDescriptor( constructorDescriptor.getValueParameters(), classDescriptor, trace); classDescriptor.getBuilder().addFunctionDescriptor(functionDescriptor); }
@NotNull private static ClassDescriptor createClass( @NotNull PackageFragmentDescriptor packageFragment, @NotNull String name, @NotNull String... typeParameters) { MutableClassDescriptor descriptor = new MutableClassDescriptor( packageFragment, packageFragment.getMemberScope(), ClassKind.CLASS, false, Name.identifier(name)); List<TypeParameterDescriptor> typeParameterDescriptors = new ArrayList<TypeParameterDescriptor>(typeParameters.length); for (int i = 0; i < typeParameters.length; i++) { String[] s = typeParameters[i].split(" "); Variance variance = Variance.valueOf(s[0].toUpperCase() + "_VARIANCE"); String typeParameterName = s[1]; TypeParameterDescriptorImpl typeParameter = TypeParameterDescriptorImpl.createForFurtherModification( descriptor, Annotations.EMPTY, false, variance, Name.identifier(typeParameterName), i); typeParameter.setInitialized(); typeParameterDescriptors.add(typeParameter); } descriptor.setModality(Modality.FINAL); descriptor.setVisibility(Visibilities.PUBLIC); descriptor.setTypeParameterDescriptors(typeParameterDescriptors); descriptor.createTypeConstructor(); return descriptor; }
@Override protected Set<CallableMemberDescriptor> collectMethodsToGenerate( MutableClassDescriptor descriptor) { final Set<CallableMemberDescriptor> superMethods = OverrideResolver.collectSuperMethods(descriptor).keySet(); for (CallableMemberDescriptor member : descriptor.getDeclaredCallableMembers()) { superMethods.removeAll(member.getOverriddenDescriptors()); } Set<CallableMemberDescriptor> result = new HashSet<CallableMemberDescriptor>(); for (CallableMemberDescriptor superMethod : superMethods) { if (superMethod.getModality().isOverridable()) { result.add(superMethod); } } return result; }
private void createTypeConstructors(@NotNull TopDownAnalysisContext c) { for (Map.Entry<JetClassOrObject, ClassDescriptorWithResolutionScopes> entry : c.getClasses().entrySet()) { JetClassOrObject classOrObject = entry.getKey(); MutableClassDescriptor descriptor = (MutableClassDescriptor) entry.getValue(); if (classOrObject instanceof JetClass) { descriptorResolver.resolveMutableClassDescriptor( (JetClass) classOrObject, descriptor, trace); } else if (classOrObject instanceof JetObjectDeclaration) { descriptor.setModality(Modality.FINAL); descriptor.setVisibility( resolveVisibilityFromModifiers(classOrObject, getDefaultClassVisibility(descriptor))); descriptor.setTypeParameterDescriptors(Collections.<TypeParameterDescriptor>emptyList()); } descriptor.createTypeConstructor(); ClassKind kind = descriptor.getKind(); if (kind == ClassKind.ENUM_ENTRY || kind == ClassKind.OBJECT || kind == ClassKind.ENUM_CLASS) { MutableClassDescriptorLite classObject = descriptor.getClassObjectDescriptor(); assert classObject != null : "Enum entries and named objects should have class objects: " + classOrObject.getText(); JetType supertype; if (kind == ClassKind.ENUM_CLASS) { supertype = KotlinBuiltIns.getInstance().getAnyType(); } else { // This is a clever hack: each enum entry and object declaration (i.e. singleton) has a // synthetic class object. // We make this class object inherit from the singleton here, thus allowing to use the // singleton's class object where // the instance of the singleton is applicable. Effectively all members of the singleton // would be present in its class // object as fake overrides, so you can access them via standard class object notation: // ObjectName.memberName() supertype = descriptor.getDefaultType(); } classObject.setSupertypes(Collections.singleton(supertype)); classObject.createTypeConstructor(); } } }
private void createComponentFunctions( @NotNull MutableClassDescriptor classDescriptor, @NotNull ConstructorDescriptor constructorDescriptor) { int parameterIndex = 0; for (ValueParameterDescriptor parameter : constructorDescriptor.getValueParameters()) { if (!parameter.getType().isError()) { PropertyDescriptor property = trace.get(BindingContext.VALUE_PARAMETER_AS_PROPERTY, parameter); if (property != null) { ++parameterIndex; SimpleFunctionDescriptor functionDescriptor = DescriptorResolver.createComponentFunctionDescriptor( parameterIndex, property, parameter, classDescriptor, trace); classDescriptor.getBuilder().addFunctionDescriptor(functionDescriptor); } } } }