[FIR] Forbid creating abstract class instances via any qualified access
^KT-58938 Fixed
This commit is contained in:
committed by
Space Team
parent
fccb391f31
commit
5daec16ce0
+6
@@ -34,6 +34,12 @@ public class DiagnosticCompilerTestFE10TestdataTestGenerated extends AbstractDia
|
||||
runTest("compiler/testData/diagnostics/tests/AbstractAccessor.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("abstractClassReference.kt")
|
||||
public void testAbstractClassReference() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/abstractClassReference.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("AbstractInAbstractClass.kt")
|
||||
public void testAbstractInAbstractClass() throws Exception {
|
||||
|
||||
+6
@@ -34,6 +34,12 @@ public class LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated
|
||||
runTest("compiler/testData/diagnostics/tests/AbstractAccessor.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("abstractClassReference.kt")
|
||||
public void testAbstractClassReference() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/abstractClassReference.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("AbstractInAbstractClass.kt")
|
||||
public void testAbstractInAbstractClass() throws Exception {
|
||||
|
||||
+6
@@ -34,6 +34,12 @@ public class FirLightTreeOldFrontendDiagnosticsTestGenerated extends AbstractFir
|
||||
runTest("compiler/testData/diagnostics/tests/AbstractAccessor.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("abstractClassReference.kt")
|
||||
public void testAbstractClassReference() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/abstractClassReference.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("AbstractInAbstractClass.kt")
|
||||
public void testAbstractInAbstractClass() throws Exception {
|
||||
|
||||
+6
@@ -34,6 +34,12 @@ public class FirPsiOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiDia
|
||||
runTest("compiler/testData/diagnostics/tests/AbstractAccessor.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("abstractClassReference.kt")
|
||||
public void testAbstractClassReference() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/abstractClassReference.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("AbstractInAbstractClass.kt")
|
||||
public void testAbstractInAbstractClass() throws Exception {
|
||||
|
||||
+1
@@ -48,6 +48,7 @@ object CommonExpressionCheckers : ExpressionCheckers() {
|
||||
FirReifiedChecker,
|
||||
FirSuspendCallChecker,
|
||||
FirLateinitIntrinsicApplicabilityChecker,
|
||||
FirAbstractClassInstantiationChecker,
|
||||
)
|
||||
|
||||
override val callCheckers: Set<FirCallChecker>
|
||||
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2010-2021 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.expression
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
||||
import org.jetbrains.kotlin.diagnostics.reportOn
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.isAbstract
|
||||
import org.jetbrains.kotlin.fir.expressions.FirCallableReferenceAccess
|
||||
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
|
||||
import org.jetbrains.kotlin.fir.references.toResolvedConstructorSymbol
|
||||
import org.jetbrains.kotlin.fir.types.coneType
|
||||
import org.jetbrains.kotlin.fir.types.toRegularClassSymbol
|
||||
|
||||
object FirAbstractClassInstantiationChecker : FirQualifiedAccessExpressionChecker() {
|
||||
override fun check(expression: FirQualifiedAccessExpression, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
val constructorSymbol = expression.calleeReference.toResolvedConstructorSymbol() ?: return
|
||||
val declarationClass = constructorSymbol.resolvedReturnTypeRef.coneType.toRegularClassSymbol(context.session) ?: return
|
||||
|
||||
if (declarationClass.isAbstract && declarationClass.classKind == ClassKind.CLASS) {
|
||||
val source = when (expression) {
|
||||
is FirCallableReferenceAccess -> expression.calleeReference.source
|
||||
else -> expression.source
|
||||
}
|
||||
|
||||
reporter.reportOn(source, FirErrors.CREATING_AN_INSTANCE_OF_ABSTRACT_CLASS, context)
|
||||
}
|
||||
}
|
||||
}
|
||||
-3
@@ -25,9 +25,6 @@ object FirConstructorCallChecker : FirFunctionCallChecker() {
|
||||
val declarationClass = constructorSymbol.resolvedReturnTypeRef.coneType.toRegularClassSymbol(context.session)
|
||||
|
||||
if (declarationClass != null) {
|
||||
if (declarationClass.isAbstract && declarationClass.classKind == ClassKind.CLASS) {
|
||||
reporter.reportOn(expression.source, FirErrors.CREATING_AN_INSTANCE_OF_ABSTRACT_CLASS, context)
|
||||
}
|
||||
if (declarationClass.classKind == ClassKind.ANNOTATION_CLASS &&
|
||||
context.qualifiedAccessOrAssignmentsOrAnnotationCalls.all { call ->
|
||||
call !is FirAnnotation
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
// FIR_IDENTICAL
|
||||
// ISSUE: KT-58938
|
||||
|
||||
abstract class AbstractClass()
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
val abstractClass = ::<!CREATING_AN_INSTANCE_OF_ABSTRACT_CLASS!>AbstractClass<!>
|
||||
abstractClass.invoke()
|
||||
}
|
||||
Vendored
+1
-1
@@ -6,7 +6,7 @@ enum class D
|
||||
|
||||
fun main() {
|
||||
::<!UNRESOLVED_REFERENCE!>A<!>
|
||||
::B
|
||||
::<!CREATING_AN_INSTANCE_OF_ABSTRACT_CLASS!>B<!>
|
||||
::<!CALLABLE_REFERENCE_TO_ANNOTATION_CONSTRUCTOR!>C<!> // KT-3465
|
||||
::<!UNRESOLVED_REFERENCE!>D<!>
|
||||
}
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
|
||||
abstract class Abstract
|
||||
|
||||
fun <D> create(fn: () -> D): D {
|
||||
return fn()
|
||||
}
|
||||
|
||||
fun main() {
|
||||
create(::Abstract)
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
|
||||
abstract class Abstract
|
||||
|
||||
|
||||
Generated
+6
@@ -34,6 +34,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
|
||||
runTest("compiler/testData/diagnostics/tests/AbstractAccessor.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("abstractClassReference.kt")
|
||||
public void testAbstractClassReference() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/abstractClassReference.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("AbstractInAbstractClass.kt")
|
||||
public void testAbstractInAbstractClass() throws Exception {
|
||||
|
||||
Reference in New Issue
Block a user