diff --git a/compiler/fir/lightTree/src/org/jetbrains/kotlin/fir/lightTree/converter/DeclarationsConverter.kt b/compiler/fir/lightTree/src/org/jetbrains/kotlin/fir/lightTree/converter/DeclarationsConverter.kt index 468cb7ad561..04817f9ad92 100644 --- a/compiler/fir/lightTree/src/org/jetbrains/kotlin/fir/lightTree/converter/DeclarationsConverter.kt +++ b/compiler/fir/lightTree/src/org/jetbrains/kotlin/fir/lightTree/converter/DeclarationsConverter.kt @@ -22,6 +22,7 @@ import org.jetbrains.kotlin.fir.builder.generateComponentFunctions import org.jetbrains.kotlin.fir.builder.generateCopyFunction import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.impl.* +import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind import org.jetbrains.kotlin.fir.diagnostics.FirSimpleDiagnostic import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.impl.* @@ -665,7 +666,7 @@ class DeclarationsConverter( } val delegatedSelfTypeRef = - if (classWrapper.isObjectLiteral()) FirErrorTypeRefImpl(null, FirSimpleDiagnostic("Constructor in object")) + if (classWrapper.isObjectLiteral()) FirErrorTypeRefImpl(null, FirSimpleDiagnostic("Constructor in object", DiagnosticKind.ConstructorInObject)) else classWrapper.delegatedSelfTypeRef val status = FirDeclarationStatusImpl(modifiers.getVisibility(), Modality.FINAL).apply { @@ -715,8 +716,8 @@ class DeclarationsConverter( val isThis = (isImplicit && classWrapper.hasPrimaryConstructor) || thisKeywordPresent val delegatedType = if (classWrapper.isObjectLiteral() || classWrapper.isInterface()) when { - isThis -> FirErrorTypeRefImpl(null, FirSimpleDiagnostic("Constructor in object")) - else -> FirErrorTypeRefImpl(null, FirSimpleDiagnostic("No super type")) + isThis -> FirErrorTypeRefImpl(null, FirSimpleDiagnostic("Constructor in object", , DiagnosticKind.ConstructorInObject)) + else -> FirErrorTypeRefImpl(null, FirSimpleDiagnostic("No super type", DiagnosticKind.Syntax)) } else when { isThis -> classWrapper.delegatedSelfTypeRef @@ -870,7 +871,7 @@ class DeclarationsConverter( private fun convertDestructingDeclaration(destructingDeclaration: LighterASTNode): DestructuringDeclaration { var isVar = false val entries = mutableListOf>() - var firExpression: FirExpression = FirErrorExpressionImpl(null, FirSimpleDiagnostic("Destructuring declaration without initializer")) + var firExpression: FirExpression = FirErrorExpressionImpl(null, FirSimpleDiagnostic("Destructuring declaration without initializer", DiagnosticKind.Syntax)) destructingDeclaration.forEachChildren { when (it.tokenType) { VAR_KEYWORD -> isVar = true @@ -1166,7 +1167,7 @@ class DeclarationsConverter( */ private fun convertExplicitDelegation(explicitDelegation: LighterASTNode): FirDelegatedTypeRef { lateinit var firTypeRef: FirTypeRef - var firExpression: FirExpression? = FirErrorExpressionImpl(null, FirSimpleDiagnostic("Should have delegate")) + var firExpression: FirExpression? = FirErrorExpressionImpl(null, FirSimpleDiagnostic("Should have delegate", DiagnosticKind.Syntax)) explicitDelegation.forEachChildren { when (it.tokenType) { TYPE_REFERENCE -> firTypeRef = convertType(it) @@ -1256,10 +1257,10 @@ class DeclarationsConverter( */ fun convertType(type: LighterASTNode): FirTypeRef { if (type.asText.isEmpty()) { - return FirErrorTypeRefImpl(null, FirSimpleDiagnostic("Unwrapped type is null")) + return FirErrorTypeRefImpl(null, FirSimpleDiagnostic("Unwrapped type is null", DiagnosticKind.Syntax)) } var typeModifiers = TypeModifier() //TODO what with suspend? - var firType: FirTypeRef = FirErrorTypeRefImpl(null, FirSimpleDiagnostic("Incomplete code")) + var firType: FirTypeRef = FirErrorTypeRefImpl(null, FirSimpleDiagnostic("Incomplete code", DiagnosticKind.Syntax)) var afterLPar = false type.forEachChildren { when (it.tokenType) { @@ -1270,7 +1271,7 @@ class DeclarationsConverter( NULLABLE_TYPE -> firType = convertNullableType(it) FUNCTION_TYPE -> firType = convertFunctionType(it) DYNAMIC_TYPE -> firType = FirDynamicTypeRefImpl(null, false) - TokenType.ERROR_ELEMENT -> firType = FirErrorTypeRefImpl(null, FirSimpleDiagnostic("Unwrapped type is null")) + TokenType.ERROR_ELEMENT -> firType = FirErrorTypeRefImpl(null, FirSimpleDiagnostic("Unwrapped type is null", DiagnosticKind.Syntax)) } } @@ -1325,7 +1326,7 @@ class DeclarationsConverter( } if (identifier == null) - return FirErrorTypeRefImpl(null, FirSimpleDiagnostic("Incomplete user type")) + return FirErrorTypeRefImpl(null, FirSimpleDiagnostic("Incomplete user type", DiagnosticKind.Syntax)) val qualifier = FirQualifierPartImpl( identifier.nameAsSafeName() 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 a7d7199df43..5ff6c58e760 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 @@ -20,6 +20,7 @@ import org.jetbrains.kotlin.fir.declarations.impl.FirAnonymousFunctionImpl import org.jetbrains.kotlin.fir.declarations.impl.FirDeclarationStatusImpl import org.jetbrains.kotlin.fir.declarations.impl.FirPropertyImpl import org.jetbrains.kotlin.fir.declarations.impl.FirValueParameterImpl +import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind import org.jetbrains.kotlin.fir.diagnostics.FirSimpleDiagnostic import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.impl.* @@ -57,7 +58,7 @@ class ExpressionsConverter( ) : BaseConverter(session, tree, context) { inline fun getAsFirExpression(expression: LighterASTNode?, errorReason: String = ""): R { - return expression?.let { convertExpression(it, errorReason) } as? R ?: (FirErrorExpressionImpl(null, FirSimpleDiagnostic(errorReason)) as R) + return expression?.let { convertExpression(it, errorReason) } as? R ?: (FirErrorExpressionImpl(null, FirSimpleDiagnostic(errorReason, DiagnosticKind.Syntax)) as R) } /***** EXPRESSIONS *****/ @@ -105,7 +106,7 @@ class ExpressionsConverter( OBJECT_LITERAL -> declarationsConverter.convertObjectLiteral(expression) FUN -> declarationsConverter.convertFunctionDeclaration(expression) - else -> FirErrorExpressionImpl(null, FirSimpleDiagnostic(errorReason)) + else -> FirErrorExpressionImpl(null, FirSimpleDiagnostic(errorReason, DiagnosticKind.Syntax)) } } @@ -159,7 +160,7 @@ class ExpressionsConverter( FirLabelImpl(null, it.asString()) } val bodyExpression = block?.let { declarationsConverter.convertBlockExpression(it) } - ?: FirErrorExpressionImpl(null, FirSimpleDiagnostic("Lambda has no body")) + ?: FirErrorExpressionImpl(null, FirSimpleDiagnostic("Lambda has no body", DiagnosticKind.Syntax)) body = if (bodyExpression is FirBlockImpl) { if (bodyExpression.statements.isEmpty()) { bodyExpression.statements.add(FirUnitExpression(null)) @@ -186,7 +187,7 @@ class ExpressionsConverter( var isLeftArgument = true lateinit var operationTokenName: String var leftArgNode: LighterASTNode? = null - var rightArgAsFir: FirExpression = FirErrorExpressionImpl(null, FirSimpleDiagnostic("No right operand")) + var rightArgAsFir: FirExpression = FirErrorExpressionImpl(null, FirSimpleDiagnostic("No right operand", DiagnosticKind.Syntax)) binaryExpression.forEachChildren { when (it.tokenType) { OPERATION_REFERENCE -> { @@ -250,7 +251,7 @@ class ExpressionsConverter( toFirOperation: String.() -> FirOperation ): FirTypeOperatorCall { lateinit var operationTokenName: String - var leftArgAsFir: FirExpression = FirErrorExpressionImpl(null, FirSimpleDiagnostic("No left operand")) + var leftArgAsFir: FirExpression = FirErrorExpressionImpl(null, FirSimpleDiagnostic("No left operand", DiagnosticKind.Syntax)) lateinit var firType: FirTypeRef binaryExpression.forEachChildren { when (it.tokenType) { @@ -286,7 +287,7 @@ class ExpressionsConverter( context.firLabels.removeLast() //println("Unused label: ${labeledExpression.getAsString()}") } - return firExpression ?: FirErrorExpressionImpl(null, FirSimpleDiagnostic("Empty label")) + return firExpression ?: FirErrorExpressionImpl(null, FirSimpleDiagnostic("Empty label", DiagnosticKind.Syntax)) } /** @@ -348,7 +349,7 @@ class ExpressionsConverter( return (firExpression as? FirAbstractAnnotatedElement)?.apply { annotations += firAnnotationList - } ?: FirErrorExpressionImpl(null, FirSimpleDiagnostic("Strange annotated expression: ${firExpression?.render()}")) + } ?: FirErrorExpressionImpl(null, FirSimpleDiagnostic("Strange annotated expression: ${firExpression?.render()}", DiagnosticKind.Syntax)) } /** @@ -356,7 +357,7 @@ class ExpressionsConverter( * @see org.jetbrains.kotlin.fir.builder.RawFirBuilder.Visitor.visitClassLiteralExpression */ private fun convertClassLiteralExpression(classLiteralExpression: LighterASTNode): FirExpression { - var firReceiverExpression: FirExpression = FirErrorExpressionImpl(null, FirSimpleDiagnostic("No receiver in class literal")) + var firReceiverExpression: FirExpression = FirErrorExpressionImpl(null, FirSimpleDiagnostic("No receiver in class literal", DiagnosticKind.Syntax)) classLiteralExpression.forEachChildren { if (it.isExpression()) firReceiverExpression = getAsFirExpression(it, "No receiver in class literal") } @@ -400,7 +401,7 @@ class ExpressionsConverter( private fun convertQualifiedExpression(dotQualifiedExpression: LighterASTNode): FirExpression { var isSelector = false var isSafe = false - var firSelector: FirExpression = FirErrorExpressionImpl(null, FirSimpleDiagnostic("Qualified expression without selector")) //after dot + var firSelector: FirExpression = FirErrorExpressionImpl(null, FirSimpleDiagnostic("Qualified expression without selector", DiagnosticKind.Syntax)) //after dot var firReceiver: FirExpression? = null //before dot dotQualifiedExpression.forEachChildren { when (it.tokenType) { @@ -450,7 +451,7 @@ class ExpressionsConverter( arguments += additionalArgument!! FirSimpleNamedReference(null, OperatorNameConventions.INVOKE, null) } - else -> FirErrorNamedReferenceImpl(null, FirSimpleDiagnostic("Call has no callee")) + else -> FirErrorNamedReferenceImpl(null, FirSimpleDiagnostic("Call has no callee", DiagnosticKind.Syntax)) } context.firFunctionCalls += this @@ -468,7 +469,7 @@ class ExpressionsConverter( } private fun LighterASTNode?.convertShortOrLongStringTemplate(errorReason: String): FirExpression { - var firExpression: FirExpression = FirErrorExpressionImpl(null, FirSimpleDiagnostic(errorReason)) + var firExpression: FirExpression = FirErrorExpressionImpl(null, FirSimpleDiagnostic(errorReason, DiagnosticKind.Syntax)) this?.forEachChildren(LONG_TEMPLATE_ENTRY_START, LONG_TEMPLATE_ENTRY_END) { firExpression = getAsFirExpression(it, errorReason) } @@ -564,7 +565,7 @@ class ExpressionsConverter( } private fun convertWhenConditionExpression(whenCondition: LighterASTNode): FirExpression { - var firExpression: FirExpression = FirErrorExpressionImpl(null, FirSimpleDiagnostic("No expression in condition with expression")) + var firExpression: FirExpression = FirErrorExpressionImpl(null, FirSimpleDiagnostic("No expression in condition with expression", DiagnosticKind.Syntax)) whenCondition.forEachChildren { when (it.tokenType) { else -> if (it.isExpression()) firExpression = getAsFirExpression(it, "No expression in condition with expression") @@ -578,7 +579,7 @@ class ExpressionsConverter( private fun convertWhenConditionInRange(whenCondition: LighterASTNode): FirExpression { var isNegate = false - var firExpression: FirExpression = FirErrorExpressionImpl(null, FirSimpleDiagnostic("No range in condition with range")) + var firExpression: FirExpression = FirErrorExpressionImpl(null, FirSimpleDiagnostic("No range in condition with range", DiagnosticKind.Syntax)) whenCondition.forEachChildren { when (it.tokenType) { NOT_IN -> isNegate = true @@ -612,7 +613,7 @@ class ExpressionsConverter( * @see org.jetbrains.kotlin.fir.builder.RawFirBuilder.Visitor.visitArrayAccessExpression */ private fun convertArrayAccessExpression(arrayAccess: LighterASTNode): FirFunctionCall { - var firExpression: FirExpression = FirErrorExpressionImpl(null, FirSimpleDiagnostic("No array expression")) + var firExpression: FirExpression = FirErrorExpressionImpl(null, FirSimpleDiagnostic("No array expression", DiagnosticKind.Syntax)) val indices: MutableList = mutableListOf() arrayAccess.forEachChildren { when (it.tokenType) { @@ -670,7 +671,7 @@ class ExpressionsConverter( */ private fun convertDoWhile(doWhileLoop: LighterASTNode): FirElement { var block: LighterASTNode? = null - var firCondition: FirExpression = FirErrorExpressionImpl(null, FirSimpleDiagnostic("No condition in do-while loop")) + var firCondition: FirExpression = FirErrorExpressionImpl(null, FirSimpleDiagnostic("No condition in do-while loop", DiagnosticKind.Syntax)) doWhileLoop.forEachChildren { when (it.tokenType) { BODY -> block = it @@ -687,7 +688,7 @@ class ExpressionsConverter( */ private fun convertWhile(whileLoop: LighterASTNode): FirElement { var block: LighterASTNode? = null - var firCondition: FirExpression = FirErrorExpressionImpl(null, FirSimpleDiagnostic("No condition in while loop")) + var firCondition: FirExpression = FirErrorExpressionImpl(null, FirSimpleDiagnostic("No condition in while loop", DiagnosticKind.Syntax)) whileLoop.forEachChildren { when (it.tokenType) { BODY -> block = it @@ -704,7 +705,7 @@ class ExpressionsConverter( */ private fun convertFor(forLoop: LighterASTNode): FirElement { var parameter: ValueParameter? = null - var rangeExpression: FirExpression = FirErrorExpressionImpl(null, FirSimpleDiagnostic("No range in for loop")) + var rangeExpression: FirExpression = FirErrorExpressionImpl(null, FirSimpleDiagnostic("No range in for loop", DiagnosticKind.Syntax)) var blockNode: LighterASTNode? = null forLoop.forEachChildren { when (it.tokenType) { @@ -847,7 +848,7 @@ class ExpressionsConverter( * @see org.jetbrains.kotlin.fir.builder.RawFirBuilder.Visitor.visitIfExpression */ private fun convertIfExpression(ifExpression: LighterASTNode): FirExpression { - var firCondition: FirExpression = FirErrorExpressionImpl(null, FirSimpleDiagnostic("If statement should have condition")) + var firCondition: FirExpression = FirErrorExpressionImpl(null, FirSimpleDiagnostic("If statement should have condition", DiagnosticKind.Syntax)) var thenBlock: LighterASTNode? = null var elseBlock: LighterASTNode? = null ifExpression.forEachChildren { @@ -909,7 +910,7 @@ class ExpressionsConverter( * @see org.jetbrains.kotlin.fir.builder.RawFirBuilder.Visitor.visitThrowExpression */ private fun convertThrow(throwExpression: LighterASTNode): FirExpression { - var firExpression: FirExpression = FirErrorExpressionImpl(null, FirSimpleDiagnostic("Nothing to throw")) + var firExpression: FirExpression = FirErrorExpressionImpl(null, FirSimpleDiagnostic("Nothing to throw", DiagnosticKind.Syntax)) throwExpression.forEachChildren { if (it.isExpression()) firExpression = getAsFirExpression(it, "Nothing to throw") } @@ -964,7 +965,7 @@ class ExpressionsConverter( private fun convertValueArgument(valueArgument: LighterASTNode): FirExpression { var identifier: String? = null var isSpread = false - var firExpression: FirExpression = FirErrorExpressionImpl(null, FirSimpleDiagnostic("Argument is absent")) + var firExpression: FirExpression = FirErrorExpressionImpl(null, FirSimpleDiagnostic("Argument is absent", DiagnosticKind.Syntax)) valueArgument.forEachChildren { when (it.tokenType) { VALUE_ARGUMENT_NAME -> identifier = it.asText diff --git a/compiler/fir/lightTree/src/org/jetbrains/kotlin/fir/lightTree/fir/ValueParameter.kt b/compiler/fir/lightTree/src/org/jetbrains/kotlin/fir/lightTree/fir/ValueParameter.kt index c7daa222e99..b5c6bdc89a6 100644 --- a/compiler/fir/lightTree/src/org/jetbrains/kotlin/fir/lightTree/fir/ValueParameter.kt +++ b/compiler/fir/lightTree/src/org/jetbrains/kotlin/fir/lightTree/fir/ValueParameter.kt @@ -12,6 +12,7 @@ import org.jetbrains.kotlin.fir.declarations.impl.FirDeclarationStatusImpl import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyGetter import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertySetter import org.jetbrains.kotlin.fir.declarations.impl.FirPropertyImpl +import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind import org.jetbrains.kotlin.fir.diagnostics.FirSimpleDiagnostic import org.jetbrains.kotlin.fir.expressions.impl.FirQualifiedAccessExpressionImpl import org.jetbrains.kotlin.fir.lightTree.fir.modifier.Modifier @@ -36,7 +37,7 @@ class ValueParameter( val name = this.firValueParameter.name var type = this.firValueParameter.returnTypeRef if (type is FirImplicitTypeRef) { - type = FirErrorTypeRefImpl(null, FirSimpleDiagnostic("Incomplete code")) + type = FirErrorTypeRefImpl(null, FirSimpleDiagnostic("Incomplete code", DiagnosticKind.Syntax)) } val status = FirDeclarationStatusImpl(modifiers.getVisibility(), modifiers.getModality()).apply { diff --git a/compiler/fir/lightTree/src/org/jetbrains/kotlin/fir/lightTree/fir/WhenEntry.kt b/compiler/fir/lightTree/src/org/jetbrains/kotlin/fir/lightTree/fir/WhenEntry.kt index 06e9953e1f3..3b833de2a30 100644 --- a/compiler/fir/lightTree/src/org/jetbrains/kotlin/fir/lightTree/fir/WhenEntry.kt +++ b/compiler/fir/lightTree/src/org/jetbrains/kotlin/fir/lightTree/fir/WhenEntry.kt @@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.lightTree.fir import org.jetbrains.kotlin.fir.FirWhenSubject import org.jetbrains.kotlin.fir.builder.generateContainsOperation import org.jetbrains.kotlin.fir.builder.generateLazyLogicalOperation +import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind import org.jetbrains.kotlin.fir.diagnostics.FirSimpleDiagnostic import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.impl.FirErrorExpressionImpl @@ -52,7 +53,7 @@ data class WhenEntry( } } else -> { - FirErrorExpressionImpl(null, FirSimpleDiagnostic("Unsupported when condition: ${this.javaClass}")) + FirErrorExpressionImpl(null, FirSimpleDiagnostic("Unsupported when condition: ${this.javaClass}", DiagnosticKind.Syntax)) } } } @@ -60,7 +61,7 @@ data class WhenEntry( fun toFirWhenConditionWithoutSubject(): FirExpression { return when (val condition = conditions.first()) { is FirOperatorCallImpl -> condition.arguments.first() - else -> FirErrorExpressionImpl(null, FirSimpleDiagnostic("No expression in condition with expression")) + else -> FirErrorExpressionImpl(null, FirSimpleDiagnostic("No expression in condition with expression", DiagnosticKind.Syntax)) } } } \ No newline at end of file diff --git a/compiler/fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/BaseFirBuilder.kt b/compiler/fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/BaseFirBuilder.kt index 1e499e2a878..bb2471f7997 100644 --- a/compiler/fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/BaseFirBuilder.kt +++ b/compiler/fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/BaseFirBuilder.kt @@ -12,7 +12,7 @@ import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.impl.FirErrorFunctionImpl import org.jetbrains.kotlin.fir.declarations.impl.FirTypeParameterImpl -import org.jetbrains.kotlin.fir.diagnostics.FirSimpleDiagnostic +import org.jetbrains.kotlin.fir.diagnostics.* import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.impl.* import org.jetbrains.kotlin.fir.references.FirReference @@ -111,7 +111,7 @@ abstract class BaseFirBuilder(val session: FirSession, val context: Context = FirErrorFunctionImpl( source, this@BaseFirBuilder.session, - FirSimpleDiagnostic("Cannot bind unlabeled return to a function"), + FirSimpleDiagnostic("Cannot bind unlabeled return to a function", DiagnosticKind.ReturnNotAllowed), FirErrorFunctionSymbol() ) ) @@ -137,7 +137,7 @@ abstract class BaseFirBuilder(val session: FirSession, val context: Context = FirErrorFunctionImpl( source, this@BaseFirBuilder.session, - FirSimpleDiagnostic("Cannot bind label $labelName to a function"), + FirSimpleDiagnostic("Cannot bind label $labelName to a function", DiagnosticKind.UnresolvedLabel), FirErrorFunctionSymbol() ) ) @@ -197,7 +197,7 @@ abstract class BaseFirBuilder(val session: FirSession, val context: Context = if (lastLoop != null) { target.bind(lastLoop) } else { - target.bind(FirErrorLoop(expression.getSourceOrNull(), "Cannot bind unlabeled jump to a loop")) + target.bind(FirErrorLoop(expression.getSourceOrNull(), FirSimpleDiagnostic("Cannot bind unlabeled jump to a loop", DiagnosticKind.Syntax))) } } else { for (firLoop in context.firLoops.asReversed()) { @@ -206,7 +206,7 @@ abstract class BaseFirBuilder(val session: FirSession, val context: Context = return this } } - target.bind(FirErrorLoop(expression.getSourceOrNull(), "Cannot bind label $labelName to a loop")) + target.bind(FirErrorLoop(expression.getSourceOrNull(), FirSimpleDiagnostic("Cannot bind label $labelName to a loop", DiagnosticKind.Syntax))) } return this } @@ -231,29 +231,29 @@ abstract class BaseFirBuilder(val session: FirSession, val context: Context = convertedText > Int.MAX_VALUE || convertedText < Int.MIN_VALUE) ) { FirConstExpressionImpl( - expression.getSourceOrNull(), IrConstKind.Long, convertedText, "Incorrect long: $text" + expression.getSourceOrNull(), IrConstKind.Long, convertedText, FirSimpleDiagnostic("Incorrect long: $text", DiagnosticKind.Syntax) ) } else if (convertedText is Number) { // TODO: support byte / short FirConstExpressionImpl( - expression.getSourceOrNull(), IrConstKind.Int, convertedText.toInt(), "Incorrect int: $text" + expression.getSourceOrNull(), IrConstKind.Int, convertedText.toInt(), FirSimpleDiagnostic("Incorrect int: $text", DiagnosticKind.Syntax) ) } else { - FirErrorExpressionImpl(expression.getSourceOrNull(), diagnostic = FirSimpleDiagnostic("Incorrect constant expression: $text")) + FirErrorExpressionImpl(expression.getSourceOrNull(), FirSimpleDiagnostic("Incorrect constant expression: $text", DiagnosticKind.IllegalConstExpression)) } FLOAT_CONSTANT -> if (convertedText is Float) { FirConstExpressionImpl( - expression.getSourceOrNull(), IrConstKind.Float, convertedText, "Incorrect float: $text" + expression.getSourceOrNull(), IrConstKind.Float, convertedText, FirSimpleDiagnostic("Incorrect float: $text", DiagnosticKind.Syntax) ) } else { FirConstExpressionImpl( - expression.getSourceOrNull(), IrConstKind.Double, convertedText as Double, "Incorrect double: $text" + expression.getSourceOrNull(), IrConstKind.Double, convertedText as Double, FirSimpleDiagnostic("Incorrect double: $text", DiagnosticKind.Syntax) ) } CHARACTER_CONSTANT -> FirConstExpressionImpl( - expression.getSourceOrNull(), IrConstKind.Char, text.parseCharacter(), "Incorrect character: $text" + expression.getSourceOrNull(), IrConstKind.Char, text.parseCharacter(), FirSimpleDiagnostic("Incorrect character: $text", DiagnosticKind.Syntax) ) BOOLEAN_CONSTANT -> FirConstExpressionImpl(expression.getSourceOrNull(), IrConstKind.Boolean, convertedText as Boolean) @@ -291,7 +291,7 @@ abstract class BaseFirBuilder(val session: FirSession, val context: Context = else -> { hasExpressions = true FirErrorExpressionImpl( - entry.getSourceOrNull(), FirSimpleDiagnostic("Incorrect template entry: ${entry.asText}") + entry.getSourceOrNull(), FirSimpleDiagnostic("Incorrect template entry: ${entry.asText}", DiagnosticKind.Syntax) ) } } @@ -344,7 +344,7 @@ abstract class BaseFirBuilder(val session: FirSession, val context: Context = convert: T.() -> FirExpression ): FirExpression { if (argument == null) { - return FirErrorExpressionImpl(argument, FirSimpleDiagnostic("Inc/dec without operand")) + return FirErrorExpressionImpl(argument, FirSimpleDiagnostic("Inc/dec without operand", DiagnosticKind.Syntax)) } val source = baseExpression?.toFirSourceElement() return FirBlockImpl(source).apply { @@ -411,7 +411,7 @@ abstract class BaseFirBuilder(val session: FirSession, val context: Context = firMemberAccess.calleeReference } else { FirErrorNamedReferenceImpl( - left.getSourceOrNull(), FirSimpleDiagnostic("Unsupported qualified LValue: ${left.asText}") + left.getSourceOrNull(), FirSimpleDiagnostic("Unsupported qualified LValue: ${left.asText}", DiagnosticKind.Syntax) ) } } @@ -420,7 +420,7 @@ abstract class BaseFirBuilder(val session: FirSession, val context: Context = } } } - return FirErrorNamedReferenceImpl(left.getSourceOrNull(), FirSimpleDiagnostic("Unsupported LValue: $tokenType")) + return FirErrorNamedReferenceImpl(left.getSourceOrNull(), FirSimpleDiagnostic("Unsupported LValue: $tokenType", DiagnosticKind.Syntax)) } fun T?.generateAssignment( @@ -469,7 +469,7 @@ abstract class BaseFirBuilder(val session: FirSession, val context: Context = statements += generateTemporaryVariable( this@BaseFirBuilder.session, this@generateAssignment.getSourceOrNull(), name, this@generateAssignment?.convert() - ?: FirErrorExpressionImpl(this.getSourceOrNull(), FirSimpleDiagnostic("No LValue in assignment")) + ?: FirErrorExpressionImpl(this.getSourceOrNull(), FirSimpleDiagnostic("No LValue in assignment", DiagnosticKind.Syntax)) ) statements += FirVariableAssignmentImpl(source, false, value, operation).apply { lValue = FirSimpleNamedReference(this.getSourceOrNull(), name, null) @@ -480,7 +480,7 @@ abstract class BaseFirBuilder(val session: FirSession, val context: Context = if (operation in FirOperation.ASSIGNMENTS && operation != FirOperation.ASSIGN) { return FirOperatorCallImpl(source, operation).apply { // TODO: take good psi - arguments += this@generateAssignment?.convert() ?: FirErrorExpressionImpl(null, FirSimpleDiagnostic("Unsupported left value of assignment: ${source?.psi?.text}")) + arguments += this@generateAssignment?.convert() ?: FirErrorExpressionImpl(null, FirSimpleDiagnostic("Unsupported left value of assignment: ${source?.psi?.text}", DiagnosticKind.Syntax)) arguments += value } } diff --git a/compiler/fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/ConversionUtils.kt b/compiler/fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/ConversionUtils.kt index 1faed478de9..80c286fd3cf 100644 --- a/compiler/fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/ConversionUtils.kt +++ b/compiler/fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/ConversionUtils.kt @@ -11,6 +11,7 @@ import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.declarations.FirVariable import org.jetbrains.kotlin.fir.declarations.impl.* +import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind import org.jetbrains.kotlin.fir.diagnostics.FirSimpleDiagnostic import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.impl.* @@ -201,7 +202,7 @@ internal fun KtWhenCondition.toFirWhenCondition( } } else -> { - FirErrorExpressionImpl(this.toFirSourceElement(), FirSimpleDiagnostic("Unsupported when condition: ${this.javaClass}")) + FirErrorExpressionImpl(this.toFirSourceElement(), FirSimpleDiagnostic("Unsupported when condition: ${this.javaClass}", DiagnosticKind.Syntax)) } } } 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 e5f9ecb7c58..894dbd77116 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 @@ -14,6 +14,7 @@ import org.jetbrains.kotlin.descriptors.Visibility import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.impl.* +import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind import org.jetbrains.kotlin.fir.diagnostics.FirSimpleDiagnostic import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.impl.* @@ -106,21 +107,21 @@ class RawFirBuilder(session: FirSession, val stubMode: Boolean) : BaseFirBuilder convertSafe() ?: implicitUnitType private fun KtTypeReference?.toFirOrErrorType(): FirTypeRef = - convertSafe() ?: FirErrorTypeRefImpl(this?.toFirSourceElement(), FirSimpleDiagnostic(if (this == null) "Incomplete code" else "Conversion failed")) + convertSafe() ?: FirErrorTypeRefImpl(this?.toFirSourceElement(), FirSimpleDiagnostic(if (this == null) "Incomplete code" else "Conversion failed", DiagnosticKind.Syntax)) // Here we accept lambda as receiver to prevent expression calculation in stub mode private fun (() -> KtExpression?).toFirExpression(errorReason: String): FirExpression = if (stubMode) FirExpressionStub(null) else with(this()) { - convertSafe() ?: FirErrorExpressionImpl(this?.toFirSourceElement(), FirSimpleDiagnostic(errorReason)) + convertSafe() ?: FirErrorExpressionImpl(this?.toFirSourceElement(), FirSimpleDiagnostic(errorReason, DiagnosticKind.Syntax)) } private fun KtExpression?.toFirExpression(errorReason: String): FirExpression = if (stubMode) FirExpressionStub(null) - else convertSafe() ?: FirErrorExpressionImpl(this?.toFirSourceElement(), FirSimpleDiagnostic(errorReason)) + else convertSafe() ?: FirErrorExpressionImpl(this?.toFirSourceElement(), FirSimpleDiagnostic(errorReason, DiagnosticKind.Syntax)) private fun KtExpression.toFirStatement(errorReason: String): FirStatement = - convertSafe() ?: FirErrorExpressionImpl(this.toFirSourceElement(), FirSimpleDiagnostic(errorReason)) + convertSafe() ?: FirErrorExpressionImpl(this.toFirSourceElement(), FirSimpleDiagnostic(errorReason, DiagnosticKind.Syntax)) private fun KtExpression.toFirStatement(): FirStatement = convert() @@ -131,7 +132,7 @@ class RawFirBuilder(session: FirSession, val stubMode: Boolean) : BaseFirBuilder return when (this) { is KtSecondaryConstructor -> toFirConstructor( delegatedSuperType, - delegatedSelfType ?: FirErrorTypeRefImpl(this.toFirSourceElement(), FirSimpleDiagnostic("Constructor in object")), + delegatedSelfType ?: FirErrorTypeRefImpl(this.toFirSourceElement(), FirSimpleDiagnostic("Constructor in object", DiagnosticKind.ConstructorInObject)), owner, hasPrimaryConstructor ) @@ -166,7 +167,7 @@ class RawFirBuilder(session: FirSession, val stubMode: Boolean) : BaseFirBuilder } private fun ValueArgument?.toFirExpression(): FirExpression { - this ?: return FirErrorExpressionImpl((this as? KtElement)?.toFirSourceElement(), FirSimpleDiagnostic("No argument given")) + this ?: return FirErrorExpressionImpl((this as? KtElement)?.toFirSourceElement(), FirSimpleDiagnostic("No argument given", DiagnosticKind.Syntax)) val name = this.getArgumentName()?.asName val expression = this.getArgumentExpression() val firExpression = when (expression) { @@ -719,7 +720,7 @@ class RawFirBuilder(session: FirSession, val stubMode: Boolean) : BaseFirBuilder val source = this.toFirSourceElement() val delegatedType = when { isThis -> delegatedSelfTypeRef - else -> delegatedSuperTypeRef ?: FirErrorTypeRefImpl(source, FirSimpleDiagnostic("No super type")) + else -> delegatedSuperTypeRef ?: FirErrorTypeRefImpl(source, FirSimpleDiagnostic("No super type", DiagnosticKind.Syntax)) } return FirDelegatedConstructorCallImpl( source, @@ -838,7 +839,7 @@ class RawFirBuilder(session: FirSession, val stubMode: Boolean) : BaseFirBuilder userType } else { - FirErrorTypeRefImpl(source, FirSimpleDiagnostic("Incomplete user type")) + FirErrorTypeRefImpl(source, FirSimpleDiagnostic("Incomplete user type", DiagnosticKind.Syntax)) } } is KtFunctionType -> { @@ -857,7 +858,7 @@ class RawFirBuilder(session: FirSession, val stubMode: Boolean) : BaseFirBuilder } functionType } - null -> FirErrorTypeRefImpl(source, FirSimpleDiagnostic("Unwrapped type is null")) + null -> FirErrorTypeRefImpl(source, FirSimpleDiagnostic("Unwrapped type is null", DiagnosticKind.Syntax)) else -> throw AssertionError("Unexpected type element: ${unwrappedElement.text}") } @@ -1231,7 +1232,7 @@ class RawFirBuilder(session: FirSession, val stubMode: Boolean) : BaseFirBuilder calleeExpression.toFirSourceElement(), calleeExpression.getReferencedNameAsName(), null ) null -> FirErrorNamedReferenceImpl( - null, FirSimpleDiagnostic("Call has no callee") + null, FirSimpleDiagnostic("Call has no callee", DiagnosticKind.Syntax) ) else -> { arguments += calleeExpression.toFirExpression("Incorrect invoke receiver") @@ -1264,7 +1265,7 @@ class RawFirBuilder(session: FirSession, val stubMode: Boolean) : BaseFirBuilder override fun visitQualifiedExpression(expression: KtQualifiedExpression, data: Unit): FirElement { val selector = expression.selectorExpression - ?: return FirErrorExpressionImpl(expression.toFirSourceElement(), FirSimpleDiagnostic("Qualified expression without selector")) + ?: return FirErrorExpressionImpl(expression.toFirSourceElement(), FirSimpleDiagnostic("Qualified expression without selector", DiagnosticKind.Syntax)) val firSelector = selector.toFirExpression("Incorrect selector expression") if (firSelector is FirModifiableQualifiedAccess) { firSelector.safe = expression is KtSafeQualifiedExpression @@ -1288,7 +1289,7 @@ class RawFirBuilder(session: FirSession, val stubMode: Boolean) : BaseFirBuilder } override fun visitParenthesizedExpression(expression: KtParenthesizedExpression, data: Unit): FirElement { - return expression.expression?.accept(this, data) ?: FirErrorExpressionImpl(expression.toFirSourceElement(), FirSimpleDiagnostic("Empty parentheses")) + return expression.expression?.accept(this, data) ?: FirErrorExpressionImpl(expression.toFirSourceElement(), FirSimpleDiagnostic("Empty parentheses", DiagnosticKind.Syntax)) } override fun visitLabeledExpression(expression: KtLabeledExpression, data: Unit): FirElement { @@ -1298,7 +1299,7 @@ class RawFirBuilder(session: FirSession, val stubMode: Boolean) : BaseFirBuilder if (labelName != null) { context.firLabels += FirLabelImpl(source, labelName) } - val result = expression.baseExpression?.accept(this, data) ?: FirErrorExpressionImpl(source, FirSimpleDiagnostic("Empty label")) + val result = expression.baseExpression?.accept(this, data) ?: FirErrorExpressionImpl(source, FirSimpleDiagnostic("Empty label", DiagnosticKind.Syntax)) if (size != context.firLabels.size) { context.firLabels.removeLast() println("Unused label: ${expression.text}") @@ -1309,7 +1310,7 @@ class RawFirBuilder(session: FirSession, val stubMode: Boolean) : BaseFirBuilder override fun visitAnnotatedExpression(expression: KtAnnotatedExpression, data: Unit): FirElement { val rawResult = expression.baseExpression?.accept(this, data) val result = rawResult as? FirAbstractAnnotatedElement - ?: FirErrorExpressionImpl(expression.toFirSourceElement(), FirSimpleDiagnostic("Strange annotated expression: ${rawResult?.render()}")) + ?: FirErrorExpressionImpl(expression.toFirSourceElement(), FirSimpleDiagnostic("Strange annotated expression: ${rawResult?.render()}", DiagnosticKind.Syntax)) expression.extractAnnotationsTo(result) return result } diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/diagnostics/FirSimpleDiagnostic.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/diagnostics/FirSimpleDiagnostic.kt index f572410c6f2..1c802b21424 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/diagnostics/FirSimpleDiagnostic.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/diagnostics/FirSimpleDiagnostic.kt @@ -5,4 +5,13 @@ package org.jetbrains.kotlin.fir.diagnostics -class FirSimpleDiagnostic(override val reason: String) : FirDiagnostic() \ No newline at end of file +class FirSimpleDiagnostic(override val reason: String, val kind: DiagnosticKind = DiagnosticKind.Other) : FirDiagnostic() + +enum class DiagnosticKind { + Syntax, + ReturnNotAllowed, + UnresolvedLabel, + IllegalConstExpression, + ConstructorInObject, + Other +} \ No newline at end of file diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/expressions/FirExpressionUtil.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/expressions/FirExpressionUtil.kt index 7616414f9ee..f2b099dc53c 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/expressions/FirExpressionUtil.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/expressions/FirExpressionUtil.kt @@ -6,6 +6,7 @@ package org.jetbrains.kotlin.fir.expressions import org.jetbrains.kotlin.fir.FirSourceElement +import org.jetbrains.kotlin.fir.diagnostics.FirDiagnostic import org.jetbrains.kotlin.fir.diagnostics.FirSimpleDiagnostic import org.jetbrains.kotlin.fir.expressions.impl.FirConstExpressionImpl import org.jetbrains.kotlin.fir.expressions.impl.FirErrorExpressionImpl @@ -24,8 +25,8 @@ inline val FirAnnotationCall.coneClassLikeType: ConeClassLikeType? inline val FirAnnotationCall.classId: ClassId? get() = coneClassLikeType?.lookupTag?.classId -fun FirConstExpressionImpl(source: FirSourceElement?, kind: IrConstKind, value: T?, errorReason: String): FirExpression = - value?.let { FirConstExpressionImpl(source, kind, it) } ?: FirErrorExpressionImpl(source, FirSimpleDiagnostic(errorReason)) +fun FirConstExpressionImpl(source: FirSourceElement?, kind: IrConstKind, value: T?, diagnostic: FirDiagnostic): FirExpression = + value?.let { FirConstExpressionImpl(source, kind, it) } ?: FirErrorExpressionImpl(source, diagnostic) inline val FirTypeOperatorCall.argument: FirExpression get() = arguments.first() @@ -37,8 +38,7 @@ fun FirExpression.toResolvedCallableSymbol(): FirCallableSymbol<*>? { return toResolvedCallableReference()?.resolvedSymbol as FirCallableSymbol<*>? } -fun FirErrorLoop(source: FirSourceElement?, reason: String): FirErrorLoop { - val diagnostic = FirSimpleDiagnostic(reason) +fun FirErrorLoop(source: FirSourceElement?, diagnostic: FirDiagnostic): FirErrorLoop { return FirErrorLoopImpl(source, diagnostic).apply { condition = FirErrorExpressionImpl(source, diagnostic) }