clear previous imports at the beginning of second phase of import resolve

This commit is contained in:
svtk
2012-01-12 16:36:25 +04:00
parent 9902200e5e
commit 5cb15c6e48
9 changed files with 114 additions and 48 deletions
@@ -132,6 +132,11 @@ public class JavaClassDescriptor extends MutableDeclarationDescriptor implements
return null; return null;
} }
@Override
public ClassDescriptor getClassObjectDescriptor() {
return null;
}
@Override @Override
public boolean isClassObjectAValue() { public boolean isClassObjectAValue() {
return false; return false;
@@ -175,13 +180,13 @@ public class JavaClassDescriptor extends MutableDeclarationDescriptor implements
} }
@Override @Override
public ClassDescriptor getInnerClass(String name) { public ClassDescriptor getInnerClassOrObject(String name) {
return null; return null;
} }
@NotNull @NotNull
@Override @Override
public Collection<ClassDescriptor> getInnerClasses() { public Collection<ClassDescriptor> getInnerClassesAndObjects() {
return Collections.emptyList(); return Collections.emptyList();
} }
} }
@@ -51,6 +51,9 @@ public interface ClassDescriptor extends ClassifierDescriptor, MemberDescriptor
@Nullable @Nullable
JetType getClassObjectType(); JetType getClassObjectType();
@Nullable
ClassDescriptor getClassObjectDescriptor();
@NotNull @NotNull
ClassKind getKind(); ClassKind getKind();
@@ -66,8 +69,8 @@ public interface ClassDescriptor extends ClassifierDescriptor, MemberDescriptor
ReceiverDescriptor getImplicitReceiver(); ReceiverDescriptor getImplicitReceiver();
@Nullable @Nullable
ClassDescriptor getInnerClass(String name); ClassDescriptor getInnerClassOrObject(String name);
@NotNull @NotNull
Collection<ClassDescriptor> getInnerClasses(); Collection<ClassDescriptor> getInnerClassesAndObjects();
} }
@@ -115,6 +115,11 @@ public class ClassDescriptorImpl extends DeclarationDescriptorImpl implements Cl
return null; return null;
} }
@Override
public ClassDescriptor getClassObjectDescriptor() {
return null;
}
@NotNull @NotNull
@Override @Override
public ClassKind getKind() { public ClassKind getKind() {
@@ -163,13 +168,13 @@ public class ClassDescriptorImpl extends DeclarationDescriptorImpl implements Cl
} }
@Override @Override
public ClassDescriptor getInnerClass(String name) { public ClassDescriptor getInnerClassOrObject(String name) {
return null; return null;
} }
@NotNull @NotNull
@Override @Override
public Collection<ClassDescriptor> getInnerClasses() { public Collection<ClassDescriptor> getInnerClassesAndObjects() {
return Collections.emptyList(); return Collections.emptyList();
} }
} }
@@ -153,6 +153,11 @@ public class LazySubstitutingClassDescriptor implements ClassDescriptor {
return original.getClassObjectType(); return original.getClassObjectType();
} }
@Override
public ClassDescriptor getClassObjectDescriptor() {
return original.getClassObjectDescriptor();
}
@NotNull @NotNull
@Override @Override
public ClassKind getKind() { public ClassKind getKind() {
@@ -187,13 +192,13 @@ public class LazySubstitutingClassDescriptor implements ClassDescriptor {
} }
@Override @Override
public ClassDescriptor getInnerClass(String name) { public ClassDescriptor getInnerClassOrObject(String name) {
return original.getInnerClass(name); return original.getInnerClassOrObject(name);
} }
@NotNull @NotNull
@Override @Override
public Collection<ClassDescriptor> getInnerClasses() { public Collection<ClassDescriptor> getInnerClassesAndObjects() {
return original.getInnerClasses(); return original.getInnerClassesAndObjects();
} }
} }
@@ -30,7 +30,7 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme
private final Set<FunctionDescriptor> functions = Sets.newHashSet(); private final Set<FunctionDescriptor> functions = Sets.newHashSet();
private List<TypeParameterDescriptor> typeParameters = Lists.newArrayList(); private List<TypeParameterDescriptor> typeParameters = Lists.newArrayList();
private Collection<JetType> supertypes = Lists.newArrayList(); private Collection<JetType> supertypes = Lists.newArrayList();
private Map<String, ClassDescriptor> innerClasses = Maps.newHashMap(); private Map<String, ClassDescriptor> innerClassesAndObjects = Maps.newHashMap();
private Modality modality; private Modality modality;
private Visibility visibility; private Visibility visibility;
@@ -109,6 +109,7 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme
} }
} }
@Override
@Nullable @Nullable
public MutableClassDescriptor getClassObjectDescriptor() { public MutableClassDescriptor getClassObjectDescriptor() {
return classObjectDescriptor; return classObjectDescriptor;
@@ -188,22 +189,25 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme
public void addClassifierDescriptor(@NotNull MutableClassDescriptor classDescriptor) { public void addClassifierDescriptor(@NotNull MutableClassDescriptor classDescriptor) {
scopeForMemberLookup.addClassifierDescriptor(classDescriptor); scopeForMemberLookup.addClassifierDescriptor(classDescriptor);
scopeForMemberResolution.addClassifierDescriptor(classDescriptor); scopeForMemberResolution.addClassifierDescriptor(classDescriptor);
innerClasses.put(classDescriptor.getName(), classDescriptor); innerClassesAndObjects.put(classDescriptor.getName(), classDescriptor);
} }
@Override
@Nullable @Nullable
public ClassDescriptor getInnerClass(String name) { public ClassDescriptor getInnerClassOrObject(String name) {
return innerClasses.get(name); return innerClassesAndObjects.get(name);
} }
@Override
@NotNull @NotNull
public Collection<ClassDescriptor> getInnerClasses() { public Collection<ClassDescriptor> getInnerClassesAndObjects() {
return innerClasses.values(); return innerClassesAndObjects.values();
} }
@Override @Override
public void addObjectDescriptor(@NotNull MutableClassDescriptor objectDescriptor) { public void addObjectDescriptor(@NotNull MutableClassDescriptor objectDescriptor) {
scopeForMemberLookup.addObjectDescriptor(objectDescriptor); scopeForMemberLookup.addObjectDescriptor(objectDescriptor);
innerClassesAndObjects.put(objectDescriptor.getName(), objectDescriptor);
} }
public void addSupertype(@NotNull JetType supertype) { public void addSupertype(@NotNull JetType supertype) {
@@ -38,9 +38,10 @@ public class ImportsResolver {
ImportResolver importResolver = new ImportResolver(context.getTrace(), firstPhase); ImportResolver importResolver = new ImportResolver(context.getTrace(), firstPhase);
for (JetFile file : context.getNamespaceDescriptors().keySet()) { for (JetFile file : context.getNamespaceDescriptors().keySet()) {
WritableScope namespaceScope = context.getNamespaceScopes().get(file); WritableScope namespaceScope = context.getNamespaceScopes().get(file);
if (firstPhase) { if (!firstPhase) {
context.getConfiguration().addDefaultImports(context.getTrace(), namespaceScope); namespaceScope.clearImports();
} }
context.getConfiguration().addDefaultImports(context.getTrace(), namespaceScope);
List<JetImportDirective> importDirectives = file.getImportDirectives(); List<JetImportDirective> importDirectives = file.getImportDirectives();
for (JetImportDirective importDirective : importDirectives) { for (JetImportDirective importDirective : importDirectives) {
@@ -51,6 +52,8 @@ public class ImportsResolver {
public static class ImportResolver { public static class ImportResolver {
private final BindingTrace trace; private final BindingTrace trace;
/* On first phase all classes and objects are imported,
on second phase previous imports are thrown and everything (including functions and properties at namespace level) is imported */
private final boolean firstPhase; private final boolean firstPhase;
public ImportResolver(BindingTrace trace, boolean firstPhase) { public ImportResolver(BindingTrace trace, boolean firstPhase) {
@@ -89,14 +92,26 @@ public class ImportsResolver {
if (descriptor instanceof NamespaceDescriptor) { if (descriptor instanceof NamespaceDescriptor) {
namespaceScope.importScope(((NamespaceDescriptor) descriptor).getMemberScope()); namespaceScope.importScope(((NamespaceDescriptor) descriptor).getMemberScope());
} }
if (descriptor instanceof ClassDescriptor && ((ClassDescriptor) descriptor).getKind() == ClassKind.OBJECT) { if (descriptor instanceof ClassDescriptor) {
Collection<? extends DeclarationDescriptor> innerClasses = getInnerClasses((ClassDescriptor) descriptor, null); ClassDescriptor objectDescriptor;
for (DeclarationDescriptor innerClass : innerClasses) { if (((ClassDescriptor) descriptor).getKind() == ClassKind.OBJECT) {
namespaceScope.importClassifierAlias(innerClass.getName(), (ClassifierDescriptor) innerClass); objectDescriptor = (ClassDescriptor) descriptor;
}
else {
objectDescriptor = ((ClassDescriptor)descriptor).getClassObjectDescriptor();
}
if (objectDescriptor != null) {
Collection<? extends DeclarationDescriptor> innerClassesAndObjects = objectDescriptor.getInnerClassesAndObjects();
for (DeclarationDescriptor innerClassOrObject : innerClassesAndObjects) {
namespaceScope.importClassifierAlias(innerClassOrObject.getName(), (ClassifierDescriptor) innerClassOrObject);
}
} }
} }
continue; continue;
} }
if (descriptor instanceof NamespaceDescriptor) {
namespaceScope.importScope(((NamespaceDescriptor) descriptor).getMemberScope());
}
if (descriptor instanceof VariableDescriptor) { if (descriptor instanceof VariableDescriptor) {
JetType type = ((VariableDescriptor) descriptor).getOutType(); JetType type = ((VariableDescriptor) descriptor).getOutType();
namespaceScope.importScope(type.getMemberScope()); namespaceScope.importScope(type.getMemberScope());
@@ -176,12 +191,19 @@ public class ImportsResolver {
if (!result.isEmpty()) return result; if (!result.isEmpty()) return result;
} }
if (declarationDescriptor instanceof ClassDescriptor) { if (declarationDescriptor instanceof ClassDescriptor) {
result = lookupObjectMembers(selector, (ClassDescriptor) declarationDescriptor); if (firstPhase) {
result = lookupInnerClassesAndObjectsInObject(selector, (ClassDescriptor) declarationDescriptor);
}
else {
result = lookupObjectMembers(selector, (ClassDescriptor) declarationDescriptor);
}
if (!result.isEmpty()) return result; if (!result.isEmpty()) return result;
} }
if (declarationDescriptor instanceof VariableDescriptor) { if (!firstPhase) {
result = lookupVariableMembers(selector, (VariableDescriptor) declarationDescriptor); if (declarationDescriptor instanceof VariableDescriptor) {
if (!result.isEmpty()) return result; result = lookupVariableMembers(selector, (VariableDescriptor) declarationDescriptor);
if (!result.isEmpty()) return result;
}
} }
} }
@@ -227,36 +249,41 @@ public class ImportsResolver {
return false; return false;
} }
@NotNull
private Collection<? extends DeclarationDescriptor> lookupInnerClassesAndObjectsInObject(@NotNull JetSimpleNameExpression objectReference,
@NotNull ClassDescriptor classDescriptor) {
assert firstPhase;
if (classDescriptor.getKind() == ClassKind.OBJECT) {
return getInnerClassesAndObjectsByName(classDescriptor, objectReference);
}
MutableClassDescriptor classObjectDescriptor = ((MutableClassDescriptor) classDescriptor).getClassObjectDescriptor();
assert classObjectDescriptor != null;
return getInnerClassesAndObjectsByName(classObjectDescriptor, objectReference);
}
@NotNull @NotNull
private Collection<? extends DeclarationDescriptor> lookupObjectMembers(@NotNull JetSimpleNameExpression memberReference, private Collection<? extends DeclarationDescriptor> lookupObjectMembers(@NotNull JetSimpleNameExpression memberReference,
@NotNull ClassDescriptor classDescriptor) { @NotNull ClassDescriptor classDescriptor) {
if (classDescriptor.getKind() == ClassKind.OBJECT) { assert !firstPhase;
return getInnerClasses(classDescriptor, memberReference); //on second phase class descriptor is only a descriptor for class object
}
if (firstPhase) return Collections.emptyList();
JetType classObjectType = classDescriptor.getClassObjectType(); JetType classObjectType = classDescriptor.getClassObjectType();
assert classObjectType != null; if (classObjectType == null) return Collections.emptyList();
return lookupDescriptorsForSimpleNameReference(memberReference, classObjectType.getMemberScope(), true); return lookupDescriptorsForSimpleNameReference(memberReference, classObjectType.getMemberScope(), true);
} }
@NotNull @NotNull
private Collection<? extends DeclarationDescriptor> getInnerClasses(@NotNull ClassDescriptor classDescriptor, @Nullable JetSimpleNameExpression memberReference) { private Collection<? extends DeclarationDescriptor> getInnerClassesAndObjectsByName(@NotNull ClassDescriptor classDescriptor, @NotNull JetSimpleNameExpression memberReference) {
if (classDescriptor.getKind() != ClassKind.OBJECT) return Collections.emptyList(); if (classDescriptor.getKind() != ClassKind.OBJECT) return Collections.emptyList();
Collection<? extends DeclarationDescriptor> descriptors; Collection<? extends DeclarationDescriptor> descriptors;
if (memberReference != null) { ClassDescriptor innerClass = classDescriptor.getInnerClassOrObject(memberReference.getReferencedName());
ClassDescriptor innerClass = classDescriptor.getInnerClass(memberReference.getReferencedName()); if (innerClass == null) return Collections.emptyList();
if (innerClass == null) return Collections.emptyList(); descriptors = Collections.<DeclarationDescriptor>singletonList(innerClass);
descriptors = Collections.<DeclarationDescriptor>singletonList(innerClass); storeResolutionResult(descriptors, memberReference, JetScope.EMPTY, true);
storeResolutionResult(descriptors, memberReference, JetScope.EMPTY, true);
}
else {
descriptors = classDescriptor.getInnerClasses();
}
return descriptors; return descriptors;
} }
private Collection<DeclarationDescriptor> lookupVariableMembers(@NotNull JetSimpleNameExpression memberReference, @NotNull VariableDescriptor variableDescriptor) { private Collection<DeclarationDescriptor> lookupVariableMembers(@NotNull JetSimpleNameExpression memberReference, @NotNull VariableDescriptor variableDescriptor) {
if (firstPhase) return Collections.emptyList(); assert !firstPhase;
JetType variableType = variableDescriptor.getReturnType(); JetType variableType = variableDescriptor.getReturnType();
if (variableType == null) return Collections.emptyList(); if (variableType == null) return Collections.emptyList();
@@ -299,12 +326,14 @@ public class ImportsResolver {
ClassifierDescriptor classifierDescriptor = outerScope.getClassifier(referencedName); ClassifierDescriptor classifierDescriptor = outerScope.getClassifier(referencedName);
if (classifierDescriptor != null) descriptors.add(classifierDescriptor); if (classifierDescriptor != null) descriptors.add(classifierDescriptor);
ClassDescriptor objectDescriptor = outerScope.getObjectDescriptor(referencedName); if (firstPhase) {
if (objectDescriptor != null) descriptors.add(objectDescriptor); descriptors.add(outerScope.getObjectDescriptor(referencedName));
}
else {
descriptors.addAll(outerScope.getFunctions(referencedName));
descriptors.addAll(outerScope.getFunctions(referencedName)); descriptors.addAll(outerScope.getProperties(referencedName));
}
descriptors.addAll(outerScope.getProperties(referencedName));
} }
storeResolutionResult(descriptors, referenceExpression, bindingScope, isLastPart); storeResolutionResult(descriptors, referenceExpression, bindingScope, isLastPart);
@@ -55,4 +55,6 @@ public interface WritableScope extends JetScope {
void importFunctionAlias(@NotNull String aliasName, @NotNull FunctionDescriptor functionDescriptor); void importFunctionAlias(@NotNull String aliasName, @NotNull FunctionDescriptor functionDescriptor);
void importVariableAlias(@NotNull String aliasName, @NotNull VariableDescriptor variableDescriptor); void importVariableAlias(@NotNull String aliasName, @NotNull VariableDescriptor variableDescriptor);
void clearImports();
} }
@@ -99,6 +99,13 @@ public class WritableScopeImpl extends WritableScopeWithImports {
super.importVariableAlias(aliasName, variableDescriptor); super.importVariableAlias(aliasName, variableDescriptor);
} }
@Override
public void clearImports() {
checkMayWrite();
super.clearImports();
}
@NotNull @NotNull
@Override @Override
public Collection<DeclarationDescriptor> getAllDescriptors() { public Collection<DeclarationDescriptor> getAllDescriptors() {
@@ -212,6 +212,12 @@ public abstract class WritableScopeWithImports extends JetScopeAdapter implement
getCurrentIndividualImportScope().addVariableAlias(aliasName, variableDescriptor); getCurrentIndividualImportScope().addVariableAlias(aliasName, variableDescriptor);
} }
@Override
public void clearImports() {
currentIndividualImportScope = null;
getImports().clear();
}
@Override @Override
public String toString() { public String toString() {
return getClass().getSimpleName() + "@" + Integer.toHexString(System.identityHashCode(this)) + " " + debugName + " for " + getContainingDeclaration(); return getClass().getSimpleName() + "@" + Integer.toHexString(System.identityHashCode(this)) + " " + debugName + " for " + getContainingDeclaration();