From 3e8e8bd3c85c3e399dbbbf0edd5ec1f23a72405e Mon Sep 17 00:00:00 2001 From: svtk Date: Wed, 11 Jan 2012 14:19:01 +0400 Subject: [PATCH] import from objects before properties resolve --- .../resolve/java/JavaClassDescriptor.java | 15 +++- .../resolve/java/JavaClassMembersScope.java | 5 ++ .../lang/resolve/java/JavaPackageScope.java | 5 ++ .../jet/lang/descriptors/ClassDescriptor.java | 7 ++ .../ClassDescriptorBoundToReceiver.java | 11 +++ .../lang/descriptors/ClassDescriptorImpl.java | 16 +++- .../LazySubstitutingClassDescriptor.java | 11 +++ .../descriptors/MutableClassDescriptor.java | 18 +++++ .../descriptors/NamespaceDescriptorImpl.java | 5 ++ .../jet/lang/descriptors/NamespaceLike.java | 2 + .../lang/resolve/AbstractScopeAdapter.java | 5 ++ .../jet/lang/resolve/AnalyzingUtils.java | 5 ++ .../jet/lang/resolve/DescriptorUtils.java | 5 ++ .../jet/lang/resolve/ImportsResolver.java | 75 ++++++++++++++----- .../jet/lang/resolve/TopDownAnalyzer.java | 5 ++ .../lang/resolve/TypeHierarchyResolver.java | 1 + .../jet/lang/resolve/scopes/ChainedScope.java | 9 +++ .../jet/lang/resolve/scopes/JetScope.java | 3 + .../jet/lang/resolve/scopes/JetScopeImpl.java | 5 ++ .../resolve/scopes/ScopeBoundToReceiver.java | 5 ++ .../resolve/scopes/SubstitutingScope.java | 5 ++ .../lang/resolve/scopes/WritableScope.java | 2 + .../resolve/scopes/WritableScopeImpl.java | 23 ++++++ .../scopes/WritableScopeWithImports.java | 13 ++++ .../resolve/scopes/WriteThroughScope.java | 20 +++++ .../jetbrains/jet/lang/types/ErrorUtils.java | 5 ++ .../diagnostics/tests/scopes/kt900.jet | 35 +++++++++ 27 files changed, 289 insertions(+), 27 deletions(-) diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaClassDescriptor.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaClassDescriptor.java index 3ffed2fa4ff..74929c74e66 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaClassDescriptor.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaClassDescriptor.java @@ -9,9 +9,7 @@ import org.jetbrains.jet.lang.resolve.scopes.receivers.ClassReceiver; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; import org.jetbrains.jet.lang.types.*; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; /** * @author abreslav @@ -175,4 +173,15 @@ public class JavaClassDescriptor extends MutableDeclarationDescriptor implements } return implicitReceiver; } + + @Override + public ClassDescriptor getInnerClass(String name) { + return null; + } + + @NotNull + @Override + public Collection getInnerClasses() { + return Collections.emptyList(); + } } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaClassMembersScope.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaClassMembersScope.java index b50c6ec59b0..7eb48c22982 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaClassMembersScope.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaClassMembersScope.java @@ -59,6 +59,11 @@ public class JavaClassMembersScope implements JetScope { return classifierDescriptor; } + @Override + public ClassDescriptor getObjectDescriptor(@NotNull String name) { + return null; + } + @NotNull @Override public Collection getAllDescriptors() { diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaPackageScope.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaPackageScope.java index 5f63f119133..31bb50ad3db 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaPackageScope.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaPackageScope.java @@ -34,6 +34,11 @@ public class JavaPackageScope extends JetScopeImpl { return semanticServices.getDescriptorResolver().resolveClass(getQualifiedName(name)); } + @Override + public ClassDescriptor getObjectDescriptor(@NotNull String name) { + return null; + } + @Override public NamespaceDescriptor getNamespace(@NotNull String name) { return semanticServices.getDescriptorResolver().resolveNamespace(getQualifiedName(name)); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ClassDescriptor.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ClassDescriptor.java index 7a72b505b27..aacd0fdf967 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ClassDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ClassDescriptor.java @@ -8,6 +8,7 @@ import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.TypeProjection; import org.jetbrains.jet.lang.types.TypeSubstitutor; +import java.util.Collection; import java.util.List; import java.util.Set; @@ -63,4 +64,10 @@ public interface ClassDescriptor extends ClassifierDescriptor, MemberDescriptor @NotNull ReceiverDescriptor getImplicitReceiver(); + + @Nullable + ClassDescriptor getInnerClass(String name); + + @NotNull + Collection getInnerClasses(); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ClassDescriptorBoundToReceiver.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ClassDescriptorBoundToReceiver.java index 569b0eb237c..9cbac03a92d 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ClassDescriptorBoundToReceiver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ClassDescriptorBoundToReceiver.java @@ -148,4 +148,15 @@ public class ClassDescriptorBoundToReceiver implements ClassDescriptor { public String getName() { return classDescriptor.getName(); } + + @Override + public ClassDescriptor getInnerClass(String name) { + return classDescriptor.getInnerClass(name); + } + + @NotNull + @Override + public Collection getInnerClasses() { + return classDescriptor.getInnerClasses(); + } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ClassDescriptorImpl.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ClassDescriptorImpl.java index 059215e2f9f..bac666c373e 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ClassDescriptorImpl.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ClassDescriptorImpl.java @@ -9,10 +9,7 @@ import org.jetbrains.jet.lang.resolve.scopes.receivers.ClassReceiver; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; import org.jetbrains.jet.lang.types.*; -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; /** * @author abreslav @@ -164,4 +161,15 @@ public class ClassDescriptorImpl extends DeclarationDescriptorImpl implements Cl } return implicitReceiver; } + + @Override + public ClassDescriptor getInnerClass(String name) { + return null; + } + + @NotNull + @Override + public Collection getInnerClasses() { + return Collections.emptyList(); + } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/LazySubstitutingClassDescriptor.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/LazySubstitutingClassDescriptor.java index 84d1946f13b..8009c6b2835 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/LazySubstitutingClassDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/LazySubstitutingClassDescriptor.java @@ -185,4 +185,15 @@ public class LazySubstitutingClassDescriptor implements ClassDescriptor { public void acceptVoid(DeclarationDescriptorVisitor visitor) { throw new UnsupportedOperationException(); // TODO } + + @Override + public ClassDescriptor getInnerClass(String name) { + return original.getInnerClass(name); + } + + @NotNull + @Override + public Collection getInnerClasses() { + return original.getInnerClasses(); + } } 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 1fad260a6cc..5fb10e4db9a 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/MutableClassDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/MutableClassDescriptor.java @@ -1,6 +1,7 @@ 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; @@ -29,6 +30,7 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme private final Set functions = Sets.newHashSet(); private List typeParameters = Lists.newArrayList(); private Collection supertypes = Lists.newArrayList(); + private Map innerClasses = Maps.newHashMap(); private Modality modality; private Visibility visibility; @@ -186,6 +188,22 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme public void addClassifierDescriptor(@NotNull MutableClassDescriptor classDescriptor) { scopeForMemberLookup.addClassifierDescriptor(classDescriptor); scopeForMemberResolution.addClassifierDescriptor(classDescriptor); + innerClasses.put(classDescriptor.getName(), classDescriptor); + } + + @Nullable + public ClassDescriptor getInnerClass(String name) { + return innerClasses.get(name); + } + + @NotNull + public Collection getInnerClasses() { + return innerClasses.values(); + } + + @Override + public void addObjectDescriptor(@NotNull MutableClassDescriptor objectDescriptor) { + scopeForMemberLookup.addObjectDescriptor(objectDescriptor); } public void addSupertype(@NotNull JetType supertype) { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/NamespaceDescriptorImpl.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/NamespaceDescriptorImpl.java index 7c940b853c8..1ebe3a7e1b7 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/NamespaceDescriptorImpl.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/NamespaceDescriptorImpl.java @@ -43,6 +43,11 @@ public class NamespaceDescriptorImpl extends AbstractNamespaceDescriptorImpl imp memberScope.addClassifierDescriptor(classDescriptor); } + @Override + public void addObjectDescriptor(@NotNull MutableClassDescriptor objectDescriptor) { + memberScope.addObjectDescriptor(objectDescriptor); + } + @Override public void addFunctionDescriptor(@NotNull FunctionDescriptor functionDescriptor) { memberScope.addFunctionDescriptor(functionDescriptor); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/NamespaceLike.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/NamespaceLike.java index 88ee358d1a1..9ccf55baba4 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/NamespaceLike.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/NamespaceLike.java @@ -65,6 +65,8 @@ public interface NamespaceLike extends DeclarationDescriptor { void addClassifierDescriptor(@NotNull MutableClassDescriptor classDescriptor); + void addObjectDescriptor(@NotNull MutableClassDescriptor objectDescriptor); + void addFunctionDescriptor(@NotNull FunctionDescriptor functionDescriptor); void addPropertyDescriptor(@NotNull PropertyDescriptor propertyDescriptor); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AbstractScopeAdapter.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AbstractScopeAdapter.java index 131a6a62933..de263c901a1 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AbstractScopeAdapter.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AbstractScopeAdapter.java @@ -45,6 +45,11 @@ public abstract class AbstractScopeAdapter implements JetScope { return getWorkerScope().getClassifier(name); } + @Override + public ClassDescriptor getObjectDescriptor(@NotNull String name) { + return getWorkerScope().getObjectDescriptor(name); + } + @NotNull @Override public Set getProperties(@NotNull String name) { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnalyzingUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnalyzingUtils.java index 57691b696fa..6ed05150f5f 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnalyzingUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnalyzingUtils.java @@ -116,6 +116,11 @@ public class AnalyzingUtils { scope.addClassifierDescriptor(classDescriptor); } + @Override + public void addObjectDescriptor(@NotNull MutableClassDescriptor objectDescriptor) { + + } + @Override public void addFunctionDescriptor(@NotNull FunctionDescriptor functionDescriptor) { scope.addFunctionDescriptor(functionDescriptor); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java index 32070cd8d11..24f8d807e70 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java @@ -240,4 +240,9 @@ public class DescriptorUtils { PsiElement element = bindingTrace.get(BindingContext.DESCRIPTOR_TO_DECLARATION, descriptor); return element instanceof JetObjectDeclarationName; } + + public static boolean isObjectDescriptor(@NotNull ClassDescriptor descriptor, BindingTrace bindingTrace) { + PsiElement element = bindingTrace.get(BindingContext.DESCRIPTOR_TO_DECLARATION, descriptor); + return element instanceof JetObjectDeclaration; + } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ImportsResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ImportsResolver.java index 3eca5209219..eeb091c419e 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ImportsResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ImportsResolver.java @@ -93,6 +93,12 @@ public class ImportsResolver { if (descriptor instanceof NamespaceDescriptor) { namespaceScope.importScope(((NamespaceDescriptor) descriptor).getMemberScope()); } + if (descriptor instanceof ClassDescriptor && DescriptorUtils.isObjectDescriptor((ClassDescriptor) descriptor, trace)) { + Collection innerClasses = getInnerClasses((ClassDescriptor) descriptor, null); + for (DeclarationDescriptor innerClass : innerClasses) { + namespaceScope.importClassifierAlias(innerClass.getName(), (ClassifierDescriptor) innerClass); + } + } continue; } if (descriptor instanceof VariableDescriptor) { @@ -164,15 +170,19 @@ public class ImportsResolver { if (lastReference == null || !canImportMembersFrom(declarationDescriptors, lastReference)) { return Collections.emptyList(); } + Collection result; for (DeclarationDescriptor declarationDescriptor : declarationDescriptors) { if (declarationDescriptor instanceof NamespaceDescriptor) { - return lookupDescriptorsForSimpleNameReference(selector, ((NamespaceDescriptor) declarationDescriptor).getMemberScope()); + result = lookupDescriptorsForSimpleNameReference(selector, ((NamespaceDescriptor) declarationDescriptor).getMemberScope()); + if (!result.isEmpty()) return result; } if (declarationDescriptor instanceof ClassDescriptor) { - return lookupObjectMembers(selector, (ClassDescriptor) declarationDescriptor); + result = lookupObjectMembers(selector, (ClassDescriptor) declarationDescriptor); + if (!result.isEmpty()) return result; } if (declarationDescriptor instanceof VariableDescriptor) { - return lookupVariableMembers(selector, (VariableDescriptor) declarationDescriptor); + result = lookupVariableMembers(selector, (VariableDescriptor) declarationDescriptor); + if (!result.isEmpty()) return result; } } @@ -219,6 +229,9 @@ public class ImportsResolver { @NotNull private Collection lookupObjectMembers(@NotNull JetSimpleNameExpression memberReference, @NotNull ClassDescriptor classDescriptor) { + if (DescriptorUtils.isObjectDescriptor(classDescriptor, trace)) { + return getInnerClasses(classDescriptor, memberReference); + } if (firstPhase) return Collections.emptyList(); JetType classObjectType = classDescriptor.getClassObjectType(); assert classObjectType != null; @@ -226,6 +239,22 @@ public class ImportsResolver { return addBoundToReceiver(members, classDescriptor); } + @NotNull + private Collection getInnerClasses(@NotNull ClassDescriptor classDescriptor, @Nullable JetSimpleNameExpression memberReference) { + if (!DescriptorUtils.isObjectDescriptor(classDescriptor, trace)) return Collections.emptyList(); + Collection descriptors; + if (memberReference != null) { + ClassDescriptor innerClass = classDescriptor.getInnerClass(memberReference.getReferencedName()); + if (innerClass == null) return Collections.emptyList(); + descriptors = Collections.singletonList(innerClass); + recordReference(descriptors, memberReference, JetScope.EMPTY); + } + else { + descriptors = classDescriptor.getInnerClasses(); + } + return addBoundToReceiver(descriptors, classDescriptor); + } + private Collection lookupVariableMembers(@NotNull JetSimpleNameExpression memberReference, @NotNull VariableDescriptor variableDescriptor) { if (firstPhase) return Collections.emptyList(); @@ -236,7 +265,7 @@ public class ImportsResolver { } @NotNull - public static Collection addBoundToReceiver(@NotNull Collection descriptors, @NotNull final DeclarationDescriptor receiver) { + public static Collection addBoundToReceiver(@NotNull Collection descriptors, @NotNull final DeclarationDescriptor receiver) { return Collections2.transform(descriptors, DescriptorUtils.getAddBoundToReceiverFunction(receiver)); } @@ -252,27 +281,33 @@ 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); + descriptors.addAll(outerScope.getFunctions(referencedName)); descriptors.addAll(outerScope.getProperties(referencedName)); } - if (!firstPhase) { - if (descriptors.size() == 1) { - trace.record(BindingContext.REFERENCE_TARGET, referenceExpression, descriptors.get(0)); - } - else if (descriptors.size() > 1) { - trace.record(BindingContext.AMBIGUOUS_REFERENCE_TARGET, referenceExpression, descriptors); - } - else { - trace.report(UNRESOLVED_REFERENCE.on(referenceExpression)); - } - - // If it's not an ambiguous case - store resolution scope - if (descriptors.size() <= 1 && outerScope != JetScope.EMPTY) { - trace.record(BindingContext.RESOLUTION_SCOPE, referenceExpression, outerScope); - } - } + recordReference(descriptors, referenceExpression, outerScope); return descriptors; } + + private void recordReference(Collection descriptors, JetSimpleNameExpression referenceExpression, JetScope outerScope) { + if (firstPhase) return; + if (descriptors.size() == 1) { + trace.record(BindingContext.REFERENCE_TARGET, referenceExpression, descriptors.iterator().next()); + } + else if (descriptors.size() > 1) { + trace.record(BindingContext.AMBIGUOUS_REFERENCE_TARGET, referenceExpression, descriptors); + } + else { + trace.report(UNRESOLVED_REFERENCE.on(referenceExpression)); + } + + // If it's not an ambiguous case - store resolution scope + if (descriptors.size() <= 1 && outerScope != JetScope.EMPTY) { + trace.record(BindingContext.RESOLUTION_SCOPE, referenceExpression, outerScope); + } + } } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TopDownAnalyzer.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TopDownAnalyzer.java index 934452b32dd..6cf99701e37 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TopDownAnalyzer.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TopDownAnalyzer.java @@ -133,6 +133,11 @@ public class TopDownAnalyzer { } + @Override + public void addObjectDescriptor(@NotNull MutableClassDescriptor objectDescriptor) { + + } + @Override public void addFunctionDescriptor(@NotNull FunctionDescriptor functionDescriptor) { throw new UnsupportedOperationException(); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java index 471a790fecb..4c797de0114 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java @@ -140,6 +140,7 @@ public class TypeHierarchyResolver { }; visitClassOrObject(declaration, (Map) context.getObjects(), mutableClassDescriptor); createPrimaryConstructorForObject((JetDeclaration) declaration, mutableClassDescriptor); + owner.addObjectDescriptor(mutableClassDescriptor); context.getTrace().record(BindingContext.CLASS, declaration, mutableClassDescriptor); return mutableClassDescriptor; } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/ChainedScope.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/ChainedScope.java index 43a5b6d4d28..12239be35d9 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/ChainedScope.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/ChainedScope.java @@ -32,6 +32,15 @@ public class ChainedScope implements JetScope { return null; } + @Override + public ClassDescriptor getObjectDescriptor(@NotNull String name) { + for (JetScope scope : scopeChain) { + ClassDescriptor objectDescriptor = scope.getObjectDescriptor(name); + if (objectDescriptor != null) return objectDescriptor; + } + return null; + } + @Override public NamespaceDescriptor getNamespace(@NotNull String name) { for (JetScope jetScope : scopeChain) { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/JetScope.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/JetScope.java index 22ffa67c092..f4e7e5f5b20 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/JetScope.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/JetScope.java @@ -28,6 +28,9 @@ public interface JetScope { @Nullable ClassifierDescriptor getClassifier(@NotNull String name); + + @Nullable + ClassDescriptor getObjectDescriptor(@NotNull String name); @Nullable NamespaceDescriptor getNamespace(@NotNull String name); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/JetScopeImpl.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/JetScopeImpl.java index 27959d5fc32..e92cb3d81fd 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/JetScopeImpl.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/JetScopeImpl.java @@ -18,6 +18,11 @@ public abstract class JetScopeImpl implements JetScope { return null; } + @Override + public ClassDescriptor getObjectDescriptor(@NotNull String name) { + return null; + } + @NotNull @Override public Set getProperties(@NotNull String name) { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/ScopeBoundToReceiver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/ScopeBoundToReceiver.java index c6008d732a7..4cd36279629 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/ScopeBoundToReceiver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/ScopeBoundToReceiver.java @@ -85,6 +85,11 @@ public class ScopeBoundToReceiver implements JetScope { return result; } + @Override + public ClassDescriptor getObjectDescriptor(@NotNull String name) { + return scope.getObjectDescriptor(name); + } + @Nullable @Override public NamespaceDescriptor getNamespace(@NotNull String name) { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/SubstitutingScope.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/SubstitutingScope.java index 036e2e9b002..e0d64d3fdd2 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/SubstitutingScope.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/SubstitutingScope.java @@ -76,6 +76,11 @@ public class SubstitutingScope implements JetScope { return substitute(workerScope.getClassifier(name)); } + @Override + public ClassDescriptor getObjectDescriptor(@NotNull String name) { + return substitute(workerScope.getObjectDescriptor(name)); + } + @NotNull @Override public Set getFunctions(@NotNull String name) { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WritableScope.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WritableScope.java index 993c9b8fb70..90bf35dea4e 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WritableScope.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WritableScope.java @@ -29,6 +29,8 @@ public interface WritableScope extends JetScope { void addClassifierDescriptor(@NotNull ClassifierDescriptor classDescriptor); + void addObjectDescriptor(@NotNull ClassDescriptor objectDescriptor); + void addClassifierAlias(@NotNull String name, @NotNull ClassifierDescriptor classifierDescriptor); void addNamespaceAlias(@NotNull String name, @NotNull NamespaceDescriptor namespaceDescriptor); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WritableScopeImpl.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WritableScopeImpl.java index 2180d9022b0..79a0fb476af 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WritableScopeImpl.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WritableScopeImpl.java @@ -42,6 +42,9 @@ public class WritableScopeImpl extends WritableScopeWithImports { @Nullable private Map> labelsToDescriptors; + + @Nullable + private Map objectDescriptors; @Nullable private ReceiverDescriptor implicitReceiver; @@ -119,6 +122,14 @@ public class WritableScopeImpl extends WritableScopeWithImports { return labelsToDescriptors; } + @NotNull + public Map getObjectDescriptors() { + if (objectDescriptors == null) { + objectDescriptors = Maps.newHashMap(); + } + return objectDescriptors; + } + @NotNull @Override public Collection getDeclarationsByLabel(@NotNull String labelName) { @@ -277,6 +288,13 @@ public class WritableScopeImpl extends WritableScopeWithImports { addClassifierAlias(classDescriptor.getName(), classDescriptor); } + @Override + public void addObjectDescriptor(@NotNull ClassDescriptor objectDescriptor) { + checkMayWrite(); + + getObjectDescriptors().put(objectDescriptor.getName(), objectDescriptor); + } + @Override public void addClassifierAlias(@NotNull String name, @NotNull ClassifierDescriptor classifierDescriptor) { checkMayWrite(); @@ -346,6 +364,11 @@ public class WritableScopeImpl extends WritableScopeWithImports { return super.getClassifier(name); } + @Override + public ClassDescriptor getObjectDescriptor(@NotNull String name) { + return getObjectDescriptors().get(name); + } + @Override public void addNamespace(@NotNull NamespaceDescriptor namespaceDescriptor) { checkMayWrite(); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WritableScopeWithImports.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WritableScopeWithImports.java index 3d26fdaa2e8..4b594ccf462 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WritableScopeWithImports.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WritableScopeWithImports.java @@ -147,6 +147,19 @@ public abstract class WritableScopeWithImports extends JetScopeAdapter implement return null; } + @Override + public ClassDescriptor getObjectDescriptor(@NotNull String name) { + checkMayRead(); + + for (JetScope imported : getImports()) { + ClassDescriptor objectDescriptor = imported.getObjectDescriptor(name); + if (objectDescriptor != null) { + return objectDescriptor; + } + } + return null; + } + @Override public NamespaceDescriptor getNamespace(@NotNull String name) { checkMayRead(); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WriteThroughScope.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WriteThroughScope.java index 1a57a7c84bf..fe4a9f137da 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WriteThroughScope.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WriteThroughScope.java @@ -124,6 +124,19 @@ public class WriteThroughScope extends WritableScopeWithImports { return super.getClassifier(name); // Imports } + @Override + public ClassDescriptor getObjectDescriptor(@NotNull String name) { + checkMayRead(); + + ClassDescriptor objectDescriptor = writableWorker.getObjectDescriptor(name); + if (objectDescriptor != null) return objectDescriptor; + + objectDescriptor = getWorkerScope().getObjectDescriptor(name); + if (objectDescriptor != null) return objectDescriptor; + + return super.getObjectDescriptor(name); // Imports + } + @Override public void addLabeledDeclaration(@NotNull DeclarationDescriptor descriptor) { checkMayWrite(); @@ -166,6 +179,13 @@ public class WriteThroughScope extends WritableScopeWithImports { writableWorker.addClassifierDescriptor(classDescriptor); } + @Override + public void addObjectDescriptor(@NotNull ClassDescriptor objectDescriptor) { + checkMayWrite(); + + writableWorker.addObjectDescriptor(objectDescriptor); + } + @Override public void addClassifierAlias(@NotNull String name, @NotNull ClassifierDescriptor classifierDescriptor) { checkMayWrite(); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/ErrorUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/ErrorUtils.java index 51e6dd2282d..f464e00543b 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/ErrorUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/ErrorUtils.java @@ -22,6 +22,11 @@ public class ErrorUtils { return ERROR_CLASS; } + @Override + public ClassDescriptor getObjectDescriptor(@NotNull String name) { + return ERROR_CLASS; + } + @NotNull @Override public Set getProperties(@NotNull String name) { diff --git a/compiler/testData/diagnostics/tests/scopes/kt900.jet b/compiler/testData/diagnostics/tests/scopes/kt900.jet index e37074bb2b6..42cb748d254 100644 --- a/compiler/testData/diagnostics/tests/scopes/kt900.jet +++ b/compiler/testData/diagnostics/tests/scopes/kt900.jet @@ -93,3 +93,38 @@ object M { fun foo() {} class R() {} } + +//FILE:d.kt +package d + +//import from objects before properties resolve + +import A.* +import M.R +import M.R.bar +import M.T +import M.Y + +var r: T = T() +val y: T = Y + +fun f() { + bar() + R.bar() + B.foo() +} + +object M { + object R { + fun bar() {} + } + open class T() {} + + object Y : T() {} +} + +object A { + object B { + fun foo() {} + } +} \ No newline at end of file