diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirInfixFunctionDeclarationChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirInfixFunctionDeclarationChecker.kt index 92deac690e2..31f1d06dc00 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirInfixFunctionDeclarationChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirInfixFunctionDeclarationChecker.kt @@ -5,11 +5,10 @@ package org.jetbrains.kotlin.fir.analysis.checkers.declaration -import org.jetbrains.kotlin.diagnostics.Errors 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.onSource +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction import org.jetbrains.kotlin.fir.declarations.isInfix @@ -28,6 +27,6 @@ object FirInfixFunctionDeclarationChecker : FirDeclarationChecker { + fun collectDiagnostics(firFile: FirFile): Iterable> { if (!componentsInitialized) { throw IllegalStateException("Components are not initialized") } @@ -37,7 +37,7 @@ abstract class AbstractDiagnosticCollector( } protected abstract fun initializeCollector() - protected abstract fun getCollectedDiagnostics(): Iterable + protected abstract fun getCollectedDiagnostics(): Iterable> abstract fun runCheck(block: (DiagnosticReporter) -> Unit) private val components: MutableList = mutableListOf() diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/ParallelDiagnosticsCollector.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/ParallelDiagnosticsCollector.kt index 8c04d7dd907..35c825b62e0 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/ParallelDiagnosticsCollector.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/ParallelDiagnosticsCollector.kt @@ -6,8 +6,8 @@ package org.jetbrains.kotlin.fir.analysis.collectors import org.jetbrains.kotlin.fir.FirSession -import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnostic import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnostic import org.jetbrains.kotlin.fir.analysis.diagnostics.SimpleDiagnosticReporter import java.util.* import java.util.concurrent.Executors @@ -42,10 +42,10 @@ class ParallelDiagnosticsCollector(session: FirSession, private val numberOfThre futures.clear() } - override fun getCollectedDiagnostics(): Iterable { + override fun getCollectedDiagnostics(): Iterable> { futures.forEach { it.get() } return Iterable { - object : Iterator { + object : Iterator> { private val globalIterator = reporters.iterator() private var localIterator = globalIterator.next().diagnostics.iterator() @@ -60,7 +60,7 @@ class ParallelDiagnosticsCollector(session: FirSession, private val numberOfThre return localIterator.hasNext() } - override fun next(): FirDiagnostic { + override fun next(): FirDiagnostic<*> { update() return localIterator.next() } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/SimpleDiagnosticsCollector.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/SimpleDiagnosticsCollector.kt index b40a44c2e27..f32f4d1a7a7 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/SimpleDiagnosticsCollector.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/SimpleDiagnosticsCollector.kt @@ -6,8 +6,8 @@ package org.jetbrains.kotlin.fir.analysis.collectors import org.jetbrains.kotlin.fir.FirSession -import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnostic import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnostic import org.jetbrains.kotlin.fir.analysis.diagnostics.SimpleDiagnosticReporter class SimpleDiagnosticsCollector(session: FirSession) : AbstractDiagnosticCollector(session) { @@ -17,7 +17,7 @@ class SimpleDiagnosticsCollector(session: FirSession) : AbstractDiagnosticCollec reporter = SimpleDiagnosticReporter() } - override fun getCollectedDiagnostics(): Iterable { + override fun getCollectedDiagnostics(): Iterable> { return reporter.diagnostics } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/components/ErrorNodeDiagnosticCollectorComponent.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/components/ErrorNodeDiagnosticCollectorComponent.kt index a0baf2ab6af..1f7a80ee302 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/components/ErrorNodeDiagnosticCollectorComponent.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/components/ErrorNodeDiagnosticCollectorComponent.kt @@ -5,16 +5,17 @@ package org.jetbrains.kotlin.fir.analysis.collectors.components -import com.intellij.psi.PsiElement -import org.jetbrains.kotlin.diagnostics.DiagnosticFactory0 -import org.jetbrains.kotlin.diagnostics.DiagnosticFactory1 -import org.jetbrains.kotlin.diagnostics.Errors import org.jetbrains.kotlin.fir.FirSourceElement import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.collectors.AbstractDiagnosticCollector -import org.jetbrains.kotlin.fir.analysis.diagnostics.* +import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticFactory0 +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors import org.jetbrains.kotlin.fir.declarations.FirErrorFunction -import org.jetbrains.kotlin.fir.diagnostics.* +import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic +import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic +import org.jetbrains.kotlin.fir.diagnostics.ConeStubDiagnostic +import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind import org.jetbrains.kotlin.fir.expressions.FirErrorExpression import org.jetbrains.kotlin.fir.expressions.FirErrorLoop import org.jetbrains.kotlin.fir.references.FirErrorNamedReference @@ -49,30 +50,29 @@ class ErrorNodeDiagnosticCollectorComponent(collector: AbstractDiagnosticCollect private fun reportFirDiagnostic(diagnostic: ConeDiagnostic, source: FirSourceElement, reporter: DiagnosticReporter) { val coneDiagnostic = when (diagnostic) { - is ConeUnresolvedReferenceError -> FirErrors.UNRESOLVED_REFERENCE.onSource(source, diagnostic.name?.asString()) - is ConeUnresolvedSymbolError -> FirErrors.UNRESOLVED_REFERENCE.onSource(source, diagnostic.classId.asString()) - is ConeUnresolvedNameError -> FirErrors.UNRESOLVED_REFERENCE.onSource(source, diagnostic.name.asString()) - is ConeInapplicableCandidateError -> FirErrors.INAPPLICABLE_CANDIDATE.onSource(source, diagnostic.candidates.map { it.symbol }) - is ConeAmbiguityError -> FirErrors.AMBIGUITY.onSource(source, diagnostic.candidates) - is ConeOperatorAmbiguityError -> FirErrors.ASSIGN_OPERATOR_AMBIGUITY.onSource(source, diagnostic.candidates) - is ConeVariableExpectedError -> Errors.VARIABLE_EXPECTED.onSource(source) - is ConeTypeMismatchError -> FirErrors.TYPE_MISMATCH.onSource(source, diagnostic.expectedType, diagnostic.actualType) - is ConeSimpleDiagnostic -> diagnostic.getFactory().onSource(source) - is ConeSimpleDiagnosticWithParameters1<*> -> diagnostic.getFactory().tryOnSource(source, diagnostic.a) + is ConeUnresolvedReferenceError -> FirErrors.UNRESOLVED_REFERENCE.on(source, diagnostic.name?.asString()) + is ConeUnresolvedSymbolError -> FirErrors.UNRESOLVED_REFERENCE.on(source, diagnostic.classId.asString()) + is ConeUnresolvedNameError -> FirErrors.UNRESOLVED_REFERENCE.on(source, diagnostic.name.asString()) + is ConeInapplicableCandidateError -> FirErrors.INAPPLICABLE_CANDIDATE.on(source, diagnostic.candidates.map { it.symbol }) + is ConeAmbiguityError -> FirErrors.AMBIGUITY.on(source, diagnostic.candidates) + is ConeOperatorAmbiguityError -> FirErrors.ASSIGN_OPERATOR_AMBIGUITY.on(source, diagnostic.candidates) + is ConeVariableExpectedError -> FirErrors.VARIABLE_EXPECTED.on(source) + is ConeTypeMismatchError -> FirErrors.TYPE_MISMATCH.on(source, diagnostic.expectedType, diagnostic.actualType) + is ConeSimpleDiagnostic -> diagnostic.getFactory().on(source) is ConeStubDiagnostic -> null else -> throw IllegalArgumentException("Unsupported diagnostic type: ${diagnostic.javaClass}") } reporter.report(coneDiagnostic) } - private fun ConeSimpleDiagnostic.getFactory(): DiagnosticFactory0 { + private fun ConeSimpleDiagnostic.getFactory(): FirDiagnosticFactory0 { @Suppress("UNCHECKED_CAST") return when (kind) { DiagnosticKind.Syntax -> FirErrors.SYNTAX_ERROR - DiagnosticKind.ReturnNotAllowed -> Errors.RETURN_NOT_ALLOWED + DiagnosticKind.ReturnNotAllowed -> FirErrors.RETURN_NOT_ALLOWED DiagnosticKind.UnresolvedLabel -> FirErrors.UNRESOLVED_LABEL DiagnosticKind.IllegalConstExpression -> FirErrors.ILLEGAL_CONST_EXPRESSION - DiagnosticKind.ConstructorInObject -> Errors.CONSTRUCTOR_IN_OBJECT + DiagnosticKind.ConstructorInObject -> FirErrors.CONSTRUCTOR_IN_OBJECT DiagnosticKind.DeserializationError -> FirErrors.DESERIALIZATION_ERROR DiagnosticKind.InferenceError -> FirErrors.INFERENCE_ERROR DiagnosticKind.NoSupertype -> FirErrors.NO_SUPERTYPE @@ -80,17 +80,10 @@ class ErrorNodeDiagnosticCollectorComponent(collector: AbstractDiagnosticCollect DiagnosticKind.EnumAsSupertype -> FirErrors.ENUM_AS_SUPERTYPE DiagnosticKind.RecursionInSupertypes -> FirErrors.RECURSION_IN_SUPERTYPES DiagnosticKind.RecursionInImplicitTypes -> FirErrors.RECURSION_IN_IMPLICIT_TYPES + DiagnosticKind.SuperNotAllowed -> FirErrors.SUPER_IS_NOT_AN_EXPRESSION DiagnosticKind.Java -> FirErrors.ERROR_FROM_JAVA_RESOLUTION DiagnosticKind.Other -> FirErrors.OTHER_ERROR else -> throw IllegalArgumentException("Unsupported diagnostic kind: $kind at $javaClass") - } as DiagnosticFactory0 - } - - private fun ConeSimpleDiagnosticWithParameters1<*>.getFactory(): DiagnosticFactory1 { - @Suppress("UNCHECKED_CAST") - return when (kind) { - DiagnosticKind.SuperNotAllowed -> Errors.SUPER_IS_NOT_AN_EXPRESSION - else -> throw IllegalArgumentException("Unsupported diagnostic kind: $kind at $javaClass") - } as DiagnosticFactory1 + } } } \ No newline at end of file diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/DiagnosticReporter.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/DiagnosticReporter.kt index b7a6b64b774..1fd260cf5f0 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/DiagnosticReporter.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/DiagnosticReporter.kt @@ -6,13 +6,13 @@ package org.jetbrains.kotlin.fir.analysis.diagnostics abstract class DiagnosticReporter { - abstract fun report(diagnostic: FirDiagnostic?) + abstract fun report(diagnostic: FirDiagnostic<*>?) } class SimpleDiagnosticReporter : DiagnosticReporter() { - val diagnostics: MutableList = mutableListOf() + val diagnostics: MutableList> = mutableListOf() - override fun report(diagnostic: FirDiagnostic?) { + override fun report(diagnostic: FirDiagnostic<*>?) { if (diagnostic == null) return diagnostics += diagnostic } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt index b83f8a43935..9e4081e3511 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt @@ -5,6 +5,10 @@ package org.jetbrains.kotlin.fir.analysis.diagnostics +import org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages +import org.jetbrains.kotlin.diagnostics.rendering.DiagnosticFactoryToRendererMap +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.NULLABLE_STRING +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.SYMBOLS import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.AMBIGUITY import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ASSIGN_OPERATOR_AMBIGUITY import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DESERIALIZATION_ERROR @@ -17,40 +21,24 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NO_SUPERTYPE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.OTHER_ERROR import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.RECURSION_IN_IMPLICIT_TYPES import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.RECURSION_IN_SUPERTYPES +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.SUPER_IS_NOT_AN_EXPRESSION import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.SYNTAX_ERROR import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TYPE_PARAMETER_AS_SUPERTYPE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.UNRESOLVED_LABEL import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.UNRESOLVED_REFERENCE -import org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages -import org.jetbrains.kotlin.diagnostics.rendering.DiagnosticFactoryToRendererMap -import org.jetbrains.kotlin.diagnostics.rendering.Renderer -import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol -import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol -import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol @Suppress("unused") class FirDefaultErrorMessages : DefaultErrorMessages.Extension { - override fun getMap(): DiagnosticFactoryToRendererMap { - return MAP + return MAP.psiDiagnosticMap } companion object { - private val SYMBOL_COLLECTION_RENDERER = Renderer { symbols: Collection> -> - symbols.joinToString(prefix = "[", postfix = "]", separator = ",", limit = 3, truncated = "...") { symbol -> - when (symbol) { - is FirClassLikeSymbol<*> -> symbol.classId.asString() - is FirCallableSymbol<*> -> symbol.callableId.toString() - else -> "???" - } - } - } - - private val MAP = DiagnosticFactoryToRendererMap("FIR").also { map -> - map.put(UNRESOLVED_REFERENCE, "Unresolved reference: {0}", Renderer { it }) - map.put(INAPPLICABLE_CANDIDATE, "Inapplicable candidate(s): {0}", SYMBOL_COLLECTION_RENDERER) - map.put(AMBIGUITY, "Ambiguity between candidates: {0}", SYMBOL_COLLECTION_RENDERER) - map.put(ASSIGN_OPERATOR_AMBIGUITY, "Ambiguity between assign operator candidates: {0}", SYMBOL_COLLECTION_RENDERER) + val MAP = FirDiagnosticFactoryToRendererMap("FIR").also { map -> + map.put(UNRESOLVED_REFERENCE, "Unresolved reference: {0}", NULLABLE_STRING) + map.put(INAPPLICABLE_CANDIDATE, "Inapplicable candidate(s): {0}", SYMBOLS) + map.put(AMBIGUITY, "Ambiguity between candidates: {0}", SYMBOLS) + map.put(ASSIGN_OPERATOR_AMBIGUITY, "Ambiguity between assign operator candidates: {0}", SYMBOLS) map.put(SYNTAX_ERROR, "Syntax error") map.put(UNRESOLVED_LABEL, "Unresolved label") map.put(ILLEGAL_CONST_EXPRESSION, "Illegal const expression") @@ -63,7 +51,7 @@ class FirDefaultErrorMessages : DefaultErrorMessages.Extension { map.put(RECURSION_IN_IMPLICIT_TYPES, "Recursion in implicit types") map.put(ERROR_FROM_JAVA_RESOLUTION, "Java resolution error") map.put(OTHER_ERROR, "Unknown (other) error") - + map.put(SUPER_IS_NOT_AN_EXPRESSION, "Super cannot be a callee") } } -} \ No newline at end of file +} diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnostic.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnostic.kt index 0feec4e797f..9debe271925 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnostic.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnostic.kt @@ -5,44 +5,127 @@ package org.jetbrains.kotlin.fir.analysis.diagnostics -import com.intellij.psi.PsiElement -import org.jetbrains.kotlin.diagnostics.* +import org.jetbrains.kotlin.diagnostics.Diagnostic +import org.jetbrains.kotlin.diagnostics.Severity +import org.jetbrains.kotlin.fir.FirLightSourceElement +import org.jetbrains.kotlin.fir.FirPsiSourceElement import org.jetbrains.kotlin.fir.FirSourceElement -import org.jetbrains.kotlin.fir.psi -class FirDiagnostic( - val diagnostic: Diagnostic, - val source: FirSourceElement -) +// ------------------------------ diagnostics ------------------------------ -inline fun DiagnosticFactory0.onSource(source: FirSourceElement): FirDiagnostic? { - val psi = source.psi as? E - ?: throw IllegalArgumentException("Incompatible PSI: expected ${E::class}, actual ${source.psi?.let { it::class }}") - return FirDiagnostic(this.on(psi), source) +sealed class FirDiagnostic { + abstract val element: E + abstract val severity: Severity + abstract val factory: AbstractFirDiagnosticFactory<*, *> } -inline fun DiagnosticFactory1.onSource(source: FirSourceElement, a: A): FirDiagnostic? { - val psi = source.psi as? E - ?: throw IllegalArgumentException("Incompatible PSI: expected ${E::class}, actual ${source.psi?.let { it::class }}") - return FirDiagnostic(this.on(psi, a), source) +sealed class FirSimpleDiagnostic : FirDiagnostic() { + abstract override val factory: FirDiagnosticFactory0<*> } -inline fun DiagnosticFactory2.onSource(source: FirSourceElement, a: A, b: B): FirDiagnostic? { - val psi = source.psi as? E - ?: throw IllegalArgumentException("Incompatible PSI: expected ${E::class}, actual ${source.psi?.let { it::class }}") - return FirDiagnostic(this.on(psi, a, b), source) +sealed class FirDiagnosticWithParameters1 : FirDiagnostic() { + abstract val a: A + abstract override val factory: FirDiagnosticFactory1<*, A> } -inline fun DiagnosticFactory3.onSource(source: FirSourceElement, a: A, b: B, c: C): FirDiagnostic? { - val psi = source.psi as? E - ?: throw IllegalArgumentException("Incompatible PSI: expected ${E::class}, actual ${source.psi?.let { it::class }}") - return FirDiagnostic(this.on(psi, a, b, c), source) +sealed class FirDiagnosticWithParameters2 : FirDiagnostic() { + abstract val a: A + abstract val b: B + abstract override val factory: FirDiagnosticFactory2<*, A, B> } -inline fun DiagnosticFactory1.tryOnSource( - source: FirSourceElement, - a: Any? -): FirDiagnostic? { - val aa = a as? A ?: throw IllegalArgumentException("Parameter passed to the factory is of incompatible type!") - return onSource(source, aa) -} \ No newline at end of file +sealed class FirDiagnosticWithParameters3 : FirDiagnostic() { + abstract val a: A + abstract val b: B + abstract val c: C + abstract override val factory: FirDiagnosticFactory3<*, A, B, C> +} + +// ------------------------------ psi diagnostics ------------------------------ + +interface FirPsiDiagnostic { + fun asPsiBasedDiagnostic(): Diagnostic + val element: E +} + +data class FirPsiSimpleDiagnostic( + override val element: E, + override val severity: Severity, + override val factory: FirDiagnosticFactory0<*> +) : FirSimpleDiagnostic(), FirPsiDiagnostic { + override fun asPsiBasedDiagnostic(): Diagnostic { + return factory.psiDiagnosticFactory.on(element.psi) + } +} + +data class FirPsiDiagnosticWithParameters1( + override val element: E, + override val a: A, + override val severity: Severity, + override val factory: FirDiagnosticFactory1<*, A> +) : FirDiagnosticWithParameters1(), FirPsiDiagnostic { + override fun asPsiBasedDiagnostic(): Diagnostic { + return factory.psiDiagnosticFactory.on(element.psi, a) + } +} + +data class FirPsiDiagnosticWithParameters2( + override val element: E, + override val a: A, + override val b: B, + override val severity: Severity, + override val factory: FirDiagnosticFactory2<*, A, B> +) : FirDiagnosticWithParameters2(), FirPsiDiagnostic { + override fun asPsiBasedDiagnostic(): Diagnostic { + return factory.psiDiagnosticFactory.on(element.psi, a, b) + } +} + +data class FirPsiDiagnosticWithParameters3( + override val element: E, + override val a: A, + override val b: B, + override val c: C, + override val severity: Severity, + override val factory: FirDiagnosticFactory3<*, A, B, C> +) : FirDiagnosticWithParameters3(), FirPsiDiagnostic { + override fun asPsiBasedDiagnostic(): Diagnostic { + return factory.psiDiagnosticFactory.on(element.psi, a, b, c) + } +} + +// ------------------------------ light tree diagnostics ------------------------------ + +interface FirLightDiagnostic { + val element: E +} + +data class FirLightSimpleDiagnostic( + override val element: E, + override val severity: Severity, + override val factory: FirDiagnosticFactory0<*> +) : FirSimpleDiagnostic(), FirLightDiagnostic + +data class FirLightDiagnosticWithParameters1( + override val element: E, + override val a: A, + override val severity: Severity, + override val factory: FirDiagnosticFactory1<*, A> +) : FirDiagnosticWithParameters1(), FirLightDiagnostic + +data class FirLightDiagnosticWithParameters2( + override val element: E, + override val a: A, + override val b: B, + override val severity: Severity, + override val factory: FirDiagnosticFactory2<*, A, B> +) : FirDiagnosticWithParameters2(), FirLightDiagnostic + +data class FirLightDiagnosticWithParameters3( + override val element: E, + override val a: A, + override val b: B, + override val c: C, + override val severity: Severity, + override val factory: FirDiagnosticFactory3<*, A, B, C> +) : FirDiagnosticWithParameters3(), FirLightDiagnostic \ No newline at end of file diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnosticFactoriesInitializer.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnosticFactoriesInitializer.kt index 4b3525afe37..6938aa3f098 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnosticFactoriesInitializer.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnosticFactoriesInitializer.kt @@ -7,13 +7,10 @@ package org.jetbrains.kotlin.diagnostics -import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors -import kotlin.reflect.full.memberProperties - -fun FirErrors.registerExternalFactories() { - val klass = FirErrors::class - for (property in klass.memberProperties) { - val factory = property.get(this) as? DiagnosticFactory<*> ?: continue - factory.name = property.name - } +/** + * This methods should me in `org.jetbrains.kotlin.diagnostics` package + * because of `DiagnosticFactory.setName` is package private + */ +fun DiagnosticFactory<*>.initializeName(name: String) { + this.name = name } \ No newline at end of file diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnosticFactory.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnosticFactory.kt new file mode 100644 index 00000000000..1ef91b7cea3 --- /dev/null +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnosticFactory.kt @@ -0,0 +1,75 @@ +/* + * 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.diagnostics + +import com.intellij.psi.PsiElement +import org.jetbrains.kotlin.diagnostics.* +import org.jetbrains.kotlin.fir.FirLightSourceElement +import org.jetbrains.kotlin.fir.FirPsiSourceElement +import org.jetbrains.kotlin.fir.FirSourceElement + +sealed class AbstractFirDiagnosticFactory>( + val name: String, + val severity: Severity, +) { + abstract val psiDiagnosticFactory: DiagnosticFactoryWithPsiElement<*, *> + + override fun toString(): String { + return name + } +} + +class FirDiagnosticFactory0( + name: String, severity: Severity, override val psiDiagnosticFactory: DiagnosticFactory0 +) : AbstractFirDiagnosticFactory>(name, severity) { + fun on(element: E): FirSimpleDiagnostic { + return when (element) { + is FirPsiSourceElement -> FirPsiSimpleDiagnostic(element, severity, this) + is FirLightSourceElement -> FirLightSimpleDiagnostic(element, severity, this) + else -> incorrectElement(element) + } + } +} + +class FirDiagnosticFactory1( + name: String, severity: Severity, override val psiDiagnosticFactory: DiagnosticFactory1 +) : AbstractFirDiagnosticFactory>(name, severity) { + fun on(element: E, a: A): FirDiagnosticWithParameters1 { + return when (element) { + is FirPsiSourceElement -> FirPsiDiagnosticWithParameters1(element, a, severity, this) + is FirLightSourceElement -> FirLightDiagnosticWithParameters1(element, a, severity, this) + else -> incorrectElement(element) + } + } +} + +class FirDiagnosticFactory2( + name: String, severity: Severity, override val psiDiagnosticFactory: DiagnosticFactory2 +) : AbstractFirDiagnosticFactory>(name, severity) { + fun on(element: E, a: A, b: B): FirDiagnosticWithParameters2 { + return when (element) { + is FirPsiSourceElement -> FirPsiDiagnosticWithParameters2(element, a, b, severity, this) + is FirLightSourceElement -> FirLightDiagnosticWithParameters2(element, a, b, severity, this) + else -> incorrectElement(element) + } + } +} + +class FirDiagnosticFactory3( + name: String, severity: Severity, override val psiDiagnosticFactory: DiagnosticFactory3 +) : AbstractFirDiagnosticFactory>(name, severity) { + fun on(element: E, a: A, b: B, c: C): FirDiagnosticWithParameters3 { + return when (element) { + is FirPsiSourceElement -> FirPsiDiagnosticWithParameters3(element, a, b, c, severity, this) + is FirLightSourceElement -> FirLightDiagnosticWithParameters3(element, a, b, c, severity, this) + else -> incorrectElement(element) + } + } +} + +private fun incorrectElement(element: FirSourceElement): Nothing { + throw IllegalArgumentException("Unknown element type: ${element::class}") +} diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnosticFactoryDsl.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnosticFactoryDsl.kt new file mode 100644 index 00000000000..63631bba178 --- /dev/null +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnosticFactoryDsl.kt @@ -0,0 +1,120 @@ +/* + * 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.diagnostics + +import com.intellij.psi.PsiElement +import org.jetbrains.kotlin.diagnostics.* +import org.jetbrains.kotlin.fir.FirSourceElement +import kotlin.properties.ReadOnlyProperty +import kotlin.reflect.KProperty + +fun warning0(): DiagnosticFactory0DelegateProvider { + return DiagnosticFactory0DelegateProvider(Severity.WARNING, null) +} + +fun warning1(): DiagnosticFactory1DelegateProvider { + return DiagnosticFactory1DelegateProvider(Severity.WARNING, null) +} + +fun warning2(): DiagnosticFactory2DelegateProvider { + return DiagnosticFactory2DelegateProvider(Severity.WARNING, null) +} + +fun warning3(): DiagnosticFactory3DelegateProvider { + return DiagnosticFactory3DelegateProvider(Severity.WARNING, null) +} + +fun error0(): DiagnosticFactory0DelegateProvider { + return DiagnosticFactory0DelegateProvider(Severity.ERROR, null) +} + +fun error1(): DiagnosticFactory1DelegateProvider { + return DiagnosticFactory1DelegateProvider(Severity.ERROR, null) +} + +fun error2(): DiagnosticFactory2DelegateProvider { + return DiagnosticFactory2DelegateProvider(Severity.ERROR, null) +} + +fun error3(): DiagnosticFactory3DelegateProvider { + return DiagnosticFactory3DelegateProvider(Severity.ERROR, null) +} + +/** + * Note that those functions can be applicable only for factories + * that takes `PsiElement` as first type parameter + */ +fun existing(psiDiagnosticFactory: DiagnosticFactory0): DiagnosticFactory0DelegateProvider { + return DiagnosticFactory0DelegateProvider(Severity.ERROR, psiDiagnosticFactory) +} + +fun existing(psiDiagnosticFactory: DiagnosticFactory1): DiagnosticFactory1DelegateProvider { + return DiagnosticFactory1DelegateProvider(Severity.ERROR, psiDiagnosticFactory) +} + +fun existing(psiDiagnosticFactory: DiagnosticFactory2): DiagnosticFactory2DelegateProvider { + return DiagnosticFactory2DelegateProvider(Severity.ERROR, psiDiagnosticFactory) +} + +fun existing(psiDiagnosticFactory: DiagnosticFactory3): DiagnosticFactory3DelegateProvider { + return DiagnosticFactory3DelegateProvider(Severity.ERROR, psiDiagnosticFactory) +} + +// ------------------------------ Providers ------------------------------ + +class DiagnosticFactory0DelegateProvider( + private val severity: Severity, + private val psiDiagnosticFactory: DiagnosticFactory0? +) { + operator fun provideDelegate(thisRef: Any?, prop: KProperty<*>): ReadOnlyProperty> { + val psiFactory = psiDiagnosticFactory ?: DiagnosticFactory0.create(severity).apply { + initializeName(prop.name) + } + return DummyDelegate(FirDiagnosticFactory0(prop.name, severity, psiFactory)) + } +} + +class DiagnosticFactory1DelegateProvider( + private val severity: Severity, + private val psiDiagnosticFactory: DiagnosticFactory1? +) { + operator fun provideDelegate(thisRef: Any?, prop: KProperty<*>): ReadOnlyProperty> { + val psiFactory = psiDiagnosticFactory ?: DiagnosticFactory1.create(severity).apply { + initializeName(prop.name) + } + return DummyDelegate(FirDiagnosticFactory1(prop.name, severity, psiFactory)) + } +} + +class DiagnosticFactory2DelegateProvider( + private val severity: Severity, + private val psiDiagnosticFactory: DiagnosticFactory2? +) { + operator fun provideDelegate(thisRef: Any?, prop: KProperty<*>): ReadOnlyProperty> { + val psiFactory = psiDiagnosticFactory ?: DiagnosticFactory2.create(severity).apply { + initializeName(prop.name) + } + return DummyDelegate(FirDiagnosticFactory2(prop.name, severity, psiFactory)) + } +} + +class DiagnosticFactory3DelegateProvider( + private val severity: Severity, + private val psiDiagnosticFactory: DiagnosticFactory3? +) { + operator fun provideDelegate(thisRef: Any?, prop: KProperty<*>): ReadOnlyProperty> { + val psiFactory = psiDiagnosticFactory ?: DiagnosticFactory3.create(severity).apply { + initializeName(prop.name) + } + return DummyDelegate(FirDiagnosticFactory3(prop.name, severity, psiFactory)) + } +} + +private class DummyDelegate(val value: T) : ReadOnlyProperty { + override fun getValue(thisRef: Any?, property: KProperty<*>): T { + return value + } +} \ No newline at end of file diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnosticFactoryToRendererMap.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnosticFactoryToRendererMap.kt new file mode 100644 index 00000000000..33d0f8a2618 --- /dev/null +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnosticFactoryToRendererMap.kt @@ -0,0 +1,59 @@ +/* + * 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.diagnostics + +import org.jetbrains.kotlin.diagnostics.rendering.DiagnosticFactoryToRendererMap +import org.jetbrains.kotlin.diagnostics.rendering.DiagnosticParameterRenderer +import org.jetbrains.kotlin.diagnostics.rendering.DiagnosticRenderer + +class FirDiagnosticFactoryToRendererMap(val name: String) { + private val diagnosticsMap: MutableMap, DiagnosticRenderer<*>> = mutableMapOf() + val psiDiagnosticMap: DiagnosticFactoryToRendererMap = + DiagnosticFactoryToRendererMap() + + operator fun get(factory: AbstractFirDiagnosticFactory<*, *>): DiagnosticRenderer<*>? = diagnosticsMap[factory] + + fun put(factory: FirDiagnosticFactory0<*>, message: String) { + psiDiagnosticMap.put(factory.psiDiagnosticFactory, message) + putToFirMap(factory) + } + + fun put( + factory: FirDiagnosticFactory1<*, A>, + message: String, + rendererA: DiagnosticParameterRenderer? + ) { + psiDiagnosticMap.put(factory.psiDiagnosticFactory, message, rendererA) + putToFirMap(factory) + } + + fun put( + factory: FirDiagnosticFactory2<*, A, B>, + message: String, + rendererA: DiagnosticParameterRenderer?, + rendererB: DiagnosticParameterRenderer? + ) { + psiDiagnosticMap.put(factory.psiDiagnosticFactory, message, rendererA, rendererB) + putToFirMap(factory) + } + + fun put( + factory: FirDiagnosticFactory3<*, A, B, C>, + message: String, + rendererA: DiagnosticParameterRenderer?, + rendererB: DiagnosticParameterRenderer?, + rendererC: DiagnosticParameterRenderer? + ) { + psiDiagnosticMap.put(factory.psiDiagnosticFactory, message, rendererA, rendererB, rendererC) + putToFirMap(factory) + } + + private fun putToFirMap(factory: AbstractFirDiagnosticFactory<*, *>) { + psiDiagnosticMap[factory.psiDiagnosticFactory]?.let { + diagnosticsMap[factory] = it + } + } +} \ No newline at end of file diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnosticRenderers.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnosticRenderers.kt new file mode 100644 index 00000000000..61f126f7cc4 --- /dev/null +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnosticRenderers.kt @@ -0,0 +1,25 @@ +/* + * 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.diagnostics + +import org.jetbrains.kotlin.diagnostics.rendering.Renderer +import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol +import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol +import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol + +object FirDiagnosticRenderers { + val NULLABLE_STRING = Renderer { it ?: "null" } + + val SYMBOLS = Renderer { symbols: Collection> -> + symbols.joinToString(prefix = "[", postfix = "]", separator = ",", limit = 3, truncated = "...") { symbol -> + when (symbol) { + is FirClassLikeSymbol<*> -> symbol.classId.asString() + is FirCallableSymbol<*> -> symbol.callableId.toString() + else -> "???" + } + } + } +} \ No newline at end of file diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt index 2ce3dae3a1c..b2933f7040d 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt @@ -5,32 +5,33 @@ package org.jetbrains.kotlin.fir.analysis.diagnostics -import org.jetbrains.kotlin.diagnostics.* -import org.jetbrains.kotlin.diagnostics.Severity.ERROR +import org.jetbrains.kotlin.diagnostics.Errors +import org.jetbrains.kotlin.fir.FirSourceElement import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol import org.jetbrains.kotlin.fir.types.ConeKotlinType -import org.jetbrains.kotlin.psi.KtElement object FirErrors { - val UNRESOLVED_REFERENCE = DiagnosticFactory1.create(ERROR) - val INAPPLICABLE_CANDIDATE = DiagnosticFactory1.create>>(ERROR) - val AMBIGUITY = DiagnosticFactory1.create>>(ERROR) - val ASSIGN_OPERATOR_AMBIGUITY = DiagnosticFactory1.create>>(ERROR) - val SYNTAX_ERROR = DiagnosticFactory0.create(ERROR) - val UNRESOLVED_LABEL = DiagnosticFactory0.create(ERROR) - val ILLEGAL_CONST_EXPRESSION = DiagnosticFactory0.create(ERROR) - val DESERIALIZATION_ERROR = DiagnosticFactory0.create(ERROR) - val INFERENCE_ERROR = DiagnosticFactory0.create(ERROR) - val NO_SUPERTYPE = DiagnosticFactory0.create(ERROR) - val TYPE_PARAMETER_AS_SUPERTYPE = DiagnosticFactory0.create(ERROR) - val ENUM_AS_SUPERTYPE = DiagnosticFactory0.create(ERROR) - val RECURSION_IN_SUPERTYPES = DiagnosticFactory0.create(ERROR) - val RECURSION_IN_IMPLICIT_TYPES = DiagnosticFactory0.create(ERROR) - val ERROR_FROM_JAVA_RESOLUTION = DiagnosticFactory0.create(ERROR) - val OTHER_ERROR = DiagnosticFactory0.create(ERROR) - val TYPE_MISMATCH = DiagnosticFactory2.create(ERROR) + val UNRESOLVED_REFERENCE by error1() + val INAPPLICABLE_CANDIDATE by error1>>() + val AMBIGUITY by error1>>() + val ASSIGN_OPERATOR_AMBIGUITY by error1>>() + val SYNTAX_ERROR by error0() + val UNRESOLVED_LABEL by error0() + val ILLEGAL_CONST_EXPRESSION by error0() + val DESERIALIZATION_ERROR by error0() + val INFERENCE_ERROR by error0() + val NO_SUPERTYPE by error0() + val TYPE_PARAMETER_AS_SUPERTYPE by error0() + val ENUM_AS_SUPERTYPE by error0() + val RECURSION_IN_SUPERTYPES by error0() + val RECURSION_IN_IMPLICIT_TYPES by error0() + val ERROR_FROM_JAVA_RESOLUTION by error0() + val OTHER_ERROR by error0() + val TYPE_MISMATCH by error2() + val VARIABLE_EXPECTED by error0() + val RETURN_NOT_ALLOWED by error0() + val CONSTRUCTOR_IN_OBJECT by error0() + val SUPER_IS_NOT_AN_EXPRESSION by error0() - init { - registerExternalFactories() - } -} \ No newline at end of file + val INAPPLICABLE_INFIX_MODIFIER by existing(Errors.INAPPLICABLE_INFIX_MODIFIER) +} diff --git a/compiler/fir/lightTree/src/org/jetbrains/kotlin/fir/lightTree/converter/ExpressionsConverter.kt b/compiler/fir/lightTree/src/org/jetbrains/kotlin/fir/lightTree/converter/ExpressionsConverter.kt index 304f1ca5d6c..c0dcd0a31f1 100644 --- a/compiler/fir/lightTree/src/org/jetbrains/kotlin/fir/lightTree/converter/ExpressionsConverter.kt +++ b/compiler/fir/lightTree/src/org/jetbrains/kotlin/fir/lightTree/converter/ExpressionsConverter.kt @@ -18,9 +18,8 @@ import org.jetbrains.kotlin.fir.declarations.builder.buildAnonymousFunction import org.jetbrains.kotlin.fir.declarations.builder.buildProperty import org.jetbrains.kotlin.fir.declarations.builder.buildValueParameter import org.jetbrains.kotlin.fir.declarations.impl.FirDeclarationStatusImpl -import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind -import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnosticWithParameters1 import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic +import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.builder.* import org.jetbrains.kotlin.fir.expressions.impl.FirModifiableQualifiedAccess @@ -504,7 +503,7 @@ class ExpressionsConverter( buildErrorNamedReference { val node = superNode!! source = node.toFirSourceElement() - diagnostic = ConeSimpleDiagnosticWithParameters1("Super cannot be a callee", node.asText, DiagnosticKind.SuperNotAllowed) + diagnostic = ConeSimpleDiagnostic("Super cannot be a callee", DiagnosticKind.SuperNotAllowed) } to null } else -> buildErrorNamedReference { diff --git a/compiler/fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt b/compiler/fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt index 155523a9b58..944bafb635d 100644 --- a/compiler/fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt +++ b/compiler/fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt @@ -18,9 +18,8 @@ import org.jetbrains.kotlin.fir.declarations.impl.FirDeclarationStatusImpl import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyAccessor import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyGetter import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertySetter -import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind -import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnosticWithParameters1 import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic +import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.builder.* import org.jetbrains.kotlin.fir.expressions.impl.FirModifiableQualifiedAccess @@ -1493,7 +1492,7 @@ class RawFirBuilder( is KtSuperExpression -> { buildErrorNamedReference { source = calleeExpression.toFirSourceElement() - diagnostic = ConeSimpleDiagnosticWithParameters1("Super cannot be a callee", calleeExpression.text, DiagnosticKind.SuperNotAllowed) + diagnostic = ConeSimpleDiagnostic("Super cannot be a callee", DiagnosticKind.SuperNotAllowed) } to null } diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/builder/FirErrorFunctionBuilder.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/builder/FirErrorFunctionBuilder.kt index 3d3907856e0..76e26f0a0be 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/builder/FirErrorFunctionBuilder.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/builder/FirErrorFunctionBuilder.kt @@ -17,13 +17,7 @@ import org.jetbrains.kotlin.fir.declarations.FirValueParameter import org.jetbrains.kotlin.fir.declarations.impl.FirErrorFunctionImpl import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall -import org.jetbrains.kotlin.fir.expressions.FirBlock -import org.jetbrains.kotlin.fir.references.FirControlFlowGraphReference -import org.jetbrains.kotlin.fir.references.impl.FirEmptyControlFlowGraphReference import org.jetbrains.kotlin.fir.symbols.impl.FirErrorFunctionSymbol -import org.jetbrains.kotlin.fir.types.FirTypeRef -import org.jetbrains.kotlin.fir.types.impl.FirErrorTypeRefImpl -import org.jetbrains.kotlin.fir.visitors.* /* * This file was generated automatically diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/builder/FirErrorExpressionBuilder.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/builder/FirErrorExpressionBuilder.kt index 50ac6615bf8..ff658283b76 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/builder/FirErrorExpressionBuilder.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/builder/FirErrorExpressionBuilder.kt @@ -12,11 +12,8 @@ import org.jetbrains.kotlin.fir.builder.FirBuilderDsl import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall import org.jetbrains.kotlin.fir.expressions.FirErrorExpression -import org.jetbrains.kotlin.fir.expressions.builder.FirExpressionBuilder import org.jetbrains.kotlin.fir.expressions.impl.FirErrorExpressionImpl import org.jetbrains.kotlin.fir.types.FirTypeRef -import org.jetbrains.kotlin.fir.types.impl.FirErrorTypeRefImpl -import org.jetbrains.kotlin.fir.visitors.* /* * This file was generated automatically diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/builder/FirErrorLoopBuilder.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/builder/FirErrorLoopBuilder.kt index d468e62cf1c..a7b137132b7 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/builder/FirErrorLoopBuilder.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/builder/FirErrorLoopBuilder.kt @@ -12,12 +12,8 @@ import org.jetbrains.kotlin.fir.builder.FirAnnotationContainerBuilder import org.jetbrains.kotlin.fir.builder.FirBuilderDsl import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall -import org.jetbrains.kotlin.fir.expressions.FirBlock import org.jetbrains.kotlin.fir.expressions.FirErrorLoop -import org.jetbrains.kotlin.fir.expressions.FirExpression -import org.jetbrains.kotlin.fir.expressions.impl.FirEmptyExpressionBlock import org.jetbrains.kotlin.fir.expressions.impl.FirErrorLoopImpl -import org.jetbrains.kotlin.fir.visitors.* /* * This file was generated automatically diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirErrorLoopImpl.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirErrorLoopImpl.kt index 31bce4d9205..1f3dfd1e218 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirErrorLoopImpl.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirErrorLoopImpl.kt @@ -12,7 +12,6 @@ import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall import org.jetbrains.kotlin.fir.expressions.FirBlock import org.jetbrains.kotlin.fir.expressions.FirErrorLoop import org.jetbrains.kotlin.fir.expressions.FirExpression -import org.jetbrains.kotlin.fir.expressions.impl.FirEmptyExpressionBlock import org.jetbrains.kotlin.fir.visitors.* /* diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/references/builder/FirErrorNamedReferenceBuilder.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/references/builder/FirErrorNamedReferenceBuilder.kt index 94a465b430b..e6bf0c1781f 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/references/builder/FirErrorNamedReferenceBuilder.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/references/builder/FirErrorNamedReferenceBuilder.kt @@ -11,9 +11,6 @@ import org.jetbrains.kotlin.fir.builder.FirBuilderDsl import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic import org.jetbrains.kotlin.fir.references.FirErrorNamedReference import org.jetbrains.kotlin.fir.references.impl.FirErrorNamedReferenceImpl -import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol -import org.jetbrains.kotlin.fir.visitors.* -import org.jetbrains.kotlin.name.Name /* * This file was generated automatically diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/types/builder/FirErrorTypeRefBuilder.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/types/builder/FirErrorTypeRefBuilder.kt index c8bbd868b4d..3a5cc5f6df5 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/types/builder/FirErrorTypeRefBuilder.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/types/builder/FirErrorTypeRefBuilder.kt @@ -11,12 +11,8 @@ import org.jetbrains.kotlin.fir.builder.FirAnnotationContainerBuilder import org.jetbrains.kotlin.fir.builder.FirBuilderDsl import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall -import org.jetbrains.kotlin.fir.types.ConeClassErrorType -import org.jetbrains.kotlin.fir.types.ConeKotlinType import org.jetbrains.kotlin.fir.types.FirErrorTypeRef -import org.jetbrains.kotlin.fir.types.FirTypeRef import org.jetbrains.kotlin.fir.types.impl.FirErrorTypeRefImpl -import org.jetbrains.kotlin.fir.visitors.* /* * This file was generated automatically diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/diagnostics/ConeSimpleDiagnostic.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/diagnostics/ConeSimpleDiagnostic.kt index ac7baa736da..74dcf02f424 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/diagnostics/ConeSimpleDiagnostic.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/diagnostics/ConeSimpleDiagnostic.kt @@ -7,12 +7,6 @@ package org.jetbrains.kotlin.fir.diagnostics class ConeSimpleDiagnostic(override val reason: String, val kind: DiagnosticKind = DiagnosticKind.Other) : ConeDiagnostic() -class ConeSimpleDiagnosticWithParameters1( - override val reason: String, - val a: A, - val kind: DiagnosticKind = DiagnosticKind.Other -) : ConeDiagnostic() - enum class DiagnosticKind { Syntax, ReturnNotAllowed, diff --git a/compiler/testData/diagnostics/tests/ObjectWithConstructor.fir.kt b/compiler/testData/diagnostics/tests/ObjectWithConstructor.fir.kt index 7ee1f433ccc..a54a650bf69 100644 --- a/compiler/testData/diagnostics/tests/ObjectWithConstructor.fir.kt +++ b/compiler/testData/diagnostics/tests/ObjectWithConstructor.fir.kt @@ -11,10 +11,10 @@ object A2 public constructor(private val prop: Int) { } val x = object (val prop: Int) { - constructor() : this(1) { + constructor() : this(1) { val x = 1 x * x - } + } } class A3 { diff --git a/compiler/tests-common/tests/org/jetbrains/kotlin/fir/AbstractFirBaseDiagnosticsTest.kt b/compiler/tests-common/tests/org/jetbrains/kotlin/fir/AbstractFirBaseDiagnosticsTest.kt index 1286d15707e..571ea9e70e1 100644 --- a/compiler/tests-common/tests/org/jetbrains/kotlin/fir/AbstractFirBaseDiagnosticsTest.kt +++ b/compiler/tests-common/tests/org/jetbrains/kotlin/fir/AbstractFirBaseDiagnosticsTest.kt @@ -24,6 +24,7 @@ import org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM import org.jetbrains.kotlin.diagnostics.PsiDiagnosticUtils import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnostic import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirPsiDiagnostic import org.jetbrains.kotlin.fir.builder.RawFirBuilder import org.jetbrains.kotlin.fir.declarations.FirFile import org.jetbrains.kotlin.fir.java.FirJavaModuleBasedSession @@ -196,7 +197,7 @@ abstract class AbstractFirBaseDiagnosticsTest : BaseDiagnosticsTest() { } protected fun TestFile.getActualText( - firDiagnostics: Iterable, + firDiagnostics: Iterable>, actualText: StringBuilder ): Boolean { val ktFile = this.ktFile @@ -308,9 +309,12 @@ abstract class AbstractFirBaseDiagnosticsTest : BaseDiagnosticsTest() { return ok[0] } - private fun Iterable.toActualDiagnostic(root: PsiElement): List { + private fun Iterable>.toActualDiagnostic(root: PsiElement): List { val result = mutableListOf() - filter { it.diagnostic.factory != FirErrors.SYNTAX_ERROR }.mapTo(result) { ActualDiagnostic(it.diagnostic, null, true) } + filter { it.factory != FirErrors.SYNTAX_ERROR }.mapTo(result) { + val oldDiagnostic = (it as FirPsiDiagnostic<*>).asPsiBasedDiagnostic() + ActualDiagnostic(oldDiagnostic, null, true) + } for (errorElement in AnalyzingUtils.getSyntaxErrorRanges(root)) { result.add(ActualDiagnostic(SyntaxErrorDiagnostic(errorElement), null, true)) } diff --git a/compiler/tests-common/tests/org/jetbrains/kotlin/fir/AbstractFirDiagnosticTest.kt b/compiler/tests-common/tests/org/jetbrains/kotlin/fir/AbstractFirDiagnosticTest.kt index 060e7f9993d..dd12f2b2e8f 100644 --- a/compiler/tests-common/tests/org/jetbrains/kotlin/fir/AbstractFirDiagnosticTest.kt +++ b/compiler/tests-common/tests/org/jetbrains/kotlin/fir/AbstractFirDiagnosticTest.kt @@ -85,8 +85,8 @@ abstract class AbstractFirDiagnosticsTest : AbstractFirBaseDiagnosticsTest() { if (firFile != null) { val session = firFile.session val collector = collectors.computeIfAbsent(session) { createCollector(session) } - val coneDiagnostics = collector.collectDiagnostics(firFile) - testFile.getActualText(coneDiagnostics, actualText) + val firDiagnostics = collector.collectDiagnostics(firFile) + testFile.getActualText(firDiagnostics, actualText) } else { actualText.append(testFile.expectedText) } diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/fir/FirIdeDiagnosticsCollector.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/fir/FirIdeDiagnosticsCollector.kt index 08a695a4c24..46ae2547937 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/fir/FirIdeDiagnosticsCollector.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/fir/FirIdeDiagnosticsCollector.kt @@ -8,9 +8,9 @@ package org.jetbrains.kotlin.idea.fir import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.analysis.collectors.AbstractDiagnosticCollector import org.jetbrains.kotlin.fir.analysis.collectors.registerAllComponents -import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnostic import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter -import org.jetbrains.kotlin.fir.psi +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnostic +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirPsiDiagnostic import org.jetbrains.kotlin.psi.KtElement class FirIdeDiagnosticsCollector(session: FirSession, private val resolveState: FirModuleResolveState) : AbstractDiagnosticCollector(session) { @@ -20,12 +20,11 @@ class FirIdeDiagnosticsCollector(session: FirSession, private val resolveState: } private inner class Reporter : DiagnosticReporter() { - override fun report(diagnostic: FirDiagnostic?) { - if (diagnostic == null) return - val psi = diagnostic.source.psi as? KtElement ?: return - resolveState.record(psi, diagnostic.diagnostic) + override fun report(diagnostic: FirDiagnostic<*>?) { + if (diagnostic !is FirPsiDiagnostic<*>) return + val psi = diagnostic.element.psi as? KtElement ?: return + resolveState.record(psi, diagnostic.asPsiBasedDiagnostic()) } - } private lateinit var reporter: Reporter @@ -34,7 +33,7 @@ class FirIdeDiagnosticsCollector(session: FirSession, private val resolveState: reporter = Reporter() } - override fun getCollectedDiagnostics(): Iterable { + override fun getCollectedDiagnostics(): Iterable> { // Not necessary in IDE return emptyList() } diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/fir/FirModuleResolveState.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/fir/FirModuleResolveState.kt index e6400ceabe6..7b157350d9c 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/fir/FirModuleResolveState.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/fir/FirModuleResolveState.kt @@ -12,9 +12,9 @@ import org.jetbrains.kotlin.diagnostics.Diagnostic import org.jetbrains.kotlin.fir.FirElement import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnostic +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirPsiDiagnostic import org.jetbrains.kotlin.fir.declarations.FirFile import org.jetbrains.kotlin.fir.java.FirProjectSessionProvider -import org.jetbrains.kotlin.fir.psi import org.jetbrains.kotlin.idea.caches.project.ModuleSourceInfo import org.jetbrains.kotlin.idea.caches.project.getModuleInfo import org.jetbrains.kotlin.psi.KtElement @@ -49,7 +49,7 @@ interface FirModuleResolveState { fun record(psi: KtElement, diagnostic: Diagnostic) - fun setDiagnosticsForFile(file: KtFile, fir: FirFile, diagnostics: Iterable = emptyList()) + fun setDiagnosticsForFile(file: KtFile, fir: FirFile, diagnostics: Iterable> = emptyList()) } class FirModuleResolveStateImpl(override val sessionProvider: FirProjectSessionProvider) : FirModuleResolveState { @@ -91,9 +91,11 @@ class FirModuleResolveStateImpl(override val sessionProvider: FirProjectSessionP list += diagnostic } - override fun setDiagnosticsForFile(file: KtFile, fir: FirFile, diagnostics: Iterable) { + override fun setDiagnosticsForFile(file: KtFile, fir: FirFile, diagnostics: Iterable>) { for (diagnostic in diagnostics) { - (diagnostic.source.psi as? KtElement)?.let { record(it, diagnostic.diagnostic) } + require(diagnostic is FirPsiDiagnostic<*>) + val psi = diagnostic.element.psi as? KtElement ?: continue + record(psi, diagnostic.asPsiBasedDiagnostic()) } diagnosedFiles[file] = file.modificationStamp