Use concrete candidate to resolve collection literal
This helps to avoid resolution errors when there is local array-like function with the same signature as in built-ins
This commit is contained in:
@@ -21,8 +21,10 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.builtins.PrimitiveType
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
|
||||
import org.jetbrains.kotlin.diagnostics.Errors.UNSUPPORTED
|
||||
import org.jetbrains.kotlin.diagnostics.Errors.UNSUPPORTED_FEATURE
|
||||
import org.jetbrains.kotlin.incremental.KotlinLookupLocation
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.KtAnnotationEntry
|
||||
import org.jetbrains.kotlin.psi.KtClass
|
||||
@@ -54,6 +56,7 @@ object CollectionLiteralResolver {
|
||||
fun resolveCollectionLiteral(collectionLiteralExpression: KtCollectionLiteralExpression,
|
||||
context: ExpressionTypingContext,
|
||||
callResolver: CallResolver,
|
||||
builtIns: KotlinBuiltIns,
|
||||
languageVersionSettings: LanguageVersionSettings
|
||||
): KotlinTypeInfo {
|
||||
if (!isInsideAnnotationEntryOrClass(collectionLiteralExpression)) {
|
||||
@@ -62,28 +65,39 @@ object CollectionLiteralResolver {
|
||||
|
||||
checkSupportsArrayLiterals(collectionLiteralExpression, context, languageVersionSettings)
|
||||
|
||||
return resolveCollectionLiteralSpecialMethod(collectionLiteralExpression, context, callResolver)
|
||||
return resolveCollectionLiteralSpecialMethod(collectionLiteralExpression, context, callResolver, builtIns)
|
||||
}
|
||||
|
||||
private fun resolveCollectionLiteralSpecialMethod(
|
||||
collectionLiteralExpression: KtCollectionLiteralExpression,
|
||||
expression: KtCollectionLiteralExpression,
|
||||
context: ExpressionTypingContext,
|
||||
callResolver: CallResolver
|
||||
callResolver: CallResolver,
|
||||
builtIns: KotlinBuiltIns
|
||||
): KotlinTypeInfo {
|
||||
val collectionLiteralCallName = getArrayFunctionCallName(context.expectedType)
|
||||
val call = CallMaker.makeCallForCollectionLiteral(collectionLiteralExpression)
|
||||
val resolutionResults = callResolver.resolveCallWithGivenName(context, call, collectionLiteralExpression, collectionLiteralCallName)
|
||||
val call = CallMaker.makeCallForCollectionLiteral(expression)
|
||||
val functionDescriptor = getFunctionDescriptorForCollectionLiteral(expression, context, builtIns)
|
||||
|
||||
// TODO: check that resolved function is from package `kotlin`, otherwise report an error
|
||||
val resolutionResults = callResolver.resolveCollectionLiteralCallWithGivenDescriptor(context, expression, call, functionDescriptor)
|
||||
|
||||
// No single result after resolving one candidate?
|
||||
if (!resolutionResults.isSingleResult) {
|
||||
return noTypeInfo(context)
|
||||
}
|
||||
|
||||
context.trace.record(COLLECTION_LITERAL_CALL, collectionLiteralExpression, resolutionResults.resultingCall)
|
||||
context.trace.record(COLLECTION_LITERAL_CALL, expression, resolutionResults.resultingCall)
|
||||
return createTypeInfo(resolutionResults.resultingDescriptor.returnType, context)
|
||||
}
|
||||
|
||||
fun checkSupportsArrayLiterals(expression: KtCollectionLiteralExpression,
|
||||
private fun getFunctionDescriptorForCollectionLiteral(
|
||||
expression: KtCollectionLiteralExpression,
|
||||
context: ExpressionTypingContext,
|
||||
builtIns: KotlinBuiltIns
|
||||
): SimpleFunctionDescriptor {
|
||||
val callName = getArrayFunctionCallName(context.expectedType)
|
||||
return builtIns.builtInsPackageScope.getContributedFunctions(callName, KotlinLookupLocation(expression)).single()
|
||||
}
|
||||
|
||||
private fun checkSupportsArrayLiterals(expression: KtCollectionLiteralExpression,
|
||||
context: ExpressionTypingContext,
|
||||
languageVersionSettings: LanguageVersionSettings
|
||||
) {
|
||||
|
||||
@@ -234,6 +234,21 @@ public class CallResolver {
|
||||
);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public OverloadResolutionResults<FunctionDescriptor> resolveCollectionLiteralCallWithGivenDescriptor(
|
||||
@NotNull ExpressionTypingContext context,
|
||||
@NotNull KtCollectionLiteralExpression expression,
|
||||
@NotNull Call call,
|
||||
@NotNull FunctionDescriptor functionDescriptor
|
||||
) {
|
||||
BasicCallResolutionContext callResolutionContext = BasicCallResolutionContext.create(context, call, CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS);
|
||||
ResolutionCandidate<FunctionDescriptor> candidate = ResolutionCandidate.create(
|
||||
call, functionDescriptor, null, ExplicitReceiverKind.NO_EXPLICIT_RECEIVER, null);
|
||||
|
||||
return computeTasksFromCandidatesAndResolvedCall(
|
||||
callResolutionContext, Collections.singleton(candidate), TracingStrategyImpl.create(expression, call));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public OverloadResolutionResults<FunctionDescriptor> resolveFunctionCall(
|
||||
@NotNull BindingTrace trace,
|
||||
|
||||
+1
-1
@@ -1505,7 +1505,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
||||
@NotNull KtCollectionLiteralExpression expression, ExpressionTypingContext context
|
||||
) {
|
||||
return CollectionLiteralResolver.INSTANCE.resolveCollectionLiteral(
|
||||
expression, context, components.callResolver, components.languageVersionSettings);
|
||||
expression, context, components.callResolver, components.builtIns, components.languageVersionSettings);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
// !LANGUAGE: +ArrayLiteralsInAnnotations
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE, -UNSUPPORTED
|
||||
|
||||
annotation class Anno(val a: Array<String> = [""], val b: IntArray = [])
|
||||
|
||||
@Anno([], [])
|
||||
fun test() {}
|
||||
|
||||
fun arrayOf(): Array<Int> = TODO()
|
||||
fun intArrayOf(): Array<Int> = TODO()
|
||||
|
||||
fun local() {
|
||||
val a1: IntArray = [1, 2]
|
||||
val a2: IntArray = []
|
||||
|
||||
val s1: Array<String> = [""]
|
||||
val s2: Array<String> = []
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
package
|
||||
|
||||
public fun arrayOf(): kotlin.Array<kotlin.Int>
|
||||
public fun intArrayOf(): kotlin.Array<kotlin.Int>
|
||||
public fun local(): kotlin.Unit
|
||||
@Anno(a = {}, b = {}) public fun test(): kotlin.Unit
|
||||
|
||||
public final annotation class Anno : kotlin.Annotation {
|
||||
public constructor Anno(/*0*/ a: kotlin.Array<kotlin.String> = ..., /*1*/ b: kotlin.IntArray = ...)
|
||||
public final val a: kotlin.Array<kotlin.String>
|
||||
public final val b: kotlin.IntArray
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
@@ -3387,6 +3387,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/collectionLiterals/noCollectionLiterals.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("resolveToFunctionFromBuiltIns.kt")
|
||||
public void testResolveToFunctionFromBuiltIns() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/collectionLiterals/resolveToFunctionFromBuiltIns.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/diagnostics/tests/constructorConsistency")
|
||||
|
||||
Reference in New Issue
Block a user