From 2adf0a3e9aa601e7067c0f63a207814cac65e231 Mon Sep 17 00:00:00 2001 From: Valentin Kipyatkov Date: Wed, 6 May 2015 18:33:52 +0300 Subject: [PATCH] KT-4908 Smart completion does not work for arguments of function with vararg #KT-4908 Fixed --- .../kotlin/idea/completion/ExpectedInfos.kt | 69 ++++++++++---- .../completion/handlers/GenerateLambda.kt | 2 +- .../smart/MultipleArgumentsItemProvider.kt | 8 +- .../kotlin/idea/completion/smart/Utils.kt | 93 ++++++++++++------- .../basic/ExtensionReceiverTypeArg.kt | 2 +- .../basic/ExtensionReceiverTypeArg.kt.after | 2 +- .../testData/handlers/basic/NestedTypeArg.kt | 2 +- .../handlers/basic/NestedTypeArg.kt.after | 2 +- .../handlers/charFilter/InfixCallAndSpace.kt | 2 - .../charFilter/InfixCallAndSpace.kt.after | 2 - .../smart/ConstructorForGenericType.kt | 2 + .../smart/ConstructorForGenericType.kt.after | 2 + .../smart/ConstructorInsertsImport.kt | 2 + .../smart/ConstructorInsertsImport.kt.after | 2 + .../smart/ConstructorInsertsImport2.kt | 2 + .../smart/ConstructorInsertsImport2.kt.after | 2 + .../testData/handlers/smart/DefaultParams.kt | 7 ++ .../handlers/smart/DefaultParams.kt.after | 7 ++ .../smart/JavaStaticMethodInsertsImport.kt | 4 +- .../JavaStaticMethodInsertsImport.kt.after | 4 +- .../testData/handlers/smart/NullableValue2.kt | 2 +- .../handlers/smart/NullableValue2.kt.after | 2 +- .../testData/handlers/smart/NullableValue3.kt | 2 +- .../handlers/smart/NullableValue3.kt.after | 2 +- .../testData/handlers/smart/SAMExpected1.kt | 2 +- .../handlers/smart/SAMExpected1.kt.after | 2 +- .../testData/handlers/smart/Vararg1.kt | 7 ++ .../testData/handlers/smart/Vararg1.kt.after | 7 ++ .../testData/handlers/smart/Vararg2.kt | 7 ++ .../testData/handlers/smart/Vararg2.kt.after | 7 ++ .../testData/handlers/smart/Vararg3.kt | 7 ++ .../testData/handlers/smart/Vararg3.kt.after | 7 ++ .../testData/handlers/smart/Vararg4.kt | 7 ++ .../testData/handlers/smart/Vararg4.kt.after | 7 ++ .../testData/handlers/smart/Vararg5.kt | 7 ++ .../testData/handlers/smart/Vararg5.kt.after | 7 ++ .../testData/handlers/smart/Vararg6.kt | 7 ++ .../testData/handlers/smart/Vararg6.kt.after | 7 ++ .../idea-completion/testData/smart/Vararg1.kt | 8 ++ .../idea-completion/testData/smart/Vararg2.kt | 9 ++ .../idea-completion/testData/smart/Vararg3.kt | 7 ++ .../idea-completion/testData/smart/Vararg4.kt | 9 ++ .../weighers/smart/NameSimilarityForVararg.kt | 7 ++ .../test/JvmSmartCompletionTestGenerated.java | 24 +++++ .../AbstractCompletionHandlerTests.kt | 4 +- .../handlers/BasicCompletionHandlerTest.kt | 12 +-- .../handlers/CompletionHandlerTestBase.kt | 20 ++-- .../SmartCompletionHandlerTestGenerated.java | 42 +++++++++ .../SmartCompletionWeigherTestGenerated.java | 6 ++ 49 files changed, 369 insertions(+), 93 deletions(-) create mode 100644 idea/idea-completion/testData/handlers/smart/DefaultParams.kt create mode 100644 idea/idea-completion/testData/handlers/smart/DefaultParams.kt.after create mode 100644 idea/idea-completion/testData/handlers/smart/Vararg1.kt create mode 100644 idea/idea-completion/testData/handlers/smart/Vararg1.kt.after create mode 100644 idea/idea-completion/testData/handlers/smart/Vararg2.kt create mode 100644 idea/idea-completion/testData/handlers/smart/Vararg2.kt.after create mode 100644 idea/idea-completion/testData/handlers/smart/Vararg3.kt create mode 100644 idea/idea-completion/testData/handlers/smart/Vararg3.kt.after create mode 100644 idea/idea-completion/testData/handlers/smart/Vararg4.kt create mode 100644 idea/idea-completion/testData/handlers/smart/Vararg4.kt.after create mode 100644 idea/idea-completion/testData/handlers/smart/Vararg5.kt create mode 100644 idea/idea-completion/testData/handlers/smart/Vararg5.kt.after create mode 100644 idea/idea-completion/testData/handlers/smart/Vararg6.kt create mode 100644 idea/idea-completion/testData/handlers/smart/Vararg6.kt.after create mode 100644 idea/idea-completion/testData/smart/Vararg1.kt create mode 100644 idea/idea-completion/testData/smart/Vararg2.kt create mode 100644 idea/idea-completion/testData/smart/Vararg3.kt create mode 100644 idea/idea-completion/testData/smart/Vararg4.kt create mode 100644 idea/idea-completion/testData/weighers/smart/NameSimilarityForVararg.kt diff --git a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/ExpectedInfos.kt b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/ExpectedInfos.kt index ba334c016e0..59b1dd0ebdb 100644 --- a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/ExpectedInfos.kt +++ b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/ExpectedInfos.kt @@ -55,13 +55,20 @@ enum class Tail { ELSE } -open data class ExpectedInfo(val type: JetType, val name: String?, val tail: Tail?) +data class ItemOptions(val starPrefix: Boolean) { + companion object { + val DEFAULT = ItemOptions(false) + val STAR_PREFIX = ItemOptions(true) + } +} -class PositionalArgumentExpectedInfo(type: JetType, name: String?, tail: Tail?, val function: FunctionDescriptor, val argumentIndex: Int) - : ExpectedInfo(type, name, tail) { +open data class ExpectedInfo(val type: JetType, val name: String?, val tail: Tail?, val itemOptions: ItemOptions = ItemOptions.DEFAULT) + +class PositionalArgumentExpectedInfo(type: JetType, name: String?, tail: Tail?, val function: FunctionDescriptor, val parameterIndex: Int, itemOptions: ItemOptions = ItemOptions.DEFAULT) + : ExpectedInfo(type, name, tail, itemOptions) { override fun equals(other: Any?) - = other is PositionalArgumentExpectedInfo && super.equals(other) && function == other.function && argumentIndex == other.argumentIndex + = other is PositionalArgumentExpectedInfo && super.equals(other) && function == other.function && parameterIndex == other.parameterIndex override fun hashCode() = function.hashCode() @@ -149,8 +156,8 @@ class ExpectedInfos( val dataFlowInfo = bindingContext.getDataFlowInfo(calleeExpression) val bindingTrace = DelegatingBindingTrace(bindingContext, "Temporary trace for completion") val context = BasicCallResolutionContext.create(bindingTrace, resolutionScope, call, expectedType, dataFlowInfo, - ContextDependency.INDEPENDENT, CheckValueArgumentsMode.ENABLED, - CompositeChecker(listOf()), SymbolUsageValidator.Empty, AdditionalTypeChecker.Composite(listOf()), false) + ContextDependency.INDEPENDENT, CheckValueArgumentsMode.ENABLED, + CompositeChecker(listOf()), SymbolUsageValidator.Empty, AdditionalTypeChecker.Composite(listOf()), false) val callResolutionContext = context.replaceCollectAllCandidates(true) val callResolver = InjectorForMacros( callElement.getProject(), @@ -163,32 +170,58 @@ class ExpectedInfos( val status = candidate.getStatus() if (status == ResolutionStatus.RECEIVER_TYPE_ERROR || status == ResolutionStatus.RECEIVER_PRESENCE_ERROR) continue - // consider only candidates with more arguments than in the truncated call and with all arguments before the current one matched - if (candidate.noErrorsInValueArguments() && (candidate.getCandidateDescriptor().getValueParameters().size() > argumentIndex || isFunctionLiteralArgument)) { - val descriptor = candidate.getResultingDescriptor() + // check that all arguments before the current one matched + if (!candidate.noErrorsInValueArguments()) continue - val thisReceiver = ExpressionTypingUtils.normalizeReceiverValueForVisibility(candidate.getDispatchReceiver(), bindingContext) - if (!Visibilities.isVisible(thisReceiver, descriptor, resolutionScope.getContainingDeclaration())) continue + val descriptor = candidate.getResultingDescriptor() + val parameters = descriptor.getValueParameters() - val parameters = descriptor.getValueParameters() - if (isFunctionLiteralArgument && argumentIndex != parameters.lastIndex) continue + val parameterIndex = if (isFunctionLiteralArgument) { + if (argumentIndex != parameters.lastIndex) continue //TODO: varargs and optional parameters + argumentIndex + } + else { + val varArgIndex = parameters.indexOfFirst { it.getVarargElementType() != null } + if (varArgIndex < 0) { + if (parameters.size() <= argumentIndex) continue + argumentIndex + } + else { + if (argumentIndex < varArgIndex) argumentIndex else varArgIndex + } + } + val thisReceiver = ExpressionTypingUtils.normalizeReceiverValueForVisibility(candidate.getDispatchReceiver(), bindingContext) + if (!Visibilities.isVisible(thisReceiver, descriptor, resolutionScope.getContainingDeclaration())) continue + + val parameter = parameters[parameterIndex] + val varargElementType = parameter.getVarargElementType() + + val expectedName = if (descriptor.hasSynthesizedParameterNames()) null else parameter.getName().asString() + + if (varargElementType != null) { + expectedInfos.add(PositionalArgumentExpectedInfo(varargElementType, expectedName?.fromPlural(), null, descriptor, parameterIndex)) + + if (argumentIndex == parameterIndex) { + val tail = if (parameterIndex == parameters.lastIndex) Tail.RPARENTH else null + expectedInfos.add(PositionalArgumentExpectedInfo(parameter.getType(), expectedName, tail, descriptor, parameterIndex, ItemOptions.STAR_PREFIX)) + } + } + else { val tail = if (isFunctionLiteralArgument) null - else if (argumentIndex == parameters.lastIndex) + else if (parameterIndex == parameters.lastIndex) Tail.RPARENTH //TODO: support square brackets - else if (parameters.drop(argumentIndex + 1).all { it.hasDefaultValue() || it.getVarargElementType() != null }) + else if (parameters.drop(parameterIndex + 1).all { it.hasDefaultValue() || it.getVarargElementType() != null }) null else Tail.COMMA - val parameter = parameters[argumentIndex] - val expectedName = if (descriptor.hasSynthesizedParameterNames()) null else parameter.getName().asString() val parameterType = if (useHeuristicSignatures) HeuristicSignatures.correctedParameterType(descriptor, argumentIndex, moduleDescriptor, callElement.getProject()) ?: parameter.getType() else parameter.getType() - expectedInfos.add(PositionalArgumentExpectedInfo(parameterType, expectedName, tail, descriptor, argumentIndex)) + expectedInfos.add(PositionalArgumentExpectedInfo(parameterType, expectedName, tail, descriptor, parameterIndex)) } } return expectedInfos diff --git a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/handlers/GenerateLambda.kt b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/handlers/GenerateLambda.kt index d5b9a257fe1..756b0729c55 100644 --- a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/handlers/GenerateLambda.kt +++ b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/handlers/GenerateLambda.kt @@ -76,7 +76,7 @@ private fun needExplicitParameterTypes(context: InsertionContext, placeholderRan PsiDocumentManager.getInstance(context.getProject()).commitAllDocuments() val file = context.getFile() as JetFile val expression = PsiTreeUtil.findElementOfClassAtRange(file, placeholderRange.getStartOffset(), placeholderRange.getEndOffset(), javaClass()) - if (expression == null) return false + ?: return false val resolutionFacade = file.getResolutionFacade() val bindingContext = resolutionFacade.analyze(expression, BodyResolveMode.PARTIAL) diff --git a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/smart/MultipleArgumentsItemProvider.kt b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/smart/MultipleArgumentsItemProvider.kt index 7a48afc8aac..ea4c775b594 100644 --- a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/smart/MultipleArgumentsItemProvider.kt +++ b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/smart/MultipleArgumentsItemProvider.kt @@ -47,15 +47,15 @@ class MultipleArgumentsItemProvider(val bindingContext: BindingContext, val added = HashSet() for (expectedInfo in expectedInfos) { - if (expectedInfo is PositionalArgumentExpectedInfo && expectedInfo.argumentIndex == 0) { + if (expectedInfo is PositionalArgumentExpectedInfo && expectedInfo.parameterIndex == 0) { val parameters = expectedInfo.function.getValueParameters() - if (parameters.size > 1) { + if (parameters.size() > 1) { val variables = ArrayList() - for ((i, parameter) in parameters.withIndices()) { + for ((i, parameter) in parameters.withIndex()) { val variable = variableInScope(parameter, resolutionScope) ?: break variables.add(variable) // TODO: cannot inline variable because of KT-5890 - if (i > 0 && parameters.stream().drop(i + 1).all { it.hasDefaultValue() }) { // this is the last parameter or all others have default values + if (i > 0 && parameters.asSequence().drop(i + 1).all { it.hasDefaultValue() }) { // this is the last parameter or all others have default values val lookupElement = createParametersLookupElement(variables) if (added.add(lookupElement.getLookupString())) { // check that we don't already have item with the same text collection.add(lookupElement) diff --git a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/smart/Utils.kt b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/smart/Utils.kt index 8b673bfde84..47dd711fd41 100644 --- a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/smart/Utils.kt +++ b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/smart/Utils.kt @@ -17,34 +17,28 @@ package org.jetbrains.kotlin.idea.completion.smart import com.intellij.codeInsight.completion.InsertHandler -import com.intellij.codeInsight.lookup.LookupElement import com.intellij.codeInsight.completion.InsertionContext -import com.intellij.psi.PsiDocumentManager -import org.jetbrains.kotlin.psi.JetFile -import org.jetbrains.kotlin.idea.util.ShortenReferences -import java.util.HashSet +import com.intellij.codeInsight.lookup.LookupElement import com.intellij.codeInsight.lookup.LookupElementDecorator -import org.jetbrains.kotlin.descriptors.FunctionDescriptor -import org.jetbrains.kotlin.types.JetType -import org.jetbrains.kotlin.builtins.KotlinBuiltIns import com.intellij.codeInsight.lookup.LookupElementPresentation -import org.jetbrains.kotlin.idea.completion.* -import org.jetbrains.kotlin.descriptors.DeclarationDescriptor -import org.jetbrains.kotlin.idea.completion.handlers.WithTailInsertHandler -import org.jetbrains.kotlin.descriptors.ConstructorDescriptor -import org.jetbrains.kotlin.descriptors.ClassifierDescriptor import com.intellij.openapi.util.Key -import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor -import org.jetbrains.kotlin.resolve.BindingContext +import com.intellij.psi.PsiDocumentManager +import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.idea.caches.resolve.ResolutionFacade +import org.jetbrains.kotlin.idea.completion.* +import org.jetbrains.kotlin.idea.completion.handlers.WithTailInsertHandler +import org.jetbrains.kotlin.idea.util.* +import org.jetbrains.kotlin.psi.JetFile +import org.jetbrains.kotlin.psi.JetValueArgument +import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType +import org.jetbrains.kotlin.resolve.BindingContext +import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns +import org.jetbrains.kotlin.types.JetType import org.jetbrains.kotlin.types.TypeSubstitutor +import org.jetbrains.kotlin.utils.addIfNotNull import java.util.ArrayList import java.util.HashMap -import org.jetbrains.kotlin.idea.util.FuzzyType -import org.jetbrains.kotlin.idea.util.makeNotNullable -import org.jetbrains.kotlin.idea.util.nullability -import org.jetbrains.kotlin.idea.util.TypeNullability -import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns +import java.util.HashSet class ArtificialElementInsertHandler( val textBeforeCaret: String, val textAfterCaret: String, val shortenRefs: Boolean) : InsertHandler{ @@ -95,6 +89,32 @@ fun LookupElement.addTail(tail: Tail?): LookupElement { } } +fun LookupElement.withOptions(options: ItemOptions): LookupElement { + var lookupElement = this + if (options.starPrefix) { + lookupElement = object : LookupElementDecorator(this) { + override fun renderElement(presentation: LookupElementPresentation) { + super.renderElement(presentation) + presentation.setItemText("*" + presentation.getItemText()) + } + + override fun handleInsert(context: InsertionContext) { + getDelegate().handleInsert(context) + + PsiDocumentManager.getInstance(context.getProject()).commitAllDocuments() + + val offset = context.getStartOffset() + val token = context.getFile().findElementAt(offset)!! + val argument = token.getStrictParentOfType() + if (argument != null) { + context.getDocument().insertString(argument.getTextRange().getStartOffset(), "*") + } + } + } + } + return lookupElement +} + fun LookupElement.addTailAndNameSimilarity(matchedExpectedInfos: Collection): LookupElement { val lookupElement = addTail(mergeTails(matchedExpectedInfos.map { it.tail })) val similarity = calcNameSimilarity(lookupElement.getLookupString(), matchedExpectedInfos) @@ -113,14 +133,14 @@ class ExpectedInfoClassification private(val substitutor: TypeSubstitutor?, val } fun Collection.classifyExpectedInfo(expectedInfo: ExpectedInfo): ExpectedInfoClassification { - val stream = stream() - val substitutor = stream.map { it.checkIsSubtypeOf(expectedInfo.type) }.firstOrNull() + val sequence = asSequence() + val substitutor = sequence.map { it.checkIsSubtypeOf(expectedInfo.type) }.firstOrNull() if (substitutor != null) { return ExpectedInfoClassification.matches(substitutor) } - if (stream.any { it.nullability() == TypeNullability.NULLABLE }) { - val substitutor2 = stream.map { it.makeNotNullable().checkIsSubtypeOf(expectedInfo.type) }.firstOrNull() + if (sequence.any { it.nullability() == TypeNullability.NULLABLE }) { + val substitutor2 = sequence.map { it.makeNotNullable().checkIsSubtypeOf(expectedInfo.type) }.firstOrNull() if (substitutor2 != null) { return ExpectedInfoClassification.matchesIfNotNullable(substitutor2) } @@ -137,36 +157,37 @@ fun MutableCollection.addLoo infoClassifier: (ExpectedInfo) -> ExpectedInfoClassification, lookupElementFactory: (TDescriptor) -> LookupElement? ) { - class DescriptorWrapper(val descriptor: TDescriptor) { - override fun equals(other: Any?) = other is DescriptorWrapper && descriptorsEqualWithSubstitution(this.descriptor, other.descriptor) + class ItemData(val descriptor: TDescriptor, val itemOptions: ItemOptions) { + override fun equals(other: Any?) + = other is ItemData && descriptorsEqualWithSubstitution(this.descriptor, other.descriptor) && itemOptions == other.itemOptions override fun hashCode() = if (this.descriptor != null) this.descriptor.getOriginal().hashCode() else 0 } - fun TDescriptor.wrap() = DescriptorWrapper(this) - fun DescriptorWrapper.unwrap() = this.descriptor - val matchedInfos = HashMap>() - val makeNullableInfos = HashMap>() + fun ItemData.createLookupElement() = lookupElementFactory(this.descriptor)?.withOptions(this.itemOptions) + + val matchedInfos = HashMap>() + val makeNullableInfos = HashMap>() for (info in expectedInfos) { val classification = infoClassifier(info) if (classification.substitutor != null) { [suppress("UNCHECKED_CAST")] val substitutedDescriptor = descriptor?.substitute(classification.substitutor) as TDescriptor val map = if (classification.makeNotNullable) makeNullableInfos else matchedInfos - map.getOrPut(substitutedDescriptor.wrap()) { ArrayList() }.add(info) + map.getOrPut(ItemData(substitutedDescriptor, info.itemOptions)) { ArrayList() }.add(info) } } if (!matchedInfos.isEmpty()) { - for ((substitutedDescriptor, infos) in matchedInfos) { - val lookupElement = lookupElementFactory(substitutedDescriptor.unwrap()) + for ((itemData, infos) in matchedInfos) { + val lookupElement = itemData.createLookupElement() if (lookupElement != null) { add(lookupElement.addTailAndNameSimilarity(infos)) } } } else { - for ((substitutedDescriptor, infos) in makeNullableInfos) { - addLookupElementsForNullable({ lookupElementFactory(substitutedDescriptor.unwrap()) }, infos) + for ((itemData, infos) in makeNullableInfos) { + addLookupElementsForNullable({ itemData.createLookupElement() }, infos) } } } @@ -182,7 +203,7 @@ private fun lookupElementsForNullable(factory: () -> LookupElement?): Collection var lookupElement = factory() if (lookupElement != null) { - lookupElement = object: LookupElementDecorator(lookupElement!!) { + lookupElement = object: LookupElementDecorator(lookupElement) { override fun renderElement(presentation: LookupElementPresentation) { super.renderElement(presentation) presentation.setItemText("!! " + presentation.getItemText()) diff --git a/idea/idea-completion/testData/handlers/basic/ExtensionReceiverTypeArg.kt b/idea/idea-completion/testData/handlers/basic/ExtensionReceiverTypeArg.kt index c6f11b638ae..05c0e94c885 100644 --- a/idea/idea-completion/testData/handlers/basic/ExtensionReceiverTypeArg.kt +++ b/idea/idea-completion/testData/handlers/basic/ExtensionReceiverTypeArg.kt @@ -1,4 +1,4 @@ fun List>foo() {} // ELEMENT: String -// TAIL_TEXT: "(kotlin)" +// TAIL_TEXT: " (kotlin)" diff --git a/idea/idea-completion/testData/handlers/basic/ExtensionReceiverTypeArg.kt.after b/idea/idea-completion/testData/handlers/basic/ExtensionReceiverTypeArg.kt.after index a91bb293cb4..7aa1b85caa3 100644 --- a/idea/idea-completion/testData/handlers/basic/ExtensionReceiverTypeArg.kt.after +++ b/idea/idea-completion/testData/handlers/basic/ExtensionReceiverTypeArg.kt.after @@ -1,4 +1,4 @@ fun List>foo() {} // ELEMENT: String -// TAIL_TEXT: "(kotlin)" +// TAIL_TEXT: " (kotlin)" diff --git a/idea/idea-completion/testData/handlers/basic/NestedTypeArg.kt b/idea/idea-completion/testData/handlers/basic/NestedTypeArg.kt index 7e98b77c934..f43b11c243d 100644 --- a/idea/idea-completion/testData/handlers/basic/NestedTypeArg.kt +++ b/idea/idea-completion/testData/handlers/basic/NestedTypeArg.kt @@ -5,4 +5,4 @@ class Pair private val v = ArrayList>> // ELEMENT: String -// TAIL_TEXT: "(kotlin)" +// TAIL_TEXT: " (kotlin)" diff --git a/idea/idea-completion/testData/handlers/basic/NestedTypeArg.kt.after b/idea/idea-completion/testData/handlers/basic/NestedTypeArg.kt.after index 23ea8aa73f8..e9dcf3eec8e 100644 --- a/idea/idea-completion/testData/handlers/basic/NestedTypeArg.kt.after +++ b/idea/idea-completion/testData/handlers/basic/NestedTypeArg.kt.after @@ -5,4 +5,4 @@ class Pair private val v = ArrayList>> // ELEMENT: String -// TAIL_TEXT: "(kotlin)" +// TAIL_TEXT: " (kotlin)" diff --git a/idea/idea-completion/testData/handlers/charFilter/InfixCallAndSpace.kt b/idea/idea-completion/testData/handlers/charFilter/InfixCallAndSpace.kt index 7fbd87a2db0..92a5952f878 100644 --- a/idea/idea-completion/testData/handlers/charFilter/InfixCallAndSpace.kt +++ b/idea/idea-completion/testData/handlers/charFilter/InfixCallAndSpace.kt @@ -1,5 +1,3 @@ -fun A.to(that: B): Pair = Pair(this, that) - fun foo() { val pair = 1 } diff --git a/idea/idea-completion/testData/handlers/charFilter/InfixCallAndSpace.kt.after b/idea/idea-completion/testData/handlers/charFilter/InfixCallAndSpace.kt.after index 042280203c8..c1d39082f5d 100644 --- a/idea/idea-completion/testData/handlers/charFilter/InfixCallAndSpace.kt.after +++ b/idea/idea-completion/testData/handlers/charFilter/InfixCallAndSpace.kt.after @@ -1,5 +1,3 @@ -fun A.to(that: B): Pair = Pair(this, that) - fun foo() { val pair = 1 to } diff --git a/idea/idea-completion/testData/handlers/smart/ConstructorForGenericType.kt b/idea/idea-completion/testData/handlers/smart/ConstructorForGenericType.kt index 06cdebbc852..75e7138603e 100644 --- a/idea/idea-completion/testData/handlers/smart/ConstructorForGenericType.kt +++ b/idea/idea-completion/testData/handlers/smart/ConstructorForGenericType.kt @@ -6,3 +6,5 @@ fun foo(p: HashMap>){} fun f(){ foo() } + +// ELEMENT: HashMap diff --git a/idea/idea-completion/testData/handlers/smart/ConstructorForGenericType.kt.after b/idea/idea-completion/testData/handlers/smart/ConstructorForGenericType.kt.after index fabcc7d4754..9114c35bef2 100644 --- a/idea/idea-completion/testData/handlers/smart/ConstructorForGenericType.kt.after +++ b/idea/idea-completion/testData/handlers/smart/ConstructorForGenericType.kt.after @@ -6,3 +6,5 @@ fun foo(p: HashMap>){} fun f(){ foo(HashMap>()) } + +// ELEMENT: HashMap diff --git a/idea/idea-completion/testData/handlers/smart/ConstructorInsertsImport.kt b/idea/idea-completion/testData/handlers/smart/ConstructorInsertsImport.kt index e03b67769a0..c8324135287 100644 --- a/idea/idea-completion/testData/handlers/smart/ConstructorInsertsImport.kt +++ b/idea/idea-completion/testData/handlers/smart/ConstructorInsertsImport.kt @@ -5,3 +5,5 @@ class X { foo() } } + +// ELEMENT: HashMap diff --git a/idea/idea-completion/testData/handlers/smart/ConstructorInsertsImport.kt.after b/idea/idea-completion/testData/handlers/smart/ConstructorInsertsImport.kt.after index 624887373f3..62d61a039c6 100644 --- a/idea/idea-completion/testData/handlers/smart/ConstructorInsertsImport.kt.after +++ b/idea/idea-completion/testData/handlers/smart/ConstructorInsertsImport.kt.after @@ -8,3 +8,5 @@ class X { foo(HashMap()) } } + +// ELEMENT: HashMap diff --git a/idea/idea-completion/testData/handlers/smart/ConstructorInsertsImport2.kt b/idea/idea-completion/testData/handlers/smart/ConstructorInsertsImport2.kt index 557b6f8f22c..edd96819be3 100644 --- a/idea/idea-completion/testData/handlers/smart/ConstructorInsertsImport2.kt +++ b/idea/idea-completion/testData/handlers/smart/ConstructorInsertsImport2.kt @@ -5,3 +5,5 @@ class X { foo() } } + +// ELEMENT: HashMap diff --git a/idea/idea-completion/testData/handlers/smart/ConstructorInsertsImport2.kt.after b/idea/idea-completion/testData/handlers/smart/ConstructorInsertsImport2.kt.after index 7d3d6230ae0..97de61531cf 100644 --- a/idea/idea-completion/testData/handlers/smart/ConstructorInsertsImport2.kt.after +++ b/idea/idea-completion/testData/handlers/smart/ConstructorInsertsImport2.kt.after @@ -9,3 +9,5 @@ class X { foo(HashMap>()) } } + +// ELEMENT: HashMap diff --git a/idea/idea-completion/testData/handlers/smart/DefaultParams.kt b/idea/idea-completion/testData/handlers/smart/DefaultParams.kt new file mode 100644 index 00000000000..4f30ca4a47a --- /dev/null +++ b/idea/idea-completion/testData/handlers/smart/DefaultParams.kt @@ -0,0 +1,7 @@ +fun foo(s: String, optional: String = ""){ } + +fun bar(s: String){ + foo() +} + +// ELEMENT: s diff --git a/idea/idea-completion/testData/handlers/smart/DefaultParams.kt.after b/idea/idea-completion/testData/handlers/smart/DefaultParams.kt.after new file mode 100644 index 00000000000..354284c10a8 --- /dev/null +++ b/idea/idea-completion/testData/handlers/smart/DefaultParams.kt.after @@ -0,0 +1,7 @@ +fun foo(s: String, optional: String = ""){ } + +fun bar(s: String){ + foo(s) +} + +// ELEMENT: s diff --git a/idea/idea-completion/testData/handlers/smart/JavaStaticMethodInsertsImport.kt b/idea/idea-completion/testData/handlers/smart/JavaStaticMethodInsertsImport.kt index 75fb8fd629f..5152cdd9b95 100644 --- a/idea/idea-completion/testData/handlers/smart/JavaStaticMethodInsertsImport.kt +++ b/idea/idea-completion/testData/handlers/smart/JavaStaticMethodInsertsImport.kt @@ -2,5 +2,5 @@ fun foo(){ val l : java.util.Calendar = } -// ELEMENT_TEXT: Calendar.getInstance -// TAIL_TEXT: (TimeZone!) +// ELEMENT_TEXT: "Calendar.getInstance" +// TAIL_TEXT: "(TimeZone!) (java.util)" diff --git a/idea/idea-completion/testData/handlers/smart/JavaStaticMethodInsertsImport.kt.after b/idea/idea-completion/testData/handlers/smart/JavaStaticMethodInsertsImport.kt.after index 6cf13af7212..ea5acd12ce3 100644 --- a/idea/idea-completion/testData/handlers/smart/JavaStaticMethodInsertsImport.kt.after +++ b/idea/idea-completion/testData/handlers/smart/JavaStaticMethodInsertsImport.kt.after @@ -4,5 +4,5 @@ fun foo(){ val l : java.util.Calendar = Calendar.getInstance() } -// ELEMENT_TEXT: Calendar.getInstance -// TAIL_TEXT: (TimeZone!) +// ELEMENT_TEXT: "Calendar.getInstance" +// TAIL_TEXT: "(TimeZone!) (java.util)" diff --git a/idea/idea-completion/testData/handlers/smart/NullableValue2.kt b/idea/idea-completion/testData/handlers/smart/NullableValue2.kt index a1e7783e4d7..4cb5321b8df 100644 --- a/idea/idea-completion/testData/handlers/smart/NullableValue2.kt +++ b/idea/idea-completion/testData/handlers/smart/NullableValue2.kt @@ -7,4 +7,4 @@ fun bar() { } // ELEMENT_TEXT: "?: getString" -// TAIL_TEXT: "(i: Int)" +// TAIL_TEXT: "(i: Int) ()" diff --git a/idea/idea-completion/testData/handlers/smart/NullableValue2.kt.after b/idea/idea-completion/testData/handlers/smart/NullableValue2.kt.after index 71edf2f6b98..d1b29d8d905 100644 --- a/idea/idea-completion/testData/handlers/smart/NullableValue2.kt.after +++ b/idea/idea-completion/testData/handlers/smart/NullableValue2.kt.after @@ -7,4 +7,4 @@ fun bar() { } // ELEMENT_TEXT: "?: getString" -// TAIL_TEXT: "(i: Int)" +// TAIL_TEXT: "(i: Int) ()" diff --git a/idea/idea-completion/testData/handlers/smart/NullableValue3.kt b/idea/idea-completion/testData/handlers/smart/NullableValue3.kt index 9bf7cf17118..22007bef800 100644 --- a/idea/idea-completion/testData/handlers/smart/NullableValue3.kt +++ b/idea/idea-completion/testData/handlers/smart/NullableValue3.kt @@ -9,4 +9,4 @@ fun foo(){ } // ELEMENT_TEXT: "!! K.bar" -// TAIL_TEXT: "()" +// TAIL_TEXT: "() ()" diff --git a/idea/idea-completion/testData/handlers/smart/NullableValue3.kt.after b/idea/idea-completion/testData/handlers/smart/NullableValue3.kt.after index 8810359cd9e..5747c5f8b39 100644 --- a/idea/idea-completion/testData/handlers/smart/NullableValue3.kt.after +++ b/idea/idea-completion/testData/handlers/smart/NullableValue3.kt.after @@ -9,4 +9,4 @@ fun foo(){ } // ELEMENT_TEXT: "!! K.bar" -// TAIL_TEXT: "()" +// TAIL_TEXT: "() ()" diff --git a/idea/idea-completion/testData/handlers/smart/SAMExpected1.kt b/idea/idea-completion/testData/handlers/smart/SAMExpected1.kt index fdd76379b31..3bd44948bd8 100644 --- a/idea/idea-completion/testData/handlers/smart/SAMExpected1.kt +++ b/idea/idea-completion/testData/handlers/smart/SAMExpected1.kt @@ -1,4 +1,4 @@ var a : Runnable = // ELEMENT_TEXT: Runnable -// TAIL_TEXT: "()" +// TAIL_TEXT: "(function: () -> Unit) (java.lang)" diff --git a/idea/idea-completion/testData/handlers/smart/SAMExpected1.kt.after b/idea/idea-completion/testData/handlers/smart/SAMExpected1.kt.after index 599e5d9546b..dd80a9ada21 100644 --- a/idea/idea-completion/testData/handlers/smart/SAMExpected1.kt.after +++ b/idea/idea-completion/testData/handlers/smart/SAMExpected1.kt.after @@ -1,4 +1,4 @@ var a : Runnable = Runnable { } // ELEMENT_TEXT: Runnable -// TAIL_TEXT: "()" +// TAIL_TEXT: "(function: () -> Unit) (java.lang)" diff --git a/idea/idea-completion/testData/handlers/smart/Vararg1.kt b/idea/idea-completion/testData/handlers/smart/Vararg1.kt new file mode 100644 index 00000000000..50b16a3871a --- /dev/null +++ b/idea/idea-completion/testData/handlers/smart/Vararg1.kt @@ -0,0 +1,7 @@ +fun foo(vararg strings: String){ } + +fun bar(s: String){ + foo() +} + +// ELEMENT: s diff --git a/idea/idea-completion/testData/handlers/smart/Vararg1.kt.after b/idea/idea-completion/testData/handlers/smart/Vararg1.kt.after new file mode 100644 index 00000000000..339e7b15e0c --- /dev/null +++ b/idea/idea-completion/testData/handlers/smart/Vararg1.kt.after @@ -0,0 +1,7 @@ +fun foo(vararg strings: String){ } + +fun bar(s: String){ + foo(s) +} + +// ELEMENT: s diff --git a/idea/idea-completion/testData/handlers/smart/Vararg2.kt b/idea/idea-completion/testData/handlers/smart/Vararg2.kt new file mode 100644 index 00000000000..da5ffa12720 --- /dev/null +++ b/idea/idea-completion/testData/handlers/smart/Vararg2.kt @@ -0,0 +1,7 @@ +fun foo(vararg strings: String){ } + +fun bar(s: String){ + foo("", ) +} + +// ELEMENT: s diff --git a/idea/idea-completion/testData/handlers/smart/Vararg2.kt.after b/idea/idea-completion/testData/handlers/smart/Vararg2.kt.after new file mode 100644 index 00000000000..ba987995f49 --- /dev/null +++ b/idea/idea-completion/testData/handlers/smart/Vararg2.kt.after @@ -0,0 +1,7 @@ +fun foo(vararg strings: String){ } + +fun bar(s: String){ + foo("", s) +} + +// ELEMENT: s diff --git a/idea/idea-completion/testData/handlers/smart/Vararg3.kt b/idea/idea-completion/testData/handlers/smart/Vararg3.kt new file mode 100644 index 00000000000..aa7b4debe83 --- /dev/null +++ b/idea/idea-completion/testData/handlers/smart/Vararg3.kt @@ -0,0 +1,7 @@ +fun foo(vararg strings: String, options: Int = 0){ } + +fun bar(s: String){ + foo("", ) +} + +// ELEMENT: s diff --git a/idea/idea-completion/testData/handlers/smart/Vararg3.kt.after b/idea/idea-completion/testData/handlers/smart/Vararg3.kt.after new file mode 100644 index 00000000000..ccd8514fe4e --- /dev/null +++ b/idea/idea-completion/testData/handlers/smart/Vararg3.kt.after @@ -0,0 +1,7 @@ +fun foo(vararg strings: String, options: Int = 0){ } + +fun bar(s: String){ + foo("", s) +} + +// ELEMENT: s diff --git a/idea/idea-completion/testData/handlers/smart/Vararg4.kt b/idea/idea-completion/testData/handlers/smart/Vararg4.kt new file mode 100644 index 00000000000..120ccb6961a --- /dev/null +++ b/idea/idea-completion/testData/handlers/smart/Vararg4.kt @@ -0,0 +1,7 @@ +fun foo(vararg strings: String){ } + +fun bar(arr: Array){ + foo() +} + +// ELEMENT: arr diff --git a/idea/idea-completion/testData/handlers/smart/Vararg4.kt.after b/idea/idea-completion/testData/handlers/smart/Vararg4.kt.after new file mode 100644 index 00000000000..144977eeb68 --- /dev/null +++ b/idea/idea-completion/testData/handlers/smart/Vararg4.kt.after @@ -0,0 +1,7 @@ +fun foo(vararg strings: String){ } + +fun bar(arr: Array){ + foo(*arr) +} + +// ELEMENT: arr diff --git a/idea/idea-completion/testData/handlers/smart/Vararg5.kt b/idea/idea-completion/testData/handlers/smart/Vararg5.kt new file mode 100644 index 00000000000..5481d131d93 --- /dev/null +++ b/idea/idea-completion/testData/handlers/smart/Vararg5.kt @@ -0,0 +1,7 @@ +fun foo(vararg strings: String){ } + +fun bar(list: List){ + foo(list.) +} + +// ELEMENT: toTypedArray diff --git a/idea/idea-completion/testData/handlers/smart/Vararg5.kt.after b/idea/idea-completion/testData/handlers/smart/Vararg5.kt.after new file mode 100644 index 00000000000..90c701b0c71 --- /dev/null +++ b/idea/idea-completion/testData/handlers/smart/Vararg5.kt.after @@ -0,0 +1,7 @@ +fun foo(vararg strings: String){ } + +fun bar(list: List){ + foo(*list.toTypedArray()) +} + +// ELEMENT: toTypedArray diff --git a/idea/idea-completion/testData/handlers/smart/Vararg6.kt b/idea/idea-completion/testData/handlers/smart/Vararg6.kt new file mode 100644 index 00000000000..52b3c7ef0ef --- /dev/null +++ b/idea/idea-completion/testData/handlers/smart/Vararg6.kt @@ -0,0 +1,7 @@ +fun foo(vararg strings: String, optional: String = ""){ } + +fun bar(arr: Array){ + foo() +} + +// ELEMENT: arr diff --git a/idea/idea-completion/testData/handlers/smart/Vararg6.kt.after b/idea/idea-completion/testData/handlers/smart/Vararg6.kt.after new file mode 100644 index 00000000000..41beb180df2 --- /dev/null +++ b/idea/idea-completion/testData/handlers/smart/Vararg6.kt.after @@ -0,0 +1,7 @@ +fun foo(vararg strings: String, optional: String = ""){ } + +fun bar(arr: Array){ + foo(*arr) +} + +// ELEMENT: arr diff --git a/idea/idea-completion/testData/smart/Vararg1.kt b/idea/idea-completion/testData/smart/Vararg1.kt new file mode 100644 index 00000000000..6d6635ed483 --- /dev/null +++ b/idea/idea-completion/testData/smart/Vararg1.kt @@ -0,0 +1,8 @@ +fun foo(vararg strings: String){ } + +fun bar(s: String, arr: Array){ + foo() +} + +// EXIST: s +// EXIST: { lookupString: "arr", itemText: "*arr" } diff --git a/idea/idea-completion/testData/smart/Vararg2.kt b/idea/idea-completion/testData/smart/Vararg2.kt new file mode 100644 index 00000000000..bc83ac034c5 --- /dev/null +++ b/idea/idea-completion/testData/smart/Vararg2.kt @@ -0,0 +1,9 @@ +fun foo(vararg strings: String){ } + +fun bar(s: String, arr: Array){ + foo("", ) +} + +// EXIST: s +// ABSENT: arr +// ABSENT: *arr diff --git a/idea/idea-completion/testData/smart/Vararg3.kt b/idea/idea-completion/testData/smart/Vararg3.kt new file mode 100644 index 00000000000..89cf36d70e0 --- /dev/null +++ b/idea/idea-completion/testData/smart/Vararg3.kt @@ -0,0 +1,7 @@ +fun foo(vararg strings: String, options: Int = 0){ } + +fun bar(s: String){ + foo("", ) +} + +// EXIST: s diff --git a/idea/idea-completion/testData/smart/Vararg4.kt b/idea/idea-completion/testData/smart/Vararg4.kt new file mode 100644 index 00000000000..7d50007e750 --- /dev/null +++ b/idea/idea-completion/testData/smart/Vararg4.kt @@ -0,0 +1,9 @@ +fun foo(vararg args: Any){ } + +fun bar(s: String, arr: Array){ + foo() +} + +// EXIST: s +// EXIST: { lookupString: "arr", itemText: "arr" } +// EXIST: { lookupString: "arr", itemText: "*arr" } diff --git a/idea/idea-completion/testData/weighers/smart/NameSimilarityForVararg.kt b/idea/idea-completion/testData/weighers/smart/NameSimilarityForVararg.kt new file mode 100644 index 00000000000..f4685c70575 --- /dev/null +++ b/idea/idea-completion/testData/weighers/smart/NameSimilarityForVararg.kt @@ -0,0 +1,7 @@ +fun foo(vararg xFooBars: String){} + +fun g(a: String, bar: String, fooBar: String, xFooBars: Array) { + foo() +} + +// ORDER: xFooBars, fooBar, bar, a diff --git a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/JvmSmartCompletionTestGenerated.java b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/JvmSmartCompletionTestGenerated.java index b3ee1bbbc22..877a74d31c1 100644 --- a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/JvmSmartCompletionTestGenerated.java +++ b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/JvmSmartCompletionTestGenerated.java @@ -371,6 +371,30 @@ public class JvmSmartCompletionTestGenerated extends AbstractJvmSmartCompletionT doTest(fileName); } + @TestMetadata("Vararg1.kt") + public void testVararg1() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/smart/Vararg1.kt"); + doTest(fileName); + } + + @TestMetadata("Vararg2.kt") + public void testVararg2() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/smart/Vararg2.kt"); + doTest(fileName); + } + + @TestMetadata("Vararg3.kt") + public void testVararg3() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/smart/Vararg3.kt"); + doTest(fileName); + } + + @TestMetadata("Vararg4.kt") + public void testVararg4() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/smart/Vararg4.kt"); + doTest(fileName); + } + @TestMetadata("VariableAsFunction1.kt") public void testVariableAsFunction1() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/smart/VariableAsFunction1.kt"); 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 f254ab4d7c6..e33fa75812c 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 @@ -18,7 +18,7 @@ package org.jetbrains.kotlin.idea.completion.test.handlers import com.intellij.codeInsight.completion.CompletionType import com.intellij.openapi.util.io.FileUtil -import org.jetbrains.kotlin.idea.test.JetLightProjectDescriptor +import org.jetbrains.kotlin.idea.test.JetWithJdkAndRuntimeLightProjectDescriptor import org.jetbrains.kotlin.test.InTextDirectivesUtils import java.io.File @@ -61,7 +61,7 @@ public abstract class AbstractCompletionHandlerTest(private val defaultCompletio fixture.configureByFile(testPath) } - override fun getProjectDescriptor() = JetLightProjectDescriptor.INSTANCE + override fun getProjectDescriptor() = JetWithJdkAndRuntimeLightProjectDescriptor.INSTANCE } public abstract class AbstractBasicCompletionHandlerTest() : AbstractCompletionHandlerTest(CompletionType.BASIC) diff --git a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/handlers/BasicCompletionHandlerTest.kt b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/handlers/BasicCompletionHandlerTest.kt index 7b2cb6c6118..14555530f31 100644 --- a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/handlers/BasicCompletionHandlerTest.kt +++ b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/handlers/BasicCompletionHandlerTest.kt @@ -61,7 +61,7 @@ public class BasicCompletionHandlerTest : CompletionHandlerTestBase(){ fun testDoNotInsertImportIfResolvedIntoJavaConstructor() = doTest() - fun testNonStandardArray() = doTest(2, "Array", "java.lang.reflect", '\n') + fun testNonStandardArray() = doTest(2, "Array", " (java.lang.reflect)", '\n') fun testNoParamsFunction() = doTest() @@ -89,15 +89,15 @@ public class BasicCompletionHandlerTest : CompletionHandlerTestBase(){ fun testHigherOrderFunction() = doTest() - fun testInsertFqnForJavaClass() = doTest(2, "SortedSet", "java.util", '\n') + fun testInsertFqnForJavaClass() = doTest(2, "SortedSet", " (java.util)", '\n') fun testHigherOrderFunctionWithArg() = doTest(2, "filterNot", null, '\n') - fun testHigherOrderFunctionWithArgs1() = doTest(1, "foo", "foo", " { String, Char -> ... }", '\n') + fun testHigherOrderFunctionWithArgs1() = doTest(1, "foo", "foo", " { String, Char -> ... } ()", '\n') - fun testHigherOrderFunctionWithArgs2() = doTest(1, "foo", "foo", "(p: (String, Char) -> Boolean)", '\n') + fun testHigherOrderFunctionWithArgs2() = doTest(1, "foo", "foo", "(p: (String, Char) -> Boolean) ()", '\n') - fun testHigherOrderFunctionWithArgs3() = doTest(1, "foo", "foo", " { String, Char -> ... }", '\n') + fun testHigherOrderFunctionWithArgs3() = doTest(1, "foo", "foo", " { String, Char -> ... } ()", '\n') fun testForceParenthesisForTabChar() = doTest(0, "some", null, '\t') @@ -170,7 +170,7 @@ public class BasicCompletionHandlerTest : CompletionHandlerTestBase(){ fun testTypeArgOfSuper() = doTest(1, "X", null, '\n') fun testKeywordClassName() = doTest(1, "class", null, '\n') - fun testKeywordFunctionName() = doTest(1, "fun", "fun", "()", '\n') + fun testKeywordFunctionName() = doTest(1, "fun", "fun", "() (test)", '\n') fun testInfixCall() = doTest(1, "to", null, null, '\n') fun testInfixCallOnSpace() = doTest(1, "to", null, null, ' ') diff --git a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/handlers/CompletionHandlerTestBase.kt b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/handlers/CompletionHandlerTestBase.kt index feb8dfdb74a..fee8cfb835b 100644 --- a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/handlers/CompletionHandlerTestBase.kt +++ b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/handlers/CompletionHandlerTestBase.kt @@ -25,9 +25,10 @@ import com.intellij.codeInsight.lookup.impl.LookupImpl import com.intellij.openapi.application.Result import com.intellij.openapi.command.WriteCommandAction import com.intellij.testFramework.fixtures.JavaCodeInsightTestFixture +import org.jetbrains.kotlin.idea.completion.test.ExpectedCompletionUtils import org.jetbrains.kotlin.idea.test.JetLightCodeInsightFixtureTestCase import org.jetbrains.kotlin.test.JetTestUtils -import org.junit.Assert +import kotlin.test.fail public abstract class CompletionHandlerTestBase() : JetLightCodeInsightFixtureTestCase() { protected val fixture: JavaCodeInsightTestFixture @@ -55,8 +56,7 @@ public abstract class CompletionHandlerTestBase() : JetLightCodeInsightFixtureTe } private fun getExistentLookupElement(lookupString: String?, itemText: String?, tailText: String?): LookupElement? { - val lookup = LookupManager.getInstance(getProject())?.getActiveLookup() as LookupImpl? - if (lookup == null) return null + val lookup = LookupManager.getInstance(getProject())?.getActiveLookup() as LookupImpl? ?: return null val items = lookup.getItems() if (lookupString == "*") { @@ -68,14 +68,14 @@ public abstract class CompletionHandlerTestBase() : JetLightCodeInsightFixtureTe var foundElement : LookupElement? = null val presentation = LookupElementPresentation() for (lookupElement in items) { - val lookupOk = if (lookupString != null) lookupElement.getLookupString().contains(lookupString) else true + val lookupOk = if (lookupString != null) lookupElement.getLookupString() == lookupString else true if (lookupOk) { lookupElement.renderElement(presentation) val textOk = if (itemText != null) { val itemItemText = presentation.getItemText() - itemItemText != null && itemItemText.contains(itemText) + itemItemText != null && itemItemText == itemText } else { true @@ -84,7 +84,7 @@ public abstract class CompletionHandlerTestBase() : JetLightCodeInsightFixtureTe if (textOk) { val tailOk = if (tailText != null) { val itemTailText = presentation.getTailText() - itemTailText != null && itemTailText.contains(tailText) + itemTailText != null && itemTailText == tailText } else { true @@ -92,7 +92,8 @@ public abstract class CompletionHandlerTestBase() : JetLightCodeInsightFixtureTe if (tailOk) { if (foundElement != null) { - Assert.fail("Several elements satisfy to completion restrictions: \n $foundElement\n $lookupElement") + val dump = ExpectedCompletionUtils.listToString(ExpectedCompletionUtils.getItemsInformation(arrayOf(foundElement, lookupElement))) + fail("Several elements satisfy to completion restrictions:\n$dump") } foundElement = lookupElement @@ -101,7 +102,10 @@ public abstract class CompletionHandlerTestBase() : JetLightCodeInsightFixtureTe } } - if (foundElement == null) error("No element satisfy completion restrictions") + if (foundElement == null) { + val dump = ExpectedCompletionUtils.listToString(ExpectedCompletionUtils.getItemsInformation(items.toTypedArray())) + error("No element satisfy completion restrictions in:\n$dump") + } return foundElement } diff --git a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/handlers/SmartCompletionHandlerTestGenerated.java b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/handlers/SmartCompletionHandlerTestGenerated.java index 9397cb0210a..0ae77c99690 100644 --- a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/handlers/SmartCompletionHandlerTestGenerated.java +++ b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/handlers/SmartCompletionHandlerTestGenerated.java @@ -293,6 +293,12 @@ public class SmartCompletionHandlerTestGenerated extends AbstractSmartCompletion doTest(fileName); } + @TestMetadata("DefaultParams.kt") + public void testDefaultParams() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/handlers/smart/DefaultParams.kt"); + doTest(fileName); + } + @TestMetadata("DoNotEraseBraceOnTab.kt") public void testDoNotEraseBraceOnTab() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/handlers/smart/DoNotEraseBraceOnTab.kt"); @@ -647,6 +653,42 @@ public class SmartCompletionHandlerTestGenerated extends AbstractSmartCompletion doTest(fileName); } + @TestMetadata("Vararg1.kt") + public void testVararg1() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/handlers/smart/Vararg1.kt"); + doTest(fileName); + } + + @TestMetadata("Vararg2.kt") + public void testVararg2() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/handlers/smart/Vararg2.kt"); + doTest(fileName); + } + + @TestMetadata("Vararg3.kt") + public void testVararg3() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/handlers/smart/Vararg3.kt"); + doTest(fileName); + } + + @TestMetadata("Vararg4.kt") + public void testVararg4() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/handlers/smart/Vararg4.kt"); + doTest(fileName); + } + + @TestMetadata("Vararg5.kt") + public void testVararg5() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/handlers/smart/Vararg5.kt"); + doTest(fileName); + } + + @TestMetadata("Vararg6.kt") + public void testVararg6() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/handlers/smart/Vararg6.kt"); + doTest(fileName); + } + @TestMetadata("WhenElse.kt") public void testWhenElse() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/handlers/smart/WhenElse.kt"); diff --git a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/weighers/SmartCompletionWeigherTestGenerated.java b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/weighers/SmartCompletionWeigherTestGenerated.java index f6fa64f7897..e13a64c5e75 100644 --- a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/weighers/SmartCompletionWeigherTestGenerated.java +++ b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/weighers/SmartCompletionWeigherTestGenerated.java @@ -167,6 +167,12 @@ public class SmartCompletionWeigherTestGenerated extends AbstractSmartCompletion doTest(fileName); } + @TestMetadata("NameSimilarityForVararg.kt") + public void testNameSimilarityForVararg() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/weighers/smart/NameSimilarityForVararg.kt"); + doTest(fileName); + } + @TestMetadata("NameSimilarityInImplicitlyTypedVarInitializer.kt") public void testNameSimilarityInImplicitlyTypedVarInitializer() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/weighers/smart/NameSimilarityInImplicitlyTypedVarInitializer.kt");