diff --git a/generators/src/org/jetbrains/kotlin/generators/tests/GenerateTests.kt b/generators/src/org/jetbrains/kotlin/generators/tests/GenerateTests.kt index 6ebe2aa9e1a..d8257839f26 100755 --- a/generators/src/org/jetbrains/kotlin/generators/tests/GenerateTests.kt +++ b/generators/src/org/jetbrains/kotlin/generators/tests/GenerateTests.kt @@ -1116,7 +1116,7 @@ fun main(args: Array) { } testClass { - model("handlers/basic") + model("handlers/basic", pattern = KT_WITHOUT_DOTS_IN_NAME) } testClass { diff --git a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/BasicCompletionSession.kt b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/BasicCompletionSession.kt index 56b32c83eba..2709895596d 100644 --- a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/BasicCompletionSession.kt +++ b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/BasicCompletionSession.kt @@ -21,6 +21,8 @@ import com.intellij.codeInsight.completion.* import com.intellij.codeInsight.completion.impl.BetterPrefixMatcher import com.intellij.codeInsight.lookup.LookupElement import com.intellij.codeInsight.lookup.LookupElementBuilder +import com.intellij.codeInsight.lookup.LookupElementDecorator +import com.intellij.codeInsight.lookup.LookupElementPresentation import com.intellij.codeInsight.template.TemplateManager import com.intellij.patterns.PatternCondition import com.intellij.patterns.StandardPatterns @@ -29,16 +31,26 @@ import com.intellij.psi.impl.source.tree.LeafPsiElement import com.intellij.psi.search.GlobalSearchScope import com.intellij.util.ProcessingContext import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.idea.analysis.analyzeInContext +import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptor +import org.jetbrains.kotlin.idea.codeInsight.ReferenceVariantsHelper import org.jetbrains.kotlin.idea.completion.handlers.createKeywordConstructLookupElement import org.jetbrains.kotlin.idea.completion.smart.ExpectedInfoMatch import org.jetbrains.kotlin.idea.completion.smart.SMART_COMPLETION_ITEM_PRIORITY_KEY import org.jetbrains.kotlin.idea.completion.smart.SmartCompletion import org.jetbrains.kotlin.idea.completion.smart.SmartCompletionItemPriority import org.jetbrains.kotlin.idea.core.ExpectedInfo +import org.jetbrains.kotlin.idea.core.NotPropertiesService +import org.jetbrains.kotlin.idea.core.completion.DeclarationLookupObject +import org.jetbrains.kotlin.idea.imports.importableFqName import org.jetbrains.kotlin.idea.project.TargetPlatformDetector +import org.jetbrains.kotlin.idea.references.KtSimpleNameReference.ShorteningMode.FORCED_SHORTENING +import org.jetbrains.kotlin.idea.references.mainReference import org.jetbrains.kotlin.idea.stubindex.PackageIndexUtil import org.jetbrains.kotlin.idea.util.CallTypeAndReceiver +import org.jetbrains.kotlin.idea.util.getResolutionScope import org.jetbrains.kotlin.lexer.KtTokens +import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor import org.jetbrains.kotlin.load.java.sam.SamConstructorDescriptor import org.jetbrains.kotlin.load.java.sam.SamConstructorDescriptorKindExclude import org.jetbrains.kotlin.name.FqName @@ -47,11 +59,16 @@ import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.* import org.jetbrains.kotlin.renderer.render import org.jetbrains.kotlin.resolve.BindingContext +import org.jetbrains.kotlin.resolve.descriptorUtil.* import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode import org.jetbrains.kotlin.resolve.scopes.DescriptorKindExclude import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter +import org.jetbrains.kotlin.resolve.scopes.ExplicitImportsScope +import org.jetbrains.kotlin.resolve.scopes.utils.addImportingScope +import org.jetbrains.kotlin.util.kind import org.jetbrains.kotlin.util.supertypesWithAny +import org.jetbrains.kotlin.utils.addIfNotNull import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull import java.util.* @@ -340,6 +357,110 @@ class BasicCompletionSession( addClassesFromIndex(classKindFilter, includeTypeAliases, prefixMatcher) } } + else if (callTypeAndReceiver is CallTypeAndReceiver.DOT) { + val qualifier = bindingContext[BindingContext.QUALIFIER, callTypeAndReceiver.receiver] + if (qualifier != null) return + val receiver = callTypeAndReceiver.receiver as? KtSimpleNameExpression ?: return + + val helper = indicesHelper(false) + + val descriptors = mutableListOf() + + val fullTextPrefixMatcher = object : PrefixMatcher(receiver.getReferencedName()) { + override fun prefixMatches(name: String): Boolean = name == prefix + + override fun cloneWithPrefix(prefix: String): PrefixMatcher { + throw UnsupportedOperationException("Not implemented") + } + } + + AllClassesCompletion(parameters.withPosition(receiver, receiver.startOffset), helper, fullTextPrefixMatcher, resolutionFacade, + { true }, true, configuration.javaClassesNotToBeUsed + ).collect({ descriptors += it }, { descriptors.addIfNotNull(it.resolveToDescriptor(resolutionFacade)) }) + + val foundDescriptors = mutableSetOf() + descriptors.asSequence() + .filter { + it.kind == ClassKind.OBJECT || + it.kind == ClassKind.ENUM_CLASS || + it.kind == ClassKind.ENUM_ENTRY || + it.hasCompanionObject || + it is JavaClassDescriptor + } + .forEach { classifier -> + val scope = nameExpression?.getResolutionScope(bindingContext) ?: return + + val desc = classifier.getImportableDescriptor() + val newScope = scope.addImportingScope(ExplicitImportsScope(listOf(desc))) + + val newContext = (nameExpression.parent as KtExpression).analyzeInContext(newScope) + + val rvHelper = ReferenceVariantsHelper(newContext, + resolutionFacade, + moduleDescriptor, + isVisibleFilter, + NotPropertiesService.getNotProperties(position)) + val rvCollector = ReferenceVariantsCollector(rvHelper, indicesHelper(true), prefixMatcher, + nameExpression, callTypeAndReceiver, resolutionFacade, newContext, + importableFqNameClassifier, configuration) + + val receiverTypes = detectReceiverTypes(newContext, nameExpression, callTypeAndReceiver) + + val factory = lookupElementFactory.copy(receiverTypes = receiverTypes, standardLookupElementsPostProcessor = { + + lookupElement -> + val lookupDescriptor = (lookupElement.`object` as? DeclarationLookupObject) + ?.descriptor as? MemberDescriptor ?: return@copy lookupElement + + if (!desc.isAncestorOf(lookupDescriptor, false)) return@copy lookupElement + + if (lookupDescriptor is CallableMemberDescriptor && + lookupDescriptor.isExtension && + lookupDescriptor.extensionReceiverParameter?.importableFqName != desc.fqNameSafe) { + return@copy lookupElement + } + + val fqNameToImport = lookupDescriptor.containingDeclaration.importableFqName ?: return@copy lookupElement + + object : LookupElementDecorator(lookupElement) { + val name = fqNameToImport.shortName() + val packageName = fqNameToImport.parent() + + override fun handleInsert(context: InsertionContext) { + super.handleInsert(context) + context.commitDocument() + val file = context.file as? KtFile + if (file != null) { + val receiverInFile = file.findElementAt(receiver.startOffset)?.getParentOfType(false) ?: return + receiverInFile.mainReference.bindToFqName(fqNameToImport, FORCED_SHORTENING) + } + } + + override fun renderElement(presentation: LookupElementPresentation?) { + super.renderElement(presentation) + presentation?.appendTailText(" for $name in $packageName", true) + } + } + }) + + + rvCollector.collectReferenceVariants(descriptorKindFilter) { (imported, notImportedExtensions) -> + + val unique = imported.asSequence() + .filterNot { it.original in foundDescriptors } + .onEach { foundDescriptors += it.original } + + val uniqueNotImportedExtensions = notImportedExtensions.asSequence() + .filterNot { it.original in foundDescriptors } + .onEach { foundDescriptors += it.original } + + collector.addDescriptorElements(unique.toList(), factory) + collector.addDescriptorElements(uniqueNotImportedExtensions.toList(), factory, notImported = true) + + flushToResultSet() + } + } + } } private fun isStartOfExtensionReceiverFor(): KtCallableDeclaration? { diff --git a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/CompletionSession.kt b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/CompletionSession.kt index faad46e5bce..d7576a7b726 100644 --- a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/CompletionSession.kt +++ b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/CompletionSession.kt @@ -39,9 +39,9 @@ import org.jetbrains.kotlin.idea.project.TargetPlatformDetector import org.jetbrains.kotlin.idea.references.mainReference import org.jetbrains.kotlin.idea.util.* import org.jetbrains.kotlin.psi.* +import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.descriptorUtil.module import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform -import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver import org.jetbrains.kotlin.types.TypeUtils @@ -127,14 +127,9 @@ abstract class CompletionSession( isVisibleFilter, NotPropertiesService.getNotProperties(position)) - protected val callTypeAndReceiver: CallTypeAndReceiver<*, *> - protected val receiverTypes: Collection? + protected val callTypeAndReceiver = if (nameExpression == null) CallTypeAndReceiver.UNKNOWN else CallTypeAndReceiver.detect(nameExpression) + protected val receiverTypes = nameExpression?.let { detectReceiverTypes(bindingContext, nameExpression, callTypeAndReceiver) } - init { - val (callTypeAndReceiver, receiverTypes) = detectCallTypeAndReceiverTypes() - this.callTypeAndReceiver = callTypeAndReceiver - this.receiverTypes = receiverTypes - } protected val basicLookupElementFactory = BasicLookupElementFactory(project, InsertHandlerProvider(callTypeAndReceiver.callType) { expectedInfos }) @@ -374,13 +369,9 @@ abstract class CompletionSession( callTypeAndReceiver.callType, inDescriptor, contextVariablesProvider) } - private fun detectCallTypeAndReceiverTypes(): Pair, Collection?> { - if (nameExpression == null) { - return CallTypeAndReceiver.UNKNOWN to null - } - - val callTypeAndReceiver = CallTypeAndReceiver.detect(nameExpression) - + protected fun detectReceiverTypes(bindingContext: BindingContext, + nameExpression: KtSimpleNameExpression, + callTypeAndReceiver: CallTypeAndReceiver<*, *>): Collection? { var receiverTypes = callTypeAndReceiver.receiverTypesWithIndex( bindingContext, nameExpression, moduleDescriptor, resolutionFacade, stableSmartCastsOnly = true /* we don't include smart cast receiver types for "unstable" receiver value to mark members grayed */) @@ -389,6 +380,6 @@ abstract class CompletionSession( receiverTypes = receiverTypes?.map { ReceiverType(it.type.makeNotNullable(), it.receiverIndex) } } - return callTypeAndReceiver to receiverTypes + return receiverTypes } } diff --git a/idea/idea-completion/testData/basic/multifile/EntriesOfNotImportedEnumFromKotlin/EntriesOfNotImportedEnumFromKotlin.dependency.kt b/idea/idea-completion/testData/basic/multifile/EntriesOfNotImportedEnumFromKotlin/EntriesOfNotImportedEnumFromKotlin.dependency.kt new file mode 100644 index 00000000000..7f8646a9e88 --- /dev/null +++ b/idea/idea-completion/testData/basic/multifile/EntriesOfNotImportedEnumFromKotlin/EntriesOfNotImportedEnumFromKotlin.dependency.kt @@ -0,0 +1,7 @@ +package foo + +enum class Color { + RED, GREEN, BLUE +} + +// ALLOW_AST_ACCESS \ No newline at end of file diff --git a/idea/idea-completion/testData/basic/multifile/EntriesOfNotImportedEnumFromKotlin/EntriesOfNotImportedEnumFromKotlin.kt b/idea/idea-completion/testData/basic/multifile/EntriesOfNotImportedEnumFromKotlin/EntriesOfNotImportedEnumFromKotlin.kt new file mode 100644 index 00000000000..24d7e792537 --- /dev/null +++ b/idea/idea-completion/testData/basic/multifile/EntriesOfNotImportedEnumFromKotlin/EntriesOfNotImportedEnumFromKotlin.kt @@ -0,0 +1,12 @@ +package bar + +fun buz() { + Color. +} + +// EXIST: RED +// EXIST: GREEN +// EXIST: BLUE +// EXIST: values +// EXIST: valueOf +// NOTHING_ELSE diff --git a/idea/idea-completion/testData/basic/multifile/StaticMembersOfNotImportedClassFromJava/StaticMembersOfNotImportedClassFromJava.kt b/idea/idea-completion/testData/basic/multifile/StaticMembersOfNotImportedClassFromJava/StaticMembersOfNotImportedClassFromJava.kt new file mode 100644 index 00000000000..ac4201cb4db --- /dev/null +++ b/idea/idea-completion/testData/basic/multifile/StaticMembersOfNotImportedClassFromJava/StaticMembersOfNotImportedClassFromJava.kt @@ -0,0 +1,11 @@ +package bar + +fun buz { + SomeClass. +} + +// EXIST: CONST_A +// EXIST: aProc +// EXIST: getA +// EXIST: FooBar +// NOTHING_ELSE \ No newline at end of file diff --git a/idea/idea-completion/testData/basic/multifile/StaticMembersOfNotImportedClassFromJava/javapackage/SomeClass.java b/idea/idea-completion/testData/basic/multifile/StaticMembersOfNotImportedClassFromJava/javapackage/SomeClass.java new file mode 100644 index 00000000000..fc3bd8c7b07 --- /dev/null +++ b/idea/idea-completion/testData/basic/multifile/StaticMembersOfNotImportedClassFromJava/javapackage/SomeClass.java @@ -0,0 +1,17 @@ +package javapackage; + +public class SomeClass { + public static void aProc() { + + } + + public static String getA() { + return CONST_A; + } + + public static final String CONST_A = "A"; + + public static class FooBar { + + } +} \ No newline at end of file diff --git a/idea/idea-completion/testData/basic/multifile/StaticMembersOfNotImportedClassFromKotlin/StaticMembersOfNotImportedClassFromKotlin.dependency.kt b/idea/idea-completion/testData/basic/multifile/StaticMembersOfNotImportedClassFromKotlin/StaticMembersOfNotImportedClassFromKotlin.dependency.kt new file mode 100644 index 00000000000..38ff29e78a6 --- /dev/null +++ b/idea/idea-completion/testData/basic/multifile/StaticMembersOfNotImportedClassFromKotlin/StaticMembersOfNotImportedClassFromKotlin.dependency.kt @@ -0,0 +1,15 @@ +package foo + +class Bar { + companion object { + fun bfun() {} + val bval = 99 + const val bconst = 100 + } + + class FooBar { + + } +} + +// ALLOW_AST_ACCESS \ No newline at end of file diff --git a/idea/idea-completion/testData/basic/multifile/StaticMembersOfNotImportedClassFromKotlin/StaticMembersOfNotImportedClassFromKotlin.kt b/idea/idea-completion/testData/basic/multifile/StaticMembersOfNotImportedClassFromKotlin/StaticMembersOfNotImportedClassFromKotlin.kt new file mode 100644 index 00000000000..798583ad1fb --- /dev/null +++ b/idea/idea-completion/testData/basic/multifile/StaticMembersOfNotImportedClassFromKotlin/StaticMembersOfNotImportedClassFromKotlin.kt @@ -0,0 +1,15 @@ +package bar + +fun buz() { + Bar. +} + +// EXIST: bconst +// EXIST: bval +// EXIST: Companion +// EXIST: FooBar +// EXIST: bfun +// EXIST: toString +// EXIST: hashCode +// EXIST: equals +// NOTHING_ELSE diff --git a/idea/idea-completion/testData/basic/multifile/StaticMembersOfNotImportedClassFromKotlinObject/StaticMembersOfNotImportedClassFromKotlinObject.dependency.kt b/idea/idea-completion/testData/basic/multifile/StaticMembersOfNotImportedClassFromKotlinObject/StaticMembersOfNotImportedClassFromKotlinObject.dependency.kt new file mode 100644 index 00000000000..b2e95167789 --- /dev/null +++ b/idea/idea-completion/testData/basic/multifile/StaticMembersOfNotImportedClassFromKotlinObject/StaticMembersOfNotImportedClassFromKotlinObject.dependency.kt @@ -0,0 +1,14 @@ +package foo + +object Bar { + + fun bfun() {} + val bval = 99 + const val bconst = 100 + + class FooBar { + + } +} + +// ALLOW_AST_ACCESS \ No newline at end of file diff --git a/idea/idea-completion/testData/basic/multifile/StaticMembersOfNotImportedClassFromKotlinObject/StaticMembersOfNotImportedClassFromKotlinObject.kt b/idea/idea-completion/testData/basic/multifile/StaticMembersOfNotImportedClassFromKotlinObject/StaticMembersOfNotImportedClassFromKotlinObject.kt new file mode 100644 index 00000000000..4c681dfb348 --- /dev/null +++ b/idea/idea-completion/testData/basic/multifile/StaticMembersOfNotImportedClassFromKotlinObject/StaticMembersOfNotImportedClassFromKotlinObject.kt @@ -0,0 +1,14 @@ +package bar + +fun buz() { + Bar. +} + +// EXIST: bconst +// EXIST: bval +// EXIST: FooBar +// EXIST: bfun +// EXIST: toString +// EXIST: hashCode +// EXIST: equals +// NOTHING_ELSE diff --git a/idea/idea-completion/testData/basic/multifile/StaticMembersOfNotImportedClassNameConflict/StaticMembersOfNotImportedClassNameConflict.dependency.kt b/idea/idea-completion/testData/basic/multifile/StaticMembersOfNotImportedClassNameConflict/StaticMembersOfNotImportedClassNameConflict.dependency.kt new file mode 100644 index 00000000000..62eba6c8643 --- /dev/null +++ b/idea/idea-completion/testData/basic/multifile/StaticMembersOfNotImportedClassNameConflict/StaticMembersOfNotImportedClassNameConflict.dependency.kt @@ -0,0 +1,13 @@ +package foo + +class Bar { + companion object { + fun inFooPackage() {} + } + + class Foo { + + } +} + +// ALLOW_AST_ACCESS \ No newline at end of file diff --git a/idea/idea-completion/testData/basic/multifile/StaticMembersOfNotImportedClassNameConflict/StaticMembersOfNotImportedClassNameConflict.dependency1.kt b/idea/idea-completion/testData/basic/multifile/StaticMembersOfNotImportedClassNameConflict/StaticMembersOfNotImportedClassNameConflict.dependency1.kt new file mode 100644 index 00000000000..bb47f46e1e0 --- /dev/null +++ b/idea/idea-completion/testData/basic/multifile/StaticMembersOfNotImportedClassNameConflict/StaticMembersOfNotImportedClassNameConflict.dependency1.kt @@ -0,0 +1,13 @@ +package foobar + +class Bar { + companion object { + fun inFooBarPackage() {} + } + + class FooBar { + + } +} + +// ALLOW_AST_ACCESS \ No newline at end of file diff --git a/idea/idea-completion/testData/basic/multifile/StaticMembersOfNotImportedClassNameConflict/StaticMembersOfNotImportedClassNameConflict.dependency2.kt b/idea/idea-completion/testData/basic/multifile/StaticMembersOfNotImportedClassNameConflict/StaticMembersOfNotImportedClassNameConflict.dependency2.kt new file mode 100644 index 00000000000..974683066e3 --- /dev/null +++ b/idea/idea-completion/testData/basic/multifile/StaticMembersOfNotImportedClassNameConflict/StaticMembersOfNotImportedClassNameConflict.dependency2.kt @@ -0,0 +1,12 @@ +package bar + +object Bar { + + fun inBarPackage() {} + + class Bar { + + } +} + +// ALLOW_AST_ACCESS \ No newline at end of file diff --git a/idea/idea-completion/testData/basic/multifile/StaticMembersOfNotImportedClassNameConflict/StaticMembersOfNotImportedClassNameConflict.kt b/idea/idea-completion/testData/basic/multifile/StaticMembersOfNotImportedClassNameConflict/StaticMembersOfNotImportedClassNameConflict.kt new file mode 100644 index 00000000000..acf872821c0 --- /dev/null +++ b/idea/idea-completion/testData/basic/multifile/StaticMembersOfNotImportedClassNameConflict/StaticMembersOfNotImportedClassNameConflict.kt @@ -0,0 +1,23 @@ +package buz + +fun foo() { + Bar. +} + +// EXIST: {"lookupString":"inBarPackage","tailText":"() for Bar in bar"} +// EXIST: {"lookupString":"Bar","tailText":" (bar.Bar) for Bar in bar"} +// EXIST: {"lookupString":"inFooBarPackage","tailText":"() for Companion in foobar.Bar"} +// EXIST: {"lookupString":"FooBar","tailText":" (foobar.Bar) for Bar in foobar"} +// EXIST: {"lookupString":"inFooPackage","tailText":"() for Companion in foo.Bar"} +// EXIST: {"lookupString":"Foo","tailText":" (foo.Bar) for Bar in foo"} +// EXIST: equals +// EXIST: hashCode +// EXIST: toString +// EXIST: {"lookupString":"inJavapackage","tailText":"() for Bar in javapackage"} +// EXIST: {"lookupString":"JavapackageC","tailText":" (javapackage.Bar)"} +// EXIST: {"lookupString":"Companion","tailText":" (foo.Bar) for Bar in foo"} +// EXIST: {"lookupString":"Companion","tailText":" (foobar.Bar) for Bar in foobar"} + + + +// NOTHING_ELSE diff --git a/idea/idea-completion/testData/basic/multifile/StaticMembersOfNotImportedClassNameConflict/javapackage/Bar.java b/idea/idea-completion/testData/basic/multifile/StaticMembersOfNotImportedClassNameConflict/javapackage/Bar.java new file mode 100644 index 00000000000..f91bb12e833 --- /dev/null +++ b/idea/idea-completion/testData/basic/multifile/StaticMembersOfNotImportedClassNameConflict/javapackage/Bar.java @@ -0,0 +1,11 @@ +package javapackage; + +public class Bar { + public static void inJavapackage() { + + } + + public static class JavapackageC { + + } +} \ No newline at end of file diff --git a/idea/idea-completion/testData/handlers/basic/staticMemberOfNotImported/AmbigiousExtension.dependency.1.kt b/idea/idea-completion/testData/handlers/basic/staticMemberOfNotImported/AmbigiousExtension.dependency.1.kt new file mode 100644 index 00000000000..6f11a8e96b2 --- /dev/null +++ b/idea/idea-completion/testData/handlers/basic/staticMemberOfNotImported/AmbigiousExtension.dependency.1.kt @@ -0,0 +1,6 @@ +package bar + +object FooBar { + +} + diff --git a/idea/idea-completion/testData/handlers/basic/staticMemberOfNotImported/AmbigiousExtension.dependency.2.kt b/idea/idea-completion/testData/handlers/basic/staticMemberOfNotImported/AmbigiousExtension.dependency.2.kt new file mode 100644 index 00000000000..8c10e5e7963 --- /dev/null +++ b/idea/idea-completion/testData/handlers/basic/staticMemberOfNotImported/AmbigiousExtension.dependency.2.kt @@ -0,0 +1,9 @@ +package foo + +object FooBar { + +} + +fun Any.foobarbuz() { + +} \ No newline at end of file diff --git a/idea/idea-completion/testData/handlers/basic/staticMemberOfNotImported/AmbigiousExtension.kt b/idea/idea-completion/testData/handlers/basic/staticMemberOfNotImported/AmbigiousExtension.kt new file mode 100644 index 00000000000..3a49d9e1b0c --- /dev/null +++ b/idea/idea-completion/testData/handlers/basic/staticMemberOfNotImported/AmbigiousExtension.kt @@ -0,0 +1,7 @@ +package buz + +fun foo() { + FooBar. +} + +// ELEMENT: foobarbuz \ No newline at end of file diff --git a/idea/idea-completion/testData/handlers/basic/staticMemberOfNotImported/AmbigiousExtension.kt.after b/idea/idea-completion/testData/handlers/basic/staticMemberOfNotImported/AmbigiousExtension.kt.after new file mode 100644 index 00000000000..2da44c88fb9 --- /dev/null +++ b/idea/idea-completion/testData/handlers/basic/staticMemberOfNotImported/AmbigiousExtension.kt.after @@ -0,0 +1,9 @@ +package buz + +import foo.foobarbuz + +fun foo() { + FooBar.foobarbuz() +} + +// ELEMENT: foobarbuz \ No newline at end of file diff --git a/idea/idea-completion/testData/handlers/basic/staticMemberOfNotImported/AmbigiousName.dependency.1.kt b/idea/idea-completion/testData/handlers/basic/staticMemberOfNotImported/AmbigiousName.dependency.1.kt new file mode 100644 index 00000000000..eb8752f8a1c --- /dev/null +++ b/idea/idea-completion/testData/handlers/basic/staticMemberOfNotImported/AmbigiousName.dependency.1.kt @@ -0,0 +1,7 @@ +package foo + +object FooBar { + fun inFoo() { + + } +} \ No newline at end of file diff --git a/idea/idea-completion/testData/handlers/basic/staticMemberOfNotImported/AmbigiousName.dependency.2.kt b/idea/idea-completion/testData/handlers/basic/staticMemberOfNotImported/AmbigiousName.dependency.2.kt new file mode 100644 index 00000000000..1465508183c --- /dev/null +++ b/idea/idea-completion/testData/handlers/basic/staticMemberOfNotImported/AmbigiousName.dependency.2.kt @@ -0,0 +1,7 @@ +package bar + +object FooBar { + fun inBar() { + + } +} \ No newline at end of file diff --git a/idea/idea-completion/testData/handlers/basic/staticMemberOfNotImported/AmbigiousName.kt b/idea/idea-completion/testData/handlers/basic/staticMemberOfNotImported/AmbigiousName.kt new file mode 100644 index 00000000000..33c53fbf645 --- /dev/null +++ b/idea/idea-completion/testData/handlers/basic/staticMemberOfNotImported/AmbigiousName.kt @@ -0,0 +1,7 @@ +package buz + +fun foo() { + FooBar. +} + +// ELEMENT: inFoo \ No newline at end of file diff --git a/idea/idea-completion/testData/handlers/basic/staticMemberOfNotImported/AmbigiousName.kt.after b/idea/idea-completion/testData/handlers/basic/staticMemberOfNotImported/AmbigiousName.kt.after new file mode 100644 index 00000000000..fc7778798e0 --- /dev/null +++ b/idea/idea-completion/testData/handlers/basic/staticMemberOfNotImported/AmbigiousName.kt.after @@ -0,0 +1,9 @@ +package buz + +import foo.FooBar + +fun foo() { + FooBar.inFoo() +} + +// ELEMENT: inFoo \ No newline at end of file diff --git a/idea/idea-completion/testData/handlers/basic/staticMemberOfNotImported/CompanionObjectMember.dependency.kt b/idea/idea-completion/testData/handlers/basic/staticMemberOfNotImported/CompanionObjectMember.dependency.kt new file mode 100644 index 00000000000..965fa6440c4 --- /dev/null +++ b/idea/idea-completion/testData/handlers/basic/staticMemberOfNotImported/CompanionObjectMember.dependency.kt @@ -0,0 +1,9 @@ +package foo + +class Bar { + companion object { + fun member() { + + } + } +} \ No newline at end of file diff --git a/idea/idea-completion/testData/handlers/basic/staticMemberOfNotImported/CompanionObjectMember.kt b/idea/idea-completion/testData/handlers/basic/staticMemberOfNotImported/CompanionObjectMember.kt new file mode 100644 index 00000000000..78c0190bc89 --- /dev/null +++ b/idea/idea-completion/testData/handlers/basic/staticMemberOfNotImported/CompanionObjectMember.kt @@ -0,0 +1,7 @@ +package buz + +fun foo() { + Bar. +} + +// ELEMENT: member \ No newline at end of file diff --git a/idea/idea-completion/testData/handlers/basic/staticMemberOfNotImported/CompanionObjectMember.kt.after b/idea/idea-completion/testData/handlers/basic/staticMemberOfNotImported/CompanionObjectMember.kt.after new file mode 100644 index 00000000000..602a464ca5d --- /dev/null +++ b/idea/idea-completion/testData/handlers/basic/staticMemberOfNotImported/CompanionObjectMember.kt.after @@ -0,0 +1,9 @@ +package buz + +import foo.Bar + +fun foo() { + Bar.member() +} + +// ELEMENT: member \ No newline at end of file diff --git a/idea/idea-completion/testData/handlers/basic/staticMemberOfNotImported/EnumEntry.dependency.kt b/idea/idea-completion/testData/handlers/basic/staticMemberOfNotImported/EnumEntry.dependency.kt new file mode 100644 index 00000000000..cafb049774f --- /dev/null +++ b/idea/idea-completion/testData/handlers/basic/staticMemberOfNotImported/EnumEntry.dependency.kt @@ -0,0 +1,5 @@ +package foo + +enum class Bar { + FOO, BAR, BUZ +} \ No newline at end of file diff --git a/idea/idea-completion/testData/handlers/basic/staticMemberOfNotImported/EnumEntry.kt b/idea/idea-completion/testData/handlers/basic/staticMemberOfNotImported/EnumEntry.kt new file mode 100644 index 00000000000..9c07fc46ce4 --- /dev/null +++ b/idea/idea-completion/testData/handlers/basic/staticMemberOfNotImported/EnumEntry.kt @@ -0,0 +1,7 @@ +package buz + +fun foo() { + Bar. +} + +// ELEMENT: FOO \ No newline at end of file diff --git a/idea/idea-completion/testData/handlers/basic/staticMemberOfNotImported/EnumEntry.kt.after b/idea/idea-completion/testData/handlers/basic/staticMemberOfNotImported/EnumEntry.kt.after new file mode 100644 index 00000000000..3ac9bf37dc6 --- /dev/null +++ b/idea/idea-completion/testData/handlers/basic/staticMemberOfNotImported/EnumEntry.kt.after @@ -0,0 +1,9 @@ +package buz + +import foo.Bar + +fun foo() { + Bar.FOO +} + +// ELEMENT: FOO \ No newline at end of file diff --git a/idea/idea-completion/testData/handlers/basic/staticMemberOfNotImported/ObjectMember.dependency.kt b/idea/idea-completion/testData/handlers/basic/staticMemberOfNotImported/ObjectMember.dependency.kt new file mode 100644 index 00000000000..95adbb4bfe4 --- /dev/null +++ b/idea/idea-completion/testData/handlers/basic/staticMemberOfNotImported/ObjectMember.dependency.kt @@ -0,0 +1,7 @@ +package foo + +object Bar { + fun member() { + + } +} diff --git a/idea/idea-completion/testData/handlers/basic/staticMemberOfNotImported/ObjectMember.kt b/idea/idea-completion/testData/handlers/basic/staticMemberOfNotImported/ObjectMember.kt new file mode 100644 index 00000000000..78c0190bc89 --- /dev/null +++ b/idea/idea-completion/testData/handlers/basic/staticMemberOfNotImported/ObjectMember.kt @@ -0,0 +1,7 @@ +package buz + +fun foo() { + Bar. +} + +// ELEMENT: member \ No newline at end of file diff --git a/idea/idea-completion/testData/handlers/basic/staticMemberOfNotImported/ObjectMember.kt.after b/idea/idea-completion/testData/handlers/basic/staticMemberOfNotImported/ObjectMember.kt.after new file mode 100644 index 00000000000..602a464ca5d --- /dev/null +++ b/idea/idea-completion/testData/handlers/basic/staticMemberOfNotImported/ObjectMember.kt.after @@ -0,0 +1,9 @@ +package buz + +import foo.Bar + +fun foo() { + Bar.member() +} + +// ELEMENT: member \ No newline at end of file diff --git a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/MultiFileJvmBasicCompletionTestGenerated.java b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/MultiFileJvmBasicCompletionTestGenerated.java index 76bffef637a..f0e5eac675b 100644 --- a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/MultiFileJvmBasicCompletionTestGenerated.java +++ b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/MultiFileJvmBasicCompletionTestGenerated.java @@ -90,6 +90,12 @@ public class MultiFileJvmBasicCompletionTestGenerated extends AbstractMultiFileJ doTest(fileName); } + @TestMetadata("EntriesOfNotImportedEnumFromKotlin") + public void testEntriesOfNotImportedEnumFromKotlin() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/basic/multifile/EntriesOfNotImportedEnumFromKotlin/"); + doTest(fileName); + } + @TestMetadata("EnumEntry") public void testEnumEntry() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/basic/multifile/EnumEntry/"); @@ -396,6 +402,30 @@ public class MultiFileJvmBasicCompletionTestGenerated extends AbstractMultiFileJ doTest(fileName); } + @TestMetadata("StaticMembersOfNotImportedClassFromJava") + public void testStaticMembersOfNotImportedClassFromJava() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/basic/multifile/StaticMembersOfNotImportedClassFromJava/"); + doTest(fileName); + } + + @TestMetadata("StaticMembersOfNotImportedClassFromKotlin") + public void testStaticMembersOfNotImportedClassFromKotlin() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/basic/multifile/StaticMembersOfNotImportedClassFromKotlin/"); + doTest(fileName); + } + + @TestMetadata("StaticMembersOfNotImportedClassFromKotlinObject") + public void testStaticMembersOfNotImportedClassFromKotlinObject() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/basic/multifile/StaticMembersOfNotImportedClassFromKotlinObject/"); + doTest(fileName); + } + + @TestMetadata("StaticMembersOfNotImportedClassNameConflict") + public void testStaticMembersOfNotImportedClassNameConflict() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/basic/multifile/StaticMembersOfNotImportedClassNameConflict/"); + doTest(fileName); + } + @TestMetadata("SyntheticExtensionDeprecated") public void testSyntheticExtensionDeprecated() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/basic/multifile/SyntheticExtensionDeprecated/"); diff --git a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/handlers/AbstractCompletionHandlerTests.kt b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/handlers/AbstractCompletionHandlerTests.kt index a49592dfd31..495cd33c1a6 100644 --- a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/handlers/AbstractCompletionHandlerTests.kt +++ b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/handlers/AbstractCompletionHandlerTests.kt @@ -21,6 +21,7 @@ import com.intellij.openapi.util.io.FileUtil import com.intellij.psi.codeStyle.CodeStyleSettingsManager import org.jetbrains.kotlin.idea.KotlinLanguage import org.jetbrains.kotlin.idea.completion.test.ExpectedCompletionUtils +import org.jetbrains.kotlin.idea.completion.test.configureWithExtraFile import org.jetbrains.kotlin.idea.core.formatter.KotlinCodeStyleSettings import org.jetbrains.kotlin.idea.test.KotlinWithJdkAndRuntimeLightProjectDescriptor import org.jetbrains.kotlin.test.InTextDirectivesUtils @@ -86,7 +87,7 @@ abstract class AbstractCompletionHandlerTest(private val defaultCompletionType: } protected open fun setUpFixture(testPath: String) { - fixture.configureByFile(testPath) + fixture.configureWithExtraFile(testPath, ".dependency", ".dependency.1", ".dependency.2") } protected open fun tearDownFixture() { diff --git a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/handlers/BasicCompletionHandlerTestGenerated.java b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/handlers/BasicCompletionHandlerTestGenerated.java index 18d7e51acdc..1f15b1ca3d0 100644 --- a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/handlers/BasicCompletionHandlerTestGenerated.java +++ b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/handlers/BasicCompletionHandlerTestGenerated.java @@ -39,7 +39,7 @@ public class BasicCompletionHandlerTestGenerated extends AbstractBasicCompletion } public void testAllFilesPresentInBasic() throws Exception { - KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/idea-completion/testData/handlers/basic"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true); + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/idea-completion/testData/handlers/basic"), Pattern.compile("^([^.]+)\\.kt$"), TargetBackend.ANY, true); } @TestMetadata("ClassKeywordBeforeName.kt") @@ -233,7 +233,7 @@ public class BasicCompletionHandlerTestGenerated extends AbstractBasicCompletion @RunWith(JUnit3RunnerWithInners.class) public static class Annotation extends AbstractBasicCompletionHandlerTest { public void testAllFilesPresentInAnnotation() throws Exception { - KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/idea-completion/testData/handlers/basic/annotation"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true); + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/idea-completion/testData/handlers/basic/annotation"), Pattern.compile("^([^.]+)\\.kt$"), TargetBackend.ANY, true); } @TestMetadata("AnnotationInBrackets.kt") @@ -266,7 +266,7 @@ public class BasicCompletionHandlerTestGenerated extends AbstractBasicCompletion @RunWith(JUnit3RunnerWithInners.class) public static class CallableReference extends AbstractBasicCompletionHandlerTest { public void testAllFilesPresentInCallableReference() throws Exception { - KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/idea-completion/testData/handlers/basic/callableReference"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true); + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/idea-completion/testData/handlers/basic/callableReference"), Pattern.compile("^([^.]+)\\.kt$"), TargetBackend.ANY, true); } @TestMetadata("ClassConstructor.kt") @@ -335,7 +335,7 @@ public class BasicCompletionHandlerTestGenerated extends AbstractBasicCompletion } public void testAllFilesPresentInExclChar() throws Exception { - KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/idea-completion/testData/handlers/basic/exclChar"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true); + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/idea-completion/testData/handlers/basic/exclChar"), Pattern.compile("^([^.]+)\\.kt$"), TargetBackend.ANY, true); } } @@ -344,7 +344,7 @@ public class BasicCompletionHandlerTestGenerated extends AbstractBasicCompletion @RunWith(JUnit3RunnerWithInners.class) public static class HighOrderFunctions extends AbstractBasicCompletionHandlerTest { public void testAllFilesPresentInHighOrderFunctions() throws Exception { - KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/idea-completion/testData/handlers/basic/highOrderFunctions"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true); + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/idea-completion/testData/handlers/basic/highOrderFunctions"), Pattern.compile("^([^.]+)\\.kt$"), TargetBackend.ANY, true); } @TestMetadata("ContextVariable.kt") @@ -491,7 +491,7 @@ public class BasicCompletionHandlerTestGenerated extends AbstractBasicCompletion } public void testAllFilesPresentInOverride() throws Exception { - KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/idea-completion/testData/handlers/basic/override"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true); + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/idea-completion/testData/handlers/basic/override"), Pattern.compile("^([^.]+)\\.kt$"), TargetBackend.ANY, true); } @TestMetadata("ImplementFunction.kt") @@ -584,7 +584,7 @@ public class BasicCompletionHandlerTestGenerated extends AbstractBasicCompletion @RunWith(JUnit3RunnerWithInners.class) public static class ParameterNameAndType extends AbstractBasicCompletionHandlerTest { public void testAllFilesPresentInParameterNameAndType() throws Exception { - KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/idea-completion/testData/handlers/basic/parameterNameAndType"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true); + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/idea-completion/testData/handlers/basic/parameterNameAndType"), Pattern.compile("^([^.]+)\\.kt$"), TargetBackend.ANY, true); } @TestMetadata("CodeStyleSettings.kt") @@ -660,12 +660,51 @@ public class BasicCompletionHandlerTestGenerated extends AbstractBasicCompletion } } + @TestMetadata("idea/idea-completion/testData/handlers/basic/staticMemberOfNotImported") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class StaticMemberOfNotImported extends AbstractBasicCompletionHandlerTest { + public void testAllFilesPresentInStaticMemberOfNotImported() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/idea-completion/testData/handlers/basic/staticMemberOfNotImported"), Pattern.compile("^([^.]+)\\.kt$"), TargetBackend.ANY, true); + } + + @TestMetadata("AmbigiousExtension.kt") + public void testAmbigiousExtension() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/handlers/basic/staticMemberOfNotImported/AmbigiousExtension.kt"); + doTest(fileName); + } + + @TestMetadata("AmbigiousName.kt") + public void testAmbigiousName() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/handlers/basic/staticMemberOfNotImported/AmbigiousName.kt"); + doTest(fileName); + } + + @TestMetadata("CompanionObjectMember.kt") + public void testCompanionObjectMember() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/handlers/basic/staticMemberOfNotImported/CompanionObjectMember.kt"); + doTest(fileName); + } + + @TestMetadata("EnumEntry.kt") + public void testEnumEntry() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/handlers/basic/staticMemberOfNotImported/EnumEntry.kt"); + doTest(fileName); + } + + @TestMetadata("ObjectMember.kt") + public void testObjectMember() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/handlers/basic/staticMemberOfNotImported/ObjectMember.kt"); + doTest(fileName); + } + } + @TestMetadata("idea/idea-completion/testData/handlers/basic/staticMembers") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) public static class StaticMembers extends AbstractBasicCompletionHandlerTest { public void testAllFilesPresentInStaticMembers() throws Exception { - KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/idea-completion/testData/handlers/basic/staticMembers"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true); + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/idea-completion/testData/handlers/basic/staticMembers"), Pattern.compile("^([^.]+)\\.kt$"), TargetBackend.ANY, true); } @TestMetadata("classObjectMethod.kt") @@ -746,7 +785,7 @@ public class BasicCompletionHandlerTestGenerated extends AbstractBasicCompletion } public void testAllFilesPresentInStringTemplate() throws Exception { - KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/idea-completion/testData/handlers/basic/stringTemplate"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true); + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/idea-completion/testData/handlers/basic/stringTemplate"), Pattern.compile("^([^.]+)\\.kt$"), TargetBackend.ANY, true); } @TestMetadata("GlobalVal.kt") @@ -803,7 +842,7 @@ public class BasicCompletionHandlerTestGenerated extends AbstractBasicCompletion } public void testAllFilesPresentInTypeArgsForCall() throws Exception { - KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/idea-completion/testData/handlers/basic/typeArgsForCall"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true); + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/idea-completion/testData/handlers/basic/typeArgsForCall"), Pattern.compile("^([^.]+)\\.kt$"), TargetBackend.ANY, true); } @TestMetadata("ExpectedTypeDoesNotHelp.kt")