[FIR] Supertype and inheritance checkers group

This commit is contained in:
Nick
2020-07-24 18:33:52 +03:00
parent 252eb1ad23
commit 28700ed64c
61 changed files with 1205 additions and 190 deletions
@@ -0,0 +1,5 @@
class A
interface C
enum class B : C, <!CLASS_IN_SUPERTYPE_FOR_ENUM!>A<!>(), Any()
@@ -0,0 +1,21 @@
FILE: classInSupertypeForEnum.kt
public final class A : R|kotlin/Any| {
public constructor(): R|A| {
super<R|kotlin/Any|>()
}
}
public abstract interface C : R|kotlin/Any| {
}
public final enum class B : R|C|, R|A|, R|kotlin/Any|, R|kotlin/Enum<B>| {
private constructor(): R|B| {
super<R|kotlin/Enum<B>|>()
}
public final static fun values(): R|kotlin/Array<B>| {
}
public final static fun valueOf(value: R|kotlin/String|): R|B| {
}
}
@@ -0,0 +1,7 @@
interface <!CONSTRUCTOR_IN_INTERFACE!>A(val s: String)<!>
interface <!CONSTRUCTOR_IN_INTERFACE!>B constructor(val s: String)<!>
interface C {
<!CONSTRUCTOR_IN_INTERFACE!>constructor(val s: String)<!> {}
}
@@ -0,0 +1,11 @@
FILE: constructorInInterface.kt
public abstract interface A : R|kotlin/Any| {
}
public abstract interface B : R|kotlin/Any| {
}
public abstract interface C : R|kotlin/Any| {
public constructor(s: R|kotlin/String|): R|C| {
super<R|kotlin/Any|>()
}
}
@@ -0,0 +1,9 @@
class A
interface B : <!DELEGATION_IN_INTERFACE, INTERFACE_WITH_SUPERCLASS!>A<!> by a {
val a: A
}
val test = A()
interface C : <!DELEGATION_IN_INTERFACE, INTERFACE_WITH_SUPERCLASS!>A<!> by test
@@ -0,0 +1,20 @@
FILE: delegationInInterface.kt
public final class A : R|kotlin/Any| {
public constructor(): R|A| {
super<R|kotlin/Any|>()
}
}
public abstract interface B : R|A| {
local final field <$$delegate_0>: R|A|
public abstract val a: R|A|
public get(): R|A|
}
public final val test: R|A| = R|/A.A|()
public get(): R|A|
public abstract interface C : R|A| {
local final field <$$delegate_0>: R|A|
}
@@ -0,0 +1,8 @@
class A
interface B : <!INTERFACE_WITH_SUPERCLASS, SUPERTYPE_INITIALIZED_IN_INTERFACE!>A<!>()
interface C
class D
interface E : <!INTERFACE_WITH_SUPERCLASS, SUPERTYPE_INITIALIZED_IN_INTERFACE!>A<!>(), C, D()
@@ -0,0 +1,19 @@
FILE: interfaceWithSuperclass.kt
public final class A : R|kotlin/Any| {
public constructor(): R|A| {
super<R|kotlin/Any|>()
}
}
public abstract interface B : R|A| {
}
public abstract interface C : R|kotlin/Any| {
}
public final class D : R|kotlin/Any| {
public constructor(): R|D| {
super<R|kotlin/Any|>()
}
}
public abstract interface E : R|A|, R|C|, R|D| {
}
@@ -0,0 +1,25 @@
interface A {
<!ANY_METHOD_IMPLEMENTED_IN_INTERFACE!>override fun toString() = "Hello"<!>
<!ANY_METHOD_IMPLEMENTED_IN_INTERFACE!>override fun equals(other: Any?) = true<!>
<!ANY_METHOD_IMPLEMENTED_IN_INTERFACE!>override fun hashCode(): Int {
return 42;
}<!>
}
interface B {
override fun toString(): String
override fun equals(other: Any?): Boolean
override fun hashCode(): Int
}
interface C {
<!ANY_METHOD_IMPLEMENTED_IN_INTERFACE!>override operator fun toString(): String = "Rest"<!>
<!ANY_METHOD_IMPLEMENTED_IN_INTERFACE!>override operator fun equals(other: Any?): Boolean = false<!>
<!ANY_METHOD_IMPLEMENTED_IN_INTERFACE!>override operator fun hashCode(): Int = 2<!>
}
interface D {
override operator fun toString(): String
override operator fun equals(other: Any?): Boolean
override operator fun hashCode(): Int
}
@@ -0,0 +1,45 @@
FILE: methodOfAnyImplementedInInterface.kt
public abstract interface A : R|kotlin/Any| {
public open override fun toString(): R|kotlin/String| {
^toString String(Hello)
}
public open override fun equals(other: R|kotlin/Any?|): R|kotlin/Boolean| {
^equals Boolean(true)
}
public open override fun hashCode(): R|kotlin/Int| {
^hashCode Int(42)
}
}
public abstract interface B : R|kotlin/Any| {
public abstract override fun toString(): R|kotlin/String|
public abstract override fun equals(other: R|kotlin/Any?|): R|kotlin/Boolean|
public abstract override fun hashCode(): R|kotlin/Int|
}
public abstract interface C : R|kotlin/Any| {
public open override operator fun toString(): R|kotlin/String| {
^toString String(Rest)
}
public open override operator fun equals(other: R|kotlin/Any?|): R|kotlin/Boolean| {
^equals Boolean(false)
}
public open override operator fun hashCode(): R|kotlin/Int| {
^hashCode Int(2)
}
}
public abstract interface D : R|kotlin/Any| {
public abstract override operator fun toString(): R|kotlin/String|
public abstract override operator fun equals(other: R|kotlin/Any?|): R|kotlin/Boolean|
public abstract override operator fun hashCode(): R|kotlin/Int|
}
@@ -0,0 +1,3 @@
sealed class A
val b = <!SEALED_CLASS_CONSTRUCTOR_CALL!>A<!>()
@@ -0,0 +1,9 @@
FILE: sealedClassConstructorCall.kt
public sealed class A : R|kotlin/Any| {
private constructor(): R|A| {
super<R|kotlin/Any|>()
}
}
public final val b: R|A| = R|/A.A|()
public get(): R|A|
@@ -0,0 +1,40 @@
sealed class A
<!REDECLARATION!>class B : A()<!>
interface C : <!INTERFACE_WITH_SUPERCLASS!>A<!>
interface D : C, <!INTERFACE_WITH_SUPERCLASS!>A<!>
class E : B, A()
sealed class P {
object H: P()
class J : P()
object T {
object V : P()
class M : P()
}
val p: P = object : <!SEALED_SUPERTYPE_IN_LOCAL_CLASS!>P<!>() {
}
val r = object : <!SEALED_SUPERTYPE_IN_LOCAL_CLASS!>P<!>() {
}
}
class K : P()
<!REDECLARATION!>object B<!> {
class I : <!SEALED_SUPERTYPE!>P<!>()
}
fun test() {
class L : <!SEALED_SUPERTYPE_IN_LOCAL_CLASS!>P<!>()
val a = object : <!SEALED_SUPERTYPE_IN_LOCAL_CLASS!>P<!>() {
}
}
@@ -0,0 +1,117 @@
FILE: sealedSupertype.kt
public sealed class A : R|kotlin/Any| {
private constructor(): R|A| {
super<R|kotlin/Any|>()
}
}
public final class B : R|A| {
public constructor(): R|B| {
super<R|A|>()
}
}
public abstract interface C : R|A| {
}
public abstract interface D : R|C|, R|A| {
}
public final class E : R|B|, R|A| {
public constructor(): R|E| {
super<R|A|>()
}
}
public sealed class P : R|kotlin/Any| {
private constructor(): R|P| {
super<R|kotlin/Any|>()
}
public final object H : R|P| {
private constructor(): R|P.H| {
super<R|P|>()
}
}
public final class J : R|P| {
public constructor(): R|P.J| {
super<R|P|>()
}
}
public final object T : R|kotlin/Any| {
private constructor(): R|P.T| {
super<R|kotlin/Any|>()
}
public final object V : R|P| {
private constructor(): R|P.T.V| {
super<R|P|>()
}
}
public final class M : R|P| {
public constructor(): R|P.T.M| {
super<R|P|>()
}
}
}
public final val p: R|P| = object : R|P| {
private constructor(): R|<anonymous>| {
super<R|P|>()
}
}
public get(): R|P|
public final val r: R|<anonymous>| = object : R|P| {
private constructor(): R|<anonymous>| {
super<R|P|>()
}
}
public get(): R|<anonymous>|
}
public final class K : R|P| {
public constructor(): R|K| {
super<R|P|>()
}
}
public final object B : R|kotlin/Any| {
private constructor(): R|B| {
super<R|kotlin/Any|>()
}
public final class I : R|P| {
public constructor(): R|B.I| {
super<R|P|>()
}
}
}
public final fun test(): R|kotlin/Unit| {
local final class L : R|P| {
public constructor(): R|L| {
super<R|P|>()
}
}
lval a: R|<anonymous>| = object : R|P| {
private constructor(): R|<anonymous>| {
super<R|P|>()
}
}
}
@@ -2,7 +2,7 @@ open class A {
open fun foo() {}
}
interface ATrait : A {
interface ATrait : <!INTERFACE_WITH_SUPERCLASS!>A<!> {
override fun foo() {
<!SUPERCLASS_NOT_ACCESSIBLE_FROM_INTERFACE!>super<A><!>.foo()
}
@@ -0,0 +1,13 @@
interface A
interface B : <!SUPERTYPE_INITIALIZED_IN_INTERFACE!>A<!>()
class C
interface D : <!INTERFACE_WITH_SUPERCLASS, SUPERTYPE_INITIALIZED_IN_INTERFACE!>C<!>()
interface E : <!INTERFACE_WITH_SUPERCLASS, SUPERTYPE_INITIALIZED_IN_INTERFACE!>Any<!>()
interface F : A, <!SUPERTYPE_INITIALIZED_IN_INTERFACE!>B<!>(), <!INTERFACE_WITH_SUPERCLASS!>C<!>, D(), Any() {
}
@@ -0,0 +1,17 @@
FILE: supertypeInitializedInInterface.kt
public abstract interface A : R|kotlin/Any| {
}
public abstract interface B : R|A| {
}
public final class C : R|kotlin/Any| {
public constructor(): R|C| {
super<R|kotlin/Any|>()
}
}
public abstract interface D : R|C| {
}
public abstract interface E : R|kotlin/Any| {
}
public abstract interface F : R|A|, R|B|, R|C|, R|D|, R|kotlin/Any| {
}
@@ -0,0 +1,3 @@
enum class A<<!TYPE_PARAMETERS_IN_ENUM!>B<!>, C : B, D>
enum class B
@@ -0,0 +1,25 @@
FILE: typeParametersInEnum.kt
public final enum class A<B, C : R|B|, D> : R|kotlin/Enum<A<B, C, D>>| {
private constructor<B, C : R|B|, D>(): R|A<B, C, D>| {
super<R|kotlin/Enum<A<B, C, D>>|>()
}
public final static fun values(): R|kotlin/Array<A>| {
}
public final static fun valueOf(value: R|kotlin/String|): R|A| {
}
}
public final enum class B : R|kotlin/Enum<B>| {
private constructor(): R|B| {
super<R|kotlin/Enum<B>|>()
}
public final static fun values(): R|kotlin/Array<B>| {
}
public final static fun valueOf(value: R|kotlin/String|): R|B| {
}
}
@@ -1,6 +1,6 @@
class Out<out T>
interface X : Out<String>
interface X : <!INTERFACE_WITH_SUPERCLASS!>Out<String><!>
abstract class Base<E> {
fun <D : Out<E>> f(t: MutableList<D>, e: MutableList<E>) {}
@@ -936,6 +936,21 @@ public class FirDiagnosticsTestGenerated extends AbstractFirDiagnosticsTest {
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/explicitDelegationCallRequired.kt");
}
@TestMetadata("classInSupertypeForEnum.kt")
public void testClassInSupertypeForEnum() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/classInSupertypeForEnum.kt");
}
@TestMetadata("constructorInInterface.kt")
public void testConstructorInInterface() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/constructorInInterface.kt");
}
@TestMetadata("delegationInInterface.kt")
public void testDelegationInInterface() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/delegationInInterface.kt");
}
@TestMetadata("incompatibleModifiers.kt")
public void testIncompatibleModifiers() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/incompatibleModifiers.kt");
@@ -946,6 +961,11 @@ public class FirDiagnosticsTestGenerated extends AbstractFirDiagnosticsTest {
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/infixFunctions.kt");
}
@TestMetadata("interfaceWithSuperclass.kt")
public void testInterfaceWithSuperclass() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/interfaceWithSuperclass.kt");
}
@TestMetadata("localAnnotationClass.kt")
public void testLocalAnnotationClass() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/localAnnotationClass.kt");
@@ -961,6 +981,11 @@ public class FirDiagnosticsTestGenerated extends AbstractFirDiagnosticsTest {
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/manyCompanionObjects.kt");
}
@TestMetadata("methodOfAnyImplementedInInterface.kt")
public void testMethodOfAnyImplementedInInterface() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/methodOfAnyImplementedInInterface.kt");
}
@TestMetadata("notASupertype.kt")
public void testNotASupertype() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/notASupertype.kt");
@@ -991,6 +1016,16 @@ public class FirDiagnosticsTestGenerated extends AbstractFirDiagnosticsTest {
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/repeatedModifier.kt");
}
@TestMetadata("sealedClassConstructorCall.kt")
public void testSealedClassConstructorCall() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/sealedClassConstructorCall.kt");
}
@TestMetadata("sealedSupertype.kt")
public void testSealedSupertype() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/sealedSupertype.kt");
}
@TestMetadata("superIsNotAnExpression.kt")
public void testSuperIsNotAnExpression() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/superIsNotAnExpression.kt");
@@ -1016,6 +1051,11 @@ public class FirDiagnosticsTestGenerated extends AbstractFirDiagnosticsTest {
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/typeArgumentsNotAllowed.kt");
}
@TestMetadata("supertypeInitializedInInterface.kt")
public void testSupertypeInitializedInInterface() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/supertypeInitializedInInterface.kt");
}
@TestMetadata("typeOfAnnotationMember.kt")
public void testTypeOfAnnotationMember() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/typeOfAnnotationMember.kt");
@@ -1026,6 +1066,11 @@ public class FirDiagnosticsTestGenerated extends AbstractFirDiagnosticsTest {
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/typeParametersInObject.kt");
}
@TestMetadata("typeParametersInEnum.kt")
public void testTypeParametersInEnum() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/typeParametersInEnum.kt");
}
@TestMetadata("upperBoundViolated.kt")
public void testUpperBoundViolated() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/upperBoundViolated.kt");
@@ -936,6 +936,21 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/explicitDelegationCallRequired.kt");
}
@TestMetadata("classInSupertypeForEnum.kt")
public void testClassInSupertypeForEnum() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/classInSupertypeForEnum.kt");
}
@TestMetadata("constructorInInterface.kt")
public void testConstructorInInterface() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/constructorInInterface.kt");
}
@TestMetadata("delegationInInterface.kt")
public void testDelegationInInterface() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/delegationInInterface.kt");
}
@TestMetadata("incompatibleModifiers.kt")
public void testIncompatibleModifiers() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/incompatibleModifiers.kt");
@@ -946,6 +961,11 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/infixFunctions.kt");
}
@TestMetadata("interfaceWithSuperclass.kt")
public void testInterfaceWithSuperclass() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/interfaceWithSuperclass.kt");
}
@TestMetadata("localAnnotationClass.kt")
public void testLocalAnnotationClass() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/localAnnotationClass.kt");
@@ -961,6 +981,11 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/manyCompanionObjects.kt");
}
@TestMetadata("methodOfAnyImplementedInInterface.kt")
public void testMethodOfAnyImplementedInInterface() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/methodOfAnyImplementedInInterface.kt");
}
@TestMetadata("notASupertype.kt")
public void testNotASupertype() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/notASupertype.kt");
@@ -991,6 +1016,16 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/repeatedModifier.kt");
}
@TestMetadata("sealedClassConstructorCall.kt")
public void testSealedClassConstructorCall() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/sealedClassConstructorCall.kt");
}
@TestMetadata("sealedSupertype.kt")
public void testSealedSupertype() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/sealedSupertype.kt");
}
@TestMetadata("superIsNotAnExpression.kt")
public void testSuperIsNotAnExpression() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/superIsNotAnExpression.kt");
@@ -1016,6 +1051,11 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/typeArgumentsNotAllowed.kt");
}
@TestMetadata("supertypeInitializedInInterface.kt")
public void testSupertypeInitializedInInterface() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/supertypeInitializedInInterface.kt");
}
@TestMetadata("typeOfAnnotationMember.kt")
public void testTypeOfAnnotationMember() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/typeOfAnnotationMember.kt");
@@ -1026,6 +1066,11 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/typeParametersInObject.kt");
}
@TestMetadata("typeParametersInEnum.kt")
public void testTypeParametersInEnum() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/typeParametersInEnum.kt");
}
@TestMetadata("upperBoundViolated.kt")
public void testUpperBoundViolated() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/upperBoundViolated.kt");
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.fir.analysis.checkers
import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.FirFakeSourceElementKind
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.symbols.CallableId
@@ -14,71 +15,86 @@ import org.jetbrains.kotlin.fir.types.FirTypeRef
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name
private open class RepresentationBuilder {
var receiver = ""
var name = ""
/**
* Provides representations for FirElement's.
*/
interface FirDeclarationPresenter {
open class RepresentationBuilder {
var receiver = ""
var name = ""
open fun build() = "[$receiver] $name"
open fun build() = "[$receiver] $name"
}
fun buildRepresentation(init: RepresentationBuilder.() -> Unit): String {
return RepresentationBuilder().apply(init).build()
}
class FunctionRepresentationBuilder : RepresentationBuilder() {
var representsOperator = false
var typeArguments = ""
var parameters = ""
override fun build() = "<$typeArguments> [$receiver] ${if (representsOperator) "operator " else ""}$name ($parameters)"
}
fun buildFunctionRepresentation(init: FunctionRepresentationBuilder.() -> Unit): String {
return FunctionRepresentationBuilder().apply(init).build()
}
fun represent(it: FirElement) = "NO_REPRESENTATION"
fun represent(it: ClassId) = it.packageFqName.asString() + '/' + it.relativeClassName.asString()
fun represent(it: CallableId) = if (it.className != null) {
it.packageName.asString() + '/' + it.className + '.' + it.callableName
} else {
it.packageName.asString() + '/' + it.callableName
}
fun represent(it: FirTypeRef) = when (it) {
is FirResolvedTypeRef -> it.type.toString()
is FirErrorTypeRef -> "ERROR"
else -> "?"
}
fun represent(it: FirTypeParameter) = it.name.asString() + " : " + it.bounds
.map { represent(it) }
.sorted()
.joinToString()
fun represent(it: FirValueParameter): String {
val prefix = if (it.isVararg) "vararg " else ""
return prefix + " " + represent(it.returnTypeRef)
}
fun represent(it: FirProperty) = buildRepresentation {
it.receiverTypeRef?.let {
receiver = represent(it)
}
name = represent(it.symbol.callableId)
}
fun represent(it: FirSimpleFunction) = buildFunctionRepresentation {
typeArguments = it.typeParameters.joinToString { represent(it) }
it.receiverTypeRef?.let {
receiver = represent(it)
}
representsOperator = it.isOperator
name = represent(it.symbol.callableId)
parameters = it.valueParameters.joinToString { represent(it) }
}
fun represent(it: FirTypeAlias) = buildRepresentation {
name = represent(it.symbol.classId)
}
fun represent(it: FirRegularClass) = buildRepresentation {
name = represent(it.symbol.classId)
}
}
private fun buildRepresentation(init: RepresentationBuilder.() -> Unit): String {
return RepresentationBuilder().apply(init).build()
}
private class FunctionRepresentationBuilder : RepresentationBuilder() {
var typeArguments = ""
var parameters = ""
override fun build() = "<$typeArguments> [$receiver] $name ($parameters)"
}
private fun buildFunctionRepresentation(init: FunctionRepresentationBuilder.() -> Unit): String {
return FunctionRepresentationBuilder().apply(init).build()
}
private fun ClassId.represent() = packageFqName.asString() + '/' + relativeClassName.asString()
private fun CallableId.represent() = if (className != null) {
packageName.asString() + '/' + className + '.' + callableName
} else {
packageName.asString() + '/' + callableName
}
private fun FirTypeRef.represent() = when (this) {
is FirResolvedTypeRef -> type.toString()
is FirErrorTypeRef -> "ERROR"
else -> "?"
}
private fun FirTypeParameter.represent() = name.asString() + " : " + bounds
.map { it.represent() }
.sorted()
.joinToString()
private fun FirValueParameter.represent(): String {
val prefix = if (this.isVararg) "vararg " else ""
return prefix + " " + this.returnTypeRef.represent()
}
private fun FirProperty.represent() = buildRepresentation {
receiver = receiverTypeRef?.represent() ?: ""
name = symbol.callableId.represent()
}
private fun FirSimpleFunction.represent() = buildFunctionRepresentation {
typeArguments = typeParameters.joinToString { it.represent() }
receiver = receiverTypeRef?.represent() ?: ""
name = symbol.callableId.represent()
parameters = valueParameters.joinToString { it.represent() }
}
private fun FirTypeAlias.represent() = buildRepresentation {
name = symbol.classId.represent()
}
private fun FirRegularClass.represent() = buildRepresentation {
name = symbol.classId.represent()
}
private class FirDefaultDeclarationPresenter : FirDeclarationPresenter
private val NO_NAME_PROVIDED = Name.special("<no name provided>")
@@ -94,7 +110,12 @@ private fun FirDeclaration.isCollectable() = when (this) {
else -> true
}
class FirDeclarationInspector {
/**
* Collects FirDeclarations for further analysis.
*/
class FirDeclarationInspector(
private val presenter: FirDeclarationPresenter = FirDefaultDeclarationPresenter()
) {
val otherDeclarations = mutableMapOf<String, MutableList<FirDeclaration>>()
val functionDeclarations = mutableMapOf<String, MutableList<FirSimpleFunction>>()
@@ -108,9 +129,9 @@ class FirDeclarationInspector {
}
val key = when (declaration) {
is FirRegularClass -> declaration.represent()
is FirTypeAlias -> declaration.represent()
is FirProperty -> declaration.represent()
is FirRegularClass -> presenter.represent(declaration)
is FirTypeAlias -> presenter.represent(declaration)
is FirProperty -> presenter.represent(declaration)
else -> return
}
@@ -125,7 +146,7 @@ class FirDeclarationInspector {
}
private fun collectFunction(declaration: FirSimpleFunction) {
val key = declaration.represent()
val key = presenter.represent(declaration)
var value = functionDeclarations[key]
if (value == null) {
@@ -136,11 +157,11 @@ class FirDeclarationInspector {
value.add(declaration)
}
private fun contains(declaration: FirDeclaration) = when (declaration) {
is FirSimpleFunction -> declaration.represent() in functionDeclarations
is FirRegularClass -> declaration.represent() in otherDeclarations
is FirTypeAlias -> declaration.represent() in otherDeclarations
is FirProperty -> declaration.represent() in otherDeclarations
fun contains(declaration: FirDeclaration) = when (declaration) {
is FirSimpleFunction -> presenter.represent(declaration) in functionDeclarations
is FirRegularClass -> presenter.represent(declaration) in otherDeclarations
is FirTypeAlias -> presenter.represent(declaration) in otherDeclarations
is FirProperty -> presenter.represent(declaration) in otherDeclarations
else -> false
}
}
@@ -13,7 +13,6 @@ import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
import org.jetbrains.kotlin.fir.expressions.impl.FirEmptyExpressionBlock
import org.jetbrains.kotlin.fir.expressions.impl.FirSingleExpressionBlock
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
import org.jetbrains.kotlin.fir.resolve.firSymbolProvider
import org.jetbrains.kotlin.fir.resolve.toSymbol
@@ -208,7 +207,7 @@ fun FirSimpleFunction.overriddenFunctions(
val firTypeScope = containingClass.unsubstitutedScope(
context.sessionHolder.session,
context.sessionHolder.scopeSession
) as FirTypeScope
)
val overriddenFunctions = mutableListOf<FirFunctionSymbol<*>>()
firTypeScope.processFunctionsByName(symbol.fir.name) { }
@@ -272,4 +271,27 @@ private fun FirDeclaration.hasBody(): Boolean = when (this) {
is FirSimpleFunction -> this.body != null && this.body !is FirEmptyExpressionBlock
is FirProperty -> this.setter?.body !is FirEmptyExpressionBlock? || this.getter?.body !is FirEmptyExpressionBlock?
else -> false
}
}
/**
* Finds any non-interface supertype and returns it
* or null if couldn't find any.
*/
fun FirClass<*>.findNonInterfaceSupertype(context: CheckerContext): FirTypeRef? {
for (it in superTypeRefs) {
val classId = it.safeAs<FirResolvedTypeRef>()
?.type.safeAs<ConeClassLikeType>()
?.lookupTag?.classId
?: continue
val fir = context.session.firSymbolProvider.getClassLikeSymbolByFqName(classId)
?.fir.safeAs<FirClass<*>>()
?: continue
if (fir.classKind != ClassKind.INTERFACE) {
return it
}
}
return null
}
@@ -22,6 +22,7 @@ object CommonDeclarationCheckers : DeclarationCheckers() {
FirLocalEntityNotAllowedChecker,
FirTypeParametersInObjectChecker,
FirConflictsChecker,
FirConstructorInInterfaceChecker,
)
override val memberDeclarationCheckers: List<FirMemberDeclarationChecker> = listOf(
@@ -31,6 +32,12 @@ object CommonDeclarationCheckers : DeclarationCheckers() {
FirSupertypeInitializedWithoutPrimaryConstructor,
FirDelegationSuperCallInEnumConstructorChecker,
FirPrimaryConstructorRequiredForDataClassChecker,
FirMethodOfAnyImplementedInInterfaceChecker,
FirSupertypeInitializedInInterfaceChecker,
FirDelegationInInterfaceChecker,
FirInterfaceWithSuperclassChecker,
FirEnumClassSimpleChecker,
FirSealedSupertypeChecker,
)
override val regularClassCheckers: List<FirRegularClassChecker> = listOf(
@@ -0,0 +1,68 @@
/*
* 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 com.intellij.lang.LighterASTNode
import com.intellij.openapi.util.Ref
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiErrorElement
import com.intellij.util.diff.FlyweightCapableTreeStructure
import org.jetbrains.kotlin.KtNodeTypes.PRIMARY_CONSTRUCTOR
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.fir.FirLightSourceElement
import org.jetbrains.kotlin.fir.FirSourceElement
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.declarations.FirClass
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.fir.lightNode
import org.jetbrains.kotlin.fir.psi
import org.jetbrains.kotlin.psi.KtPrimaryConstructor
object FirConstructorInInterfaceChecker : FirBasicDeclarationChecker() {
override fun check(declaration: FirDeclaration, context: CheckerContext, reporter: DiagnosticReporter) {
if (declaration !is FirClass<*> || declaration.classKind != ClassKind.INTERFACE) {
return
}
if (declaration.source?.hasPrimaryConstructor() == true) {
reporter.report(declaration.source)
}
}
private fun FirSourceElement.hasPrimaryConstructor(): Boolean {
val localPsi = psi
val localLightNode = lightNode
if (localPsi != null && localPsi !is PsiErrorElement) {
return localPsi.hasPrimaryConstructor()
} else if (localLightNode != null && this is FirLightSourceElement) {
return localLightNode.hasPrimaryConstructor(tree)
}
return false
}
private fun PsiElement.hasPrimaryConstructor(): Boolean {
return lastChild !is PsiErrorElement && lastChild is KtPrimaryConstructor
}
private fun LighterASTNode.hasPrimaryConstructor(tree: FlyweightCapableTreeStructure<LighterASTNode>): Boolean {
val children = getChildren(tree)
return children.lastOrNull()?.tokenType == PRIMARY_CONSTRUCTOR
}
private fun LighterASTNode.getChildren(tree: FlyweightCapableTreeStructure<LighterASTNode>): List<LighterASTNode> {
val children = Ref<Array<LighterASTNode?>>()
val count = tree.getChildren(this, children)
return if (count > 0) children.get().filterNotNull() else emptyList()
}
private fun DiagnosticReporter.report(source: FirSourceElement?) {
source?.let { report(FirErrors.CONSTRUCTOR_IN_INTERFACE.on(it)) }
}
}
@@ -0,0 +1,77 @@
/*
* 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 com.intellij.lang.LighterASTNode
import com.intellij.openapi.util.Ref
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiErrorElement
import com.intellij.util.diff.FlyweightCapableTreeStructure
import org.jetbrains.kotlin.KtNodeTypes
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.fir.FirLightSourceElement
import org.jetbrains.kotlin.fir.FirSourceElement
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.declarations.FirClass
import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration
import org.jetbrains.kotlin.fir.lightNode
import org.jetbrains.kotlin.fir.psi
import org.jetbrains.kotlin.psi.KtDelegatedSuperTypeEntry
object FirDelegationInInterfaceChecker : FirMemberDeclarationChecker() {
override fun check(declaration: FirMemberDeclaration, context: CheckerContext, reporter: DiagnosticReporter) {
if (declaration !is FirClass<*> || declaration.classKind != ClassKind.INTERFACE) {
return
}
declaration.source?.findSuperTypeDelegation()?.let {
reporter.report(declaration.superTypeRefs.getOrNull(it)?.source)
}
}
private fun FirSourceElement.findSuperTypeDelegation(): Int {
val localPsi = psi
val localLightNode = lightNode
if (localPsi != null && localPsi !is PsiErrorElement) {
return localPsi.findSuperTypeDelegation()
} else if (localLightNode != null && this is FirLightSourceElement) {
return localLightNode.findSuperTypeDelegation(tree)
}
return -1
}
private fun PsiElement.findSuperTypeDelegation() = if (children.isNotEmpty() && children[0] !is PsiErrorElement) {
children[0].children.indexOfFirst { it is KtDelegatedSuperTypeEntry }
} else {
-1
}
private fun LighterASTNode.findSuperTypeDelegation(tree: FlyweightCapableTreeStructure<LighterASTNode>): Int {
val children = getChildren(tree)
return if (children.isNotEmpty()) {
children.find { it.tokenType == KtNodeTypes.SUPER_TYPE_LIST }
?.getChildren(tree)
?.indexOfFirst { it.tokenType == KtNodeTypes.DELEGATED_SUPER_TYPE_ENTRY }
?: -1
} else {
-1
}
}
private fun LighterASTNode.getChildren(tree: FlyweightCapableTreeStructure<LighterASTNode>): List<LighterASTNode> {
val children = Ref<Array<LighterASTNode?>>()
val count = tree.getChildren(this, children)
return if (count > 0) children.get().filterNotNull() else emptyList()
}
private fun DiagnosticReporter.report(source: FirSourceElement?) {
source?.let { report(FirErrors.DELEGATION_IN_INTERFACE.on(it)) }
}
}
@@ -0,0 +1,39 @@
/*
* 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.descriptors.ClassKind
import org.jetbrains.kotlin.fir.FirSourceElement
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.findNonInterfaceSupertype
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.declarations.FirClass
import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration
object FirEnumClassSimpleChecker : FirMemberDeclarationChecker() {
override fun check(declaration: FirMemberDeclaration, context: CheckerContext, reporter: DiagnosticReporter) {
if (declaration !is FirClass<*> || declaration.classKind != ClassKind.ENUM_CLASS) {
return
}
declaration.findNonInterfaceSupertype(context)?.let {
reporter.reportClassInSupertypeForEnum(it.source)
}
if (declaration.typeParameters.isNotEmpty()) {
reporter.reportTypeParametersInEnum(declaration.typeParameters.firstOrNull()?.source)
}
}
private fun DiagnosticReporter.reportClassInSupertypeForEnum(source: FirSourceElement?) {
source?.let { report(FirErrors.CLASS_IN_SUPERTYPE_FOR_ENUM.on(it)) }
}
private fun DiagnosticReporter.reportTypeParametersInEnum(source: FirSourceElement?) {
source?.let { report(FirErrors.TYPE_PARAMETERS_IN_ENUM.on(it)) }
}
}
@@ -0,0 +1,31 @@
/*
* 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.descriptors.ClassKind
import org.jetbrains.kotlin.fir.FirSourceElement
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.findNonInterfaceSupertype
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.declarations.FirClass
import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration
object FirInterfaceWithSuperclassChecker : FirMemberDeclarationChecker() {
override fun check(declaration: FirMemberDeclaration, context: CheckerContext, reporter: DiagnosticReporter) {
if (declaration !is FirClass<*> || declaration.classKind != ClassKind.INTERFACE) {
return
}
declaration.findNonInterfaceSupertype(context)?.let {
reporter.report(it.source)
}
}
private fun DiagnosticReporter.report(source: FirSourceElement?) {
source?.let { report(FirErrors.INTERFACE_WITH_SUPERCLASS.on(it)) }
}
}
@@ -0,0 +1,63 @@
/*
* 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.descriptors.ClassKind
import org.jetbrains.kotlin.fir.FirSourceElement
import org.jetbrains.kotlin.fir.analysis.checkers.FirDeclarationInspector
import org.jetbrains.kotlin.fir.analysis.checkers.FirDeclarationPresenter
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.resolve.firSymbolProvider
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
object FirMethodOfAnyImplementedInInterfaceChecker : FirMemberDeclarationChecker(), FirDeclarationPresenter {
private var inspector: FirDeclarationInspector? = null
private fun getInspector(context: CheckerContext) = inspector ?: FirDeclarationInspector(this).apply {
val anyClassId = context.session.builtinTypes.anyType.id
context.session.firSymbolProvider.getClassLikeSymbolByFqName(anyClassId)
?.fir.safeAs<FirRegularClass>()
?.declarations
?.filterIsInstance<FirSimpleFunction>()
?.filter { it !is FirConstructor }
?.forEach {
collect(it)
}
inspector = this
}
override fun represent(it: FirSimpleFunction) = buildFunctionRepresentation {
typeArguments = it.typeParameters.joinToString { represent(it) }
it.receiverTypeRef?.let {
receiver = represent(it)
}
name = it.name.asString()
parameters = it.valueParameters.joinToString { represent(it) }
}
override fun check(declaration: FirMemberDeclaration, context: CheckerContext, reporter: DiagnosticReporter) {
if (declaration !is FirClass<*> || declaration.classKind != ClassKind.INTERFACE) {
return
}
for (it in declaration.declarations) {
val inspector = getInspector(context)
if (it is FirSimpleFunction && inspector.contains(it) && it.body != null && it.isOverride) {
reporter.report(it.source)
}
}
}
private fun DiagnosticReporter.report(source: FirSourceElement?) {
source?.let { report(FirErrors.ANY_METHOD_IMPLEMENTED_IN_INTERFACE.on(it)) }
}
}
@@ -0,0 +1,58 @@
/*
* 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.descriptors.Modality
import org.jetbrains.kotlin.fir.FirSourceElement
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirQualifiedAccessChecker
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.declarations.FirConstructor
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.declarations.classId
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
import org.jetbrains.kotlin.fir.resolve.firSymbolProvider
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
object FirSealedClassConstructorCallChecker : FirQualifiedAccessChecker() {
override fun check(functionCall: FirQualifiedAccessExpression, context: CheckerContext, reporter: DiagnosticReporter) {
val constructorFir = functionCall.calleeReference.safeAs<FirResolvedNamedReference>()
?.resolvedSymbol
?.fir.safeAs<FirConstructor>()
?: return
val typeClassId = constructorFir.returnTypeRef.safeAs<FirResolvedTypeRef>()
?.type.safeAs<ConeClassLikeType>()
?.lookupTag
?.classId
?: return
val typeFir = typeClassId.toRegularClass(context)
?: return
if (typeFir.status.modality == Modality.SEALED) {
reporter.report(functionCall.calleeReference.source)
}
}
private fun ClassId.toRegularClass(context: CheckerContext): FirRegularClass? = if (!isLocal) {
context.session.firSymbolProvider.getClassLikeSymbolByFqName(this)
?.fir.safeAs()
} else {
context.containingDeclarations
.lastOrNull { it.safeAs<FirRegularClass>()?.classId == this }
.safeAs()
}
private fun DiagnosticReporter.report(source: FirSourceElement?) {
source?.let { report(FirErrors.SEALED_CLASS_CONSTRUCTOR_CALL.on(it)) }
}
}
@@ -0,0 +1,115 @@
/*
* 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.descriptors.Modality
import org.jetbrains.kotlin.fir.FirSourceElement
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.resolve.firSymbolProvider
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
object FirSealedSupertypeChecker : FirMemberDeclarationChecker() {
override fun check(declaration: FirMemberDeclaration, context: CheckerContext, reporter: DiagnosticReporter) {
if (declaration is FirClass<*>) {
// only the file declaration is present
when {
context.containingDeclarations.size == 1 -> {
checkTopLevelDeclaration(declaration, context, reporter)
}
declaration.classId.isLocal -> {
checkLocalDeclaration(declaration, context, reporter)
}
else -> {
checkInnerDeclaration(declaration, context, reporter)
}
}
} else if (declaration is FirProperty) {
val initializer = declaration.initializer.safeAs<FirClass<*>>()
?: return
checkLocalDeclaration(initializer, context, reporter)
}
}
private fun checkTopLevelDeclaration(declaration: FirClass<*>, context: CheckerContext, reporter: DiagnosticReporter) {
for (it in declaration.superTypeRefs) {
val classId = it.safeAs<FirResolvedTypeRef>()
?.type.safeAs<ConeClassLikeType>()
?.lookupTag?.classId
?: continue
if (classId.isLocal) {
continue
}
val fir = context.session.firSymbolProvider.getClassLikeSymbolByFqName(classId)
?.fir.safeAs<FirRegularClass>()
?: continue
if (fir.status.modality == Modality.SEALED && classId.outerClassId != null) {
reporter.report(it.source)
return
}
}
}
private fun checkLocalDeclaration(declaration: FirClass<*>, context: CheckerContext, reporter: DiagnosticReporter) {
for (it in declaration.superTypeRefs) {
val classId = it.safeAs<FirResolvedTypeRef>()
?.type.safeAs<ConeClassLikeType>()
?.lookupTag?.classId
?: continue
if (classId.isLocal) {
continue
}
val fir = context.session.firSymbolProvider.getClassLikeSymbolByFqName(classId)
?.fir.safeAs<FirRegularClass>()
?: continue
if (fir.status.modality == Modality.SEALED) {
reporter.reportInLocal(it.source)
return
}
}
}
private fun checkInnerDeclaration(declaration: FirClass<*>, context: CheckerContext, reporter: DiagnosticReporter) {
for (it in declaration.superTypeRefs) {
val classId = it.safeAs<FirResolvedTypeRef>()
?.type.safeAs<ConeClassLikeType>()
?.lookupTag?.classId
?: continue
if (classId.isLocal) {
continue
}
val fir = context.session.firSymbolProvider.getClassLikeSymbolByFqName(classId)
?.fir.safeAs<FirRegularClass>()
?: continue
if (fir.status.modality == Modality.SEALED && !context.containingDeclarations.contains(fir)) {
reporter.report(it.source)
return
}
}
}
private fun DiagnosticReporter.report(source: FirSourceElement?) {
source?.let { report(FirErrors.SEALED_SUPERTYPE.on(it)) }
}
private fun DiagnosticReporter.reportInLocal(source: FirSourceElement?) {
source?.let { report(FirErrors.SEALED_SUPERTYPE_IN_LOCAL_CLASS.on(it)) }
}
}
@@ -0,0 +1,77 @@
/*
* 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 com.intellij.lang.LighterASTNode
import com.intellij.openapi.util.Ref
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiErrorElement
import com.intellij.util.diff.FlyweightCapableTreeStructure
import org.jetbrains.kotlin.KtNodeTypes
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.fir.FirLightSourceElement
import org.jetbrains.kotlin.fir.FirSourceElement
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.declarations.FirClass
import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration
import org.jetbrains.kotlin.fir.lightNode
import org.jetbrains.kotlin.fir.psi
import org.jetbrains.kotlin.psi.KtSuperTypeCallEntry
object FirSupertypeInitializedInInterfaceChecker : FirMemberDeclarationChecker() {
override fun check(declaration: FirMemberDeclaration, context: CheckerContext, reporter: DiagnosticReporter) {
if (declaration !is FirClass<*> || declaration.classKind != ClassKind.INTERFACE) {
return
}
declaration.source?.findSuperTypeCall()?.let {
reporter.report(declaration.superTypeRefs.getOrNull(it)?.source)
}
}
private fun FirSourceElement.findSuperTypeCall(): Int {
val localPsi = psi
val localLightNode = lightNode
if (localPsi != null && localPsi !is PsiErrorElement) {
return localPsi.findSuperTypeCall()
} else if (localLightNode != null && this is FirLightSourceElement) {
return localLightNode.findSuperTypeCall(tree)
}
return -1
}
private fun PsiElement.findSuperTypeCall() = if (children.isNotEmpty() && children[0] !is PsiErrorElement) {
children[0].children.indexOfFirst { it is KtSuperTypeCallEntry }
} else {
-1
}
private fun LighterASTNode.findSuperTypeCall(tree: FlyweightCapableTreeStructure<LighterASTNode>): Int {
val children = getChildren(tree)
return if (children.isNotEmpty()) {
children.find { it.tokenType == KtNodeTypes.SUPER_TYPE_LIST }
?.getChildren(tree)
?.indexOfFirst { it.tokenType == KtNodeTypes.SUPER_TYPE_CALL_ENTRY }
?: -1
} else {
-1
}
}
private fun LighterASTNode.getChildren(tree: FlyweightCapableTreeStructure<LighterASTNode>): List<LighterASTNode> {
val children = Ref<Array<LighterASTNode?>>()
val count = tree.getChildren(this, children)
return if (count > 0) children.get().filterNotNull() else emptyList()
}
private fun DiagnosticReporter.report(source: FirSourceElement?) {
source?.let { report(FirErrors.SUPERTYPE_INITIALIZED_IN_INTERFACE.on(it)) }
}
}
@@ -5,6 +5,8 @@
package org.jetbrains.kotlin.fir.analysis.checkers.expression
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirSealedClassConstructorCallChecker
object CommonExpressionCheckers : ExpressionCheckers() {
override val expressionCheckers: List<FirBasicExpresionChecker> = listOf()
override val qualifiedAccessCheckers: List<FirQualifiedAccessChecker> = listOf(
@@ -16,6 +18,7 @@ object CommonExpressionCheckers : ExpressionCheckers() {
FirProjectionsOnNonClassTypeArgumentChecker,
FirUpperBoundViolatedChecker,
FirTypeArgumentsNotAllowedExpressionChecker,
FirSealedClassConstructorCallChecker,
)
override val functionCallCheckers: List<FirFunctionCallChecker> = listOf()
}
@@ -17,12 +17,15 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ABSTRACT_SUPER_CA
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.AMBIGUITY
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ANNOTATION_CLASS_MEMBER
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ANNOTATION_PARAMETER_DEFAULT_VALUE_MUST_BE_CONSTANT
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ANY_METHOD_IMPLEMENTED_IN_INTERFACE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ASSIGN_OPERATOR_AMBIGUITY
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.BREAK_OR_CONTINUE_OUTSIDE_A_LOOP
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CLASS_IN_SUPERTYPE_FOR_ENUM
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CONFLICTING_OVERLOADS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CONSTRUCTOR_IN_INTERFACE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CONSTRUCTOR_IN_OBJECT
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CYCLIC_CONSTRUCTOR_DELEGATION_CALL
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DELEGATION_IN_INTERFACE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DELEGATION_SUPER_CALL_IN_ENUM_CONSTRUCTOR
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DEPRECATED_MODIFIER_PAIR
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DESERIALIZATION_ERROR
@@ -44,6 +47,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INAPPLICABLE_CAND
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INAPPLICABLE_INFIX_MODIFIER
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INCOMPATIBLE_MODIFIERS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INFERENCE_ERROR
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INTERFACE_WITH_SUPERCLASS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INVALID_TYPE_OF_ANNOTATION_MEMBER
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.LEAKED_IN_PLACE_LAMBDA
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.LOCAL_ANNOTATION_CLASS_ERROR
@@ -70,13 +74,18 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REDECLARATION
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REDUNDANT_MODIFIER
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REPEATED_MODIFIER
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.RETURN_NOT_ALLOWED
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.SEALED_CLASS_CONSTRUCTOR_CALL
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.SEALED_SUPERTYPE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.SEALED_SUPERTYPE_IN_LOCAL_CLASS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.SUPERCLASS_NOT_ACCESSIBLE_FROM_INTERFACE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.SUPERTYPE_INITIALIZED_IN_INTERFACE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.SUPERTYPE_INITIALIZED_WITHOUT_PRIMARY_CONSTRUCTOR
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.SUPER_IS_NOT_AN_EXPRESSION
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.SUPER_NOT_AVAILABLE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.SYNTAX_ERROR
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TYPE_ARGUMENTS_NOT_ALLOWED
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TYPE_MISMATCH
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TYPE_PARAMETERS_IN_ENUM
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TYPE_PARAMETERS_IN_OBJECT
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TYPE_PARAMETER_AS_SUPERTYPE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.UNINITIALIZED_VARIABLE
@@ -112,6 +121,7 @@ class FirDefaultErrorMessages : DefaultErrorMessages.Extension {
map.put(NOT_A_LOOP_LABEL, "The label does not denote a loop") // *
map.put(VARIABLE_EXPECTED, "Variable expected")
map.put(RETURN_NOT_ALLOWED, "'return' is not allowed here")
map.put(DELEGATION_IN_INTERFACE, "Interfaces cannot use delegation")
// Unresolved
map.put(HIDDEN, "Symbol {0} is invisible", SYMBOL)
@@ -138,6 +148,11 @@ class FirDefaultErrorMessages : DefaultErrorMessages.Extension {
"Explicitly qualified supertype is extended by another supertype ''{0}''",
TO_STRING
)
map.put(SUPERTYPE_INITIALIZED_IN_INTERFACE, "Interfaces cannot initialize supertypes")
map.put(INTERFACE_WITH_SUPERCLASS, "An interface cannot inherit from a class")
map.put(CLASS_IN_SUPERTYPE_FOR_ENUM, "Enum class cannot inherit from classes")
map.put(SEALED_SUPERTYPE, "This type is sealed, so it can be inherited by only its own nested classes or objects")
map.put(SEALED_SUPERTYPE_IN_LOCAL_CLASS, "Local class cannot extend a sealed class")
// Constructor problems
map.put(CONSTRUCTOR_IN_OBJECT, "Constructors are not allowed for objects")
@@ -153,6 +168,7 @@ class FirDefaultErrorMessages : DefaultErrorMessages.Extension {
EXPLICIT_DELEGATION_CALL_REQUIRED,
"Explicit 'this' or 'super' call is required. There is no constructor in superclass that can be called without arguments"
)
map.put(SEALED_CLASS_CONSTRUCTOR_CALL, "Sealed types cannot be instantiated")
// Annotations
map.put(ANNOTATION_CLASS_MEMBER, "Members are not allowed in annotation class")
@@ -226,11 +242,13 @@ class FirDefaultErrorMessages : DefaultErrorMessages.Extension {
map.put(NO_TYPE_FOR_TYPE_PARAMETER, "There're no types suitable for this type parameter") // &
map.put(TYPE_PARAMETERS_IN_OBJECT, "Type parameters are not allowed for objects")
// map.put(ILLEGAL_PROJECTION_USAGE, ...) // &
map.put(TYPE_PARAMETERS_IN_ENUM, "Enum class cannot have type parameters")
// Redeclarations
map.put(MANY_COMPANION_OBJECTS, "Only one companion object is allowed per class")
map.put(CONFLICTING_OVERLOADS, "Conflicting overloads: {0}", TO_STRING) // *
map.put(REDECLARATION, "Conflicting declarations: {0}", TO_STRING) // *
map.put(ANY_METHOD_IMPLEMENTED_IN_INTERFACE, "An interface may not implement a method of 'Any'") // &
// Invalid local declarations
map.put(
@@ -36,6 +36,7 @@ object FirErrors {
val NOT_A_LOOP_LABEL by error0<FirSourceElement, PsiElement>()
val VARIABLE_EXPECTED by error0<FirSourceElement, PsiElement>()
val RETURN_NOT_ALLOWED by error0<FirSourceElement, PsiElement>()
val DELEGATION_IN_INTERFACE by error0<FirSourceElement, PsiElement>()
// Unresolved
val HIDDEN by error1<FirSourceElement, PsiElement, AbstractFirBasedSymbol<*>>()
@@ -58,6 +59,11 @@ object FirErrors {
val NOT_A_SUPERTYPE by error0<FirSourceElement, PsiElement>()
val SUPERCLASS_NOT_ACCESSIBLE_FROM_INTERFACE by error0<FirSourceElement, PsiElement>()
val QUALIFIED_SUPERTYPE_EXTENDED_BY_OTHER_SUPERTYPE by error1<FirSourceElement, PsiElement, FirClass<*>>()
val SUPERTYPE_INITIALIZED_IN_INTERFACE by error0<FirSourceElement, PsiElement>()
val INTERFACE_WITH_SUPERCLASS by error0<FirSourceElement, PsiElement>()
val CLASS_IN_SUPERTYPE_FOR_ENUM by error0<FirSourceElement, PsiElement>()
val SEALED_SUPERTYPE by error0<FirSourceElement, PsiElement>()
val SEALED_SUPERTYPE_IN_LOCAL_CLASS by error0<FirSourceElement, PsiElement>()
// Constructor problems
val CONSTRUCTOR_IN_OBJECT by existing<FirSourceElement, KtDeclaration>(Errors.CONSTRUCTOR_IN_OBJECT)
@@ -70,6 +76,7 @@ object FirErrors {
val DELEGATION_SUPER_CALL_IN_ENUM_CONSTRUCTOR by warning0<FirSourceElement, PsiElement>()
val PRIMARY_CONSTRUCTOR_REQUIRED_FOR_DATA_CLASS by warning0<FirSourceElement, PsiElement>()
val EXPLICIT_DELEGATION_CALL_REQUIRED by warning0<FirSourceElement, PsiElement>()
val SEALED_CLASS_CONSTRUCTOR_CALL by error0<FirSourceElement, PsiElement>()
// Annotations
val ANNOTATION_CLASS_MEMBER by existing<FirSourceElement, PsiElement>(Errors.ANNOTATION_CLASS_MEMBER)
@@ -117,11 +124,13 @@ object FirErrors {
val NO_TYPE_FOR_TYPE_PARAMETER by error0<FirSourceElement, PsiElement>()
val TYPE_PARAMETERS_IN_OBJECT by error0<FirSourceElement, PsiElement>()
val ILLEGAL_PROJECTION_USAGE by error0<FirSourceElement, PsiElement>()
val TYPE_PARAMETERS_IN_ENUM by error0<FirSourceElement, PsiElement>()
// Redeclarations
val MANY_COMPANION_OBJECTS by error0<FirSourceElement, PsiElement>()
val CONFLICTING_OVERLOADS by error1<FirSourceElement, PsiElement, String>()
val REDECLARATION by error1<FirSourceElement, PsiElement, String>()
val ANY_METHOD_IMPLEMENTED_IN_INTERFACE by error0<FirSourceElement, PsiElement>()
// Invalid local declarations
val LOCAL_OBJECT_NOT_ALLOWED by error1<FirSourceElement, PsiElement, Name>()
@@ -24,17 +24,17 @@ interface T2<T> {}
interface Test() {
}
interface Test1 : C2() {}
interface Test1 : <!INTERFACE_WITH_SUPERCLASS, SUPERTYPE_INITIALIZED_IN_INTERFACE!>C2<!>() {}
interface Test2 : C2 {}
interface Test2 : <!INTERFACE_WITH_SUPERCLASS!>C2<!> {}
interface Test3 : C2, C3 {}
interface Test3 : <!INTERFACE_WITH_SUPERCLASS!>C2<!>, C3 {}
interface Test4 : T1 {}
interface Test5 : T1, T1 {}
interface Test6 : C1 {}
interface Test6 : <!INTERFACE_WITH_SUPERCLASS!>C1<!> {}
class CTest1() : OC1() {}
@@ -1,5 +1,5 @@
// JAVAC_EXPECTED_FILE
interface MyTrait: Object {
interface MyTrait: <!INTERFACE_WITH_SUPERCLASS!>Object<!> {
override fun toString(): String
public override fun finalize()
public override fun wait()
@@ -1,46 +0,0 @@
// !DIAGNOSTICS: -WARNING +CAST_NEVER_SUCCEEDS
interface T1
interface T2
interface T3
open class OC1: T1
open class OC2: OC1(), T2
class FC1: OC2(), T3
interface T4: OC1
interface T5: T2
fun <TP1: OC1, TP2: T2, TP3: OC2> test(
t2: T2,
t4: T4,
fc1: FC1,
oc1: OC1,
oc2: OC2,
tp1: TP1,
tp2: TP2
) {
fc1 as FC1
fc1 as OC1
fc1 as T1
fc1 as TP1
oc1 as FC1
oc1 as OC2
oc2 as OC1
oc1 as T2
oc1 as T1
oc1 as TP1
oc1 as TP2
t2 as FC1
t2 as OC2
t4 as OC1
t2 as T2
t2 as T5
t2 as TP2
tp1 as FC1
tp1 as OC1
tp1 as OC2
tp2 as T2
tp2 as T5
tp1 as TP3
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// !DIAGNOSTICS: -WARNING +CAST_NEVER_SUCCEEDS
interface T1
interface T2
@@ -2,6 +2,6 @@ open class C {
val x = 1
}
interface Tr : C {
interface Tr : <!INTERFACE_WITH_SUPERCLASS!>C<!> {
fun getX() = 1
}
@@ -1,7 +1,7 @@
// FILE: test.kt
enum class MyEnum(): MyClass() {}
enum class MyEnum(): <!CLASS_IN_SUPERTYPE_FOR_ENUM!>MyClass<!>() {}
enum class MyEnum2(): MyTrait {}
enum class MyEnum3(): MyEnumBase() {}
enum class MyEnum3(): <!CLASS_IN_SUPERTYPE_FOR_ENUM!>MyEnumBase<!>() {}
open class MyClass() {}
@@ -2,6 +2,6 @@
package bug
public enum class Foo<T> {
public enum class Foo<<!TYPE_PARAMETERS_IN_ENUM!>T<!>> {
A()
}
@@ -1,9 +1,9 @@
interface IA {
override fun toString(): String = "IA"
<!ANY_METHOD_IMPLEMENTED_IN_INTERFACE!>override fun toString(): String = "IA"<!>
override fun equals(other: Any?): Boolean = super.equals(other)
<!ANY_METHOD_IMPLEMENTED_IN_INTERFACE!>override fun equals(other: Any?): Boolean = super.equals(other)<!>
override fun hashCode(): Int {
<!ANY_METHOD_IMPLEMENTED_IN_INTERFACE!>override fun hashCode(): Int {
return 42;
}
}<!>
}
@@ -1,13 +1,13 @@
interface IA
interface IB : IA {
override fun toString(): String = "IB"
<!ANY_METHOD_IMPLEMENTED_IN_INTERFACE!>override fun toString(): String = "IB"<!>
}
interface IC : IB {
override fun toString(): String = "IC"
<!ANY_METHOD_IMPLEMENTED_IN_INTERFACE!>override fun toString(): String = "IC"<!>
}
interface ID : IC {
override fun toString(): String = "ID"
<!ANY_METHOD_IMPLEMENTED_IN_INTERFACE!>override fun toString(): String = "ID"<!>
}
@@ -7,5 +7,5 @@ interface IRight {
}
interface IDiamond : ILeft, IRight {
override fun toString(): String = "IDiamond"
<!ANY_METHOD_IMPLEMENTED_IN_INTERFACE!>override fun toString(): String = "IDiamond"<!>
}
@@ -1,11 +0,0 @@
open class Aaa() {
open fun foo() = 1
}
open class Bbb() : Aaa() {
override fun foo() = 2
}
interface Ccc : Aaa
class Ddd() : Bbb(), Ccc
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
open class Aaa() {
open fun foo() = 1
}
@@ -4,7 +4,7 @@ open class AL {
fun get(i : Int) : Any? = i
}
interface ALE<T> : AL {
interface ALE<T> : <!INTERFACE_WITH_SUPERCLASS!>AL<!> {
fun getOrNull(index: Int, value: T) : T {
return get(index) as? T ?: value
}
@@ -1,10 +1,10 @@
sealed class Base
class Derived: Base() {
class Derived2: Base()
class Derived2: <!SEALED_SUPERTYPE!>Base<!>()
}
fun test() {
class Local: Base()
class Local: <!SEALED_SUPERTYPE_IN_LOCAL_CLASS!>Base<!>()
}
-13
View File
@@ -1,13 +0,0 @@
sealed class Sealed {
object First: Sealed()
open class NonFirst: Sealed() {
object Second: NonFirst()
object Third: NonFirst()
fun foo(): Int {
val s = object: Sealed() {}
class Local: Sealed() {}
return s.hashCode()
}
}
val p: Sealed = object: Sealed() {}
}
+1
View File
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
sealed class Sealed {
object First: Sealed()
open class NonFirst: Sealed() {
@@ -1,3 +1,3 @@
sealed class Base {
fun foo() = Base()
fun foo() = <!SEALED_CLASS_CONSTRUCTOR_CALL!>Base<!>()
}
@@ -2,8 +2,8 @@ class A {
sealed class Base
}
class Derived : A.Base()
class Derived : <!SEALED_SUPERTYPE!>A.Base<!>()
fun test() {
class DerivedLocal : A.Base()
class DerivedLocal : <!SEALED_SUPERTYPE_IN_LOCAL_CLASS!>A.Base<!>()
}
@@ -1,6 +1,6 @@
interface A1 : <!UNRESOLVED_REFERENCE!>B<!>
interface A2 : <!UNRESOLVED_REFERENCE!>B<!>()
interface A2 : <!SUPERTYPE_INITIALIZED_IN_INTERFACE, UNRESOLVED_REFERENCE!>B<!>()
class A3 : <!UNRESOLVED_REFERENCE!>B<!>, <!UNRESOLVED_REFERENCE!>B<!>
@@ -1,10 +0,0 @@
open class A {
open fun foo() {}
}
interface ATrait : A {
override fun foo() {
<!SUPERCLASS_NOT_ACCESSIBLE_FROM_INTERFACE!>super<A><!>.foo()
}
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
open class A {
open fun foo() {}
}
@@ -1,5 +0,0 @@
interface AnyTrait : Any
class Foo : AnyTrait
class Bar : AnyTrait, Any()
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
interface AnyTrait : <!INTERFACE_WITH_SUPERCLASS!>Any<!>
class Foo : AnyTrait
@@ -1,9 +1,9 @@
open class bar()
interface Foo() : bar(), bar, bar {
interface Foo() : <!INTERFACE_WITH_SUPERCLASS!>bar<!>(), bar, bar {
}
interface Foo2 : bar, Foo {
interface Foo2 : <!INTERFACE_WITH_SUPERCLASS!>bar<!>, Foo {
}
open class Foo1() : bar(), bar, Foo, <!UNRESOLVED_REFERENCE!>Foo<!>() {}
@@ -17,8 +17,8 @@ val test3a = <!HIDDEN!>EnumClass<!>()
sealed class SealedClass
typealias Test4 = SealedClass
val test4 = Test4()
val test4a = SealedClass()
val test4 = <!SEALED_CLASS_CONSTRUCTOR_CALL!>Test4<!>()
val test4a = <!SEALED_CLASS_CONSTRUCTOR_CALL!>SealedClass<!>()
class Outer {
inner class Inner