From 79bed083e605777be8233daa7fb5547d6caa5629 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Fri, 4 Nov 2022 08:36:57 +0100 Subject: [PATCH] [FIR] allow primary constructors in interfaces to support invalid code KTIJ-23504 --- ...sSourceModuleResolveCallTestGenerated.java | 6 +++++ ...sSourceModuleResolveCallTestGenerated.java | 6 +++++ ...sSourceModuleResolveCallTestGenerated.java | 6 +++++ .../superTypeCallEntryResolveToCallInfo.kt | 7 +++++ .../superTypeCallEntryResolveToCallInfo.txt | 14 ++++++++++ .../constructorInInterface.fir.txt | 14 ++++++++++ .../diagnostics/constructorInInterface.kt | 4 +-- .../typeAliasWithTypeArguments.fir.txt | 4 +++ .../resolve/typeAliasWithTypeArguments.kt | 2 +- .../checkers/CommonDeclarationCheckers.kt | 1 - .../FirConstructorInInterfaceChecker.kt | 26 ------------------- .../converter/DeclarationsConverter.kt | 2 +- .../kotlin/fir/builder/RawFirBuilder.kt | 7 +++-- .../tests/SupertypeListChecks.fir.kt | 2 +- .../tests/TraitWithConstructor.fir.kt | 18 ------------- .../diagnostics/tests/TraitWithConstructor.kt | 1 + .../traitSupertypeList.fir.kt | 4 +-- 17 files changed, 68 insertions(+), 56 deletions(-) create mode 100644 analysis/analysis-api/testData/components/callResolver/resolveCall/superTypeCallEntryResolveToCallInfo.kt create mode 100644 analysis/analysis-api/testData/components/callResolver/resolveCall/superTypeCallEntryResolveToCallInfo.txt delete mode 100644 compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirConstructorInInterfaceChecker.kt delete mode 100644 compiler/testData/diagnostics/tests/TraitWithConstructor.fir.kt diff --git a/analysis/analysis-api-fe10/tests-gen/org/jetbrains/kotlin/analysis/api/fe10/test/cases/generated/cases/components/callResolver/Fe10IdeNormalAnalysisSourceModuleResolveCallTestGenerated.java b/analysis/analysis-api-fe10/tests-gen/org/jetbrains/kotlin/analysis/api/fe10/test/cases/generated/cases/components/callResolver/Fe10IdeNormalAnalysisSourceModuleResolveCallTestGenerated.java index 4a0c6a40c25..95ad3001d44 100644 --- a/analysis/analysis-api-fe10/tests-gen/org/jetbrains/kotlin/analysis/api/fe10/test/cases/generated/cases/components/callResolver/Fe10IdeNormalAnalysisSourceModuleResolveCallTestGenerated.java +++ b/analysis/analysis-api-fe10/tests-gen/org/jetbrains/kotlin/analysis/api/fe10/test/cases/generated/cases/components/callResolver/Fe10IdeNormalAnalysisSourceModuleResolveCallTestGenerated.java @@ -718,6 +718,12 @@ public class Fe10IdeNormalAnalysisSourceModuleResolveCallTestGenerated extends A runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/smartCastImplicitExtensionReceiver.kt"); } + @Test + @TestMetadata("superTypeCallEntryResolveToCallInfo.kt") + public void testSuperTypeCallEntryResolveToCallInfo() throws Exception { + runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/superTypeCallEntryResolveToCallInfo.kt"); + } + @Test @TestMetadata("unresolvableOperator_elvis_1.kt") public void testUnresolvableOperator_elvis_1() throws Exception { diff --git a/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/callResolver/FirIdeNormalAnalysisSourceModuleResolveCallTestGenerated.java b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/callResolver/FirIdeNormalAnalysisSourceModuleResolveCallTestGenerated.java index b666f1022b9..453e9533873 100644 --- a/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/callResolver/FirIdeNormalAnalysisSourceModuleResolveCallTestGenerated.java +++ b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/callResolver/FirIdeNormalAnalysisSourceModuleResolveCallTestGenerated.java @@ -718,6 +718,12 @@ public class FirIdeNormalAnalysisSourceModuleResolveCallTestGenerated extends Ab runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/smartCastImplicitExtensionReceiver.kt"); } + @Test + @TestMetadata("superTypeCallEntryResolveToCallInfo.kt") + public void testSuperTypeCallEntryResolveToCallInfo() throws Exception { + runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/superTypeCallEntryResolveToCallInfo.kt"); + } + @Test @TestMetadata("unresolvableOperator_elvis_1.kt") public void testUnresolvableOperator_elvis_1() throws Exception { diff --git a/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/components/callResolver/FirStandaloneNormalAnalysisSourceModuleResolveCallTestGenerated.java b/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/components/callResolver/FirStandaloneNormalAnalysisSourceModuleResolveCallTestGenerated.java index 0b7941d1ff0..b83ebcb4a4c 100644 --- a/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/components/callResolver/FirStandaloneNormalAnalysisSourceModuleResolveCallTestGenerated.java +++ b/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/components/callResolver/FirStandaloneNormalAnalysisSourceModuleResolveCallTestGenerated.java @@ -718,6 +718,12 @@ public class FirStandaloneNormalAnalysisSourceModuleResolveCallTestGenerated ext runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/smartCastImplicitExtensionReceiver.kt"); } + @Test + @TestMetadata("superTypeCallEntryResolveToCallInfo.kt") + public void testSuperTypeCallEntryResolveToCallInfo() throws Exception { + runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/superTypeCallEntryResolveToCallInfo.kt"); + } + @Test @TestMetadata("unresolvableOperator_elvis_1.kt") public void testUnresolvableOperator_elvis_1() throws Exception { diff --git a/analysis/analysis-api/testData/components/callResolver/resolveCall/superTypeCallEntryResolveToCallInfo.kt b/analysis/analysis-api/testData/components/callResolver/resolveCall/superTypeCallEntryResolveToCallInfo.kt new file mode 100644 index 00000000000..09590be7137 --- /dev/null +++ b/analysis/analysis-api/testData/components/callResolver/resolveCall/superTypeCallEntryResolveToCallInfo.kt @@ -0,0 +1,7 @@ +interface SimpleClass() : java.lang.Object(), I { + fun foo() : String = "610" + toString() + + override fun toString() : String { return foo() } +} + +interface I {} \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/callResolver/resolveCall/superTypeCallEntryResolveToCallInfo.txt b/analysis/analysis-api/testData/components/callResolver/resolveCall/superTypeCallEntryResolveToCallInfo.txt new file mode 100644 index 00000000000..309bf762ba9 --- /dev/null +++ b/analysis/analysis-api/testData/components/callResolver/resolveCall/superTypeCallEntryResolveToCallInfo.txt @@ -0,0 +1,14 @@ +KtSuccessCallInfo: + call = KtDelegatedConstructorCall: + kind = SUPER_CALL + partiallyAppliedSymbol = KtPartiallyAppliedSymbol: + dispatchReceiver = null + extensionReceiver = null + signature = KtFunctionLikeSignature: + receiverType = null + returnType = java.lang.Object + symbol = (): java.lang.Object + valueParameters = [] + callableIdIfNonLocal = null + typeArgumentsMapping = {} + argumentMapping = {} \ No newline at end of file diff --git a/compiler/fir/analysis-tests/testData/resolve/diagnostics/constructorInInterface.fir.txt b/compiler/fir/analysis-tests/testData/resolve/diagnostics/constructorInInterface.fir.txt index c930dde7117..4d0950fe161 100644 --- a/compiler/fir/analysis-tests/testData/resolve/diagnostics/constructorInInterface.fir.txt +++ b/compiler/fir/analysis-tests/testData/resolve/diagnostics/constructorInInterface.fir.txt @@ -1,7 +1,21 @@ FILE: constructorInInterface.kt public abstract interface A : R|kotlin/Any| { + public constructor(s: R|kotlin/String|): R|A| { + super() + } + + public open val s: R|kotlin/String| = R|/s| + public get(): R|kotlin/String| + } public abstract interface B : R|kotlin/Any| { + public constructor(s: R|kotlin/String|): R|B| { + super() + } + + public open val s: R|kotlin/String| = R|/s| + public get(): R|kotlin/String| + } public abstract interface C : R|kotlin/Any| { public constructor(s: R|kotlin/String|): R|C| { diff --git a/compiler/fir/analysis-tests/testData/resolve/diagnostics/constructorInInterface.kt b/compiler/fir/analysis-tests/testData/resolve/diagnostics/constructorInInterface.kt index 07b507704e1..ba1fa7e4554 100644 --- a/compiler/fir/analysis-tests/testData/resolve/diagnostics/constructorInInterface.kt +++ b/compiler/fir/analysis-tests/testData/resolve/diagnostics/constructorInInterface.kt @@ -1,6 +1,6 @@ -interface A(val s: String) +interface A(val s: String) -interface B constructor(val s: String) +interface B constructor(val s: String) interface C { constructor(s: String) {} diff --git a/compiler/fir/analysis-tests/testData/resolve/typeAliasWithTypeArguments.fir.txt b/compiler/fir/analysis-tests/testData/resolve/typeAliasWithTypeArguments.fir.txt index 150abf3b79f..06a411730ea 100644 --- a/compiler/fir/analysis-tests/testData/resolve/typeAliasWithTypeArguments.fir.txt +++ b/compiler/fir/analysis-tests/testData/resolve/typeAliasWithTypeArguments.fir.txt @@ -12,6 +12,10 @@ FILE: typeAliasWithTypeArguments.kt } public abstract interface Inv : R|kotlin/Any| { + public constructor(): R|Inv| { + super() + } + public abstract fun k(): R|K| public abstract fun t(): R|T| diff --git a/compiler/fir/analysis-tests/testData/resolve/typeAliasWithTypeArguments.kt b/compiler/fir/analysis-tests/testData/resolve/typeAliasWithTypeArguments.kt index 3284a8adb33..3d7b2940bcd 100644 --- a/compiler/fir/analysis-tests/testData/resolve/typeAliasWithTypeArguments.kt +++ b/compiler/fir/analysis-tests/testData/resolve/typeAliasWithTypeArguments.kt @@ -10,7 +10,7 @@ interface C { fun baz() } -interface Inv() { +interface Inv() { fun k(): K fun t(): T } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonDeclarationCheckers.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonDeclarationCheckers.kt index b0bf92fa2cb..e89a46b6c37 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonDeclarationCheckers.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonDeclarationCheckers.kt @@ -98,7 +98,6 @@ object CommonDeclarationCheckers : DeclarationCheckers() { FirAnnotationClassDeclarationChecker, FirOptInAnnotationClassChecker, FirCommonConstructorDelegationIssuesChecker, - FirConstructorInInterfaceChecker, FirDelegationSuperCallInEnumConstructorChecker, FirDelegationInInterfaceSyntaxChecker, FirEnumClassSimpleChecker, diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirConstructorInInterfaceChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirConstructorInInterfaceChecker.kt deleted file mode 100644 index 41c5ed5525c..00000000000 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirConstructorInInterfaceChecker.kt +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. - * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. - */ - -package org.jetbrains.kotlin.fir.analysis.checkers.declaration - -import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext -import org.jetbrains.kotlin.diagnostics.DiagnosticReporter -import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors -import org.jetbrains.kotlin.diagnostics.hasPrimaryConstructor -import org.jetbrains.kotlin.diagnostics.reportOn -import org.jetbrains.kotlin.fir.declarations.FirRegularClass -import org.jetbrains.kotlin.fir.declarations.utils.isInterface - -object FirConstructorInInterfaceChecker : FirRegularClassChecker() { - override fun check(declaration: FirRegularClass, context: CheckerContext, reporter: DiagnosticReporter) { - if (!declaration.isInterface) { - return - } - - if (declaration.source?.hasPrimaryConstructor() == true) { - reporter.reportOn(declaration.source, FirErrors.CONSTRUCTOR_IN_INTERFACE, context) - } - } -} diff --git a/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/DeclarationsConverter.kt b/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/DeclarationsConverter.kt index 16b2b2d5a76..400b9abcde3 100644 --- a/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/DeclarationsConverter.kt +++ b/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/DeclarationsConverter.kt @@ -861,7 +861,7 @@ class DeclarationsConverter( if (primaryConstructor == null && (containingClassIsExpectClass && classKind != ClassKind.ENUM_CLASS && classKind != ClassKind.ENUM_ENTRY) ) return null - if (classWrapper.isInterface()) return null + if (primaryConstructor == null && classWrapper.isInterface()) return null var modifiers = Modifier() val valueParameters = mutableListOf() diff --git a/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt b/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt index cdfc861fa3a..4d103d054bd 100644 --- a/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt +++ b/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt @@ -9,7 +9,6 @@ import com.intellij.psi.PsiElement import com.intellij.psi.tree.IElementType import org.jetbrains.kotlin.* import org.jetbrains.kotlin.builtins.StandardNames.BACKING_FIELD -import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Visibilities @@ -873,10 +872,10 @@ open class RawFirBuilder( // TODO: in case we have no primary constructor, // it may be not possible to determine delegated super type right here delegatedSuperTypeRef = delegatedSuperTypeRef ?: defaultDelegatedSuperTypeRef - val shouldNotGenerateImplicitPrimaryConstructor = hasExplicitPrimaryConstructor() || hasSecondaryConstructors() || - (containingClassIsExpectClass && classKind != ClassKind.ENUM_CLASS) + val shouldGenerateImplicitPrimaryConstructor = + !hasExplicitPrimaryConstructor() && !hasSecondaryConstructors() && !(containingClassIsExpectClass && classKind != ClassKind.ENUM_CLASS) - if ((this !is KtClass || !this.isInterface()) && (primaryConstructor != null || !shouldNotGenerateImplicitPrimaryConstructor)) { + if (primaryConstructor != null || (this !is KtClass || !this.isInterface()) && shouldGenerateImplicitPrimaryConstructor) { val firPrimaryConstructor = primaryConstructor.toFirConstructor( superTypeCallEntry, delegatedSuperTypeRef!!, diff --git a/compiler/testData/diagnostics/tests/SupertypeListChecks.fir.kt b/compiler/testData/diagnostics/tests/SupertypeListChecks.fir.kt index 88e5d08ed79..4063957c3f8 100644 --- a/compiler/testData/diagnostics/tests/SupertypeListChecks.fir.kt +++ b/compiler/testData/diagnostics/tests/SupertypeListChecks.fir.kt @@ -21,7 +21,7 @@ interface T1 {} interface T2 {} -interface Test() { +interface Test() { } interface Test1 : C2() {} diff --git a/compiler/testData/diagnostics/tests/TraitWithConstructor.fir.kt b/compiler/testData/diagnostics/tests/TraitWithConstructor.fir.kt deleted file mode 100644 index fc2b752110b..00000000000 --- a/compiler/testData/diagnostics/tests/TraitWithConstructor.fir.kt +++ /dev/null @@ -1,18 +0,0 @@ -// !DIAGNOSTICS: -MISSING_CONSTRUCTOR_KEYWORD - -class C(val a: String) {} - -interface T1(val x: String) {} - -interface T2 constructor() {} - -interface T3 private constructor(a: Int) {} - -interface T4 { - constructor(a: Int) { - val b: Int = 1 - } -} - -interface T5 private () : T4 {} -interface T6 private : T5 {} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/TraitWithConstructor.kt b/compiler/testData/diagnostics/tests/TraitWithConstructor.kt index 5b380da0daa..a36d9f70204 100644 --- a/compiler/testData/diagnostics/tests/TraitWithConstructor.kt +++ b/compiler/testData/diagnostics/tests/TraitWithConstructor.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !DIAGNOSTICS: -MISSING_CONSTRUCTOR_KEYWORD class C(val a: String) {} diff --git a/compiler/testData/diagnostics/tests/traitWithRequired/traitSupertypeList.fir.kt b/compiler/testData/diagnostics/tests/traitWithRequired/traitSupertypeList.fir.kt index 6a3facf9a42..4c031381891 100644 --- a/compiler/testData/diagnostics/tests/traitWithRequired/traitSupertypeList.fir.kt +++ b/compiler/testData/diagnostics/tests/traitWithRequired/traitSupertypeList.fir.kt @@ -1,10 +1,10 @@ open class bar() -interface Foo() : bar(), bar, bar { +interface Foo() : bar(), bar, bar { } interface Foo2 : bar, Foo { } -open class Foo1() : bar(), bar, Foo, Foo() {} +open class Foo1() : bar(), bar, Foo, Foo() {} open class Foo12 : bar(), bar {}