From 2e420fc3129d2022fc4d854589ff5d6d7f9e36bf Mon Sep 17 00:00:00 2001 From: Valentin Kipyatkov Date: Wed, 14 Jan 2015 21:36:34 +0300 Subject: [PATCH] Conflicting imports error for imports of classes and packages --- .../jetbrains/kotlin/diagnostics/Errors.java | 2 +- .../rendering/DefaultErrorMessages.java | 1 + .../kotlin/resolve/ImportsResolver.java | 26 ++++++++++--- .../tests/imports/ExplicitImportsAmbiguity.kt | 4 +- .../ExplicitPackageImportsAmbiguity.kt | 17 +++++++++ .../ExplicitPackageImportsAmbiguity.txt | 37 +++++++++++++++++++ .../checkers/JetDiagnosticsTestGenerated.java | 6 +++ .../idea/quickfix/QuickFixRegistrar.java | 1 + 8 files changed, 85 insertions(+), 9 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/imports/ExplicitPackageImportsAmbiguity.kt create mode 100644 compiler/testData/diagnostics/tests/imports/ExplicitPackageImportsAmbiguity.txt diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java index 9e5ef59880e..5ce20193a9a 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java @@ -103,7 +103,7 @@ public interface Errors { DiagnosticFactory1 CANNOT_BE_IMPORTED = DiagnosticFactory1.create(ERROR); DiagnosticFactory0 USELESS_HIDDEN_IMPORT = DiagnosticFactory0.create(WARNING); - + DiagnosticFactory1 CONFLICTING_IMPORT = DiagnosticFactory1.create(ERROR); DiagnosticFactory0 USELESS_SIMPLE_IMPORT = DiagnosticFactory0.create(WARNING); // Modifiers diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java index c01c87dd753..7cd68141ca5 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java @@ -169,6 +169,7 @@ public class DefaultErrorMessages { MAP.put(CANNOT_IMPORT_FROM_ELEMENT, "Cannot import from ''{0}''", NAME); MAP.put(CANNOT_BE_IMPORTED, "Cannot import ''{0}'', functions and properties can be imported only from packages", NAME); MAP.put(USELESS_HIDDEN_IMPORT, "Useless import, it is hidden further"); + MAP.put(CONFLICTING_IMPORT, "Conflicting import, imported name ''{0}'' is ambiguous", STRING); MAP.put(USELESS_SIMPLE_IMPORT, "Useless import, does nothing"); MAP.put(PLATFORM_CLASS_MAPPED_TO_KOTLIN, "This class shouldn''t be used in Kotlin. Use {0} instead.", CLASSES_OR_SEPARATED); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/ImportsResolver.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/ImportsResolver.java index e3d1dffeb65..5dc798e5382 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/ImportsResolver.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/ImportsResolver.java @@ -175,13 +175,10 @@ public class ImportsResolver { ) { JetExpression importedReference = importDirective.getImportedReference(); - if (importedReference == null || resolvedTo == null) { - return; - } + if (importedReference == null || resolvedTo == null) return; + Name aliasName = JetPsiUtil.getAliasName(importDirective); - if (aliasName == null) { - return; - } + if (aliasName == null) return; boolean uselessHiddenImport = true; for (DeclarationDescriptor target : resolvedTo) { @@ -202,6 +199,23 @@ public class ImportsResolver { if (uselessHiddenImport) { trace.report(USELESS_HIDDEN_IMPORT.on(importedReference)); } + else { + if (resolvedTo.size() == 1) { + DeclarationDescriptor target = resolvedTo.iterator().next(); + if (target instanceof ClassDescriptor) { + if (fileScope.getClassifier(aliasName) == null) { + trace.report(CONFLICTING_IMPORT.on(importedReference, aliasName.asString())); + return; + } + } + else if (target instanceof PackageViewDescriptor) { + if (fileScope.getPackage(aliasName) == null) { + trace.report(CONFLICTING_IMPORT.on(importedReference, aliasName.asString())); + return; + } + } + } + } if (!importDirective.isAllUnder() && importedReference instanceof JetSimpleNameExpression && diff --git a/compiler/testData/diagnostics/tests/imports/ExplicitImportsAmbiguity.kt b/compiler/testData/diagnostics/tests/imports/ExplicitImportsAmbiguity.kt index 531567ef13f..3387bc1847f 100644 --- a/compiler/testData/diagnostics/tests/imports/ExplicitImportsAmbiguity.kt +++ b/compiler/testData/diagnostics/tests/imports/ExplicitImportsAmbiguity.kt @@ -11,7 +11,7 @@ class X // FILE: c.kt package c -import a.X -import b.X +import a.X +import b.X class Y : X \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/imports/ExplicitPackageImportsAmbiguity.kt b/compiler/testData/diagnostics/tests/imports/ExplicitPackageImportsAmbiguity.kt new file mode 100644 index 00000000000..4c0e81da140 --- /dev/null +++ b/compiler/testData/diagnostics/tests/imports/ExplicitPackageImportsAmbiguity.kt @@ -0,0 +1,17 @@ +// FILE: a.kt +package a.x + +class X + +// FILE: b.kt +package b.x + +class X + +// FILE: c.kt +package c + +import a.x +import b.x + +class Y : x.X \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/imports/ExplicitPackageImportsAmbiguity.txt b/compiler/testData/diagnostics/tests/imports/ExplicitPackageImportsAmbiguity.txt new file mode 100644 index 00000000000..fe3dd5b10cd --- /dev/null +++ b/compiler/testData/diagnostics/tests/imports/ExplicitPackageImportsAmbiguity.txt @@ -0,0 +1,37 @@ +package + +package a { + + package a.x { + + internal final class X { + public constructor X() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } + } +} + +package b { + + package b.x { + + internal final class X { + public constructor X() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } + } +} + +package c { + + internal final class Y { + public constructor Y() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } +} diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java index 493e6e4bec6..f77e8e3c6d3 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java @@ -4739,6 +4739,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest { doTest(fileName); } + @TestMetadata("ExplicitPackageImportsAmbiguity.kt") + public void testExplicitPackageImportsAmbiguity() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/imports/ExplicitPackageImportsAmbiguity.kt"); + doTest(fileName); + } + @TestMetadata("importFunctionWithAllUnderImport.kt") public void testImportFunctionWithAllUnderImport() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/imports/importFunctionWithAllUnderImport.kt"); diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixRegistrar.java b/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixRegistrar.java index d7f401a67ee..6a09e8faf09 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixRegistrar.java +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixRegistrar.java @@ -129,6 +129,7 @@ public class QuickFixRegistrar { JetSingleIntentionActionFactory removeImportFixFactory = RemovePsiElementSimpleFix.createRemoveImportFactory(); QuickFixes.factories.put(USELESS_SIMPLE_IMPORT, removeImportFixFactory); QuickFixes.factories.put(USELESS_HIDDEN_IMPORT, removeImportFixFactory); + QuickFixes.factories.put(CONFLICTING_IMPORT, removeImportFixFactory); QuickFixes.factories.put(SUPERTYPE_NOT_INITIALIZED, ChangeToConstructorInvocationFix.createFactory()); QuickFixes.factories.put(FUNCTION_CALL_EXPECTED, ChangeToFunctionInvocationFix.createFactory());