From 6728a384e498385f5298bd96b9d10e0f3bc09390 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Tue, 23 Dec 2014 15:18:18 +0300 Subject: [PATCH] KT-4881 Annotation resolved to package should be compile-time error #KT-4881 Fixed --- .../resolve/QualifiedExpressionResolver.java | 44 +++++++++++++++++-- .../jet/lang/resolve/TypeResolver.kt | 2 +- .../boxInline/complex/forEachLine.1.kt | 2 +- .../boxInline/complex/lambdaInLambda.1.kt | 2 +- .../tests/PackageInTypePosition.kt | 9 ++++ .../tests/PackageInTypePosition.txt | 6 +++ .../checkers/JetDiagnosticsTestGenerated.java | 6 +++ .../lang/resolve/lazy/ElementResolver.java | 2 +- .../ClassResolvedToPackage.expected.kt | 2 +- libraries/stdlib/test/js/SetJsTest.kt | 8 ++-- 10 files changed, 70 insertions(+), 13 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/PackageInTypePosition.kt create mode 100644 compiler/testData/diagnostics/tests/PackageInTypePosition.txt diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/QualifiedExpressionResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/QualifiedExpressionResolver.java index a8fbad82831..792fedd0ea0 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/QualifiedExpressionResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/QualifiedExpressionResolver.java @@ -27,6 +27,7 @@ import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.diagnostics.Errors; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.name.Name; +import org.jetbrains.jet.lang.resolve.scopes.AbstractScopeAdapter; import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue; @@ -156,8 +157,10 @@ public class QualifiedExpressionResolver { public Collection lookupDescriptorsForUserType( @NotNull JetUserType userType, @NotNull JetScope outerScope, - @NotNull BindingTrace trace + @NotNull BindingTrace trace, + boolean onlyClassifiers ) { + if (userType.isAbsoluteInRootPackage()) { trace.report(Errors.UNSUPPORTED.on(userType, "package")); return Collections.emptyList(); @@ -168,12 +171,45 @@ public class QualifiedExpressionResolver { return Collections.emptyList(); } JetUserType qualifier = userType.getQualifier(); + + // We do not want to resolve the last segment of a user type to a package + JetScope filteredScope = filterOutPackagesIfNeeded(outerScope, onlyClassifiers); + if (qualifier == null) { - return lookupDescriptorsForSimpleNameReference(referenceExpression, outerScope, outerScope, trace, LookupMode.ONLY_CLASSES_AND_PACKAGES, + return lookupDescriptorsForSimpleNameReference(referenceExpression, filteredScope, outerScope, trace, LookupMode.ONLY_CLASSES_AND_PACKAGES, false, true); } - Collection declarationDescriptors = lookupDescriptorsForUserType(qualifier, outerScope, trace); - return lookupSelectorDescriptors(referenceExpression, declarationDescriptors, trace, outerScope, LookupMode.ONLY_CLASSES_AND_PACKAGES, true); + Collection declarationDescriptors = lookupDescriptorsForUserType(qualifier, outerScope, trace, false); + return lookupSelectorDescriptors(referenceExpression, declarationDescriptors, trace, filteredScope, LookupMode.ONLY_CLASSES_AND_PACKAGES, true); + } + + private static JetScope filterOutPackagesIfNeeded(final JetScope outerScope, boolean noPackages) { + return !noPackages ? outerScope : new AbstractScopeAdapter() { + + @NotNull + @Override + protected JetScope getWorkerScope() { + return outerScope; + } + + @Nullable + @Override + public PackageViewDescriptor getPackage(@NotNull Name name) { + return null; + } + + @NotNull + @Override + public Collection getAllDescriptors() { + throw new UnsupportedOperationException("Should not be called, because it may be cached before filtering is applied"); + } + + @NotNull + @Override + public Collection getOwnDeclaredDescriptors() { + throw new UnsupportedOperationException("Should not be called, because it may be cached before filtering is applied"); + } + }; } @NotNull diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeResolver.kt b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeResolver.kt index c06d3944c3e..2d4bcd507d4 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeResolver.kt +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeResolver.kt @@ -288,7 +288,7 @@ public class TypeResolver( } public fun resolveClass(scope: JetScope, userType: JetUserType, trace: BindingTrace): ClassifierDescriptor? { - val classifierDescriptor = qualifiedExpressionResolver.lookupDescriptorsForUserType(userType, scope, trace) + val classifierDescriptor = qualifiedExpressionResolver.lookupDescriptorsForUserType(userType, scope, trace, true) .firstIsInstanceOrNull() if (classifierDescriptor != null) { ImportsResolver.reportPlatformClassMappedToKotlin(moduleDescriptor, trace, userType, classifierDescriptor) diff --git a/compiler/testData/codegen/boxInline/complex/forEachLine.1.kt b/compiler/testData/codegen/boxInline/complex/forEachLine.1.kt index 4feda8f080c..36546d0c85c 100644 --- a/compiler/testData/codegen/boxInline/complex/forEachLine.1.kt +++ b/compiler/testData/codegen/boxInline/complex/forEachLine.1.kt @@ -6,7 +6,7 @@ fun sample(): Input { return Input("Hello", "World"); } -test fun testForEachLine() { +fun testForEachLine() { val list = ArrayList() val reader = sample() diff --git a/compiler/testData/codegen/boxInline/complex/lambdaInLambda.1.kt b/compiler/testData/codegen/boxInline/complex/lambdaInLambda.1.kt index ade1b1d20cc..0b6bdfea55a 100644 --- a/compiler/testData/codegen/boxInline/complex/lambdaInLambda.1.kt +++ b/compiler/testData/codegen/boxInline/complex/lambdaInLambda.1.kt @@ -6,7 +6,7 @@ fun sample(): Input { return Input("Hello", "World"); } -test fun testForEachLine() { +fun testForEachLine() { val list = ArrayList() val reader = sample() diff --git a/compiler/testData/diagnostics/tests/PackageInTypePosition.kt b/compiler/testData/diagnostics/tests/PackageInTypePosition.kt new file mode 100644 index 00000000000..121c770ff01 --- /dev/null +++ b/compiler/testData/diagnostics/tests/PackageInTypePosition.kt @@ -0,0 +1,9 @@ +// !DIAGNOSTICS: -UNUSED_PARAMETER + +// FILE: a.kt + +package foo + +// FILE: b.kt + +foo fun bar(p: foo): foo = null!! \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/PackageInTypePosition.txt b/compiler/testData/diagnostics/tests/PackageInTypePosition.txt new file mode 100644 index 00000000000..bf0df3674f4 --- /dev/null +++ b/compiler/testData/diagnostics/tests/PackageInTypePosition.txt @@ -0,0 +1,6 @@ +package + +[ERROR : foo]() internal fun bar(/*0*/ p: [ERROR : foo]): [ERROR : foo] + +package foo { +} diff --git a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java index 9bcc864dae3..3025583202e 100644 --- a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java @@ -340,6 +340,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest { doTest(fileName); } + @TestMetadata("PackageInTypePosition.kt") + public void testPackageInTypePosition() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/PackageInTypePosition.kt"); + doTest(fileName); + } + @TestMetadata("PackageQualified.kt") public void testPackageQualified() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/PackageQualified.kt"); diff --git a/idea/ide-common/src/org/jetbrains/jet/lang/resolve/lazy/ElementResolver.java b/idea/ide-common/src/org/jetbrains/jet/lang/resolve/lazy/ElementResolver.java index 50beb430fc9..bd2c0a5a235 100644 --- a/idea/ide-common/src/org/jetbrains/jet/lang/resolve/lazy/ElementResolver.java +++ b/idea/ide-common/src/org/jetbrains/jet/lang/resolve/lazy/ElementResolver.java @@ -478,7 +478,7 @@ public abstract class ElementResolver { if (qualifier != null) { JetScope resolutionScope = getExpressionResolutionScope(resolveSession, expression); Collection descriptors = - qualifiedExpressionResolver.lookupDescriptorsForUserType(qualifier, resolutionScope, trace); + qualifiedExpressionResolver.lookupDescriptorsForUserType(qualifier, resolutionScope, trace, false); for (DeclarationDescriptor descriptor : descriptors) { if (descriptor instanceof LazyPackageDescriptor) { return ((LazyPackageDescriptor) descriptor).getMemberScope(); diff --git a/idea/testData/copyPaste/imports/ClassResolvedToPackage.expected.kt b/idea/testData/copyPaste/imports/ClassResolvedToPackage.expected.kt index a5383b9ca4c..3c0fd8f2cb8 100644 --- a/idea/testData/copyPaste/imports/ClassResolvedToPackage.expected.kt +++ b/idea/testData/copyPaste/imports/ClassResolvedToPackage.expected.kt @@ -2,7 +2,7 @@ package to import a.a -fun f(i: a.a) { +fun f(i: a) { a.a a() } \ No newline at end of file diff --git a/libraries/stdlib/test/js/SetJsTest.kt b/libraries/stdlib/test/js/SetJsTest.kt index f09e026e8d2..ad2aa9aead1 100644 --- a/libraries/stdlib/test/js/SetJsTest.kt +++ b/libraries/stdlib/test/js/SetJsTest.kt @@ -17,7 +17,7 @@ class ComplexSetJsTest : SetJsTest() { assertEquals(data, set) } - test override fun constructors() { + Test override fun constructors() { doTest() } @@ -29,7 +29,7 @@ class ComplexSetJsTest : SetJsTest() { class PrimitiveSetJsTest : SetJsTest() { override fun createEmptyMutableSet(): MutableSet = HashSet() override fun createEmptyMutableSetWithNullableValues(): MutableSet = HashSet() - test override fun constructors() { + Test override fun constructors() { HashSet() HashSet(3) HashSet(3, 0.5f) @@ -43,7 +43,7 @@ class PrimitiveSetJsTest : SetJsTest() { class LinkedHashSetTest : SetJsTest() { override fun createEmptyMutableSet(): MutableSet = LinkedHashSet() override fun createEmptyMutableSetWithNullableValues(): MutableSet = LinkedHashSet() - test override fun constructors() { + Test override fun constructors() { LinkedHashSet() LinkedHashSet(3) LinkedHashSet(3, 0.5f) @@ -186,7 +186,7 @@ abstract class SetJsTest { } } - test abstract fun constructors() + abstract fun constructors() Test fun nullAsValue() { val set = createEmptyMutableSetWithNullableValues()