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;
}
@Override
public ClassDescriptor getClassObjectDescriptor() {
return null;
}
@Override
public boolean isClassObjectAValue() {
return false;
@@ -175,13 +180,13 @@ public class JavaClassDescriptor extends MutableDeclarationDescriptor implements
}
@Override
public ClassDescriptor getInnerClass(String name) {
public ClassDescriptor getInnerClassOrObject(String name) {
return null;
}
@NotNull
@Override
public Collection<ClassDescriptor> getInnerClasses() {
public Collection<ClassDescriptor> getInnerClassesAndObjects() {
return Collections.emptyList();
}
}
@@ -51,6 +51,9 @@ public interface ClassDescriptor extends ClassifierDescriptor, MemberDescriptor
@Nullable
JetType getClassObjectType();
@Nullable
ClassDescriptor getClassObjectDescriptor();
@NotNull
ClassKind getKind();
@@ -66,8 +69,8 @@ public interface ClassDescriptor extends ClassifierDescriptor, MemberDescriptor
ReceiverDescriptor getImplicitReceiver();
@Nullable
ClassDescriptor getInnerClass(String name);
ClassDescriptor getInnerClassOrObject(String name);
@NotNull
Collection<ClassDescriptor> getInnerClasses();
Collection<ClassDescriptor> getInnerClassesAndObjects();
}
@@ -115,6 +115,11 @@ public class ClassDescriptorImpl extends DeclarationDescriptorImpl implements Cl
return null;
}
@Override
public ClassDescriptor getClassObjectDescriptor() {
return null;
}
@NotNull
@Override
public ClassKind getKind() {
@@ -163,13 +168,13 @@ public class ClassDescriptorImpl extends DeclarationDescriptorImpl implements Cl
}
@Override
public ClassDescriptor getInnerClass(String name) {
public ClassDescriptor getInnerClassOrObject(String name) {
return null;
}
@NotNull
@Override
public Collection<ClassDescriptor> getInnerClasses() {
public Collection<ClassDescriptor> getInnerClassesAndObjects() {
return Collections.emptyList();
}
}
@@ -153,6 +153,11 @@ public class LazySubstitutingClassDescriptor implements ClassDescriptor {
return original.getClassObjectType();
}
@Override
public ClassDescriptor getClassObjectDescriptor() {
return original.getClassObjectDescriptor();
}
@NotNull
@Override
public ClassKind getKind() {
@@ -187,13 +192,13 @@ public class LazySubstitutingClassDescriptor implements ClassDescriptor {
}
@Override
public ClassDescriptor getInnerClass(String name) {
return original.getInnerClass(name);
public ClassDescriptor getInnerClassOrObject(String name) {
return original.getInnerClassOrObject(name);
}
@NotNull
@Override
public Collection<ClassDescriptor> getInnerClasses() {
return original.getInnerClasses();
public Collection<ClassDescriptor> getInnerClassesAndObjects() {
return original.getInnerClassesAndObjects();
}
}
@@ -30,7 +30,7 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme
private final Set<FunctionDescriptor> functions = Sets.newHashSet();
private List<TypeParameterDescriptor> typeParameters = 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 Visibility visibility;
@@ -109,6 +109,7 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme
}
}
@Override
@Nullable
public MutableClassDescriptor getClassObjectDescriptor() {
return classObjectDescriptor;
@@ -188,22 +189,25 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme
public void addClassifierDescriptor(@NotNull MutableClassDescriptor classDescriptor) {
scopeForMemberLookup.addClassifierDescriptor(classDescriptor);
scopeForMemberResolution.addClassifierDescriptor(classDescriptor);
innerClasses.put(classDescriptor.getName(), classDescriptor);
innerClassesAndObjects.put(classDescriptor.getName(), classDescriptor);
}
@Override
@Nullable
public ClassDescriptor getInnerClass(String name) {
return innerClasses.get(name);
public ClassDescriptor getInnerClassOrObject(String name) {
return innerClassesAndObjects.get(name);
}
@Override
@NotNull
public Collection<ClassDescriptor> getInnerClasses() {
return innerClasses.values();
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) {
@@ -38,9 +38,10 @@ public class ImportsResolver {
ImportResolver importResolver = new ImportResolver(context.getTrace(), firstPhase);
for (JetFile file : context.getNamespaceDescriptors().keySet()) {
WritableScope namespaceScope = context.getNamespaceScopes().get(file);
if (firstPhase) {
context.getConfiguration().addDefaultImports(context.getTrace(), namespaceScope);
if (!firstPhase) {
namespaceScope.clearImports();
}
context.getConfiguration().addDefaultImports(context.getTrace(), namespaceScope);
List<JetImportDirective> importDirectives = file.getImportDirectives();
for (JetImportDirective importDirective : importDirectives) {
@@ -51,6 +52,8 @@ public class ImportsResolver {
public static class ImportResolver {
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;
public ImportResolver(BindingTrace trace, boolean firstPhase) {
@@ -89,14 +92,26 @@ public class ImportsResolver {
if (descriptor instanceof NamespaceDescriptor) {
namespaceScope.importScope(((NamespaceDescriptor) descriptor).getMemberScope());
}
if (descriptor instanceof ClassDescriptor && ((ClassDescriptor) descriptor).getKind() == ClassKind.OBJECT) {
Collection<? extends DeclarationDescriptor> innerClasses = getInnerClasses((ClassDescriptor) descriptor, null);
for (DeclarationDescriptor innerClass : innerClasses) {
namespaceScope.importClassifierAlias(innerClass.getName(), (ClassifierDescriptor) innerClass);
if (descriptor instanceof ClassDescriptor) {
ClassDescriptor objectDescriptor;
if (((ClassDescriptor) descriptor).getKind() == ClassKind.OBJECT) {
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;
}
if (descriptor instanceof NamespaceDescriptor) {
namespaceScope.importScope(((NamespaceDescriptor) descriptor).getMemberScope());
}
if (descriptor instanceof VariableDescriptor) {
JetType type = ((VariableDescriptor) descriptor).getOutType();
namespaceScope.importScope(type.getMemberScope());
@@ -176,12 +191,19 @@ public class ImportsResolver {
if (!result.isEmpty()) return result;
}
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 (declarationDescriptor instanceof VariableDescriptor) {
result = lookupVariableMembers(selector, (VariableDescriptor) declarationDescriptor);
if (!result.isEmpty()) return result;
if (!firstPhase) {
if (declarationDescriptor instanceof VariableDescriptor) {
result = lookupVariableMembers(selector, (VariableDescriptor) declarationDescriptor);
if (!result.isEmpty()) return result;
}
}
}
@@ -227,36 +249,41 @@ public class ImportsResolver {
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
private Collection<? extends DeclarationDescriptor> lookupObjectMembers(@NotNull JetSimpleNameExpression memberReference,
@NotNull ClassDescriptor classDescriptor) {
if (classDescriptor.getKind() == ClassKind.OBJECT) {
return getInnerClasses(classDescriptor, memberReference);
}
if (firstPhase) return Collections.emptyList();
assert !firstPhase;
//on second phase class descriptor is only a descriptor for class object
JetType classObjectType = classDescriptor.getClassObjectType();
assert classObjectType != null;
if (classObjectType == null) return Collections.emptyList();
return lookupDescriptorsForSimpleNameReference(memberReference, classObjectType.getMemberScope(), true);
}
@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();
Collection<? extends DeclarationDescriptor> descriptors;
if (memberReference != null) {
ClassDescriptor innerClass = classDescriptor.getInnerClass(memberReference.getReferencedName());
if (innerClass == null) return Collections.emptyList();
descriptors = Collections.<DeclarationDescriptor>singletonList(innerClass);
storeResolutionResult(descriptors, memberReference, JetScope.EMPTY, true);
}
else {
descriptors = classDescriptor.getInnerClasses();
}
ClassDescriptor innerClass = classDescriptor.getInnerClassOrObject(memberReference.getReferencedName());
if (innerClass == null) return Collections.emptyList();
descriptors = Collections.<DeclarationDescriptor>singletonList(innerClass);
storeResolutionResult(descriptors, memberReference, JetScope.EMPTY, true);
return descriptors;
}
private Collection<DeclarationDescriptor> lookupVariableMembers(@NotNull JetSimpleNameExpression memberReference, @NotNull VariableDescriptor variableDescriptor) {
if (firstPhase) return Collections.emptyList();
assert !firstPhase;
JetType variableType = variableDescriptor.getReturnType();
if (variableType == null) return Collections.emptyList();
@@ -299,12 +326,14 @@ public class ImportsResolver {
ClassifierDescriptor classifierDescriptor = outerScope.getClassifier(referencedName);
if (classifierDescriptor != null) descriptors.add(classifierDescriptor);
ClassDescriptor objectDescriptor = outerScope.getObjectDescriptor(referencedName);
if (objectDescriptor != null) descriptors.add(objectDescriptor);
if (firstPhase) {
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);
@@ -55,4 +55,6 @@ public interface WritableScope extends JetScope {
void importFunctionAlias(@NotNull String aliasName, @NotNull FunctionDescriptor functionDescriptor);
void importVariableAlias(@NotNull String aliasName, @NotNull VariableDescriptor variableDescriptor);
void clearImports();
}
@@ -99,6 +99,13 @@ public class WritableScopeImpl extends WritableScopeWithImports {
super.importVariableAlias(aliasName, variableDescriptor);
}
@Override
public void clearImports() {
checkMayWrite();
super.clearImports();
}
@NotNull
@Override
public Collection<DeclarationDescriptor> getAllDescriptors() {
@@ -212,6 +212,12 @@ public abstract class WritableScopeWithImports extends JetScopeAdapter implement
getCurrentIndividualImportScope().addVariableAlias(aliasName, variableDescriptor);
}
@Override
public void clearImports() {
currentIndividualImportScope = null;
getImports().clear();
}
@Override
public String toString() {
return getClass().getSimpleName() + "@" + Integer.toHexString(System.identityHashCode(this)) + " " + debugName + " for " + getContainingDeclaration();