[FIR] allow primary constructors in interfaces to support invalid code

KTIJ-23504
This commit is contained in:
Anna Kozlova
2022-11-04 08:36:57 +01:00
parent ce94816d9e
commit 79bed083e6
17 changed files with 68 additions and 56 deletions
@@ -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 {
@@ -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 {
@@ -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 {
@@ -0,0 +1,7 @@
interface SimpleClass() : <expr>java.lang.Object()</expr>, I {
fun foo() : String = "610" + toString()
override fun toString() : String { return foo() }
}
interface I {}
@@ -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 = <constructor>(): java.lang.Object
valueParameters = []
callableIdIfNonLocal = null
typeArgumentsMapping = {}
argumentMapping = {}
@@ -1,7 +1,21 @@
FILE: constructorInInterface.kt
public abstract interface A : R|kotlin/Any| {
public constructor(s: R|kotlin/String|): R|A| {
super<R|kotlin/Any|>()
}
public open val s: R|kotlin/String| = R|<local>/s|
public get(): R|kotlin/String|
}
public abstract interface B : R|kotlin/Any| {
public constructor(s: R|kotlin/String|): R|B| {
super<R|kotlin/Any|>()
}
public open val s: R|kotlin/String| = R|<local>/s|
public get(): R|kotlin/String|
}
public abstract interface C : R|kotlin/Any| {
public constructor(s: R|kotlin/String|): R|C| {
@@ -1,6 +1,6 @@
interface <!CONSTRUCTOR_IN_INTERFACE!>A(val s: String)<!>
interface A<!CONSTRUCTOR_IN_INTERFACE!>(val s: String)<!>
interface <!CONSTRUCTOR_IN_INTERFACE!>B constructor(val s: String)<!>
interface B <!CONSTRUCTOR_IN_INTERFACE!>constructor(val s: String)<!>
interface C {
<!CONSTRUCTOR_IN_INTERFACE!>constructor(s: String)<!> {}
@@ -12,6 +12,10 @@ FILE: typeAliasWithTypeArguments.kt
}
public abstract interface Inv<K, T> : R|kotlin/Any| {
public constructor<K, T>(): R|Inv<K, T>| {
super<R|kotlin/Any|>()
}
public abstract fun k(): R|K|
public abstract fun t(): R|T|
@@ -10,7 +10,7 @@ interface C {
fun baz()
}
interface <!CONSTRUCTOR_IN_INTERFACE!>Inv<K, T>()<!> {
interface Inv<K, T><!CONSTRUCTOR_IN_INTERFACE!>()<!> {
fun k(): K
fun t(): T
}
@@ -98,7 +98,6 @@ object CommonDeclarationCheckers : DeclarationCheckers() {
FirAnnotationClassDeclarationChecker,
FirOptInAnnotationClassChecker,
FirCommonConstructorDelegationIssuesChecker,
FirConstructorInInterfaceChecker,
FirDelegationSuperCallInEnumConstructorChecker,
FirDelegationInInterfaceSyntaxChecker,
FirEnumClassSimpleChecker,
@@ -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)
}
}
}
@@ -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<ValueParameter>()
@@ -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!!,
@@ -21,7 +21,7 @@ interface T1 {}
interface T2<T> {}
interface <!CONSTRUCTOR_IN_INTERFACE!>Test()<!> {
interface Test<!CONSTRUCTOR_IN_INTERFACE!>()<!> {
}
interface Test1 : <!INTERFACE_WITH_SUPERCLASS, SUPERTYPE_INITIALIZED_IN_INTERFACE!>C2<!>() {}
@@ -1,18 +0,0 @@
// !DIAGNOSTICS: -MISSING_CONSTRUCTOR_KEYWORD
class C(val a: String) {}
interface <!CONSTRUCTOR_IN_INTERFACE!>T1(val x: String)<!> {}
interface <!CONSTRUCTOR_IN_INTERFACE!>T2 constructor()<!> {}
interface <!CONSTRUCTOR_IN_INTERFACE!>T3 private constructor(a: Int)<!> {}
interface T4 {
<!CONSTRUCTOR_IN_INTERFACE!>constructor(a: Int)<!> {
val b: Int = 1
}
}
interface <!CONSTRUCTOR_IN_INTERFACE!>T5 private ()<!> : T4 {}
interface <!CONSTRUCTOR_IN_INTERFACE!>T6<!> private<!SYNTAX!><!> : T5 {}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// !DIAGNOSTICS: -MISSING_CONSTRUCTOR_KEYWORD
class C(val a: String) {}
@@ -1,10 +1,10 @@
open class bar()
interface <!CONSTRUCTOR_IN_INTERFACE!>Foo()<!> : <!INTERFACE_WITH_SUPERCLASS, SUPERTYPE_INITIALIZED_IN_INTERFACE!>bar<!>(), <!MANY_CLASSES_IN_SUPERTYPE_LIST, SUPERTYPE_APPEARS_TWICE!>bar<!>, <!MANY_CLASSES_IN_SUPERTYPE_LIST, SUPERTYPE_APPEARS_TWICE!>bar<!> {
interface Foo<!CONSTRUCTOR_IN_INTERFACE!>()<!> : <!INTERFACE_WITH_SUPERCLASS, SUPERTYPE_INITIALIZED_IN_INTERFACE!>bar<!>(), <!MANY_CLASSES_IN_SUPERTYPE_LIST, SUPERTYPE_APPEARS_TWICE!>bar<!>, <!MANY_CLASSES_IN_SUPERTYPE_LIST, SUPERTYPE_APPEARS_TWICE!>bar<!> {
}
interface Foo2 : <!INTERFACE_WITH_SUPERCLASS!>bar<!>, Foo {
}
open class Foo1() : bar(), <!MANY_CLASSES_IN_SUPERTYPE_LIST, SUPERTYPE_APPEARS_TWICE!>bar<!>, Foo, <!SUPERTYPE_APPEARS_TWICE, UNRESOLVED_REFERENCE!>Foo<!>() {}
open class Foo1() : bar(), <!MANY_CLASSES_IN_SUPERTYPE_LIST, SUPERTYPE_APPEARS_TWICE!>bar<!>, Foo, <!SUPERTYPE_APPEARS_TWICE!>Foo<!>() {}
open class Foo12 : bar(), <!MANY_CLASSES_IN_SUPERTYPE_LIST, SUPERTYPE_APPEARS_TWICE!>bar<!> {}