diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDataClassConverters.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDataClassConverters.kt index 7a17a82f1b8..575bc3b4d84 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDataClassConverters.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDataClassConverters.kt @@ -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, diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnostics.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnostics.kt index 50e86a29a4b..89ef0ce0e93 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnostics.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnostics.kt @@ -295,6 +295,10 @@ sealed interface KtFirDiagnostic : KtDiagnosticWithPsi { override val diagnosticClass get() = CreatingAnInstanceOfAbstractClass::class } + interface NoConstructor : KtFirDiagnostic { + override val diagnosticClass get() = NoConstructor::class + } + interface FunctionCallExpected : KtFirDiagnostic { override val diagnosticClass get() = FunctionCallExpected::class val functionName: String diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnosticsImpl.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnosticsImpl.kt index 0117bc9a916..75cbe0adf58 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnosticsImpl.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnosticsImpl.kt @@ -339,6 +339,11 @@ internal class CreatingAnInstanceOfAbstractClassImpl( token: KtLifetimeToken, ) : KtAbstractFirDiagnostic(firDiagnostic, token), KtFirDiagnostic.CreatingAnInstanceOfAbstractClass +internal class NoConstructorImpl( + firDiagnostic: KtPsiDiagnostic, + token: KtLifetimeToken, +) : KtAbstractFirDiagnostic(firDiagnostic, token), KtFirDiagnostic.NoConstructor + internal class FunctionCallExpectedImpl( override val functionName: String, override val hasValueParameters: Boolean, diff --git a/analysis/analysis-api/testData/components/callResolver/resolveCall/enumSuperTypeInterface.txt b/analysis/analysis-api/testData/components/callResolver/resolveCall/enumSuperTypeInterface.txt index b3f4eec7227..a7d86dd469f 100644 --- a/analysis/analysis-api/testData/components/callResolver/resolveCall/enumSuperTypeInterface.txt +++ b/analysis/analysis-api/testData/components/callResolver/resolveCall/enumSuperTypeInterface.txt @@ -1,3 +1,3 @@ KtErrorCallInfo: candidateCalls = [] - diagnostic = ERROR> \ No newline at end of file + diagnostic = ERROR \ No newline at end of file diff --git a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt index ae635c771fc..b394dacc64d 100644 --- a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt +++ b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt @@ -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() + val NO_CONSTRUCTOR by error(PositioningStrategy.VALUE_ARGUMENTS_LIST) val FUNCTION_CALL_EXPECTED by error(PositioningStrategy.REFERENCED_NAME_BY_QUALIFIED) { parameter("functionName") parameter("hasValueParameters") diff --git a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/model/RegularDiagnosticData.kt b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/model/RegularDiagnosticData.kt index 3d5fe07773b..576b8352a58 100644 --- a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/model/RegularDiagnosticData.kt +++ b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/model/RegularDiagnosticData.kt @@ -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, diff --git a/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt b/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt index be2a200bdec..be41781c06d 100644 --- a/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt +++ b/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt @@ -165,6 +165,7 @@ object FirErrors { // Call resolution val CREATING_AN_INSTANCE_OF_ABSTRACT_CLASS by error0() + val NO_CONSTRUCTOR by error0(SourceElementPositioningStrategies.VALUE_ARGUMENTS_LIST) val FUNCTION_CALL_EXPECTED by error2(SourceElementPositioningStrategies.REFERENCED_NAME_BY_QUALIFIED) val ILLEGAL_SELECTOR by error0() val NO_RECEIVER_ALLOWED by error0() diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrorsDefaultMessages.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrorsDefaultMessages.kt index ea013c73882..518bbd1bd01 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrorsDefaultMessages.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrorsDefaultMessages.kt @@ -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, diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/coneDiagnosticToFirDiagnostic.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/coneDiagnosticToFirDiagnostic.kt index 52b1efcb0bb..fc3b414e198 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/coneDiagnosticToFirDiagnostic.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/coneDiagnosticToFirDiagnostic.kt @@ -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 { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt index 87b08053180..200a02125d1 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt @@ -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) } } diff --git a/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/diagnostics/ConeDiagnostics.kt b/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/diagnostics/ConeDiagnostics.kt index 6051fe4959e..b7760579b53 100644 --- a/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/diagnostics/ConeDiagnostics.kt +++ b/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/diagnostics/ConeDiagnostics.kt @@ -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 diff --git a/compiler/frontend.common-psi/src/org/jetbrains/kotlin/diagnostics/LightTreePositioningStrategies.kt b/compiler/frontend.common-psi/src/org/jetbrains/kotlin/diagnostics/LightTreePositioningStrategies.kt index 3e1361e5d2b..be4df6fedb3 100644 --- a/compiler/frontend.common-psi/src/org/jetbrains/kotlin/diagnostics/LightTreePositioningStrategies.kt +++ b/compiler/frontend.common-psi/src/org/jetbrains/kotlin/diagnostics/LightTreePositioningStrategies.kt @@ -558,6 +558,23 @@ object LightTreePositioningStrategies { } } + val VALUE_ARGUMENTS_LIST: LightTreePositioningStrategy = object : LightTreePositioningStrategy() { + override fun mark( + node: LighterASTNode, + startOffset: Int, + endOffset: Int, + tree: FlyweightCapableTreeStructure, + ): List { + 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, diff --git a/compiler/frontend.common-psi/src/org/jetbrains/kotlin/diagnostics/PositioningStrategies.kt b/compiler/frontend.common-psi/src/org/jetbrains/kotlin/diagnostics/PositioningStrategies.kt index 60b5b80144d..bcace455a68 100644 --- a/compiler/frontend.common-psi/src/org/jetbrains/kotlin/diagnostics/PositioningStrategies.kt +++ b/compiler/frontend.common-psi/src/org/jetbrains/kotlin/diagnostics/PositioningStrategies.kt @@ -707,6 +707,13 @@ object PositioningStrategies { } } + @JvmField + val VALUE_ARGUMENTS_LIST: PositioningStrategy = object : PositioningStrategy() { + override fun mark(element: KtElement): List { + return markElement(element.getChildOfType() ?: element) + } + } + @JvmField val FUNCTION_PARAMETERS: PositioningStrategy = object : PositioningStrategy() { override fun mark(element: KtFunction): List { diff --git a/compiler/frontend.common-psi/src/org/jetbrains/kotlin/diagnostics/SourceElementPositioningStrategies.kt b/compiler/frontend.common-psi/src/org/jetbrains/kotlin/diagnostics/SourceElementPositioningStrategies.kt index 87e8f4194de..b66fbef7302 100644 --- a/compiler/frontend.common-psi/src/org/jetbrains/kotlin/diagnostics/SourceElementPositioningStrategies.kt +++ b/compiler/frontend.common-psi/src/org/jetbrains/kotlin/diagnostics/SourceElementPositioningStrategies.kt @@ -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 diff --git a/compiler/testData/diagnostics/tests/classObjects/classWithFunctionSupertype_after.fir.kt b/compiler/testData/diagnostics/tests/classObjects/classWithFunctionSupertype_after.fir.kt index 3f57255dd85..ddab9fcf98e 100644 --- a/compiler/testData/diagnostics/tests/classObjects/classWithFunctionSupertype_after.fir.kt +++ b/compiler/testData/diagnostics/tests/classObjects/classWithFunctionSupertype_after.fir.kt @@ -2,12 +2,12 @@ // LANGUAGE: +ProhibitConstructorCallOnFunctionalSupertype // ISSUE: KT-46344 -abstract class A : () -> Int() -abstract class B : (() -> Int)() -abstract class C : Function0() -abstract class D : suspend () -> Int() -abstract class E : (suspend () -> Int)() -abstract class F : kotlin.coroutines.SuspendFunction0() +abstract class A : () -> Int() +abstract class B : (() -> Int)() +abstract class C : Function0() +abstract class D : suspend () -> Int() +abstract class E : (suspend () -> Int)() +abstract class F : kotlin.coroutines.SuspendFunction0() interface IA : () -> Int() interface IB : (() -> Int)() diff --git a/compiler/testData/diagnostics/tests/classObjects/classWithFunctionSupertype_before.fir.kt b/compiler/testData/diagnostics/tests/classObjects/classWithFunctionSupertype_before.fir.kt index e58c6ee93fd..905fec8ca7b 100644 --- a/compiler/testData/diagnostics/tests/classObjects/classWithFunctionSupertype_before.fir.kt +++ b/compiler/testData/diagnostics/tests/classObjects/classWithFunctionSupertype_before.fir.kt @@ -2,12 +2,12 @@ // LANGUAGE: -ProhibitConstructorCallOnFunctionalSupertype // ISSUE: KT-46344 -abstract class A : () -> Int() -abstract class B : (() -> Int)() -abstract class C : Function0() -abstract class D : suspend () -> Int() -abstract class E : (suspend () -> Int)() -abstract class F : kotlin.coroutines.SuspendFunction0() +abstract class A : () -> Int() +abstract class B : (() -> Int)() +abstract class C : Function0() +abstract class D : suspend () -> Int() +abstract class E : (suspend () -> Int)() +abstract class F : kotlin.coroutines.SuspendFunction0() interface IA : () -> Int() interface IB : (() -> Int)() diff --git a/compiler/testData/diagnostics/tests/enum/enumInheritance.fir.kt b/compiler/testData/diagnostics/tests/enum/enumInheritance.fir.kt index 6b73dad2e58..0f9b4e45fbc 100644 --- a/compiler/testData/diagnostics/tests/enum/enumInheritance.fir.kt +++ b/compiler/testData/diagnostics/tests/enum/enumInheritance.fir.kt @@ -1,8 +1,7 @@ -// COMPARE_WITH_LIGHT_TREE // FILE: test.kt enum class MyEnum(): MyClass() {} enum class MyEnum2(): MyTrait {} -enum class MyEnum2_1(): MyTrait() {} +enum class MyEnum2_1(): MyTrait() {} enum class MyEnum3(): MyEnumBase() {} open class MyClass() {} diff --git a/compiler/testData/diagnostics/tests/enum/enumInheritance.kt b/compiler/testData/diagnostics/tests/enum/enumInheritance.kt index 12725079adb..3169cc3ea90 100644 --- a/compiler/testData/diagnostics/tests/enum/enumInheritance.kt +++ b/compiler/testData/diagnostics/tests/enum/enumInheritance.kt @@ -1,4 +1,3 @@ -// COMPARE_WITH_LIGHT_TREE // FILE: test.kt enum class MyEnum(): MyClass() {} enum class MyEnum2(): MyTrait {} diff --git a/compiler/testData/diagnostics/tests/incompleteCode/diagnosticWithSyntaxError/typeReferenceError.fir.kt b/compiler/testData/diagnostics/tests/incompleteCode/diagnosticWithSyntaxError/typeReferenceError.fir.kt index aaf127120e7..cc8d10e7646 100644 --- a/compiler/testData/diagnostics/tests/incompleteCode/diagnosticWithSyntaxError/typeReferenceError.fir.kt +++ b/compiler/testData/diagnostics/tests/incompleteCode/diagnosticWithSyntaxError/typeReferenceError.fir.kt @@ -1,3 +1,3 @@ package typeReferenceError -class Pair<:(val c: fun main() +class Pair<:(val c: fun main()