split MutableClassDescriptor

into MutableClassDescriptor base class MutableClassDescriptorLite.
Latter will be used to replace JavaClassDescriptor
This commit is contained in:
Stepan Koltsov
2012-01-14 04:27:15 +04:00
parent 2fe9344225
commit 10eb516743
2 changed files with 357 additions and 240 deletions
@@ -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<ConstructorDescriptor> constructors = Sets.newLinkedHashSet();
public class MutableClassDescriptor extends MutableClassDescriptorLite {
private final Set<CallableMemberDescriptor> callableMembers = Sets.newHashSet();
private final Set<PropertyDescriptor> properties = Sets.newHashSet();
private final Set<NamedFunctionDescriptor> functions = Sets.newHashSet();
private List<TypeParameterDescriptor> typeParameters;
private Collection<JetType> supertypes = Lists.newArrayList();
private Map<String, ClassDescriptor> 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<ClassDescriptor> 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<TypeParameterDescriptor> typeParameters) {
if (this.typeParameters != null) {
throw new IllegalStateException();
}
this.typeParameters = new ArrayList<TypeParameterDescriptor>();
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.<AnnotationDescriptor>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<TypeProjection> typeArguments) {
assert typeArguments.size() == typeConstructor.getParameters().size();
if (typeArguments.isEmpty()) return scopeForMemberLookup;
List<TypeParameterDescriptor> typeParameters = getTypeConstructor().getParameters();
Map<TypeConstructor, TypeProjection> 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<ConstructorDescriptor> 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, D> R accept(DeclarationDescriptorVisitor<R, D> 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<JetType> 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();
}
}
}
@@ -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<ConstructorDescriptor> constructors = Sets.newLinkedHashSet();
private Map<String, ClassDescriptor> innerClassesAndObjects = Maps.newHashMap();
private List<TypeParameterDescriptor> typeParameters;
private Collection<JetType> 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.<AnnotationDescriptor>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<TypeProjection> typeArguments) {
assert typeArguments.size() == typeConstructor.getParameters().size();
if (typeArguments.isEmpty()) return scopeForMemberLookup;
List<TypeParameterDescriptor> typeParameters = getTypeConstructor().getParameters();
Map<TypeConstructor, TypeProjection> substitutionContext = TypeUtils.buildSubstitutionContext(typeParameters, typeArguments);
return new SubstitutingScope(scopeForMemberLookup, TypeSubstitutor.create(substitutionContext));
}
@NotNull
@Override
public Set<ConstructorDescriptor> 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<JetType> 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<ClassDescriptor> 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<TypeParameterDescriptor> typeParameters) {
if (this.typeParameters != null) {
throw new IllegalStateException();
}
this.typeParameters = new ArrayList<TypeParameterDescriptor>();
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, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
return visitor.visitClassDescriptor(this, data);
}
}