[FIR] Approximate integer constants in lhs of callable reference

This commit is contained in:
Dmitriy Novozhilov
2020-04-14 15:57:54 +03:00
parent c71f9d9640
commit f7dc06a772
8 changed files with 40 additions and 4 deletions
@@ -0,0 +1,9 @@
fun Short.foo(): Int = 1
fun Int.foo(): Int = 2
fun testRef(f: () -> Int) {}
fun test() {
// should resolve to Int.foo
testRef(1::foo)
}
@@ -0,0 +1,12 @@
FILE: integerLiteralInLhs.kt
public final fun R|kotlin/Short|.foo(): R|kotlin/Int| {
^foo Int(1)
}
public final fun R|kotlin/Int|.foo(): R|kotlin/Int| {
^foo Int(2)
}
public final fun testRef(f: R|() -> kotlin/Int|): R|kotlin/Unit| {
}
public final fun test(): R|kotlin/Unit| {
R|/testRef|(Int(1)::R|/foo|)
}
@@ -1637,6 +1637,11 @@ public class FirDiagnosticsTestGenerated extends AbstractFirDiagnosticsTest {
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve/references"), Pattern.compile("^([^.]+)\\.kt$"), null, true); KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve/references"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
} }
@TestMetadata("integerLiteralInLhs.kt")
public void testIntegerLiteralInLhs() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/references/integerLiteralInLhs.kt");
}
@TestMetadata("referenceToExtension.kt") @TestMetadata("referenceToExtension.kt")
public void testReferenceToExtension() throws Exception { public void testReferenceToExtension() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/references/referenceToExtension.kt"); runTest("compiler/fir/analysis-tests/testData/resolve/references/referenceToExtension.kt");
@@ -1637,6 +1637,11 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve/references"), Pattern.compile("^([^.]+)\\.kt$"), null, true); KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve/references"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
} }
@TestMetadata("integerLiteralInLhs.kt")
public void testIntegerLiteralInLhs() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/references/integerLiteralInLhs.kt");
}
@TestMetadata("referenceToExtension.kt") @TestMetadata("referenceToExtension.kt")
public void testReferenceToExtension() throws Exception { public void testReferenceToExtension() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/references/referenceToExtension.kt"); runTest("compiler/fir/analysis-tests/testData/resolve/references/referenceToExtension.kt");
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.fir.declarations.FirTypeAlias
import org.jetbrains.kotlin.fir.declarations.expandedConeType import org.jetbrains.kotlin.fir.declarations.expandedConeType
import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.references.FirNamedReference import org.jetbrains.kotlin.fir.references.FirNamedReference
import org.jetbrains.kotlin.fir.resolve.transformers.IntegerLiteralTypeApproximationTransformer
import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
import org.jetbrains.kotlin.types.Variance import org.jetbrains.kotlin.types.Variance
@@ -41,7 +42,8 @@ internal val FirFunctionCall.hasExplicitValueArguments: Boolean
get() = true // TODO: hasExplicitArgumentList || hasExplicitLambdaArguments get() = true // TODO: hasExplicitArgumentList || hasExplicitLambdaArguments
class FirDoubleColonExpressionResolver( class FirDoubleColonExpressionResolver(
private val session: FirSession private val session: FirSession,
private val integerLiteralTypeApproximator: IntegerLiteralTypeApproximationTransformer
) { ) {
// Returns true if the expression is not a call expression without value arguments (such as "A<B>") or a qualified expression // Returns true if the expression is not a call expression without value arguments (such as "A<B>") or a qualified expression
@@ -78,6 +80,9 @@ class FirDoubleColonExpressionResolver(
} }
internal fun resolveDoubleColonLHS(doubleColonExpression: FirCallableReferenceAccess): DoubleColonLHS? { internal fun resolveDoubleColonLHS(doubleColonExpression: FirCallableReferenceAccess): DoubleColonLHS? {
if (doubleColonExpression.explicitReceiver is FirConstExpression<*>) {
doubleColonExpression.transformExplicitReceiver(integerLiteralTypeApproximator, null)
}
val resultForExpr = tryResolveLHS(doubleColonExpression, this::shouldTryResolveLHSAsExpression, this::resolveExpressionOnLHS) val resultForExpr = tryResolveLHS(doubleColonExpression, this::shouldTryResolveLHSAsExpression, this::resolveExpressionOnLHS)
if (resultForExpr != null && !resultForExpr.isObjectQualifier) { if (resultForExpr != null && !resultForExpr.isObjectQualifier) {
return resultForExpr return resultForExpr
@@ -232,7 +232,6 @@ abstract class FirAbstractBodyResolveTransformer(phase: FirResolvePhase) : FirAb
override val inferenceComponents: InferenceComponents = inferenceComponents(session, returnTypeCalculator, scopeSession) override val inferenceComponents: InferenceComponents = inferenceComponents(session, returnTypeCalculator, scopeSession)
override val resolutionStageRunner: ResolutionStageRunner = ResolutionStageRunner(inferenceComponents) override val resolutionStageRunner: ResolutionStageRunner = ResolutionStageRunner(inferenceComponents)
override val samResolver: FirSamResolver = FirSamResolverImpl(session, scopeSession) override val samResolver: FirSamResolver = FirSamResolverImpl(session, scopeSession)
override val doubleColonExpressionResolver: FirDoubleColonExpressionResolver = FirDoubleColonExpressionResolver(session)
private val qualifiedResolver: FirQualifiedNameResolver = FirQualifiedNameResolver(this) private val qualifiedResolver: FirQualifiedNameResolver = FirQualifiedNameResolver(this)
override val callResolver: FirCallResolver = FirCallResolver( override val callResolver: FirCallResolver = FirCallResolver(
this, this,
@@ -247,6 +246,8 @@ abstract class FirAbstractBodyResolveTransformer(phase: FirResolvePhase) : FirAb
override val syntheticCallGenerator: FirSyntheticCallGenerator = FirSyntheticCallGenerator(this) override val syntheticCallGenerator: FirSyntheticCallGenerator = FirSyntheticCallGenerator(this)
override val integerLiteralTypeApproximator: IntegerLiteralTypeApproximationTransformer = override val integerLiteralTypeApproximator: IntegerLiteralTypeApproximationTransformer =
IntegerLiteralTypeApproximationTransformer(symbolProvider, inferenceComponents.ctx) IntegerLiteralTypeApproximationTransformer(symbolProvider, inferenceComponents.ctx)
override val doubleColonExpressionResolver: FirDoubleColonExpressionResolver =
FirDoubleColonExpressionResolver(session, integerLiteralTypeApproximator)
override val integerOperatorsTypeUpdater: IntegerOperatorsTypeUpdater = IntegerOperatorsTypeUpdater(integerLiteralTypeApproximator) override val integerOperatorsTypeUpdater: IntegerOperatorsTypeUpdater = IntegerOperatorsTypeUpdater(integerLiteralTypeApproximator)
} }
} }
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
fun Boolean.foo() = 1 fun Boolean.foo() = 1
fun Byte.foo() = 2 fun Byte.foo() = 2
fun Short.foo() = 3 fun Short.foo() = 3
@@ -7,5 +7,5 @@ fun f(x: KClass<out Int>) {}
fun test() { fun test() {
f(42::class) f(42::class)
f((40 + 2)::class) f((40 + 2)::class)
<!UNRESOLVED_REFERENCE!>42::toInt<!> 42::toInt
} }