[FIR] Add kind to diagnostics reported by RawFirBuilder

This commit is contained in:
Dmitriy Novozhilov
2019-10-31 12:16:31 +03:00
parent 8b5f568a15
commit 7503449e8d
9 changed files with 84 additions and 69 deletions
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.fir.builder.generateComponentFunctions
import org.jetbrains.kotlin.fir.builder.generateCopyFunction import org.jetbrains.kotlin.fir.builder.generateCopyFunction
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.impl.* 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.diagnostics.FirSimpleDiagnostic
import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.expressions.impl.* import org.jetbrains.kotlin.fir.expressions.impl.*
@@ -665,7 +666,7 @@ class DeclarationsConverter(
} }
val delegatedSelfTypeRef = 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 else classWrapper.delegatedSelfTypeRef
val status = FirDeclarationStatusImpl(modifiers.getVisibility(), Modality.FINAL).apply { val status = FirDeclarationStatusImpl(modifiers.getVisibility(), Modality.FINAL).apply {
@@ -715,8 +716,8 @@ class DeclarationsConverter(
val isThis = (isImplicit && classWrapper.hasPrimaryConstructor) || thisKeywordPresent val isThis = (isImplicit && classWrapper.hasPrimaryConstructor) || thisKeywordPresent
val delegatedType = val delegatedType =
if (classWrapper.isObjectLiteral() || classWrapper.isInterface()) when { if (classWrapper.isObjectLiteral() || classWrapper.isInterface()) when {
isThis -> FirErrorTypeRefImpl(null, FirSimpleDiagnostic("Constructor in object")) isThis -> FirErrorTypeRefImpl(null, FirSimpleDiagnostic("Constructor in object", , DiagnosticKind.ConstructorInObject))
else -> FirErrorTypeRefImpl(null, FirSimpleDiagnostic("No super type")) else -> FirErrorTypeRefImpl(null, FirSimpleDiagnostic("No super type", DiagnosticKind.Syntax))
} }
else when { else when {
isThis -> classWrapper.delegatedSelfTypeRef isThis -> classWrapper.delegatedSelfTypeRef
@@ -870,7 +871,7 @@ class DeclarationsConverter(
private fun convertDestructingDeclaration(destructingDeclaration: LighterASTNode): DestructuringDeclaration { private fun convertDestructingDeclaration(destructingDeclaration: LighterASTNode): DestructuringDeclaration {
var isVar = false var isVar = false
val entries = mutableListOf<FirVariable<*>>() val entries = mutableListOf<FirVariable<*>>()
var firExpression: FirExpression = FirErrorExpressionImpl(null, FirSimpleDiagnostic("Destructuring declaration without initializer")) var firExpression: FirExpression = FirErrorExpressionImpl(null, FirSimpleDiagnostic("Destructuring declaration without initializer", DiagnosticKind.Syntax))
destructingDeclaration.forEachChildren { destructingDeclaration.forEachChildren {
when (it.tokenType) { when (it.tokenType) {
VAR_KEYWORD -> isVar = true VAR_KEYWORD -> isVar = true
@@ -1166,7 +1167,7 @@ class DeclarationsConverter(
*/ */
private fun convertExplicitDelegation(explicitDelegation: LighterASTNode): FirDelegatedTypeRef { private fun convertExplicitDelegation(explicitDelegation: LighterASTNode): FirDelegatedTypeRef {
lateinit var firTypeRef: FirTypeRef 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 { explicitDelegation.forEachChildren {
when (it.tokenType) { when (it.tokenType) {
TYPE_REFERENCE -> firTypeRef = convertType(it) TYPE_REFERENCE -> firTypeRef = convertType(it)
@@ -1256,10 +1257,10 @@ class DeclarationsConverter(
*/ */
fun convertType(type: LighterASTNode): FirTypeRef { fun convertType(type: LighterASTNode): FirTypeRef {
if (type.asText.isEmpty()) { 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 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 var afterLPar = false
type.forEachChildren { type.forEachChildren {
when (it.tokenType) { when (it.tokenType) {
@@ -1270,7 +1271,7 @@ class DeclarationsConverter(
NULLABLE_TYPE -> firType = convertNullableType(it) NULLABLE_TYPE -> firType = convertNullableType(it)
FUNCTION_TYPE -> firType = convertFunctionType(it) FUNCTION_TYPE -> firType = convertFunctionType(it)
DYNAMIC_TYPE -> firType = FirDynamicTypeRefImpl(null, false) 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) if (identifier == null)
return FirErrorTypeRefImpl(null, FirSimpleDiagnostic("Incomplete user type")) return FirErrorTypeRefImpl(null, FirSimpleDiagnostic("Incomplete user type", DiagnosticKind.Syntax))
val qualifier = FirQualifierPartImpl( val qualifier = FirQualifierPartImpl(
identifier.nameAsSafeName() identifier.nameAsSafeName()
@@ -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.FirDeclarationStatusImpl
import org.jetbrains.kotlin.fir.declarations.impl.FirPropertyImpl import org.jetbrains.kotlin.fir.declarations.impl.FirPropertyImpl
import org.jetbrains.kotlin.fir.declarations.impl.FirValueParameterImpl 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.diagnostics.FirSimpleDiagnostic
import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.expressions.impl.* import org.jetbrains.kotlin.fir.expressions.impl.*
@@ -57,7 +58,7 @@ class ExpressionsConverter(
) : BaseConverter(session, tree, context) { ) : BaseConverter(session, tree, context) {
inline fun <reified R : FirElement> getAsFirExpression(expression: LighterASTNode?, errorReason: String = ""): R { inline fun <reified R : FirElement> 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 *****/ /***** EXPRESSIONS *****/
@@ -105,7 +106,7 @@ class ExpressionsConverter(
OBJECT_LITERAL -> declarationsConverter.convertObjectLiteral(expression) OBJECT_LITERAL -> declarationsConverter.convertObjectLiteral(expression)
FUN -> declarationsConverter.convertFunctionDeclaration(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()) FirLabelImpl(null, it.asString())
} }
val bodyExpression = block?.let { declarationsConverter.convertBlockExpression(it) } 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) { body = if (bodyExpression is FirBlockImpl) {
if (bodyExpression.statements.isEmpty()) { if (bodyExpression.statements.isEmpty()) {
bodyExpression.statements.add(FirUnitExpression(null)) bodyExpression.statements.add(FirUnitExpression(null))
@@ -186,7 +187,7 @@ class ExpressionsConverter(
var isLeftArgument = true var isLeftArgument = true
lateinit var operationTokenName: String lateinit var operationTokenName: String
var leftArgNode: LighterASTNode? = null 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 { binaryExpression.forEachChildren {
when (it.tokenType) { when (it.tokenType) {
OPERATION_REFERENCE -> { OPERATION_REFERENCE -> {
@@ -250,7 +251,7 @@ class ExpressionsConverter(
toFirOperation: String.() -> FirOperation toFirOperation: String.() -> FirOperation
): FirTypeOperatorCall { ): FirTypeOperatorCall {
lateinit var operationTokenName: String 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 lateinit var firType: FirTypeRef
binaryExpression.forEachChildren { binaryExpression.forEachChildren {
when (it.tokenType) { when (it.tokenType) {
@@ -286,7 +287,7 @@ class ExpressionsConverter(
context.firLabels.removeLast() context.firLabels.removeLast()
//println("Unused label: ${labeledExpression.getAsString()}") //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 { return (firExpression as? FirAbstractAnnotatedElement)?.apply {
annotations += firAnnotationList 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 * @see org.jetbrains.kotlin.fir.builder.RawFirBuilder.Visitor.visitClassLiteralExpression
*/ */
private fun convertClassLiteralExpression(classLiteralExpression: LighterASTNode): FirExpression { 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 { classLiteralExpression.forEachChildren {
if (it.isExpression()) firReceiverExpression = getAsFirExpression(it, "No receiver in class literal") if (it.isExpression()) firReceiverExpression = getAsFirExpression(it, "No receiver in class literal")
} }
@@ -400,7 +401,7 @@ class ExpressionsConverter(
private fun convertQualifiedExpression(dotQualifiedExpression: LighterASTNode): FirExpression { private fun convertQualifiedExpression(dotQualifiedExpression: LighterASTNode): FirExpression {
var isSelector = false var isSelector = false
var isSafe = 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 var firReceiver: FirExpression? = null //before dot
dotQualifiedExpression.forEachChildren { dotQualifiedExpression.forEachChildren {
when (it.tokenType) { when (it.tokenType) {
@@ -450,7 +451,7 @@ class ExpressionsConverter(
arguments += additionalArgument!! arguments += additionalArgument!!
FirSimpleNamedReference(null, OperatorNameConventions.INVOKE, null) 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 context.firFunctionCalls += this
@@ -468,7 +469,7 @@ class ExpressionsConverter(
} }
private fun LighterASTNode?.convertShortOrLongStringTemplate(errorReason: String): FirExpression { 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) { this?.forEachChildren(LONG_TEMPLATE_ENTRY_START, LONG_TEMPLATE_ENTRY_END) {
firExpression = getAsFirExpression(it, errorReason) firExpression = getAsFirExpression(it, errorReason)
} }
@@ -564,7 +565,7 @@ class ExpressionsConverter(
} }
private fun convertWhenConditionExpression(whenCondition: LighterASTNode): FirExpression { 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 { whenCondition.forEachChildren {
when (it.tokenType) { when (it.tokenType) {
else -> if (it.isExpression()) firExpression = getAsFirExpression(it, "No expression in condition with expression") 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 { private fun convertWhenConditionInRange(whenCondition: LighterASTNode): FirExpression {
var isNegate = false 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 { whenCondition.forEachChildren {
when (it.tokenType) { when (it.tokenType) {
NOT_IN -> isNegate = true NOT_IN -> isNegate = true
@@ -612,7 +613,7 @@ class ExpressionsConverter(
* @see org.jetbrains.kotlin.fir.builder.RawFirBuilder.Visitor.visitArrayAccessExpression * @see org.jetbrains.kotlin.fir.builder.RawFirBuilder.Visitor.visitArrayAccessExpression
*/ */
private fun convertArrayAccessExpression(arrayAccess: LighterASTNode): FirFunctionCall { 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<FirExpression> = mutableListOf() val indices: MutableList<FirExpression> = mutableListOf()
arrayAccess.forEachChildren { arrayAccess.forEachChildren {
when (it.tokenType) { when (it.tokenType) {
@@ -670,7 +671,7 @@ class ExpressionsConverter(
*/ */
private fun convertDoWhile(doWhileLoop: LighterASTNode): FirElement { private fun convertDoWhile(doWhileLoop: LighterASTNode): FirElement {
var block: LighterASTNode? = null 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 { doWhileLoop.forEachChildren {
when (it.tokenType) { when (it.tokenType) {
BODY -> block = it BODY -> block = it
@@ -687,7 +688,7 @@ class ExpressionsConverter(
*/ */
private fun convertWhile(whileLoop: LighterASTNode): FirElement { private fun convertWhile(whileLoop: LighterASTNode): FirElement {
var block: LighterASTNode? = null 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 { whileLoop.forEachChildren {
when (it.tokenType) { when (it.tokenType) {
BODY -> block = it BODY -> block = it
@@ -704,7 +705,7 @@ class ExpressionsConverter(
*/ */
private fun convertFor(forLoop: LighterASTNode): FirElement { private fun convertFor(forLoop: LighterASTNode): FirElement {
var parameter: ValueParameter? = null 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 var blockNode: LighterASTNode? = null
forLoop.forEachChildren { forLoop.forEachChildren {
when (it.tokenType) { when (it.tokenType) {
@@ -847,7 +848,7 @@ class ExpressionsConverter(
* @see org.jetbrains.kotlin.fir.builder.RawFirBuilder.Visitor.visitIfExpression * @see org.jetbrains.kotlin.fir.builder.RawFirBuilder.Visitor.visitIfExpression
*/ */
private fun convertIfExpression(ifExpression: LighterASTNode): FirExpression { 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 thenBlock: LighterASTNode? = null
var elseBlock: LighterASTNode? = null var elseBlock: LighterASTNode? = null
ifExpression.forEachChildren { ifExpression.forEachChildren {
@@ -909,7 +910,7 @@ class ExpressionsConverter(
* @see org.jetbrains.kotlin.fir.builder.RawFirBuilder.Visitor.visitThrowExpression * @see org.jetbrains.kotlin.fir.builder.RawFirBuilder.Visitor.visitThrowExpression
*/ */
private fun convertThrow(throwExpression: LighterASTNode): FirExpression { 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 { throwExpression.forEachChildren {
if (it.isExpression()) firExpression = getAsFirExpression(it, "Nothing to throw") if (it.isExpression()) firExpression = getAsFirExpression(it, "Nothing to throw")
} }
@@ -964,7 +965,7 @@ class ExpressionsConverter(
private fun convertValueArgument(valueArgument: LighterASTNode): FirExpression { private fun convertValueArgument(valueArgument: LighterASTNode): FirExpression {
var identifier: String? = null var identifier: String? = null
var isSpread = false 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 { valueArgument.forEachChildren {
when (it.tokenType) { when (it.tokenType) {
VALUE_ARGUMENT_NAME -> identifier = it.asText VALUE_ARGUMENT_NAME -> identifier = it.asText
@@ -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.FirDefaultPropertyGetter
import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertySetter import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertySetter
import org.jetbrains.kotlin.fir.declarations.impl.FirPropertyImpl 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.diagnostics.FirSimpleDiagnostic
import org.jetbrains.kotlin.fir.expressions.impl.FirQualifiedAccessExpressionImpl import org.jetbrains.kotlin.fir.expressions.impl.FirQualifiedAccessExpressionImpl
import org.jetbrains.kotlin.fir.lightTree.fir.modifier.Modifier import org.jetbrains.kotlin.fir.lightTree.fir.modifier.Modifier
@@ -36,7 +37,7 @@ class ValueParameter(
val name = this.firValueParameter.name val name = this.firValueParameter.name
var type = this.firValueParameter.returnTypeRef var type = this.firValueParameter.returnTypeRef
if (type is FirImplicitTypeRef) { 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 { val status = FirDeclarationStatusImpl(modifiers.getVisibility(), modifiers.getModality()).apply {
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.lightTree.fir
import org.jetbrains.kotlin.fir.FirWhenSubject import org.jetbrains.kotlin.fir.FirWhenSubject
import org.jetbrains.kotlin.fir.builder.generateContainsOperation import org.jetbrains.kotlin.fir.builder.generateContainsOperation
import org.jetbrains.kotlin.fir.builder.generateLazyLogicalOperation 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.diagnostics.FirSimpleDiagnostic
import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.expressions.impl.FirErrorExpressionImpl import org.jetbrains.kotlin.fir.expressions.impl.FirErrorExpressionImpl
@@ -52,7 +53,7 @@ data class WhenEntry(
} }
} }
else -> { 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 { fun toFirWhenConditionWithoutSubject(): FirExpression {
return when (val condition = conditions.first()) { return when (val condition = conditions.first()) {
is FirOperatorCallImpl -> condition.arguments.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))
} }
} }
} }
@@ -12,7 +12,7 @@ import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.impl.FirErrorFunctionImpl import org.jetbrains.kotlin.fir.declarations.impl.FirErrorFunctionImpl
import org.jetbrains.kotlin.fir.declarations.impl.FirTypeParameterImpl 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.*
import org.jetbrains.kotlin.fir.expressions.impl.* import org.jetbrains.kotlin.fir.expressions.impl.*
import org.jetbrains.kotlin.fir.references.FirReference import org.jetbrains.kotlin.fir.references.FirReference
@@ -111,7 +111,7 @@ abstract class BaseFirBuilder<T>(val session: FirSession, val context: Context =
FirErrorFunctionImpl( FirErrorFunctionImpl(
source, source,
this@BaseFirBuilder.session, this@BaseFirBuilder.session,
FirSimpleDiagnostic("Cannot bind unlabeled return to a function"), FirSimpleDiagnostic("Cannot bind unlabeled return to a function", DiagnosticKind.ReturnNotAllowed),
FirErrorFunctionSymbol() FirErrorFunctionSymbol()
) )
) )
@@ -137,7 +137,7 @@ abstract class BaseFirBuilder<T>(val session: FirSession, val context: Context =
FirErrorFunctionImpl( FirErrorFunctionImpl(
source, source,
this@BaseFirBuilder.session, this@BaseFirBuilder.session,
FirSimpleDiagnostic("Cannot bind label $labelName to a function"), FirSimpleDiagnostic("Cannot bind label $labelName to a function", DiagnosticKind.UnresolvedLabel),
FirErrorFunctionSymbol() FirErrorFunctionSymbol()
) )
) )
@@ -197,7 +197,7 @@ abstract class BaseFirBuilder<T>(val session: FirSession, val context: Context =
if (lastLoop != null) { if (lastLoop != null) {
target.bind(lastLoop) target.bind(lastLoop)
} else { } 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 { } else {
for (firLoop in context.firLoops.asReversed()) { for (firLoop in context.firLoops.asReversed()) {
@@ -206,7 +206,7 @@ abstract class BaseFirBuilder<T>(val session: FirSession, val context: Context =
return this 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 return this
} }
@@ -231,29 +231,29 @@ abstract class BaseFirBuilder<T>(val session: FirSession, val context: Context =
convertedText > Int.MAX_VALUE || convertedText < Int.MIN_VALUE) convertedText > Int.MAX_VALUE || convertedText < Int.MIN_VALUE)
) { ) {
FirConstExpressionImpl( 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) { } else if (convertedText is Number) {
// TODO: support byte / short // TODO: support byte / short
FirConstExpressionImpl( FirConstExpressionImpl(
expression.getSourceOrNull(), IrConstKind.Int, convertedText.toInt(), "Incorrect int: $text" expression.getSourceOrNull(), IrConstKind.Int, convertedText.toInt(), FirSimpleDiagnostic("Incorrect int: $text", DiagnosticKind.Syntax)
) )
} else { } else {
FirErrorExpressionImpl(expression.getSourceOrNull(), diagnostic = FirSimpleDiagnostic("Incorrect constant expression: $text")) FirErrorExpressionImpl(expression.getSourceOrNull(), FirSimpleDiagnostic("Incorrect constant expression: $text", DiagnosticKind.IllegalConstExpression))
} }
FLOAT_CONSTANT -> FLOAT_CONSTANT ->
if (convertedText is Float) { if (convertedText is Float) {
FirConstExpressionImpl( FirConstExpressionImpl(
expression.getSourceOrNull(), IrConstKind.Float, convertedText, "Incorrect float: $text" expression.getSourceOrNull(), IrConstKind.Float, convertedText, FirSimpleDiagnostic("Incorrect float: $text", DiagnosticKind.Syntax)
) )
} else { } else {
FirConstExpressionImpl( 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 -> CHARACTER_CONSTANT ->
FirConstExpressionImpl( FirConstExpressionImpl(
expression.getSourceOrNull(), IrConstKind.Char, text.parseCharacter(), "Incorrect character: $text" expression.getSourceOrNull(), IrConstKind.Char, text.parseCharacter(), FirSimpleDiagnostic("Incorrect character: $text", DiagnosticKind.Syntax)
) )
BOOLEAN_CONSTANT -> BOOLEAN_CONSTANT ->
FirConstExpressionImpl(expression.getSourceOrNull(), IrConstKind.Boolean, convertedText as Boolean) FirConstExpressionImpl(expression.getSourceOrNull(), IrConstKind.Boolean, convertedText as Boolean)
@@ -291,7 +291,7 @@ abstract class BaseFirBuilder<T>(val session: FirSession, val context: Context =
else -> { else -> {
hasExpressions = true hasExpressions = true
FirErrorExpressionImpl( 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<T>(val session: FirSession, val context: Context =
convert: T.() -> FirExpression convert: T.() -> FirExpression
): FirExpression { ): FirExpression {
if (argument == null) { 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() val source = baseExpression?.toFirSourceElement()
return FirBlockImpl(source).apply { return FirBlockImpl(source).apply {
@@ -411,7 +411,7 @@ abstract class BaseFirBuilder<T>(val session: FirSession, val context: Context =
firMemberAccess.calleeReference firMemberAccess.calleeReference
} else { } else {
FirErrorNamedReferenceImpl( 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<T>(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( fun T?.generateAssignment(
@@ -469,7 +469,7 @@ abstract class BaseFirBuilder<T>(val session: FirSession, val context: Context =
statements += generateTemporaryVariable( statements += generateTemporaryVariable(
this@BaseFirBuilder.session, this@generateAssignment.getSourceOrNull(), name, this@BaseFirBuilder.session, this@generateAssignment.getSourceOrNull(), name,
this@generateAssignment?.convert() 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 { statements += FirVariableAssignmentImpl(source, false, value, operation).apply {
lValue = FirSimpleNamedReference(this.getSourceOrNull(), name, null) lValue = FirSimpleNamedReference(this.getSourceOrNull(), name, null)
@@ -480,7 +480,7 @@ abstract class BaseFirBuilder<T>(val session: FirSession, val context: Context =
if (operation in FirOperation.ASSIGNMENTS && operation != FirOperation.ASSIGN) { if (operation in FirOperation.ASSIGNMENTS && operation != FirOperation.ASSIGN) {
return FirOperatorCallImpl(source, operation).apply { return FirOperatorCallImpl(source, operation).apply {
// TODO: take good psi // 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 arguments += value
} }
} }
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.declarations.FirVariable import org.jetbrains.kotlin.fir.declarations.FirVariable
import org.jetbrains.kotlin.fir.declarations.impl.* 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.diagnostics.FirSimpleDiagnostic
import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.expressions.impl.* import org.jetbrains.kotlin.fir.expressions.impl.*
@@ -201,7 +202,7 @@ internal fun KtWhenCondition.toFirWhenCondition(
} }
} }
else -> { else -> {
FirErrorExpressionImpl(this.toFirSourceElement(), FirSimpleDiagnostic("Unsupported when condition: ${this.javaClass}")) FirErrorExpressionImpl(this.toFirSourceElement(), FirSimpleDiagnostic("Unsupported when condition: ${this.javaClass}", DiagnosticKind.Syntax))
} }
} }
} }
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.descriptors.Visibility
import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.impl.* 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.diagnostics.FirSimpleDiagnostic
import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.expressions.impl.* import org.jetbrains.kotlin.fir.expressions.impl.*
@@ -106,21 +107,21 @@ class RawFirBuilder(session: FirSession, val stubMode: Boolean) : BaseFirBuilder
convertSafe() ?: implicitUnitType convertSafe() ?: implicitUnitType
private fun KtTypeReference?.toFirOrErrorType(): FirTypeRef = 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 // Here we accept lambda as receiver to prevent expression calculation in stub mode
private fun (() -> KtExpression?).toFirExpression(errorReason: String): FirExpression = private fun (() -> KtExpression?).toFirExpression(errorReason: String): FirExpression =
if (stubMode) FirExpressionStub(null) if (stubMode) FirExpressionStub(null)
else with(this()) { else with(this()) {
convertSafe<FirExpression>() ?: FirErrorExpressionImpl(this?.toFirSourceElement(), FirSimpleDiagnostic(errorReason)) convertSafe<FirExpression>() ?: FirErrorExpressionImpl(this?.toFirSourceElement(), FirSimpleDiagnostic(errorReason, DiagnosticKind.Syntax))
} }
private fun KtExpression?.toFirExpression(errorReason: String): FirExpression = private fun KtExpression?.toFirExpression(errorReason: String): FirExpression =
if (stubMode) FirExpressionStub(null) if (stubMode) FirExpressionStub(null)
else convertSafe<FirExpression>() ?: FirErrorExpressionImpl(this?.toFirSourceElement(), FirSimpleDiagnostic(errorReason)) else convertSafe<FirExpression>() ?: FirErrorExpressionImpl(this?.toFirSourceElement(), FirSimpleDiagnostic(errorReason, DiagnosticKind.Syntax))
private fun KtExpression.toFirStatement(errorReason: String): FirStatement = 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 = private fun KtExpression.toFirStatement(): FirStatement =
convert() convert()
@@ -131,7 +132,7 @@ class RawFirBuilder(session: FirSession, val stubMode: Boolean) : BaseFirBuilder
return when (this) { return when (this) {
is KtSecondaryConstructor -> toFirConstructor( is KtSecondaryConstructor -> toFirConstructor(
delegatedSuperType, delegatedSuperType,
delegatedSelfType ?: FirErrorTypeRefImpl(this.toFirSourceElement(), FirSimpleDiagnostic("Constructor in object")), delegatedSelfType ?: FirErrorTypeRefImpl(this.toFirSourceElement(), FirSimpleDiagnostic("Constructor in object", DiagnosticKind.ConstructorInObject)),
owner, owner,
hasPrimaryConstructor hasPrimaryConstructor
) )
@@ -166,7 +167,7 @@ class RawFirBuilder(session: FirSession, val stubMode: Boolean) : BaseFirBuilder
} }
private fun ValueArgument?.toFirExpression(): FirExpression { 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 name = this.getArgumentName()?.asName
val expression = this.getArgumentExpression() val expression = this.getArgumentExpression()
val firExpression = when (expression) { val firExpression = when (expression) {
@@ -719,7 +720,7 @@ class RawFirBuilder(session: FirSession, val stubMode: Boolean) : BaseFirBuilder
val source = this.toFirSourceElement() val source = this.toFirSourceElement()
val delegatedType = when { val delegatedType = when {
isThis -> delegatedSelfTypeRef isThis -> delegatedSelfTypeRef
else -> delegatedSuperTypeRef ?: FirErrorTypeRefImpl(source, FirSimpleDiagnostic("No super type")) else -> delegatedSuperTypeRef ?: FirErrorTypeRefImpl(source, FirSimpleDiagnostic("No super type", DiagnosticKind.Syntax))
} }
return FirDelegatedConstructorCallImpl( return FirDelegatedConstructorCallImpl(
source, source,
@@ -838,7 +839,7 @@ class RawFirBuilder(session: FirSession, val stubMode: Boolean) : BaseFirBuilder
userType userType
} else { } else {
FirErrorTypeRefImpl(source, FirSimpleDiagnostic("Incomplete user type")) FirErrorTypeRefImpl(source, FirSimpleDiagnostic("Incomplete user type", DiagnosticKind.Syntax))
} }
} }
is KtFunctionType -> { is KtFunctionType -> {
@@ -857,7 +858,7 @@ class RawFirBuilder(session: FirSession, val stubMode: Boolean) : BaseFirBuilder
} }
functionType 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}") 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 calleeExpression.toFirSourceElement(), calleeExpression.getReferencedNameAsName(), null
) )
null -> FirErrorNamedReferenceImpl( null -> FirErrorNamedReferenceImpl(
null, FirSimpleDiagnostic("Call has no callee") null, FirSimpleDiagnostic("Call has no callee", DiagnosticKind.Syntax)
) )
else -> { else -> {
arguments += calleeExpression.toFirExpression("Incorrect invoke receiver") 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 { override fun visitQualifiedExpression(expression: KtQualifiedExpression, data: Unit): FirElement {
val selector = expression.selectorExpression 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") val firSelector = selector.toFirExpression("Incorrect selector expression")
if (firSelector is FirModifiableQualifiedAccess) { if (firSelector is FirModifiableQualifiedAccess) {
firSelector.safe = expression is KtSafeQualifiedExpression 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 { 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 { override fun visitLabeledExpression(expression: KtLabeledExpression, data: Unit): FirElement {
@@ -1298,7 +1299,7 @@ class RawFirBuilder(session: FirSession, val stubMode: Boolean) : BaseFirBuilder
if (labelName != null) { if (labelName != null) {
context.firLabels += FirLabelImpl(source, labelName) 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) { if (size != context.firLabels.size) {
context.firLabels.removeLast() context.firLabels.removeLast()
println("Unused label: ${expression.text}") 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 { override fun visitAnnotatedExpression(expression: KtAnnotatedExpression, data: Unit): FirElement {
val rawResult = expression.baseExpression?.accept(this, data) val rawResult = expression.baseExpression?.accept(this, data)
val result = rawResult as? FirAbstractAnnotatedElement 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) expression.extractAnnotationsTo(result)
return result return result
} }
@@ -5,4 +5,13 @@
package org.jetbrains.kotlin.fir.diagnostics package org.jetbrains.kotlin.fir.diagnostics
class FirSimpleDiagnostic(override val reason: String) : FirDiagnostic() class FirSimpleDiagnostic(override val reason: String, val kind: DiagnosticKind = DiagnosticKind.Other) : FirDiagnostic()
enum class DiagnosticKind {
Syntax,
ReturnNotAllowed,
UnresolvedLabel,
IllegalConstExpression,
ConstructorInObject,
Other
}
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.fir.expressions package org.jetbrains.kotlin.fir.expressions
import org.jetbrains.kotlin.fir.FirSourceElement 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.diagnostics.FirSimpleDiagnostic
import org.jetbrains.kotlin.fir.expressions.impl.FirConstExpressionImpl import org.jetbrains.kotlin.fir.expressions.impl.FirConstExpressionImpl
import org.jetbrains.kotlin.fir.expressions.impl.FirErrorExpressionImpl import org.jetbrains.kotlin.fir.expressions.impl.FirErrorExpressionImpl
@@ -24,8 +25,8 @@ inline val FirAnnotationCall.coneClassLikeType: ConeClassLikeType?
inline val FirAnnotationCall.classId: ClassId? inline val FirAnnotationCall.classId: ClassId?
get() = coneClassLikeType?.lookupTag?.classId get() = coneClassLikeType?.lookupTag?.classId
fun <T> FirConstExpressionImpl(source: FirSourceElement?, kind: IrConstKind<T>, value: T?, errorReason: String): FirExpression = fun <T> FirConstExpressionImpl(source: FirSourceElement?, kind: IrConstKind<T>, value: T?, diagnostic: FirDiagnostic): FirExpression =
value?.let { FirConstExpressionImpl(source, kind, it) } ?: FirErrorExpressionImpl(source, FirSimpleDiagnostic(errorReason)) value?.let { FirConstExpressionImpl(source, kind, it) } ?: FirErrorExpressionImpl(source, diagnostic)
inline val FirTypeOperatorCall.argument: FirExpression get() = arguments.first() inline val FirTypeOperatorCall.argument: FirExpression get() = arguments.first()
@@ -37,8 +38,7 @@ fun FirExpression.toResolvedCallableSymbol(): FirCallableSymbol<*>? {
return toResolvedCallableReference()?.resolvedSymbol as FirCallableSymbol<*>? return toResolvedCallableReference()?.resolvedSymbol as FirCallableSymbol<*>?
} }
fun FirErrorLoop(source: FirSourceElement?, reason: String): FirErrorLoop { fun FirErrorLoop(source: FirSourceElement?, diagnostic: FirDiagnostic): FirErrorLoop {
val diagnostic = FirSimpleDiagnostic(reason)
return FirErrorLoopImpl(source, diagnostic).apply { return FirErrorLoopImpl(source, diagnostic).apply {
condition = FirErrorExpressionImpl(source, diagnostic) condition = FirErrorExpressionImpl(source, diagnostic)
} }