diff --git a/compiler/backend/src/org/jetbrains/jet/compiler/TipsManager.java b/compiler/backend/src/org/jetbrains/jet/compiler/TipsManager.java index b105ef2a633..36d4e7eeb07 100644 --- a/compiler/backend/src/org/jetbrains/jet/compiler/TipsManager.java +++ b/compiler/backend/src/org/jetbrains/jet/compiler/TipsManager.java @@ -8,8 +8,10 @@ import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.descriptors.CallableDescriptor; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; +import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor; import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor; import org.jetbrains.jet.lang.psi.JetExpression; +import org.jetbrains.jet.lang.psi.JetImportDirective; import org.jetbrains.jet.lang.psi.JetQualifiedExpression; import org.jetbrains.jet.lang.psi.JetSimpleNameExpression; import org.jetbrains.jet.lang.resolve.BindingContext; @@ -42,12 +44,14 @@ public final class TipsManager { @NotNull public static Collection getReferenceVariants(JetSimpleNameExpression expression, BindingContext context) { PsiElement parent = expression.getParent(); - if (parent instanceof JetQualifiedExpression) { + + if (parent instanceof JetQualifiedExpression && !(parent.getParent() instanceof JetImportDirective)) { + // Process as call expression JetQualifiedExpression qualifiedExpression = (JetQualifiedExpression) parent; JetExpression receiverExpression = qualifiedExpression.getReceiverExpression(); - final JetType expressionType = context.get(BindingContext.EXPRESSION_TYPE, receiverExpression); final JetScope resolutionScope = context.get(BindingContext.RESOLUTION_SCOPE, receiverExpression); + final JetType expressionType = context.get(BindingContext.EXPRESSION_TYPE, receiverExpression); if (expressionType != null && resolutionScope != null) { return includeExternalCallableExtensions( @@ -58,7 +62,12 @@ public final class TipsManager { else { JetScope resolutionScope = context.get(BindingContext.RESOLUTION_SCOPE, expression); if (resolutionScope != null) { - return excludeNotCallableExtensions(resolutionScope.getAllDescriptors(), resolutionScope); + if (parent instanceof JetImportDirective) { + return excludeNonPackageDescriptors(resolutionScope.getAllDescriptors()); + } + else { + return excludeNotCallableExtensions(resolutionScope.getAllDescriptors(), resolutionScope); + } } } @@ -80,6 +89,16 @@ public final class TipsManager { return Lists.newArrayList(descriptorsSet); } + + private static Collection excludeNonPackageDescriptors( + @NotNull Collection descriptors) { + return Collections2.filter(descriptors, new Predicate() { + @Override + public boolean apply(DeclarationDescriptor declarationDescriptor) { + return declarationDescriptor instanceof NamespaceDescriptor; + } + }); + } private static Collection includeExternalCallableExtensions( @NotNull Collection descriptors, diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/StandardConfiguration.java b/compiler/frontend/src/org/jetbrains/jet/lang/StandardConfiguration.java index 30a2675b2a8..9d553a51af0 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/StandardConfiguration.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/StandardConfiguration.java @@ -26,7 +26,7 @@ public class StandardConfiguration implements Configuration { @Override public void addDefaultImports(@NotNull BindingTrace trace, @NotNull WritableScope rootScope) { JetImportDirective importDirective = JetPsiFactory.createImportDirective(project, "std.*"); - new ImportsResolver.ImportResolver(trace, true).processImportReference(importDirective, rootScope, rootScope); + new ImportsResolver.ImportResolver(trace, true).processImportReference(importDirective, rootScope); } @Override 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 29027eec06c..d51a7eff87a 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ImportsResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ImportsResolver.java @@ -46,7 +46,7 @@ public class ImportsResolver { List importDirectives = file.getImportDirectives(); for (JetImportDirective importDirective : importDirectives) { - importResolver.processImportReference(importDirective, namespaceScope, JetScope.EMPTY); + importResolver.processImportReference(importDirective, namespaceScope); } } } @@ -60,7 +60,7 @@ public class ImportsResolver { this.firstPhase = firstPhase; } - public void processImportReference(JetImportDirective importDirective, WritableScope namespaceScope, JetScope outerScope) { + public void processImportReference(JetImportDirective importDirective, WritableScope namespaceScope) { if (importDirective.isAbsoluteInRootNamespace()) { trace.report(UNSUPPORTED.on(importDirective, "TypeHierarchyResolver")); // TODO return; @@ -73,8 +73,17 @@ public class ImportsResolver { } else { assert importedReference instanceof JetSimpleNameExpression; - JetScope scope = importDirective.isAllUnder() ? namespaceScope : outerScope; - descriptors = lookupDescriptorsForSimpleNameReference((JetSimpleNameExpression) importedReference, scope); + + if (importDirective.isAllUnder()) { + // Example: import java.* + descriptors = lookupDescriptorsForSimpleNameReference((JetSimpleNameExpression) importedReference, namespaceScope); + } + else { + // Example: import IDENTIFIER + // Should be unresolved error + descriptors = lookupDescriptorsForSimpleNameReference((JetSimpleNameExpression) importedReference, JetScope.EMPTY); + trace.record(BindingContext.RESOLUTION_SCOPE, importedReference, namespaceScope); + } } JetSimpleNameExpression referenceExpression = getLastReference(importedReference); if (importDirective.isAllUnder()) { @@ -88,9 +97,7 @@ public class ImportsResolver { } if (descriptor instanceof VariableDescriptor) { JetType type = ((VariableDescriptor) descriptor).getOutType(); - if (type != null) { - namespaceScope.importScope(ScopeBoundToReceiver.create(descriptor, type.getMemberScope())); - } + namespaceScope.importScope(ScopeBoundToReceiver.create(descriptor, type.getMemberScope())); } else if (descriptor instanceof ClassDescriptor) { namespaceScope.importScope(ScopeBoundToReceiver.create(descriptor, ((ClassDescriptor) descriptor).getDefaultType().getMemberScope())); @@ -159,12 +166,13 @@ public class ImportsResolver { return lookupDescriptorsForSimpleNameReference(selector, ((NamespaceDescriptor) declarationDescriptor).getMemberScope()); } if (declarationDescriptor instanceof ClassDescriptor) { - return lookupObjectMembers(selector, lastReference, (ClassDescriptor) declarationDescriptor); + return lookupObjectMembers(selector, (ClassDescriptor) declarationDescriptor); } if (declarationDescriptor instanceof VariableDescriptor) { return lookupVariableMembers(selector, (VariableDescriptor) declarationDescriptor); } } + return Collections.emptyList(); } @@ -206,7 +214,8 @@ public class ImportsResolver { } @NotNull - private Collection lookupObjectMembers(@NotNull JetSimpleNameExpression memberReference, @NotNull JetSimpleNameExpression classReference, @NotNull ClassDescriptor classDescriptor) { + private Collection lookupObjectMembers(@NotNull JetSimpleNameExpression memberReference, + @NotNull ClassDescriptor classDescriptor) { if (firstPhase) return Collections.emptyList(); JetType classObjectType = classDescriptor.getClassObjectType(); assert classObjectType != null; @@ -230,6 +239,7 @@ public class ImportsResolver { @NotNull private Collection lookupDescriptorsForSimpleNameReference(@NotNull JetSimpleNameExpression referenceExpression, @NotNull JetScope outerScope) { + List descriptors = Lists.newArrayList(); String referencedName = referenceExpression.getReferencedName(); if (referencedName != null) { @@ -242,11 +252,10 @@ public class ImportsResolver { descriptors.addAll(outerScope.getFunctions(referencedName)); descriptors.addAll(outerScope.getProperties(referencedName)); - } if (!firstPhase) { if (descriptors.size() == 1) { - trace.record(BindingContext.REFERENCE_TARGET, referenceExpression, descriptors.iterator().next()); + trace.record(BindingContext.REFERENCE_TARGET, referenceExpression, descriptors.get(0)); } else if (descriptors.size() > 1) { trace.record(BindingContext.AMBIGUOUS_REFERENCE_TARGET, referenceExpression, descriptors); @@ -254,6 +263,11 @@ public class ImportsResolver { 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); + } } return descriptors; } diff --git a/idea/testData/completion/basic/InEmptyImport.kt b/idea/testData/completion/basic/InEmptyImport.kt new file mode 100644 index 00000000000..3d140369fed --- /dev/null +++ b/idea/testData/completion/basic/InEmptyImport.kt @@ -0,0 +1,6 @@ +package Test + +import + +// EXIST: java, javax, reflect +// ABSENT: Array, Integer \ No newline at end of file diff --git a/idea/testData/completion/basic/InImport.kt b/idea/testData/completion/basic/InImport.kt new file mode 100644 index 00000000000..b2e02557987 --- /dev/null +++ b/idea/testData/completion/basic/InImport.kt @@ -0,0 +1,9 @@ +package Test + +import java.util. + +class Test { + +} + +// EXIST: AbstractList, Date, Random, concurrent \ No newline at end of file