From f7dc06a772dacc0e8f83616753595ef4b19a0a44 Mon Sep 17 00:00:00 2001 From: Dmitriy Novozhilov Date: Tue, 14 Apr 2020 15:57:54 +0300 Subject: [PATCH] [FIR] Approximate integer constants in lhs of callable reference --- .../resolve/references/integerLiteralInLhs.kt | 9 +++++++++ .../resolve/references/integerLiteralInLhs.txt | 12 ++++++++++++ .../kotlin/fir/FirDiagnosticsTestGenerated.java | 5 +++++ .../FirDiagnosticsWithLightTreeTestGenerated.java | 5 +++++ .../fir/resolve/FirDoubleColonExpressionResolver.kt | 7 ++++++- .../resolve/FirAbstractBodyResolveTransformer.kt | 3 ++- .../box/callableReference/bound/primitiveReceiver.kt | 1 - .../tests/classLiteral/integerValueType.fir.kt | 2 +- 8 files changed, 40 insertions(+), 4 deletions(-) create mode 100644 compiler/fir/analysis-tests/testData/resolve/references/integerLiteralInLhs.kt create mode 100644 compiler/fir/analysis-tests/testData/resolve/references/integerLiteralInLhs.txt diff --git a/compiler/fir/analysis-tests/testData/resolve/references/integerLiteralInLhs.kt b/compiler/fir/analysis-tests/testData/resolve/references/integerLiteralInLhs.kt new file mode 100644 index 00000000000..cb39869714a --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/references/integerLiteralInLhs.kt @@ -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) +} \ No newline at end of file diff --git a/compiler/fir/analysis-tests/testData/resolve/references/integerLiteralInLhs.txt b/compiler/fir/analysis-tests/testData/resolve/references/integerLiteralInLhs.txt new file mode 100644 index 00000000000..c520d569d77 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/references/integerLiteralInLhs.txt @@ -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|) + } diff --git a/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirDiagnosticsTestGenerated.java index c40884f1de5..e6e77cc897e 100644 --- a/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirDiagnosticsTestGenerated.java @@ -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); } + @TestMetadata("integerLiteralInLhs.kt") + public void testIntegerLiteralInLhs() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/references/integerLiteralInLhs.kt"); + } + @TestMetadata("referenceToExtension.kt") public void testReferenceToExtension() throws Exception { runTest("compiler/fir/analysis-tests/testData/resolve/references/referenceToExtension.kt"); diff --git a/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithLightTreeTestGenerated.java b/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithLightTreeTestGenerated.java index 209ca256894..cffc32f8c43 100644 --- a/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithLightTreeTestGenerated.java +++ b/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithLightTreeTestGenerated.java @@ -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); } + @TestMetadata("integerLiteralInLhs.kt") + public void testIntegerLiteralInLhs() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/references/integerLiteralInLhs.kt"); + } + @TestMetadata("referenceToExtension.kt") public void testReferenceToExtension() throws Exception { runTest("compiler/fir/analysis-tests/testData/resolve/references/referenceToExtension.kt"); diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/FirDoubleColonExpressionResolver.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/FirDoubleColonExpressionResolver.kt index 6b5bdee4745..d5d269a78c0 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/FirDoubleColonExpressionResolver.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/FirDoubleColonExpressionResolver.kt @@ -14,6 +14,7 @@ import org.jetbrains.kotlin.fir.declarations.FirTypeAlias import org.jetbrains.kotlin.fir.declarations.expandedConeType import org.jetbrains.kotlin.fir.expressions.* 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.impl.ConeClassLikeTypeImpl import org.jetbrains.kotlin.types.Variance @@ -41,7 +42,8 @@ internal val FirFunctionCall.hasExplicitValueArguments: Boolean get() = true // TODO: hasExplicitArgumentList || hasExplicitLambdaArguments 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") or a qualified expression @@ -78,6 +80,9 @@ class FirDoubleColonExpressionResolver( } internal fun resolveDoubleColonLHS(doubleColonExpression: FirCallableReferenceAccess): DoubleColonLHS? { + if (doubleColonExpression.explicitReceiver is FirConstExpression<*>) { + doubleColonExpression.transformExplicitReceiver(integerLiteralTypeApproximator, null) + } val resultForExpr = tryResolveLHS(doubleColonExpression, this::shouldTryResolveLHSAsExpression, this::resolveExpressionOnLHS) if (resultForExpr != null && !resultForExpr.isObjectQualifier) { return resultForExpr diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirAbstractBodyResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirAbstractBodyResolveTransformer.kt index 978d9263673..e0b65140c7c 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirAbstractBodyResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirAbstractBodyResolveTransformer.kt @@ -232,7 +232,6 @@ abstract class FirAbstractBodyResolveTransformer(phase: FirResolvePhase) : FirAb override val inferenceComponents: InferenceComponents = inferenceComponents(session, returnTypeCalculator, scopeSession) override val resolutionStageRunner: ResolutionStageRunner = ResolutionStageRunner(inferenceComponents) override val samResolver: FirSamResolver = FirSamResolverImpl(session, scopeSession) - override val doubleColonExpressionResolver: FirDoubleColonExpressionResolver = FirDoubleColonExpressionResolver(session) private val qualifiedResolver: FirQualifiedNameResolver = FirQualifiedNameResolver(this) override val callResolver: FirCallResolver = FirCallResolver( this, @@ -247,6 +246,8 @@ abstract class FirAbstractBodyResolveTransformer(phase: FirResolvePhase) : FirAb override val syntheticCallGenerator: FirSyntheticCallGenerator = FirSyntheticCallGenerator(this) override val integerLiteralTypeApproximator: IntegerLiteralTypeApproximationTransformer = IntegerLiteralTypeApproximationTransformer(symbolProvider, inferenceComponents.ctx) + override val doubleColonExpressionResolver: FirDoubleColonExpressionResolver = + FirDoubleColonExpressionResolver(session, integerLiteralTypeApproximator) override val integerOperatorsTypeUpdater: IntegerOperatorsTypeUpdater = IntegerOperatorsTypeUpdater(integerLiteralTypeApproximator) } } diff --git a/compiler/testData/codegen/box/callableReference/bound/primitiveReceiver.kt b/compiler/testData/codegen/box/callableReference/bound/primitiveReceiver.kt index 9b98db647bf..2773e0cdcd1 100644 --- a/compiler/testData/codegen/box/callableReference/bound/primitiveReceiver.kt +++ b/compiler/testData/codegen/box/callableReference/bound/primitiveReceiver.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR fun Boolean.foo() = 1 fun Byte.foo() = 2 fun Short.foo() = 3 diff --git a/compiler/testData/diagnostics/tests/classLiteral/integerValueType.fir.kt b/compiler/testData/diagnostics/tests/classLiteral/integerValueType.fir.kt index 5eba48b42c9..53b51edd83f 100644 --- a/compiler/testData/diagnostics/tests/classLiteral/integerValueType.fir.kt +++ b/compiler/testData/diagnostics/tests/classLiteral/integerValueType.fir.kt @@ -7,5 +7,5 @@ fun f(x: KClass) {} fun test() { f(42::class) f((40 + 2)::class) - 42::toInt + 42::toInt }