From aadfc59d0f4a2ce1a2d08180af180f3e943d49f2 Mon Sep 17 00:00:00 2001 From: Dmitriy Novozhilov Date: Fri, 4 Feb 2022 15:28:02 +0300 Subject: [PATCH] [FIR] Complete delegated constructor calls without proper constructed type This is needed to definitely complete arguments of such calls --- .../unresolvedSuperReference.descriptors.txt | 3 +++ .../resolveCall/unresolvedSuperReference.txt | 2 +- ...nosisCompilerFirTestdataTestGenerated.java | 6 +++++ ...TouchedTilContractsPhaseTestGenerated.java | 5 ++++ .../erroneousDelegatedConstructorCall.fir.txt | 7 +++++ .../erroneousDelegatedConstructorCall.kt | 2 ++ .../runners/FirDiagnosticTestGenerated.java | 6 +++++ ...DiagnosticsWithLightTreeTestGenerated.java | 6 +++++ .../jetbrains/kotlin/fir/FirCallResolver.kt | 26 ++++++++++++++----- .../FirExpressionsResolveTransformer.kt | 18 +++++-------- 10 files changed, 62 insertions(+), 19 deletions(-) create mode 100644 analysis/analysis-api/testData/components/callResolver/resolveCall/unresolvedSuperReference.descriptors.txt create mode 100644 compiler/fir/analysis-tests/testData/resolve/constructors/erroneousDelegatedConstructorCall.fir.txt create mode 100644 compiler/fir/analysis-tests/testData/resolve/constructors/erroneousDelegatedConstructorCall.kt diff --git a/analysis/analysis-api/testData/components/callResolver/resolveCall/unresolvedSuperReference.descriptors.txt b/analysis/analysis-api/testData/components/callResolver/resolveCall/unresolvedSuperReference.descriptors.txt new file mode 100644 index 00000000000..75a68b6d735 --- /dev/null +++ b/analysis/analysis-api/testData/components/callResolver/resolveCall/unresolvedSuperReference.descriptors.txt @@ -0,0 +1,3 @@ +KtErrorCallInfo: + candidateCalls = [] + diagnostic = ERROR diff --git a/analysis/analysis-api/testData/components/callResolver/resolveCall/unresolvedSuperReference.txt b/analysis/analysis-api/testData/components/callResolver/resolveCall/unresolvedSuperReference.txt index 4ee017f7063..3b4bc902b98 100644 --- a/analysis/analysis-api/testData/components/callResolver/resolveCall/unresolvedSuperReference.txt +++ b/analysis/analysis-api/testData/components/callResolver/resolveCall/unresolvedSuperReference.txt @@ -1,3 +1,3 @@ KtErrorCallInfo: candidateCalls = [] - diagnostic = ERROR \ No newline at end of file + diagnostic = ERROR diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerFirTestdataTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerFirTestdataTestGenerated.java index 1fe9959c18e..736b86bd126 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerFirTestdataTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerFirTestdataTestGenerated.java @@ -1175,6 +1175,12 @@ public class DiagnosisCompilerFirTestdataTestGenerated extends AbstractDiagnosis KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve/constructors"), Pattern.compile("^([^.]+)\\.kt$"), null, true); } + @Test + @TestMetadata("erroneousDelegatedConstructorCall.kt") + public void testErroneousDelegatedConstructorCall() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/constructors/erroneousDelegatedConstructorCall.kt"); + } + @Test @TestMetadata("noSuperCallInSupertypes.kt") public void testNoSuperCallInSupertypes() throws Exception { diff --git a/compiler/fir/analysis-tests/legacy-fir-tests/tests-gen/org/jetbrains/kotlin/fir/LazyBodyIsNotTouchedTilContractsPhaseTestGenerated.java b/compiler/fir/analysis-tests/legacy-fir-tests/tests-gen/org/jetbrains/kotlin/fir/LazyBodyIsNotTouchedTilContractsPhaseTestGenerated.java index 9390f5f053f..8cc69277367 100644 --- a/compiler/fir/analysis-tests/legacy-fir-tests/tests-gen/org/jetbrains/kotlin/fir/LazyBodyIsNotTouchedTilContractsPhaseTestGenerated.java +++ b/compiler/fir/analysis-tests/legacy-fir-tests/tests-gen/org/jetbrains/kotlin/fir/LazyBodyIsNotTouchedTilContractsPhaseTestGenerated.java @@ -1019,6 +1019,11 @@ public class LazyBodyIsNotTouchedTilContractsPhaseTestGenerated extends Abstract KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve/constructors"), Pattern.compile("^([^.]+)\\.kt$"), null, true); } + @TestMetadata("erroneousDelegatedConstructorCall.kt") + public void testErroneousDelegatedConstructorCall() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/constructors/erroneousDelegatedConstructorCall.kt"); + } + @TestMetadata("noSuperCallInSupertypes.kt") public void testNoSuperCallInSupertypes() throws Exception { runTest("compiler/fir/analysis-tests/testData/resolve/constructors/noSuperCallInSupertypes.kt"); diff --git a/compiler/fir/analysis-tests/testData/resolve/constructors/erroneousDelegatedConstructorCall.fir.txt b/compiler/fir/analysis-tests/testData/resolve/constructors/erroneousDelegatedConstructorCall.fir.txt new file mode 100644 index 00000000000..f8a48930878 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/constructors/erroneousDelegatedConstructorCall.fir.txt @@ -0,0 +1,7 @@ +FILE: erroneousDelegatedConstructorCall.kt + public final class A : { + public constructor(): R|A| { + super<>(R|/id|(R|/materialize|())) + } + + } diff --git a/compiler/fir/analysis-tests/testData/resolve/constructors/erroneousDelegatedConstructorCall.kt b/compiler/fir/analysis-tests/testData/resolve/constructors/erroneousDelegatedConstructorCall.kt new file mode 100644 index 00000000000..971c20b5b47 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/constructors/erroneousDelegatedConstructorCall.kt @@ -0,0 +1,2 @@ +// INFERENCE_HELPERS +class A : Undefined(id(materialize())) diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticTestGenerated.java index e07b4829ada..42c1f8b8c62 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticTestGenerated.java @@ -1175,6 +1175,12 @@ public class FirDiagnosticTestGenerated extends AbstractFirDiagnosticTest { KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve/constructors"), Pattern.compile("^([^.]+)\\.kt$"), null, true); } + @Test + @TestMetadata("erroneousDelegatedConstructorCall.kt") + public void testErroneousDelegatedConstructorCall() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/constructors/erroneousDelegatedConstructorCall.kt"); + } + @Test @TestMetadata("noSuperCallInSupertypes.kt") public void testNoSuperCallInSupertypes() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticsWithLightTreeTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticsWithLightTreeTestGenerated.java index 51cbe853ec9..5ab38c83cac 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticsWithLightTreeTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticsWithLightTreeTestGenerated.java @@ -1175,6 +1175,12 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve/constructors"), Pattern.compile("^([^.]+)\\.kt$"), null, true); } + @Test + @TestMetadata("erroneousDelegatedConstructorCall.kt") + public void testErroneousDelegatedConstructorCall() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/constructors/erroneousDelegatedConstructorCall.kt"); + } + @Test @TestMetadata("noSuperCallInSupertypes.kt") public void testNoSuperCallInSupertypes() throws Exception { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt index 6aef3a1a327..7bf69ee8f51 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt @@ -12,7 +12,9 @@ import org.jetbrains.kotlin.fir.declarations.utils.hasExplicitBackingField import org.jetbrains.kotlin.fir.declarations.utils.isInner import org.jetbrains.kotlin.fir.declarations.utils.isReferredViaField import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic +import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic import org.jetbrains.kotlin.fir.diagnostics.ConeStubDiagnostic +import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.builder.buildResolvedReifiedParameterReference import org.jetbrains.kotlin.fir.references.* @@ -436,15 +438,14 @@ class FirCallResolver( fun resolveDelegatingConstructorCall( delegatedConstructorCall: FirDelegatedConstructorCall, - constructedType: ConeClassLikeType + constructedType: ConeClassLikeType? ): FirDelegatedConstructorCall { val name = SpecialNames.INIT - val symbol = constructedType.lookupTag.toSymbol(components.session) - val typeArguments = - constructedType.typeArguments.take((symbol?.fir as? FirRegularClass)?.typeParameters?.count { it is FirTypeParameter } ?: 0) - .map { - it.toFirTypeProjection() - } + val symbol = constructedType?.lookupTag?.toSymbol(components.session) + val typeArguments = constructedType?.typeArguments + ?.take((symbol?.fir as? FirRegularClass)?.typeParameters?.count { it is FirTypeParameter } ?: 0) + ?.map { it.toFirTypeProjection() } + ?: emptyList() val callInfo = CallInfo( delegatedConstructorCall, @@ -460,6 +461,17 @@ class FirCallResolver( ) towerResolver.reset() + if (constructedType == null) { + val errorReference = createErrorReferenceWithErrorCandidate( + callInfo, + ConeSimpleDiagnostic("Erroneous delegated constructor call", DiagnosticKind.UnresolvedSupertype), + delegatedConstructorCall.calleeReference.source, + transformer.resolutionContext, + components.resolutionStageRunner + ) + return delegatedConstructorCall.transformCalleeReference(StoreNameReference, errorReference) + } + val result = towerResolver.runResolverForDelegatingConstructor( callInfo, constructedType, diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt index 07cb98de1fc..a3a62b301f5 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt @@ -1057,17 +1057,13 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform } val reference = delegatedConstructorCall.calleeReference - val constructorType: ConeClassLikeType = when (reference) { - is FirThisReference -> { - lastDispatchReceiver?.type as? ConeClassLikeType ?: return delegatedConstructorCall - } - is FirSuperReference -> { - // TODO: unresolved supertype - val supertype = reference.superTypeRef.coneTypeSafe() - ?.takeIf { it !is ConeErrorType } ?: return delegatedConstructorCall - supertype.fullyExpandedType(session) - } - else -> return delegatedConstructorCall + val constructorType: ConeClassLikeType? = when (reference) { + is FirThisReference -> lastDispatchReceiver?.type as? ConeClassLikeType + is FirSuperReference -> reference.superTypeRef + .coneTypeSafe() + ?.takeIf { it !is ConeErrorType } + ?.fullyExpandedType(session) + else -> null } val resolvedCall = callResolver.resolveDelegatingConstructorCall(delegatedConstructorCall, constructorType)