KT-6628 Allow imports of classes from root package

#KT-6628 Fixed
This commit is contained in:
Valentin Kipyatkov
2015-01-20 18:05:35 +03:00
parent fa779bbdd2
commit 77a560775f
31 changed files with 115 additions and 185 deletions
@@ -103,7 +103,6 @@ public interface Errors {
DiagnosticFactory1<JetSimpleNameExpression, DeclarationDescriptor> CANNOT_BE_IMPORTED = DiagnosticFactory1.create(ERROR);
DiagnosticFactory1<JetExpression, String> CONFLICTING_IMPORT = DiagnosticFactory1.create(ERROR);
DiagnosticFactory0<JetExpression> USELESS_SIMPLE_IMPORT = DiagnosticFactory0.create(WARNING);
// Modifiers
@@ -169,7 +169,6 @@ 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(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);
MAP.put(CANNOT_INFER_PARAMETER_TYPE,
@@ -133,7 +133,7 @@ public class ImportsResolver {
if (lookupMode == LookupMode.EVERYTHING) {
for (JetImportDirective importDirective : importDirectives) {
reportConflictingOrUselessImport(importDirective, fileScope, resolvedDirectives.get(importDirective), trace);
reportConflictingImport(importDirective, fileScope, resolvedDirectives.get(importDirective), trace);
}
}
}
@@ -167,7 +167,7 @@ public class ImportsResolver {
}
}
public static void reportConflictingOrUselessImport(
public static void reportConflictingImport(
@NotNull JetImportDirective importDirective,
@NotNull JetScope fileScope,
@Nullable Collection<? extends DeclarationDescriptor> resolvedTo,
@@ -180,26 +180,18 @@ public class ImportsResolver {
Name aliasName = JetPsiUtil.getAliasName(importDirective);
if (aliasName == null) return;
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 (resolvedTo.size() != 1) return;
DeclarationDescriptor target = resolvedTo.iterator().next();
if (target instanceof ClassDescriptor) {
if (fileScope.getClassifier(aliasName) == null) {
trace.report(CONFLICTING_IMPORT.on(importedReference, aliasName.asString()));
}
}
if (!importDirective.isAllUnder() &&
importedReference instanceof JetSimpleNameExpression &&
importDirective.getAliasName() == null) {
trace.report(USELESS_SIMPLE_IMPORT.on(importedReference));
else if (target instanceof PackageViewDescriptor) {
if (fileScope.getPackage(aliasName) == null) {
trace.report(CONFLICTING_IMPORT.on(importedReference, aliasName.asString()));
}
}
}
}
@@ -28,8 +28,8 @@ public class JetModuleUtil {
return getRootPackageScope(module, /* scopeIncludingMembers = */ false);
}
public static JetScope getImportsResolutionScope(ModuleDescriptor module, boolean inRootPackage) {
return getRootPackageScope(module, /* scopeIncludingMembers = */ inRootPackage);
public static JetScope getImportsResolutionScope(ModuleDescriptor module, boolean includeRootPackageClasses) {
return getRootPackageScope(module, /* scopeIncludingMembers = */ includeRootPackageClasses);
}
private static JetScope getRootPackageScope(ModuleDescriptor module, boolean scopeIncludingMembers) {
@@ -71,7 +71,6 @@ class LazyFileScope private(
file.getImportDirectives()
val packageView = getPackageViewDescriptor(file, resolveSession)
val inRootPackage = packageView.getFqName().isRoot()
val rootPackageView = resolveSession.getModuleDescriptor().getPackage(FqName.ROOT)
?: throw IllegalStateException("Root package not found")
val packageFragment = resolveSession.getPackageFragment(file.getPackageFqName())
@@ -79,8 +78,8 @@ class LazyFileScope private(
val onlyVisibleFilter = VisibilityFilter(packageFragment, true)
val onlyInvisibleFilter = VisibilityFilter(packageFragment, false)
val aliasImportResolver = LazyImportResolver(resolveSession, packageView, AliasImportsIndexed(imports), traceForImportResolve, inRootPackage)
val allUnderImportResolver = LazyImportResolver(resolveSession, packageView, AllUnderImportsIndexed(imports), traceForImportResolve, inRootPackage)
val aliasImportResolver = LazyImportResolver(resolveSession, packageView, AliasImportsIndexed(imports), traceForImportResolve, true)
val allUnderImportResolver = LazyImportResolver(resolveSession, packageView, AllUnderImportsIndexed(imports), traceForImportResolve, true)
val defaultAliasImportResolver = LazyImportResolver(resolveSession, rootPackageView, AliasImportsIndexed(defaultImports), traceForDefaultImportResolve, false)
val defaultAllUnderImportResolver = LazyImportResolver(resolveSession, rootPackageView, AllUnderImportsIndexed(defaultImports), traceForDefaultImportResolve, false)
@@ -68,12 +68,12 @@ class LazyImportResolver(
val packageView: PackageViewDescriptor,
val indexedImports: IndexedImports,
private val traceForImportResolve: BindingTrace,
private val inRootPackage: Boolean
includeRootPackageClasses: Boolean
) {
private val importedScopesProvider = resolveSession.getStorageManager().createMemoizedFunction {
(directive: JetImportDirective) -> ImportDirectiveResolveCache(directive)
}
private val rootScope = JetModuleUtil.getImportsResolutionScope(resolveSession.getModuleDescriptor(), inRootPackage)
private val rootScope = JetModuleUtil.getImportsResolutionScope(resolveSession.getModuleDescriptor(), includeRootPackageClasses)
private var directiveUnderResolve: JetImportDirective? = null
@@ -135,7 +135,7 @@ class LazyImportResolver(
val status = importedScopesProvider(importDirective).importResolveStatus
if (status != null && !status.descriptors.isEmpty()) {
val fileScope = resolveSession.getScopeProvider().getFileScope(importDirective.getContainingJetFile())
ImportsResolver.reportConflictingOrUselessImport(importDirective, fileScope, status.descriptors, traceForImportResolve)
ImportsResolver.reportConflictingImport(importDirective, fileScope, status.descriptors, traceForImportResolve)
}
}
@@ -1,25 +0,0 @@
// FILE: rootPackage.kt
class Klass {
}
fun function() = ""
val property = ""
// FILE: anotherFromRootPackage.kt
fun foo() {
Klass()
function() + property
}
// FILE: anotherFromRootPackage.kt
package pkg
import <!UNRESOLVED_REFERENCE!>Klass<!>
import <!UNRESOLVED_REFERENCE!>function<!>
import <!UNRESOLVED_REFERENCE!>property<!>
fun foo() {
<!UNRESOLVED_REFERENCE!>Klass<!>()
<!UNRESOLVED_REFERENCE!>function<!>() <!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>+<!> <!UNRESOLVED_REFERENCE!>property<!>
}
@@ -0,0 +1,25 @@
// FILE: rootPackage.kt
class Klass {
}
fun function() = ""
val property = ""
// FILE: anotherFromRootPackage.kt
fun foo(): Klass {
function() + property
return Klass()
}
// FILE: anotherFromRootPackage.kt
package pkg
import Klass
import function
import property
fun foo(): Klass {
function() + property
return Klass()
}
@@ -1,7 +1,7 @@
package
internal val property: kotlin.String = ""
internal fun foo(): kotlin.Unit
internal fun foo(): Klass
internal fun function(): kotlin.String
internal final class Klass {
@@ -12,5 +12,5 @@ internal final class Klass {
}
package pkg {
internal fun foo(): kotlin.Unit
internal fun foo(): Klass
}
@@ -1,5 +0,0 @@
package a
import <!USELESS_SIMPLE_IMPORT!>a<!>
object B {}
@@ -1,18 +0,0 @@
package
package a {
internal object B {
private constructor B()
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
public class object <class-object-for-B> : a.B {
private constructor <class-object-for-B>()
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
}
}
}
@@ -1,9 +0,0 @@
// FILE:a.kt
package a
import <!USELESS_SIMPLE_IMPORT!>b<!>
// FILE:b.kt
package b
class B()
@@ -1,14 +0,0 @@
package
package a {
}
package b {
internal final class B {
public constructor B()
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
}
}
@@ -6,5 +6,5 @@ public class Ccc extends Bbb {
}
//FILE: Ddd.kt
import <!USELESS_SIMPLE_IMPORT!>Ccc<!>
import Ccc
@@ -16,13 +16,13 @@ fun foo() {
// FILE: otherPackage.kt
package test
import `!`Klass
import `!`function
import `!`property
import `k`Klass
import `f`function
import `p`property
fun foo() {
`!`Klass()
`!`function()
`!`property
`k`Klass()
`f`function()
`p`property
}
@@ -21,9 +21,9 @@ fun foo() {
// FILE: nonRoot.kt
package nonRoot
import java.lang.* // will not import Fake
import java.lang.* // will import Fake
fun foo() {
`!`Fake()
java.lang.`!`Fake() // qualification doesn't help, because we are in other package
`Fake`Fake()
java.lang.`!`Fake() // qualified access to root package's class does not work
}
@@ -4751,12 +4751,6 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
doTest(fileName);
}
@TestMetadata("DontImportRootScope.kt")
public void testDontImportRootScope() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/imports/DontImportRootScope.kt");
doTest(fileName);
}
@TestMetadata("ExplicitImportsAmbiguity.kt")
public void testExplicitImportsAmbiguity() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/imports/ExplicitImportsAmbiguity.kt");
@@ -4781,6 +4775,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
doTest(fileName);
}
@TestMetadata("ImportFromRootPackage.kt")
public void testImportFromRootPackage() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/imports/ImportFromRootPackage.kt");
doTest(fileName);
}
@TestMetadata("importFunctionWithAllUnderImport.kt")
public void testImportFunctionWithAllUnderImport() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/imports/importFunctionWithAllUnderImport.kt");
@@ -4847,18 +4847,6 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
doTest(fileName);
}
@TestMetadata("ImportsUselessSimpleImport.kt")
public void testImportsUselessSimpleImport() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/imports/ImportsUselessSimpleImport.kt");
doTest(fileName);
}
@TestMetadata("ImportsUselessSimpleImport2.kt")
public void testImportsUselessSimpleImport2() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/imports/ImportsUselessSimpleImport2.kt");
doTest(fileName);
}
@TestMetadata("JavaPackageLocalClassNotImported.kt")
public void testJavaPackageLocalClassNotImported() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/imports/JavaPackageLocalClassNotImported.kt");
@@ -61,12 +61,6 @@ public class ResolveTestGenerated extends AbstractResolveTest {
doTest(fileName);
}
@TestMetadata("DontImportRootScope.resolve")
public void testDontImportRootScope() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/resolve/DontImportRootScope.resolve");
doTest(fileName);
}
@TestMetadata("ErrorSupertype.resolve")
public void testErrorSupertype() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/resolve/ErrorSupertype.resolve");
@@ -85,6 +79,12 @@ public class ResolveTestGenerated extends AbstractResolveTest {
doTest(fileName);
}
@TestMetadata("ImportFromRootScope.resolve")
public void testImportFromRootScope() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/resolve/ImportFromRootScope.resolve");
doTest(fileName);
}
@TestMetadata("ImportingRootScopeWhenProcessingImports.resolve")
public void testImportingRootScopeWhenProcessingImports() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/resolve/ImportingRootScopeWhenProcessingImports.resolve");
@@ -36,8 +36,8 @@ remove.type.arguments=Remove type arguments
remove.useless.nullable=Remove useless '?'
remove.nullable.family=Remove '?'
remove.spread.sign=Remove '*'
remove.useless.import=Remove useless import for ''{0}''
remove.useless.import.family=Remove Useless Import
remove.conflicting.import=Remove conflicting import for ''{0}''
remove.conflicting.import.family=Remove Conflicting Import
replace.operation.in.binary.expression=Replace operation in a binary expression
replace.cast.with.static.assert=Replace a cast with a static assert
replace.with.dot.call=Replace with dot call
@@ -127,7 +127,6 @@ public class QuickFixRegistrar {
QuickFixes.factories.put(UNRESOLVED_REFERENCE_WRONG_RECEIVER, unresolvedReferenceFactory);
JetSingleIntentionActionFactory removeImportFixFactory = RemovePsiElementSimpleFix.createRemoveImportFactory();
QuickFixes.factories.put(USELESS_SIMPLE_IMPORT, removeImportFixFactory);
QuickFixes.factories.put(CONFLICTING_IMPORT, removeImportFixFactory);
QuickFixes.factories.put(SUPERTYPE_NOT_INITIALIZED, ChangeToConstructorInvocationFix.createFactory());
@@ -66,10 +66,10 @@ public class RemovePsiElementSimpleFix extends JetIntentionAction<PsiElement> {
JetExpression exp = directive.getImportedReference();
if (exp != null) {
return new RemovePsiElementSimpleFix(directive,
JetBundle.message("remove.useless.import", exp.getText()));
JetBundle.message("remove.conflicting.import", exp.getText()));
}
return new RemovePsiElementSimpleFix(directive,
JetBundle.message("remove.useless.import",""));
JetBundle.message("remove.conflicting.import",""));
}
}
};
@@ -2,7 +2,7 @@ import testData.libraries.*
fun foo() {
processDouble(1.0);
processDouble(Double())
processDouble(testData.libraries.Double())
}
// main.kt
@@ -0,0 +1,8 @@
// "Remove conflicting import for 'java.util.ArrayList'" "true"
package test
import java.util.HashMap as ArrayList
fun foo(a : ArrayList<String, String>) {
}
@@ -0,0 +1,9 @@
// "Remove conflicting import for 'java.util.ArrayList'" "true"
package test
import java.util.ArrayList<caret>
import java.util.HashMap as ArrayList
fun foo(a : ArrayList<String, String>) {
}
@@ -1,8 +0,0 @@
// "Remove useless import for 'test'" "true"
package test
import org.jetbrains
fun main(args : Array<String>) {
}
@@ -1,9 +0,0 @@
// "Remove useless import for 'test'" "true"
package test
import org.jetbrains
import test<caret>
fun main(args : Array<String>) {
}
@@ -1,8 +1,8 @@
package nonRoot
import java.lang.* // will not import Fake
import java.lang.*
fun foo() {
<caret>Fake()
}
//REF_EMPTY
//REF: (java.lang).Fake
@@ -2,4 +2,4 @@ package test
import <caret>Klass
//REF_EMPTY
//REF: (<root>).Klass
@@ -30,7 +30,7 @@ import java.util.regex.Pattern;
@SuppressWarnings("all")
@TestMetadata("idea/testData/quickfix")
@TestDataPath("$PROJECT_ROOT")
@InnerTestClasses({QuickFixTestGenerated.Abstract.class, QuickFixTestGenerated.AddStarProjections.class, QuickFixTestGenerated.AutoImports.class, QuickFixTestGenerated.ChangeSignature.class, QuickFixTestGenerated.CheckArguments.class, QuickFixTestGenerated.CreateFromUsage.class, QuickFixTestGenerated.Expressions.class, QuickFixTestGenerated.Migration.class, QuickFixTestGenerated.Modifiers.class, QuickFixTestGenerated.Nullables.class, QuickFixTestGenerated.Override.class, QuickFixTestGenerated.PlatformClasses.class, QuickFixTestGenerated.Supercalls.class, QuickFixTestGenerated.SupertypeInitialization.class, QuickFixTestGenerated.Suppress.class, QuickFixTestGenerated.TypeAddition.class, QuickFixTestGenerated.TypeImports.class, QuickFixTestGenerated.TypeMismatch.class, QuickFixTestGenerated.TypeProjection.class, QuickFixTestGenerated.UselessImports.class, QuickFixTestGenerated.Variables.class, QuickFixTestGenerated.When.class})
@InnerTestClasses({QuickFixTestGenerated.Abstract.class, QuickFixTestGenerated.AddStarProjections.class, QuickFixTestGenerated.AutoImports.class, QuickFixTestGenerated.ChangeSignature.class, QuickFixTestGenerated.CheckArguments.class, QuickFixTestGenerated.ConflictingImports.class, QuickFixTestGenerated.CreateFromUsage.class, QuickFixTestGenerated.Expressions.class, QuickFixTestGenerated.Migration.class, QuickFixTestGenerated.Modifiers.class, QuickFixTestGenerated.Nullables.class, QuickFixTestGenerated.Override.class, QuickFixTestGenerated.PlatformClasses.class, QuickFixTestGenerated.Supercalls.class, QuickFixTestGenerated.SupertypeInitialization.class, QuickFixTestGenerated.Suppress.class, QuickFixTestGenerated.TypeAddition.class, QuickFixTestGenerated.TypeImports.class, QuickFixTestGenerated.TypeMismatch.class, QuickFixTestGenerated.TypeProjection.class, QuickFixTestGenerated.Variables.class, QuickFixTestGenerated.When.class})
@RunWith(JUnit3RunnerWithInners.class)
public class QuickFixTestGenerated extends AbstractQuickFixTest {
public void testAllFilesPresentInQuickfix() throws Exception {
@@ -617,6 +617,21 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
}
}
@TestMetadata("idea/testData/quickfix/conflictingImports")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class ConflictingImports extends AbstractQuickFixTest {
public void testAllFilesPresentInConflictingImports() throws Exception {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/quickfix/conflictingImports"), Pattern.compile("^before(\\w+)\\.kt$"), true);
}
@TestMetadata("beforeRemoveConflictingImport.kt")
public void testRemoveConflictingImport() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/conflictingImports/beforeRemoveConflictingImport.kt");
doTest(fileName);
}
}
@TestMetadata("idea/testData/quickfix/createFromUsage")
@TestDataPath("$PROJECT_ROOT")
@InnerTestClasses({CreateFromUsage.CreateClass.class, CreateFromUsage.CreateFunction.class, CreateFromUsage.CreateVariable.class})
@@ -4641,21 +4656,6 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
}
}
@TestMetadata("idea/testData/quickfix/uselessImports")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class UselessImports extends AbstractQuickFixTest {
public void testAllFilesPresentInUselessImports() throws Exception {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/quickfix/uselessImports"), Pattern.compile("^before(\\w+)\\.kt$"), true);
}
@TestMetadata("beforeRemoveUselessImport.kt")
public void testRemoveUselessImport() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/uselessImports/beforeRemoveUselessImport.kt");
doTest(fileName);
}
}
@TestMetadata("idea/testData/quickfix/variables")
@TestDataPath("$PROJECT_ROOT")
@InnerTestClasses({Variables.ChangeMutability.class, Variables.ChangeToBackingField.class, Variables.ChangeToFunctionInvocation.class, Variables.ChangeToPropertyName.class, Variables.RemoveValVarFromParameter.class})
@@ -97,12 +97,6 @@ public class ReferenceResolveTestGenerated extends AbstractReferenceResolveTest
doTest(fileName);
}
@TestMetadata("DontImportRootScope.kt")
public void testDontImportRootScope() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/resolve/references/DontImportRootScope.kt");
doTest(fileName);
}
@TestMetadata("EnumValues.kt")
public void testEnumValues() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/resolve/references/EnumValues.kt");
@@ -145,6 +139,12 @@ public class ReferenceResolveTestGenerated extends AbstractReferenceResolveTest
doTest(fileName);
}
@TestMetadata("ImportFromRootScope.kt")
public void testImportFromRootScope() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/resolve/references/ImportFromRootScope.kt");
doTest(fileName);
}
@TestMetadata("InClassParameter.kt")
public void testInClassParameter() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/resolve/references/InClassParameter.kt");