[Psi2Ir] Fix generation of IrError* nodes

- Provide detailed description
 - Support syntax-incorrect statements
 - Generate an error declaration if normal generation has failed
This commit is contained in:
Roman Artemev
2020-07-07 14:29:24 +03:00
parent a60782f3df
commit 563af709a8
3 changed files with 29 additions and 19 deletions
@@ -39,24 +39,34 @@ class DeclarationGenerator(override val context: GeneratorContext) : Generator {
fun KotlinType.toIrType() = typeTranslator.translateType(this)
fun generateMemberDeclaration(ktDeclaration: KtDeclaration): IrDeclaration? =
when (ktDeclaration) {
is KtNamedFunction ->
FunctionGenerator(this).generateFunctionDeclaration(ktDeclaration)
is KtProperty ->
PropertyGenerator(this).generatePropertyDeclaration(ktDeclaration)
is KtClassOrObject ->
generateClassOrObjectDeclaration(ktDeclaration)
is KtTypeAlias ->
generateTypeAliasDeclaration(ktDeclaration)
is KtScript ->
ScriptGenerator(this).generateScriptDeclaration(ktDeclaration)
else ->
fun generateMemberDeclaration(ktDeclaration: KtDeclaration): IrDeclaration? {
return try {
when (ktDeclaration) {
is KtNamedFunction ->
FunctionGenerator(this).generateFunctionDeclaration(ktDeclaration)
is KtProperty ->
PropertyGenerator(this).generatePropertyDeclaration(ktDeclaration)
is KtClassOrObject ->
generateClassOrObjectDeclaration(ktDeclaration)
is KtTypeAlias ->
generateTypeAliasDeclaration(ktDeclaration)
is KtScript ->
ScriptGenerator(this).generateScriptDeclaration(ktDeclaration)
else ->
context.irFactory.createErrorDeclaration(
ktDeclaration.startOffsetSkippingComments, ktDeclaration.endOffset,
getOrFail(BindingContext.DECLARATION_TO_DESCRIPTOR, ktDeclaration)
)
}
} catch (e: Throwable) {
if (context.configuration.ignoreErrors) {
context.irFactory.createErrorDeclaration(
ktDeclaration.startOffsetSkippingComments, ktDeclaration.endOffset,
getOrFail(BindingContext.DECLARATION_TO_DESCRIPTOR, ktDeclaration)
)
} else throw e
}
}
fun generateSyntheticClassOrObject(syntheticDeclaration: KtPureClassOrObject): IrClass {
return generateClassOrObjectDeclaration(syntheticDeclaration)
@@ -27,13 +27,13 @@ import org.jetbrains.kotlin.types.ErrorUtils
class ErrorExpressionGenerator(statementGenerator: StatementGenerator) : StatementGeneratorExtension(statementGenerator) {
private val ignoreErrors: Boolean get() = context.configuration.ignoreErrors
private inline fun generateErrorExpression(ktElement: KtElement, e: Exception? = null, body: () -> IrExpression) =
private inline fun generateErrorExpression(ktElement: KtElement, e: Throwable? = null, body: () -> IrExpression) =
if (ignoreErrors)
body()
else
throw RuntimeException("${e?.message}: ${ktElement::class.java.simpleName}:\n${ktElement.text}", e)
fun generateErrorExpression(ktElement: KtElement, e: Exception): IrExpression =
fun generateErrorExpression(ktElement: KtElement, e: Throwable): IrExpression =
generateErrorExpression(ktElement, e) {
val errorExpressionType =
if (ktElement is KtExpression)
@@ -43,14 +43,14 @@ class ErrorExpressionGenerator(statementGenerator: StatementGenerator) : Stateme
IrErrorExpressionImpl(
ktElement.startOffsetSkippingComments, ktElement.endOffset,
errorExpressionType.toIrType(),
e.message ?: ""
e.message ?: ktElement.text
)
}
fun generateErrorCall(ktCall: KtCallExpression): IrExpression = generateErrorExpression(ktCall) {
val type = getErrorExpressionType(ktCall).toIrType()
val irErrorCall = IrErrorCallExpressionImpl(ktCall.startOffsetSkippingComments, ktCall.endOffset, type, "") // TODO problem description?
val irErrorCall = IrErrorCallExpressionImpl(ktCall.startOffsetSkippingComments, ktCall.endOffset, type, ktCall.text) // TODO problem description?
irErrorCall.explicitReceiver = (ktCall.parent as? KtDotQualifiedExpression)?.run {
receiverExpression.genExpr()
}
@@ -71,7 +71,7 @@ class ErrorExpressionGenerator(statementGenerator: StatementGenerator) : Stateme
fun generateErrorSimpleName(ktName: KtSimpleNameExpression): IrExpression = generateErrorExpression(ktName) {
val type = getErrorExpressionType(ktName).toIrType()
val irErrorCall = IrErrorCallExpressionImpl(ktName.startOffsetSkippingComments, ktName.endOffset, type, "") // TODO problem description?
val irErrorCall = IrErrorCallExpressionImpl(ktName.startOffsetSkippingComments, ktName.endOffset, type, ktName.text) // TODO problem description?
irErrorCall.explicitReceiver = (ktName.parent as? KtDotQualifiedExpression)?.let { ktParent ->
if (ktParent.receiverExpression == ktName) null
else ktParent.receiverExpression.genExpr()
@@ -73,7 +73,7 @@ class StatementGenerator(
private fun KtElement.genStmt(): IrStatement =
try {
deparenthesize().accept(this@StatementGenerator, null)
} catch (e: Exception) {
} catch (e: Throwable) {
ErrorExpressionGenerator(this@StatementGenerator).generateErrorExpression(this, e)
}