diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/TopDownAnalyzerFacadeForJVM.java b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/TopDownAnalyzerFacadeForJVM.java index c260ca4d57d..84a57efbe4e 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/TopDownAnalyzerFacadeForJVM.java +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/TopDownAnalyzerFacadeForJVM.java @@ -17,7 +17,6 @@ package org.jetbrains.kotlin.resolve.jvm; import com.google.common.base.Predicate; -import com.google.common.collect.ImmutableList; import com.intellij.openapi.project.Project; import com.intellij.psi.PsiFile; import com.intellij.psi.search.GlobalSearchScope; @@ -26,16 +25,19 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.analyzer.AnalysisResult; import org.jetbrains.kotlin.builtins.KotlinBuiltIns; import org.jetbrains.kotlin.context.GlobalContext; +import org.jetbrains.kotlin.descriptors.ClassDescriptor; import org.jetbrains.kotlin.descriptors.PackageFragmentProvider; import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl; import org.jetbrains.kotlin.di.InjectorForTopDownAnalyzerForJvm; import org.jetbrains.kotlin.load.kotlin.incremental.IncrementalPackageFragmentProvider; import org.jetbrains.kotlin.load.kotlin.incremental.cache.IncrementalCache; import org.jetbrains.kotlin.load.kotlin.incremental.cache.IncrementalCacheProvider; +import org.jetbrains.kotlin.name.FqName; import org.jetbrains.kotlin.name.Name; import org.jetbrains.kotlin.platform.JavaToKotlinClassMap; import org.jetbrains.kotlin.psi.JetFile; import org.jetbrains.kotlin.resolve.BindingTrace; +import org.jetbrains.kotlin.resolve.DescriptorUtils; import org.jetbrains.kotlin.resolve.ImportPath; import org.jetbrains.kotlin.resolve.TopDownAnalysisParameters; import org.jetbrains.kotlin.resolve.lazy.declarations.FileBasedDeclarationProviderFactory; @@ -48,12 +50,23 @@ public enum TopDownAnalyzerFacadeForJVM { INSTANCE; - public static final List DEFAULT_IMPORTS = ImmutableList.of( - new ImportPath("java.lang.*"), - new ImportPath("kotlin.*"), - new ImportPath("kotlin.jvm.*"), - new ImportPath("kotlin.io.*") - ); + public static final List DEFAULT_IMPORTS = buildDefaultImports(); + + private static List buildDefaultImports() { + List list = new ArrayList(); + list.add(new ImportPath("java.lang.*")); + list.add(new ImportPath("kotlin.*")); + list.add(new ImportPath("kotlin.jvm.*")); + list.add(new ImportPath("kotlin.io.*")); + // all classes from package "kotlin" mapped to java classes are imported explicitly so that they take priority over classes from java.lang + for (ClassDescriptor descriptor : JavaToKotlinClassMap.INSTANCE.allKotlinClasses()) { + FqName fqName = DescriptorUtils.getFqNameSafe(descriptor); + if (fqName.parent().equals(new FqName("kotlin"))) { + list.add(new ImportPath(fqName, false)); + } + } + return list; + } private TopDownAnalyzerFacadeForJVM() { } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/Importer.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/Importer.kt index 1321302cc16..6854552747c 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/Importer.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/Importer.kt @@ -26,14 +26,13 @@ import java.util.ArrayList import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter import org.jetbrains.kotlin.utils.Printer -public class Importer(private val platformToKotlinClassMap: PlatformToKotlinClassMap) { +public class Importer { private val allUnderImportScopes = ArrayList() private val explicitImports = ArrayList>() public fun addAllUnderImport(descriptor: DeclarationDescriptor) { if (descriptor is PackageViewDescriptor) { - val scope = NoSubpackagesInPackageScope(descriptor) - allUnderImportScopes.add(createFilteringScope(scope, descriptor, platformToKotlinClassMap)) + allUnderImportScopes.add(NoSubpackagesInPackageScope(descriptor)) } else if (descriptor is ClassDescriptor && descriptor.getKind() != ClassKind.OBJECT) { allUnderImportScopes.add(descriptor.getStaticScope()) @@ -45,12 +44,6 @@ public class Importer(private val platformToKotlinClassMap: PlatformToKotlinClas } } - private fun createFilteringScope(scope: JetScope, descriptor: PackageViewDescriptor, platformToKotlinClassMap: PlatformToKotlinClassMap): JetScope { - val kotlinAnalogsForClassesInside = platformToKotlinClassMap.mapPlatformClassesInside(descriptor) - if (kotlinAnalogsForClassesInside.isEmpty()) return scope - return FilteringScope(scope) { descriptor -> kotlinAnalogsForClassesInside.all { it.getName() != descriptor.getName() } } - } - public fun addAliasImport(descriptor: DeclarationDescriptor, aliasName: Name) { explicitImports.add(descriptor to aliasName) } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/ImportsResolver.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/ImportsResolver.java index 8019372e023..34402baa04c 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/ImportsResolver.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/ImportsResolver.java @@ -99,7 +99,7 @@ public class ImportsResolver { ) { @NotNull JetScope rootScope = JetModuleUtil.getSubpackagesOfRootScope(module); - Importer importer = new Importer(module.getPlatformToKotlinClassMap()); + Importer importer = new Importer(); if (lookupMode == LookupMode.EVERYTHING) { fileScope.clearImports(); } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/LazyFileScope.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/LazyFileScope.kt index fcc15ce90e7..2a369a29790 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/LazyFileScope.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/LazyFileScope.kt @@ -40,7 +40,7 @@ class LazyFileScope private( debugName: String ) : ChainedScope(containingDeclaration, debugName, - *(listOf(aliasImportsScope, defaultAliasImportsScope, currentPackageMembersScope, rootPackagesScope, allUnderImportsScope, defaultAllUnderImportsScope) + additionalScopes).copyToArray()) { + *(listOf(aliasImportsScope, currentPackageMembersScope, rootPackagesScope, defaultAliasImportsScope, defaultAllUnderImportsScope, allUnderImportsScope) + additionalScopes).copyToArray()) { public fun forceResolveAllImports() { aliasImportsScope.forceResolveAllContents() diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/LazyImportScope.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/LazyImportScope.kt index cd42c855436..bfd7ddfa696 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/LazyImportScope.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/LazyImportScope.kt @@ -98,7 +98,7 @@ class LazyImportScope( val directiveImportScope = WritableScopeImpl(JetScope.Empty, containingDeclaration, RedeclarationHandler.DO_NOTHING, "Scope for import '" + directive.getDebugText() + "' resolve in " + toString()) directiveImportScope.changeLockLevel(WritableScope.LockLevel.BOTH) - val importer = Importer(resolveSession.getModuleDescriptor().platformToKotlinClassMap) + val importer = Importer() directiveUnderResolve = directive val descriptors: Collection diff --git a/compiler/testData/diagnostics/tests/imports/DefaultImportsPriority.kt b/compiler/testData/diagnostics/tests/imports/DefaultImportsPriority.kt new file mode 100644 index 00000000000..29a2c010174 --- /dev/null +++ b/compiler/testData/diagnostics/tests/imports/DefaultImportsPriority.kt @@ -0,0 +1,6 @@ +import java.lang.reflect.* +import java.util.List + +fun foo( + p1: Array /* should be resolved to kotlin.Array */, + p2: List /* should be resolved to java.util.List */) { } \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/imports/DefaultImportsPriority.txt b/compiler/testData/diagnostics/tests/imports/DefaultImportsPriority.txt new file mode 100644 index 00000000000..4bb2c5c48bc --- /dev/null +++ b/compiler/testData/diagnostics/tests/imports/DefaultImportsPriority.txt @@ -0,0 +1,3 @@ +package + +internal fun foo(/*0*/ p1: kotlin.Array, /*1*/ p2: java.util.List): kotlin.Unit diff --git a/compiler/testData/resolve/imports/ImportConflictsWithMappedToJava.resolve b/compiler/testData/resolve/imports/ImportConflictsWithMappedToJava.resolve index 2f1c0a696e4..2c1ff062c5c 100644 --- a/compiler/testData/resolve/imports/ImportConflictsWithMappedToJava.resolve +++ b/compiler/testData/resolve/imports/ImportConflictsWithMappedToJava.resolve @@ -4,8 +4,8 @@ package test import testing.custom.* -// Non default import has priority over default one. No conflicts are expected. -val a1: `custom`List? = null +// Default import has priority over on-demand ones. No conflicts are expected. +val a1: `kotlin::List`List? = null //FILE:javaUtilImport.kt //---------------------------------------------------------------------------------- @@ -13,7 +13,7 @@ package test import java.util.* -// Mapped declarations are dropped from on-demand imports. +// Default imports take over import-on-demand // TODO: Fix for lazy resolve test // val a2: 'kotlin::List'List? = null @@ -24,8 +24,8 @@ package test import testing.custom.* import java.util.* -// Mapped declarations are dropped from on-demand "java.util" import. So no conflicts are expected. -val a3: `custom`List? = null +// Default import has priority over on-demand ones. No conflicts are expected. +val a3: `kotlin::List`List? = null //FILE:singleClassImportFromJavaUtil.kt //---------------------------------------------------------------------------------- diff --git a/compiler/testData/type-checker-test.kt b/compiler/testData/type-checker-test.kt index a5b335c478e..03cbad5cb9e 100644 --- a/compiler/testData/type-checker-test.kt +++ b/compiler/testData/type-checker-test.kt @@ -29,9 +29,9 @@ class WithPredicate() { val p : Boolean } -open class List() -open class AbstractList : List -open class ArrayList() : Any, AbstractList, List +open class InvList() +open class AbstractList : InvList +open class ArrayList() : Any, AbstractList, InvList fun f() : Unit {} fun f(a : Int) : Int {a} diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java index cdfef0d997f..60450d614aa 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java @@ -4745,6 +4745,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest { doTest(fileName); } + @TestMetadata("DefaultImportsPriority.kt") + public void testDefaultImportsPriority() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/imports/DefaultImportsPriority.kt"); + doTest(fileName); + } + @TestMetadata("DontImportRootScope.kt") public void testDontImportRootScope() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/imports/DontImportRootScope.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/types/JetTypeCheckerTest.java b/compiler/tests/org/jetbrains/kotlin/types/JetTypeCheckerTest.java index e6d5cdba952..8cfd97387fe 100644 --- a/compiler/tests/org/jetbrains/kotlin/types/JetTypeCheckerTest.java +++ b/compiler/tests/org/jetbrains/kotlin/types/JetTypeCheckerTest.java @@ -304,7 +304,7 @@ public class JetTypeCheckerTest extends JetLiteFixture { assertSubtype("Derived_T", "Base_T"); assertSubtype("MDerived_T", "Base_T"); - assertSubtype("ArrayList", "List"); + assertSubtype("ArrayList", "InvList"); // assertSubtype("java.lang.Integer", "java.lang.Comparable?"); } @@ -596,7 +596,14 @@ public class JetTypeCheckerTest extends JetLiteFixture { InjectorForJavaDescriptorResolver injector = InjectorForJavaDescriptorResolverUtil.create(getProject(), trace, true); ModuleDescriptor module = injector.getModule(); for (ImportPath defaultImport : module.getDefaultImports()) { - writableScope.importScope(module.getPackage(defaultImport.fqnPart()).getMemberScope()); + FqName fqName = defaultImport.fqnPart(); + if (defaultImport.isAllUnder()) { + writableScope.importScope(module.getPackage(fqName).getMemberScope()); + } + else { + writableScope.addClassifierAlias(defaultImport.getImportedName(), + module.getPackage(fqName.parent()).getMemberScope().getClassifier(fqName.shortName())); + } } writableScope.importScope(module.getPackage(FqName.ROOT).getMemberScope()); writableScope.changeLockLevel(WritableScope.LockLevel.BOTH); diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/platform/JavaToKotlinClassMap.java b/core/descriptor.loader.java/src/org/jetbrains/kotlin/platform/JavaToKotlinClassMap.java index cd0417cfb99..3c634dbc4e7 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/platform/JavaToKotlinClassMap.java +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/platform/JavaToKotlinClassMap.java @@ -36,8 +36,9 @@ public class JavaToKotlinClassMap extends JavaToKotlinClassMapBuilder implements private final Map classDescriptorMap = new HashMap(); private final Map classDescriptorMapForCovariantPositions = new HashMap(); - private final Map primitiveTypesMap = new HashMap(); + private final Map primitiveTypesMap = new LinkedHashMap(); private final Map> packagesWithMappedClasses = new HashMap>(); + private final Set allKotlinClasses = new LinkedHashSet(); private JavaToKotlinClassMap() { init(); @@ -57,6 +58,10 @@ public class JavaToKotlinClassMap extends JavaToKotlinClassMapBuilder implements primitiveTypesMap.put(wrapperFqName.asString(), builtIns.getNullablePrimitiveJetType(primitiveType)); } primitiveTypesMap.put("void", KotlinBuiltIns.getInstance().getUnitType()); + + for (JetType type : primitiveTypesMap.values()) { + allKotlinClasses.add((ClassDescriptor)type.getConstructor().getDeclarationDescriptor()); + } } @Nullable @@ -119,6 +124,8 @@ public class JavaToKotlinClassMap extends JavaToKotlinClassMapBuilder implements packagesWithMappedClasses.put(packageFqName, classesInPackage); } classesInPackage.add(kotlinDescriptor); + + allKotlinClasses.add(kotlinDescriptor); } @NotNull @@ -155,4 +162,9 @@ public class JavaToKotlinClassMap extends JavaToKotlinClassMapBuilder implements Collection result = packagesWithMappedClasses.get(fqName.toSafe()); return result == null ? Collections.emptySet() : Collections.unmodifiableCollection(result); } + + @NotNull + public Set allKotlinClasses() { + return allKotlinClasses; + } } diff --git a/core/descriptors/src/org/jetbrains/kotlin/builtins/KotlinBuiltIns.java b/core/descriptors/src/org/jetbrains/kotlin/builtins/KotlinBuiltIns.java index 8b56d4ff2ab..e1a9891d854 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/builtins/KotlinBuiltIns.java +++ b/core/descriptors/src/org/jetbrains/kotlin/builtins/KotlinBuiltIns.java @@ -135,8 +135,6 @@ public class KotlinBuiltIns { for (PrimitiveType primitive : PrimitiveType.values()) { makePrimitive(primitive); } - - computeNonPhysicalClasses(); } private void makePrimitive(@NotNull PrimitiveType primitiveType) { @@ -476,57 +474,6 @@ public class KotlinBuiltIns { return getBuiltInClassByName("MutableListIterator"); } - /** - * Classes that only exist for the Kotlin compiler: they are erased at runtime. - * As a consequence they, for example, shouldn't be referred to by other languages - * (e.g. Java). - */ - @NotNull - public Set getNonPhysicalClasses() { - return Collections.unmodifiableSet(nonPhysicalClasses); - } - - private void computeNonPhysicalClasses() { - nonPhysicalClasses.addAll(Arrays.asList( - getAny(), - getNothing(), - - getNumber(), - getString(), - getCharSequence(), - getThrowable(), - - getIterator(), - getIterable(), - getCollection(), - getList(), - getListIterator(), - getSet(), - getMap(), - getMapEntry(), - - getMutableIterator(), - getMutableIterable(), - getMutableCollection(), - getMutableList(), - getMutableListIterator(), - getMutableSet(), - getMutableMap(), - getMutableMapEntry(), - - getDataClassAnnotation(), - getAnnotation(), - getComparable(), - getEnum(), - getArray() - )); - - for (PrimitiveType primitiveType : values()) { - nonPhysicalClasses.add(getPrimitiveClassDescriptor(primitiveType)); - nonPhysicalClasses.add(getPrimitiveArrayClassDescriptor(primitiveType)); - } - } - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // GET TYPE diff --git a/idea/src/org/jetbrains/kotlin/idea/completion/AllClassesCompletion.kt b/idea/src/org/jetbrains/kotlin/idea/completion/AllClassesCompletion.kt index e9333dbba53..bd7525118e2 100644 --- a/idea/src/org/jetbrains/kotlin/idea/completion/AllClassesCompletion.kt +++ b/idea/src/org/jetbrains/kotlin/idea/completion/AllClassesCompletion.kt @@ -20,7 +20,6 @@ import com.intellij.codeInsight.completion.* import org.jetbrains.kotlin.asJava.KotlinLightClass import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.psi.JetFile -import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.idea.project.ProjectStructureUtil import org.jetbrains.kotlin.idea.caches.KotlinIndicesHelper import org.jetbrains.kotlin.descriptors.DeclarationDescriptor @@ -28,6 +27,8 @@ import com.intellij.psi.search.GlobalSearchScope import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.idea.caches.resolve.ResolutionFacade import org.jetbrains.kotlin.descriptors.ModuleDescriptor +import org.jetbrains.kotlin.platform.JavaToKotlinClassMap +import org.jetbrains.kotlin.builtins.KotlinBuiltIns class AllClassesCompletion(val parameters: CompletionParameters, val lookupElementFactory: LookupElementFactory, @@ -39,8 +40,10 @@ class AllClassesCompletion(val parameters: CompletionParameters, val kindFilter: (ClassKind) -> Boolean, val visibilityFilter: (DeclarationDescriptor) -> Boolean) { fun collect(result: LookupElementsCollector) { - val builtIns = KotlinBuiltIns.getInstance().getNonPhysicalClasses().filter { kindFilter(it.getKind()) && prefixMatcher.prefixMatches(it.getName().asString()) } - result.addDescriptorElements(builtIns, suppressAutoInsertion = true) + //TODO: this is a temporary hack until we have built-ins in indices + val builtIns = JavaToKotlinClassMap.INSTANCE.allKotlinClasses() + listOf(KotlinBuiltIns.getInstance().getNothing()) + val filteredBuiltIns = builtIns.filter { kindFilter(it.getKind()) && prefixMatcher.prefixMatches(it.getName().asString()) } + result.addDescriptorElements(filteredBuiltIns, suppressAutoInsertion = true) val helper = KotlinIndicesHelper(scope.getProject(), resolutionFacade, bindingContext, scope, moduleDescriptor, visibilityFilter) result.addDescriptorElements(helper.getClassDescriptors({ prefixMatcher.prefixMatches(it) }, kindFilter),