@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 List<MutableClassDescriptorLite> topologicallySortClassesAndObjects( @NotNull TopDownAnalysisContext c) { // A topsort is needed only for better diagnostics: // edges that get removed to disconnect loops are more reasonable in this case //noinspection unchecked return DFS.topologicalOrder( (Iterable) c.getClasses().values(), new DFS.Neighbors<MutableClassDescriptorLite>() { @NotNull @Override public Iterable<MutableClassDescriptorLite> getNeighbors( MutableClassDescriptorLite current) { List<MutableClassDescriptorLite> result = Lists.newArrayList(); for (JetType supertype : current.getSupertypes()) { DeclarationDescriptor declarationDescriptor = supertype.getConstructor().getDeclarationDescriptor(); if (declarationDescriptor instanceof MutableClassDescriptorLite) { MutableClassDescriptorLite classDescriptor = (MutableClassDescriptorLite) declarationDescriptor; result.add(classDescriptor); } } return result; } }); }
private void resolveAnonymousInitializers() { for (Map.Entry<JetClass, MutableClassDescriptor> entry : context.getClasses().entrySet()) { resolveAnonymousInitializers(entry.getKey(), entry.getValue()); } for (Map.Entry<JetObjectDeclaration, MutableClassDescriptor> entry : context.getObjects().entrySet()) { resolveAnonymousInitializers(entry.getKey(), entry.getValue()); } }
private void resolveDelegationSpecifierLists() { // TODO : Make sure the same thing is not initialized twice for (Map.Entry<JetClass, MutableClassDescriptor> entry : context.getClasses().entrySet()) { resolveDelegationSpecifierList(entry.getKey(), entry.getValue()); } for (Map.Entry<JetObjectDeclaration, MutableClassDescriptor> entry : context.getObjects().entrySet()) { resolveDelegationSpecifierList(entry.getKey(), entry.getValue()); } }
private void resolvePropertyDeclarationBodies() { // Member properties Set<JetProperty> processed = Sets.newHashSet(); for (Map.Entry<JetClass, MutableClassDescriptor> entry : context.getClasses().entrySet()) { JetClass jetClass = entry.getKey(); if (!context.completeAnalysisNeeded(jetClass)) continue; MutableClassDescriptor classDescriptor = entry.getValue(); for (JetProperty property : jetClass.getProperties()) { final PropertyDescriptor propertyDescriptor = this.context.getProperties().get(property); assert propertyDescriptor != null; computeDeferredType(propertyDescriptor.getReturnType()); JetExpression initializer = property.getInitializer(); if (initializer != null) { ConstructorDescriptor primaryConstructor = classDescriptor.getUnsubstitutedPrimaryConstructor(); if (primaryConstructor != null) { JetScope declaringScopeForPropertyInitializer = this.context.getDeclaringScopes().get(property); resolvePropertyInitializer( property, propertyDescriptor, initializer, declaringScopeForPropertyInitializer); } } resolvePropertyAccessors(property, propertyDescriptor); processed.add(property); } } // Top-level properties & properties of objects for (Map.Entry<JetProperty, PropertyDescriptor> entry : this.context.getProperties().entrySet()) { JetProperty property = entry.getKey(); if (!context.completeAnalysisNeeded(property)) continue; if (processed.contains(property)) continue; final PropertyDescriptor propertyDescriptor = entry.getValue(); computeDeferredType(propertyDescriptor.getReturnType()); JetScope declaringScope = this.context.getDeclaringScopes().get(property); JetExpression initializer = property.getInitializer(); if (initializer != null) { resolvePropertyInitializer(property, propertyDescriptor, initializer, declaringScope); } resolvePropertyAccessors(property, propertyDescriptor); } }
private void resolveTypesInClassHeaders(@NotNull TopDownAnalysisContext c) { for (Map.Entry<JetClassOrObject, ClassDescriptorWithResolutionScopes> entry : c.getClasses().entrySet()) { JetClassOrObject classOrObject = entry.getKey(); if (classOrObject instanceof JetClass) { ClassDescriptorWithResolutionScopes descriptor = entry.getValue(); //noinspection unchecked descriptorResolver.resolveGenericBounds( (JetClass) classOrObject, descriptor, descriptor.getScopeForClassHeaderResolution(), (List) descriptor.getTypeConstructor().getParameters(), trace); } } for (Map.Entry<JetClassOrObject, ClassDescriptorWithResolutionScopes> entry : c.getClasses().entrySet()) { descriptorResolver.resolveSupertypesForMutableClassDescriptor( entry.getKey(), (MutableClassDescriptor) entry.getValue(), trace); } }
private void resolvePrimaryConstructorParameters() { for (Map.Entry<JetClass, MutableClassDescriptor> entry : context.getClasses().entrySet()) { JetClass klass = entry.getKey(); MutableClassDescriptor classDescriptor = entry.getValue(); ConstructorDescriptor unsubstitutedPrimaryConstructor = classDescriptor.getUnsubstitutedPrimaryConstructor(); if (unsubstitutedPrimaryConstructor != null) { checkDefaultParameterValues( klass.getPrimaryConstructorParameters(), unsubstitutedPrimaryConstructor.getValueParameters(), classDescriptor.getScopeForInitializers()); } } }
@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; }
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(); } } }