From 10eb5167436ea73a5721216723e49d5c4b3b7679 Mon Sep 17 00:00:00 2001 From: Stepan Koltsov Date: Sat, 14 Jan 2012 04:27:15 +0400 Subject: [PATCH] split MutableClassDescriptor into MutableClassDescriptor base class MutableClassDescriptorLite. Latter will be used to replace JavaClassDescriptor --- .../descriptors/MutableClassDescriptor.java | 258 +------------ .../MutableClassDescriptorLite.java | 339 ++++++++++++++++++ 2 files changed, 357 insertions(+), 240 deletions(-) create mode 100644 compiler/frontend/src/org/jetbrains/jet/lang/descriptors/MutableClassDescriptorLite.java diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/MutableClassDescriptor.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/MutableClassDescriptor.java index 3369c2e24f9..b7913d08efb 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/MutableClassDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/MutableClassDescriptor.java @@ -1,11 +1,9 @@ package org.jetbrains.jet.lang.descriptors; -import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Sets; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.psi.JetParameter; import org.jetbrains.jet.lang.resolve.AbstractScopeAdapter; import org.jetbrains.jet.lang.resolve.BindingContext; @@ -22,34 +20,18 @@ import java.util.*; /** * @author abreslav */ -public class MutableClassDescriptor extends MutableDeclarationDescriptor implements ClassDescriptor, NamespaceLike { - private ConstructorDescriptor primaryConstructor; - private final Set constructors = Sets.newLinkedHashSet(); +public class MutableClassDescriptor extends MutableClassDescriptorLite { private final Set callableMembers = Sets.newHashSet(); private final Set properties = Sets.newHashSet(); private final Set functions = Sets.newHashSet(); - private List typeParameters; - private Collection supertypes = Lists.newArrayList(); - private Map innerClassesAndObjects = Maps.newHashMap(); - private Modality modality; - private Visibility visibility; - private TypeConstructor typeConstructor; private final WritableScope scopeForMemberResolution; - private final WritableScope scopeForMemberLookup; // This scope contains type parameters but does not contain inner classes private final WritableScope scopeForSupertypeResolution; private final WritableScope scopeForInitializers; //contains members + primary constructor value parameters + map for backing fields - private MutableClassDescriptor classObjectDescriptor; - private JetType classObjectType; - private JetType defaultType; - private final ClassKind kind; - private JetType superclassType; - private ClassReceiver implicitReceiver; - public MutableClassDescriptor(@NotNull BindingTrace trace, @NotNull DeclarationDescriptor containingDeclaration, @NotNull JetScope outerScope, ClassKind kind) { - super(containingDeclaration); + super(containingDeclaration, kind, new TraceBasedRedeclarationHandler(trace)); if (containingDeclaration instanceof ClassDescriptor || containingDeclaration instanceof NamespaceLike @@ -61,23 +43,20 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme } TraceBasedRedeclarationHandler redeclarationHandler = new TraceBasedRedeclarationHandler(trace); - this.scopeForMemberLookup = new WritableScopeImpl(JetScope.EMPTY, this, redeclarationHandler).setDebugName("MemberLookup").changeLockLevel(WritableScope.LockLevel.BOTH); this.scopeForSupertypeResolution = new WritableScopeImpl(outerScope, this, redeclarationHandler).setDebugName("SupertypeResolution").changeLockLevel(WritableScope.LockLevel.BOTH); this.scopeForMemberResolution = new WritableScopeImpl(scopeForSupertypeResolution, this, redeclarationHandler).setDebugName("MemberResolution").changeLockLevel(WritableScope.LockLevel.BOTH); this.scopeForInitializers = new WritableScopeImpl(scopeForMemberResolution, this, redeclarationHandler).setDebugName("Initializers").changeLockLevel(WritableScope.LockLevel.BOTH); - this.kind = kind; } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + @Override - public ClassObjectStatus setClassObjectDescriptor(@NotNull MutableClassDescriptor classObjectDescriptor) { - if (this.classObjectDescriptor != null) return ClassObjectStatus.DUPLICATE; - if (!isStatic(this.getContainingDeclaration())) { - return ClassObjectStatus.NOT_ALLOWED; + public ClassObjectStatus setClassObjectDescriptor(@NotNull final MutableClassDescriptor classObjectDescriptor) { + ClassObjectStatus r = super.setClassObjectDescriptor(classObjectDescriptor); + if (r != ClassObjectStatus.OK) { + return r; } - assert classObjectDescriptor.getKind() == ClassKind.OBJECT; - this.classObjectDescriptor = classObjectDescriptor; // Members of the class object are accessible from the class // The scope must be lazy, because classObjectDescriptor may not by fully built yet @@ -85,54 +64,23 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme @NotNull @Override protected JetScope getWorkerScope() { - return MutableClassDescriptor.this.classObjectDescriptor.getDefaultType().getMemberScope(); + return classObjectDescriptor.getDefaultType().getMemberScope(); } @NotNull @Override public ReceiverDescriptor getImplicitReceiver() { - return MutableClassDescriptor.this.classObjectDescriptor.getImplicitReceiver(); + return classObjectDescriptor.getImplicitReceiver(); } } ); + return ClassObjectStatus.OK; } - private static boolean isStatic(DeclarationDescriptor declarationDescriptor) { - if (declarationDescriptor instanceof NamespaceDescriptor) { - return true; - } else if (declarationDescriptor instanceof ClassDescriptor) { - ClassDescriptor classDescriptor = (ClassDescriptor) declarationDescriptor; - return classDescriptor.getKind() == ClassKind.OBJECT || classDescriptor.getKind() == ClassKind.ENUM_CLASS; - } else { - return false; - } - } - @Override - @Nullable - public MutableClassDescriptor getClassObjectDescriptor() { - return classObjectDescriptor; - } - - public void setPrimaryConstructor(@NotNull ConstructorDescriptor constructorDescriptor, BindingTrace trace) { - assert this.primaryConstructor == null : "Primary constructor assigned twice " + this; - this.primaryConstructor = constructorDescriptor; - addConstructor(constructorDescriptor, trace); - } - - @Override - @Nullable - public ConstructorDescriptor getUnsubstitutedPrimaryConstructor() { - return primaryConstructor; - } - - public void addConstructor(@NotNull ConstructorDescriptor constructorDescriptor, BindingTrace trace) { - assert constructorDescriptor.getContainingDeclaration() == this; - constructors.add(constructorDescriptor); - if (defaultType != null) { - ((ConstructorDescriptorImpl) constructorDescriptor).setReturnType(getDefaultType()); - } + public void addConstructor(@NotNull ConstructorDescriptor constructorDescriptor, @NotNull BindingTrace trace) { + super.addConstructor(constructorDescriptor, trace); if (constructorDescriptor.isPrimary()) { for (ValueParameterDescriptor valueParameterDescriptor : constructorDescriptor.getValueParameters()) { JetParameter parameter = (JetParameter) trace.getBindingContext().get(BindingContext.DESCRIPTOR_TO_DECLARATION, valueParameterDescriptor); @@ -146,17 +94,17 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme @Override public void addPropertyDescriptor(@NotNull PropertyDescriptor propertyDescriptor) { + super.addPropertyDescriptor(propertyDescriptor); properties.add(propertyDescriptor); callableMembers.add(propertyDescriptor); - scopeForMemberLookup.addPropertyDescriptor(propertyDescriptor); scopeForMemberResolution.addPropertyDescriptor(propertyDescriptor); } @Override public void addFunctionDescriptor(@NotNull NamedFunctionDescriptor functionDescriptor) { + super.addFunctionDescriptor(functionDescriptor); functions.add(functionDescriptor); callableMembers.add(functionDescriptor); - scopeForMemberLookup.addFunctionDescriptor(functionDescriptor); scopeForMemberResolution.addFunctionDescriptor(functionDescriptor); } @@ -175,54 +123,15 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme return callableMembers; } - @Override - public NamespaceDescriptorImpl getNamespace(String name) { - throw new UnsupportedOperationException("Classes do not define namespaces"); - } - - @Override - public void addNamespace(@NotNull NamespaceDescriptor namespaceDescriptor) { - throw new UnsupportedOperationException("Classes do not define namespaces"); - } - @Override public void addClassifierDescriptor(@NotNull MutableClassDescriptor classDescriptor) { - scopeForMemberLookup.addClassifierDescriptor(classDescriptor); + super.addClassifierDescriptor(classDescriptor); scopeForMemberResolution.addClassifierDescriptor(classDescriptor); - innerClassesAndObjects.put(classDescriptor.getName(), classDescriptor); - } - - @Override - @Nullable - public ClassDescriptor getInnerClassOrObject(String name) { - return innerClassesAndObjects.get(name); - } - - @Override - @NotNull - public Collection getInnerClassesAndObjects() { - return innerClassesAndObjects.values(); - } - - @Override - public void addObjectDescriptor(@NotNull MutableClassDescriptor objectDescriptor) { - scopeForMemberLookup.addObjectDescriptor(objectDescriptor); - innerClassesAndObjects.put(objectDescriptor.getName(), objectDescriptor); - } - - public void addSupertype(@NotNull JetType supertype) { - if (!ErrorUtils.isErrorType(supertype)) { - supertypes.add(supertype); - } } public void setTypeParameterDescriptors(List typeParameters) { - if (this.typeParameters != null) { - throw new IllegalStateException(); - } - this.typeParameters = new ArrayList(); + super.setTypeParameterDescriptors(typeParameters); for (TypeParameterDescriptor typeParameterDescriptor : typeParameters) { - this.typeParameters.add(typeParameterDescriptor); scopeForSupertypeResolution.addTypeParameterDescriptor(typeParameterDescriptor); } scopeForSupertypeResolution.changeLockLevel(WritableScope.LockLevel.READING); @@ -236,57 +145,10 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme scopeForMemberResolution.addLabeledDeclaration(this); } - @NotNull @Override - public TypeConstructor getTypeConstructor() { - return typeConstructor; - } - public void createTypeConstructor() { - assert typeConstructor == null : typeConstructor; - this.typeConstructor = new TypeConstructorImpl( - this, - Collections.emptyList(), // TODO : pass annotations from the class? - !modality.isOverridable(), - getName(), - typeParameters, - supertypes); + super.createTypeConstructor(); scopeForMemberResolution.setImplicitReceiver(new ClassReceiver(this)); - for (FunctionDescriptor functionDescriptor : constructors) { - ((ConstructorDescriptorImpl) functionDescriptor).setReturnType(getDefaultType()); - } - } - - public void addSupertypesToScopeForMemberLookup() { - for (JetType supertype : supertypes) { - scopeForMemberLookup.importScope(supertype.getMemberScope()); - } - } - - @NotNull - @Override - public JetScope getMemberScope(List typeArguments) { - assert typeArguments.size() == typeConstructor.getParameters().size(); - if (typeArguments.isEmpty()) return scopeForMemberLookup; - - List typeParameters = getTypeConstructor().getParameters(); - Map substitutionContext = TypeUtils.buildSubstitutionContext(typeParameters, typeArguments); - return new SubstitutingScope(scopeForMemberLookup, TypeSubstitutor.create(substitutionContext)); - } - - @NotNull - @Override - public JetType getDefaultType() { - if (defaultType == null) { - defaultType = TypeUtils.makeUnsubstitutedType(this, scopeForMemberLookup); - } - return defaultType; - } - - @NotNull - @Override - public Set getConstructors() { - return constructors; } @NotNull @@ -294,11 +156,6 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme return scopeForSupertypeResolution; } - @NotNull - public JetScope getScopeForMemberLookup() { - return scopeForMemberLookup; - } - @NotNull public JetScope getScopeForMemberResolution() { return scopeForMemberResolution; @@ -309,90 +166,11 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme return scopeForInitializers; } - @NotNull - @Override - public ClassDescriptor substitute(TypeSubstitutor substitutor) { - if (substitutor.isEmpty()) { - return this; - } - return new LazySubstitutingClassDescriptor(this, substitutor); - } - - @Override - public JetType getClassObjectType() { - if (classObjectType == null && classObjectDescriptor != null) { - classObjectType = classObjectDescriptor.getDefaultType(); - } - return classObjectType; - } - - @Override - public boolean isClassObjectAValue() { - return true; - } - - @Override - public R accept(DeclarationDescriptorVisitor visitor, D data) { - return visitor.visitClassDescriptor(this, data); - } - - @Override - public boolean hasConstructors() { - return !constructors.isEmpty(); - } - - @NotNull - @Override - public ClassKind getKind() { - return kind; - } - - public void setModality(Modality modality) { - this.modality = modality; - } - - public void setVisibility(Visibility visibility) { - this.visibility = visibility; - } - - @Override - @NotNull - public Modality getModality() { - return modality; - } - - @NotNull - @Override - public Visibility getVisibility() { - return visibility; - } - - @Override - public String toString() { - return DescriptorRenderer.TEXT.render(this) + "[" + getClass().getCanonicalName() + "@" + System.identityHashCode(this) + "]"; - } - - public Collection getSupertypes() { - return supertypes; - } - - @NotNull - @Override - public ReceiverDescriptor getImplicitReceiver() { - if (implicitReceiver == null) { - implicitReceiver = new ClassReceiver(this); - } - return implicitReceiver; - } - public void lockScopes() { + super.lockScopes(); scopeForSupertypeResolution.changeLockLevel(WritableScope.LockLevel.READING); - scopeForMemberLookup.changeLockLevel(WritableScope.LockLevel.READING); scopeForMemberResolution.changeLockLevel(WritableScope.LockLevel.READING); scopeForInitializers.changeLockLevel(WritableScope.LockLevel.READING); - if (classObjectDescriptor != null) { - classObjectDescriptor.lockScopes(); - } } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/MutableClassDescriptorLite.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/MutableClassDescriptorLite.java new file mode 100644 index 00000000000..0c5f437f43e --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/MutableClassDescriptorLite.java @@ -0,0 +1,339 @@ +package org.jetbrains.jet.lang.descriptors; + +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; +import org.jetbrains.jet.lang.psi.JetParameter; +import org.jetbrains.jet.lang.resolve.AbstractScopeAdapter; +import org.jetbrains.jet.lang.resolve.BindingContext; +import org.jetbrains.jet.lang.resolve.BindingTrace; +import org.jetbrains.jet.lang.resolve.scopes.JetScope; +import org.jetbrains.jet.lang.resolve.scopes.RedeclarationHandler; +import org.jetbrains.jet.lang.resolve.scopes.SubstitutingScope; +import org.jetbrains.jet.lang.resolve.scopes.WritableScope; +import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl; +import org.jetbrains.jet.lang.resolve.scopes.receivers.ClassReceiver; +import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; +import org.jetbrains.jet.lang.types.ErrorUtils; +import org.jetbrains.jet.lang.types.JetType; +import org.jetbrains.jet.lang.types.TypeConstructor; +import org.jetbrains.jet.lang.types.TypeConstructorImpl; +import org.jetbrains.jet.lang.types.TypeProjection; +import org.jetbrains.jet.lang.types.TypeSubstitutor; +import org.jetbrains.jet.lang.types.TypeUtils; +import org.jetbrains.jet.resolve.DescriptorRenderer; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * @author Stepan Koltsov + */ +public class MutableClassDescriptorLite extends MutableDeclarationDescriptor implements ClassDescriptor, NamespaceLike { + private ConstructorDescriptor primaryConstructor; + private final Set constructors = Sets.newLinkedHashSet(); + + private Map innerClassesAndObjects = Maps.newHashMap(); + + private List typeParameters; + private Collection supertypes = Lists.newArrayList(); + + private TypeConstructor typeConstructor; + + private Modality modality; + private Visibility visibility; + + private MutableClassDescriptor classObjectDescriptor; + private JetType classObjectType; + private JetType defaultType; + private final ClassKind kind; + + private final WritableScope scopeForMemberLookup; + + private ClassReceiver implicitReceiver; + + public MutableClassDescriptorLite(DeclarationDescriptor containingDeclaration, ClassKind kind, RedeclarationHandler redeclarationHandler) { + super(containingDeclaration); + + this.scopeForMemberLookup = new WritableScopeImpl(JetScope.EMPTY, this, redeclarationHandler).setDebugName("MemberLookup").changeLockLevel(WritableScope.LockLevel.BOTH); + + this.kind = kind; + } + + + private static boolean isStatic(DeclarationDescriptor declarationDescriptor) { + if (declarationDescriptor instanceof NamespaceDescriptor) { + return true; + } else if (declarationDescriptor instanceof ClassDescriptor) { + ClassDescriptor classDescriptor = (ClassDescriptor) declarationDescriptor; + return classDescriptor.getKind() == ClassKind.OBJECT || classDescriptor.getKind() == ClassKind.ENUM_CLASS; + } else { + return false; + } + } + + + + @Override + public ClassObjectStatus setClassObjectDescriptor(@NotNull MutableClassDescriptor classObjectDescriptor) { + if (this.classObjectDescriptor != null) return ClassObjectStatus.DUPLICATE; + if (!isStatic(this.getContainingDeclaration())) { + return ClassObjectStatus.NOT_ALLOWED; + } + assert classObjectDescriptor.getKind() == ClassKind.OBJECT; + this.classObjectDescriptor = classObjectDescriptor; + + return ClassObjectStatus.OK; + } + + + + + + @NotNull + @Override + public TypeConstructor getTypeConstructor() { + return typeConstructor; + } + + public void createTypeConstructor() { + assert typeConstructor == null : typeConstructor; + this.typeConstructor = new TypeConstructorImpl( + this, + Collections.emptyList(), // TODO : pass annotations from the class? + !modality.isOverridable(), + getName(), + typeParameters, + supertypes); + for (FunctionDescriptor functionDescriptor : constructors) { + ((ConstructorDescriptorImpl) functionDescriptor).setReturnType(getDefaultType()); + } + } + + public void addSupertypesToScopeForMemberLookup() { + for (JetType supertype : supertypes) { + scopeForMemberLookup.importScope(supertype.getMemberScope()); + } + } + + @NotNull + @Override + public JetScope getMemberScope(List typeArguments) { + assert typeArguments.size() == typeConstructor.getParameters().size(); + if (typeArguments.isEmpty()) return scopeForMemberLookup; + + List typeParameters = getTypeConstructor().getParameters(); + Map substitutionContext = TypeUtils.buildSubstitutionContext(typeParameters, typeArguments); + return new SubstitutingScope(scopeForMemberLookup, TypeSubstitutor.create(substitutionContext)); + } + + + @NotNull + @Override + public Set getConstructors() { + return constructors; + } + + @NotNull + public JetScope getScopeForMemberLookup() { + return scopeForMemberLookup; + } + + @NotNull + @Override + public ClassDescriptor substitute(TypeSubstitutor substitutor) { + if (substitutor.isEmpty()) { + return this; + } + return new LazySubstitutingClassDescriptor(this, substitutor); + } + + @Override + public JetType getClassObjectType() { + if (classObjectType == null && classObjectDescriptor != null) { + classObjectType = classObjectDescriptor.getDefaultType(); + } + return classObjectType; + } + + @Override + public boolean isClassObjectAValue() { + return true; + } + + + @Override + public boolean hasConstructors() { + return !constructors.isEmpty(); + } + + @NotNull + @Override + public ClassKind getKind() { + return kind; + } + + public void setModality(Modality modality) { + this.modality = modality; + } + + public void setVisibility(Visibility visibility) { + this.visibility = visibility; + } + + @Override + @NotNull + public Modality getModality() { + return modality; + } + + @NotNull + @Override + public Visibility getVisibility() { + return visibility; + } + + public Collection getSupertypes() { + return supertypes; + } + + + + + + + + + + public void setPrimaryConstructor(@NotNull ConstructorDescriptor constructorDescriptor, BindingTrace trace) { + assert this.primaryConstructor == null : "Primary constructor assigned twice " + this; + this.primaryConstructor = constructorDescriptor; + addConstructor(constructorDescriptor, trace); + } + + @Override + @Nullable + public ConstructorDescriptor getUnsubstitutedPrimaryConstructor() { + return primaryConstructor; + } + + public void addConstructor(@NotNull ConstructorDescriptor constructorDescriptor, @Nullable BindingTrace trace) { + assert constructorDescriptor.getContainingDeclaration() == this; + constructors.add(constructorDescriptor); + if (defaultType != null) { + ((ConstructorDescriptorImpl) constructorDescriptor).setReturnType(getDefaultType()); + } + } + + @NotNull + @Override + public JetType getDefaultType() { + if (defaultType == null) { + defaultType = TypeUtils.makeUnsubstitutedType(this, scopeForMemberLookup); + } + return defaultType; + } + + @Override + @Nullable + public MutableClassDescriptor getClassObjectDescriptor() { + return classObjectDescriptor; + } + + @Override + public void addPropertyDescriptor(@NotNull PropertyDescriptor propertyDescriptor) { + scopeForMemberLookup.addPropertyDescriptor(propertyDescriptor); + } + + @Override + public void addFunctionDescriptor(@NotNull NamedFunctionDescriptor functionDescriptor) { + scopeForMemberLookup.addFunctionDescriptor(functionDescriptor); + } + + @Override + public void addNamespace(@NotNull NamespaceDescriptor namespaceDescriptor) { + throw new UnsupportedOperationException("Classes do not define namespaces"); + } + + @Override + public NamespaceDescriptorImpl getNamespace(String name) { + throw new UnsupportedOperationException("Classes do not define namespaces"); + } + + @Override + public void addClassifierDescriptor(@NotNull MutableClassDescriptor classDescriptor) { + scopeForMemberLookup.addClassifierDescriptor(classDescriptor); + innerClassesAndObjects.put(classDescriptor.getName(), classDescriptor); + } + + @Override + @Nullable + public ClassDescriptor getInnerClassOrObject(String name) { + return innerClassesAndObjects.get(name); + } + + @Override + @NotNull + public Collection getInnerClassesAndObjects() { + return innerClassesAndObjects.values(); + } + + @Override + public void addObjectDescriptor(@NotNull MutableClassDescriptor objectDescriptor) { + scopeForMemberLookup.addObjectDescriptor(objectDescriptor); + innerClassesAndObjects.put(objectDescriptor.getName(), objectDescriptor); + } + + public void addSupertype(@NotNull JetType supertype) { + if (!ErrorUtils.isErrorType(supertype)) { + supertypes.add(supertype); + } + } + + public void setTypeParameterDescriptors(List typeParameters) { + if (this.typeParameters != null) { + throw new IllegalStateException(); + } + this.typeParameters = new ArrayList(); + for (TypeParameterDescriptor typeParameterDescriptor : typeParameters) { + this.typeParameters.add(typeParameterDescriptor); + } + } + + + public void lockScopes() { + scopeForMemberLookup.changeLockLevel(WritableScope.LockLevel.READING); + if (classObjectDescriptor != null) { + classObjectDescriptor.lockScopes(); + } + } + + + @NotNull + @Override + public ReceiverDescriptor getImplicitReceiver() { + if (implicitReceiver == null) { + implicitReceiver = new ClassReceiver(this); + } + return implicitReceiver; + } + + + @Override + public String toString() { + return DescriptorRenderer.TEXT.render(this) + "[" + getClass().getCanonicalName() + "@" + System.identityHashCode(this) + "]"; + } + + @Override + public R accept(DeclarationDescriptorVisitor visitor, D data) { + return visitor.visitClassDescriptor(this, data); + } + +}