[FIR] Report separate error for delegated constructor call to interface
#KT-59216 Fixed
This commit is contained in:
committed by
Space Team
parent
5abab2197b
commit
e7c213e06e
+6
@@ -363,6 +363,12 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirErrors.NO_CONSTRUCTOR) { firDiagnostic ->
|
||||
NoConstructorImpl(
|
||||
firDiagnostic as KtPsiDiagnostic,
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirErrors.FUNCTION_CALL_EXPECTED) { firDiagnostic ->
|
||||
FunctionCallExpectedImpl(
|
||||
firDiagnostic.a,
|
||||
|
||||
+4
@@ -295,6 +295,10 @@ sealed interface KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
|
||||
override val diagnosticClass get() = CreatingAnInstanceOfAbstractClass::class
|
||||
}
|
||||
|
||||
interface NoConstructor : KtFirDiagnostic<PsiElement> {
|
||||
override val diagnosticClass get() = NoConstructor::class
|
||||
}
|
||||
|
||||
interface FunctionCallExpected : KtFirDiagnostic<PsiElement> {
|
||||
override val diagnosticClass get() = FunctionCallExpected::class
|
||||
val functionName: String
|
||||
|
||||
+5
@@ -339,6 +339,11 @@ internal class CreatingAnInstanceOfAbstractClassImpl(
|
||||
token: KtLifetimeToken,
|
||||
) : KtAbstractFirDiagnostic<KtExpression>(firDiagnostic, token), KtFirDiagnostic.CreatingAnInstanceOfAbstractClass
|
||||
|
||||
internal class NoConstructorImpl(
|
||||
firDiagnostic: KtPsiDiagnostic,
|
||||
token: KtLifetimeToken,
|
||||
) : KtAbstractFirDiagnostic<PsiElement>(firDiagnostic, token), KtFirDiagnostic.NoConstructor
|
||||
|
||||
internal class FunctionCallExpectedImpl(
|
||||
override val functionName: String,
|
||||
override val hasValueParameters: Boolean,
|
||||
|
||||
Vendored
+1
-1
@@ -1,3 +1,3 @@
|
||||
KtErrorCallInfo:
|
||||
candidateCalls = []
|
||||
diagnostic = ERROR<UNRESOLVED_REFERENCE: Unresolved reference: <init>>
|
||||
diagnostic = ERROR<NO_CONSTRUCTOR: This type does not have a constructor.>
|
||||
+1
@@ -152,6 +152,7 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
|
||||
|
||||
val CALL_RESOLUTION by object : DiagnosticGroup("Call resolution") {
|
||||
val CREATING_AN_INSTANCE_OF_ABSTRACT_CLASS by error<KtExpression>()
|
||||
val NO_CONSTRUCTOR by error<PsiElement>(PositioningStrategy.VALUE_ARGUMENTS_LIST)
|
||||
val FUNCTION_CALL_EXPECTED by error<PsiElement>(PositioningStrategy.REFERENCED_NAME_BY_QUALIFIED) {
|
||||
parameter<String>("functionName")
|
||||
parameter<Boolean>("hasValueParameters")
|
||||
|
||||
+1
@@ -76,6 +76,7 @@ enum class PositioningStrategy(private val strategy: String? = null) {
|
||||
USELESS_ELVIS,
|
||||
NAME_OF_NAMED_ARGUMENT,
|
||||
VALUE_ARGUMENTS,
|
||||
VALUE_ARGUMENTS_LIST,
|
||||
SUPERTYPES_LIST,
|
||||
RETURN_WITH_LABEL,
|
||||
PROPERTY_INITIALIZER,
|
||||
|
||||
@@ -165,6 +165,7 @@ object FirErrors {
|
||||
|
||||
// Call resolution
|
||||
val CREATING_AN_INSTANCE_OF_ABSTRACT_CLASS by error0<KtExpression>()
|
||||
val NO_CONSTRUCTOR by error0<PsiElement>(SourceElementPositioningStrategies.VALUE_ARGUMENTS_LIST)
|
||||
val FUNCTION_CALL_EXPECTED by error2<PsiElement, String, Boolean>(SourceElementPositioningStrategies.REFERENCED_NAME_BY_QUALIFIED)
|
||||
val ILLEGAL_SELECTOR by error0<PsiElement>()
|
||||
val NO_RECEIVER_ALLOWED by error0<PsiElement>()
|
||||
|
||||
+2
@@ -139,6 +139,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CONST_VAL_WITH_GE
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CONST_VAL_WITH_NON_CONST_INITIALIZER
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CONTRACT_NOT_ALLOWED
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CREATING_AN_INSTANCE_OF_ABSTRACT_CLASS
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NO_CONSTRUCTOR
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CYCLE_IN_ANNOTATION_PARAMETER
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CYCLIC_CONSTRUCTOR_DELEGATION_CALL
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CYCLIC_GENERIC_UPPER_BOUND
|
||||
@@ -736,6 +737,7 @@ object FirErrorsDefaultMessages : BaseDiagnosticRendererFactory() {
|
||||
TO_STRING
|
||||
)
|
||||
map.put(CREATING_AN_INSTANCE_OF_ABSTRACT_CLASS, "Cannot create an instance of an abstract class")
|
||||
map.put(NO_CONSTRUCTOR, "This type does not have a constructor.")
|
||||
map.put(FUNCTION_CALL_EXPECTED, "Function invocation ''{0}({1})'' expected", TO_STRING, FUNCTION_PARAMETERS)
|
||||
map.put(
|
||||
FUNCTION_EXPECTED,
|
||||
|
||||
+1
@@ -58,6 +58,7 @@ private fun ConeDiagnostic.toKtDiagnostic(
|
||||
is ConeUnresolvedTypeQualifierError -> FirErrors.UNRESOLVED_REFERENCE.createOn(source, this.qualifier)
|
||||
is ConeFunctionCallExpectedError -> FirErrors.FUNCTION_CALL_EXPECTED.createOn(source, this.name.asString(), this.hasValueParameters)
|
||||
is ConeFunctionExpectedError -> FirErrors.FUNCTION_EXPECTED.createOn(source, this.expression, this.type)
|
||||
is ConeNoConstructorError -> FirErrors.NO_CONSTRUCTOR.createOn(callOrAssignmentSource ?: source)
|
||||
is ConeResolutionToClassifierError -> when (this.candidateSymbol.classKind) {
|
||||
ClassKind.INTERFACE -> FirErrors.INTERFACE_AS_FUNCTION.createOn(source, this.candidateSymbol)
|
||||
ClassKind.CLASS -> when {
|
||||
|
||||
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.hasExplicitBackingField
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.isInner
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.isInterface
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.isReferredViaField
|
||||
import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic
|
||||
import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
|
||||
@@ -697,10 +698,14 @@ class FirCallResolver(
|
||||
}
|
||||
|
||||
candidates.isEmpty() -> {
|
||||
if (name.asString() == "invoke" && explicitReceiver is FirConstExpression<*>) {
|
||||
ConeFunctionExpectedError(explicitReceiver.value?.toString() ?: "", explicitReceiver.typeRef.coneType)
|
||||
} else {
|
||||
ConeUnresolvedNameError(name)
|
||||
when {
|
||||
name.asString() == "invoke" && explicitReceiver is FirConstExpression<*> ->
|
||||
ConeFunctionExpectedError(
|
||||
explicitReceiver.value?.toString() ?: "",
|
||||
explicitReceiver.typeRef.coneType,
|
||||
)
|
||||
reference is FirSuperReference && (reference.superTypeRef.firClassLike(session) as? FirClass)?.isInterface == true -> ConeNoConstructorError
|
||||
else -> ConeUnresolvedNameError(name)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+4
@@ -82,6 +82,10 @@ class ConeFunctionExpectedError(val expression: String, val type: ConeKotlinType
|
||||
override val reason: String get() = "Expression '$expression' of type '$type' cannot be invoked as a function"
|
||||
}
|
||||
|
||||
object ConeNoConstructorError : ConeDiagnostic {
|
||||
override val reason: String get() = "This type does not have a constructor"
|
||||
}
|
||||
|
||||
class ConeResolutionToClassifierError(
|
||||
override val candidate: AbstractCandidate,
|
||||
override val candidateSymbol: FirRegularClassSymbol
|
||||
|
||||
+17
@@ -558,6 +558,23 @@ object LightTreePositioningStrategies {
|
||||
}
|
||||
}
|
||||
|
||||
val VALUE_ARGUMENTS_LIST: LightTreePositioningStrategy = object : LightTreePositioningStrategy() {
|
||||
override fun mark(
|
||||
node: LighterASTNode,
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
tree: FlyweightCapableTreeStructure<LighterASTNode>,
|
||||
): List<TextRange> {
|
||||
return markElement(
|
||||
tree.findChildByType(node, KtNodeTypes.VALUE_ARGUMENT_LIST) ?: node,
|
||||
startOffset,
|
||||
endOffset,
|
||||
tree,
|
||||
node
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
val VALUE_ARGUMENTS: LightTreePositioningStrategy = object : LightTreePositioningStrategy() {
|
||||
override fun mark(
|
||||
node: LighterASTNode,
|
||||
|
||||
+7
@@ -707,6 +707,13 @@ object PositioningStrategies {
|
||||
}
|
||||
}
|
||||
|
||||
@JvmField
|
||||
val VALUE_ARGUMENTS_LIST: PositioningStrategy<KtElement> = object : PositioningStrategy<KtElement>() {
|
||||
override fun mark(element: KtElement): List<TextRange> {
|
||||
return markElement(element.getChildOfType<KtValueArgumentList>() ?: element)
|
||||
}
|
||||
}
|
||||
|
||||
@JvmField
|
||||
val FUNCTION_PARAMETERS: PositioningStrategy<KtFunction> = object : PositioningStrategy<KtFunction>() {
|
||||
override fun mark(element: KtFunction): List<TextRange> {
|
||||
|
||||
+5
@@ -163,6 +163,11 @@ object SourceElementPositioningStrategies {
|
||||
PositioningStrategies.VALUE_ARGUMENTS
|
||||
)
|
||||
|
||||
val VALUE_ARGUMENTS_LIST = SourceElementPositioningStrategy(
|
||||
LightTreePositioningStrategies.VALUE_ARGUMENTS_LIST,
|
||||
PositioningStrategies.VALUE_ARGUMENTS_LIST
|
||||
)
|
||||
|
||||
val SUPERTYPES_LIST = SourceElementPositioningStrategy(
|
||||
LightTreePositioningStrategies.SUPERTYPES_LIST,
|
||||
PositioningStrategies.SUPERTYPES_LIST
|
||||
|
||||
+6
-6
@@ -2,12 +2,12 @@
|
||||
// LANGUAGE: +ProhibitConstructorCallOnFunctionalSupertype
|
||||
// ISSUE: KT-46344
|
||||
|
||||
abstract class A : <!UNRESOLVED_REFERENCE!>() -> Int<!>()
|
||||
abstract class B : <!UNRESOLVED_REFERENCE!>(() -> Int)<!>()
|
||||
abstract class C : <!UNRESOLVED_REFERENCE!>Function0<Int><!>()
|
||||
abstract class D : <!UNRESOLVED_REFERENCE!>suspend () -> Int<!>()
|
||||
abstract class E : <!UNRESOLVED_REFERENCE!>(suspend () -> Int)<!>()
|
||||
abstract class F : <!UNRESOLVED_REFERENCE!>kotlin.coroutines.SuspendFunction0<Int><!>()
|
||||
abstract class A : () -> Int<!NO_CONSTRUCTOR!>()<!>
|
||||
abstract class B : (() -> Int)<!NO_CONSTRUCTOR!>()<!>
|
||||
abstract class C : Function0<Int><!NO_CONSTRUCTOR!>()<!>
|
||||
abstract class D : suspend () -> Int<!NO_CONSTRUCTOR!>()<!>
|
||||
abstract class E : (suspend () -> Int)<!NO_CONSTRUCTOR!>()<!>
|
||||
abstract class F : kotlin.coroutines.SuspendFunction0<Int><!NO_CONSTRUCTOR!>()<!>
|
||||
|
||||
interface IA : <!SUPERTYPE_INITIALIZED_IN_INTERFACE!>() -> Int<!>()
|
||||
interface IB : <!SUPERTYPE_INITIALIZED_IN_INTERFACE!>(() -> Int)<!>()
|
||||
|
||||
+6
-6
@@ -2,12 +2,12 @@
|
||||
// LANGUAGE: -ProhibitConstructorCallOnFunctionalSupertype
|
||||
// ISSUE: KT-46344
|
||||
|
||||
abstract class A : <!UNRESOLVED_REFERENCE!>() -> Int<!>()
|
||||
abstract class B : <!UNRESOLVED_REFERENCE!>(() -> Int)<!>()
|
||||
abstract class C : <!UNRESOLVED_REFERENCE!>Function0<Int><!>()
|
||||
abstract class D : <!UNRESOLVED_REFERENCE!>suspend () -> Int<!>()
|
||||
abstract class E : <!UNRESOLVED_REFERENCE!>(suspend () -> Int)<!>()
|
||||
abstract class F : <!UNRESOLVED_REFERENCE!>kotlin.coroutines.SuspendFunction0<Int><!>()
|
||||
abstract class A : () -> Int<!NO_CONSTRUCTOR!>()<!>
|
||||
abstract class B : (() -> Int)<!NO_CONSTRUCTOR!>()<!>
|
||||
abstract class C : Function0<Int><!NO_CONSTRUCTOR!>()<!>
|
||||
abstract class D : suspend () -> Int<!NO_CONSTRUCTOR!>()<!>
|
||||
abstract class E : (suspend () -> Int)<!NO_CONSTRUCTOR!>()<!>
|
||||
abstract class F : kotlin.coroutines.SuspendFunction0<Int><!NO_CONSTRUCTOR!>()<!>
|
||||
|
||||
interface IA : <!SUPERTYPE_INITIALIZED_IN_INTERFACE!>() -> Int<!>()
|
||||
interface IB : <!SUPERTYPE_INITIALIZED_IN_INTERFACE!>(() -> Int)<!>()
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
// COMPARE_WITH_LIGHT_TREE
|
||||
// FILE: test.kt
|
||||
enum class MyEnum(): <!CLASS_IN_SUPERTYPE_FOR_ENUM!>MyClass<!>() {}
|
||||
enum class MyEnum2(): MyTrait {}
|
||||
enum class MyEnum2_1(): <!UNRESOLVED_REFERENCE!>MyTrait<!>() {}
|
||||
enum class MyEnum2_1(): MyTrait<!NO_CONSTRUCTOR!>()<!> {}
|
||||
enum class MyEnum3(): <!CLASS_IN_SUPERTYPE_FOR_ENUM, FINAL_SUPERTYPE, INVISIBLE_REFERENCE!>MyEnumBase<!>() {}
|
||||
|
||||
open class MyClass() {}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// COMPARE_WITH_LIGHT_TREE
|
||||
// FILE: test.kt
|
||||
enum class MyEnum(): <!CLASS_IN_SUPERTYPE_FOR_ENUM!>MyClass<!>() {}
|
||||
enum class MyEnum2(): MyTrait {}
|
||||
|
||||
+1
-1
@@ -1,3 +1,3 @@
|
||||
package typeReferenceError
|
||||
|
||||
<!ABSTRACT_MEMBER_NOT_IMPLEMENTED!>class Pair<!><<!SYNTAX!><!>:<!UNRESOLVED_REFERENCE!>(<!UNSUPPORTED!>val<!> c: <!SYNTAX!><!SYNTAX!><!>fun<!><!SYNTAX!><!> <!UNRESOLVED_REFERENCE!>main<!><!>()
|
||||
<!ABSTRACT_MEMBER_NOT_IMPLEMENTED!>class Pair<!><<!SYNTAX!><!>:(<!UNSUPPORTED!>val<!> c: <!SYNTAX!><!SYNTAX!><!>fun<!><!SYNTAX!><!> <!UNRESOLVED_REFERENCE!>main<!><!NO_CONSTRUCTOR!>()<!>
|
||||
|
||||
Reference in New Issue
Block a user