From 483da9607cb1a7a21c900678a782bc87697afd8f Mon Sep 17 00:00:00 2001 From: Valentin Kipyatkov Date: Tue, 9 Jun 2015 23:10:47 +0300 Subject: [PATCH] KT-4893 Code completion should not show multiple functions with the same signature #KT-4893 Fixed --- .../kotlin/psi/JetValueArgumentName.java | 13 +- .../org/jetbrains/kotlin/psi/ValueArgument.kt | 8 +- .../ValueArgumentsToParametersMapper.java | 20 +- .../resolve/calls/tasks/dynamicCalls.kt | 2 +- .../kotlin/resolve/calls/util/CallMaker.java | 2 +- .../resolve/scopes/ExplicitImportsScope.kt | 48 +++++ .../org/jetbrains/kotlin/utils/addToStdlib.kt | 0 .../codeInsight/ReferenceVariantsHelper.kt | 66 +++---- .../idea/util/ShadowedDeclarationsFilter.kt | 178 ++++++++++++++++++ .../org/jetbrains/kotlin/idea/util/Utils.kt | 38 ++++ .../idea/completion/CompletionSession.kt | 16 +- .../kotlin/idea/completion/ExpectedInfos.kt | 13 +- .../completion/PackageDirectiveCompletion.kt | 3 +- .../smart/MultipleArgumentsItemProvider.kt | 3 +- .../idea/completion/smart/SmartCompletion.kt | 7 - .../basic/common/shadowing/InInitializer1.kt | 6 + .../basic/common/shadowing/InInitializer2.kt | 5 + .../basic/common/shadowing/InInitializer3.kt | 8 + .../basic/common/shadowing/Locals1.kt | 15 ++ .../basic/common/shadowing/Locals2.kt | 10 + .../basic/common/shadowing/Overloads.kt | 17 ++ .../common/shadowing/OverloadsAndVararg.kt | 17 ++ .../common/shadowing/PreferCloserMember.kt | 14 ++ .../common/shadowing/PreferMemberExtension.kt | 19 ++ .../shadowing/PreferMemberToExtension.kt | 24 +++ .../common/shadowing/PreferMemberToGlobal.kt | 12 ++ .../shadowing/PreferMoreSpecificExtension.kt | 19 ++ ...PreferMoreSpecificExtension1.dependency.kt | 4 + .../PreferMoreSpecificExtension1.kt | 12 ++ ...PreferMoreSpecificExtension2.dependency.kt | 4 + .../PreferMoreSpecificExtension2.kt | 10 + .../test/JSBasicCompletionTestGenerated.java | 81 ++++++++ .../test/JvmBasicCompletionTestGenerated.java | 81 ++++++++ ...tiFileJvmBasicCompletionTestGenerated.java | 12 ++ .../org/jetbrains/kotlin/idea/core/Utils.kt | 4 +- .../kotlin/idea/core/psiModificationUtils.kt | 2 +- .../JetFunctionParameterInfoHandler.java | 3 +- .../quickfix/ChangeFunctionSignatureFix.java | 4 +- .../quickfix/ReplaceWithAnnotationAnalyzer.kt | 26 --- ...structorFromDelegationCallActionFactory.kt | 2 +- ...orFromDelegatorToSuperCallActionFactory.kt | 2 +- ...mCallWithConstructorCalleeActionFactory.kt | 2 +- .../usages/JetFunctionCallUsage.java | 11 +- 43 files changed, 737 insertions(+), 106 deletions(-) create mode 100644 core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/ExplicitImportsScope.kt rename {compiler/util => core/util.runtime}/src/org/jetbrains/kotlin/utils/addToStdlib.kt (100%) create mode 100644 idea/ide-common/src/org/jetbrains/kotlin/idea/util/ShadowedDeclarationsFilter.kt create mode 100644 idea/idea-completion/testData/basic/common/shadowing/InInitializer1.kt create mode 100644 idea/idea-completion/testData/basic/common/shadowing/InInitializer2.kt create mode 100644 idea/idea-completion/testData/basic/common/shadowing/InInitializer3.kt create mode 100644 idea/idea-completion/testData/basic/common/shadowing/Locals1.kt create mode 100644 idea/idea-completion/testData/basic/common/shadowing/Locals2.kt create mode 100644 idea/idea-completion/testData/basic/common/shadowing/Overloads.kt create mode 100644 idea/idea-completion/testData/basic/common/shadowing/OverloadsAndVararg.kt create mode 100644 idea/idea-completion/testData/basic/common/shadowing/PreferCloserMember.kt create mode 100644 idea/idea-completion/testData/basic/common/shadowing/PreferMemberExtension.kt create mode 100644 idea/idea-completion/testData/basic/common/shadowing/PreferMemberToExtension.kt create mode 100644 idea/idea-completion/testData/basic/common/shadowing/PreferMemberToGlobal.kt create mode 100644 idea/idea-completion/testData/basic/common/shadowing/PreferMoreSpecificExtension.kt create mode 100644 idea/idea-completion/testData/basic/multifile/PreferMoreSpecificExtension1/PreferMoreSpecificExtension1.dependency.kt create mode 100644 idea/idea-completion/testData/basic/multifile/PreferMoreSpecificExtension1/PreferMoreSpecificExtension1.kt create mode 100644 idea/idea-completion/testData/basic/multifile/PreferMoreSpecificExtension2/PreferMoreSpecificExtension2.dependency.kt create mode 100644 idea/idea-completion/testData/basic/multifile/PreferMoreSpecificExtension2/PreferMoreSpecificExtension2.kt diff --git a/compiler/frontend/src/org/jetbrains/kotlin/psi/JetValueArgumentName.java b/compiler/frontend/src/org/jetbrains/kotlin/psi/JetValueArgumentName.java index 0c5c658e29d..466e1bb1f8d 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/psi/JetValueArgumentName.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/psi/JetValueArgumentName.java @@ -18,16 +18,23 @@ package org.jetbrains.kotlin.psi; import com.intellij.lang.ASTNode; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.JetNodeTypes; +import org.jetbrains.kotlin.name.Name; -public class JetValueArgumentName extends JetElementImpl { +public class JetValueArgumentName extends JetElementImpl implements ValueArgumentName { public JetValueArgumentName(@NotNull ASTNode node) { super(node); } - @Nullable @IfNotParsed + @Override + @NotNull public JetSimpleNameExpression getReferenceExpression() { return (JetSimpleNameExpression) findChildByType(JetNodeTypes.REFERENCE_EXPRESSION); } + + @NotNull + @Override + public Name getAsName() { + return getReferenceExpression().getReferencedNameAsName(); + } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/psi/ValueArgument.kt b/compiler/frontend/src/org/jetbrains/kotlin/psi/ValueArgument.kt index 6c9baee81a2..b28eef1a954 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/psi/ValueArgument.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/psi/ValueArgument.kt @@ -17,12 +17,13 @@ package org.jetbrains.kotlin.psi import com.intellij.psi.impl.source.tree.LeafPsiElement +import org.jetbrains.kotlin.name.Name public trait ValueArgument { IfNotParsed public fun getArgumentExpression(): JetExpression? - public fun getArgumentName(): JetValueArgumentName? + public fun getArgumentName(): ValueArgumentName? public fun isNamed(): Boolean @@ -40,3 +41,8 @@ public trait FunctionLiteralArgument : ValueArgument { override fun getArgumentExpression(): JetExpression } + +public interface ValueArgumentName { + public val asName: Name + public val referenceExpression: JetSimpleNameExpression? +} diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/ValueArgumentsToParametersMapper.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/ValueArgumentsToParametersMapper.java index f05d1e0a36b..636ae99dd21 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/ValueArgumentsToParametersMapper.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/ValueArgumentsToParametersMapper.java @@ -155,9 +155,11 @@ public class ValueArgumentsToParametersMapper { D candidate = candidateCall.getCandidateDescriptor(); - JetSimpleNameExpression nameReference = argument.getArgumentName().getReferenceExpression(); - ValueParameterDescriptor valueParameterDescriptor = parameterByName.get(nameReference.getReferencedNameAsName()); - if (!candidate.hasStableParameterNames()) { + ValueArgumentName argumentName = argument.getArgumentName(); + assert argumentName != null; + ValueParameterDescriptor valueParameterDescriptor = parameterByName.get(argumentName.getAsName()); + JetReferenceExpression nameReference = argumentName.getReferenceExpression(); + if (!candidate.hasStableParameterNames() && nameReference != null) { report(NAMED_ARGUMENTS_NOT_ALLOWED.on( nameReference, candidate instanceof FunctionInvokeDescriptor ? INVOKE_ON_FUNCTION_TYPE : NON_KOTLIN_FUNCTION @@ -165,14 +167,20 @@ public class ValueArgumentsToParametersMapper { } if (valueParameterDescriptor == null) { - report(NAMED_PARAMETER_NOT_FOUND.on(nameReference, nameReference)); + if (nameReference != null) { + report(NAMED_PARAMETER_NOT_FOUND.on(nameReference, nameReference)); + } unmappedArguments.add(argument); setStatus(WEAK_ERROR); } else { - candidateCall.getTrace().record(REFERENCE_TARGET, nameReference, valueParameterDescriptor); + if (nameReference != null) { + candidateCall.getTrace().record(REFERENCE_TARGET, nameReference, valueParameterDescriptor); + } if (!usedParameters.add(valueParameterDescriptor)) { - report(ARGUMENT_PASSED_TWICE.on(nameReference)); + if (nameReference != null) { + report(ARGUMENT_PASSED_TWICE.on(nameReference)); + } unmappedArguments.add(argument); setStatus(WEAK_ERROR); } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tasks/dynamicCalls.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tasks/dynamicCalls.kt index 00f7ca2eaea..b46e928cab8 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tasks/dynamicCalls.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tasks/dynamicCalls.kt @@ -182,7 +182,7 @@ object DynamicCallableDescriptors { null, index, Annotations.EMPTY, - arg.getArgumentName()?.getReferenceExpression()?.getReferencedNameAsName() ?: Name.identifier("p$index"), + arg.getArgumentName()?.asName ?: Name.identifier("p$index"), outType, false, varargElementType, diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/util/CallMaker.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/util/CallMaker.java index 6f1d45d31ed..de74eacd22f 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/util/CallMaker.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/util/CallMaker.java @@ -60,7 +60,7 @@ public class CallMaker { } @Override - public JetValueArgumentName getArgumentName() { + public ValueArgumentName getArgumentName() { return null; } diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/ExplicitImportsScope.kt b/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/ExplicitImportsScope.kt new file mode 100644 index 00000000000..a4338a758ca --- /dev/null +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/ExplicitImportsScope.kt @@ -0,0 +1,48 @@ +/* + * Copyright 2010-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.resolve.scopes + +import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.utils.Printer +import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull + +public class ExplicitImportsScope(private val descriptors: Collection) : JetScope { + override fun getClassifier(name: Name) = descriptors.filter { it.getName() == name }.firstIsInstanceOrNull() + + override fun getPackage(name: Name)= descriptors.filter { it.getName() == name }.firstIsInstanceOrNull() + + override fun getProperties(name: Name) = descriptors.filter { it.getName() == name }.filterIsInstance() + + override fun getLocalVariable(name: Name): VariableDescriptor? = null + + override fun getFunctions(name: Name) = descriptors.filter { it.getName() == name }.filterIsInstance() + + override fun getContainingDeclaration() = throw UnsupportedOperationException() + + override fun getDeclarationsByLabel(labelName: Name) = emptyList() + + override fun getDescriptors(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean) = descriptors + + override fun getImplicitReceiversHierarchy() = emptyList() + + override fun getOwnDeclaredDescriptors() = emptyList() + + override fun printScopeStructure(p: Printer) { + p.println(javaClass.getName()) + } +} diff --git a/compiler/util/src/org/jetbrains/kotlin/utils/addToStdlib.kt b/core/util.runtime/src/org/jetbrains/kotlin/utils/addToStdlib.kt similarity index 100% rename from compiler/util/src/org/jetbrains/kotlin/utils/addToStdlib.kt rename to core/util.runtime/src/org/jetbrains/kotlin/utils/addToStdlib.kt diff --git a/idea/ide-common/src/org/jetbrains/kotlin/idea/codeInsight/ReferenceVariantsHelper.kt b/idea/ide-common/src/org/jetbrains/kotlin/idea/codeInsight/ReferenceVariantsHelper.kt index 05da65e1e45..1476c1da491 100644 --- a/idea/ide-common/src/org/jetbrains/kotlin/idea/codeInsight/ReferenceVariantsHelper.kt +++ b/idea/ide-common/src/org/jetbrains/kotlin/idea/codeInsight/ReferenceVariantsHelper.kt @@ -1,4 +1,5 @@ /* + * Copyright 2010-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,34 +17,37 @@ package org.jetbrains.kotlin.idea.codeInsight -import org.jetbrains.kotlin.descriptors.* -import org.jetbrains.kotlin.psi.* -import org.jetbrains.kotlin.psi.psiUtil.* -import org.jetbrains.kotlin.resolve.BindingContext -import org.jetbrains.kotlin.resolve.calls.smartcasts.SmartCastUtils -import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo -import org.jetbrains.kotlin.resolve.scopes.JetScope -import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver -import java.util.* -import org.jetbrains.kotlin.resolve.bindingContextUtil.getDataFlowInfo +import com.intellij.openapi.project.Project +import org.jetbrains.kotlin.descriptors.CallableDescriptor +import org.jetbrains.kotlin.descriptors.ClassDescriptor +import org.jetbrains.kotlin.descriptors.DeclarationDescriptor +import org.jetbrains.kotlin.descriptors.ModuleDescriptor +import org.jetbrains.kotlin.idea.util.* +import org.jetbrains.kotlin.lexer.JetTokens import org.jetbrains.kotlin.name.Name -import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue -import org.jetbrains.kotlin.resolve.scopes.getDescriptorsFiltered -import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter +import org.jetbrains.kotlin.psi.* +import org.jetbrains.kotlin.psi.psiUtil.getReceiverExpression +import org.jetbrains.kotlin.resolve.BindingContext +import org.jetbrains.kotlin.resolve.bindingContextUtil.getDataFlowInfo +import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo +import org.jetbrains.kotlin.resolve.calls.smartcasts.SmartCastUtils import org.jetbrains.kotlin.resolve.scopes.DescriptorKindExclude +import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter +import org.jetbrains.kotlin.resolve.scopes.JetScope +import org.jetbrains.kotlin.resolve.scopes.getDescriptorsFiltered +import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver +import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue import org.jetbrains.kotlin.types.JetType import org.jetbrains.kotlin.types.TypeUtils import org.jetbrains.kotlin.types.checker.JetTypeChecker -import org.jetbrains.kotlin.lexer.JetTokens -import org.jetbrains.kotlin.idea.util.CallType -import org.jetbrains.kotlin.idea.util.substituteExtensionIfCallable -import org.jetbrains.kotlin.idea.util.getImplicitReceiversWithInstance +import java.util.* public class ReferenceVariantsHelper( private val context: BindingContext, + private val moduleDescriptor: ModuleDescriptor, + private val project: Project, private val visibilityFilter: (DeclarationDescriptor) -> Boolean ) { - public data class ReceiversData( public val receivers: Collection, public val callType: CallType @@ -59,7 +63,10 @@ public class ReferenceVariantsHelper( useRuntimeReceiverType: Boolean, nameFilter: (Name) -> Boolean ): Collection { - return getReferenceVariantsNoVisibilityFilter(expression, kindFilter, useRuntimeReceiverType, nameFilter).filter(visibilityFilter) + val variants = getReferenceVariantsNoVisibilityFilter(expression, kindFilter, useRuntimeReceiverType, nameFilter) + .filter(visibilityFilter) + return ShadowedDeclarationsFilter(context, moduleDescriptor, project).filter(variants, expression) + //TODO: if visibility filter is empty, filter out shadowed can work incorrectly! } private fun getReferenceVariantsNoVisibilityFilter( @@ -69,7 +76,7 @@ public class ReferenceVariantsHelper( nameFilter: (Name) -> Boolean ): Collection { val parent = expression.getParent() - val resolutionScope = context[BindingContext.RESOLUTION_SCOPE, expression] ?: return listOf() + val resolutionScope = context.correctedResolutionScope(expression) ?: return listOf() val containingDeclaration = resolutionScope.getContainingDeclaration() if (parent is JetImportDirective || parent is JetPackageDirective) { @@ -80,13 +87,12 @@ public class ReferenceVariantsHelper( return resolutionScope.getDescriptorsFiltered(kindFilter.restrictedToKinds(DescriptorKindFilter.CLASSIFIERS_MASK or DescriptorKindFilter.PACKAGES_MASK), nameFilter) } + val descriptors = LinkedHashSet() + val pair = getExplicitReceiverData(expression) if (pair != null) { val (receiverExpression, callType) = pair - // Process as call expression - val descriptors = HashSet() - val qualifier = context[BindingContext.QUALIFIER, receiverExpression] if (qualifier != null) { // It's impossible to add extension function for package or class (if it's companion object, expression type is not null) @@ -107,20 +113,16 @@ public class ReferenceVariantsHelper( descriptors.addCallableExtensions(resolutionScope, receiverValue, dataFlowInfo, callType, kindFilter, nameFilter) } - - return descriptors } else { val dataFlowInfo = context.getDataFlowInfo(expression) - val descriptorsSet = HashSet() - // process instance members that can be called via implicit receiver's instances val receivers = resolutionScope.getImplicitReceiversWithInstance() val receiverValues = receivers.map { it.getValue() } for (receiverValue in receiverValues) { for (variant in SmartCastUtils.getSmartCastVariantsWithLessSpecificExcluded(receiverValue, context, containingDeclaration, dataFlowInfo)) { - descriptorsSet.addMembersFromReceiver(variant, CallType.NORMAL, kindFilter, nameFilter) + descriptors.addMembersFromReceiver(variant, CallType.NORMAL, kindFilter, nameFilter) } } @@ -129,17 +131,17 @@ public class ReferenceVariantsHelper( if (descriptor is CallableDescriptor && descriptor.getExtensionReceiverParameter() != null) { val dispatchReceiver = descriptor.getDispatchReceiverParameter() if (dispatchReceiver == null || dispatchReceiver in receivers) { - descriptorsSet.addAll(descriptor.substituteExtensionIfCallable(receiverValues, context, dataFlowInfo, CallType.NORMAL, containingDeclaration)) + descriptors.addAll(descriptor.substituteExtensionIfCallable(receiverValues, context, dataFlowInfo, CallType.NORMAL, containingDeclaration)) } } else { if (descriptor is CallableDescriptor && descriptor.getDispatchReceiverParameter() != null) continue // should already be processed via implicit receivers - descriptorsSet.add(descriptor) + descriptors.add(descriptor) } } - - return descriptorsSet } + + return descriptors } private fun MutableCollection.addMembersFromReceiver( diff --git a/idea/ide-common/src/org/jetbrains/kotlin/idea/util/ShadowedDeclarationsFilter.kt b/idea/ide-common/src/org/jetbrains/kotlin/idea/util/ShadowedDeclarationsFilter.kt new file mode 100644 index 00000000000..b48cb677b8a --- /dev/null +++ b/idea/ide-common/src/org/jetbrains/kotlin/idea/util/ShadowedDeclarationsFilter.kt @@ -0,0 +1,178 @@ +/* + * Copyright 2010-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.idea.util + +import com.intellij.openapi.project.Project +import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.di.InjectorForMacros +import org.jetbrains.kotlin.idea.imports.canBeReferencedViaImport +import org.jetbrains.kotlin.psi.* +import org.jetbrains.kotlin.resolve.BindingContext +import org.jetbrains.kotlin.resolve.DelegatingBindingTrace +import org.jetbrains.kotlin.resolve.bindingContextUtil.getDataFlowInfo +import org.jetbrains.kotlin.resolve.calls.callUtil.getCall +import org.jetbrains.kotlin.resolve.calls.checkers.AdditionalTypeChecker +import org.jetbrains.kotlin.resolve.calls.checkers.CompositeChecker +import org.jetbrains.kotlin.resolve.calls.context.BasicCallResolutionContext +import org.jetbrains.kotlin.resolve.calls.context.CheckValueArgumentsMode +import org.jetbrains.kotlin.resolve.calls.context.ContextDependency +import org.jetbrains.kotlin.resolve.calls.util.DelegatingCall +import org.jetbrains.kotlin.resolve.scopes.ChainedScope +import org.jetbrains.kotlin.resolve.scopes.ExplicitImportsScope +import org.jetbrains.kotlin.resolve.validation.SymbolUsageValidator +import org.jetbrains.kotlin.types.TypeUtils +import java.util.ArrayList + +public class ShadowedDeclarationsFilter( + private val bindingContext: BindingContext, + private val moduleDescriptor: ModuleDescriptor, + private val project: Project, + private val importDeclarations: Boolean = false +) { + private val psiFactory = JetPsiFactory(project) + private val dummyExpressionFactory = DummyExpressionFactory(psiFactory) + + public fun filter(declarations: Collection, expression: JetSimpleNameExpression): Collection { + val call = expression.getCall(bindingContext) ?: return declarations + + return declarations + .groupBy { signature(it) } + .flatMap { filterEqualSignatureGroup(it.value, call) } + } + + private fun signature(descriptor: DeclarationDescriptor): Any { + return when (descriptor) { + is SimpleFunctionDescriptor -> FunctionSignature(descriptor) + is VariableDescriptor -> descriptor.getName() + else -> descriptor + } + } + + private fun filterEqualSignatureGroup(descriptors: Collection, call: Call): Collection { + if (descriptors.size() == 1) return descriptors + + val first = descriptors.first() + val isFunction = first is FunctionDescriptor + val name = first.getName() + val parameters = (first as CallableDescriptor).getValueParameters() + + val dummyArgumentExpressions = dummyExpressionFactory.createDummyExpressions(parameters.size()) + + val bindingTrace = DelegatingBindingTrace(bindingContext, "Temporary trace for filtering shadowed declarations") + for ((expression, parameter) in dummyArgumentExpressions.zip(parameters)) { + bindingTrace.recordType(expression, parameter.getVarargElementType() ?: parameter.getType()) + bindingTrace.record(BindingContext.PROCESSED, expression, true) + } + + val firstVarargIndex = parameters.withIndex().firstOrNull { it.value.getVarargElementType() != null }?.index + val useNamedFromIndex = if (firstVarargIndex != null && firstVarargIndex != parameters.lastIndex) firstVarargIndex else parameters.size() + + class DummyArgument(val index: Int) : ValueArgument { + private val expression = dummyArgumentExpressions[index] + + private val argumentName: ValueArgumentName? = if (isNamed()) { + object : ValueArgumentName { + override val asName = parameters[index].getName() + override val referenceExpression = null + } + } + else { + null + } + + override fun getArgumentExpression() = expression + override fun isNamed() = index >= useNamedFromIndex + override fun getArgumentName() = argumentName + override fun asElement() = expression + override fun getSpreadElement() = null + override fun isExternal() = false + } + + val arguments = ArrayList() + for (i in parameters.indices) { + arguments.add(DummyArgument(i)) + } + + val newCall = object : DelegatingCall(call) { + //TODO: compiler crash (KT-8011) + //val arguments = parameters.indices.map { DummyArgument(it) } + val callee = psiFactory.createExpressionByPattern("$0", name) + + override fun getCalleeExpression() = callee + + override fun getValueArgumentList() = null + + override fun getValueArguments() = arguments + + override fun getFunctionLiteralArguments() = emptyList() + + override fun getTypeArguments() = emptyList() + + override fun getTypeArgumentList() = null + } + + val calleeExpression = call.getCalleeExpression() ?: return descriptors + var resolutionScope = bindingContext.correctedResolutionScope(calleeExpression) ?: return descriptors + + if (importDeclarations) { + val importableDescriptors = descriptors.filter { it.canBeReferencedViaImport() } + resolutionScope = ChainedScope(resolutionScope.getContainingDeclaration(), "Scope with explicitly imported descriptors", + ExplicitImportsScope(importableDescriptors), resolutionScope) + } + + val dataFlowInfo = bindingContext.getDataFlowInfo(calleeExpression) + val context = BasicCallResolutionContext.create(bindingTrace, resolutionScope, newCall, TypeUtils.NO_EXPECTED_TYPE, dataFlowInfo, + ContextDependency.INDEPENDENT, CheckValueArgumentsMode.ENABLED, + CompositeChecker(listOf()), SymbolUsageValidator.Empty, AdditionalTypeChecker.Composite(listOf()), false) + val callResolver = InjectorForMacros(project, moduleDescriptor).getCallResolver() + val results = if (isFunction) callResolver.resolveFunctionCall(context) else callResolver.resolveSimpleProperty(context) + val resultingDescriptors = results.getResultingCalls().map { it.getResultingDescriptor() }.toSet() + val filtered = descriptors.filter { it in resultingDescriptors } + return if (filtered.isNotEmpty()) filtered else descriptors /* something went wrong, none of our declarations among resolve candidates, let's not filter anything */ + } + + private class DummyExpressionFactory(val factory: JetPsiFactory) { + private val expressions = ArrayList() + + fun createDummyExpressions(count: Int): List { + while (expressions.size() < count) { + expressions.add(factory.createExpression("dummy")) + } + return expressions.take(count) + } + } + + private class FunctionSignature(val function: FunctionDescriptor) { + override fun equals(other: Any?): Boolean { + if (other === this) return true + if (other !is FunctionSignature) return false + if (function.getName() != other.function.getName()) return false + val parameters1 = function.getValueParameters() + val parameters2 = other.function.getValueParameters() + if (parameters1.size() != parameters2.size()) return false + for (i in parameters1.indices) { + val p1 = parameters1[i] + val p2 = parameters2[i] + if (p1.getVarargElementType() != p2.getVarargElementType()) return false // both should be vararg or or both not + if (p1.getType() != p2.getType()) return false + } + return true + } + + override fun hashCode() = function.getName().hashCode() * 17 + function.getValueParameters().size() + } +} \ No newline at end of file diff --git a/idea/ide-common/src/org/jetbrains/kotlin/idea/util/Utils.kt b/idea/ide-common/src/org/jetbrains/kotlin/idea/util/Utils.kt index 8bd0518e496..31ee368c5af 100644 --- a/idea/ide-common/src/org/jetbrains/kotlin/idea/util/Utils.kt +++ b/idea/ide-common/src/org/jetbrains/kotlin/idea/util/Utils.kt @@ -16,8 +16,15 @@ package org.jetbrains.kotlin.idea.util +import org.jetbrains.kotlin.descriptors.DeclarationDescriptor +import org.jetbrains.kotlin.descriptors.VariableDescriptor import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.* +import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf +import org.jetbrains.kotlin.resolve.BindingContext +import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter +import org.jetbrains.kotlin.resolve.scopes.JetScope +import org.jetbrains.kotlin.utils.addIfNotNull public fun JetFunctionLiteral.findLabelAndCall(): Pair { val literalParent = (this.getParent() as JetFunctionLiteralExpression).getParent() @@ -44,3 +51,34 @@ public fun JetFunctionLiteral.findLabelAndCall(): Pair() + for (element in expression.parentsWithSelf) { + if (element is JetExpression) { + val declaration = element.getParent() as? JetVariableDeclaration ?: continue + if (element == declaration.getInitializer()) { + variablesToExclude.addIfNotNull(get(BindingContext.VARIABLE, declaration)) + } + } + } + + if (variablesToExclude.isEmpty()) return scope + + return object : JetScope by scope { + override fun getDescriptors(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean) + = scope.getDescriptors(kindFilter, nameFilter).filter { it !in variablesToExclude } + + //TODO: it's not correct! + override fun getLocalVariable(name: Name): VariableDescriptor? { + val variable = scope.getLocalVariable(name) ?: return null + return if (variable in variablesToExclude) null else variable + } + + override fun getProperties(name: Name) = scope.getProperties(name).filter { it !in variablesToExclude } + } +} \ No newline at end of file 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 2bae535f0c1..078608ddf80 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,6 +39,7 @@ import org.jetbrains.kotlin.idea.core.comparePossiblyOverridingDescriptors import org.jetbrains.kotlin.idea.core.isVisible import org.jetbrains.kotlin.idea.references.JetSimpleNameReference import org.jetbrains.kotlin.idea.util.CallType +import org.jetbrains.kotlin.idea.util.ShadowedDeclarationsFilter import org.jetbrains.kotlin.idea.util.makeNotNullable import org.jetbrains.kotlin.lexer.JetTokens import org.jetbrains.kotlin.load.java.descriptors.SamConstructorDescriptorKindExclude @@ -74,6 +75,7 @@ abstract class CompletionSessionBase(protected val configuration: CompletionSess private val file = position.getContainingFile() as JetFile protected val resolutionFacade: ResolutionFacade = file.getResolutionFacade() protected val moduleDescriptor: ModuleDescriptor = resolutionFacade.findModuleDescriptor(file) + protected val project: Project = position.getProject() protected val reference: JetSimpleNameReference? protected val expression: JetExpression? @@ -126,7 +128,7 @@ abstract class CompletionSessionBase(protected val configuration: CompletionSess protected val prefixMatcher: PrefixMatcher = this.resultSet.getPrefixMatcher() - protected val referenceVariantsHelper: ReferenceVariantsHelper = ReferenceVariantsHelper(bindingContext) { isVisibleDescriptor(it) } + protected val referenceVariantsHelper: ReferenceVariantsHelper = ReferenceVariantsHelper(bindingContext, moduleDescriptor, project) { isVisibleDescriptor(it) } protected val receiversData: ReferenceVariantsHelper.ReceiversData? = reference?.let { referenceVariantsHelper.getReferenceVariantsReceivers(it.expression) } @@ -158,8 +160,6 @@ abstract class CompletionSessionBase(protected val configuration: CompletionSess protected val collector: LookupElementsCollector = LookupElementsCollector(prefixMatcher, parameters, resolutionFacade, lookupElementFactory, inDescriptor, collectorContext) - protected val project: Project = position.getProject() - protected val originalSearchScope: GlobalSearchScope = ResolutionFacade.getResolveScope(parameters.getOriginalFile() as JetFile) // we need to exclude the original file from scope because our resolve session is built with this file replaced by synthetic one @@ -224,8 +224,12 @@ abstract class CompletionSessionBase(protected val configuration: CompletionSess protected fun getTopLevelCallables(): Collection = indicesHelper.getTopLevelCallables({ prefixMatcher.prefixMatches(it) }) - protected fun getTopLevelExtensions(): Collection - = indicesHelper.getCallableTopLevelExtensions({ prefixMatcher.prefixMatches(it) }, reference!!.expression) + protected fun getTopLevelExtensions(): Collection { + val extensions = indicesHelper.getCallableTopLevelExtensions({ prefixMatcher.prefixMatches(it) }, reference!!.expression) + //TODO: it filters out too much + //TODO: not filtered out dominated by members + return ShadowedDeclarationsFilter(bindingContext, moduleDescriptor, project, importDeclarations = true).filter(extensions, reference.expression) + } protected fun addAllClasses(kindFilter: (ClassKind) -> Boolean) { AllClassesCompletion( @@ -451,7 +455,7 @@ class SmartCompletionSession(configuration: CompletionSessionConfiguration, para val dummyArgument = object : FunctionLiteralArgument { override fun getFunctionLiteral() = throw UnsupportedOperationException() override fun getArgumentExpression() = throw UnsupportedOperationException() - override fun getArgumentName(): JetValueArgumentName? = null + override fun getArgumentName(): ValueArgumentName? = null override fun isNamed() = false override fun asElement() = throw UnsupportedOperationException() override fun getSpreadElement(): LeafPsiElement? = null 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 59460bd966c..1bf7e2a80e8 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 @@ -25,6 +25,7 @@ import org.jetbrains.kotlin.idea.completion.smart.toList import org.jetbrains.kotlin.idea.core.mapArgumentsToParameters import org.jetbrains.kotlin.idea.util.makeNotNullable import org.jetbrains.kotlin.lexer.JetTokens +import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.DelegatingBindingTrace @@ -63,9 +64,9 @@ data class ItemOptions(val starPrefix: Boolean) { open data class ExpectedInfo(val type: JetType, val expectedName: String?, val tail: Tail?, val itemOptions: ItemOptions = ItemOptions.DEFAULT) -data class ArgumentPosition(val argumentIndex: Int, val argumentName: String?, val isFunctionLiteralArgument: Boolean) { +data class ArgumentPosition(val argumentIndex: Int, val argumentName: Name?, val isFunctionLiteralArgument: Boolean) { constructor(argumentIndex: Int, isFunctionLiteralArgument: Boolean = false) : this(argumentIndex, null, isFunctionLiteralArgument) - constructor(argumentIndex: Int, argumentName: String?) : this(argumentIndex, argumentName, false) + constructor(argumentIndex: Int, argumentName: Name?) : this(argumentIndex, argumentName, false) } class ArgumentExpectedInfo(type: JetType, name: String?, tail: Tail?, val function: FunctionDescriptor, val position: ArgumentPosition, itemOptions: ItemOptions = ItemOptions.DEFAULT) @@ -133,7 +134,7 @@ class ExpectedInfos( assert(argumentIndex >= 0) { "Could not find argument '$argument' among arguments of call: $call" } - val argumentName = argument.getArgumentName()?.getReferenceExpression()?.getReferencedName() + val argumentName = argument.getArgumentName()?.asName val isFunctionLiteralArgument = argument is FunctionLiteralArgument val argumentPosition = ArgumentPosition(argumentIndex, argumentName, isFunctionLiteralArgument) @@ -243,9 +244,9 @@ class ExpectedInfos( return expectedInfos } - private fun namedArgumentTail(argumentToParameter: Map, argumentName: String, descriptor: FunctionDescriptor): Tail? { - val usedParameterNames = (argumentToParameter.values().map { it.getName().asString() } + listOf(argumentName)).toSet() - val notUsedParameters = descriptor.getValueParameters().filter { it.getName().asString() !in usedParameterNames } + private fun namedArgumentTail(argumentToParameter: Map, argumentName: Name, descriptor: FunctionDescriptor): Tail? { + val usedParameterNames = (argumentToParameter.values().map { it.getName() } + listOf(argumentName)).toSet() + val notUsedParameters = descriptor.getValueParameters().filter { it.getName() !in usedParameterNames } return if (notUsedParameters.isEmpty()) Tail.RPARENTH else if (notUsedParameters.all { it.hasDefaultValue() }) diff --git a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/PackageDirectiveCompletion.kt b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/PackageDirectiveCompletion.kt index 684372e8e85..57dc2d30122 100644 --- a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/PackageDirectiveCompletion.kt +++ b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/PackageDirectiveCompletion.kt @@ -51,8 +51,9 @@ object PackageDirectiveCompletion { val resolutionFacade = ref.expression.getResolutionFacade() val bindingContext = resolutionFacade.analyze(ref.expression) + val moduleDescriptor = resolutionFacade.findModuleDescriptor(file) - val variants = ReferenceVariantsHelper(bindingContext, { true }).getPackageReferenceVariants(ref.expression, prefixMatcher.asNameFilter()) + val variants = ReferenceVariantsHelper(bindingContext, moduleDescriptor, file.getProject(), { true }).getPackageReferenceVariants(ref.expression, prefixMatcher.asNameFilter()) for (variant in variants) { val lookupElement = LookupElementFactory(resolutionFacade, listOf()).createLookupElement(variant, false) if (!lookupElement.getLookupString().contains(DUMMY_IDENTIFIER)) { 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 9aed5a60b5e..ff3eb94709a 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 @@ -25,6 +25,7 @@ import org.jetbrains.kotlin.descriptors.VariableDescriptor import org.jetbrains.kotlin.idea.JetDescriptorIconProvider import org.jetbrains.kotlin.idea.completion.* import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers +import org.jetbrains.kotlin.idea.util.correctedResolutionScope import org.jetbrains.kotlin.psi.JetExpression import org.jetbrains.kotlin.renderer.render import org.jetbrains.kotlin.resolve.BindingContext @@ -40,7 +41,7 @@ class MultipleArgumentsItemProvider(val bindingContext: BindingContext, public fun addToCollection(collection: MutableCollection, expectedInfos: Collection, context: JetExpression) { - val resolutionScope = bindingContext[BindingContext.RESOLUTION_SCOPE, context] ?: return + val resolutionScope = bindingContext.correctedResolutionScope(context) ?: return val added = HashSet() for (expectedInfo in expectedInfos) { diff --git a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/smart/SmartCompletion.kt b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/smart/SmartCompletion.kt index 9c02ac39a54..8964ae58624 100644 --- a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/smart/SmartCompletion.kt +++ b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/smart/SmartCompletion.kt @@ -264,13 +264,6 @@ class SmartCompletion( private fun calcItemsToSkip(expression: JetExpression): Set { val parent = expression.getParent() when(parent) { - is JetProperty -> { - //TODO: this can be filtered out by ordinary completion - if (expression == parent.getInitializer()) { - return bindingContext[BindingContext.DECLARATION_TO_DESCRIPTOR, parent].toSet() - } - } - is JetBinaryExpression -> { if (parent.getRight() == expression) { val operationToken = parent.getOperationToken() diff --git a/idea/idea-completion/testData/basic/common/shadowing/InInitializer1.kt b/idea/idea-completion/testData/basic/common/shadowing/InInitializer1.kt new file mode 100644 index 00000000000..b379bb74980 --- /dev/null +++ b/idea/idea-completion/testData/basic/common/shadowing/InInitializer1.kt @@ -0,0 +1,6 @@ +fun foo(xxx: String) { + var xxx = xx +} + +// EXIST: { lookupString: "xxx", itemText: "xxx", typeText: "String" } +// NOTHING_ELSE diff --git a/idea/idea-completion/testData/basic/common/shadowing/InInitializer2.kt b/idea/idea-completion/testData/basic/common/shadowing/InInitializer2.kt new file mode 100644 index 00000000000..50e8e2c16ea --- /dev/null +++ b/idea/idea-completion/testData/basic/common/shadowing/InInitializer2.kt @@ -0,0 +1,5 @@ +fun foo() { + var xxx = +} + +// ABSENT: xxx diff --git a/idea/idea-completion/testData/basic/common/shadowing/InInitializer3.kt b/idea/idea-completion/testData/basic/common/shadowing/InInitializer3.kt new file mode 100644 index 00000000000..8f6985a2612 --- /dev/null +++ b/idea/idea-completion/testData/basic/common/shadowing/InInitializer3.kt @@ -0,0 +1,8 @@ +fun foo(xxx: Int) { + val xxx: Any = run { + xx + } +} + +// EXIST: { lookupString: "xxx", itemText: "xxx", typeText: "Int" } +// NOTHING_ELSE diff --git a/idea/idea-completion/testData/basic/common/shadowing/Locals1.kt b/idea/idea-completion/testData/basic/common/shadowing/Locals1.kt new file mode 100644 index 00000000000..81059e43592 --- /dev/null +++ b/idea/idea-completion/testData/basic/common/shadowing/Locals1.kt @@ -0,0 +1,15 @@ +class C { + val xxx = 1 + + fun foo(xxx: String) { + val xxx = 'x' + + if (true) { + val xxx = true + xx + } + } +} + +// EXIST: { lookupString: "xxx", itemText: "xxx", typeText: "Boolean" } +// NOTHING_ELSE diff --git a/idea/idea-completion/testData/basic/common/shadowing/Locals2.kt b/idea/idea-completion/testData/basic/common/shadowing/Locals2.kt new file mode 100644 index 00000000000..a1119f44b91 --- /dev/null +++ b/idea/idea-completion/testData/basic/common/shadowing/Locals2.kt @@ -0,0 +1,10 @@ +class C { + val xxx = 1 + + fun foo(xxx: String) { + xx + } +} + +// EXIST: { lookupString: "xxx", itemText: "xxx", typeText: "String" } +// NOTHING_ELSE diff --git a/idea/idea-completion/testData/basic/common/shadowing/Overloads.kt b/idea/idea-completion/testData/basic/common/shadowing/Overloads.kt new file mode 100644 index 00000000000..ccfa0fa1b8f --- /dev/null +++ b/idea/idea-completion/testData/basic/common/shadowing/Overloads.kt @@ -0,0 +1,17 @@ +package ppp + +class C { + fun xxx(p: Int) = "" + + fun foo() { + xx + } +} + +fun C.xxx(p: Int) = 1 +fun Any.xxx(c: Char) = 1 +fun C.xxx(c: Char) = 1 + +// EXIST: { lookupString: "xxx", itemText: "xxx", tailText: "(p: Int)", typeText: "String" } +// EXIST: { lookupString: "xxx", itemText: "xxx", tailText: "(c: Char) for C in ppp", typeText: "Int" } +// NOTHING_ELSE diff --git a/idea/idea-completion/testData/basic/common/shadowing/OverloadsAndVararg.kt b/idea/idea-completion/testData/basic/common/shadowing/OverloadsAndVararg.kt new file mode 100644 index 00000000000..b3a0aecf77b --- /dev/null +++ b/idea/idea-completion/testData/basic/common/shadowing/OverloadsAndVararg.kt @@ -0,0 +1,17 @@ +package ppp + +class C { + fun xxx(vararg s: String, p: Int) = "" + + fun foo() { + xx + } +} + +fun C.xxx(vararg s: String, p: Int) = 1 +fun Any.xxx(vararg s: String, c: Char) = 1 +fun C.xxx(vararg s: String, c: Char) = 1 + +// EXIST: { lookupString: "xxx", itemText: "xxx", tailText: "(vararg s: String, p: Int)", typeText: "String" } +// EXIST: { lookupString: "xxx", itemText: "xxx", tailText: "(vararg s: String, c: Char) for C in ppp", typeText: "Int" } +// NOTHING_ELSE diff --git a/idea/idea-completion/testData/basic/common/shadowing/PreferCloserMember.kt b/idea/idea-completion/testData/basic/common/shadowing/PreferCloserMember.kt new file mode 100644 index 00000000000..460899f9740 --- /dev/null +++ b/idea/idea-completion/testData/basic/common/shadowing/PreferCloserMember.kt @@ -0,0 +1,14 @@ +class C { + inner class Inner { + fun foo() { + xx + } + + val xxx: String get() = 1 + } + + val xxx: Int get() = 1 +} + +// EXIST: { lookupString: "xxx", itemText: "xxx", typeText: "String" } +// NOTHING_ELSE diff --git a/idea/idea-completion/testData/basic/common/shadowing/PreferMemberExtension.kt b/idea/idea-completion/testData/basic/common/shadowing/PreferMemberExtension.kt new file mode 100644 index 00000000000..913c4b6460b --- /dev/null +++ b/idea/idea-completion/testData/basic/common/shadowing/PreferMemberExtension.kt @@ -0,0 +1,19 @@ +interface I + +class C : I { + inner class Inner { + fun foo() { + xx + } + + val Any.xxx: Int get() = 1 + } + + val I.xxx: Int get() = 1 + +} + +val C.xxx: Int get() = 1 + +// EXIST: { lookupString: "xxx", itemText: "xxx", tailText: " for Any in C.Inner", typeText: "Int" } +// NOTHING_ELSE diff --git a/idea/idea-completion/testData/basic/common/shadowing/PreferMemberToExtension.kt b/idea/idea-completion/testData/basic/common/shadowing/PreferMemberToExtension.kt new file mode 100644 index 00000000000..63281448cfe --- /dev/null +++ b/idea/idea-completion/testData/basic/common/shadowing/PreferMemberToExtension.kt @@ -0,0 +1,24 @@ +package ppp + +class C { + val xxx = "" + fun xxx() = "" + fun xxx(p: Int) = "" + + fun foo() { + xx + } +} + +val C.xxx: Int + get() = 1 + +fun C.xxx() = 1 +fun C.xxx(p: Int) = 1 +fun C.xxx(p: String) = 1 + +// EXIST: { lookupString: "xxx", itemText: "xxx", tailText: null, typeText: "String" } +// EXIST: { lookupString: "xxx", itemText: "xxx", tailText: "()", typeText: "String" } +// EXIST: { lookupString: "xxx", itemText: "xxx", tailText: "(p: Int)", typeText: "String" } +// EXIST: { lookupString: "xxx", itemText: "xxx", tailText: "(p: String) for C in ppp", typeText: "Int" } +// NOTHING_ELSE diff --git a/idea/idea-completion/testData/basic/common/shadowing/PreferMemberToGlobal.kt b/idea/idea-completion/testData/basic/common/shadowing/PreferMemberToGlobal.kt new file mode 100644 index 00000000000..58cc265e091 --- /dev/null +++ b/idea/idea-completion/testData/basic/common/shadowing/PreferMemberToGlobal.kt @@ -0,0 +1,12 @@ +val xxx: Int get() = 1 + +class C { + fun foo() { + xx + } + + val xxx: String get() = 1 +} + +// EXIST: { lookupString: "xxx", itemText: "xxx", typeText: "String" } +// NOTHING_ELSE diff --git a/idea/idea-completion/testData/basic/common/shadowing/PreferMoreSpecificExtension.kt b/idea/idea-completion/testData/basic/common/shadowing/PreferMoreSpecificExtension.kt new file mode 100644 index 00000000000..c97b0522b9c --- /dev/null +++ b/idea/idea-completion/testData/basic/common/shadowing/PreferMoreSpecificExtension.kt @@ -0,0 +1,19 @@ +package ppp + +interface I + +class C : I { + fun foo() { + xx + } +} + +val Any.xxx: Int get() = 1 +val I.xxx: Int get() = 1 + +fun Any.xxx() = 1 +fun C.xxx() = 1 + +// EXIST: { lookupString: "xxx", itemText: "xxx", tailText: " for I in ppp", typeText: "Int" } +// EXIST: { lookupString: "xxx", itemText: "xxx", tailText: "() for C in ppp", typeText: "Int" } +// NOTHING_ELSE diff --git a/idea/idea-completion/testData/basic/multifile/PreferMoreSpecificExtension1/PreferMoreSpecificExtension1.dependency.kt b/idea/idea-completion/testData/basic/multifile/PreferMoreSpecificExtension1/PreferMoreSpecificExtension1.dependency.kt new file mode 100644 index 00000000000..7989c84e6e9 --- /dev/null +++ b/idea/idea-completion/testData/basic/multifile/PreferMoreSpecificExtension1/PreferMoreSpecificExtension1.dependency.kt @@ -0,0 +1,4 @@ +package dependency + +fun Any.xxx(): Int = 1 +fun ppp.C.xxx(): Int = 1 diff --git a/idea/idea-completion/testData/basic/multifile/PreferMoreSpecificExtension1/PreferMoreSpecificExtension1.kt b/idea/idea-completion/testData/basic/multifile/PreferMoreSpecificExtension1/PreferMoreSpecificExtension1.kt new file mode 100644 index 00000000000..1b75282e209 --- /dev/null +++ b/idea/idea-completion/testData/basic/multifile/PreferMoreSpecificExtension1/PreferMoreSpecificExtension1.kt @@ -0,0 +1,12 @@ +package ppp + +import dependency.* + +class C { + fun foo() { + xx + } +} + +// EXIST: { lookupString: "xxx", itemText: "xxx", tailText: "() for C in dependency", typeText: "Int" } +// NOTHING_ELSE diff --git a/idea/idea-completion/testData/basic/multifile/PreferMoreSpecificExtension2/PreferMoreSpecificExtension2.dependency.kt b/idea/idea-completion/testData/basic/multifile/PreferMoreSpecificExtension2/PreferMoreSpecificExtension2.dependency.kt new file mode 100644 index 00000000000..7989c84e6e9 --- /dev/null +++ b/idea/idea-completion/testData/basic/multifile/PreferMoreSpecificExtension2/PreferMoreSpecificExtension2.dependency.kt @@ -0,0 +1,4 @@ +package dependency + +fun Any.xxx(): Int = 1 +fun ppp.C.xxx(): Int = 1 diff --git a/idea/idea-completion/testData/basic/multifile/PreferMoreSpecificExtension2/PreferMoreSpecificExtension2.kt b/idea/idea-completion/testData/basic/multifile/PreferMoreSpecificExtension2/PreferMoreSpecificExtension2.kt new file mode 100644 index 00000000000..11b7993003d --- /dev/null +++ b/idea/idea-completion/testData/basic/multifile/PreferMoreSpecificExtension2/PreferMoreSpecificExtension2.kt @@ -0,0 +1,10 @@ +package ppp + +class C { + fun foo() { + xx + } +} + +// EXIST: { lookupString: "xxx", itemText: "xxx", tailText: "() for C in dependency", typeText: "Int" } +// NOTHING_ELSE diff --git a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/JSBasicCompletionTestGenerated.java b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/JSBasicCompletionTestGenerated.java index 49df4f3aa12..169b861bf69 100644 --- a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/JSBasicCompletionTestGenerated.java +++ b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/JSBasicCompletionTestGenerated.java @@ -1396,6 +1396,87 @@ public class JSBasicCompletionTestGenerated extends AbstractJSBasicCompletionTes } } + @TestMetadata("idea/idea-completion/testData/basic/common/shadowing") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Shadowing extends AbstractJSBasicCompletionTest { + public void testAllFilesPresentInShadowing() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/idea-completion/testData/basic/common/shadowing"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("InInitializer1.kt") + public void testInInitializer1() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/shadowing/InInitializer1.kt"); + doTest(fileName); + } + + @TestMetadata("InInitializer2.kt") + public void testInInitializer2() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/shadowing/InInitializer2.kt"); + doTest(fileName); + } + + @TestMetadata("InInitializer3.kt") + public void testInInitializer3() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/shadowing/InInitializer3.kt"); + doTest(fileName); + } + + @TestMetadata("Locals1.kt") + public void testLocals1() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/shadowing/Locals1.kt"); + doTest(fileName); + } + + @TestMetadata("Locals2.kt") + public void testLocals2() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/shadowing/Locals2.kt"); + doTest(fileName); + } + + @TestMetadata("Overloads.kt") + public void testOverloads() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/shadowing/Overloads.kt"); + doTest(fileName); + } + + @TestMetadata("OverloadsAndVararg.kt") + public void testOverloadsAndVararg() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/shadowing/OverloadsAndVararg.kt"); + doTest(fileName); + } + + @TestMetadata("PreferCloserMember.kt") + public void testPreferCloserMember() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/shadowing/PreferCloserMember.kt"); + doTest(fileName); + } + + @TestMetadata("PreferMemberExtension.kt") + public void testPreferMemberExtension() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/shadowing/PreferMemberExtension.kt"); + doTest(fileName); + } + + @TestMetadata("PreferMemberToExtension.kt") + public void testPreferMemberToExtension() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/shadowing/PreferMemberToExtension.kt"); + doTest(fileName); + } + + @TestMetadata("PreferMemberToGlobal.kt") + public void testPreferMemberToGlobal() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/shadowing/PreferMemberToGlobal.kt"); + doTest(fileName); + } + + @TestMetadata("PreferMoreSpecificExtension.kt") + public void testPreferMoreSpecificExtension() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/shadowing/PreferMoreSpecificExtension.kt"); + doTest(fileName); + } + } + @TestMetadata("idea/idea-completion/testData/basic/common/typeArgsOrNot") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/JvmBasicCompletionTestGenerated.java b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/JvmBasicCompletionTestGenerated.java index 44794e4c831..e9aaf98e02d 100644 --- a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/JvmBasicCompletionTestGenerated.java +++ b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/JvmBasicCompletionTestGenerated.java @@ -1396,6 +1396,87 @@ public class JvmBasicCompletionTestGenerated extends AbstractJvmBasicCompletionT } } + @TestMetadata("idea/idea-completion/testData/basic/common/shadowing") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Shadowing extends AbstractJvmBasicCompletionTest { + public void testAllFilesPresentInShadowing() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/idea-completion/testData/basic/common/shadowing"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("InInitializer1.kt") + public void testInInitializer1() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/shadowing/InInitializer1.kt"); + doTest(fileName); + } + + @TestMetadata("InInitializer2.kt") + public void testInInitializer2() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/shadowing/InInitializer2.kt"); + doTest(fileName); + } + + @TestMetadata("InInitializer3.kt") + public void testInInitializer3() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/shadowing/InInitializer3.kt"); + doTest(fileName); + } + + @TestMetadata("Locals1.kt") + public void testLocals1() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/shadowing/Locals1.kt"); + doTest(fileName); + } + + @TestMetadata("Locals2.kt") + public void testLocals2() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/shadowing/Locals2.kt"); + doTest(fileName); + } + + @TestMetadata("Overloads.kt") + public void testOverloads() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/shadowing/Overloads.kt"); + doTest(fileName); + } + + @TestMetadata("OverloadsAndVararg.kt") + public void testOverloadsAndVararg() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/shadowing/OverloadsAndVararg.kt"); + doTest(fileName); + } + + @TestMetadata("PreferCloserMember.kt") + public void testPreferCloserMember() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/shadowing/PreferCloserMember.kt"); + doTest(fileName); + } + + @TestMetadata("PreferMemberExtension.kt") + public void testPreferMemberExtension() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/shadowing/PreferMemberExtension.kt"); + doTest(fileName); + } + + @TestMetadata("PreferMemberToExtension.kt") + public void testPreferMemberToExtension() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/shadowing/PreferMemberToExtension.kt"); + doTest(fileName); + } + + @TestMetadata("PreferMemberToGlobal.kt") + public void testPreferMemberToGlobal() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/shadowing/PreferMemberToGlobal.kt"); + doTest(fileName); + } + + @TestMetadata("PreferMoreSpecificExtension.kt") + public void testPreferMoreSpecificExtension() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/shadowing/PreferMoreSpecificExtension.kt"); + doTest(fileName); + } + } + @TestMetadata("idea/idea-completion/testData/basic/common/typeArgsOrNot") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) 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 106c0676868..d862fc0ad17 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 @@ -209,6 +209,18 @@ public class MultiFileJvmBasicCompletionTestGenerated extends AbstractMultiFileJ doTest(fileName); } + @TestMetadata("PreferMoreSpecificExtension1") + public void testPreferMoreSpecificExtension1() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/multifile/PreferMoreSpecificExtension1/"); + doTest(fileName); + } + + @TestMetadata("PreferMoreSpecificExtension2") + public void testPreferMoreSpecificExtension2() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/multifile/PreferMoreSpecificExtension2/"); + doTest(fileName); + } + @TestMetadata("TopLevelFunction") public void testTopLevelFunction() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/multifile/TopLevelFunction/"); diff --git a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/Utils.kt b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/Utils.kt index f7cc0a32b41..bff4ef49c12 100644 --- a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/Utils.kt +++ b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/Utils.kt @@ -29,7 +29,7 @@ public fun Call.mapArgumentsToParameters(targetDescriptor: CallableDescriptor): if (parameters.isEmpty()) return emptyMap() val map = HashMap() - val parametersByName = parameters.toMap { it.getName().asString() } + val parametersByName = parameters.toMap { it.getName() } var positionalArgumentIndex: Int? = 0 @@ -38,7 +38,7 @@ public fun Call.mapArgumentsToParameters(targetDescriptor: CallableDescriptor): map[argument] = parameters.last() } else { - val argumentName = argument.getArgumentName()?.getReferenceExpression()?.getReferencedName() + val argumentName = argument.getArgumentName()?.asName if (argumentName != null) { if (targetDescriptor.hasStableParameterNames()) { diff --git a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/psiModificationUtils.kt b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/psiModificationUtils.kt index cf4d3a324fe..54b86fd30cf 100644 --- a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/psiModificationUtils.kt +++ b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/psiModificationUtils.kt @@ -61,7 +61,7 @@ public fun JetFunctionLiteralArgument.moveInsideParenthesesAndReplaceWith( val newCallExpression = oldCallExpression.copy() as JetCallExpression val psiFactory = JetPsiFactory(getProject()) - val argument = if (newCallExpression.getValueArgumentsInParentheses().any { it.getArgumentName() != null }) { + val argument = if (newCallExpression.getValueArgumentsInParentheses().any { it.isNamed() }) { psiFactory.createArgument(replacement, functionLiteralArgumentName) } else { diff --git a/idea/src/org/jetbrains/kotlin/idea/parameterInfo/JetFunctionParameterInfoHandler.java b/idea/src/org/jetbrains/kotlin/idea/parameterInfo/JetFunctionParameterInfoHandler.java index 52049c7abaf..89606052d28 100644 --- a/idea/src/org/jetbrains/kotlin/idea/parameterInfo/JetFunctionParameterInfoHandler.java +++ b/idea/src/org/jetbrains/kotlin/idea/parameterInfo/JetFunctionParameterInfoHandler.java @@ -385,6 +385,7 @@ public class JetFunctionParameterInfoHandler implements ParameterInfoHandlerWith ResolutionFacade resolutionFacade = ResolvePackage.getResolutionFacade(callNameExpression.getContainingJetFile()); BindingContext bindingContext = resolutionFacade.analyze(callNameExpression, BodyResolveMode.FULL); + ModuleDescriptor moduleDescriptor = resolutionFacade.findModuleDescriptor(callNameExpression); JetScope scope = bindingContext.get(BindingContext.RESOLUTION_SCOPE, callNameExpression); final DeclarationDescriptor placeDescriptor; @@ -409,7 +410,7 @@ public class JetFunctionParameterInfoHandler implements ParameterInfoHandlerWith return name.equals(refName); } }; - Collection variants = new ReferenceVariantsHelper(bindingContext, visibilityFilter).getReferenceVariants( + Collection variants = new ReferenceVariantsHelper(bindingContext, moduleDescriptor, file.getProject(), visibilityFilter).getReferenceVariants( callNameExpression, new DescriptorKindFilter(DescriptorKindFilter.FUNCTIONS_MASK | DescriptorKindFilter.CLASSIFIERS_MASK, Collections.emptyList()), false, nameFilter); diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeFunctionSignatureFix.java b/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeFunctionSignatureFix.java index 5b95dbe42cd..c3ec4a48817 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeFunctionSignatureFix.java +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeFunctionSignatureFix.java @@ -98,11 +98,11 @@ public abstract class ChangeFunctionSignatureFix extends JetIntentionAction throw IllegalArgumentException("Cannot find resolution scope for $descriptor") } } - - private class ExplicitImportsScope(val descriptors: Collection) : JetScope { - override fun getClassifier(name: Name) = descriptors.filter { it.getName() == name }.firstIsInstanceOrNull() - - override fun getPackage(name: Name)= descriptors.filter { it.getName() == name }.firstIsInstanceOrNull() - - override fun getProperties(name: Name) = descriptors.filter { it.getName() == name }.filterIsInstance() - - override fun getLocalVariable(name: Name): VariableDescriptor? = null - - override fun getFunctions(name: Name) = descriptors.filter { it.getName() == name }.filterIsInstance() - - override fun getContainingDeclaration() = throw UnsupportedOperationException() - - override fun getDeclarationsByLabel(labelName: Name) = emptyList() - - override fun getDescriptors(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean) = descriptors - - override fun getImplicitReceiversHierarchy() = emptyList() - - override fun getOwnDeclaredDescriptors() = emptyList() - - override fun printScopeStructure(p: Printer) { - p.println(javaClass.getName()) - } - } } \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createCallable/CreateConstructorFromDelegationCallActionFactory.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createCallable/CreateConstructorFromDelegationCallActionFactory.kt index 805d7ac970f..51775960af6 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createCallable/CreateConstructorFromDelegationCallActionFactory.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createCallable/CreateConstructorFromDelegationCallActionFactory.kt @@ -59,7 +59,7 @@ object CreateConstructorFromDelegationCallActionFactory : JetSingleIntentionActi val parameters = delegationCall.getValueArguments().map { ParameterInfo( it.getArgumentExpression()?.let { TypeInfo(it, Variance.IN_VARIANCE) } ?: TypeInfo(anyType, Variance.IN_VARIANCE), - it.getArgumentName()?.getReferenceExpression()?.getReferencedName() + it.getArgumentName()?.asName?.asString() ) } diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createCallable/CreateConstructorFromDelegatorToSuperCallActionFactory.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createCallable/CreateConstructorFromDelegatorToSuperCallActionFactory.kt index c3af941c505..38bfc9f4c29 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createCallable/CreateConstructorFromDelegatorToSuperCallActionFactory.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createCallable/CreateConstructorFromDelegatorToSuperCallActionFactory.kt @@ -55,7 +55,7 @@ object CreateConstructorFromDelegatorToSuperCallActionFactory : JetSingleIntenti val parameters = delegationCall.getValueArguments().map { ParameterInfo( it.getArgumentExpression()?.let { TypeInfo(it, Variance.IN_VARIANCE) } ?: TypeInfo(anyType, Variance.IN_VARIANCE), - it.getArgumentName()?.getReferenceExpression()?.getReferencedName() + it.getArgumentName()?.asName?.asString() ) } diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createClass/CreateClassFromCallWithConstructorCalleeActionFactory.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createClass/CreateClassFromCallWithConstructorCalleeActionFactory.kt index 8a5fb028a49..edd73429ce3 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createClass/CreateClassFromCallWithConstructorCalleeActionFactory.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createClass/CreateClassFromCallWithConstructorCalleeActionFactory.kt @@ -69,7 +69,7 @@ public object CreateClassFromCallWithConstructorCalleeActionFactory : JetSingleI val parameterInfos = valueArguments.map { ParameterInfo( it.getArgumentExpression()?.let { TypeInfo(it, Variance.IN_VARIANCE) } ?: TypeInfo(anyType, Variance.IN_VARIANCE), - it.getArgumentName()?.getReferenceExpression()?.getReferencedName() ?: defaultParamName + it.getArgumentName()?.asName?.asString() ?: defaultParamName ) } diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/changeSignature/usages/JetFunctionCallUsage.java b/idea/src/org/jetbrains/kotlin/idea/refactoring/changeSignature/usages/JetFunctionCallUsage.java index f1d43830812..e302f1d25dd 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/changeSignature/usages/JetFunctionCallUsage.java +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/changeSignature/usages/JetFunctionCallUsage.java @@ -293,7 +293,7 @@ public class JetFunctionCallUsage extends JetUsageInfo { assert arguments != null : "Argument list is expected: " + element.getText(); List oldArguments = element.getValueArguments(); - boolean isNamedCall = oldArguments.size() > 1 && oldArguments.get(0).getArgumentName() != null; + boolean isNamedCall = oldArguments.size() > 1 && oldArguments.get(0).isNamed(); StringBuilder parametersBuilder = new StringBuilder("("); boolean isFirst = true; @@ -364,7 +364,7 @@ public class JetFunctionCallUsage extends JetUsageInfo { ValueArgument oldArgument = argumentMap.get(parameterInfo.getOldIndex()); if (oldArgument != null) { - JetValueArgumentName argumentName = oldArgument.getArgumentName(); + ValueArgumentName argumentName = oldArgument.getArgumentName(); JetSimpleNameExpression argumentNameExpression = argumentName != null ? argumentName.getReferenceExpression() : null; changeArgumentName(argumentNameExpression, parameterInfo); //noinspection ConstantConditions @@ -457,9 +457,8 @@ public class JetFunctionCallUsage extends JetUsageInfo { for (int i = 0; i < oldArguments.size(); i++) { ValueArgument argument = oldArguments.get(i); - JetValueArgumentName argumentName = argument.getArgumentName(); - JetSimpleNameExpression argumentNameExpression = argumentName != null ? argumentName.getReferenceExpression() : null; - String oldParameterName = argumentNameExpression != null ? argumentNameExpression.getReferencedName() : null; + ValueArgumentName argumentName = argument.getArgumentName(); + String oldParameterName = argumentName != null ? argumentName.getAsName().asString() : null; if (oldParameterName != null) { Integer oldParameterIndex = changeInfo.getOldParameterIndex(oldParameterName); @@ -476,7 +475,7 @@ public class JetFunctionCallUsage extends JetUsageInfo { private void changeArgumentNames(JetChangeInfo changeInfo, JetCallElement element) { for (ValueArgument argument : element.getValueArguments()) { - JetValueArgumentName argumentName = argument.getArgumentName(); + ValueArgumentName argumentName = argument.getArgumentName(); JetSimpleNameExpression argumentNameExpression = argumentName != null ? argumentName.getReferenceExpression() : null; if (argumentNameExpression != null) {