[NI] Add feature for choosing candidate by lambda return type
This commit is contained in:
+23
@@ -1788,6 +1788,29 @@ public class FirOldFrontendDiagnosticsTestWithStdlibGenerated extends AbstractFi
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/diagnostics/testsWithStdLib/factoryPattern")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class FactoryPattern extends AbstractFirOldFrontendDiagnosticsTestWithStdlib {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInFactoryPattern() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/testsWithStdLib/factoryPattern"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("overloadByLambdaReturnType_disabled.kt")
|
||||
public void testOverloadByLambdaReturnType_disabled() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/factoryPattern/overloadByLambdaReturnType_disabled.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("overloadByLambdaReturnType_enabled.kt")
|
||||
public void testOverloadByLambdaReturnType_enabled() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/factoryPattern/overloadByLambdaReturnType_enabled.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/diagnostics/testsWithStdLib/forInArrayLoop")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
+2
@@ -119,6 +119,8 @@ class FirCallCompleter(
|
||||
inferenceSession.addPartiallyResolvedCall(approximatedCall)
|
||||
CompletionResult(approximatedCall, false)
|
||||
}
|
||||
|
||||
ConstraintSystemCompletionMode.UNTIL_FIRST_LAMBDA -> throw IllegalStateException()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+6
-2
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns.isPrimitiveTypeOrNullablePri
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns.isUnderKotlinPackage
|
||||
import org.jetbrains.kotlin.builtins.UnsignedTypes
|
||||
import org.jetbrains.kotlin.builtins.createFunctionType
|
||||
import org.jetbrains.kotlin.builtins.isFunctionTypeOrSubtype
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
@@ -196,8 +197,10 @@ class KotlinResolutionCallbacksImpl(
|
||||
val functionTypeInfo = expressionTypingServices.getTypeInfo(psiCallArgument.expression, actualContext)
|
||||
(temporaryTrace ?: trace).record(BindingContext.NEW_INFERENCE_LAMBDA_INFO, psiCallArgument.ktFunction, LambdaInfo.STUB_EMPTY)
|
||||
|
||||
val inferedReturnType = functionTypeInfo.type?.arguments?.last()?.type?.takeIf { functionTypeInfo.type?.isFunctionTypeOrSubtype == true }
|
||||
|
||||
if (coroutineSession?.hasInapplicableCall() == true) {
|
||||
return ReturnArgumentsAnalysisResult(ReturnArgumentsInfo.empty, coroutineSession, hasInapplicableCallForBuilderInference = true)
|
||||
return ReturnArgumentsAnalysisResult(ReturnArgumentsInfo.empty, coroutineSession, inferedReturnType, hasInapplicableCallForBuilderInference = true)
|
||||
} else {
|
||||
temporaryTrace?.commit()
|
||||
}
|
||||
@@ -244,7 +247,8 @@ class KotlinResolutionCallbacksImpl(
|
||||
lastExpressionCoercedToUnit,
|
||||
returnArgumentFound
|
||||
),
|
||||
coroutineSession
|
||||
coroutineSession,
|
||||
inferedReturnType
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -18,15 +18,14 @@ package org.jetbrains.kotlin.resolve.calls
|
||||
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus
|
||||
import org.jetbrains.kotlin.resolve.calls.components.CallableReferenceResolver
|
||||
import org.jetbrains.kotlin.resolve.calls.components.KotlinCallCompleter
|
||||
import org.jetbrains.kotlin.resolve.calls.components.KotlinResolutionCallbacks
|
||||
import org.jetbrains.kotlin.resolve.calls.components.NewOverloadingConflictResolver
|
||||
import org.jetbrains.kotlin.resolve.calls.components.*
|
||||
import org.jetbrains.kotlin.resolve.calls.context.CheckArgumentTypesMode
|
||||
import org.jetbrains.kotlin.resolve.calls.model.*
|
||||
import org.jetbrains.kotlin.resolve.calls.tower.*
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValueWithSmartCastInfo
|
||||
import org.jetbrains.kotlin.types.UnwrappedType
|
||||
import org.jetbrains.kotlin.types.model.safeSubstitute
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.same
|
||||
import java.lang.UnsupportedOperationException
|
||||
|
||||
|
||||
@@ -142,13 +141,19 @@ class KotlinCallResolver(
|
||||
}
|
||||
}
|
||||
|
||||
val maximallySpecificCandidates = overloadingConflictResolver.chooseMaximallySpecificCandidates(
|
||||
var maximallySpecificCandidates = overloadingConflictResolver.chooseMaximallySpecificCandidates(
|
||||
refinedCandidates,
|
||||
CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS,
|
||||
discriminateGenerics = true // todo
|
||||
)
|
||||
|
||||
if (maximallySpecificCandidates.size > 1 && callComponents.languageVersionSettings.supportsFeature(LanguageFeature.FactoryPatternResolution)) {
|
||||
maximallySpecificCandidates = kotlinCallCompleter.chooseCandidateRegardingFactoryPatternResolution(maximallySpecificCandidates, resolutionCallbacks)
|
||||
}
|
||||
|
||||
return kotlinCallCompleter.runCompletion(candidateFactory, maximallySpecificCandidates, expectedType, resolutionCallbacks)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
+1
@@ -59,6 +59,7 @@ data class ReturnArgumentsInfo(
|
||||
data class ReturnArgumentsAnalysisResult(
|
||||
val returnArgumentsInfo: ReturnArgumentsInfo,
|
||||
val inferenceSession: InferenceSession?,
|
||||
val lambdaReturnType: KotlinType? = null,
|
||||
val hasInapplicableCallForBuilderInference: Boolean = false
|
||||
)
|
||||
|
||||
|
||||
+84
@@ -5,6 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.resolve.calls.components
|
||||
|
||||
import org.jetbrains.kotlin.builtins.isFunctionTypeOrSubtype
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.synthetic.SyntheticMemberDescriptor
|
||||
@@ -15,11 +16,15 @@ import org.jetbrains.kotlin.resolve.calls.inference.components.KotlinConstraintS
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.components.TrivialConstraintTypeInferenceOracle
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage.Empty.hasContradiction
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.model.ExpectedTypeConstraintPosition
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.model.LambdaArgumentConstraintPosition
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.model.TypeVariableTypeConstructor
|
||||
import org.jetbrains.kotlin.resolve.calls.model.*
|
||||
import org.jetbrains.kotlin.resolve.calls.tower.forceResolution
|
||||
import org.jetbrains.kotlin.types.ErrorUtils
|
||||
import org.jetbrains.kotlin.types.TypeUtils
|
||||
import org.jetbrains.kotlin.types.UnwrappedType
|
||||
import org.jetbrains.kotlin.types.model.safeSubstitute
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.same
|
||||
|
||||
class KotlinCallCompleter(
|
||||
private val postponedArgumentsAnalyzer: PostponedArgumentsAnalyzer,
|
||||
@@ -66,10 +71,89 @@ class KotlinCallCompleter(
|
||||
candidate.runCompletion(completionMode, diagnosticHolder, resolutionCallbacks)
|
||||
candidate.asCallResolutionResult(completionMode, diagnosticHolder)
|
||||
}
|
||||
ConstraintSystemCompletionMode.UNTIL_FIRST_LAMBDA -> throw IllegalStateException("Should not be here")
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
fun chooseCandidateRegardingFactoryPatternResolution(
|
||||
candidates: Set<KotlinResolutionCandidate>,
|
||||
resolutionCallbacks: KotlinResolutionCallbacks
|
||||
): Set<KotlinResolutionCandidate> {
|
||||
val lambdas = candidates.flatMap { candidate ->
|
||||
candidate.getSubResolvedAtoms()
|
||||
.filter { it is ResolvedLambdaAtom && !it.analyzed }
|
||||
.map { candidate to it as ResolvedLambdaAtom }
|
||||
}.groupBy { (_, atom) -> atom.atom }
|
||||
.values
|
||||
.singleOrNull()
|
||||
?.toMap() ?: return candidates
|
||||
|
||||
if (!lambdas.values.same { it.parameters.size }) return candidates
|
||||
if (!lambdas.values.all { it.expectedType?.isFunctionTypeOrSubtype == true }) return candidates
|
||||
|
||||
for (candidate in lambdas.keys) {
|
||||
candidate.runCompletion(
|
||||
ConstraintSystemCompletionMode.UNTIL_FIRST_LAMBDA,
|
||||
candidate,
|
||||
resolutionCallbacks
|
||||
)
|
||||
}
|
||||
if (!lambdas.entries.same { (candidate, atom) -> candidate.getInputTypesOfLambdaAtom(atom) }) {
|
||||
return candidates
|
||||
}
|
||||
|
||||
val newAtoms = mutableMapOf<KotlinResolutionCandidate, ResolvedLambdaAtom>()
|
||||
for ((candidate, atom) in lambdas.entries) {
|
||||
newAtoms[candidate] = kotlinConstraintSystemCompleter.prepareLambdaAtomForFactoryPattern(atom, candidate, candidate)
|
||||
}
|
||||
|
||||
val diagnosticHolderForLambda = KotlinDiagnosticsHolder.SimpleHolder()
|
||||
val iterator = newAtoms.entries.iterator()
|
||||
val (firstCandidate, firstAtom) = iterator.next()
|
||||
val results = postponedArgumentsAnalyzer.analyzeLambda(
|
||||
firstCandidate.getSystem().asPostponedArgumentsAnalyzerContext(),
|
||||
resolutionCallbacks,
|
||||
firstAtom,
|
||||
diagnosticHolderForLambda
|
||||
)
|
||||
lambdas.getValue(firstCandidate).setAnalyzedResults(results.returnArgumentsInfo, listOf(firstAtom))
|
||||
|
||||
val lambdaReturnType = results.lambdaReturnType ?: return candidates
|
||||
while (iterator.hasNext()) {
|
||||
val (candidate, atom) = iterator.next()
|
||||
atom.setAnalyzedResults(results.returnArgumentsInfo, firstAtom.subResolvedAtoms!!)
|
||||
lambdas.getValue(candidate).setAnalyzedResults(results.returnArgumentsInfo, listOf(atom))
|
||||
candidate.csBuilder.addSubtypeConstraint(lambdaReturnType, atom.returnType, LambdaArgumentConstraintPosition(atom))
|
||||
}
|
||||
|
||||
val errorCandidates = mutableSetOf<KotlinResolutionCandidate>()
|
||||
val successfulCandidates = mutableSetOf<KotlinResolutionCandidate>()
|
||||
|
||||
for (candidate in candidates) {
|
||||
if (candidate.isSuccessful) {
|
||||
successfulCandidates += candidate
|
||||
} else {
|
||||
errorCandidates += candidate
|
||||
}
|
||||
}
|
||||
return when {
|
||||
successfulCandidates.isNotEmpty() -> successfulCandidates
|
||||
else -> errorCandidates
|
||||
}
|
||||
}
|
||||
|
||||
private fun KotlinResolutionCandidate.getInputTypesOfLambdaAtom(atom: ResolvedLambdaAtom): List<UnwrappedType> {
|
||||
val result = mutableListOf<UnwrappedType>()
|
||||
val substitutor = csBuilder.buildCurrentSubstitutor()
|
||||
val ctx = getSystem().asConstraintSystemCompleterContext()
|
||||
for (inputType in atom.inputTypes) {
|
||||
result += substitutor.safeSubstitute(ctx, inputType) as UnwrappedType
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
|
||||
private fun KotlinResolutionCandidate.checkSamWithVararg(diagnosticHolder: KotlinDiagnosticsHolder.SimpleHolder) {
|
||||
val samConversionPerArgumentWithWarningsForVarargAfterSam =
|
||||
callComponents.languageVersionSettings.supportsFeature(LanguageFeature.SamConversionPerArgument) &&
|
||||
|
||||
+18
@@ -220,6 +220,24 @@ fun LambdaWithTypeVariableAsExpectedTypeAtom.transformToResolvedLambda(
|
||||
return resolvedLambdaAtom
|
||||
}
|
||||
|
||||
fun ResolvedLambdaAtom.transformToResolvedLambda(
|
||||
csBuilder: ConstraintSystemBuilder,
|
||||
diagnosticsHolder: KotlinDiagnosticsHolder,
|
||||
expectedType: UnwrappedType,
|
||||
returnTypeVariable: TypeVariableForLambdaReturnType? = null
|
||||
): ResolvedLambdaAtom {
|
||||
val resolvedLambdaAtom = preprocessLambdaArgument(
|
||||
csBuilder,
|
||||
atom,
|
||||
expectedType,
|
||||
diagnosticsHolder,
|
||||
forceResolution = true,
|
||||
returnTypeVariable = returnTypeVariable
|
||||
) as ResolvedLambdaAtom
|
||||
|
||||
return resolvedLambdaAtom
|
||||
}
|
||||
|
||||
private fun preprocessCallableReference(
|
||||
csBuilder: ConstraintSystemBuilder,
|
||||
argument: CallableReferenceKotlinCallArgument,
|
||||
|
||||
+18
-14
@@ -17,6 +17,7 @@ import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.model.CoroutinePosition
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.model.LambdaArgumentConstraintPosition
|
||||
import org.jetbrains.kotlin.resolve.calls.model.*
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.UnwrappedType
|
||||
import org.jetbrains.kotlin.types.model.*
|
||||
import org.jetbrains.kotlin.types.typeUtil.builtIns
|
||||
@@ -65,12 +66,12 @@ class PostponedArgumentsAnalyzer(
|
||||
}
|
||||
}
|
||||
|
||||
private fun analyzeLambda(
|
||||
fun analyzeLambda(
|
||||
c: Context,
|
||||
resolutionCallbacks: KotlinResolutionCallbacks,
|
||||
lambda: ResolvedLambdaAtom,
|
||||
diagnosticHolder: KotlinDiagnosticsHolder
|
||||
) {
|
||||
): ReturnArgumentsAnalysisResult {
|
||||
val stubsForPostponedVariables = c.bindingStubsForPostponedVariables()
|
||||
val currentSubstitutor = c.buildCurrentSubstitutor(stubsForPostponedVariables.mapKeys { it.key.freshTypeConstructor(c) })
|
||||
|
||||
@@ -120,20 +121,21 @@ class PostponedArgumentsAnalyzer(
|
||||
else FilteredAnnotations(annotations, true) { it != KotlinBuiltIns.FQ_NAMES.extensionFunctionType }
|
||||
}
|
||||
|
||||
val (returnArgumentsInfo, inferenceSession, hasInapplicableCallForBuilderInference) =
|
||||
resolutionCallbacks.analyzeAndGetLambdaReturnArguments(
|
||||
lambda.atom,
|
||||
lambda.isSuspend,
|
||||
receiver,
|
||||
parameters,
|
||||
expectedTypeForReturnArguments,
|
||||
convertedAnnotations ?: Annotations.EMPTY,
|
||||
stubsForPostponedVariables.cast()
|
||||
)
|
||||
val returnArgumentsAnalysisResult = resolutionCallbacks.analyzeAndGetLambdaReturnArguments(
|
||||
lambda.atom,
|
||||
lambda.isSuspend,
|
||||
receiver,
|
||||
parameters,
|
||||
expectedTypeForReturnArguments,
|
||||
convertedAnnotations ?: Annotations.EMPTY,
|
||||
stubsForPostponedVariables.cast()
|
||||
)
|
||||
val (returnArgumentsInfo, inferenceSession, inferedReturnType, hasInapplicableCallForBuilderInference) =
|
||||
returnArgumentsAnalysisResult
|
||||
|
||||
if (hasInapplicableCallForBuilderInference) {
|
||||
c.getBuilder().removePostponedVariables()
|
||||
return
|
||||
return returnArgumentsAnalysisResult
|
||||
}
|
||||
|
||||
val returnArguments = returnArgumentsInfo.nonErrorArguments
|
||||
@@ -169,7 +171,7 @@ class PostponedArgumentsAnalyzer(
|
||||
val postponedVariables = inferenceSession.inferPostponedVariables(lambda, storageSnapshot, diagnosticHolder)
|
||||
if (postponedVariables == null) {
|
||||
c.getBuilder().removePostponedVariables()
|
||||
return
|
||||
return returnArgumentsAnalysisResult
|
||||
}
|
||||
|
||||
for ((constructor, resultType) in postponedVariables) {
|
||||
@@ -180,6 +182,8 @@ class PostponedArgumentsAnalyzer(
|
||||
c.getBuilder().addEqualityConstraint(variable.defaultType(c), resultType, CoroutinePosition())
|
||||
}
|
||||
}
|
||||
|
||||
return returnArgumentsAnalysisResult
|
||||
}
|
||||
|
||||
private fun UnwrappedType?.receiver(): UnwrappedType? {
|
||||
|
||||
+36
-1
@@ -5,6 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.resolve.calls.inference.components
|
||||
|
||||
import org.jetbrains.kotlin.resolve.calls.components.transformToResolvedLambda
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilder
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.model.*
|
||||
import org.jetbrains.kotlin.resolve.calls.model.*
|
||||
@@ -12,6 +13,8 @@ import org.jetbrains.kotlin.types.*
|
||||
import org.jetbrains.kotlin.types.model.KotlinTypeMarker
|
||||
import org.jetbrains.kotlin.types.model.TypeConstructorMarker
|
||||
import org.jetbrains.kotlin.types.model.TypeVariableMarker
|
||||
import org.jetbrains.kotlin.types.model.safeSubstitute
|
||||
import org.jetbrains.kotlin.types.typeUtil.asTypeProjection
|
||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
import kotlin.collections.LinkedHashSet
|
||||
@@ -24,7 +27,8 @@ class KotlinConstraintSystemCompleter(
|
||||
|
||||
enum class ConstraintSystemCompletionMode {
|
||||
FULL,
|
||||
PARTIAL
|
||||
PARTIAL,
|
||||
UNTIL_FIRST_LAMBDA
|
||||
}
|
||||
|
||||
interface Context : VariableFixationFinder.Context, ResultTypeResolver.Context {
|
||||
@@ -91,7 +95,9 @@ class KotlinConstraintSystemCompleter(
|
||||
analyze: (PostponedResolvedAtom) -> Unit
|
||||
) {
|
||||
completion@ while (true) {
|
||||
// TODO
|
||||
val postponedArguments = getOrderedNotAnalyzedPostponedArguments(topLevelAtoms)
|
||||
if (completionMode == ConstraintSystemCompletionMode.UNTIL_FIRST_LAMBDA && hasLambdaToAnalyze(postponedArguments)) return
|
||||
|
||||
// Stage 1: analyze postponed arguments with fixed parameter types
|
||||
if (analyzeArgumentWithFixedParameterTypes(postponedArguments, analyze))
|
||||
@@ -210,6 +216,35 @@ class KotlinConstraintSystemCompleter(
|
||||
return false
|
||||
}
|
||||
|
||||
fun prepareLambdaAtomForFactoryPattern(
|
||||
atom: ResolvedLambdaAtom,
|
||||
candidate: KotlinResolutionCandidate,
|
||||
diagnosticsHolder: KotlinDiagnosticsHolder,
|
||||
): ResolvedLambdaAtom {
|
||||
val returnVariable = TypeVariableForLambdaReturnType(candidate.callComponents.builtIns, "_R")
|
||||
val csBuilder = candidate.csBuilder
|
||||
csBuilder.registerVariable(returnVariable)
|
||||
val functionalType: KotlinType = csBuilder.buildCurrentSubstitutor().safeSubstitute(candidate.getSystem().asConstraintSystemCompleterContext(), atom.expectedType!!) as KotlinType
|
||||
val expectedType = KotlinTypeFactory.simpleType(
|
||||
functionalType.annotations,
|
||||
functionalType.constructor,
|
||||
functionalType.arguments.dropLast(1) + returnVariable.defaultType.asTypeProjection(),
|
||||
functionalType.isMarkedNullable
|
||||
)
|
||||
csBuilder.addSubtypeConstraint(
|
||||
expectedType,
|
||||
functionalType,
|
||||
ArgumentConstraintPosition(atom.atom)
|
||||
)
|
||||
return atom.transformToResolvedLambda(csBuilder, diagnosticsHolder, expectedType, returnVariable)
|
||||
}
|
||||
|
||||
private fun Context.hasLambdaToAnalyze(
|
||||
postponedArguments: List<PostponedResolvedAtom>
|
||||
): Boolean {
|
||||
return analyzeArgumentWithFixedParameterTypes(postponedArguments) {}
|
||||
}
|
||||
|
||||
private fun findPostponedArgumentWithRevisableExpectedType(postponedArguments: List<PostponedResolvedAtom>) =
|
||||
postponedArguments.firstOrNull { argument -> argument is PostponedAtomWithRevisableExpectedType }
|
||||
|
||||
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
// !LANGUAGE: +NewInference -FactoryPatternResolution
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_VARIABLE -UNUSED_EXPRESSION
|
||||
// ISSUE: KT-11265
|
||||
|
||||
fun create(f: (Int) -> Int): Int = 1
|
||||
fun create(f: (Int) -> String): String = ""
|
||||
|
||||
fun takeString(s: String) {}
|
||||
fun takeInt(s: Int) {}
|
||||
|
||||
fun test_1() {
|
||||
val x = <!AMBIGUITY!>create<!> { "" }
|
||||
takeString(x)
|
||||
}
|
||||
|
||||
fun test_2() {
|
||||
val x = <!AMBIGUITY!>create<!> { 1 }
|
||||
takeInt(x)
|
||||
}
|
||||
|
||||
fun test_3() {
|
||||
val x = <!AMBIGUITY!>create<!> { 1.0 }
|
||||
}
|
||||
|
||||
fun <K> create(x: K, f: (K) -> Int): Int = 1
|
||||
fun <T> create(x: T, f: (T) -> String): String = ""
|
||||
|
||||
fun test_4() {
|
||||
val x = <!AMBIGUITY!>create<!>("") { "" }
|
||||
takeString(x)
|
||||
}
|
||||
|
||||
fun test_5() {
|
||||
val x = <!AMBIGUITY!>create<!>("") { 1 }
|
||||
takeInt(x)
|
||||
}
|
||||
Vendored
+36
@@ -0,0 +1,36 @@
|
||||
// !LANGUAGE: +NewInference -FactoryPatternResolution
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_VARIABLE -UNUSED_EXPRESSION
|
||||
// ISSUE: KT-11265
|
||||
|
||||
fun create(f: (Int) -> Int): Int = 1
|
||||
fun create(f: (Int) -> String): String = ""
|
||||
|
||||
fun takeString(s: String) {}
|
||||
fun takeInt(s: Int) {}
|
||||
|
||||
fun test_1() {
|
||||
val x = <!OVERLOAD_RESOLUTION_AMBIGUITY!>create<!> { "" }
|
||||
takeString(<!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>x<!>)
|
||||
}
|
||||
|
||||
fun test_2() {
|
||||
val x = <!OVERLOAD_RESOLUTION_AMBIGUITY!>create<!> { 1 }
|
||||
takeInt(<!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>x<!>)
|
||||
}
|
||||
|
||||
fun test_3() {
|
||||
val x = <!OVERLOAD_RESOLUTION_AMBIGUITY!>create<!> { 1.0 }
|
||||
}
|
||||
|
||||
fun <K> create(x: K, f: (K) -> Int): Int = 1
|
||||
fun <T> create(x: T, f: (T) -> String): String = ""
|
||||
|
||||
fun test_4() {
|
||||
val x = <!OVERLOAD_RESOLUTION_AMBIGUITY!>create<!>("") { "" }
|
||||
takeString(<!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>x<!>)
|
||||
}
|
||||
|
||||
fun test_5() {
|
||||
val x = <!OVERLOAD_RESOLUTION_AMBIGUITY!>create<!>("") { 1 }
|
||||
takeInt(<!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>x<!>)
|
||||
}
|
||||
compiler/testData/diagnostics/testsWithStdLib/factoryPattern/overloadByLambdaReturnType_disabled.txt
Vendored
+13
@@ -0,0 +1,13 @@
|
||||
package
|
||||
|
||||
public fun create(/*0*/ f: (kotlin.Int) -> kotlin.Int): kotlin.Int
|
||||
public fun create(/*0*/ f: (kotlin.Int) -> kotlin.String): kotlin.String
|
||||
public fun </*0*/ K> create(/*0*/ x: K, /*1*/ f: (K) -> kotlin.Int): kotlin.Int
|
||||
public fun </*0*/ T> create(/*0*/ x: T, /*1*/ f: (T) -> kotlin.String): kotlin.String
|
||||
public fun takeInt(/*0*/ s: kotlin.Int): kotlin.Unit
|
||||
public fun takeString(/*0*/ s: kotlin.String): kotlin.Unit
|
||||
public fun test_1(): kotlin.Unit
|
||||
public fun test_2(): kotlin.Unit
|
||||
public fun test_3(): kotlin.Unit
|
||||
public fun test_4(): kotlin.Unit
|
||||
public fun test_5(): kotlin.Unit
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
// !LANGUAGE: +NewInference +FactoryPatternResolution
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_VARIABLE -UNUSED_EXPRESSION
|
||||
// ISSUE: KT-11265
|
||||
|
||||
fun create(f: (Int) -> Int): Int = 1
|
||||
fun create(f: (Int) -> String): String = ""
|
||||
|
||||
fun takeString(s: String) {}
|
||||
fun takeInt(s: Int) {}
|
||||
|
||||
fun test_1() {
|
||||
val x = <!AMBIGUITY!>create<!> { "" }
|
||||
takeString(x)
|
||||
}
|
||||
|
||||
fun test_2() {
|
||||
val x = <!AMBIGUITY!>create<!> { 1 }
|
||||
takeInt(x)
|
||||
}
|
||||
|
||||
fun test_3() {
|
||||
val x = <!AMBIGUITY!>create<!> { 1.0 }
|
||||
}
|
||||
|
||||
fun <K> create(x: K, f: (K) -> Int): Int = 1
|
||||
fun <T> create(x: T, f: (T) -> String): String = ""
|
||||
|
||||
fun test_4() {
|
||||
val x = <!AMBIGUITY!>create<!>("") { "" }
|
||||
takeString(x)
|
||||
}
|
||||
|
||||
fun test_5() {
|
||||
val x = <!AMBIGUITY!>create<!>("") { 1 }
|
||||
takeInt(x)
|
||||
}
|
||||
Vendored
+36
@@ -0,0 +1,36 @@
|
||||
// !LANGUAGE: +NewInference +FactoryPatternResolution
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_VARIABLE -UNUSED_EXPRESSION
|
||||
// ISSUE: KT-11265
|
||||
|
||||
fun create(f: (Int) -> Int): Int = 1
|
||||
fun create(f: (Int) -> String): String = ""
|
||||
|
||||
fun takeString(s: String) {}
|
||||
fun takeInt(s: Int) {}
|
||||
|
||||
fun test_1() {
|
||||
val x = create { "" }
|
||||
takeString(x)
|
||||
}
|
||||
|
||||
fun test_2() {
|
||||
val x = create { 1 }
|
||||
takeInt(x)
|
||||
}
|
||||
|
||||
fun test_3() {
|
||||
val x = <!NONE_APPLICABLE!>create<!> { 1.0 }
|
||||
}
|
||||
|
||||
fun <K> create(x: K, f: (K) -> Int): Int = 1
|
||||
fun <T> create(x: T, f: (T) -> String): String = ""
|
||||
|
||||
fun test_4() {
|
||||
val x = create("") { "" }
|
||||
takeString(x)
|
||||
}
|
||||
|
||||
fun test_5() {
|
||||
val x = create("") { 1 }
|
||||
takeInt(x)
|
||||
}
|
||||
Vendored
+13
@@ -0,0 +1,13 @@
|
||||
package
|
||||
|
||||
public fun create(/*0*/ f: (kotlin.Int) -> kotlin.Int): kotlin.Int
|
||||
public fun create(/*0*/ f: (kotlin.Int) -> kotlin.String): kotlin.String
|
||||
public fun </*0*/ K> create(/*0*/ x: K, /*1*/ f: (K) -> kotlin.Int): kotlin.Int
|
||||
public fun </*0*/ T> create(/*0*/ x: T, /*1*/ f: (T) -> kotlin.String): kotlin.String
|
||||
public fun takeInt(/*0*/ s: kotlin.Int): kotlin.Unit
|
||||
public fun takeString(/*0*/ s: kotlin.String): kotlin.Unit
|
||||
public fun test_1(): kotlin.Unit
|
||||
public fun test_2(): kotlin.Unit
|
||||
public fun test_3(): kotlin.Unit
|
||||
public fun test_4(): kotlin.Unit
|
||||
public fun test_5(): kotlin.Unit
|
||||
+23
@@ -2803,6 +2803,29 @@ public class DiagnosticsTestWithStdLibGenerated extends AbstractDiagnosticsTestW
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/diagnostics/testsWithStdLib/factoryPattern")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class FactoryPattern extends AbstractDiagnosticsTestWithStdLib {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInFactoryPattern() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/testsWithStdLib/factoryPattern"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("overloadByLambdaReturnType_disabled.kt")
|
||||
public void testOverloadByLambdaReturnType_disabled() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/factoryPattern/overloadByLambdaReturnType_disabled.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("overloadByLambdaReturnType_enabled.kt")
|
||||
public void testOverloadByLambdaReturnType_enabled() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/factoryPattern/overloadByLambdaReturnType_enabled.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/diagnostics/testsWithStdLib/forInArrayLoop")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsTestWithStdLibUsingJavacGenerated.java
Generated
+23
@@ -2803,6 +2803,29 @@ public class DiagnosticsTestWithStdLibUsingJavacGenerated extends AbstractDiagno
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/diagnostics/testsWithStdLib/factoryPattern")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class FactoryPattern extends AbstractDiagnosticsTestWithStdLibUsingJavac {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInFactoryPattern() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/testsWithStdLib/factoryPattern"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("overloadByLambdaReturnType_disabled.kt")
|
||||
public void testOverloadByLambdaReturnType_disabled() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/factoryPattern/overloadByLambdaReturnType_disabled.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("overloadByLambdaReturnType_enabled.kt")
|
||||
public void testOverloadByLambdaReturnType_enabled() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/factoryPattern/overloadByLambdaReturnType_enabled.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/diagnostics/testsWithStdLib/forInArrayLoop")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
@@ -153,6 +153,7 @@ enum class LanguageFeature(
|
||||
FunctionReferenceWithDefaultValueAsOtherType(sinceVersion = KOTLIN_1_4),
|
||||
NonStrictOnlyInputTypesChecks(sinceVersion = KOTLIN_1_4),
|
||||
SuspendConversion(sinceVersion = KOTLIN_1_4, defaultState = State.DISABLED),
|
||||
FactoryPatternResolution(sinceVersion = KOTLIN_1_4),
|
||||
|
||||
BooleanElvisBoundSmartCasts(sinceVersion = KOTLIN_1_3, defaultState = State.DISABLED), // see KT-26357 for details
|
||||
NewDataFlowForTryExpressions(sinceVersion = KOTLIN_1_4, defaultState = State.DISABLED),
|
||||
|
||||
@@ -148,4 +148,17 @@ inline fun <T, R, C : MutableCollection<in R>> Iterable<T>.flatMapToNullable(des
|
||||
}
|
||||
|
||||
fun <E : Enum<E>> min(a: E, b: E): E = if (a < b) a else b
|
||||
fun <E : Comparable<E>> min(a: E, b: E): E = if (a < b) a else b
|
||||
fun <E : Comparable<E>> min(a: E, b: E): E = if (a < b) a else b
|
||||
|
||||
inline fun <T, R> Iterable<T>.same(extractor: (T) -> R): Boolean {
|
||||
val iterator = iterator()
|
||||
val firstValue = extractor(iterator.next())
|
||||
while (iterator.hasNext()) {
|
||||
val item = iterator.next()
|
||||
val value = extractor(item)
|
||||
if (value != firstValue) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
Reference in New Issue
Block a user