New J2K: Add better error reporting in AST builder
This commit is contained in:
@@ -134,14 +134,16 @@ class JavaToJKTreeBuilder constructor(
|
|||||||
)
|
)
|
||||||
is PsiPolyadicExpression -> JKJavaPolyadicExpressionImpl(
|
is PsiPolyadicExpression -> JKJavaPolyadicExpressionImpl(
|
||||||
operands.map { it.toJK() },
|
operands.map { it.toJK() },
|
||||||
Array(operands.lastIndex) { getTokenBeforeOperand(operands[it + 1]) }.map { it?.tokenType?.toJK() ?: TODO() }
|
Array(operands.lastIndex) { index ->
|
||||||
|
getTokenBeforeOperand(operands[index + 1])
|
||||||
|
}.map {
|
||||||
|
it?.tokenType?.toJK() ?: throwCanNotConvertError()
|
||||||
|
}
|
||||||
)
|
)
|
||||||
is PsiArrayInitializerExpression -> toJK()
|
is PsiArrayInitializerExpression -> toJK()
|
||||||
is PsiLambdaExpression -> toJK()
|
is PsiLambdaExpression -> toJK()
|
||||||
is PsiClassObjectAccessExpressionImpl -> toJK()
|
is PsiClassObjectAccessExpressionImpl -> toJK()
|
||||||
else -> {
|
else -> throwCanNotConvertError()
|
||||||
throw RuntimeException("Not supported: ${this::class}")
|
|
||||||
}
|
|
||||||
}.also {
|
}.also {
|
||||||
if (this != null) {
|
if (this != null) {
|
||||||
(it as PsiOwner).psi = this
|
(it as PsiOwner).psi = this
|
||||||
@@ -275,7 +277,7 @@ class JavaToJKTreeBuilder constructor(
|
|||||||
val callee = when ((methodExpression.referenceNameElement as PsiKeyword).tokenType) {
|
val callee = when ((methodExpression.referenceNameElement as PsiKeyword).tokenType) {
|
||||||
SUPER_KEYWORD -> JKSuperExpressionImpl()
|
SUPER_KEYWORD -> JKSuperExpressionImpl()
|
||||||
THIS_KEYWORD -> JKThisExpressionImpl(JKLabelEmptyImpl())
|
THIS_KEYWORD -> JKThisExpressionImpl(JKLabelEmptyImpl())
|
||||||
else -> error("Unknown keyword in callee position")
|
else -> throwCanNotConvertError("unknown keyword in callee position")
|
||||||
}
|
}
|
||||||
JKDelegationConstructorCallImpl(symbol as JKMethodSymbol, callee, arguments.toJK())
|
JKDelegationConstructorCallImpl(symbol as JKMethodSymbol, callee, arguments.toJK())
|
||||||
}
|
}
|
||||||
@@ -332,7 +334,7 @@ class JavaToJKTreeBuilder constructor(
|
|||||||
JKJavaOperatorImpl.tokenToOperator[JavaTokenType.EQ]!!
|
JKJavaOperatorImpl.tokenToOperator[JavaTokenType.EQ]!!
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
else -> TODO()
|
else -> throwCanNotConvertError("expected getter or setter call")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -351,7 +353,7 @@ class JavaToJKTreeBuilder constructor(
|
|||||||
.qualified(qualifier)
|
.qualified(qualifier)
|
||||||
symbol is JKFieldSymbol ->
|
symbol is JKFieldSymbol ->
|
||||||
JKFieldAccessExpressionImpl(symbol).qualified(qualifier)
|
JKFieldAccessExpressionImpl(symbol).qualified(qualifier)
|
||||||
else -> TODO(text)
|
else -> throwCanNotConvertError("unexpected symbol ${symbol::class}")
|
||||||
}.also {
|
}.also {
|
||||||
it.assignNonCodeElements(this)
|
it.assignNonCodeElements(this)
|
||||||
}
|
}
|
||||||
@@ -397,7 +399,7 @@ class JavaToJKTreeBuilder constructor(
|
|||||||
is JKClassSymbol -> JKClassAccessExpressionImpl(symbol)
|
is JKClassSymbol -> JKClassAccessExpressionImpl(symbol)
|
||||||
is JKFieldSymbol -> JKFieldAccessExpressionImpl(symbol)
|
is JKFieldSymbol -> JKFieldAccessExpressionImpl(symbol)
|
||||||
is JKPackageSymbol -> JKPackageAccessExpressionImpl(symbol)
|
is JKPackageSymbol -> JKPackageAccessExpressionImpl(symbol)
|
||||||
else -> TODO()
|
else -> throwCanNotConvertError("unexpected symbol ${symbol::class}")
|
||||||
}.qualified(qualifierExpression?.toJK()).also {
|
}.qualified(qualifierExpression?.toJK()).also {
|
||||||
it.assignNonCodeElements(this)
|
it.assignNonCodeElements(this)
|
||||||
}
|
}
|
||||||
@@ -441,7 +443,7 @@ class JavaToJKTreeBuilder constructor(
|
|||||||
val classSymbol =
|
val classSymbol =
|
||||||
classOrAnonymousClassReference?.resolve()?.let {
|
classOrAnonymousClassReference?.resolve()?.let {
|
||||||
symbolProvider.provideDirectSymbol(it) as JKClassSymbol
|
symbolProvider.provideDirectSymbol(it) as JKClassSymbol
|
||||||
} ?: JKUnresolvedClassSymbol(classOrAnonymousClassReference?.referenceName!!)
|
} ?: JKUnresolvedClassSymbol(classOrAnonymousClassReference?.referenceName ?: throwCanNotConvertError())
|
||||||
val typeArgumentList =
|
val typeArgumentList =
|
||||||
this.typeArgumentList.toJK()
|
this.typeArgumentList.toJK()
|
||||||
.takeIf { it.typeArguments.isNotEmpty() }
|
.takeIf { it.typeArguments.isNotEmpty() }
|
||||||
@@ -470,21 +472,25 @@ class JavaToJKTreeBuilder constructor(
|
|||||||
|
|
||||||
|
|
||||||
fun PsiArrayAccessExpression.toJK(): JKExpression {
|
fun PsiArrayAccessExpression.toJK(): JKExpression {
|
||||||
return JKArrayAccessExpressionImpl(arrayExpression.toJK(), indexExpression?.toJK() ?: TODO())
|
return JKArrayAccessExpressionImpl(
|
||||||
.also {
|
arrayExpression.toJK(),
|
||||||
it.assignNonCodeElements(this)
|
indexExpression?.toJK() ?: throwCanNotConvertError()
|
||||||
}
|
).also {
|
||||||
|
it.assignNonCodeElements(this)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun PsiTypeCastExpression.toJK(): JKExpression {
|
fun PsiTypeCastExpression.toJK(): JKExpression {
|
||||||
return JKTypeCastExpressionImpl(operand?.toJK() ?: TODO(), castType?.type?.toJK(symbolProvider)?.asTypeElement() ?: TODO())
|
return JKTypeCastExpressionImpl(
|
||||||
.also {
|
operand?.toJK() ?: throwCanNotConvertError(),
|
||||||
it.assignNonCodeElements(this)
|
castType?.type?.toJK(symbolProvider)?.asTypeElement() ?: throwCanNotConvertError()
|
||||||
}
|
).also {
|
||||||
|
it.assignNonCodeElements(this)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun PsiParenthesizedExpression.toJK(): JKExpression {
|
fun PsiParenthesizedExpression.toJK(): JKExpression {
|
||||||
return JKParenthesizedExpressionImpl(expression?.toJK() ?: TODO())
|
return JKParenthesizedExpressionImpl(expression.toJK())
|
||||||
.also {
|
.also {
|
||||||
it.assignNonCodeElements(this)
|
it.assignNonCodeElements(this)
|
||||||
}
|
}
|
||||||
@@ -595,7 +601,12 @@ class JavaToJKTreeBuilder constructor(
|
|||||||
nameIdentifier.toJK(),
|
nameIdentifier.toJK(),
|
||||||
with(expressionTreeMapper) { argumentList?.toJK() ?: JKArgumentListImpl() },
|
with(expressionTreeMapper) { argumentList?.toJK() ?: JKArgumentListImpl() },
|
||||||
initializingClass?.createClassBody() ?: JKEmptyClassBodyImpl(),
|
initializingClass?.createClassBody() ?: JKEmptyClassBodyImpl(),
|
||||||
JKTypeElementImpl(JKClassTypeImpl(symbolProvider.provideDirectSymbol(containingClass!!) as JKClassSymbol, emptyList()))
|
JKTypeElementImpl(
|
||||||
|
JKClassTypeImpl(
|
||||||
|
symbolProvider.provideDirectSymbol(containingClass ?: throwCanNotConvertError()) as JKClassSymbol,
|
||||||
|
emptyList()
|
||||||
|
)
|
||||||
|
)
|
||||||
).also {
|
).also {
|
||||||
symbolProvider.provideUniverseSymbol(this, it)
|
symbolProvider.provideUniverseSymbol(this, it)
|
||||||
it.psi = this
|
it.psi = this
|
||||||
@@ -658,13 +669,15 @@ class JavaToJKTreeBuilder constructor(
|
|||||||
|
|
||||||
fun PsiAnnotation.toJK(): JKAnnotation =
|
fun PsiAnnotation.toJK(): JKAnnotation =
|
||||||
JKAnnotationImpl(
|
JKAnnotationImpl(
|
||||||
symbolProvider.provideSymbolForReference<JKSymbol>(nameReferenceElement!!).safeAs<JKClassSymbol>()
|
symbolProvider.provideSymbolForReference<JKSymbol>(
|
||||||
?: JKUnresolvedClassSymbol(nameReferenceElement!!.text),
|
nameReferenceElement ?: throwCanNotConvertError()
|
||||||
|
).safeAs<JKClassSymbol>()
|
||||||
|
?: JKUnresolvedClassSymbol(nameReferenceElement?.text ?: throwCanNotConvertError()),
|
||||||
parameterList.attributes.map { parameter ->
|
parameterList.attributes.map { parameter ->
|
||||||
if (parameter.nameIdentifier != null) {
|
if (parameter.nameIdentifier != null) {
|
||||||
JKAnnotationNameParameterImpl(
|
JKAnnotationNameParameterImpl(
|
||||||
parameter.value?.toJK() ?: JKStubExpressionImpl(),
|
parameter.value?.toJK() ?: JKStubExpressionImpl(),
|
||||||
JKNameIdentifierImpl(parameter.name!!)
|
JKNameIdentifierImpl(parameter.name ?: throwCanNotConvertError())
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
JKAnnotationParameterImpl(
|
JKAnnotationParameterImpl(
|
||||||
@@ -694,7 +707,7 @@ class JavaToJKTreeBuilder constructor(
|
|||||||
JKKtAnnotationArrayInitializerExpressionImpl(
|
JKKtAnnotationArrayInitializerExpressionImpl(
|
||||||
initializers.map { it.toJK() }
|
initializers.map { it.toJK() }
|
||||||
)
|
)
|
||||||
else -> TODO(this::class.toString())
|
else -> throwCanNotConvertError()
|
||||||
}.also {
|
}.also {
|
||||||
it.assignNonCodeElements(this)
|
it.assignNonCodeElements(this)
|
||||||
}
|
}
|
||||||
@@ -703,7 +716,7 @@ class JavaToJKTreeBuilder constructor(
|
|||||||
JKJavaAnnotationMethodImpl(
|
JKJavaAnnotationMethodImpl(
|
||||||
returnType?.toJK(symbolProvider)?.asTypeElement()
|
returnType?.toJK(symbolProvider)?.asTypeElement()
|
||||||
?: JKTypeElementImpl(JKJavaVoidType).takeIf { isConstructor }
|
?: JKTypeElementImpl(JKJavaVoidType).takeIf { isConstructor }
|
||||||
?: TODO(),
|
?: throwCanNotConvertError("type of PsiAnnotationMethod can not be retrieved"),
|
||||||
nameIdentifier.toJK(),
|
nameIdentifier.toJK(),
|
||||||
defaultValue?.toJK() ?: JKStubExpressionImpl()
|
defaultValue?.toJK() ?: JKStubExpressionImpl()
|
||||||
).also {
|
).also {
|
||||||
@@ -718,7 +731,7 @@ class JavaToJKTreeBuilder constructor(
|
|||||||
return JKJavaMethodImpl(
|
return JKJavaMethodImpl(
|
||||||
returnType?.toJK(symbolProvider)?.asTypeElement()
|
returnType?.toJK(symbolProvider)?.asTypeElement()
|
||||||
?: JKTypeElementImpl(JKJavaVoidType).takeIf { isConstructor }
|
?: JKTypeElementImpl(JKJavaVoidType).takeIf { isConstructor }
|
||||||
?: TODO(),
|
?: throwCanNotConvertError("type of PsiAnnotationMethod can not be retrieved"),
|
||||||
nameIdentifier.toJK(),
|
nameIdentifier.toJK(),
|
||||||
parameterList.parameters.map { it.toJK() },
|
parameterList.parameters.map { it.toJK() },
|
||||||
body?.toJK() ?: JKBodyStubImpl,
|
body?.toJK() ?: JKBodyStubImpl,
|
||||||
@@ -794,7 +807,7 @@ class JavaToJKTreeBuilder constructor(
|
|||||||
when (it) {
|
when (it) {
|
||||||
is PsiClass -> it.toJK()
|
is PsiClass -> it.toJK()
|
||||||
is PsiLocalVariable -> it.toJK()
|
is PsiLocalVariable -> it.toJK()
|
||||||
else -> TODO(it::class.java.toString())
|
else -> it.throwCanNotConvertError()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
is PsiAssertStatement ->
|
is PsiAssertStatement ->
|
||||||
@@ -884,7 +897,7 @@ class JavaToJKTreeBuilder constructor(
|
|||||||
with(expressionTreeMapper) { lockExpression?.toJK() } ?: JKStubExpressionImpl(),
|
with(expressionTreeMapper) { lockExpression?.toJK() } ?: JKStubExpressionImpl(),
|
||||||
body?.toJK() ?: JKBodyStubImpl
|
body?.toJK() ?: JKBodyStubImpl
|
||||||
)
|
)
|
||||||
else -> TODO("for ${this::class}")
|
else -> throwCanNotConvertError()
|
||||||
}.also {
|
}.also {
|
||||||
if (this != null) {
|
if (this != null) {
|
||||||
(it as PsiOwner).psi = this
|
(it as PsiOwner).psi = this
|
||||||
@@ -894,19 +907,21 @@ class JavaToJKTreeBuilder constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun PsiCatchSection.toJK(): JKJavaTryCatchSection =
|
fun PsiCatchSection.toJK(): JKJavaTryCatchSection =
|
||||||
JKJavaTryCatchSectionImpl(parameter?.toJK()!!, catchBlock?.toJK() ?: JKBodyStubImpl)
|
JKJavaTryCatchSectionImpl(
|
||||||
.also {
|
parameter?.toJK() ?: throwCanNotConvertError(),
|
||||||
it.psi = this
|
catchBlock?.toJK() ?: JKBodyStubImpl
|
||||||
}.also {
|
).also {
|
||||||
it.assignNonCodeElements(this)
|
it.psi = this
|
||||||
}
|
}.also {
|
||||||
|
it.assignNonCodeElements(this)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO better way than generateSequence.last??
|
//TODO better way than generateSequence.last??
|
||||||
fun PsiLabeledStatement.collectLabels(): Pair<List<PsiIdentifier>, PsiStatement> =
|
fun PsiLabeledStatement.collectLabels(): Pair<List<PsiIdentifier>, PsiStatement> =
|
||||||
generateSequence(emptyList<PsiIdentifier>() to this as PsiStatement) { (labels, statement) ->
|
generateSequence(emptyList<PsiIdentifier>() to this as PsiStatement) { (labels, statement) ->
|
||||||
if (statement !is PsiLabeledStatementImpl) return@generateSequence null
|
if (statement !is PsiLabeledStatementImpl) return@generateSequence null
|
||||||
(labels + statement.labelIdentifier) to statement.statement!!
|
(labels + statement.labelIdentifier) to (statement.statement ?: throwCanNotConvertError())
|
||||||
}.last()
|
}.last()
|
||||||
|
|
||||||
|
|
||||||
@@ -934,7 +949,7 @@ class JavaToJKTreeBuilder constructor(
|
|||||||
|
|
||||||
private fun PsiElement.collectNonCodeElements(): Pair<List<JKNonCodeElement>, List<JKNonCodeElement>> {
|
private fun PsiElement.collectNonCodeElements(): Pair<List<JKNonCodeElement>, List<JKNonCodeElement>> {
|
||||||
fun PsiElement.toToken(): JKNonCodeElement? {
|
fun PsiElement.toToken(): JKNonCodeElement? {
|
||||||
if (this in tokenCache) return tokenCache[this]!!
|
if (this in tokenCache) return tokenCache.getValue(this)
|
||||||
val token = when {
|
val token = when {
|
||||||
this is PsiDocComment ->
|
this is PsiDocComment ->
|
||||||
JKCommentElementImpl(IdeaDocCommentConverter.convertDocComment(this))
|
JKCommentElementImpl(IdeaDocCommentConverter.convertDocComment(this))
|
||||||
@@ -1001,5 +1016,10 @@ class JavaToJKTreeBuilder constructor(
|
|||||||
|
|
||||||
private inline fun <reified T : JKNonCodeElementsListOwner> T.withAssignedNonCodeElements(psi: PsiElement?): T =
|
private inline fun <reified T : JKNonCodeElementsListOwner> T.withAssignedNonCodeElements(psi: PsiElement?): T =
|
||||||
also { it.assignNonCodeElements(psi) }
|
also { it.assignNonCodeElements(psi) }
|
||||||
|
|
||||||
|
private fun PsiElement.throwCanNotConvertError(message: String? = null): Nothing {
|
||||||
|
error("Cannot convert the following Java element ${this::class} with text `$text`" + message?.let { " due to `$it`" }.orEmpty())
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user