KT-4893 Code completion should not show multiple functions with the same signature
#KT-4893 Fixed
This commit is contained in:
@@ -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?
|
||||
}
|
||||
|
||||
+14
-6
@@ -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())
|
||||
}
|
||||
}
|
||||
+34
-32
@@ -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() })
|
||||
|
||||
+2
-1
@@ -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)) {
|
||||
|
||||
+2
-1
@@ -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
|
||||
+19
@@ -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
|
||||
+24
@@ -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
|
||||
+19
@@ -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
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
package dependency
|
||||
|
||||
fun Any.xxx(): Int = 1
|
||||
fun ppp.C.xxx(): Int = 1
|
||||
+12
@@ -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
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
package dependency
|
||||
|
||||
fun Any.xxx(): Int = 1
|
||||
fun ppp.C.xxx(): Int = 1
|
||||
+10
@@ -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
|
||||
+81
@@ -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)
|
||||
|
||||
+81
@@ -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)
|
||||
|
||||
+12
@@ -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 {
|
||||
|
||||
+2
-1
@@ -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())
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -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()
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -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()
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -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
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
+5
-6
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user