KT-1579 "Can't import nested class/trait" partially: Entry can be imported, but Map.Entry in code is still unresolved

This commit is contained in:
Svetlana Isakova
2012-03-16 17:09:18 +04:00
parent ba841816c8
commit 114988ac82
15 changed files with 341 additions and 273 deletions
@@ -117,7 +117,9 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
v.visitOuterClass(typeMapper.mapType(container.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName(), null, null);
}
for (ClassDescriptor innerClass : descriptor.getInnerClassesAndObjects()) {
for (DeclarationDescriptor declarationDescriptor : descriptor.getUnsubstitutedInnerClassesScope().getAllDescriptors()) {
assert declarationDescriptor instanceof ClassDescriptor;
ClassDescriptor innerClass = (ClassDescriptor) declarationDescriptor;
// TODO: proper access
int innerClassAccess = ACC_PUBLIC;
if (innerClass.getModality() == Modality.FINAL) {
@@ -36,6 +36,9 @@ public interface ClassDescriptor extends ClassifierDescriptor, MemberDescriptor,
@NotNull
JetScope getMemberScope(List<TypeProjection> typeArguments);
@NotNull
JetScope getUnsubstitutedInnerClassesScope();
@NotNull
Set<ConstructorDescriptor> getConstructors();
@@ -77,10 +80,4 @@ public interface ClassDescriptor extends ClassifierDescriptor, MemberDescriptor,
@NotNull
ReceiverDescriptor getImplicitReceiver();
@Nullable
ClassDescriptor getInnerClassOrObject(String name);
@NotNull
Collection<ClassDescriptor> getInnerClassesAndObjects();
}
@@ -176,14 +176,9 @@ public class ClassDescriptorImpl extends DeclarationDescriptorImpl implements Cl
return implicitReceiver;
}
@Override
public ClassDescriptor getInnerClassOrObject(String name) {
return null;
}
@NotNull
@Override
public Collection<ClassDescriptor> getInnerClassesAndObjects() {
return Collections.emptyList();
public JetScope getUnsubstitutedInnerClassesScope() {
return JetScope.EMPTY;
}
}
@@ -20,7 +20,6 @@ import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.resolve.scopes.SubstitutingScope;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
@@ -204,14 +203,9 @@ public class LazySubstitutingClassDescriptor implements ClassDescriptor {
throw new UnsupportedOperationException(); // TODO
}
@Override
public ClassDescriptor getInnerClassOrObject(String name) {
return original.getInnerClassOrObject(name);
}
@NotNull
@Override
public Collection<ClassDescriptor> getInnerClassesAndObjects() {
return original.getInnerClassesAndObjects();
public JetScope getUnsubstitutedInnerClassesScope() {
return original.getUnsubstitutedInnerClassesScope();
}
}
@@ -23,9 +23,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.resolve.BindingTrace;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.resolve.scopes.SubstitutingScope;
import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
import org.jetbrains.jet.lang.resolve.scopes.*;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ClassReceiver;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import org.jetbrains.jet.lang.types.*;
@@ -42,8 +40,6 @@ public class MutableClassDescriptorLite extends MutableDeclarationDescriptor imp
private List<AnnotationDescriptor> annotations = Lists.newArrayList();
private Map<String, ClassDescriptor> innerClassesAndObjects = Maps.newHashMap();
private List<TypeParameterDescriptor> typeParameters;
private Collection<JetType> supertypes = Lists.newArrayList();
@@ -58,6 +54,7 @@ public class MutableClassDescriptorLite extends MutableDeclarationDescriptor imp
private final ClassKind kind;
private JetScope scopeForMemberLookup;
private JetScope innerClassesScope;
private ClassReceiver implicitReceiver;
@@ -109,6 +106,7 @@ public class MutableClassDescriptorLite extends MutableDeclarationDescriptor imp
public void setScopeForMemberLookup(JetScope scopeForMemberLookup) {
this.scopeForMemberLookup = scopeForMemberLookup;
this.innerClassesScope = new InnerClassesScopeWrapper(scopeForMemberLookup);
}
public void createTypeConstructor() {
@@ -264,25 +262,17 @@ public class MutableClassDescriptorLite extends MutableDeclarationDescriptor imp
@Override
public void addClassifierDescriptor(@NotNull MutableClassDescriptorLite classDescriptor) {
getScopeForMemberLookupAsWritableScope().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 JetScope getUnsubstitutedInnerClassesScope() {
return innerClassesScope;
}
@Override
public void addObjectDescriptor(@NotNull MutableClassDescriptorLite objectDescriptor) {
getScopeForMemberLookupAsWritableScope().addObjectDescriptor(objectDescriptor);
innerClassesAndObjects.put(objectDescriptor.getName(), objectDescriptor);
}
public void addSupertype(@NotNull JetType supertype) {
@@ -304,7 +294,6 @@ public class MutableClassDescriptorLite extends MutableDeclarationDescriptor imp
}
}
public void lockScopes() {
getScopeForMemberLookupAsWritableScope().changeLockLevel(WritableScope.LockLevel.READING);
if (classObjectDescriptor != null) {
@@ -247,14 +247,6 @@ public class DescriptorUtils {
return null;
}
@Nullable
public static ClassDescriptor getObjectIfObjectOrClassObjectDescriptor(ClassDescriptor descriptor) {
if ((descriptor).getKind() == ClassKind.OBJECT) {
return descriptor;
}
return descriptor.getClassObjectDescriptor();
}
@NotNull
public static JetType getFunctionExpectedReturnType(@NotNull FunctionDescriptor descriptor, @NotNull JetElement function) {
JetType expectedType;
@@ -21,9 +21,7 @@ import com.intellij.openapi.util.Pair;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
import org.jetbrains.jet.lang.types.JetType;
import java.util.Collection;
import java.util.List;
/**
@@ -68,26 +66,12 @@ import java.util.List;
if (descriptor instanceof NamespaceDescriptor) {
namespaceScope.importScope(((NamespaceDescriptor) descriptor).getMemberScope());
}
if (firstPhase) {
if (descriptor instanceof ClassDescriptor) {
ClassDescriptor objectDescriptor = DescriptorUtils.getObjectIfObjectOrClassObjectDescriptor((ClassDescriptor) descriptor);
if (objectDescriptor != null) {
Collection<? extends DeclarationDescriptor> innerClassesAndObjects = objectDescriptor.getInnerClassesAndObjects();
for (DeclarationDescriptor innerClassOrObject : innerClassesAndObjects) {
namespaceScope.importClassifierAlias(innerClassOrObject.getName(), (ClassifierDescriptor) innerClassOrObject);
}
}
}
return;
}
if (descriptor instanceof VariableDescriptor) {
JetType type = ((VariableDescriptor) descriptor).getType();
namespaceScope.importScope(type.getMemberScope());
}
else if (descriptor instanceof ClassDescriptor) {
JetType classObjectType = ((ClassDescriptor) descriptor).getClassObjectType();
if (classObjectType != null) {
namespaceScope.importScope(classObjectType.getMemberScope());
if (descriptor instanceof ClassDescriptor && ((ClassDescriptor) descriptor).getKind() != ClassKind.OBJECT) {
ClassDescriptor classDescriptor = (ClassDescriptor) descriptor;
namespaceScope.importScope(classDescriptor.getUnsubstitutedInnerClassesScope());
ClassDescriptor classObjectDescriptor = classDescriptor.getClassObjectDescriptor();
if (classObjectDescriptor != null) {
namespaceScope.importScope(classObjectDescriptor.getUnsubstitutedInnerClassesScope());
}
}
}
@@ -20,20 +20,17 @@ import com.google.common.base.Predicate;
import com.google.common.collect.Collections2;
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 javax.inject.Inject;
import org.jetbrains.jet.lang.ModuleConfiguration;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
import org.jetbrains.jet.lang.types.JetType;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import javax.inject.Inject;
import java.util.*;
import static org.jetbrains.jet.lang.diagnostics.Errors.*;
@@ -46,6 +43,8 @@ public class ImportsResolver {
private TopDownAnalysisContext context;
@NotNull
private ModuleConfiguration configuration;
@NotNull
private SingleImportResolver singleImportResolver;
@Inject
public void setContext(@NotNull TopDownAnalysisContext context) {
@@ -57,6 +56,9 @@ public class ImportsResolver {
this.configuration = configuration;
}
public ImportsResolver() {
this.singleImportResolver = new SingleImportResolver();
}
public void processTypeImports() {
processImports(true);
@@ -66,9 +68,10 @@ public class ImportsResolver {
processImports(false);
}
// 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 void processImports(boolean firstPhase) {
SingleImportResolver importResolver = new SingleImportResolver(context.getTrace(), firstPhase);
SingleImportResolver defaultImportResolver = new SingleImportResolver(TemporaryBindingTrace.create(context.getTrace()), firstPhase);//not to trace errors of default imports
TemporaryBindingTrace temporaryTrace = TemporaryBindingTrace.create(context.getTrace()); //not to trace errors of default imports
for (JetFile file : context.getNamespaceDescriptors().keySet()) {
WritableScope namespaceScope = context.getNamespaceScopes().get(file);
Importer.DelayedImporter delayedImporter = new Importer.DelayedImporter(namespaceScope, firstPhase);
@@ -79,12 +82,12 @@ public class ImportsResolver {
Collection<JetImportDirective> defaultImportDirectives = Lists.newArrayList();
configuration.addDefaultImports(namespaceScope, defaultImportDirectives);
for (JetImportDirective defaultImportDirective : defaultImportDirectives) {
defaultImportResolver.processImportReference(defaultImportDirective, namespaceScope, delayedImporter);
singleImportResolver.processImportReference(defaultImportDirective, namespaceScope, delayedImporter, temporaryTrace, firstPhase);
}
List<JetImportDirective> importDirectives = file.getImportDirectives();
for (JetImportDirective importDirective : importDirectives) {
Collection<? extends DeclarationDescriptor> descriptors = importResolver.processImportReference(importDirective, namespaceScope, delayedImporter);
Collection<? extends DeclarationDescriptor> descriptors = singleImportResolver.processImportReference(importDirective, namespaceScope, delayedImporter, context.getTrace(), firstPhase);
if (descriptors.size() == 1) {
resolvedDirectives.put(importDirective, descriptors.iterator().next());
}
@@ -162,23 +165,17 @@ public class ImportsResolver {
@NotNull JetImportDirective importDirective,
@NotNull JetScope scope, @NotNull BindingTrace trace
) {
ImportsResolver.SingleImportResolver importResolver = new ImportsResolver.SingleImportResolver(trace, false);
return importResolver.processImportReference(importDirective, scope, Importer.DO_NOTHING);
ImportsResolver.SingleImportResolver importResolver = new ImportsResolver.SingleImportResolver();
return importResolver.processImportReference(importDirective, scope, Importer.DO_NOTHING, trace, false);
}
private static class SingleImportResolver {
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 SingleImportResolver(BindingTrace trace, boolean firstPhase) {
this.trace = trace;
this.firstPhase = firstPhase;
}
@NotNull
public Collection<? extends DeclarationDescriptor> processImportReference(@NotNull JetImportDirective importDirective, @NotNull JetScope scope, @NotNull Importer importer) {
public Collection<? extends DeclarationDescriptor> processImportReference(@NotNull JetImportDirective importDirective,
@NotNull JetScope scope,
@NotNull Importer importer,
@NotNull BindingTrace trace,
boolean firstPhase) {
if (importDirective.isAbsoluteInRootNamespace()) {
trace.report(UNSUPPORTED.on(importDirective, "TypeHierarchyResolver")); // TODO
return Collections.emptyList();
@@ -190,16 +187,16 @@ public class ImportsResolver {
Collection<? extends DeclarationDescriptor> descriptors;
if (importedReference instanceof JetQualifiedExpression) {
descriptors = lookupDescriptorsForQualifiedExpression((JetQualifiedExpression) importedReference, scope);
descriptors = lookupDescriptorsForQualifiedExpression((JetQualifiedExpression) importedReference, scope, trace, firstPhase);
}
else {
assert importedReference instanceof JetSimpleNameExpression;
descriptors = lookupDescriptorsForSimpleNameReference((JetSimpleNameExpression) importedReference, scope, true);
descriptors = lookupDescriptorsForSimpleNameReference((JetSimpleNameExpression) importedReference, scope, trace, firstPhase, true);
}
JetSimpleNameExpression referenceExpression = getLastReference(importedReference);
if (importDirective.isAllUnder()) {
if (referenceExpression == null || !canImportMembersFrom(descriptors, referenceExpression)) {
if (referenceExpression == null || !canImportMembersFrom(descriptors, referenceExpression, trace,firstPhase)) {
return Collections.emptyList();
}
@@ -223,147 +220,120 @@ public class ImportsResolver {
@NotNull
private Collection<? extends DeclarationDescriptor> lookupDescriptorsForQualifiedExpression(
@NotNull JetQualifiedExpression importedReference, @NotNull JetScope outerScope) {
@NotNull JetQualifiedExpression importedReference,
@NotNull JetScope outerScope,
@NotNull BindingTrace trace,
boolean firstPhase) {
JetExpression receiverExpression = importedReference.getReceiverExpression();
Collection<? extends DeclarationDescriptor> declarationDescriptors;
if (receiverExpression instanceof JetQualifiedExpression) {
declarationDescriptors = lookupDescriptorsForQualifiedExpression((JetQualifiedExpression) receiverExpression, outerScope);
declarationDescriptors = lookupDescriptorsForQualifiedExpression((JetQualifiedExpression) receiverExpression, outerScope, trace, firstPhase);
}
else {
assert receiverExpression instanceof JetSimpleNameExpression;
declarationDescriptors = lookupDescriptorsForSimpleNameReference((JetSimpleNameExpression) receiverExpression, outerScope, true);
declarationDescriptors = lookupDescriptorsForSimpleNameReference((JetSimpleNameExpression) receiverExpression, outerScope, trace, firstPhase, true);
}
JetExpression selectorExpression = importedReference.getSelectorExpression();
if (selectorExpression instanceof JetSimpleNameExpression) {
JetSimpleNameExpression selector = (JetSimpleNameExpression) selectorExpression;
JetSimpleNameExpression lastReference = getLastReference(receiverExpression);
if (lastReference == null || !canImportMembersFrom(declarationDescriptors, lastReference)) {
return Collections.emptyList();
}
if (!(selectorExpression instanceof JetSimpleNameExpression)) return Collections.emptyList();
Collection<? extends DeclarationDescriptor> result;
for (DeclarationDescriptor declarationDescriptor : declarationDescriptors) {
if (declarationDescriptor instanceof NamespaceDescriptor) {
result = lookupDescriptorsForSimpleNameReference(selector, ((NamespaceDescriptor) declarationDescriptor).getMemberScope(), true);
if (!result.isEmpty()) {
return result;
}
}
if (declarationDescriptor instanceof ClassDescriptor) {
result = lookupObjectMembers((ClassDescriptor) declarationDescriptor, selector);
if (!result.isEmpty()) {
return result;
}
}
if (declarationDescriptor instanceof VariableDescriptor) {
result = lookupVariableMembers((VariableDescriptor) declarationDescriptor, selector);
if (!result.isEmpty()) {
return result;
}
JetSimpleNameExpression selector = (JetSimpleNameExpression) selectorExpression;
JetSimpleNameExpression lastReference = getLastReference(receiverExpression);
if (lastReference == null || !canImportMembersFrom(declarationDescriptors, lastReference, trace, firstPhase)) {
return Collections.emptyList();
}
Set<SuccessfulLookupResult> results = Sets.newHashSet();
for (DeclarationDescriptor declarationDescriptor : declarationDescriptors) {
if (declarationDescriptor instanceof NamespaceDescriptor) {
addResult(results, lookupSimpleNameReference(selector, ((NamespaceDescriptor) declarationDescriptor).getMemberScope(), firstPhase, true));
}
if (declarationDescriptor instanceof ClassDescriptor) {
addResult(results, lookupSimpleNameReference(selector, getAppropriateScope((ClassDescriptor) declarationDescriptor, firstPhase), firstPhase, false));
ClassDescriptor classObjectDescriptor = ((ClassDescriptor) declarationDescriptor).getClassObjectDescriptor();
if (classObjectDescriptor != null) {
addResult(results, lookupSimpleNameReference(selector, getAppropriateScope(classObjectDescriptor, firstPhase), firstPhase, false));
}
}
}
return Collections.emptyList();
if (results.isEmpty()) {
return Collections.emptyList();
}
return filterAndStoreResolutionResult(results, selector, trace, firstPhase);
}
private boolean canImportMembersFrom(@NotNull Collection<? extends DeclarationDescriptor> descriptors, @NotNull JetSimpleNameExpression reference) {
private static JetScope getAppropriateScope(ClassDescriptor classDescriptor, boolean firstPhase) {
return firstPhase ? classDescriptor.getUnsubstitutedInnerClassesScope() : classDescriptor.getDefaultType().getMemberScope();
}
private static void addResult(Set<SuccessfulLookupResult> results, LookupResult result) {
if (result == LookupResult.EMPTY) return;
results.add((SuccessfulLookupResult) result);
}
private boolean canImportMembersFrom(@NotNull Collection<? extends DeclarationDescriptor> descriptors,
@NotNull JetSimpleNameExpression reference,
@NotNull BindingTrace trace,
boolean firstPhase) {
if (firstPhase) {
return true;
}
if (descriptors.size() == 1) {
return canImportMembersFrom(descriptors.iterator().next(), reference, trace);
return canImportMembersFrom(descriptors.iterator().next(), reference, trace, firstPhase);
}
TemporaryBindingTrace temporaryTrace = TemporaryBindingTrace.create(trace);
boolean canImport = false;
for (DeclarationDescriptor descriptor : descriptors) {
canImport |= canImportMembersFrom(descriptor, reference, temporaryTrace);
canImport |= canImportMembersFrom(descriptor, reference, temporaryTrace, firstPhase);
}
if (!canImport) {
temporaryTrace.commit();
}
return canImport;
}
private boolean canImportMembersFrom(@NotNull DeclarationDescriptor descriptor,
@NotNull JetSimpleNameExpression reference,
@NotNull BindingTrace trace) {
@NotNull BindingTrace trace,
boolean firstPhase) {
assert !firstPhase;
if (descriptor instanceof NamespaceDescriptor) {
return true;
}
if (descriptor instanceof ClassDescriptor) {
ClassDescriptor classDescriptor = (ClassDescriptor) descriptor;
JetType classObjectType = classDescriptor.getClassObjectType();
if (classObjectType == null) {
trace.report(NO_CLASS_OBJECT.on(reference, classDescriptor));
return false;
}
return true;
}
if (descriptor instanceof VariableDescriptor && ((VariableDescriptor) descriptor).isObjectDeclaration()) {
if (descriptor instanceof ClassDescriptor && ((ClassDescriptor) descriptor).getKind() != ClassKind.OBJECT) {
return true;
}
trace.report(CANNOT_IMPORT_FROM_ELEMENT.on(reference, descriptor));
return false;
}
@NotNull
private Collection<? extends DeclarationDescriptor> lookupObjectMembers(@NotNull ClassDescriptor classDescriptor, @NotNull JetSimpleNameExpression memberReference) {
if (firstPhase) {
ClassDescriptor objectDescriptor = DescriptorUtils.getObjectIfObjectOrClassObjectDescriptor(classDescriptor);
if (objectDescriptor == null) {
return Collections.emptyList();
}
return getInnerClassesAndObjectsByName(objectDescriptor, memberReference);
}
//on second phase class descriptor is only a descriptor for class object
JetType classObjectType = classDescriptor.getClassObjectType();
if (classObjectType == null) {
return Collections.emptyList();
}
return lookupDescriptorsForSimpleNameReference(memberReference, classObjectType.getMemberScope(), false);
}
@NotNull
private Collection<? extends DeclarationDescriptor> getInnerClassesAndObjectsByName(@NotNull ClassDescriptor classDescriptor, @NotNull JetSimpleNameExpression memberReference) {
assert classDescriptor.getKind() == ClassKind.OBJECT;
Collection<? extends DeclarationDescriptor> descriptors;
ClassDescriptor innerClass = classDescriptor.getInnerClassOrObject(memberReference.getReferencedName());
if (innerClass == null) {
return Collections.emptyList();
}
descriptors = Collections.<DeclarationDescriptor>singletonList(innerClass);
return filterResolutionResult(descriptors, memberReference, JetScope.EMPTY, false);
}
private Collection<? extends DeclarationDescriptor> lookupVariableMembers(@NotNull VariableDescriptor variableDescriptor, @NotNull JetSimpleNameExpression memberReference) {
if (firstPhase) {
return Collections.emptyList();
}
JetType variableType = variableDescriptor.getReturnType();
if (variableType == null) {
return Collections.emptyList();
}
return lookupDescriptorsForSimpleNameReference(memberReference, variableType.getMemberScope(), false);
}
@NotNull
private Collection<? extends DeclarationDescriptor> lookupDescriptorsForSimpleNameReference(
@NotNull JetSimpleNameExpression referenceExpression,
@NotNull JetScope outerScope,
@NotNull BindingTrace trace,
boolean firstPhase,
boolean namespaceLevel) {
LookupResult lookupResult = lookupSimpleNameReference(referenceExpression, outerScope, firstPhase, namespaceLevel);
if (lookupResult == LookupResult.EMPTY) return Collections.emptyList();
return filterAndStoreResolutionResult(Collections.singletonList((SuccessfulLookupResult) lookupResult), referenceExpression, trace, firstPhase);
}
private LookupResult lookupSimpleNameReference(
@NotNull JetSimpleNameExpression referenceExpression,
@NotNull JetScope outerScope,
boolean firstPhase,
boolean namespaceLevel) {
String referencedName = referenceExpression.getReferencedName();
if (referencedName == null) {
return Collections.emptyList();
//to store a scope where we tried to resolve this reference
return new SuccessfulLookupResult(Collections.<DeclarationDescriptor>emptyList(), outerScope, namespaceLevel);
}
List<DeclarationDescriptor> descriptors = Lists.newArrayList();
Set<DeclarationDescriptor> descriptors = Sets.newHashSet();
NamespaceDescriptor namespaceDescriptor = outerScope.getNamespace(referencedName);
if (namespaceDescriptor != null) {
descriptors.add(namespaceDescriptor);
@@ -386,39 +356,55 @@ public class ImportsResolver {
descriptors.add(localVariable);
}
}
return filterResolutionResult(descriptors, referenceExpression, outerScope, namespaceLevel);
return new SuccessfulLookupResult(descriptors, outerScope, namespaceLevel);
}
private Collection<? extends DeclarationDescriptor> filterResolutionResult(
@NotNull Collection<? extends DeclarationDescriptor> descriptors,
private Collection<? extends DeclarationDescriptor> filterAndStoreResolutionResult(
@NotNull Collection<SuccessfulLookupResult> lookupResults,
@NotNull JetSimpleNameExpression referenceExpression,
@NotNull JetScope resolutionScope,
//functions and properties can be imported if namespaceLevel == true
boolean namespaceLevel) {
@NotNull BindingTrace trace,
boolean firstPhase) {
//functions and properties can be imported if lookupResult.namespaceLevel == true
Collection<DeclarationDescriptor> descriptors = Sets.newLinkedHashSet();
for (SuccessfulLookupResult lookupResult : lookupResults) {
descriptors.addAll(lookupResult.descriptors);
}
if (firstPhase) {
return Collections2.filter(descriptors, new Predicate<DeclarationDescriptor>() {
@Override
public boolean apply(@Nullable DeclarationDescriptor descriptor) {
return (descriptor instanceof ClassDescriptor) ||
return (descriptor instanceof ClassDescriptor) ||
(descriptor instanceof NamespaceDescriptor);
}
});
}
Collection<? extends DeclarationDescriptor> filteredDescriptors;
if (namespaceLevel) {
filteredDescriptors = descriptors;
}
else {
filteredDescriptors = Collections2.filter(descriptors, new Predicate<DeclarationDescriptor>() {
Collection<DeclarationDescriptor> filteredDescriptors = Sets.newLinkedHashSet();
for (SuccessfulLookupResult lookupResult : lookupResults) {
if (lookupResult.namespaceLevel) {
filteredDescriptors.addAll(lookupResult.descriptors);
continue;
}
filteredDescriptors.addAll(Collections2.filter(lookupResult.descriptors, new Predicate<DeclarationDescriptor>() {
@Override
public boolean apply(@Nullable DeclarationDescriptor descriptor) {
return (descriptor instanceof NamespaceDescriptor) ||
(descriptor instanceof ClassDescriptor) ||
(descriptor instanceof VariableDescriptor && ((VariableDescriptor) descriptor).isObjectDeclaration());
}
});
}));
}
storeResolutionResult(descriptors, filteredDescriptors, referenceExpression, resolutionScope);
Collection<JetScope> possibleResolutionScopes = Lists.newArrayList();
for (SuccessfulLookupResult lookupResult : lookupResults) {
if (!lookupResult.descriptors.isEmpty()) {
possibleResolutionScopes.add(lookupResult.resolutionScope);
}
}
if (possibleResolutionScopes.isEmpty()) {
for (SuccessfulLookupResult lookupResult : lookupResults) {
possibleResolutionScopes.add(lookupResult.resolutionScope);
}
}
storeResolutionResult(descriptors, filteredDescriptors, referenceExpression, possibleResolutionScopes, trace);
return filteredDescriptors;
}
@@ -426,12 +412,16 @@ public class ImportsResolver {
@NotNull Collection<? extends DeclarationDescriptor> descriptors,
@NotNull Collection<? extends DeclarationDescriptor> canBeImportedDescriptors,
@NotNull JetSimpleNameExpression referenceExpression,
@NotNull JetScope resolutionScope) {
@NotNull Collection<JetScope> possibleResolutionScopes,
@NotNull BindingTrace trace) {
assert canBeImportedDescriptors.size() <= descriptors.size();
assert !possibleResolutionScopes.isEmpty();
//todo completion here needs all possible resolution scopes, if there are many
JetScope resolutionScope = possibleResolutionScopes.iterator().next();
// A special case - will fill all trace information
if (resolveClassNamespaceAmbiguity(canBeImportedDescriptors, referenceExpression, resolutionScope)) {
if (resolveClassNamespaceAmbiguity(canBeImportedDescriptors, referenceExpression, resolutionScope, trace)) {
return;
}
@@ -451,8 +441,6 @@ public class ImportsResolver {
else if (canBeImportedDescriptors.size() == 1) {
trace.record(BindingContext.REFERENCE_TARGET, referenceExpression, canBeImportedDescriptors.iterator().next());
trace.record(BindingContext.RESOLUTION_SCOPE, referenceExpression, resolutionScope);
} else {
// trace.report(UNRESOLVED_REFERENCE.on(referenceExpression));
}
// Check for more information and additional errors
@@ -471,9 +459,10 @@ public class ImportsResolver {
*
* @return <code>true</code> if method has successfully resolved ambiguity
*/
private boolean resolveClassNamespaceAmbiguity(Collection<? extends DeclarationDescriptor> filteredDescriptors,
JetSimpleNameExpression referenceExpression,
JetScope resolutionScope) {
private boolean resolveClassNamespaceAmbiguity(@NotNull Collection<? extends DeclarationDescriptor> filteredDescriptors,
@NotNull JetSimpleNameExpression referenceExpression,
@NotNull JetScope resolutionScope,
@NotNull BindingTrace trace) {
if (filteredDescriptors.size() == 2) {
NamespaceDescriptor namespaceDescriptor = null;
@@ -499,5 +488,21 @@ public class ImportsResolver {
return false;
}
private interface LookupResult {
LookupResult EMPTY = new LookupResult() {};
}
private static class SuccessfulLookupResult implements LookupResult {
final Collection<? extends DeclarationDescriptor> descriptors;
final JetScope resolutionScope;
final boolean namespaceLevel;
private SuccessfulLookupResult(Collection<? extends DeclarationDescriptor> descriptors, JetScope resolutionScope, boolean namespaceLevel) {
this.descriptors = descriptors;
this.resolutionScope = resolutionScope;
this.namespaceLevel = namespaceLevel;
}
}
}
}
}
@@ -0,0 +1,93 @@
/*
* Copyright 2010-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.lang.resolve.scopes;
import com.google.common.base.Predicate;
import com.google.common.collect.Collections2;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.ClassKind;
import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import java.util.Collection;
import java.util.List;
/**
* @author svtk
*/
public class InnerClassesScopeWrapper extends JetScopeImpl {
private final JetScope actualScope;
public InnerClassesScopeWrapper(JetScope actualScope) {
this.actualScope = actualScope;
}
private boolean isClass(DeclarationDescriptor descriptor) {
return descriptor instanceof ClassDescriptor && ((ClassDescriptor) descriptor).getKind() != ClassKind.OBJECT;
}
@Override
public ClassifierDescriptor getClassifier(@NotNull String name) {
ClassifierDescriptor classifier = actualScope.getClassifier(name);
if (isClass(classifier)) return classifier;
return null;
}
@NotNull
@Override
public DeclarationDescriptor getContainingDeclaration() {
return actualScope.getContainingDeclaration();
}
@NotNull
@Override
public Collection<DeclarationDescriptor> getDeclarationsByLabel(String labelName) {
Collection<DeclarationDescriptor> declarationsByLabel = actualScope.getDeclarationsByLabel(labelName);
return Collections2.filter(declarationsByLabel, new Predicate<DeclarationDescriptor>() {
@Override
public boolean apply(@Nullable DeclarationDescriptor descriptor) {
return isClass(descriptor);
}
});
}
@NotNull
@Override
public Collection<DeclarationDescriptor> getAllDescriptors() {
Collection<DeclarationDescriptor> allDescriptors = actualScope.getAllDescriptors();
return Collections2.filter(allDescriptors, new Predicate<DeclarationDescriptor>() {
@Override
public boolean apply(@Nullable DeclarationDescriptor descriptor) {
return isClass(descriptor);
}
});
}
@NotNull
@Override
public ReceiverDescriptor getImplicitReceiver() {
return actualScope.getImplicitReceiver();
}
@Override
public void getImplicitReceiversHierarchy(@NotNull List<ReceiverDescriptor> result) {
actualScope.getImplicitReceiversHierarchy(result);
}
}
@@ -70,7 +70,7 @@ fun bar() {}
//FILE:c.kt
package c
import C.*
import <!CANNOT_IMPORT_FROM_ELEMENT!>C<!>.*
object C {
fun f() {
@@ -79,7 +79,7 @@ object C {
}
fun foo() {
if (i == 3) f()
if (<!UNRESOLVED_REFERENCE!>i<!> == 3) <!UNRESOLVED_REFERENCE!>f<!>()
}
//FILE:d.kt
@@ -96,4 +96,4 @@ class A() {
open class B() {}
object C : B() {}
}
}
}
@@ -0,0 +1,9 @@
//FILE:a.kt
package lib
trait WithInner {
trait Inner {
}
}
//FILE:b.kt
package user
import lib.WithInner.Inner
@@ -0,0 +1,12 @@
//FILE:a.kt
//+JDK
package a
import java.util.Map.*
fun foo(b : Entry<String, String>) = b
//FILE:b.kt
//+JDK
package b
import java.util.Map.Entry
fun bar(b : Entry<String, String>) = b
@@ -0,0 +1,24 @@
// import all members from class object
package c
import A.*
import <!CANNOT_IMPORT_FROM_ELEMENT!>M<!>.*
fun foo() {
val <!UNUSED_VARIABLE!>b<!>: B = B()
var <!UNUSED_VARIABLE!>r<!>: <!UNRESOLVED_REFERENCE!>R<!> = <!UNRESOLVED_REFERENCE!>R<!>()
}
class A() {
class object {
class B() {
class object {
}
}
}
}
object M {
fun foo() {}
class R() {}
}
@@ -0,0 +1,33 @@
package d
//import from objects before properties resolve
import <!CANNOT_IMPORT_FROM_ELEMENT!>A<!>.*
import <!CANNOT_IMPORT_FROM_ELEMENT!>M<!>.R
import <!CANNOT_IMPORT_FROM_ELEMENT!>M<!>.R.bar
import <!CANNOT_IMPORT_FROM_ELEMENT!>M<!>.T
import <!CANNOT_IMPORT_FROM_ELEMENT!>M<!>.Y
var r: T = <!UNRESOLVED_REFERENCE!>T<!>()
val y: T = <!UNRESOLVED_REFERENCE!>Y<!>
fun f() {
<!UNRESOLVED_REFERENCE!>bar<!>()
<!UNRESOLVED_REFERENCE!>R<!>.bar()
<!UNRESOLVED_REFERENCE!>B<!>.foo()
}
object M {
object R {
fun bar() {}
}
open class T() {}
object Y : T() {}
}
object A {
object B {
fun foo() {}
}
}
@@ -35,7 +35,7 @@ object N {
//FILE:b.kt
package b
import N.M
import <!CANNOT_IMPORT_FROM_ELEMENT!>N<!>.M
import A.P
import b.A.B
@@ -45,7 +45,7 @@ fun foo() {
P.foo()
M.bar()
<!UNRESOLVED_REFERENCE!>M<!>.bar()
}
class A() {
@@ -66,65 +66,4 @@ object N {
object M {
fun bar() {}
}
}
//FILE:c.kt
// import all members from class object
package c
import A.*
import M.*
fun foo() {
val <!UNUSED_VARIABLE!>b<!>: B = B()
var <!UNUSED_VARIABLE!>r<!>: R = R()
}
class A() {
class object {
class B() {
class object {
}
}
}
}
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.<!CANNOT_BE_IMPORTED!>bar<!>
import M.T
import M.Y
var r: T = T()
val y: T = Y
fun f() {
<!UNRESOLVED_REFERENCE!>bar<!>()
R.bar()
B.foo()
}
object M {
object R {
fun bar() {}
}
open class T() {}
object Y : T() {}
}
object A {
object B {
fun foo() {}
}
}
}