KT-4893 Code completion should not show multiple functions with the same signature

#KT-4893 Fixed
This commit is contained in:
Valentin Kipyatkov
2015-06-09 23:10:47 +03:00
parent 4c0e7e32e7
commit 483da9607c
43 changed files with 737 additions and 106 deletions
@@ -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();
}
}
@@ -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?
}
@@ -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);
}
@@ -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,
@@ -60,7 +60,7 @@ public class CallMaker {
}
@Override
public JetValueArgumentName getArgumentName() {
public ValueArgumentName getArgumentName() {
return null;
}
@@ -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<DeclarationDescriptor>) : JetScope {
override fun getClassifier(name: Name) = descriptors.filter { it.getName() == name }.firstIsInstanceOrNull<ClassifierDescriptor>()
override fun getPackage(name: Name)= descriptors.filter { it.getName() == name }.firstIsInstanceOrNull<PackageViewDescriptor>()
override fun getProperties(name: Name) = descriptors.filter { it.getName() == name }.filterIsInstance<VariableDescriptor>()
override fun getLocalVariable(name: Name): VariableDescriptor? = null
override fun getFunctions(name: Name) = descriptors.filter { it.getName() == name }.filterIsInstance<FunctionDescriptor>()
override fun getContainingDeclaration() = throw UnsupportedOperationException()
override fun getDeclarationsByLabel(labelName: Name) = emptyList<DeclarationDescriptor>()
override fun getDescriptors(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean) = descriptors
override fun getImplicitReceiversHierarchy() = emptyList<ReceiverParameterDescriptor>()
override fun getOwnDeclaredDescriptors() = emptyList<DeclarationDescriptor>()
override fun printScopeStructure(p: Printer) {
p.println(javaClass.getName())
}
}
@@ -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<ReceiverValue>,
public val callType: CallType
@@ -59,7 +63,10 @@ public class ReferenceVariantsHelper(
useRuntimeReceiverType: Boolean,
nameFilter: (Name) -> Boolean
): Collection<DeclarationDescriptor> {
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<DeclarationDescriptor> {
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<DeclarationDescriptor>()
val pair = getExplicitReceiverData(expression)
if (pair != null) {
val (receiverExpression, callType) = pair
// Process as call expression
val descriptors = HashSet<DeclarationDescriptor>()
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<DeclarationDescriptor>()
// 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<DeclarationDescriptor>.addMembersFromReceiver(
@@ -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 <TDescriptor : DeclarationDescriptor> filter(declarations: Collection<TDescriptor>, expression: JetSimpleNameExpression): Collection<TDescriptor> {
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 <TDescriptor : DeclarationDescriptor> filterEqualSignatureGroup(descriptors: Collection<TDescriptor>, call: Call): Collection<TDescriptor> {
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<DummyArgument>()
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<FunctionLiteralArgument>()
override fun getTypeArguments() = emptyList<JetTypeProjection>()
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<JetExpression>()
fun createDummyExpressions(count: Int): List<JetExpression> {
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()
}
}
@@ -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<Name?, JetCallExpression?> {
val literalParent = (this.getParent() as JetFunctionLiteralExpression).getParent()
@@ -44,3 +51,34 @@ public fun JetFunctionLiteral.findLabelAndCall(): Pair<Name?, JetCallExpression?
}
}
}
// returns corrected resolution scope excluding variable inside its own initializer
// will not be needed after correcting JetScope stored BindingContext (see KT-4822 Wrong scope is used for local variable name completion)
public fun BindingContext.correctedResolutionScope(expression: JetExpression): JetScope? {
val scope = get(BindingContext.RESOLUTION_SCOPE, expression) ?: return null
val variablesToExclude = hashSetOf<VariableDescriptor>()
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 }
}
}
@@ -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<DeclarationDescriptor>
= indicesHelper.getTopLevelCallables({ prefixMatcher.prefixMatches(it) })
protected fun getTopLevelExtensions(): Collection<CallableDescriptor>
= indicesHelper.getCallableTopLevelExtensions({ prefixMatcher.prefixMatches(it) }, reference!!.expression)
protected fun getTopLevelExtensions(): Collection<CallableDescriptor> {
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
@@ -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<ValueArgument, ValueParameterDescriptor>, 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<ValueArgument, ValueParameterDescriptor>, 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() })
@@ -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)) {
@@ -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<LookupElement>,
expectedInfos: Collection<ExpectedInfo>,
context: JetExpression) {
val resolutionScope = bindingContext[BindingContext.RESOLUTION_SCOPE, context] ?: return
val resolutionScope = bindingContext.correctedResolutionScope(context) ?: return
val added = HashSet<String>()
for (expectedInfo in expectedInfos) {
@@ -264,13 +264,6 @@ class SmartCompletion(
private fun calcItemsToSkip(expression: JetExpression): Set<DeclarationDescriptor> {
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()
@@ -0,0 +1,6 @@
fun foo(xxx: String) {
var xxx = xx<caret>
}
// EXIST: { lookupString: "xxx", itemText: "xxx", typeText: "String" }
// NOTHING_ELSE
@@ -0,0 +1,5 @@
fun foo() {
var xxx = <caret>
}
// ABSENT: xxx
@@ -0,0 +1,8 @@
fun foo(xxx: Int) {
val xxx: Any = run {
xx<caret>
}
}
// EXIST: { lookupString: "xxx", itemText: "xxx", typeText: "Int" }
// NOTHING_ELSE
@@ -0,0 +1,15 @@
class C {
val xxx = 1
fun foo(xxx: String) {
val xxx = 'x'
if (true) {
val xxx = true
xx<caret>
}
}
}
// EXIST: { lookupString: "xxx", itemText: "xxx", typeText: "Boolean" }
// NOTHING_ELSE
@@ -0,0 +1,10 @@
class C {
val xxx = 1
fun foo(xxx: String) {
xx<caret>
}
}
// EXIST: { lookupString: "xxx", itemText: "xxx", typeText: "String" }
// NOTHING_ELSE
@@ -0,0 +1,17 @@
package ppp
class C {
fun xxx(p: Int) = ""
fun foo() {
xx<caret>
}
}
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
@@ -0,0 +1,17 @@
package ppp
class C {
fun xxx(vararg s: String, p: Int) = ""
fun foo() {
xx<caret>
}
}
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
@@ -0,0 +1,14 @@
class C {
inner class Inner {
fun foo() {
xx<caret>
}
val xxx: String get() = 1
}
val xxx: Int get() = 1
}
// EXIST: { lookupString: "xxx", itemText: "xxx", typeText: "String" }
// NOTHING_ELSE
@@ -0,0 +1,19 @@
interface I
class C : I {
inner class Inner {
fun foo() {
xx<caret>
}
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
@@ -0,0 +1,24 @@
package ppp
class C {
val xxx = ""
fun xxx() = ""
fun xxx(p: Int) = ""
fun foo() {
xx<caret>
}
}
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
@@ -0,0 +1,12 @@
val xxx: Int get() = 1
class C {
fun foo() {
xx<caret>
}
val xxx: String get() = 1
}
// EXIST: { lookupString: "xxx", itemText: "xxx", typeText: "String" }
// NOTHING_ELSE
@@ -0,0 +1,19 @@
package ppp
interface I
class C : I {
fun foo() {
xx<caret>
}
}
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
@@ -0,0 +1,4 @@
package dependency
fun Any.xxx(): Int = 1
fun ppp.C.xxx(): Int = 1
@@ -0,0 +1,12 @@
package ppp
import dependency.*
class C {
fun foo() {
xx<caret>
}
}
// EXIST: { lookupString: "xxx", itemText: "xxx", tailText: "() for C in dependency", typeText: "Int" }
// NOTHING_ELSE
@@ -0,0 +1,4 @@
package dependency
fun Any.xxx(): Int = 1
fun ppp.C.xxx(): Int = 1
@@ -0,0 +1,10 @@
package ppp
class C {
fun foo() {
xx<caret>
}
}
// EXIST: { lookupString: "xxx", itemText: "xxx", tailText: "() for C in dependency", typeText: "Int" }
// NOTHING_ELSE
@@ -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)
@@ -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)
@@ -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/");
@@ -29,7 +29,7 @@ public fun Call.mapArgumentsToParameters(targetDescriptor: CallableDescriptor):
if (parameters.isEmpty()) return emptyMap()
val map = HashMap<ValueArgument, ValueParameterDescriptor>()
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()) {
@@ -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 {
@@ -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<DeclarationDescriptor> variants = new ReferenceVariantsHelper(bindingContext, visibilityFilter).getReferenceVariants(
Collection<DeclarationDescriptor> variants = new ReferenceVariantsHelper(bindingContext, moduleDescriptor, file.getProject(), visibilityFilter).getReferenceVariants(
callNameExpression, new DescriptorKindFilter(DescriptorKindFilter.FUNCTIONS_MASK | DescriptorKindFilter.CLASSIFIERS_MASK,
Collections.<DescriptorKindExclude>emptyList()), false, nameFilter);
@@ -98,11 +98,11 @@ public abstract class ChangeFunctionSignatureFix extends JetIntentionAction<PsiE
}
protected static String getNewArgumentName(ValueArgument argument, JetNameValidator validator) {
JetValueArgumentName argumentName = argument.getArgumentName();
ValueArgumentName argumentName = argument.getArgumentName();
JetExpression expression = argument.getArgumentExpression();
if (argumentName != null) {
return validator.validateName(argumentName.getName());
return validator.validateName(argumentName.getAsName().asString());
}
else if (expression != null) {
return JetNameSuggester.suggestNames(expression, validator, "param")[0];
@@ -189,30 +189,4 @@ object ReplaceWithAnnotationAnalyzer {
else -> throw IllegalArgumentException("Cannot find resolution scope for $descriptor")
}
}
private class ExplicitImportsScope(val descriptors: Collection<DeclarationDescriptor>) : JetScope {
override fun getClassifier(name: Name) = descriptors.filter { it.getName() == name }.firstIsInstanceOrNull<ClassifierDescriptor>()
override fun getPackage(name: Name)= descriptors.filter { it.getName() == name }.firstIsInstanceOrNull<PackageViewDescriptor>()
override fun getProperties(name: Name) = descriptors.filter { it.getName() == name }.filterIsInstance<VariableDescriptor>()
override fun getLocalVariable(name: Name): VariableDescriptor? = null
override fun getFunctions(name: Name) = descriptors.filter { it.getName() == name }.filterIsInstance<FunctionDescriptor>()
override fun getContainingDeclaration() = throw UnsupportedOperationException()
override fun getDeclarationsByLabel(labelName: Name) = emptyList<DeclarationDescriptor>()
override fun getDescriptors(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean) = descriptors
override fun getImplicitReceiversHierarchy() = emptyList<ReceiverParameterDescriptor>()
override fun getOwnDeclaredDescriptors() = emptyList<DeclarationDescriptor>()
override fun printScopeStructure(p: Printer) {
p.println(javaClass.getName())
}
}
}
@@ -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()
)
}
@@ -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()
)
}
@@ -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
)
}
@@ -293,7 +293,7 @@ public class JetFunctionCallUsage extends JetUsageInfo<JetCallElement> {
assert arguments != null : "Argument list is expected: " + element.getText();
List<? extends ValueArgument> 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<JetCallElement> {
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<JetCallElement> {
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<JetCallElement> {
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) {