import from objects before properties resolve

This commit is contained in:
svtk
2012-01-11 14:19:01 +04:00
parent a22b78d60d
commit 3e8e8bd3c8
27 changed files with 289 additions and 27 deletions
@@ -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<ClassDescriptor> getInnerClasses() {
return Collections.emptyList();
}
}
@@ -59,6 +59,11 @@ public class JavaClassMembersScope implements JetScope {
return classifierDescriptor;
}
@Override
public ClassDescriptor getObjectDescriptor(@NotNull String name) {
return null;
}
@NotNull
@Override
public Collection<DeclarationDescriptor> getAllDescriptors() {
@@ -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));
@@ -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<ClassDescriptor> getInnerClasses();
}
@@ -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<ClassDescriptor> getInnerClasses() {
return classDescriptor.getInnerClasses();
}
}
@@ -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<ClassDescriptor> getInnerClasses() {
return Collections.emptyList();
}
}
@@ -185,4 +185,15 @@ public class LazySubstitutingClassDescriptor implements ClassDescriptor {
public void acceptVoid(DeclarationDescriptorVisitor<Void, Void> visitor) {
throw new UnsupportedOperationException(); // TODO
}
@Override
public ClassDescriptor getInnerClass(String name) {
return original.getInnerClass(name);
}
@NotNull
@Override
public Collection<ClassDescriptor> getInnerClasses() {
return original.getInnerClasses();
}
}
@@ -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<FunctionDescriptor> functions = Sets.newHashSet();
private List<TypeParameterDescriptor> typeParameters = Lists.newArrayList();
private Collection<JetType> supertypes = Lists.newArrayList();
private Map<String, ClassDescriptor> 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<ClassDescriptor> getInnerClasses() {
return innerClasses.values();
}
@Override
public void addObjectDescriptor(@NotNull MutableClassDescriptor objectDescriptor) {
scopeForMemberLookup.addObjectDescriptor(objectDescriptor);
}
public void addSupertype(@NotNull JetType supertype) {
@@ -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);
@@ -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);
@@ -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<VariableDescriptor> getProperties(@NotNull String name) {
@@ -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);
@@ -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;
}
}
@@ -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<DeclarationDescriptor> 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<DeclarationDescriptor> 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<DeclarationDescriptor> 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<DeclarationDescriptor> getInnerClasses(@NotNull ClassDescriptor classDescriptor, @Nullable JetSimpleNameExpression memberReference) {
if (!DescriptorUtils.isObjectDescriptor(classDescriptor, trace)) 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);
recordReference(descriptors, memberReference, JetScope.EMPTY);
}
else {
descriptors = classDescriptor.getInnerClasses();
}
return addBoundToReceiver(descriptors, classDescriptor);
}
private Collection<DeclarationDescriptor> lookupVariableMembers(@NotNull JetSimpleNameExpression memberReference, @NotNull VariableDescriptor variableDescriptor) {
if (firstPhase) return Collections.emptyList();
@@ -236,7 +265,7 @@ public class ImportsResolver {
}
@NotNull
public static Collection<DeclarationDescriptor> addBoundToReceiver(@NotNull Collection<DeclarationDescriptor> descriptors, @NotNull final DeclarationDescriptor receiver) {
public static Collection<DeclarationDescriptor> addBoundToReceiver(@NotNull Collection<? extends DeclarationDescriptor> 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<? extends DeclarationDescriptor> 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);
}
}
}
}
@@ -133,6 +133,11 @@ public class TopDownAnalyzer {
}
@Override
public void addObjectDescriptor(@NotNull MutableClassDescriptor objectDescriptor) {
}
@Override
public void addFunctionDescriptor(@NotNull FunctionDescriptor functionDescriptor) {
throw new UnsupportedOperationException();
@@ -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;
}
@@ -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) {
@@ -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);
@@ -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<VariableDescriptor> getProperties(@NotNull String name) {
@@ -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) {
@@ -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<FunctionDescriptor> getFunctions(@NotNull String name) {
@@ -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);
@@ -42,6 +42,9 @@ public class WritableScopeImpl extends WritableScopeWithImports {
@Nullable
private Map<String, List<DeclarationDescriptor>> labelsToDescriptors;
@Nullable
private Map<String, ClassDescriptor> objectDescriptors;
@Nullable
private ReceiverDescriptor implicitReceiver;
@@ -119,6 +122,14 @@ public class WritableScopeImpl extends WritableScopeWithImports {
return labelsToDescriptors;
}
@NotNull
public Map<String, ClassDescriptor> getObjectDescriptors() {
if (objectDescriptors == null) {
objectDescriptors = Maps.newHashMap();
}
return objectDescriptors;
}
@NotNull
@Override
public Collection<DeclarationDescriptor> 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();
@@ -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();
@@ -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();
@@ -22,6 +22,11 @@ public class ErrorUtils {
return ERROR_CLASS;
}
@Override
public ClassDescriptor getObjectDescriptor(@NotNull String name) {
return ERROR_CLASS;
}
@NotNull
@Override
public Set<VariableDescriptor> getProperties(@NotNull String name) {
@@ -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() {}
}
}