Smart completion: support for overloaded method calls

This commit is contained in:
Valentin Kipyatkov
2014-03-27 15:21:57 +04:00
parent 15364ceae6
commit 50bb90a1e3
13 changed files with 279 additions and 38 deletions
@@ -21,21 +21,21 @@ import org.jetbrains.jet.lang.descriptors.ModuleDescriptor;
import org.jetbrains.jet.lang.PlatformToKotlinClassMap;
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices;
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingComponents;
import org.jetbrains.jet.lang.resolve.calls.CallResolver;
import org.jetbrains.jet.context.GlobalContext;
import org.jetbrains.jet.storage.StorageManager;
import org.jetbrains.jet.lang.resolve.AnnotationResolver;
import org.jetbrains.jet.lang.resolve.calls.CallResolver;
import org.jetbrains.jet.lang.resolve.calls.ArgumentTypeResolver;
import org.jetbrains.jet.lang.resolve.TypeResolver;
import org.jetbrains.jet.lang.resolve.QualifiedExpressionResolver;
import org.jetbrains.jet.lang.resolve.calls.CandidateResolver;
import org.jetbrains.jet.lang.resolve.calls.CallExpressionResolver;
import org.jetbrains.jet.lang.resolve.DescriptorResolver;
import org.jetbrains.jet.lang.resolve.DelegatedPropertyResolver;
import org.jetbrains.jet.lang.resolve.TypeResolver;
import org.jetbrains.jet.lang.resolve.QualifiedExpressionResolver;
import org.jetbrains.jet.lang.resolve.calls.CallResolverExtensionProvider;
import org.jetbrains.jet.lang.types.expressions.ControlStructureTypingUtils;
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingUtils;
import org.jetbrains.jet.lang.types.expressions.ForLoopConventionsChecker;
import org.jetbrains.jet.lang.resolve.calls.ArgumentTypeResolver;
import org.jetbrains.jet.lang.resolve.calls.CandidateResolver;
import org.jetbrains.annotations.NotNull;
import javax.annotation.PreDestroy;
@@ -48,21 +48,21 @@ public class InjectorForMacros {
private final PlatformToKotlinClassMap platformToKotlinClassMap;
private final ExpressionTypingServices expressionTypingServices;
private final ExpressionTypingComponents expressionTypingComponents;
private final CallResolver callResolver;
private final GlobalContext globalContext;
private final StorageManager storageManager;
private final AnnotationResolver annotationResolver;
private final CallResolver callResolver;
private final ArgumentTypeResolver argumentTypeResolver;
private final TypeResolver typeResolver;
private final QualifiedExpressionResolver qualifiedExpressionResolver;
private final CandidateResolver candidateResolver;
private final CallExpressionResolver callExpressionResolver;
private final DescriptorResolver descriptorResolver;
private final DelegatedPropertyResolver delegatedPropertyResolver;
private final TypeResolver typeResolver;
private final QualifiedExpressionResolver qualifiedExpressionResolver;
private final CallResolverExtensionProvider callResolverExtensionProvider;
private final ControlStructureTypingUtils controlStructureTypingUtils;
private final ExpressionTypingUtils expressionTypingUtils;
private final ForLoopConventionsChecker forLoopConventionsChecker;
private final ArgumentTypeResolver argumentTypeResolver;
private final CandidateResolver candidateResolver;
public InjectorForMacros(
@NotNull Project project,
@@ -73,21 +73,21 @@ public class InjectorForMacros {
this.platformToKotlinClassMap = moduleDescriptor.getPlatformToKotlinClassMap();
this.expressionTypingComponents = new ExpressionTypingComponents();
this.expressionTypingServices = new ExpressionTypingServices(getExpressionTypingComponents());
this.callResolver = new CallResolver();
this.globalContext = org.jetbrains.jet.context.ContextPackage.GlobalContext();
this.storageManager = globalContext.getStorageManager();
this.annotationResolver = new AnnotationResolver();
this.callResolver = new CallResolver();
this.argumentTypeResolver = new ArgumentTypeResolver();
this.typeResolver = new TypeResolver();
this.qualifiedExpressionResolver = new QualifiedExpressionResolver();
this.candidateResolver = new CandidateResolver();
this.callExpressionResolver = new CallExpressionResolver();
this.descriptorResolver = new DescriptorResolver();
this.delegatedPropertyResolver = new DelegatedPropertyResolver();
this.typeResolver = new TypeResolver();
this.qualifiedExpressionResolver = new QualifiedExpressionResolver();
this.callResolverExtensionProvider = new CallResolverExtensionProvider();
this.controlStructureTypingUtils = new ControlStructureTypingUtils(getExpressionTypingServices());
this.expressionTypingUtils = new ExpressionTypingUtils(getExpressionTypingServices(), callResolver);
this.expressionTypingUtils = new ExpressionTypingUtils(getExpressionTypingServices(), getCallResolver());
this.forLoopConventionsChecker = new ForLoopConventionsChecker();
this.argumentTypeResolver = new ArgumentTypeResolver();
this.candidateResolver = new CandidateResolver();
this.expressionTypingServices.setAnnotationResolver(annotationResolver);
this.expressionTypingServices.setCallExpressionResolver(callExpressionResolver);
@@ -105,24 +105,15 @@ public class InjectorForMacros {
this.expressionTypingComponents.setGlobalContext(globalContext);
this.expressionTypingComponents.setPlatformToKotlinClassMap(platformToKotlinClassMap);
this.callResolver.setArgumentTypeResolver(argumentTypeResolver);
this.callResolver.setCandidateResolver(candidateResolver);
this.callResolver.setExpressionTypingServices(expressionTypingServices);
this.callResolver.setTypeResolver(typeResolver);
annotationResolver.setCallResolver(callResolver);
annotationResolver.setStorageManager(storageManager);
annotationResolver.setTypeResolver(typeResolver);
callResolver.setArgumentTypeResolver(argumentTypeResolver);
callResolver.setCandidateResolver(candidateResolver);
callResolver.setExpressionTypingServices(expressionTypingServices);
callResolver.setTypeResolver(typeResolver);
argumentTypeResolver.setExpressionTypingServices(expressionTypingServices);
argumentTypeResolver.setTypeResolver(typeResolver);
typeResolver.setAnnotationResolver(annotationResolver);
typeResolver.setModuleDescriptor(moduleDescriptor);
typeResolver.setQualifiedExpressionResolver(qualifiedExpressionResolver);
candidateResolver.setArgumentTypeResolver(argumentTypeResolver);
callExpressionResolver.setExpressionTypingServices(expressionTypingServices);
descriptorResolver.setAnnotationResolver(annotationResolver);
@@ -134,10 +125,19 @@ public class InjectorForMacros {
delegatedPropertyResolver.setCallResolver(callResolver);
delegatedPropertyResolver.setExpressionTypingServices(expressionTypingServices);
typeResolver.setAnnotationResolver(annotationResolver);
typeResolver.setModuleDescriptor(moduleDescriptor);
typeResolver.setQualifiedExpressionResolver(qualifiedExpressionResolver);
forLoopConventionsChecker.setExpressionTypingServices(expressionTypingServices);
forLoopConventionsChecker.setExpressionTypingUtils(expressionTypingUtils);
forLoopConventionsChecker.setProject(project);
argumentTypeResolver.setExpressionTypingServices(expressionTypingServices);
argumentTypeResolver.setTypeResolver(typeResolver);
candidateResolver.setArgumentTypeResolver(argumentTypeResolver);
}
@PreDestroy
@@ -152,4 +152,8 @@ public class InjectorForMacros {
return this.expressionTypingComponents;
}
public CallResolver getCallResolver() {
return this.callResolver;
}
}
@@ -23,6 +23,8 @@ import com.intellij.psi.impl.source.tree.LeafPsiElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue;
import org.jetbrains.jet.lang.psi.Call.CallType;
@@ -159,12 +161,14 @@ public class CallMaker {
}
}
@NotNull
public static Call makeCallWithExpressions(@NotNull JetElement callElement, @NotNull ReceiverValue explicitReceiver,
@Nullable ASTNode callOperationNode, @NotNull JetExpression calleeExpression,
@NotNull List<JetExpression> argumentExpressions) {
return makeCallWithExpressions(callElement, explicitReceiver, callOperationNode, calleeExpression, argumentExpressions, CallType.DEFAULT);
}
@NotNull
public static Call makeCallWithExpressions(@NotNull JetElement callElement, @NotNull ReceiverValue explicitReceiver,
@Nullable ASTNode callOperationNode, @NotNull JetExpression calleeExpression,
@NotNull List<JetExpression> argumentExpressions, @NotNull CallType callType) {
@@ -175,23 +179,28 @@ public class CallMaker {
return makeCall(callElement, explicitReceiver, callOperationNode, calleeExpression, arguments, callType);
}
@NotNull
public static Call makeCall(JetElement callElement, ReceiverValue explicitReceiver, @Nullable ASTNode callOperationNode, JetExpression calleeExpression, List<? extends ValueArgument> arguments) {
return makeCall(callElement, explicitReceiver, callOperationNode, calleeExpression, arguments, CallType.DEFAULT);
}
@NotNull
public static Call makeCall(JetElement callElement, ReceiverValue explicitReceiver, @Nullable ASTNode callOperationNode,
JetExpression calleeExpression, List<? extends ValueArgument> arguments, CallType callType) {
return new CallImpl(callElement, explicitReceiver, callOperationNode, calleeExpression, arguments, callType);
}
@NotNull
public static Call makeCall(@NotNull ReceiverValue leftAsReceiver, JetBinaryExpression expression) {
return makeCallWithExpressions(expression, leftAsReceiver, null, expression.getOperationReference(), Collections.singletonList(expression.getRight()));
}
@NotNull
public static Call makeCall(@NotNull ReceiverValue baseAsReceiver, JetUnaryExpression expression) {
return makeCall(expression, baseAsReceiver, null, expression.getOperationReference(), Collections.<ValueArgument>emptyList());
}
@NotNull
public static Call makeArraySetCall(@NotNull ReceiverValue arrayAsReceiver, @NotNull JetArrayAccessExpression arrayAccessExpression,
@NotNull JetExpression rightHandSide, @NotNull CallType callType) {
List<JetExpression> arguments = Lists.newArrayList(arrayAccessExpression.getIndexExpressions());
@@ -199,23 +208,28 @@ public class CallMaker {
return makeCallWithExpressions(arrayAccessExpression, arrayAsReceiver, null, arrayAccessExpression, arguments, callType);
}
@NotNull
public static Call makeArrayGetCall(@NotNull ReceiverValue arrayAsReceiver, @NotNull JetArrayAccessExpression arrayAccessExpression,
@NotNull CallType callType) {
return makeCallWithExpressions(arrayAccessExpression, arrayAsReceiver, null, arrayAccessExpression, arrayAccessExpression.getIndexExpressions(), callType);
}
@NotNull
public static ValueArgument makeValueArgument(@NotNull JetExpression expression) {
return makeValueArgument(expression, expression);
}
@NotNull
public static ValueArgument makeValueArgument(@Nullable JetExpression expression, @NotNull PsiElement reportErrorsOn) {
return new ExpressionValueArgument(expression, reportErrorsOn);
}
@NotNull
public static Call makePropertyCall(@NotNull ReceiverValue explicitReceiver, @Nullable ASTNode callOperationNode, @NotNull JetSimpleNameExpression nameExpression) {
return makeCallWithExpressions(nameExpression, explicitReceiver, callOperationNode, nameExpression, Collections.<JetExpression>emptyList());
}
@NotNull
public static Call makeCall(@NotNull final ReceiverValue explicitReceiver, @Nullable final ASTNode callOperationNode, @NotNull final JetCallElement callElement) {
return new Call() {
@Override
@@ -290,6 +304,7 @@ public class CallMaker {
};
}
@NotNull
public static Call makeCall(@NotNull JetElement callElement, @NotNull ReceiverValue explicitReceiver) {
return new CallImpl(callElement, explicitReceiver, null, null, Collections.<ValueArgument>emptyList());
}
@@ -25,6 +25,7 @@ import org.jetbrains.jet.lang.psi.JetDeclaration;
import org.jetbrains.jet.lang.resolve.BindingContext;
public interface KotlinCodeAnalyzer {
@NotNull
ModuleDescriptor getModuleDescriptor();
@NotNull
@@ -34,6 +34,7 @@ import org.jetbrains.jet.di.*
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingComponents
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingUtils
import org.jetbrains.jet.descriptors.serialization.descriptors.MemberFilter
import org.jetbrains.jet.lang.resolve.calls.CallResolver
// NOTE: After making changes, you need to re-generate the injectors.
// To do that, you can run main in this file.
@@ -174,6 +175,7 @@ private fun generatorForMacro() =
publicField(javaClass<ExpressionTypingServices>())
publicField(javaClass<ExpressionTypingComponents>())
publicField(javaClass<CallResolver>())
field(javaClass<GlobalContext>(), useAsContext = true,
init = GivenExpression("org.jetbrains.jet.context.ContextPackage.GlobalContext()"))
@@ -33,6 +33,18 @@ import com.intellij.openapi.application.ApplicationManager
import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache
import org.jetbrains.jet.plugin.codeInsight.ShortenReferences
import org.jetbrains.jet.utils.*
import org.jetbrains.jet.di.InjectorForMacros
import org.jetbrains.jet.lang.resolve.calls.context.BasicCallResolutionContext
import org.jetbrains.jet.lang.resolve.calls.context.SimpleResolutionContext
import org.jetbrains.jet.lang.resolve.calls.context.ContextDependency
import org.jetbrains.jet.lang.resolve.calls.context.CheckValueArgumentsMode
import org.jetbrains.jet.lang.resolve.calls.CompositeExtension
import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResults
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall
import org.jetbrains.jet.lang.resolve.calls.util.CallMaker
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue
import com.intellij.lang.ASTNode
trait SmartCompletionData{
fun accepts(descriptor: DeclarationDescriptor): Boolean
@@ -53,17 +65,25 @@ fun buildSmartCompletionData(expression: JetSimpleNameExpression, resolveSession
}
val bindingContext = resolveSession.resolveToElement(expressionWithType)
val expectedType: JetType? = bindingContext.get(BindingContext.EXPECTED_EXPRESSION_TYPE, expressionWithType)
if (expectedType == null || expectedType.isError()) return null
val allExpectedTypes = calcExpectedTypes(expressionWithType, bindingContext, resolveSession.getModuleDescriptor()) ?: return null
val expectedTypes = allExpectedTypes.filter { !it.isError() }
if (expectedTypes.isEmpty()) return null
val itemsToSkip = calcItemsToSkip(expressionWithType, resolveSession)
val additionalElements = ArrayList<LookupElement>()
if (receiver == null) {
typeInstantiationItems(expectedType, resolveSession, bindingContext).toCollection(additionalElements)
thisItems(expressionWithType, expectedType, bindingContext).toCollection(additionalElements)
staticMembers(expressionWithType, expectedType, resolveSession, bindingContext).toCollection(additionalElements)
for (expectedType in expectedTypes) {
//TODO: there can be duplicates here for multiple expected types
typeInstantiationItems(expectedType, resolveSession, bindingContext).toCollection(additionalElements)
//TODO: there can be duplicates here for multiple expected types
staticMembers(expressionWithType, expectedType, resolveSession, bindingContext).toCollection(additionalElements)
}
thisItems(expressionWithType, expectedTypes, bindingContext).toCollection(additionalElements)
}
val dataFlowInfo = bindingContext.get(BindingContext.EXPRESSION_DATA_FLOW_INFO, expressionWithType)
@@ -97,12 +117,74 @@ fun buildSmartCompletionData(expression: JetSimpleNameExpression, resolveSession
return object: SmartCompletionData {
override fun accepts(descriptor: DeclarationDescriptor)
= !itemsToSkip.contains(descriptor) && typesOf(descriptor).any { isSubtypeOf(it, expectedType) }
= !itemsToSkip.contains(descriptor)
&& typesOf(descriptor).any {
descriptorType -> expectedTypes.any { expectedType -> isSubtypeOf(descriptorType, expectedType) }
}
override val additionalElements = additionalElements
}
}
private fun calcExpectedTypes(expressionWithType: JetExpression, bindingContext: BindingContext, moduleDescriptor: ModuleDescriptor): Collection<JetType>? {
val expectedTypes = calcArgumentExpectedTypes(expressionWithType, bindingContext, moduleDescriptor)
if (expectedTypes != null) {
return expectedTypes
}
else{
val expectedType = bindingContext.get(BindingContext.EXPECTED_EXPRESSION_TYPE, expressionWithType) ?: return null
return listOf(expectedType)
}
}
private fun calcArgumentExpectedTypes(expressionWithType: JetExpression, bindingContext: BindingContext, moduleDescriptor: ModuleDescriptor): Collection<JetType>? {
val argument = expressionWithType.getParent() as? JetValueArgument ?: return null
if (argument.isNamed()) return null //TODO - support named arguments (also do not forget to check for presence of named arguments before)
val argumentList = argument.getParent() as JetValueArgumentList
val argumentIndex = argumentList.getArguments().indexOf(argument)
val callExpression = argumentList.getParent() as? JetCallExpression ?: return null
val calleeExpression = callExpression.getCalleeExpression()
val parent = callExpression.getParent()
val receiver: ReceiverValue
val callOperationNode: ASTNode?
if (parent is JetQualifiedExpression && callExpression == parent.getSelectorExpression()) {
val receiverExpression = parent.getReceiverExpression()
val expressionType = bindingContext.get(BindingContext.EXPRESSION_TYPE, receiverExpression) ?: return null
receiver = ExpressionReceiver(receiverExpression, expressionType)
callOperationNode = parent.getOperationTokenNode()
}
else {
receiver = ReceiverValue.NO_RECEIVER
callOperationNode = null
}
val call = CallMaker.makeCall(receiver, callOperationNode, callExpression)
val resolutionScope = bindingContext.get(BindingContext.RESOLUTION_SCOPE, calleeExpression) ?: return null //TODO: discuss it
val callResolutionContext = BasicCallResolutionContext.create(
DelegatingBindingTrace(bindingContext, "Temporary trace for smart completion"),
resolutionScope,
call,
bindingContext.get(BindingContext.EXPECTED_EXPRESSION_TYPE, callExpression) ?: TypeUtils.NO_EXPECTED_TYPE,
bindingContext.get(BindingContext.EXPRESSION_DATA_FLOW_INFO, callExpression) ?: DataFlowInfo.EMPTY,
ContextDependency.INDEPENDENT,
CheckValueArgumentsMode.ENABLED,
CompositeExtension(listOf()),
false).replaceCollectAllCandidates(true)
val callResolver = InjectorForMacros(expressionWithType.getProject(), moduleDescriptor).getCallResolver()!!
val results: OverloadResolutionResults<FunctionDescriptor> = callResolver.resolveFunctionCall(callResolutionContext)
val expectedTypes = HashSet<JetType>()
for (candidate: ResolvedCall<FunctionDescriptor> in results.getAllCandidates()!!) {
val parameters = candidate.getResultingDescriptor().getValueParameters()
if (parameters.size <= argumentIndex) continue
val parameterDescriptor = parameters[argumentIndex]
expectedTypes.add(parameterDescriptor.getType())
}
return expectedTypes
}
private fun calcItemsToSkip(expression: JetExpression, resolveSession: ResolveSessionForBodies): Collection<DeclarationDescriptor> {
val parent = expression.getParent()
when(parent) {
@@ -215,7 +297,7 @@ private fun typeInstantiationItems(expectedType: JetType, resolveSession: Resolv
}
}
private fun thisItems(context: JetExpression, expectedType: JetType, bindingContext: BindingContext): Iterable<LookupElement> {
private fun thisItems(context: JetExpression, expectedTypes: Collection<JetType>, bindingContext: BindingContext): Iterable<LookupElement> {
val scope = bindingContext.get(BindingContext.RESOLUTION_SCOPE, context)
if (scope == null) return listOf()
@@ -224,7 +306,7 @@ private fun thisItems(context: JetExpression, expectedType: JetType, bindingCont
for (i in 0..receivers.size - 1) {
val receiver = receivers[i]
val thisType = receiver.getType()
if (isSubtypeOf(thisType, expectedType)) {
if (expectedTypes.any { isSubtypeOf(thisType, it) }) {
//TODO: use this code when KT-4258 fixed
//val expressionText = if (i == 0) "this" else "this@" + (thisQualifierName(receiver, bindingContext) ?: continue)
val qualifier = if (i == 0) null else thisQualifierName(receiver, bindingContext) ?: continue
@@ -54,6 +54,7 @@ public class ResolveSessionForBodies implements KotlinCodeAnalyzer, Modification
return resolveElementCache.resolveToElement(element);
}
@NotNull
@Override
public ModuleDescriptor getModuleDescriptor() {
return resolveSession.getModuleDescriptor();
@@ -0,0 +1,9 @@
import java.io.File
fun f(p1: Any, p2: String, p3: File) {
File(<caret>)
}
// ABSENT: p1
// EXIST: p2
// EXIST: p3
@@ -0,0 +1,18 @@
val s = ""
val i = 123
fun f(p1: Any, p2: String, p3: Int) {
foo(<caret>123) // this call is resolved to Foo(Int) but types from all signatures should participate
}
fun foo(p1: String, p2: Any) {
}
fun foo(p1: Int) {
}
// ABSENT: p1
// EXIST: p2
// EXIST: p3
// EXIST: s
// EXIST: i
@@ -0,0 +1,23 @@
val s = ""
val i = 123
fun f(p1: Any, p2: String, p3: Int, p4: Char) {
foo(<caret>abc)
}
fun foo(p1: String, p2: Any) {
}
fun foo(p1: Int) {
}
// add this signature so that call above is not resolved
fun foo(p1: Char) {
}
// ABSENT: p1
// EXIST: p2
// EXIST: p3
// EXIST: p4
// EXIST: s
// EXIST: i
@@ -0,0 +1,13 @@
fun f(p1: Any, p2: String, p3: Int) {
foo("abc", <caret>)
}
fun foo(p1: String, p2: String) {
}
fun foo(p1: Int, p2: Int) {
}
// ABSENT: p1
// EXIST: p2
// ABSENT: p3
@@ -0,0 +1,24 @@
val s = ""
val i = 123
fun f(p1: Any, p2: String, p3: Int, p4: Char) {
C().foo(<caret>abc)
}
class C {
fun foo(p1: String, p2: Any) {
}
fun foo(p1: Int) {
}
fun foo(p1: Char) {
}
}
// ABSENT: p1
// EXIST: p2
// EXIST: p3
// EXIST: p4
// EXIST: s
// EXIST: i
@@ -0,0 +1,24 @@
val s = ""
val i = 123
fun f(c: C?, p1: Any, p2: String, p3: Int, p4: Char) {
c?.foo(<caret>abc)
}
class C {
fun foo(p1: String, p2: Any) {
}
fun foo(p1: Int) {
}
fun foo(p1: Char) {
}
}
// ABSENT: p1
// EXIST: p2
// EXIST: p3
// EXIST: p4
// EXIST: s
// EXIST: i
@@ -186,6 +186,31 @@ public class JvmSmartCompletionTestGenerated extends AbstractJvmSmartCompletionT
doTest("idea/testData/completion/smart/NotSillyAssignment.kt");
}
@TestMetadata("OverloadedConstructorArgument.kt")
public void testOverloadedConstructorArgument() throws Exception {
doTest("idea/testData/completion/smart/OverloadedConstructorArgument.kt");
}
@TestMetadata("OverloadedMethodCallArgument1.kt")
public void testOverloadedMethodCallArgument1() throws Exception {
doTest("idea/testData/completion/smart/OverloadedMethodCallArgument1.kt");
}
@TestMetadata("OverloadedMethodCallArgument2.kt")
public void testOverloadedMethodCallArgument2() throws Exception {
doTest("idea/testData/completion/smart/OverloadedMethodCallArgument2.kt");
}
@TestMetadata("QualifiedOverloadedMethodCallArgument1.kt")
public void testQualifiedOverloadedMethodCallArgument1() throws Exception {
doTest("idea/testData/completion/smart/QualifiedOverloadedMethodCallArgument1.kt");
}
@TestMetadata("QualifiedOverloadedMethodCallArgument2.kt")
public void testQualifiedOverloadedMethodCallArgument2() throws Exception {
doTest("idea/testData/completion/smart/QualifiedOverloadedMethodCallArgument2.kt");
}
@TestMetadata("QualifiedThis.kt")
public void testQualifiedThis() throws Exception {
doTest("idea/testData/completion/smart/QualifiedThis.kt");