New J2K: remove extra interfaces in AST structure & split AST definitions to proper files

This commit is contained in:
Ilya Kirillov
2019-09-06 23:26:43 +03:00
parent fd85c2bb43
commit be94eb5405
86 changed files with 3227 additions and 4525 deletions
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.nj2k
import org.jetbrains.kotlin.nj2k.tree.JKTreeElement
import org.jetbrains.kotlin.nj2k.types.JKTypeFactory
@@ -44,10 +44,9 @@ import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.nj2k.symbols.*
import org.jetbrains.kotlin.nj2k.tree.*
import org.jetbrains.kotlin.nj2k.tree.JKLiteralExpression.LiteralType.*
import org.jetbrains.kotlin.nj2k.tree.impl.*
import org.jetbrains.kotlin.nj2k.types.JKJavaArrayType
import org.jetbrains.kotlin.nj2k.types.JKJavaPrimitiveType
import org.jetbrains.kotlin.nj2k.types.JKTypeFactory
import org.jetbrains.kotlin.nj2k.types.*
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
import org.jetbrains.kotlin.psi.psiUtil.isExtensionDeclaration
@@ -71,17 +70,17 @@ class JavaToJKTreeBuilder constructor(
private val declarationMapper = DeclarationMapper(expressionTreeMapper)
private fun PsiJavaFile.toJK(): JKFile =
JKFileImpl(
packageStatement?.toJK() ?: JKPackageDeclarationImpl(JKNameIdentifierImpl("")),
JKFile(
packageStatement?.toJK() ?: JKPackageDeclaration(JKNameIdentifier("")),
importList.toJK(),
with(declarationMapper) { classes.map { it.toJK() } }
)
private fun PsiImportList?.toJK(): JKImportList =
JKImportListImpl(this?.allImportStatements?.mapNotNull { it.toJK() }.orEmpty())
JKImportList(this?.allImportStatements?.mapNotNull { it.toJK() }.orEmpty())
private fun PsiPackageStatement.toJK(): JKPackageDeclaration =
JKPackageDeclarationImpl(JKNameIdentifierImpl(packageName))
JKPackageDeclaration(JKNameIdentifier(packageName))
.also {
it.assignNonCodeElements(this)
}
@@ -97,7 +96,7 @@ class JavaToJKTreeBuilder constructor(
?: target.safeAs<KtLightClassForDecompiledDeclaration>()?.fqName?.parent()?.asString()?.let { "$it.*" }
?: rawName
return JKImportStatementImpl(JKNameIdentifierImpl(name))
return JKImportStatement(JKNameIdentifier(name))
.also {
it.assignNonCodeElements(this)
}
@@ -105,16 +104,16 @@ class JavaToJKTreeBuilder constructor(
private fun PsiIdentifier?.toJK(): JKNameIdentifier =
this?.let {
JKNameIdentifierImpl(it.text).also {
JKNameIdentifier(it.text).also {
it.assignNonCodeElements(this)
}
} ?: JKNameIdentifierImpl("")
} ?: JKNameIdentifier("")
private inner class ExpressionTreeMapper {
fun PsiExpression?.toJK(): JKExpression {
return when (this) {
null -> JKStubExpressionImpl()
null -> JKStubExpression()
is PsiBinaryExpression -> toJK()
is PsiPrefixExpression -> toJK()
is PsiPostfixExpression -> toJK()
@@ -128,14 +127,14 @@ class JavaToJKTreeBuilder constructor(
is PsiAssignmentExpression -> toJK()
is PsiInstanceOfExpression -> toJK()
is PsiThisExpression ->
JKThisExpressionImpl(
qualifier?.referenceName?.let { JKLabelTextImpl(JKNameIdentifierImpl(it)) } ?: JKLabelEmptyImpl()
JKThisExpression(
qualifier?.referenceName?.let { JKLabelText(JKNameIdentifier(it)) } ?: JKLabelEmpty()
)
is PsiSuperExpression ->
JKSuperExpressionImpl(
qualifier?.referenceName?.let { JKLabelTextImpl(JKNameIdentifierImpl(it)) } ?: JKLabelEmptyImpl()
JKSuperExpression(
qualifier?.referenceName?.let { JKLabelText(JKNameIdentifier(it)) } ?: JKLabelEmpty()
)
is PsiConditionalExpression -> JKIfElseExpressionImpl(
is PsiConditionalExpression -> JKIfElseExpression(
condition.toJK(), thenExpression.toJK(), elseExpression.toJK()
)
is PsiPolyadicExpression -> {
@@ -143,7 +142,7 @@ class JavaToJKTreeBuilder constructor(
val type = type?.toJK() ?: typeFactory.types.nullableAny
val jkOperands = operands.map { it.toJK().parenthesizeIfBinaryExpression() }
jkOperands.reduce { acc, operand ->
JKBinaryExpressionImpl(acc, operand, JKKtOperatorImpl(token, type))
JKBinaryExpression(acc, operand, JKKtOperatorImpl(token, type))
}.let { folded ->
if (jkOperands.any { it.containsNewLine() }) folded.parenthesize()
else folded
@@ -163,26 +162,26 @@ class JavaToJKTreeBuilder constructor(
fun PsiClassObjectAccessExpressionImpl.toJK(): JKClassLiteralExpression {
val type = operand.type.toJK().updateNullabilityRecursively(Nullability.NotNull)
return JKClassLiteralExpressionImpl(
JKTypeElementImpl(type),
return JKClassLiteralExpression(
JKTypeElement(type),
when (type) {
is JKJavaPrimitiveType -> JKClassLiteralExpression.LiteralType.JAVA_PRIMITIVE_CLASS
is JKJavaVoidType -> JKClassLiteralExpression.LiteralType.JAVA_VOID_TYPE
else -> JKClassLiteralExpression.LiteralType.JAVA_CLASS
is JKJavaPrimitiveType -> JKClassLiteralExpression.ClassLiteralType.JAVA_PRIMITIVE_CLASS
is JKJavaVoidType -> JKClassLiteralExpression.ClassLiteralType.JAVA_VOID_TYPE
else -> JKClassLiteralExpression.ClassLiteralType.JAVA_CLASS
}
).also {
it.assignNonCodeElements(this)
}
}
fun PsiInstanceOfExpression.toJK(): JKKtIsExpression =
JKKtIsExpressionImpl(operand.toJK(), JKTypeElementImpl(checkType?.type?.toJK() ?: JKNoTypeImpl))
fun PsiInstanceOfExpression.toJK(): JKIsExpression =
JKIsExpression(operand.toJK(), JKTypeElement(checkType?.type?.toJK() ?: JKNoTypeImpl))
.also {
it.assignNonCodeElements(this)
}
fun PsiAssignmentExpression.toJK(): JKJavaAssignmentExpression {
return JKJavaAssignmentExpressionImpl(
return JKJavaAssignmentExpression(
lExpression.toJK(),
rExpression.toJK(),
createOperator(operationSign.tokenType, type)
@@ -201,7 +200,7 @@ class JavaToJKTreeBuilder constructor(
}
else -> JKOperatorToken.fromElementType(operationSign.tokenType)
}
return JKBinaryExpressionImpl(
return JKBinaryExpression(
lOperand.toJK(),
rOperand.toJK(),
JKKtOperatorImpl(
@@ -216,16 +215,16 @@ class JavaToJKTreeBuilder constructor(
fun PsiLiteralExpression.toJK(): JKLiteralExpression {
require(this is PsiLiteralExpressionImpl)
return when (this.literalElementType) {
JavaTokenType.NULL_KEYWORD -> JKNullLiteral()
JavaTokenType.TRUE_KEYWORD -> JKBooleanLiteral(true)
JavaTokenType.FALSE_KEYWORD -> JKBooleanLiteral(false)
JavaTokenType.STRING_LITERAL -> JKJavaLiteralExpressionImpl(text, STRING)
JavaTokenType.CHARACTER_LITERAL -> JKJavaLiteralExpressionImpl(text, CHAR)
JavaTokenType.INTEGER_LITERAL -> JKJavaLiteralExpressionImpl(text, INT)
JavaTokenType.LONG_LITERAL -> JKJavaLiteralExpressionImpl(text, LONG)
JavaTokenType.FLOAT_LITERAL -> JKJavaLiteralExpressionImpl(text, FLOAT)
JavaTokenType.DOUBLE_LITERAL -> JKJavaLiteralExpressionImpl(text, DOUBLE)
return when (literalElementType) {
JavaTokenType.NULL_KEYWORD -> JKLiteralExpression("null", NULL)
JavaTokenType.TRUE_KEYWORD -> JKLiteralExpression("true", BOOLEAN)
JavaTokenType.FALSE_KEYWORD -> JKLiteralExpression("false", BOOLEAN)
JavaTokenType.STRING_LITERAL -> JKLiteralExpression(text, STRING)
JavaTokenType.CHARACTER_LITERAL -> JKLiteralExpression(text, CHAR)
JavaTokenType.INTEGER_LITERAL -> JKLiteralExpression(text, INT)
JavaTokenType.LONG_LITERAL -> JKLiteralExpression(text, LONG)
JavaTokenType.FLOAT_LITERAL -> JKLiteralExpression(text, FLOAT)
JavaTokenType.DOUBLE_LITERAL -> JKLiteralExpression(text, DOUBLE)
else -> error("Unknown literal element type: ${this.literalElementType}")
}.also {
it.assignNonCodeElements(this)
@@ -240,23 +239,23 @@ class JavaToJKTreeBuilder constructor(
fun PsiPrefixExpression.toJK(): JKExpression = when (operationSign.tokenType) {
JavaTokenType.TILDE -> operand.toJK().callOn(symbolProvider.provideMethodSymbol("kotlin.Int.inv"))
else -> JKPrefixExpressionImpl(operand.toJK(), createOperator(operationSign.tokenType, type))
else -> JKPrefixExpression(operand.toJK(), createOperator(operationSign.tokenType, type))
}.also {
it.assignNonCodeElements(this)
}
fun PsiPostfixExpression.toJK(): JKExpression =
JKPostfixExpressionImpl(operand.toJK(), createOperator(operationSign.tokenType, type)).also {
JKPostfixExpression(operand.toJK(), createOperator(operationSign.tokenType, type)).also {
it.assignNonCodeElements(this)
}
fun PsiLambdaExpression.toJK(): JKExpression {
return JKLambdaExpressionImpl(
return JKLambdaExpression(
body.let {
when (it) {
is PsiExpression -> JKExpressionStatementImpl(it.toJK())
is PsiCodeBlock -> JKBlockStatementImpl(with(declarationMapper) { it.toJK() })
else -> JKBlockStatementImpl(JKBodyStubImpl)
is PsiExpression -> JKExpressionStatement(it.toJK())
is PsiCodeBlock -> JKBlockStatement(with(declarationMapper) { it.toJK() })
else -> JKBlockStatement(JKBodyStub)
}
},
with(declarationMapper) { parameterList.parameters.map { it.toJK() } },
@@ -294,11 +293,11 @@ class JavaToJKTreeBuilder constructor(
return when {
methodExpression.referenceNameElement is PsiKeyword -> {
val callee = when ((methodExpression.referenceNameElement as PsiKeyword).tokenType) {
SUPER_KEYWORD -> JKSuperExpressionImpl()
THIS_KEYWORD -> JKThisExpressionImpl(JKLabelEmptyImpl())
SUPER_KEYWORD -> JKSuperExpression()
THIS_KEYWORD -> JKThisExpression(JKLabelEmpty())
else -> throwCanNotConvertError("unknown keyword in callee position")
}
JKDelegationConstructorCallImpl(symbol as JKMethodSymbol, callee, arguments.toJK())
JKDelegationConstructorCall(symbol as JKMethodSymbol, callee, arguments.toJK())
}
target is KtLightMethod -> {
@@ -308,14 +307,14 @@ class JavaToJKTreeBuilder constructor(
if (origin.isExtensionDeclaration()) {
val receiver = arguments.expressions.firstOrNull()?.toJK()?.parenthesizeIfBinaryExpression()
origin.fqName?.also { importStorage.addImport(it) }
JKJavaMethodCallExpressionImpl(
JKCallExpressionImpl(
symbolProvider.provideDirectSymbol(origin) as JKMethodSymbol,
arguments.expressions.drop(1).map { it.toJK() }.toArgumentList(),
typeArguments
).qualified(receiver)
} else {
origin.fqName?.also { importStorage.addImport(it) }
JKJavaMethodCallExpressionImpl(
JKCallExpressionImpl(
symbolProvider.provideDirectSymbol(origin) as JKMethodSymbol,
arguments.toJK(),
typeArguments
@@ -329,13 +328,12 @@ class JavaToJKTreeBuilder constructor(
else origin as KtNamedDeclaration
val parameterCount = target.parameterList.parameters.size
val propertyAccessExpression =
JKFieldAccessExpressionImpl(symbolProvider.provideDirectSymbol(property) as JKFieldSymbol)
JKFieldAccessExpression(symbolProvider.provideDirectSymbol(property) as JKFieldSymbol)
val isExtension = property.isExtensionDeclaration()
val isTopLevel = origin.getStrictParentOfType<KtClassOrObject>() == null
val propertyAccess = if (isTopLevel) {
if (isExtension) JKQualifiedExpressionImpl(
if (isExtension) JKQualifiedExpression(
arguments.expressions.first().toJK(),
JKJavaQualifierImpl.DOT,
propertyAccessExpression
)
else propertyAccessExpression
@@ -347,7 +345,7 @@ class JavaToJKTreeBuilder constructor(
1 /* setter */ -> {
val argument = (arguments.expressions[if (isExtension) 1 else 0]).toJK()
JKJavaAssignmentExpressionImpl(
JKJavaAssignmentExpression(
propertyAccess,
argument,
createOperator(JavaTokenType.EQ, type)//TODO correct type
@@ -358,7 +356,7 @@ class JavaToJKTreeBuilder constructor(
}
else -> {
JKJavaMethodCallExpressionImpl(
JKCallExpressionImpl(
JKMultiverseMethodSymbol(target, typeFactory),
arguments.toJK(),
typeArguments
@@ -368,10 +366,10 @@ class JavaToJKTreeBuilder constructor(
}
symbol is JKMethodSymbol ->
JKJavaMethodCallExpressionImpl(symbol, arguments.toJK(), typeArguments)
JKCallExpressionImpl(symbol, arguments.toJK(), typeArguments)
.qualified(qualifier)
symbol is JKFieldSymbol ->
JKFieldAccessExpressionImpl(symbol).qualified(qualifier)
JKFieldAccessExpression(symbol).qualified(qualifier)
else -> throwCanNotConvertError("unexpected symbol ${symbol::class}")
}.also {
it.assignNonCodeElements(this)
@@ -385,7 +383,7 @@ class JavaToJKTreeBuilder constructor(
}?.takeUnless { type ->
type.isKotlinFunctionalType
}?.toJK()
?.asTypeElement() ?: JKTypeElementImpl(JKNoTypeImpl)
?.asTypeElement() ?: JKTypeElement(JKNoTypeImpl)
fun PsiMethodReferenceExpression.toJK(): JKMethodReferenceExpression {
val symbol = symbolProvider.provideSymbolForReference<JKSymbol>(this).let { symbol ->
@@ -396,8 +394,8 @@ class JavaToJKTreeBuilder constructor(
}
}
return JKMethodReferenceExpressionImpl(
qualifierExpression?.toJK() ?: JKStubExpressionImpl(),
return JKMethodReferenceExpression(
qualifierExpression?.toJK() ?: JKStubExpression(),
symbol,
functionalType(),
isConstructor
@@ -409,19 +407,19 @@ class JavaToJKTreeBuilder constructor(
val target = resolve()
if (target is KtLightClassForFacade
|| target is KtLightClassForDecompiledDeclaration
) return JKStubExpressionImpl()
) return JKStubExpression()
if (target is KtLightField
&& target.name == "INSTANCE"
&& target.containingClass.kotlinOrigin is KtObjectDeclaration
) {
return qualifierExpression?.toJK() ?: JKStubExpressionImpl()
return qualifierExpression?.toJK() ?: JKStubExpression()
}
val symbol = symbolProvider.provideSymbolForReference<JKSymbol>(this)
return when (symbol) {
is JKClassSymbol -> JKClassAccessExpressionImpl(symbol)
is JKFieldSymbol -> JKFieldAccessExpressionImpl(symbol)
is JKPackageSymbol -> JKPackageAccessExpressionImpl(symbol)
is JKClassSymbol -> JKClassAccessExpression(symbol)
is JKFieldSymbol -> JKFieldAccessExpression(symbol)
is JKPackageSymbol -> JKPackageAccessExpression(symbol)
else -> throwCanNotConvertError("unexpected symbol ${symbol::class}")
}.qualified(qualifierExpression?.toJK()).also {
it.assignNonCodeElements(this)
@@ -429,9 +427,9 @@ class JavaToJKTreeBuilder constructor(
}
fun PsiArrayInitializerExpression.toJK(): JKExpression {
return JKJavaNewArrayImpl(
return JKJavaNewArray(
initializers.map { it.toJK() },
JKTypeElementImpl(type?.toJK().safeAs<JKJavaArrayType>()?.type ?: JKContextType)
JKTypeElement(type?.toJK().safeAs<JKJavaArrayType>()?.type ?: JKContextType)
).also {
it.assignNonCodeElements(this)
}
@@ -455,9 +453,9 @@ class JavaToJKTreeBuilder constructor(
}
child = child.nextSibling
}
JKJavaNewEmptyArrayImpl(
dimensions.map { it?.toJK() ?: JKStubExpressionImpl() },
JKTypeElementImpl(generateSequence(type?.toJK()) { it.safeAs<JKJavaArrayType>()?.type }.last())
JKJavaNewEmptyArray(
dimensions.map { it?.toJK() ?: JKStubExpression() },
JKTypeElement(generateSequence(type?.toJK()) { it.safeAs<JKJavaArrayType>()?.type }.last())
).also {
it.psi = this
}
@@ -476,29 +474,28 @@ class JavaToJKTreeBuilder constructor(
?: classOrAnonymousClassReference
?.typeParameters
?.let { typeParameters ->
JKTypeArgumentListImpl(typeParameters.map { JKTypeElementImpl(it.toJK()) })
} ?: JKTypeArgumentListImpl()
JKJavaNewExpressionImpl(
JKTypeArgumentList(typeParameters.map { JKTypeElement(it.toJK()) })
} ?: JKTypeArgumentList()
JKNewExpression(
classSymbol,
argumentList?.toJK() ?: JKArgumentListImpl(),
argumentList?.toJK() ?: JKArgumentList(),
typeArgumentList,
with(declarationMapper) { anonymousClass?.createClassBody() } ?: JKEmptyClassBodyImpl()
with(declarationMapper) { anonymousClass?.createClassBody() } ?: JKClassBody(),
anonymousClass != null
)
}
return qualifier?.let {
JKQualifiedExpressionImpl(it.toJK(), JKJavaQualifierImpl.DOT, newExpression)
} ?: newExpression
return newExpression.qualified(qualifier?.toJK())
}
fun PsiReferenceParameterList.toJK(): JKTypeArgumentList =
JKTypeArgumentListImpl(this.typeArguments.map { JKTypeElementImpl(it.toJK()) })
JKTypeArgumentList(typeArguments.map { JKTypeElement(it.toJK()) })
.also {
it.assignNonCodeElements(this)
}
fun PsiArrayAccessExpression.toJK(): JKExpression {
return JKArrayAccessExpressionImpl(
return JKArrayAccessExpression(
arrayExpression.toJK(),
indexExpression?.toJK() ?: throwCanNotConvertError()
).also {
@@ -507,7 +504,7 @@ class JavaToJKTreeBuilder constructor(
}
fun PsiTypeCastExpression.toJK(): JKExpression {
return JKTypeCastExpressionImpl(
return JKTypeCastExpression(
operand?.toJK() ?: throwCanNotConvertError(),
castType?.type?.toJK()?.asTypeElement() ?: throwCanNotConvertError()
).also {
@@ -516,7 +513,7 @@ class JavaToJKTreeBuilder constructor(
}
fun PsiParenthesizedExpression.toJK(): JKExpression {
return JKParenthesizedExpressionImpl(expression.toJK())
return JKParenthesizedExpression(expression.toJK())
.also {
it.assignNonCodeElements(this)
}
@@ -532,7 +529,7 @@ class JavaToJKTreeBuilder constructor(
&& lastExpressionType is PsiArrayType
) {
val staredExpression =
JKPrefixExpressionImpl(
JKPrefixExpression(
jkExpressions.last(),
JKKtSpreadOperator(lastExpressionType.toJK())
).withNonCodeElementsFrom(jkExpressions.last())
@@ -550,45 +547,42 @@ class JavaToJKTreeBuilder constructor(
private inner class DeclarationMapper(val expressionTreeMapper: ExpressionTreeMapper) {
fun PsiTypeParameterList.toJK(): JKTypeParameterList =
JKTypeParameterListImpl(typeParameters.map { it.toJK() })
JKTypeParameterList(typeParameters.map { it.toJK() })
.also {
it.assignNonCodeElements(this)
}
fun PsiTypeParameter.toJK(): JKTypeParameter =
JKTypeParameterImpl(
JKTypeParameter(
nameIdentifier.toJK(),
extendsListTypes.map { JKTypeElementImpl(it.toJK()) }
extendsListTypes.map { JKTypeElement(it.toJK()) }
).also {
symbolProvider.provideUniverseSymbol(this, it)
it.assignNonCodeElements(this)
}
fun PsiClass.toJK(): JKClass =
JKClassImpl(
JKClass(
nameIdentifier.toJK(),
inheritanceInfo(),
classKind(),
typeParameterList?.toJK() ?: JKTypeParameterListImpl(),
typeParameterList?.toJK() ?: JKTypeParameterList(),
createClassBody(),
annotationList(this),
otherModifiers(),
visibility(),
modality()
).also { jkClassImpl ->
jkClassImpl.psi = this
symbolProvider.provideUniverseSymbol(this, jkClassImpl)
}.also {
it.assignNonCodeElements(this)
).also { klass ->
klass.psi = this
symbolProvider.provideUniverseSymbol(this, klass)
klass.assignNonCodeElements(this)
}
fun PsiClass.inheritanceInfo(): JKInheritanceInfo {
val implTypes =
implementsList?.referencedTypes?.map { JKTypeElementImpl(it.toJK()) }.orEmpty()
val extensionType =
extendsList?.referencedTypes?.map { JKTypeElementImpl(it.toJK()) }.orEmpty()
return JKInheritanceInfoImpl(extensionType, implTypes)
val implTypes = implementsList?.referencedTypes?.map { JKTypeElement(it.toJK()) }.orEmpty()
val extensionType = extendsList?.referencedTypes?.map { JKTypeElement(it.toJK()) }.orEmpty()
return JKInheritanceInfo(extensionType, implTypes)
.also {
if (implementsList != null) {
it.assignNonCodeElements(implementsList!!)
@@ -597,7 +591,7 @@ class JavaToJKTreeBuilder constructor(
}
fun PsiClass.createClassBody() =
JKClassBodyImpl(
JKClassBody(
children.mapNotNull {
when (it) {
is PsiEnumConstant -> it.toJK()
@@ -614,21 +608,20 @@ class JavaToJKTreeBuilder constructor(
it.rightBrace.assignNonCodeElements(rBrace)
}
fun PsiClassInitializer.toJK(): JKDeclaration =
(if (hasModifier(JvmModifier.STATIC))
JKJavaStaticInitDeclarationImpl(body.toJK())
else JKKtInitDeclarationImpl(body.toJK()))
.also {
it.assignNonCodeElements(this)
}
fun PsiClassInitializer.toJK(): JKDeclaration = when {
hasModifier(JvmModifier.STATIC) -> JKJavaStaticInitDeclaration(body.toJK())
else -> JKKtInitDeclaration(body.toJK())
}.also {
it.assignNonCodeElements(this)
}
fun PsiEnumConstant.toJK(): JKEnumConstant =
JKEnumConstantImpl(
JKEnumConstant(
nameIdentifier.toJK(),
with(expressionTreeMapper) { argumentList?.toJK() ?: JKArgumentListImpl() },
initializingClass?.createClassBody() ?: JKEmptyClassBodyImpl(),
JKTypeElementImpl(
with(expressionTreeMapper) { argumentList?.toJK() ?: JKArgumentList() },
initializingClass?.createClassBody() ?: JKClassBody(),
JKTypeElement(
JKClassTypeImpl(
symbolProvider.provideDirectSymbol(containingClass ?: throwCanNotConvertError()) as JKClassSymbol,
emptyList()
@@ -637,13 +630,12 @@ class JavaToJKTreeBuilder constructor(
).also {
symbolProvider.provideUniverseSymbol(this, it)
it.psi = this
}.also {
it.assignNonCodeElements(this)
}
fun PsiMember.modality() =
modality({ ast, psi -> ast.assignNonCodeElements(psi) })
modality { ast, psi -> ast.assignNonCodeElements(psi) }
fun PsiMember.otherModifiers() =
modifierList?.children?.mapNotNull { child ->
@@ -658,7 +650,7 @@ class JavaToJKTreeBuilder constructor(
else -> null
}?.let {
JKOtherModifierElementImpl(it).withAssignedNonCodeElements(child)
JKOtherModifierElement(it).withAssignedNonCodeElements(child)
}
}.orEmpty()
@@ -666,28 +658,27 @@ class JavaToJKTreeBuilder constructor(
private fun PsiMember.visibility(): JKVisibilityModifierElement =
visibility(referenceSearcher) { ast, psi -> ast.assignNonCodeElements(psi) }
fun PsiField.toJK(): JKJavaField {
return JKJavaFieldImpl(
JKTypeElementImpl(type.toJK()).withAssignedNonCodeElements(typeElement),
fun PsiField.toJK(): JKField {
return JKField(
JKTypeElement(type.toJK()).withAssignedNonCodeElements(typeElement),
nameIdentifier.toJK(),
with(expressionTreeMapper) { initializer.toJK() },
annotationList(this),
otherModifiers(),
visibility(),
modality(),
JKMutabilityModifierElementImpl(Mutability.UNKNOWN)
JKMutabilityModifierElement(Mutability.UNKNOWN)
).also {
symbolProvider.provideUniverseSymbol(this, it)
it.psi = this
}.also {
it.assignNonCodeElements(this)
}
}
fun <T : PsiModifierListOwner> T.annotationList(docCommentOwner: PsiDocCommentOwner?): JKAnnotationList {
val plainAnnotations = annotations.map { it.cast<PsiAnnotation>().toJK() }
val deprecatedAnnotation = docCommentOwner?.docComment?.deprecatedAnnotation() ?: return JKAnnotationListImpl(plainAnnotations)
return JKAnnotationListImpl(
val deprecatedAnnotation = docCommentOwner?.docComment?.deprecatedAnnotation() ?: return JKAnnotationList(plainAnnotations)
return JKAnnotationList(
plainAnnotations.mapNotNull { annotation ->
if (annotation.classSymbol.fqName == "java.lang.Deprecated") null else annotation
} + deprecatedAnnotation
@@ -695,20 +686,20 @@ class JavaToJKTreeBuilder constructor(
}
fun PsiAnnotation.toJK(): JKAnnotation =
JKAnnotationImpl(
JKAnnotation(
symbolProvider.provideSymbolForReference<JKSymbol>(
nameReferenceElement ?: throwCanNotConvertError()
).safeAs<JKClassSymbol>()
?: JKUnresolvedClassSymbol(nameReferenceElement?.text ?: throwCanNotConvertError(), typeFactory),
parameterList.attributes.map { parameter ->
if (parameter.nameIdentifier != null) {
JKAnnotationNameParameterImpl(
parameter.value?.toJK() ?: JKStubExpressionImpl(),
JKNameIdentifierImpl(parameter.name ?: throwCanNotConvertError())
JKAnnotationNameParameter(
parameter.value?.toJK() ?: JKStubExpression(),
JKNameIdentifier(parameter.name ?: throwCanNotConvertError())
)
} else {
JKAnnotationParameterImpl(
parameter.value?.toJK() ?: JKStubExpressionImpl()
parameter.value?.toJK() ?: JKStubExpression()
)
}
}
@@ -718,7 +709,7 @@ class JavaToJKTreeBuilder constructor(
fun PsiDocComment.deprecatedAnnotation(): JKAnnotation? =
findTagByName("deprecated")?.let { tag ->
JKAnnotationImpl(
JKAnnotation(
symbolProvider.provideClassSymbol("kotlin.Deprecated"),
listOf(
JKAnnotationParameterImpl(stringLiteral(tag.content(), typeFactory))
@@ -731,40 +722,40 @@ class JavaToJKTreeBuilder constructor(
is PsiExpression -> with(expressionTreeMapper) { toJK() }
is PsiAnnotation -> toJK()
is PsiArrayInitializerMemberValue ->
JKKtAnnotationArrayInitializerExpressionImpl(
initializers.map { it.toJK() }
)
JKKtAnnotationArrayInitializerExpression(initializers.map { it.toJK() })
else -> throwCanNotConvertError()
}.also {
it.assignNonCodeElements(this)
}
fun PsiAnnotationMethod.toJK(): JKJavaAnnotationMethod =
JKJavaAnnotationMethodImpl(
JKJavaAnnotationMethod(
returnType?.toJK()?.asTypeElement()
?: JKTypeElementImpl(JKJavaVoidType).takeIf { isConstructor }
?: JKTypeElement(JKJavaVoidType).takeIf { isConstructor }
?: throwCanNotConvertError("type of PsiAnnotationMethod can not be retrieved"),
nameIdentifier.toJK(),
defaultValue?.toJK() ?: JKStubExpressionImpl()
defaultValue?.toJK() ?: JKStubExpression(),
otherModifiers(),
visibility(),
modality()
).also {
it.psi = this
symbolProvider.provideUniverseSymbol(this, it)
}.also {
it.assignNonCodeElements(this)
}
fun PsiMethod.toJK(): JKJavaMethod {
return JKJavaMethodImpl(
fun PsiMethod.toJK(): JKMethod {
return JKMethodImpl(
returnType?.toJK()?.asTypeElement()
?: JKTypeElementImpl(JKJavaVoidType).takeIf { isConstructor }
?: JKTypeElement(JKJavaVoidType).takeIf { isConstructor }
?: throwCanNotConvertError("type of PsiAnnotationMethod can not be retrieved"),
nameIdentifier.toJK(),
parameterList.parameters.map { it.toJK() },
body?.toJK() ?: JKBodyStubImpl,
typeParameterList?.toJK() ?: JKTypeParameterListImpl(),
body?.toJK() ?: JKBodyStub,
typeParameterList?.toJK() ?: JKTypeParameterList(),
annotationList(this),
throwsList.referencedTypes.map { JKTypeElementImpl(it.toJK()) },
throwsList.referencedTypes.map { JKTypeElement(it.toJK()) },
otherModifiers(),
visibility(),
modality()
@@ -783,9 +774,9 @@ class JavaToJKTreeBuilder constructor(
fun PsiParameter.toJK(): JKParameter {
val rawType = type.toJK()
val type =
if (isVarArgs && rawType is JKJavaArrayType) JKTypeElementImpl(rawType.type)
if (isVarArgs && rawType is JKJavaArrayType) JKTypeElement(rawType.type)
else rawType.asTypeElement()
return JKParameterImpl(
return JKParameter(
type,
nameIdentifier.toJK(),
isVarArgs,
@@ -808,11 +799,11 @@ class JavaToJKTreeBuilder constructor(
fun PsiLocalVariable.toJK(): JKLocalVariable =
JKLocalVariableImpl(
JKTypeElementImpl(type.toJK()).withAssignedNonCodeElements(typeElement),
JKLocalVariable(
JKTypeElement(type.toJK()).withAssignedNonCodeElements(typeElement),
nameIdentifier.toJK(),
with(expressionTreeMapper) { initializer.toJK() },
JKMutabilityModifierElementImpl(
JKMutabilityModifierElement(
if (hasModifierProperty(PsiModifier.FINAL)) Mutability.IMMUTABLE
else Mutability.UNKNOWN
),
@@ -826,11 +817,11 @@ class JavaToJKTreeBuilder constructor(
fun PsiStatement?.toJK(): JKStatement {
return when (this) {
null -> JKExpressionStatementImpl(JKStubExpressionImpl())
is PsiExpressionStatement -> JKExpressionStatementImpl(with(expressionTreeMapper) { expression.toJK() })
is PsiReturnStatement -> JKReturnStatementImpl(with(expressionTreeMapper) { returnValue.toJK() })
null -> JKExpressionStatement(JKStubExpression())
is PsiExpressionStatement -> JKExpressionStatement(with(expressionTreeMapper) { expression.toJK() })
is PsiReturnStatement -> JKReturnStatement(with(expressionTreeMapper) { returnValue.toJK() })
is PsiDeclarationStatement ->
JKDeclarationStatementImpl(declaredElements.map {
JKDeclarationStatement(declaredElements.map {
when (it) {
is PsiClass -> it.toJK()
is PsiLocalVariable -> it.toJK()
@@ -838,91 +829,87 @@ class JavaToJKTreeBuilder constructor(
}
})
is PsiAssertStatement ->
JKJavaAssertStatementImpl(
JKJavaAssertStatement(
with(expressionTreeMapper) { assertCondition.toJK() },
with(expressionTreeMapper) { assertDescription?.toJK() } ?: JKStubExpressionImpl())
with(expressionTreeMapper) { assertDescription?.toJK() } ?: JKStubExpression())
is PsiIfStatement ->
if (elseElement == null)
JKIfStatementImpl(with(expressionTreeMapper) { condition.toJK() }, thenBranch.toJK())
else
JKIfElseStatementImpl(with(expressionTreeMapper) { condition.toJK() }, thenBranch.toJK(), elseBranch.toJK())
with(expressionTreeMapper) {
JKIfElseStatement(condition.toJK(), thenBranch.toJK(), elseBranch.toJK())
}
is PsiForStatement -> JKJavaForLoopStatementImpl(
is PsiForStatement -> JKJavaForLoopStatement(
initialization.toJK(),
with(expressionTreeMapper) { condition.toJK() },
when (update) {
is PsiExpressionListStatement ->
(update as PsiExpressionListStatement).expressionList.expressions.map {
JKExpressionStatementImpl(with(expressionTreeMapper) { it.toJK() })
JKExpressionStatement(with(expressionTreeMapper) { it.toJK() })
}
else -> listOf(update.toJK())
},
body.toJK()
)
is PsiForeachStatement ->
JKForInStatementImpl(
JKForInStatement(
iterationParameter.toJK(),
with(expressionTreeMapper) { iteratedValue?.toJK() ?: JKStubExpressionImpl() },
with(expressionTreeMapper) { iteratedValue?.toJK() ?: JKStubExpression() },
body?.toJK() ?: blockStatement()
)
is PsiBlockStatement -> JKBlockStatementImpl(codeBlock.toJK())
is PsiWhileStatement -> JKWhileStatementImpl(with(expressionTreeMapper) { condition.toJK() }, body.toJK())
is PsiDoWhileStatement -> JKDoWhileStatementImpl(body.toJK(), with(expressionTreeMapper) { condition.toJK() })
is PsiBlockStatement -> JKBlockStatement(codeBlock.toJK())
is PsiWhileStatement -> JKWhileStatement(with(expressionTreeMapper) { condition.toJK() }, body.toJK())
is PsiDoWhileStatement -> JKDoWhileStatement(body.toJK(), with(expressionTreeMapper) { condition.toJK() })
is PsiSwitchStatement -> {
val cases = mutableListOf<JKJavaSwitchCase>()
for (statement in body?.statements.orEmpty()) {
when (statement) {
is PsiSwitchLabelStatement ->
cases += if (statement.isDefaultCase)
JKJavaDefaultSwitchCaseImpl(emptyList()).withAssignedNonCodeElements(statement)
else
JKJavaLabelSwitchCaseImpl(
cases += when {
statement.isDefaultCase -> JKJavaDefaultSwitchCase(emptyList())
else -> JKJavaLabelSwitchCase(
with(expressionTreeMapper) { statement.caseValue.toJK() },
emptyList()
).withAssignedNonCodeElements(statement)
)
}.withAssignedNonCodeElements(statement)
else ->
cases.lastOrNull()?.also { it.statements = it.statements + statement.toJK() }
?: run {
cases += JKJavaLabelSwitchCaseImpl(
JKStubExpressionImpl(),
cases += JKJavaLabelSwitchCase(
JKStubExpression(),
listOf(statement.toJK())
)
}
}
}
JKJavaSwitchStatementImpl(with(expressionTreeMapper) { expression.toJK() }, cases)
}
is PsiBreakStatement -> {
if (labelIdentifier != null)
JKBreakWithLabelStatementImpl(JKNameIdentifierImpl(labelIdentifier!!.text))
else
JKBreakStatementImpl()
JKJavaSwitchStatement(with(expressionTreeMapper) { expression.toJK() }, cases)
}
is PsiBreakStatement ->
JKBreakStatement(labelIdentifier?.let { JKLabelText(JKNameIdentifier(it.text)) } ?: JKLabelEmpty())
is PsiContinueStatement -> {
val label = labelIdentifier?.let {
JKLabelTextImpl(JKNameIdentifierImpl(it.text))
} ?: JKLabelEmptyImpl()
JKContinueStatementImpl(label)
JKLabelText(JKNameIdentifier(it.text))
} ?: JKLabelEmpty()
JKContinueStatement(label)
}
is PsiLabeledStatement -> {
val (labels, statement) = collectLabels()
JKLabeledStatementImpl(statement.toJK(), labels.map { JKNameIdentifierImpl(it.text) }).asStatement()
JKLabeledExpression(statement.toJK(), labels.map { JKNameIdentifier(it.text) }).asStatement()
}
is PsiEmptyStatement -> JKEmptyStatementImpl()
is PsiEmptyStatement -> JKEmptyStatement()
is PsiThrowStatement ->
JKJavaThrowStatementImpl(with(expressionTreeMapper) { exception.toJK() })
JKJavaThrowStatement(with(expressionTreeMapper) { exception.toJK() })
is PsiTryStatement ->
JKJavaTryStatementImpl(
JKJavaTryStatement(
resourceList?.toList()?.map { (it as PsiLocalVariable).toJK() }.orEmpty(),
tryBlock?.toJK() ?: JKBodyStubImpl,
finallyBlock?.toJK() ?: JKBodyStubImpl,
tryBlock?.toJK() ?: JKBodyStub,
finallyBlock?.toJK() ?: JKBodyStub,
catchSections.map { it.toJK() }
)
is PsiSynchronizedStatement ->
JKJavaSynchronizedStatementImpl(
with(expressionTreeMapper) { lockExpression?.toJK() } ?: JKStubExpressionImpl(),
body?.toJK() ?: JKBodyStubImpl
JKJavaSynchronizedStatement(
with(expressionTreeMapper) { lockExpression?.toJK() } ?: JKStubExpression(),
body?.toJK() ?: JKBodyStub
)
else -> throwCanNotConvertError()
}.also {
@@ -934,17 +921,15 @@ class JavaToJKTreeBuilder constructor(
}
fun PsiCatchSection.toJK(): JKJavaTryCatchSection =
JKJavaTryCatchSectionImpl(
JKJavaTryCatchSection(
parameter?.toJK() ?: throwCanNotConvertError(),
catchBlock?.toJK() ?: JKBodyStubImpl
catchBlock?.toJK() ?: JKBodyStub
).also {
it.psi = this
}.also {
it.assignNonCodeElements(this)
}
}
//TODO better way than generateSequence.last??
fun PsiLabeledStatement.collectLabels(): Pair<List<PsiIdentifier>, PsiStatement> =
generateSequence(emptyList<PsiIdentifier>() to this as PsiStatement) { (labels, statement) ->
if (statement !is PsiLabeledStatementImpl) return@generateSequence null
@@ -967,10 +952,10 @@ class JavaToJKTreeBuilder constructor(
if (psi.parent is PsiReferenceList) {
val factory = JavaPsiFacade.getInstance(psi.project).elementFactory
val type = factory.createType(psi)
JKTypeElementImpl(type.toJK().updateNullabilityRecursively(Nullability.NotNull))
JKTypeElement(type.toJK().updateNullabilityRecursively(Nullability.NotNull))
} else null
else -> null
}?.let { JKTreeRootImpl(it) }
}?.let { JKTreeRoot(it) }
private val tokenCache = mutableMapOf<PsiElement, JKNonCodeElement>()
@@ -979,9 +964,9 @@ class JavaToJKTreeBuilder constructor(
if (this in tokenCache) return tokenCache.getValue(this)
val token = when {
this is PsiDocComment ->
JKCommentElementImpl(IdeaDocCommentConverter.convertDocComment(this))
this is PsiComment -> JKCommentElementImpl(text)
this is PsiWhiteSpace -> JKSpaceElementImpl(text)
JKCommentElement(IdeaDocCommentConverter.convertDocComment(this))
this is PsiComment -> JKCommentElement(text)
this is PsiWhiteSpace -> JKSpaceElement(text)
text == ";" -> null
text == "" -> null
else -> error("Token should be either token or whitespace")
@@ -10,7 +10,6 @@ import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.nj2k.symbols.JKClassSymbol
import org.jetbrains.kotlin.nj2k.symbols.getDisplayName
import org.jetbrains.kotlin.nj2k.tree.*
import org.jetbrains.kotlin.nj2k.tree.impl.*
import org.jetbrains.kotlin.nj2k.tree.visitors.JKVisitorWithCommentsPrinting
import org.jetbrains.kotlin.nj2k.types.*
import org.jetbrains.kotlin.utils.Printer
@@ -120,7 +119,7 @@ class NewCodeBuilder(context: NewJ2kConverterContext) {
printer.printWithNoIndent("try ")
ktTryExpression.tryBlock.accept(this)
ktTryExpression.catchSections.forEach { it.accept(this) }
if (ktTryExpression.finallyBlock != JKBodyStubImpl) {
if (ktTryExpression.finallyBlock != JKBodyStub) {
printer.printWithNoIndent("finally ")
ktTryExpression.finallyBlock.accept(this)
}
@@ -192,18 +191,15 @@ class NewCodeBuilder(context: NewJ2kConverterContext) {
override fun visitBreakStatementRaw(breakStatement: JKBreakStatement) {
printer.printWithNoIndent("break")
breakStatement.label.accept(this)
}
override fun visitBreakWithLabelStatementRaw(breakWithLabelStatement: JKBreakWithLabelStatement) {
printer.printWithNoIndent("break@")
breakWithLabelStatement.label.accept(this)
}
private fun renderModifiersList(modifiersList: JKModifiersListOwner) {
val hasOverrideModifier = modifiersList.safeAs<JKOtherModifiersOwner>()
?.otherModifierElements
?.any { it.otherModifier == OtherModifier.OVERRIDE } == true
printer.renderList(modifiersList.modifierElements(), " ") { modifierElement ->
modifiersList.forEachModifier { modifierElement ->
if (modifierElement.modifier == Modality.FINAL || modifierElement.modifier == Visibility.PUBLIC) {
if (hasOverrideModifier) {
modifierElement.accept(this)
@@ -214,6 +210,7 @@ class NewCodeBuilder(context: NewJ2kConverterContext) {
} else {
modifierElement.accept(this)
}
printer.printWithNoIndent(" ")
}
}
@@ -233,13 +230,11 @@ class NewCodeBuilder(context: NewJ2kConverterContext) {
val primaryConstructor = klass.primaryConstructor()
primaryConstructor?.accept(this)
if (klass.inheritance.present()) {
printer.printWithNoIndent(" : ")
klass.inheritance.accept(this)
}
//TODO should it be here?
renderExtraTypeParametersUpperBounds(klass.typeParameterList)
klass.classBody.accept(this)
@@ -279,7 +274,6 @@ class NewCodeBuilder(context: NewJ2kConverterContext) {
printer.renderList(enumConstants) {
it.accept(this)
}
}
private fun renderNonEnumClassDeclarations(declarations: List<JKDeclaration>) {
@@ -289,30 +283,22 @@ class NewCodeBuilder(context: NewJ2kConverterContext) {
}
override fun visitKtPropertyRaw(ktProperty: JKKtProperty) {
ktProperty.annotationList.accept(this)
if (ktProperty.annotationList.annotations.isNotEmpty()) {
override fun visitFieldRaw(field: JKField) {
field.annotationList.accept(this)
if (field.annotationList.annotations.isNotEmpty()) {
printer.println()
}
renderModifiersList(ktProperty)
renderModifiersList(field)
printer.printWithNoIndent(" ")
ktProperty.name.accept(this)
if (ktProperty.type.present()) {
field.name.accept(this)
if (field.type.present()) {
printer.printWithNoIndent(":")
ktProperty.type.accept(this)
field.type.accept(this)
}
if (ktProperty.initializer !is JKStubExpression) {
if (field.initializer !is JKStubExpression) {
printer.printWithNoIndent(" = ")
ktProperty.initializer.accept(this)
}
if (ktProperty.getter !is JKKtEmptyGetterOrSetter) {
printer.printlnWithNoIndent()
ktProperty.getter.accept(this)
}
if (ktProperty.setter !is JKKtEmptyGetterOrSetter) {
printer.printlnWithNoIndent()
ktProperty.setter.accept(this)
field.initializer.accept(this)
}
}
@@ -323,7 +309,7 @@ class NewCodeBuilder(context: NewJ2kConverterContext) {
enumConstant.arguments.accept(this)
}
}
if (enumConstant.body !is JKEmptyClassBody) {
if (enumConstant.body.declarations.isNotEmpty()) {
enumConstant.body.accept(this)
}
}
@@ -336,10 +322,11 @@ class NewCodeBuilder(context: NewJ2kConverterContext) {
}
}
override fun visitKtIsExpressionRaw(ktIsExpression: JKKtIsExpression) {
ktIsExpression.expression.accept(this)
override fun visitIsExpressionRaw(isExpression: JKIsExpression) {
isExpression.expression.accept(this)
printer.printWithNoIndent(" is ")
ktIsExpression.type.accept(this)
isExpression.type.accept(this)
}
override fun visitParameterRaw(parameter: JKParameter) {
@@ -352,7 +339,7 @@ class NewCodeBuilder(context: NewJ2kConverterContext) {
}
if (parameter.parent is JKKtPrimaryConstructor
&& (parameter.parent?.parent?.parent as? JKClass)?.classKind == JKClass.ClassKind.ANNOTATION
) {//TODO get rid of
) {
printer.print(" val ")
}
parameter.name.accept(this)
@@ -382,29 +369,29 @@ class NewCodeBuilder(context: NewJ2kConverterContext) {
}
}
override fun visitKtFunctionRaw(ktFunction: JKKtFunction) {
override fun visitMethodRaw(method: JKMethod) {
printer.printIndent()
if (ktFunction.annotationList.annotations.isNotEmpty()) {
ktFunction.annotationList.accept(this)
if (method.annotationList.annotations.isNotEmpty()) {
method.annotationList.accept(this)
printer.printlnWithNoIndent(" ")
}
renderModifiersList(ktFunction)
renderModifiersList(method)
printer.printWithNoIndent(" fun ")
ktFunction.typeParameterList.accept(this)
method.typeParameterList.accept(this)
elementInfoStorage.getOrCreateInfoForElement(ktFunction).let {
elementInfoStorage.getOrCreateInfoForElement(method).let {
printer.printWithNoIndent(it.render())
}
ktFunction.name.accept(this)
renderTokenElement(ktFunction.leftParen)
printer.renderList(ktFunction.parameters) {
method.name.accept(this)
renderTokenElement(method.leftParen)
printer.renderList(method.parameters) {
it.accept(this)
}
renderTokenElement(ktFunction.rightParen)
renderTokenElement(method.rightParen)
printer.printWithNoIndent(": ")
ktFunction.returnType.accept(this)
renderExtraTypeParametersUpperBounds(ktFunction.typeParameterList)
ktFunction.block.accept(this)
method.returnType.accept(this)
renderExtraTypeParametersUpperBounds(method.typeParameterList)
method.block.accept(this)
}
override fun visitIfElseExpressionRaw(ifElseExpression: JKIfElseExpression) {
@@ -412,49 +399,28 @@ class NewCodeBuilder(context: NewJ2kConverterContext) {
ifElseExpression.condition.accept(this)
printer.printWithNoIndent(")")
ifElseExpression.thenBranch.accept(this)
printer.printWithNoIndent(" else ")
ifElseExpression.elseBranch.accept(this)
}
override fun visitIfStatementRaw(ifStatement: JKIfStatement) {
printer.printWithNoIndent("if (")
ifStatement.condition.accept(this)
printer.printWithNoIndent(")")
if (ifStatement.thenBranch.isEmpty()) {
printer.printWithNoIndent(";")
} else {
ifStatement.thenBranch.accept(this)
if (ifElseExpression.elseBranch !is JKStubExpression) {
printer.printWithNoIndent(" else ")
ifElseExpression.elseBranch.accept(this)
}
}
override fun visitIfElseStatementRaw(ifElseStatement: JKIfElseStatement) {
visitIfStatement(ifElseStatement)
printer.printWithNoIndent(" else ")
ifElseStatement.elseBranch.accept(this)
}
override fun visitKtGetterOrSetterRaw(ktGetterOrSetter: JKKtGetterOrSetter) {
printer.indented {
renderModifiersList(ktGetterOrSetter)
printer.printWithNoIndent(" ")
when (ktGetterOrSetter.kind) {
JKKtGetterOrSetter.Kind.GETTER -> printer.printWithNoIndent("get")
JKKtGetterOrSetter.Kind.SETTER -> printer.printWithNoIndent("set")
}
if (!ktGetterOrSetter.body.isEmpty()) {
when (ktGetterOrSetter.kind) {
JKKtGetterOrSetter.Kind.GETTER -> printer.printWithNoIndent("() ")
JKKtGetterOrSetter.Kind.SETTER -> printer.printWithNoIndent("(value) ")
}
ktGetterOrSetter.body.accept(this)
}
printer.printWithNoIndent("if (")
ifElseStatement.condition.accept(this)
printer.printWithNoIndent(")")
if (ifElseStatement.thenBranch.isEmpty()) {
printer.printWithNoIndent(";")
} else {
ifElseStatement.thenBranch.accept(this)
}
if (!ifElseStatement.elseBranch.isEmpty()) {
printer.printWithNoIndent(" else ")
ifElseStatement.elseBranch.accept(this)
}
printer.printlnWithNoIndent()
}
override fun visitKtEmptyGetterOrSetterRaw(ktEmptyGetterOrSetter: JKKtEmptyGetterOrSetter) {
}
override fun visitBinaryExpressionRaw(binaryExpression: JKBinaryExpression) {
binaryExpression.left.accept(this)
@@ -517,12 +483,12 @@ class NewCodeBuilder(context: NewJ2kConverterContext) {
printer.printWithNoIndent(" ")
}
override fun visitLabeledStatementRaw(labeledStatement: JKLabeledStatement) {
for (label in labeledStatement.labels) {
override fun visitLabeledExpressionRaw(labeledExpression: JKLabeledExpression) {
for (label in labeledExpression.labels) {
label.accept(this)
printer.printWithNoIndent("@")
}
labeledStatement.statement.accept(this)
labeledExpression.statement.accept(this)
}
override fun visitNameIdentifierRaw(nameIdentifier: JKNameIdentifier) {
@@ -536,20 +502,10 @@ class NewCodeBuilder(context: NewJ2kConverterContext) {
override fun visitQualifiedExpressionRaw(qualifiedExpression: JKQualifiedExpression) {
qualifiedExpression.receiver.accept(this)
printer.printWithNoIndent(
when (qualifiedExpression.operator) {
is JKJavaQualifierImpl.DOT /*<-remove this TODO!*/, is JKKtQualifierImpl.DOT -> "."
is JKKtQualifierImpl.SAFE -> "?."
else -> TODO()
}
)
printer.printWithNoIndent(".")
qualifiedExpression.selector.accept(this)
}
override fun visitExpressionListRaw(expressionList: JKExpressionList) {
printer.renderList(expressionList.expressions) { it.accept(this) }
}
override fun visitArgumentListRaw(argumentList: JKArgumentList) {
printer.renderList(argumentList.arguments) { it.accept(this) }
@@ -565,11 +521,11 @@ class NewCodeBuilder(context: NewJ2kConverterContext) {
namedArgument.value.accept(this)
}
override fun visitMethodCallExpressionRaw(methodCallExpression: JKMethodCallExpression) {
printer.printWithNoIndent(FqName(methodCallExpression.identifier.fqName).shortName().asString().escaped())
methodCallExpression.typeArgumentList.accept(this)
override fun visitCallExpressionRaw(callExpression: JKCallExpression) {
printer.printWithNoIndent(FqName(callExpression.identifier.fqName).shortName().asString().escaped())
callExpression.typeArgumentList.accept(this)
printer.par {
methodCallExpression.arguments.accept(this)
callExpression.arguments.accept(this)
}
}
@@ -643,19 +599,19 @@ class NewCodeBuilder(context: NewJ2kConverterContext) {
ktConvertedFromForLoopSyntheticWhileStatement.whileStatement.accept(this)
}
override fun visitJavaNewExpressionRaw(javaNewExpression: JKJavaNewExpression) {
if (javaNewExpression.isAnonymousClass()) {
override fun visitNewExpressionRaw(newExpression: JKNewExpression) {
if (newExpression.isAnonymousClass) {
printer.printWithNoIndent("object : ")
}
printer.renderClassSymbol(javaNewExpression.classSymbol, javaNewExpression)
javaNewExpression.typeArgumentList.accept(this)
if (!javaNewExpression.classSymbol.isInterface() || javaNewExpression.arguments.arguments.isNotEmpty()) {
printer.renderClassSymbol(newExpression.classSymbol, newExpression)
newExpression.typeArgumentList.accept(this)
if (!newExpression.classSymbol.isInterface() || newExpression.arguments.arguments.isNotEmpty()) {
printer.par(ParenthesisKind.ROUND) {
javaNewExpression.arguments.accept(this)
newExpression.arguments.accept(this)
}
}
if (javaNewExpression.isAnonymousClass()) {
javaNewExpression.classBody.accept(this)
if (newExpression.isAnonymousClass) {
newExpression.classBody.accept(this)
}
}
@@ -681,8 +637,6 @@ class NewCodeBuilder(context: NewJ2kConverterContext) {
renderTokenElement(classBody.rightBrace)
}
override fun visitEmptyClassBodyRaw(emptyClassBody: JKEmptyClassBody) {}
override fun visitTypeElementRaw(typeElement: JKTypeElement) {
printer.renderType(typeElement.type, typeElement)
}
@@ -716,13 +670,6 @@ class NewCodeBuilder(context: NewJ2kConverterContext) {
printer.printWithNoIndent(fieldAccessExpression.identifier.name.escaped())
}
override fun visitArrayAccessExpressionRaw(arrayAccessExpression: JKArrayAccessExpression) {
arrayAccessExpression.expression.accept(this)
printer.print(".get(")
arrayAccessExpression.indexExpression.accept(this)
printer.print(")")
}
override fun visitPackageAccessExpressionRaw(packageAccessExpression: JKPackageAccessExpression) {
printer.printWithNoIndent(packageAccessExpression.identifier.name.escaped())
}
@@ -754,19 +701,19 @@ class NewCodeBuilder(context: NewJ2kConverterContext) {
}
}
override fun visitKtConstructorRaw(ktConstructor: JKKtConstructor) {
ktConstructor.annotationList.accept(this)
if (ktConstructor.annotationList.annotations.isNotEmpty()) {
override fun visitConstructorRaw(constructor: JKConstructor) {
constructor.annotationList.accept(this)
if (constructor.annotationList.annotations.isNotEmpty()) {
printer.println()
}
renderModifiersList(ktConstructor)
renderModifiersList(constructor)
printer.print(" constructor")
renderParameterList(ktConstructor.parameters)
if (ktConstructor.delegationCall !is JKStubExpression) {
renderParameterList(constructor.parameters)
if (constructor.delegationCall !is JKStubExpression) {
builder.append(" : ")
ktConstructor.delegationCall.accept(this)
constructor.delegationCall.accept(this)
}
ktConstructor.block.accept(this)
constructor.block.accept(this)
}
override fun visitKtPrimaryConstructorRaw(ktPrimaryConstructor: JKKtPrimaryConstructor) {
@@ -781,8 +728,6 @@ class NewCodeBuilder(context: NewJ2kConverterContext) {
}
}
override fun visitBodyStub(bodyStub: JKBodyStub) {
}
override fun visitLambdaExpressionRaw(lambdaExpression: JKLambdaExpression) {
val printLambda = {
@@ -846,7 +791,7 @@ class NewCodeBuilder(context: NewJ2kConverterContext) {
printer.printWithNoIndent("when(")
ktWhenStatement.expression.accept(this)
printer.printWithNoIndent(")")
printer.block(multiline = true) {
printer.block() {
printer.renderList(ktWhenStatement.cases, { printer.printlnWithNoIndent() }) {
it.accept(this)
}
@@ -880,16 +825,16 @@ class NewCodeBuilder(context: NewJ2kConverterContext) {
}
override fun visitClassLiteralExpressionRaw(classLiteralExpression: JKClassLiteralExpression) {
if (classLiteralExpression.literalType == JKClassLiteralExpression.LiteralType.JAVA_VOID_TYPE) {
if (classLiteralExpression.literalType == JKClassLiteralExpression.ClassLiteralType.JAVA_VOID_TYPE) {
printer.printWithNoIndent("Void.TYPE")
} else {
printer.renderType(classLiteralExpression.classType.type, classLiteralExpression)
printer.printWithNoIndent("::")
when (classLiteralExpression.literalType) {
JKClassLiteralExpression.LiteralType.KOTLIN_CLASS -> printer.printWithNoIndent("class")
JKClassLiteralExpression.LiteralType.JAVA_CLASS -> printer.printWithNoIndent("class.java")
JKClassLiteralExpression.LiteralType.JAVA_PRIMITIVE_CLASS -> printer.printWithNoIndent("class.javaPrimitiveType")
JKClassLiteralExpression.LiteralType.JAVA_VOID_TYPE -> {
JKClassLiteralExpression.ClassLiteralType.KOTLIN_CLASS -> printer.printWithNoIndent("class")
JKClassLiteralExpression.ClassLiteralType.JAVA_CLASS -> printer.printWithNoIndent("class.java")
JKClassLiteralExpression.ClassLiteralType.JAVA_PRIMITIVE_CLASS -> printer.printWithNoIndent("class.javaPrimitiveType")
JKClassLiteralExpression.ClassLiteralType.JAVA_VOID_TYPE -> {
}
}
}
@@ -939,7 +884,7 @@ private class JKPrinter(
this.popIndent()
}
inline fun block(multiline: Boolean = false, crossinline body: () -> Unit) {
inline fun block(crossinline body: () -> Unit) {
par(ParenthesisKind.CURVED) {
indented(body)
}
@@ -1,24 +0,0 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.nj2k
import org.jetbrains.kotlin.nj2k.tree.JKElement
import org.jetbrains.kotlin.nj2k.tree.impl.JKElementBase
import org.jetbrains.kotlin.nj2k.tree.withNonCodeElementsFrom
@Suppress("UNCHECKED_CAST")
fun <T : JKElement> T.copyTree(): T =
when (this) {
is JKElementBase ->
this.copy().withNonCodeElementsFrom(this) as T
else -> TODO("Not supported+$this.toString()")
}
fun <T : JKElement> T.copyTreeAndDetach(): T =
this.copyTree().also {
if (it.parent != null) it.detach(it.parent!!)
}
@@ -14,11 +14,16 @@ import org.jetbrains.kotlin.j2k.ast.Nullability
import org.jetbrains.kotlin.js.resolve.diagnostics.findPsi
import org.jetbrains.kotlin.nj2k.*
import org.jetbrains.kotlin.nj2k.symbols.JKUniverseMethodSymbol
import org.jetbrains.kotlin.nj2k.tree.*
import org.jetbrains.kotlin.nj2k.tree.impl.JKCapturedType
import org.jetbrains.kotlin.nj2k.tree.impl.psi
import org.jetbrains.kotlin.nj2k.tree.JKMethod
import org.jetbrains.kotlin.nj2k.tree.JKTreeElement
import org.jetbrains.kotlin.nj2k.tree.JKTypeElement
import org.jetbrains.kotlin.nj2k.types.isCollectionType
import org.jetbrains.kotlin.nj2k.types.JKCapturedType
import org.jetbrains.kotlin.nj2k.types.JKParametrizedType
import org.jetbrains.kotlin.nj2k.types.JKStarProjectionType
import org.jetbrains.kotlin.nj2k.types.JKType
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
class AddElementsInfoConversion(context: NewJ2kConverterContext) : RecursiveApplicableConversionBase(context) {
@@ -7,9 +7,6 @@ package org.jetbrains.kotlin.nj2k.conversions
import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
import org.jetbrains.kotlin.nj2k.tree.*
import org.jetbrains.kotlin.nj2k.tree.impl.JKBinaryExpressionImpl
import org.jetbrains.kotlin.nj2k.tree.impl.JKParenthesizedExpressionImpl
class AddParenthesisForLineBreaksInBinaryExpression(override val context: NewJ2kConverterContext) :
RecursiveApplicableConversionBase(context) {
@@ -19,8 +16,8 @@ class AddParenthesisForLineBreaksInBinaryExpression(override val context: NewJ2k
if (element.left.rightNonCodeElements.any {
it is JKSpaceElement && '\n' in it.text
}) {
return JKParenthesizedExpressionImpl(
JKBinaryExpressionImpl(
return JKParenthesizedExpression(
JKBinaryExpression(
element::left.detached(),
element::right.detached(),
element.operator
@@ -7,10 +7,14 @@ package org.jetbrains.kotlin.nj2k.conversions
import org.jetbrains.kotlin.j2k.ast.Nullability
import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
import org.jetbrains.kotlin.nj2k.modality
import org.jetbrains.kotlin.nj2k.toExpression
import org.jetbrains.kotlin.nj2k.tree.*
import org.jetbrains.kotlin.nj2k.tree.impl.*
import org.jetbrains.kotlin.nj2k.types.JKJavaArrayType
import org.jetbrains.kotlin.nj2k.types.isArrayType
import org.jetbrains.kotlin.nj2k.types.replaceJavaClassWithKotlinClassType
import org.jetbrains.kotlin.nj2k.types.updateNullabilityRecursively
class AnnotationClassConversion(context: NewJ2kConverterContext) : RecursiveApplicableConversionBase(context) {
override fun applyToElement(element: JKTreeElement): JKTreeElement {
@@ -19,14 +23,14 @@ class AnnotationClassConversion(context: NewJ2kConverterContext) : RecursiveAppl
val javaAnnotationMethods =
element.classBody.declarations
.filterIsInstance<JKJavaAnnotationMethod>()
val constructor = JKKtPrimaryConstructorImpl(
JKNameIdentifierImpl(""),
val constructor = JKKtPrimaryConstructor(
JKNameIdentifier(""),
javaAnnotationMethods.map { it.asKotlinAnnotationParameter() },
JKStubExpressionImpl(),
JKAnnotationListImpl(),
JKStubExpression(),
JKAnnotationList(),
emptyList(),
JKVisibilityModifierElementImpl(Visibility.PUBLIC),
JKModalityModifierElementImpl(Modality.FINAL)
JKVisibilityModifierElement(Visibility.PUBLIC),
JKModalityModifierElement(Modality.FINAL)
)
element.modality = Modality.FINAL
element.classBody.declarations += constructor
@@ -34,24 +38,24 @@ class AnnotationClassConversion(context: NewJ2kConverterContext) : RecursiveAppl
return recurse(element)
}
private fun JKJavaAnnotationMethod.asKotlinAnnotationParameter(): JKParameterImpl {
private fun JKJavaAnnotationMethod.asKotlinAnnotationParameter(): JKParameter {
val type = returnType.type
.updateNullabilityRecursively(Nullability.NotNull)
.replaceJavaClassWithKotlinClassType(symbolProvider)
val initializer = this::defaultValue.detached().toExpression(symbolProvider)
val isVarArgs = type is JKJavaArrayType && name.value == "value"
return JKParameterImpl(
JKTypeElementImpl(
return JKParameter(
JKTypeElement(
if (!isVarArgs) type else (type as JKJavaArrayType).type
),
JKNameIdentifierImpl(name.value),
JKNameIdentifier(name.value),
isVarArgs = isVarArgs,
initializer =
if (type.isArrayType()
&& initializer !is JKKtAnnotationArrayInitializerExpression
&& initializer !is JKStubExpression
) {
JKKtAnnotationArrayInitializerExpressionImpl(initializer)
JKKtAnnotationArrayInitializerExpression(initializer)
} else initializer
).also { parameter ->
if (leftNonCodeElements.any { it is JKCommentElement }) {
@@ -12,10 +12,7 @@ import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
import org.jetbrains.kotlin.nj2k.primaryConstructor
import org.jetbrains.kotlin.nj2k.toExpression
import org.jetbrains.kotlin.nj2k.tree.*
import org.jetbrains.kotlin.nj2k.tree.impl.JKAnnotationNameParameterImpl
import org.jetbrains.kotlin.nj2k.tree.impl.JKAnnotationParameterImpl
import org.jetbrains.kotlin.nj2k.tree.impl.JKKtAnnotationArrayInitializerExpressionImpl
import org.jetbrains.kotlin.nj2k.tree.impl.JKNameIdentifierImpl
import org.jetbrains.kotlin.nj2k.types.isArrayType
class AnnotationConversion(context: NewJ2kConverterContext) : RecursiveApplicableConversionBase(context) {
override fun applyToElement(element: JKTreeElement): JKTreeElement {
@@ -43,15 +40,15 @@ class AnnotationConversion(context: NewJ2kConverterContext) : RecursiveApplicabl
&& annotation.isVarargsArgument(annotationParameter.name.value)
&& annotationParameter.value !is JKKtAnnotationArrayInitializerExpression -> {
listOf(
JKAnnotationNameParameterImpl(
JKKtAnnotationArrayInitializerExpressionImpl(annotationParameter::value.detached()),
JKNameIdentifierImpl(annotationParameter.name.value)
JKAnnotationNameParameter(
JKKtAnnotationArrayInitializerExpression(annotationParameter::value.detached()),
JKNameIdentifier(annotationParameter.name.value)
)
)
}
annotationParameter is JKAnnotationNameParameterImpl ->
annotationParameter is JKAnnotationNameParameter ->
listOf(
JKAnnotationNameParameterImpl(
JKAnnotationNameParameter(
annotationParameter::value.detached(),
annotationParameter::name.detached()
)
@@ -11,8 +11,8 @@ import org.jetbrains.kotlin.j2k.ast.Nullability
import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
import org.jetbrains.kotlin.nj2k.toArgumentList
import org.jetbrains.kotlin.nj2k.tree.*
import org.jetbrains.kotlin.nj2k.tree.impl.*
import org.jetbrains.kotlin.nj2k.types.JKJavaPrimitiveType
import org.jetbrains.kotlin.nj2k.types.*
import org.jetbrains.kotlin.resolve.CollectionLiteralResolver
@@ -27,9 +27,9 @@ class ArrayInitializerConversion(context: NewJ2kConverterContext) : RecursiveApp
else
CollectionLiteralResolver.ARRAY_OF_FUNCTION.asString()
val typeArguments =
if (primitiveArrayType == null) JKTypeArgumentListImpl(listOf(element::type.detached()))
else JKTypeArgumentListImpl()
newElement = JKJavaMethodCallExpressionImpl(
if (primitiveArrayType == null) JKTypeArgumentList(listOf(element::type.detached()))
else JKTypeArgumentList()
newElement = JKCallExpressionImpl(
symbolProvider.provideMethodSymbol("kotlin.$arrayConstructorName"),
element.initializer.also { element.initializer = emptyList() }.toArgumentList(),
typeArguments
@@ -46,33 +46,33 @@ class ArrayInitializerConversion(context: NewJ2kConverterContext) : RecursiveApp
private fun buildArrayInitializer(dimensions: List<JKExpression>, type: JKType): JKExpression {
if (dimensions.size == 1) {
return if (type !is JKJavaPrimitiveType) {
JKJavaMethodCallExpressionImpl(
JKCallExpressionImpl(
symbolProvider.provideMethodSymbol("kotlin.arrayOfNulls"),
JKArgumentListImpl(dimensions[0]),
JKTypeArgumentListImpl(listOf(JKTypeElementImpl(type)))
JKArgumentList(dimensions[0]),
JKTypeArgumentList(listOf(JKTypeElement(type)))
)
} else {
JKJavaNewExpressionImpl(
JKNewExpression(
symbolProvider.provideClassSymbol(type.arrayFqName()),
JKArgumentListImpl(dimensions[0]),
JKTypeArgumentListImpl(emptyList())
JKArgumentList(dimensions[0]),
JKTypeArgumentList(emptyList())
)
}
}
if (dimensions[1] !is JKStubExpression) {
val arrayType = dimensions.drop(1).fold(type) { currentType, _ ->
JKJavaArrayTypeImpl(currentType)
JKJavaArrayType(currentType)
}
return JKJavaNewExpressionImpl(
return JKNewExpression(
symbolProvider.provideClassSymbol("kotlin.Array"),
JKArgumentListImpl(
JKArgumentList(
dimensions[0],
JKLambdaExpressionImpl(
JKExpressionStatementImpl(buildArrayInitializer(dimensions.subList(1, dimensions.size), type)),
JKLambdaExpression(
JKExpressionStatement(buildArrayInitializer(dimensions.subList(1, dimensions.size), type)),
emptyList()
)
),
JKTypeArgumentListImpl(listOf(JKTypeElementImpl(arrayType)))
JKTypeArgumentList(listOf(JKTypeElement(arrayType)))
)
}
var resultType = JKClassTypeImpl(
@@ -87,10 +87,10 @@ class ArrayInitializerConversion(context: NewJ2kConverterContext) : RecursiveApp
Nullability.Default
)
}
return JKJavaMethodCallExpressionImpl(
return JKCallExpressionImpl(
symbolProvider.provideMethodSymbol("kotlin.arrayOfNulls"),
JKArgumentListImpl(dimensions[0]),
JKTypeArgumentListImpl(listOf(JKTypeElementImpl(resultType)))
JKArgumentList(dimensions[0]),
JKTypeArgumentList(listOf(JKTypeElement(resultType)))
)
}
}
@@ -13,8 +13,9 @@ package org.jetbrains.kotlin.nj2k.conversions
import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
import org.jetbrains.kotlin.nj2k.symbols.JKUniverseFieldSymbol
import org.jetbrains.kotlin.nj2k.tree.*
import org.jetbrains.kotlin.nj2k.tree.impl.JKFieldAccessExpressionImpl
import org.jetbrains.kotlin.nj2k.types.JKJavaArrayType
import org.jetbrains.kotlin.nj2k.types.type
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
@@ -24,7 +25,7 @@ class ArrayOperationsConversion(context: NewJ2kConverterContext) : RecursiveAppl
val selector = element.selector as? JKFieldAccessExpression ?: return recurse(element)
if (element.receiver.isArrayOrVarargTypeParameter() && selector.identifier.name == "length") {
val sizeCall =
JKFieldAccessExpressionImpl(
JKFieldAccessExpression(
symbolProvider.provideFieldSymbol("kotlin.Array.size")
)
element.selector = sizeCall
@@ -7,12 +7,7 @@ package org.jetbrains.kotlin.nj2k.conversions
import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
import org.jetbrains.kotlin.nj2k.kotlinAssert
import org.jetbrains.kotlin.nj2k.tree.JKJavaAssertStatement
import org.jetbrains.kotlin.nj2k.tree.JKStubExpression
import org.jetbrains.kotlin.nj2k.tree.JKTreeElement
import org.jetbrains.kotlin.nj2k.tree.detached
import org.jetbrains.kotlin.nj2k.tree.impl.JKExpressionStatementImpl
import org.jetbrains.kotlin.nj2k.tree.impl.JKLambdaExpressionImpl
import org.jetbrains.kotlin.nj2k.tree.*
class AssertStatementConversion(context: NewJ2kConverterContext) : RecursiveApplicableConversionBase(context) {
@@ -20,12 +15,12 @@ class AssertStatementConversion(context: NewJ2kConverterContext) : RecursiveAppl
if (element !is JKJavaAssertStatement) return recurse(element)
val messageExpression =
if (element.description is JKStubExpression) null
else JKLambdaExpressionImpl(
JKExpressionStatementImpl(element::description.detached()),
else JKLambdaExpression(
JKExpressionStatement(element::description.detached()),
emptyList()
)
return recurse(
JKExpressionStatementImpl(
JKExpressionStatement(
kotlinAssert(
element::condition.detached(),
messageExpression,
@@ -6,9 +6,8 @@
package org.jetbrains.kotlin.nj2k.conversions
import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
import org.jetbrains.kotlin.nj2k.copyTreeAndDetach
import org.jetbrains.kotlin.nj2k.tree.*
import org.jetbrains.kotlin.nj2k.tree.impl.*
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
class AssignmentExpressionUnfoldingConversion(context: NewJ2kConverterContext) : RecursiveApplicableConversionBase(context) {
@@ -57,7 +56,7 @@ class AssignmentExpressionUnfoldingConversion(context: NewJ2kConverterContext) :
val assignment = expression as? JKJavaAssignmentExpression ?: return null
return when {
canBeConvertedToBlock() && assignment.expression is JKJavaAssignmentExpression ->
JKBlockStatementImpl(JKBlockImpl(assignment.unfoldToStatementsList(assignmentTarget = null)))
JKBlockStatement(JKBlockImpl(assignment.unfoldToStatementsList(assignmentTarget = null)))
else -> createKtAssignmentStatement(
assignment::field.detached(),
assignment::expression.detached(),
@@ -69,7 +68,6 @@ class AssignmentExpressionUnfoldingConversion(context: NewJ2kConverterContext) :
private fun JKExpressionStatement.canBeConvertedToBlock() = when (val parent = parent) {
is JKLoopStatement -> parent.body == this
is JKIfElseStatement -> parent.thenBranch == this || parent.elseBranch == this
is JKIfStatement -> parent.thenBranch == this
is JKJavaSwitchCase -> true
else -> false
}
@@ -110,7 +108,7 @@ class AssignmentExpressionUnfoldingConversion(context: NewJ2kConverterContext) :
null -> statements
else -> {
assignmentTarget.initializer = statements.last().field.copyTreeAndDetach()
statements + JKDeclarationStatementImpl(listOf(assignmentTarget))
statements + JKDeclarationStatement(listOf(assignmentTarget))
}
}
}
@@ -118,14 +116,14 @@ class AssignmentExpressionUnfoldingConversion(context: NewJ2kConverterContext) :
private fun JKJavaAssignmentExpression.toExpressionChainLink(receiver: JKExpression): JKExpression {
val assignment = createKtAssignmentStatement(
this::field.detached(),
JKKtItExpressionImpl(operator.returnType),
JKKtItExpression(operator.returnType),
operator
).withNonCodeElementsFrom(this)
return when {
operator.isSimpleToken() ->
JKAssignmentChainAlsoLinkImpl(receiver, assignment, field.copyTreeAndDetach())
JKAssignmentChainAlsoLink(receiver, assignment, field.copyTreeAndDetach())
else ->
JKAssignmentChainLetLinkImpl(receiver, assignment, field.copyTreeAndDetach())
JKAssignmentChainLetLink(receiver, assignment, field.copyTreeAndDetach())
}
}
@@ -139,9 +137,9 @@ class AssignmentExpressionUnfoldingConversion(context: NewJ2kConverterContext) :
operator: JKOperator
) = when {
operator.isOnlyJavaToken() ->
JKKtAssignmentStatementImpl(
JKKtAssignmentStatement(
field,
JKBinaryExpressionImpl(
JKBinaryExpression(
field.copyTreeAndDetach(),
expression,
JKKtOperatorImpl(
@@ -151,7 +149,7 @@ class AssignmentExpressionUnfoldingConversion(context: NewJ2kConverterContext) :
),
JKOperatorToken.EQ
)
else -> JKKtAssignmentStatementImpl(field, expression, operator.token)
else -> JKKtAssignmentStatement(field, expression, operator.token)
}
private fun JKOperator.isSimpleToken() = when {
@@ -7,7 +7,7 @@ package org.jetbrains.kotlin.nj2k.conversions
import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
import org.jetbrains.kotlin.nj2k.tree.*
import org.jetbrains.kotlin.nj2k.tree.impl.*
class BlockToRunConversion(context: NewJ2kConverterContext) : RecursiveApplicableConversionBase(context) {
override fun applyToElement(element: JKTreeElement): JKTreeElement {
@@ -19,15 +19,15 @@ class BlockToRunConversion(context: NewJ2kConverterContext) : RecursiveApplicabl
if (parentDeclaration.psi == null) return recurse(element)
element.invalidate()
val lambda = JKLambdaExpressionImpl(
JKBlockStatementImpl(element.block),
val lambda = JKLambdaExpression(
JKBlockStatement(element.block),
emptyList()
)
val call = JKKtCallExpressionImpl(
val call = JKCallExpressionImpl(
symbolProvider.provideMethodSymbol("kotlin.run"),
JKArgumentListImpl(lambda)
JKArgumentList(lambda)
)
return recurse(JKExpressionStatementImpl(call).withNonCodeElementsFrom(element))
return recurse(JKExpressionStatement(call).withNonCodeElementsFrom(element))
}
}
@@ -7,29 +7,29 @@ package org.jetbrains.kotlin.nj2k.conversions
import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
import org.jetbrains.kotlin.nj2k.tree.*
import org.jetbrains.kotlin.nj2k.tree.impl.JKArgumentListImpl
import org.jetbrains.kotlin.nj2k.tree.impl.JKKtCallExpressionImpl
import org.jetbrains.kotlin.nj2k.types.primitiveTypes
class BoxedTypeOperationsConversion(context: NewJ2kConverterContext) : RecursiveApplicableConversionBase(context) {
override fun applyToElement(element: JKTreeElement): JKTreeElement {
return recurse(
when (element) {
is JKMethodCallExpression ->
is JKCallExpression ->
convertBoxedTypeUnwrapping(element)
is JKJavaNewExpression -> convertCreationOfBoxedType(element)
is JKNewExpression -> convertCreationOfBoxedType(element)
else -> null
} ?: element
)
}
private fun convertCreationOfBoxedType(newExpression: JKJavaNewExpression): JKExpression? {
private fun convertCreationOfBoxedType(newExpression: JKNewExpression): JKExpression? {
if (newExpression.classSymbol.fqName !in boxedTypeFqNames) return null
val singleArgument = newExpression.arguments.arguments.singleOrNull() ?: return null
return singleArgument::value.detached()
}
private fun convertBoxedTypeUnwrapping(methodCallExpression: JKMethodCallExpression): JKExpression? {
private fun convertBoxedTypeUnwrapping(methodCallExpression: JKCallExpression): JKExpression? {
val (boxedJavaType, operationType) =
primitiveTypeUnwrapRegexp.matchEntire(methodCallExpression.identifier.fqName)
?.groupValues
@@ -38,11 +38,11 @@ class BoxedTypeOperationsConversion(context: NewJ2kConverterContext) : Recursive
} ?: return null
val primitiveTypeName = boxedTypeToPrimitiveType[boxedJavaType] ?: return null
if (operationType !in primitiveTypeNames) return null
return JKKtCallExpressionImpl(
return JKCallExpressionImpl(
symbolProvider.provideMethodSymbol(
"kotlin.${primitiveTypeName.capitalize()}.to${operationType.capitalize()}"
),
JKArgumentListImpl()
JKArgumentList()
).withNonCodeElementsFrom(methodCallExpression)
}
@@ -11,7 +11,10 @@ import org.jetbrains.kotlin.nj2k.symbols.JKMethodSymbol
import org.jetbrains.kotlin.nj2k.symbols.JKUnresolvedField
import org.jetbrains.kotlin.nj2k.symbols.deepestFqName
import org.jetbrains.kotlin.nj2k.tree.*
import org.jetbrains.kotlin.nj2k.tree.impl.*
import org.jetbrains.kotlin.nj2k.types.isArrayType
import org.jetbrains.kotlin.nj2k.types.isStringType
import org.jetbrains.kotlin.nj2k.types.type
import org.jetbrains.kotlin.utils.addToStdlib.cast
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
@@ -52,7 +55,7 @@ class BuiltinMembersConversion(context: NewJ2kConverterContext) : RecursiveAppli
}
private fun JKExpression.getConversion(): Conversion? = when (this) {
is JKMethodCallExpression ->
is JKCallExpression ->
conversions[identifier.deepestFqName()]?.firstOrNull { conversion ->
if (conversion.from !is Method) return@firstOrNull false
if (conversion.filter?.invoke(this) == false) return@firstOrNull false
@@ -66,7 +69,7 @@ class BuiltinMembersConversion(context: NewJ2kConverterContext) : RecursiveAppli
true
}
is JKJavaNewExpression ->
is JKNewExpression ->
conversions[classSymbol.deepestFqName()]?.firstOrNull { conversion ->
if (conversion.from !is NewExpression) return@firstOrNull false
if (conversion.filter?.invoke(this) == false) return@firstOrNull false
@@ -86,23 +89,23 @@ class BuiltinMembersConversion(context: NewJ2kConverterContext) : RecursiveAppli
) : ResultBuilder {
override fun build(from: JKExpression): JKExpression =
when (from) {
is JKMethodCallExpression ->
JKKtCallExpressionImpl(
is JKCallExpression ->
JKCallExpressionImpl(
symbolProvider.provideMethodSymbol(fqName),
argumentsProvider(from::arguments.detached()),
from::typeArgumentList.detached()
).withNonCodeElementsFrom(from)
is JKFieldAccessExpression ->
JKKtCallExpressionImpl(
JKCallExpressionImpl(
symbolProvider.provideMethodSymbol(fqName),
JKArgumentListImpl(),
JKTypeArgumentListImpl()
JKArgumentList(),
JKTypeArgumentList()
).withNonCodeElementsFrom(from)
is JKJavaNewExpression ->
JKKtCallExpressionImpl(
is JKNewExpression ->
JKCallExpressionImpl(
symbolProvider.provideMethodSymbol(fqName),
argumentsProvider(from::arguments.detached()),
JKTypeArgumentListImpl()
JKTypeArgumentList()
).withNonCodeElementsFrom(from)
else -> error("Bad conversion")
}
@@ -113,12 +116,12 @@ class BuiltinMembersConversion(context: NewJ2kConverterContext) : RecursiveAppli
) : ResultBuilder {
override fun build(from: JKExpression): JKExpression =
when (from) {
is JKMethodCallExpression ->
JKFieldAccessExpressionImpl(
is JKCallExpression ->
JKFieldAccessExpression(
symbolProvider.provideFieldSymbol(fqName)
).withNonCodeElementsFrom(from)
is JKFieldAccessExpression ->
JKFieldAccessExpressionImpl(
JKFieldAccessExpression(
symbolProvider.provideFieldSymbol(fqName)
).withNonCodeElementsFrom(from)
else -> error("Bad conversion")
@@ -130,14 +133,13 @@ class BuiltinMembersConversion(context: NewJ2kConverterContext) : RecursiveAppli
) : ResultBuilder {
override fun build(from: JKExpression): JKExpression =
when (from) {
is JKMethodCallExpression -> {
is JKCallExpression -> {
val arguments = from.arguments::arguments.detached()
JKQualifiedExpressionImpl(
JKQualifiedExpression(
arguments.first()::value.detached().parenthesizeIfBinaryExpression(),
JKKtQualifierImpl.DOT,
JKKtCallExpressionImpl(
JKCallExpressionImpl(
symbolProvider.provideMethodSymbol(fqName),
JKArgumentListImpl(arguments.drop(1)),
JKArgumentList(arguments.drop(1)),
from::typeArgumentList.detached()
)
).withNonCodeElementsFrom(from)
@@ -247,9 +249,9 @@ class BuiltinMembersConversion(context: NewJ2kConverterContext) : RecursiveAppli
convertTo Method("kotlin.collections.toTypedArray")
withByArgumentsFilter {
it.singleOrNull()?.let { parameter ->
parameter.safeAs<JKMethodCallExpression>()?.identifier?.fqName == "kotlin.arrayOfNulls"
parameter.safeAs<JKCallExpression>()?.identifier?.fqName == "kotlin.arrayOfNulls"
} == true
} withArgumentsProvider { JKArgumentListImpl() },
} withArgumentsProvider { JKArgumentList() },
Method("java.util.List.remove") convertTo Method("kotlin.collections.MutableCollection.removeAt"),
Method("java.util.Map.Entry.getKey") convertTo Field("kotlin.collections.Map.Entry.key"),
@@ -269,11 +271,11 @@ class BuiltinMembersConversion(context: NewJ2kConverterContext) : RecursiveAppli
withByArgumentsFilter { it.singleOrNull()?.type(typeFactory)?.isStringType() == true }
withArgumentsProvider { arguments ->
val argument = arguments.arguments.single()::value.detached()
val call = JKKtCallExpressionImpl(
val call = JKCallExpressionImpl(
symbolProvider.provideMethodSymbol("kotlin.text.charset"),
JKArgumentListImpl(argument)
JKArgumentList(argument)
)
JKArgumentListImpl(call)
JKArgumentList(call)
},
Method("java.lang.String.getBytes") convertTo Method("kotlin.text.toByteArray"),
Method("java.lang.String.valueOf")
@@ -289,7 +291,7 @@ class BuiltinMembersConversion(context: NewJ2kConverterContext) : RecursiveAppli
val srcEndArgument = argumentList.arguments[1]::value.detached()
val dstArgument = argumentList.arguments[2]::value.detached()
val dstBeginArgument = argumentList.arguments[3]::value.detached()
JKArgumentListImpl(dstArgument, dstBeginArgument, srcBeginArgument, srcEndArgument)
JKArgumentList(dstArgument, dstBeginArgument, srcBeginArgument, srcEndArgument)
},
Method("java.lang.String.valueOf")
@@ -310,7 +312,7 @@ class BuiltinMembersConversion(context: NewJ2kConverterContext) : RecursiveAppli
detachedArguments.first()::value.detached().callOn(
symbolProvider.provideMethodSymbol("kotlin.text.toRegex")
)
JKArgumentListImpl(listOf(JKArgumentImpl(first)) + detachedArguments.drop(1))
JKArgumentList(listOf(JKArgumentImpl(first)) + detachedArguments.drop(1))
},
Method("java.lang.String.replaceFirst")
convertTo Method("kotlin.text.replaceFirst")
@@ -321,15 +323,15 @@ class BuiltinMembersConversion(context: NewJ2kConverterContext) : RecursiveAppli
symbolProvider.provideMethodSymbol("kotlin.text.toRegex")
)
JKArgumentListImpl(listOf(JKArgumentImpl(first)) + detachedArguments.drop(1))
JKArgumentList(listOf(JKArgumentImpl(first)) + detachedArguments.drop(1))
},
Method("java.lang.String.equalsIgnoreCase")
convertTo Method("kotlin.text.equals")
withArgumentsProvider { arguments ->
JKArgumentListImpl(
arguments::arguments.detached() + JKNamedArgumentImpl(
JKBooleanLiteral(true),
JKNameIdentifierImpl("ignoreCase")
JKArgumentList(
arguments::arguments.detached() + JKNamedArgument(
JKLiteralExpression("true", JKLiteralExpression.LiteralType.BOOLEAN),
JKNameIdentifier("ignoreCase")
)
)
},
@@ -337,10 +339,10 @@ class BuiltinMembersConversion(context: NewJ2kConverterContext) : RecursiveAppli
Method("java.lang.String.compareToIgnoreCase")
convertTo Method("kotlin.text.compareTo")
withArgumentsProvider { arguments ->
JKArgumentListImpl(
arguments::arguments.detached() + JKNamedArgumentImpl(
JKBooleanLiteral(true),
JKNameIdentifierImpl("ignoreCase")
JKArgumentList(
arguments::arguments.detached() + JKNamedArgument(
JKLiteralExpression("true", JKLiteralExpression.LiteralType.BOOLEAN),
JKNameIdentifier("ignoreCase")
)
)
},
@@ -350,22 +352,22 @@ class BuiltinMembersConversion(context: NewJ2kConverterContext) : RecursiveAppli
withByArgumentsFilter { it.size == 5 }
withArgumentsProvider { arguments ->
val detachedArguments = arguments::arguments.detached()
JKArgumentListImpl(
detachedArguments.drop(1) + JKNamedArgumentImpl(
JKArgumentList(
detachedArguments.drop(1) + JKNamedArgument(
detachedArguments.first()::value.detached().also {
it.clearNonCodeElements()
},
JKNameIdentifierImpl("ignoreCase")
JKNameIdentifier("ignoreCase")
)
)
},
Method("java.lang.String.concat") convertTo
CustomExpression { expression ->
if (expression !is JKMethodCallExpression) error("Expression should be JKMethodCallExpression")
if (expression !is JKCallExpression) error("Expression should be JKCallExpression")
val firstArgument = expression.parent.cast<JKQualifiedExpression>()::receiver.detached()
val secondArgument = expression.arguments.arguments.first()::value.detached()
JKBinaryExpressionImpl(
JKBinaryExpression(
firstArgument,
secondArgument,
JKKtOperatorImpl(JKOperatorToken.PLUS, typeFactory.types.possiblyNullString)
@@ -378,7 +380,7 @@ class BuiltinMembersConversion(context: NewJ2kConverterContext) : RecursiveAppli
andAfter { expression ->
val arguments =
expression.cast<JKQualifiedExpression>()
.selector.cast<JKMethodCallExpression>()
.selector.cast<JKCallExpression>()
.arguments
val limitArgument = arguments.arguments[1].value
val limit = limitArgument.asLiteralTextWithPrefix()?.toIntOrNull()
@@ -391,8 +393,8 @@ class BuiltinMembersConversion(context: NewJ2kConverterContext) : RecursiveAppli
}.callOn(
symbolProvider.provideMethodSymbol("kotlin.collections.dropLastWhile"),
listOf(
JKLambdaExpressionImpl(
JKFieldAccessExpressionImpl(
JKLambdaExpression(
JKFieldAccessExpression(
JKUnresolvedField(//TODO replace with `it` parameter
"it",
typeFactory
@@ -407,7 +409,7 @@ class BuiltinMembersConversion(context: NewJ2kConverterContext) : RecursiveAppli
val lastArgument = arguments.arguments.last().value.copyTreeAndDetach()
.callOn(
symbolProvider.provideMethodSymbol("kotlin.ranges.coerceAtLeast"),
listOf(JKKtLiteralExpressionImpl("0", JKLiteralExpression.LiteralType.INT))
listOf(JKLiteralExpression("0", JKLiteralExpression.LiteralType.INT))
)
arguments.arguments = arguments.arguments.dropLast(1) + JKArgumentImpl(lastArgument)
}
@@ -422,17 +424,17 @@ class BuiltinMembersConversion(context: NewJ2kConverterContext) : RecursiveAppli
Method("java.lang.String.trim")
convertTo Method("kotlin.text.trim")
withArgumentsProvider {
JKArgumentListImpl(
JKLambdaExpressionImpl(
JKExpressionStatementImpl(
JKBinaryExpressionImpl(
JKFieldAccessExpressionImpl(
JKArgumentList(
JKLambdaExpression(
JKExpressionStatement(
JKBinaryExpression(
JKFieldAccessExpression(
JKUnresolvedField(//TODO replace with `it` parameter
"it",
typeFactory
)
),
JKKtLiteralExpressionImpl("' '", JKLiteralExpression.LiteralType.CHAR),
JKLiteralExpression("' '", JKLiteralExpression.LiteralType.CHAR),
JKKtOperatorImpl(
JKOperatorToken.LTEQ,
typeFactory.types.boolean
@@ -444,11 +446,11 @@ class BuiltinMembersConversion(context: NewJ2kConverterContext) : RecursiveAppli
)
},
Method("java.lang.String.format") convertTo CustomExpression { expression ->
JKClassAccessExpressionImpl(
JKClassAccessExpression(
symbolProvider.provideClassSymbol(KotlinBuiltIns.FQ_NAMES.string)
).callOn(
symbolProvider.provideMethodSymbol("kotlin.text.String.format"),
(expression as JKMethodCallExpression).arguments::arguments.detached()
(expression as JKCallExpression).arguments::arguments.detached()
)
} withReplaceType ReplaceType.REPLACE_WITH_QUALIFIER,
@@ -469,13 +471,12 @@ class BuiltinMembersConversion(context: NewJ2kConverterContext) : RecursiveAppli
private fun JKExpression.callOn(symbol: JKMethodSymbol, arguments: List<JKArgument> = emptyList()) =
JKQualifiedExpressionImpl(
JKQualifiedExpression(
this,
JKKtQualifierImpl.DOT,
JKKtCallExpressionImpl(
JKCallExpressionImpl(
symbol,
JKArgumentListImpl(arguments),
JKTypeArgumentListImpl()
JKArgumentList(arguments),
JKTypeArgumentList()
)
)
@@ -6,12 +6,11 @@
package org.jetbrains.kotlin.nj2k.conversions
import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
import org.jetbrains.kotlin.nj2k.declarationList
import org.jetbrains.kotlin.nj2k.getCompanion
import org.jetbrains.kotlin.nj2k.psi
import org.jetbrains.kotlin.nj2k.tree.*
import org.jetbrains.kotlin.nj2k.tree.impl.JKAnnotationListImpl
import org.jetbrains.kotlin.nj2k.tree.impl.JKClassImpl
import org.jetbrains.kotlin.nj2k.tree.impl.JKModalityModifierElementImpl
import org.jetbrains.kotlin.nj2k.tree.impl.psi
class ClassToObjectPromotionConversion(context: NewJ2kConverterContext) : RecursiveApplicableConversionBase(context) {
override fun applyToElement(element: JKTreeElement): JKTreeElement {
@@ -37,7 +36,7 @@ class ClassToObjectPromotionConversion(context: NewJ2kConverterContext) : Recurs
companion.invalidate()
element.invalidate()
return recurse(
JKClassImpl(
JKClass(
element.name,
element.inheritance,
JKClass.ClassKind.OBJECT,
@@ -49,10 +48,10 @@ class ClassToObjectPromotionConversion(context: NewJ2kConverterContext) : Recurs
it is JKClass && it.classKind != JKClass.ClassKind.COMPANION
}.map { it.detached(element.classBody) }
},
JKAnnotationListImpl(),
JKAnnotationList(),
element.otherModifierElements,
element.visibilityElement,
JKModalityModifierElementImpl(Modality.FINAL)
JKModalityModifierElement(Modality.FINAL)
).withNonCodeElementsFrom(element)
)
}
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
import org.jetbrains.kotlin.nj2k.symbols.JKSymbol
import org.jetbrains.kotlin.nj2k.symbols.fqNameToImport
import org.jetbrains.kotlin.nj2k.tree.*
import org.jetbrains.kotlin.nj2k.types.JKClassType
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
@@ -24,9 +25,9 @@ class CollectImportsConversion(context: NewJ2kConverterContext) : RecursiveAppli
when (element) {
is JKClassAccessExpression -> addSymbol(element.identifier)
is JKFieldAccessExpression -> addSymbol(element.identifier)
is JKMethodCallExpression -> addSymbol(element.identifier)
is JKCallExpression -> addSymbol(element.identifier)
is JKAnnotation -> addSymbol(element.classSymbol)
is JKJavaNewExpression -> addSymbol(element.classSymbol)
is JKNewExpression -> addSymbol(element.classSymbol)
is JKInheritanceInfo -> {
element.implements
}
@@ -7,19 +7,18 @@ package org.jetbrains.kotlin.nj2k.conversions
import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
import org.jetbrains.kotlin.nj2k.tree.*
import org.jetbrains.kotlin.nj2k.tree.impl.JKKtConstructorImpl
import org.jetbrains.kotlin.nj2k.tree.impl.JKStubExpressionImpl
class ConstructorConversion(context: NewJ2kConverterContext) : RecursiveApplicableConversionBase(context) {
override fun applyToElement(element: JKTreeElement): JKTreeElement {
if (element !is JKJavaMethod) return recurse(element)
if (element !is JKMethod) return recurse(element)
val outerClass = element.parentOfType<JKClass>() ?: return recurse(element)
if (element.name.value != outerClass.name.value) return recurse(element)
element.invalidate()
val delegationCall = lookupDelegationCall(element.block) ?: JKStubExpressionImpl()
val delegationCall = lookupDelegationCall(element.block) ?: JKStubExpression()
return JKKtConstructorImpl(
return JKConstructorImpl(
element.name,
element.parameters,
element.block,
@@ -8,8 +8,8 @@ package org.jetbrains.kotlin.nj2k.conversions
import org.jetbrains.kotlin.nj2k.*
import org.jetbrains.kotlin.nj2k.symbols.JKUniverseMethodSymbol
import org.jetbrains.kotlin.nj2k.tree.*
import org.jetbrains.kotlin.nj2k.tree.impl.JKFieldAccessExpressionImpl
import org.jetbrains.kotlin.nj2k.tree.impl.psi
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
class DefaultArgumentsConversion(context: NewJ2kConverterContext) : RecursiveApplicableConversionBase(context) {
@@ -98,7 +98,7 @@ class DefaultArgumentsConversion(context: NewJ2kConverterContext) : RecursiveApp
if (target is JKParameter) {
val newSymbol =
symbolProvider.provideUniverseSymbol(calledMethod.parameters[method.parameters.indexOf(target)])
return JKFieldAccessExpressionImpl(newSymbol)
return JKFieldAccessExpression(newSymbol)
}
}
@@ -109,13 +109,14 @@ class DefaultArgumentsConversion(context: NewJ2kConverterContext) : RecursiveApp
element.declarations -= method
calledMethod.withNonCodeElementsFrom(method)
}
for (method in element.declarations) {
if (method !is JKJavaMethod) continue
if (method.hasParametersWithDefaultValues()
&& (method.visibility == Visibility.PUBLIC || method.visibility == Visibility.INTERNAL)
) {
method.annotationList.annotations += jvmAnnotation("JvmOverloads", symbolProvider)
if (element.parentOfType<JKClass>()?.classKind != JKClass.ClassKind.ANNOTATION) {
for (method in element.declarations) {
if (method !is JKMethod) continue
if (method.hasParametersWithDefaultValues()
&& (method.visibility == Visibility.PUBLIC || method.visibility == Visibility.INTERNAL)
) {
method.annotationList.annotations += jvmAnnotation("JvmOverloads", symbolProvider)
}
}
}
@@ -128,11 +129,11 @@ class DefaultArgumentsConversion(context: NewJ2kConverterContext) : RecursiveApp
if (first is JKNameIdentifier && second is JKNameIdentifier) return first.value == second.value
if (first is JKLiteralExpression && second is JKLiteralExpression) return first.literal == second.literal
if (first is JKFieldAccessExpression && second is JKFieldAccessExpression && first.identifier != second.identifier) return false
if (first is JKMethodCallExpression && second is JKMethodCallExpression && first.identifier != second.identifier) return false
return if (first is JKBranchElement && second is JKBranchElement) {
if (first is JKCallExpression && second is JKCallExpression && first.identifier != second.identifier) return false
return if (first is JKTreeElement && second is JKTreeElement) {
first.children.zip(second.children) { childOfFirst, childOfSecond ->
when {
childOfFirst is JKBranchElement && childOfSecond is JKBranchElement -> {
childOfFirst is JKTreeElement && childOfSecond is JKTreeElement -> {
areTheSameExpressions(
childOfFirst,
childOfSecond
@@ -155,14 +156,14 @@ class DefaultArgumentsConversion(context: NewJ2kConverterContext) : RecursiveApp
private fun JKMethod.hasParametersWithDefaultValues() =
parameters.any { it.initializer !is JKStubExpression }
private fun lookupCall(statement: JKStatement): JKMethodCallExpression? {
private fun lookupCall(statement: JKStatement): JKCallExpression? {
val expression = when (statement) {
is JKExpressionStatement -> statement.expression
is JKReturnStatement -> statement.expression
else -> null
}
return when (expression) {
is JKMethodCallExpression -> expression
is JKCallExpression -> expression
is JKQualifiedExpression -> {
if (expression.receiver !is JKThisExpression) return null
expression.selector.safeAs()
@@ -170,5 +171,4 @@ class DefaultArgumentsConversion(context: NewJ2kConverterContext) : RecursiveApp
else -> null
}
}
}
@@ -9,10 +9,8 @@ import com.intellij.psi.PsiEnumConstant
import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
import org.jetbrains.kotlin.nj2k.symbols.*
import org.jetbrains.kotlin.nj2k.tree.*
import org.jetbrains.kotlin.nj2k.tree.impl.JKClassAccessExpressionImpl
import org.jetbrains.kotlin.nj2k.tree.impl.JKFieldAccessExpressionImpl
import org.jetbrains.kotlin.nj2k.tree.impl.JKKtQualifierImpl
import org.jetbrains.kotlin.nj2k.tree.impl.JKQualifiedExpressionImpl
import org.jetbrains.kotlin.psi.psiUtil.containingClass
@@ -23,10 +21,9 @@ class EnumFieldAccessConversion(context: NewJ2kConverterContext) : RecursiveAppl
val enumsClassSymbol = element.identifier.enumClassSymbol() ?: return recurse(element)
return recurse(
JKQualifiedExpressionImpl(
JKClassAccessExpressionImpl(enumsClassSymbol),
JKKtQualifierImpl.DOT,
JKFieldAccessExpressionImpl(element.identifier)
JKQualifiedExpression(
JKClassAccessExpression(enumsClassSymbol),
JKFieldAccessExpression(element.identifier)
)
)
}
@@ -9,17 +9,17 @@ import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
import org.jetbrains.kotlin.nj2k.equalsExpression
import org.jetbrains.kotlin.nj2k.symbols.deepestFqName
import org.jetbrains.kotlin.nj2k.tree.*
import org.jetbrains.kotlin.nj2k.tree.impl.JKParenthesizedExpressionImpl
class EqualsOperatorConversion(context: NewJ2kConverterContext) : RecursiveApplicableConversionBase(context) {
override fun applyToElement(element: JKTreeElement): JKTreeElement {
if (element !is JKQualifiedExpression) return recurse(element)
if (element.receiver is JKSuperExpression) return recurse(element)
val selector = element.selector as? JKMethodCallExpression ?: return (element)
val selector = element.selector as? JKCallExpression ?: return (element)
val argument = selector.arguments.arguments.singleOrNull() ?: return recurse(element)
if (selector.identifier.deepestFqName() == "java.lang.Object.equals") {
return recurse(
JKParenthesizedExpressionImpl(
JKParenthesizedExpression(
equalsExpression(
element::receiver.detached(),
argument::value.detached(),
@@ -7,31 +7,13 @@ package org.jetbrains.kotlin.nj2k.conversions
import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
import org.jetbrains.kotlin.nj2k.tree.*
import org.jetbrains.kotlin.nj2k.tree.impl.*
class FieldToPropertyConversion(context : NewJ2kConverterContext) : RecursiveApplicableConversionBase(context) {
class FieldToPropertyConversion(context: NewJ2kConverterContext) : RecursiveApplicableConversionBase(context) {
override fun applyToElement(element: JKTreeElement): JKTreeElement {
if (element !is JKJavaField) return recurse(element)
element.invalidate()
val mutability =
if (element.modality == Modality.FINAL) Mutability.IMMUTABLE
else Mutability.MUTABLE
return recurse(
JKKtPropertyImpl(
element.type,
element.name,
element.initializer,
JKKtEmptyGetterOrSetterImpl(),
JKKtEmptyGetterOrSetterImpl(),
element.annotationList,
element.otherModifierElements,
element.visibilityElement,
JKModalityModifierElementImpl(Modality.FINAL),
JKMutabilityModifierElementImpl(mutability).withNonCodeElementsFrom(element.modalityElement)
).also {
it.psi = element.psi
it.takeNonCodeElementsFrom(element)
}
)
if (element !is JKField) return recurse(element)
element.mutability = if (element.modality == Modality.FINAL) Mutability.IMMUTABLE else Mutability.MUTABLE
element.modality = Modality.FINAL
return recurse(element)
}
}
@@ -10,7 +10,6 @@ import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
import org.jetbrains.kotlin.nj2k.tree.JKImportList
import org.jetbrains.kotlin.nj2k.tree.JKTreeElement
class FilterImportsConversion(context : NewJ2kConverterContext) : RecursiveApplicableConversionBase(context) {
override fun applyToElement(element: JKTreeElement): JKTreeElement {
if (element !is JKImportList) return recurse(element)
@@ -13,8 +13,11 @@ import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.nj2k.*
import org.jetbrains.kotlin.nj2k.symbols.deepestFqName
import org.jetbrains.kotlin.nj2k.tree.*
import org.jetbrains.kotlin.nj2k.tree.impl.*
import org.jetbrains.kotlin.nj2k.types.JKJavaArrayType
import org.jetbrains.kotlin.nj2k.types.JKJavaPrimitiveType
import org.jetbrains.kotlin.nj2k.types.JKNoTypeImpl
import org.jetbrains.kotlin.nj2k.types.type
import kotlin.math.abs
@@ -35,23 +38,23 @@ class ForConversion(context: NewJ2kConverterContext) : RecursiveApplicableConver
val whileBody = createWhileBody(loopStatement)
val condition =
if (loopStatement.condition !is JKStubExpression) loopStatement::condition.detached()
else JKBooleanLiteral(true)
val whileStatement = JKWhileStatementImpl(condition, whileBody)
else JKLiteralExpression("true", JKLiteralExpression.LiteralType.BOOLEAN)
val whileStatement = JKWhileStatement(condition, whileBody)
if (loopStatement.initializer is JKEmptyStatement) return whileStatement
val convertedFromForLoopSyntheticWhileStatement =
JKKtConvertedFromForLoopSyntheticWhileStatementImpl(
JKKtConvertedFromForLoopSyntheticWhileStatement(
loopStatement::initializer.detached(),
whileStatement
)
val notNeedParentBlock = loopStatement.parent is JKBlock
|| loopStatement.parent is JKLabeledStatement && loopStatement.parent?.parent is JKBlock
|| loopStatement.parent is JKLabeledExpression && loopStatement.parent?.parent is JKBlock
return when {
loopStatement.hasNameConflict() ->
JKExpressionStatementImpl(
JKExpressionStatement(
runExpression(
convertedFromForLoopSyntheticWhileStatement,
symbolProvider
@@ -71,8 +74,8 @@ class ForConversion(context: NewJ2kConverterContext) : RecursiveApplicableConver
if (elementPsi.findContinuedStatement()?.toContinuedLoop() != loopStatement.psi<PsiForStatement>()) return recurse(element)
val statements = loopStatement.updaters.map { it.copyTreeAndDetach() } + element.copyTreeAndDetach()
return if (element.parent is JKBlock)
JKBlockStatementWithoutBracketsImpl(statements)
else JKBlockStatementImpl(JKBlockImpl(statements))
JKBlockStatementWithoutBrackets(statements)
else JKBlockStatement(JKBlockImpl(statements))
}
}
@@ -91,15 +94,15 @@ class ForConversion(context: NewJ2kConverterContext) : RecursiveApplicableConver
val statements =
if (hasNameConflict) {
listOf(JKExpressionStatementImpl(runExpression(body, symbolProvider))) + loopStatement::updaters.detached()
listOf(JKExpressionStatement(runExpression(body, symbolProvider))) + loopStatement::updaters.detached()
} else {
body.block::statements.detached() + loopStatement::updaters.detached()
}
return JKBlockStatementImpl(JKBlockImpl(statements))
return JKBlockStatement(JKBlockImpl(statements))
} else {
val statements =
listOf(body as JKStatement) + loopStatement::updaters.detached()
return JKBlockStatementImpl(JKBlockImpl(statements))
return JKBlockStatement(JKBlockImpl(statements))
}
}
@@ -136,15 +139,15 @@ class ForConversion(context: NewJ2kConverterContext) : RecursiveApplicableConver
val range = forIterationRange(start, right, reversed, inclusive, loopVarPsi)
val explicitType =
if (context.converter.settings.specifyLocalVariableTypeByDefault)
JKJavaPrimitiveTypeImpl.INT
JKJavaPrimitiveType.INT
else JKNoTypeImpl
val loopVarDeclaration =
JKForLoopVariableImpl(
JKTypeElementImpl(explicitType),
JKForLoopVariable(
JKTypeElement(explicitType),
loopVar::name.detached(),
JKStubExpressionImpl()
JKStubExpression()
)
return JKForInStatementImpl(
return JKForInStatement(
loopVarDeclaration,
range,
loopStatement::body.detached()
@@ -176,13 +179,13 @@ class ForConversion(context: NewJ2kConverterContext) : RecursiveApplicableConver
convertBound(bound, if (inclusiveComparison) 0 else +1),
context
)
bound !is JKKtLiteralExpression && !inclusiveComparison ->
bound !is JKLiteralExpression && !inclusiveComparison ->
untilToExpression(
start,
convertBound(bound, 0),
context
)
else -> JKBinaryExpressionImpl(
else -> JKBinaryExpression(
start,
convertBound(bound, if (inclusiveComparison) 0 else -1),
JKKtOperatorImpl(
@@ -198,13 +201,13 @@ class ForConversion(context: NewJ2kConverterContext) : RecursiveApplicableConver
if (bound is JKLiteralExpression && bound.type == JKLiteralExpression.LiteralType.INT) {
val value = bound.literal.toInt()
return JKKtLiteralExpressionImpl((value + correction).toString(), bound.type)
return JKLiteralExpression((value + correction).toString(), bound.type)
}
val sign = if (correction > 0) JKOperatorToken.PLUS else JKOperatorToken.MINUS
return JKBinaryExpressionImpl(
return JKBinaryExpression(
bound,
JKKtLiteralExpressionImpl(abs(correction).toString(), JKLiteralExpression.LiteralType.INT),
JKLiteralExpression(abs(correction).toString(), JKLiteralExpression.LiteralType.INT),
JKKtOperatorImpl(
sign,
typeFactory.types.int
@@ -239,12 +242,11 @@ class ForConversion(context: NewJ2kConverterContext) : RecursiveApplicableConver
?: return null
return if (reversed) {
JKQualifiedExpressionImpl(
JKQualifiedExpression(
indices,
JKKtQualifierImpl.DOT,
JKJavaMethodCallExpressionImpl(
JKCallExpressionImpl(
symbolProvider.provideMethodSymbol("kotlin.collections.reversed"),
JKArgumentListImpl()
JKArgumentList()
)
)
} else indices
@@ -252,7 +254,7 @@ class ForConversion(context: NewJ2kConverterContext) : RecursiveApplicableConver
private fun indicesByCollectionSize(javaSizeCall: JKQualifiedExpression): JKQualifiedExpression? {
val methodCall = javaSizeCall.selector as? JKMethodCallExpression ?: return null
val methodCall = javaSizeCall.selector as? JKCallExpression ?: return null
return if (methodCall.identifier.deepestFqName() == "java.util.Collection.size"
&& methodCall.arguments.arguments.isEmpty()
) toIndicesCall(javaSizeCall) else null
@@ -269,10 +271,10 @@ class ForConversion(context: NewJ2kConverterContext) : RecursiveApplicableConver
private fun toIndicesCall(javaSizeCall: JKQualifiedExpression): JKQualifiedExpression? {
if (javaSizeCall.psi == null) return null
val selector = JKFieldAccessExpressionImpl(
val selector = JKFieldAccessExpression(
symbolProvider.provideFieldSymbol("kotlin.collections.indices")
)
return JKQualifiedExpressionImpl(javaSizeCall::receiver.detached(), javaSizeCall.operator, selector)
return JKQualifiedExpression(javaSizeCall::receiver.detached(), selector)
}
private fun JKJavaForLoopStatement.hasNameConflict(): Boolean {
@@ -8,14 +8,14 @@ package org.jetbrains.kotlin.nj2k.conversions
import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
import org.jetbrains.kotlin.nj2k.symbols.JKClassSymbol
import org.jetbrains.kotlin.nj2k.tree.*
import org.jetbrains.kotlin.nj2k.tree.impl.JKBlockStatementImpl
import org.jetbrains.kotlin.nj2k.tree.impl.JKLambdaExpressionImpl
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
class FunctionAsAnonymousObjectToLambdaConversion(context: NewJ2kConverterContext) : RecursiveApplicableConversionBase(context) {
override fun applyToElement(element: JKTreeElement): JKTreeElement {
if (element !is JKJavaNewExpression) return recurse(element)
if (element.isAnonymousClass()
if (element !is JKNewExpression) return recurse(element)
if (element.isAnonymousClass
&& element.classSymbol.isKtFunction()
) {
val invokeFunction = element.classBody.declarations.singleOrNull()
@@ -23,8 +23,8 @@ class FunctionAsAnonymousObjectToLambdaConversion(context: NewJ2kConverterContex
?.takeIf { it.name.value == "invoke" }
?: return recurse(element)
return recurse(
JKLambdaExpressionImpl(
JKBlockStatementImpl(invokeFunction::block.detached()),
JKLambdaExpression(
JKBlockStatement(invokeFunction::block.detached()),
invokeFunction::parameters.detached()
)
)
@@ -6,14 +6,13 @@
package org.jetbrains.kotlin.nj2k.conversions
import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
import org.jetbrains.kotlin.nj2k.copyTreeAndDetach
import org.jetbrains.kotlin.nj2k.isEquals
import org.jetbrains.kotlin.nj2k.parenthesizeIfBinaryExpression
import org.jetbrains.kotlin.nj2k.symbols.JKMethodSymbol
import org.jetbrains.kotlin.nj2k.symbols.isUnresolved
import org.jetbrains.kotlin.nj2k.symbols.parameterTypesWithUnfoldedVarargs
import org.jetbrains.kotlin.nj2k.tree.*
import org.jetbrains.kotlin.nj2k.tree.impl.*
import org.jetbrains.kotlin.nj2k.types.JKClassType
import org.jetbrains.kotlin.nj2k.types.*
import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
@@ -21,7 +20,7 @@ class ImplicitCastsConversion(context: NewJ2kConverterContext) : RecursiveApplic
override fun applyToElement(element: JKTreeElement): JKTreeElement {
when (element) {
is JKVariable -> convertVariable(element)
is JKMethodCallExpression -> convertMethodCallExpression(element)
is JKCallExpression -> convertMethodCallExpression(element)
is JKBinaryExpression -> return recurse(convertBinaryExpression(element))
is JKKtAssignmentStatement -> convertAssignmentStatement(element)
}
@@ -31,23 +30,22 @@ class ImplicitCastsConversion(context: NewJ2kConverterContext) : RecursiveApplic
private fun convertBinaryExpression(binaryExpression: JKBinaryExpression): JKExpression {
fun JKBinaryExpression.convertBinaryOperationWithChar(): JKBinaryExpression {
val leftType = left.type(typeFactory)?.asPrimitiveType() ?: return this
val rightType = right.type(typeFactory)?.asPrimitiveType() ?: return this
val leftType = left.calculateType(typeFactory).asPrimitiveType() ?: return this
val rightType = right.calculateType(typeFactory).asPrimitiveType() ?: return this
val leftOperandCastedCasted by lazy {
JKBinaryExpressionImpl(
val leftOperandCastedCasted by lazy(LazyThreadSafetyMode.NONE) {
JKBinaryExpression(
::left.detached().let { it.castTo(rightType, strict = true) ?: it },
::right.detached(),
operator
)
}
val rightOperandCastedCasted by lazy {
JKBinaryExpressionImpl(
val rightOperandCastedCasted by lazy(LazyThreadSafetyMode.NONE) {
JKBinaryExpression(
::left.detached(),
::right.detached().let { it.castTo(leftType, strict = true) ?: it },
operator
)
}
@@ -73,21 +71,20 @@ class ImplicitCastsConversion(context: NewJ2kConverterContext) : RecursiveApplic
}
private fun convertAssignmentStatement(statement: JKKtAssignmentStatement) {
val expressionType = statement.field.type(typeFactory) ?: return
val expressionType = statement.field.calculateType(typeFactory) ?: return
statement.expression.castTo(expressionType)?.also {
statement.expression = it
}
}
private fun convertMethodCallExpression(expression: JKMethodCallExpression) {
private fun convertMethodCallExpression(expression: JKCallExpression) {
if (expression.identifier.isUnresolved) return
val parameterTypes = expression.identifier.parameterTypesWithUnfoldedVarargs() ?: return
val newArguments =
(expression.arguments.arguments.asSequence() zip parameterTypes)
.map { (expression, toType) ->
expression.value.castTo(toType)
}.toList()
val parameterTypes = expression.identifier.parameterTypesWithLastArgumentUnfoldedAsVararg() ?: return
val newArguments = expression.arguments.arguments.mapIndexed { argumentIndex, argument ->
val toType = parameterTypes.getOrNull(argumentIndex) ?: parameterTypes.last()
argument.value.castTo(toType)
}
val needUpdate = newArguments.any { it != null }
if (needUpdate) {
for ((newArgument, oldArgument) in newArguments zip expression.arguments.arguments) {
@@ -100,15 +97,14 @@ class ImplicitCastsConversion(context: NewJ2kConverterContext) : RecursiveApplic
private fun JKExpression.castStringToRegex(toType: JKType): JKExpression? {
if (toType.safeAs<JKClassType>()?.classReference?.fqName != "java.util.regex.Pattern") return null
val expressionType = type(typeFactory) ?: return null
val expressionType = calculateType(typeFactory)
if (!expressionType.isStringType()) return null
return JKQualifiedExpressionImpl(
return JKQualifiedExpression(
copyTreeAndDetach().parenthesizeIfBinaryExpression(),
JKKtQualifierImpl.DOT,
JKKtCallExpressionImpl(
JKCallExpressionImpl(
symbolProvider.provideMethodSymbol("kotlin.text.toRegex"),
JKArgumentListImpl(),
JKTypeArgumentListImpl()
JKArgumentList(),
JKTypeArgumentList()
)
)
@@ -116,26 +112,26 @@ class ImplicitCastsConversion(context: NewJ2kConverterContext) : RecursiveApplic
private fun JKExpression.castToAsPrimitiveTypes(toType: JKType, strict: Boolean): JKExpression? {
if (this is JKPrefixExpression
&& (operator.token.text == "+" || operator.token.text == "-")
&& (operator.token == JKOperatorToken.PLUS || operator.token == JKOperatorToken.MINUS)
) {
val casted = expression.castToAsPrimitiveTypes(toType, strict) ?: return null
return JKPrefixExpressionImpl(casted, operator)
return JKPrefixExpression(casted, operator)
}
val expressionTypeAsPrimitive = type(typeFactory)?.asPrimitiveType() ?: return null
val expressionTypeAsPrimitive = calculateType(typeFactory).asPrimitiveType() ?: return null
val toTypeAsPrimitive = toType.asPrimitiveType() ?: return null
if (toTypeAsPrimitive == expressionTypeAsPrimitive) return null
if (this is JKLiteralExpression) {
if (!strict
&& expressionTypeAsPrimitive == JKJavaPrimitiveTypeImpl.INT
&& (toTypeAsPrimitive == JKJavaPrimitiveTypeImpl.LONG ||
toTypeAsPrimitive == JKJavaPrimitiveTypeImpl.SHORT ||
toTypeAsPrimitive == JKJavaPrimitiveTypeImpl.BYTE)
&& expressionTypeAsPrimitive == JKJavaPrimitiveType.INT
&& (toTypeAsPrimitive == JKJavaPrimitiveType.LONG ||
toTypeAsPrimitive == JKJavaPrimitiveType.SHORT ||
toTypeAsPrimitive == JKJavaPrimitiveType.BYTE)
) return null
val expectedType = toTypeAsPrimitive.toLiteralType() ?: JKLiteralExpression.LiteralType.INT
if (expressionTypeAsPrimitive.isNumberType() && toTypeAsPrimitive.isNumberType()) {
return JKJavaLiteralExpressionImpl(
return JKLiteralExpression(
literal,
expectedType
)
@@ -144,22 +140,27 @@ class ImplicitCastsConversion(context: NewJ2kConverterContext) : RecursiveApplic
val initialTypeName = expressionTypeAsPrimitive.jvmPrimitiveType.javaKeywordName.capitalize()
val conversionFunctionName = "to${toTypeAsPrimitive.jvmPrimitiveType.javaKeywordName.capitalize()}"
return JKQualifiedExpressionImpl(
this.copyTreeAndDetach(),
JKKtQualifierImpl.DOT,
JKJavaMethodCallExpressionImpl(
return JKQualifiedExpression(
copyTreeAndDetach(),
JKCallExpressionImpl(
symbolProvider.provideMethodSymbol("kotlin.$initialTypeName.$conversionFunctionName"),
JKArgumentListImpl()
JKArgumentList()
)
)
}
private fun JKExpression.castTo(toType: JKType, strict: Boolean = false): JKExpression? {
val expressionType = type(typeFactory)
val expressionType = calculateType(typeFactory)
if (expressionType == toType) return null
castToAsPrimitiveTypes(toType, strict)?.also { return it }
castStringToRegex(toType)?.also { return it }
return null
}
private fun JKMethodSymbol.parameterTypesWithLastArgumentUnfoldedAsVararg(): List<JKType>? {
val realParameterTypes = parameterTypes ?: return null
if (realParameterTypes.isEmpty()) return null
val lastArrayType = realParameterTypes.lastOrNull()?.arrayInnerType() ?: return realParameterTypes
return realParameterTypes.subList(0, realParameterTypes.lastIndex) + lastArrayType
}
}
@@ -6,13 +6,12 @@
package org.jetbrains.kotlin.nj2k.conversions
import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
import org.jetbrains.kotlin.nj2k.declarationList
import org.jetbrains.kotlin.nj2k.findUsages
import org.jetbrains.kotlin.nj2k.modality
import org.jetbrains.kotlin.nj2k.symbols.JKMethodSymbol
import org.jetbrains.kotlin.nj2k.tree.*
import org.jetbrains.kotlin.nj2k.tree.impl.JKBooleanLiteral
import org.jetbrains.kotlin.nj2k.tree.impl.JKJavaLiteralExpressionImpl
import org.jetbrains.kotlin.nj2k.tree.impl.JKJavaPrimitiveTypeImpl
import org.jetbrains.kotlin.nj2k.tree.impl.JKNullLiteral
import org.jetbrains.kotlin.nj2k.types.JKClassType
import org.jetbrains.kotlin.nj2k.types.JKJavaPrimitiveType
import org.jetbrains.kotlin.nj2k.types.JKTypeParameterType
@@ -26,7 +25,7 @@ class ImplicitInitializerConversion(context: NewJ2kConverterContext) : Recursive
}
override fun applyToElement(element: JKTreeElement): JKTreeElement {
if (element !is JKJavaField) return recurse(element)
if (element !is JKField) return recurse(element)
if (element.initializer !is JKStubExpression) return recurse(element)
val initializationState = element.initializationState()
@@ -40,7 +39,7 @@ class ImplicitInitializerConversion(context: NewJ2kConverterContext) : Recursive
}
val newInitializer = when (val fieldType = element.type.type) {
is JKClassType, is JKTypeParameterType -> JKNullLiteral()
is JKClassType, is JKTypeParameterType -> JKLiteralExpression("null", JKLiteralExpression.LiteralType.NULL)
is JKJavaPrimitiveType -> createPrimitiveTypeInitializer(fieldType)
else -> null
}
@@ -50,11 +49,11 @@ class ImplicitInitializerConversion(context: NewJ2kConverterContext) : Recursive
return element
}
private fun JKJavaField.initializationState(): InitializationState {
private fun JKField.initializationState(): InitializationState {
val fieldSymbol = symbolProvider.provideUniverseSymbol(this)
val containingClass = parentOfType<JKClass>() ?: return InitializationState.NON_INITIALIZED
val symbolToConstructor = containingClass.declarationList
.filterIsInstance<JKKtConstructor>()
.filterIsInstance<JKConstructor>()
.map { symbolProvider.provideUniverseSymbol(it) to it }
.toMap()
@@ -63,7 +62,7 @@ class ImplicitInitializerConversion(context: NewJ2kConverterContext) : Recursive
?.identifier
val constructors = containingClass.declarationList
.filterIsInstance<JKKtConstructor>()
.filterIsInstance<JKConstructor>()
.map { symbolProvider.provideUniverseSymbol(it) to false }
.toMap()
.toMutableMap()
@@ -74,11 +73,11 @@ class ImplicitInitializerConversion(context: NewJ2kConverterContext) : Recursive
when {
parent is JKKtAssignmentStatement -> parent
parent is JKQualifiedExpression && parent.receiver is JKThisExpression ->
parent.parent as? JKKtAssignmentStatement
parent.parent as? JKKtAssignmentStatement
else -> null
} ?: return@mapNotNull null
val constructor =
(assignmentStatement.parent as? JKBlock)?.parent as? JKKtConstructor ?: return@mapNotNull null
(assignmentStatement.parent as? JKBlock)?.parent as? JKConstructor ?: return@mapNotNull null
val isInitializer = when (parent) {
is JKKtAssignmentStatement -> (parent.field as? JKFieldAccessExpression)?.identifier == fieldSymbol
@@ -118,9 +117,9 @@ class ImplicitInitializerConversion(context: NewJ2kConverterContext) : Recursive
private fun createPrimitiveTypeInitializer(primitiveType: JKJavaPrimitiveType): JKLiteralExpression =
when (primitiveType) {
JKJavaPrimitiveTypeImpl.BOOLEAN ->
JKBooleanLiteral(false)
JKJavaPrimitiveType.BOOLEAN ->
JKLiteralExpression("false", JKLiteralExpression.LiteralType.STRING)
else ->
JKJavaLiteralExpressionImpl("0", JKLiteralExpression.LiteralType.INT)
JKLiteralExpression("0", JKLiteralExpression.LiteralType.INT)
}
}
@@ -6,11 +6,11 @@
package org.jetbrains.kotlin.nj2k.conversions
import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
import org.jetbrains.kotlin.nj2k.tree.OtherModifier
import org.jetbrains.kotlin.nj2k.isLocalClass
import org.jetbrains.kotlin.nj2k.tree.JKClass
import org.jetbrains.kotlin.nj2k.tree.JKOtherModifierElement
import org.jetbrains.kotlin.nj2k.tree.JKTreeElement
import org.jetbrains.kotlin.nj2k.tree.impl.JKOtherModifierElementImpl
import org.jetbrains.kotlin.nj2k.tree.isLocalClass
import org.jetbrains.kotlin.nj2k.tree.OtherModifier
class InnerClassConversion(context : NewJ2kConverterContext) : RecursiveApplicableConversionBase(context) {
override fun applyToElement(element: JKTreeElement): JKTreeElement {
@@ -34,7 +34,7 @@ class InnerClassConversion(context : NewJ2kConverterContext) : RecursiveApplicab
outer.classKind != JKClass.ClassKind.INTERFACE &&
element.classKind != JKClass.ClassKind.ENUM
) {
element.otherModifierElements += JKOtherModifierElementImpl(OtherModifier.INNER)
element.otherModifierElements += JKOtherModifierElement(OtherModifier.INNER)
}
return recurseArmed(element, element)
}
@@ -6,50 +6,32 @@
package org.jetbrains.kotlin.nj2k.conversions
import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
import org.jetbrains.kotlin.nj2k.declarationList
import org.jetbrains.kotlin.nj2k.symbols.JKClassSymbol
import org.jetbrains.kotlin.nj2k.symbols.JKUniverseClassSymbol
import org.jetbrains.kotlin.nj2k.tree.*
import org.jetbrains.kotlin.nj2k.tree.impl.*
import org.jetbrains.kotlin.nj2k.types.JKClassType
import org.jetbrains.kotlin.nj2k.types.JKNoType
class InsertDefaultPrimaryConstructorConversion(context: NewJ2kConverterContext) : RecursiveApplicableConversionBase(context) {
override fun applyToElement(element: JKTreeElement): JKTreeElement {
if (element !is JKClass) return recurse(element)
if (element.classKind != JKClass.ClassKind.CLASS) return recurse(element)
if (element.declarationList.any { it is JKKtConstructor }) return recurse(element)
if (element.declarationList.any { it is JKConstructor }) return recurse(element)
val constructor = JKKtPrimaryConstructorImpl(
JKNameIdentifierImpl(element.name.value),
val constructor = JKKtPrimaryConstructor(
JKNameIdentifier(element.name.value),
emptyList(),
JKStubExpressionImpl(),
JKAnnotationListImpl(),
JKStubExpression(),
JKAnnotationList(),
emptyList(),
JKVisibilityModifierElementImpl(Visibility.PUBLIC),
JKModalityModifierElementImpl(Modality.FINAL)
JKVisibilityModifierElement(Visibility.PUBLIC),
JKModalityModifierElement(Modality.FINAL)
)
element.classBody.declarations += constructor
val superClassSymbol =
(element.inheritance.extends.singleOrNull() as? JKClassType)?.classReference
if (superClassSymbol is JKUniverseClassSymbol) {
val superClass = recurse(superClassSymbol.target)
val superConstructor = symbolProvider.provideUniverseSymbol(
superClass.declarationList.singleOrNull { it is JKKtConstructor && it.parameters.isEmpty() } as? JKMethod ?: return recurse(
element
)
)
constructor.delegationCall = JKDelegationConstructorCallImpl(superConstructor, JKSuperExpressionImpl(), JKArgumentListImpl())
}
return recurse(element)
}
private val JKClassSymbol.kind
get() = when (this) {
is JKUniverseClassSymbol -> target.classKind
else -> null
}
}
@@ -6,7 +6,9 @@
package org.jetbrains.kotlin.nj2k.conversions
import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
import org.jetbrains.kotlin.nj2k.declarationList
import org.jetbrains.kotlin.nj2k.getOrCreateCompanionObject
import org.jetbrains.kotlin.nj2k.modality
import org.jetbrains.kotlin.nj2k.tree.*
@@ -6,10 +6,8 @@
package org.jetbrains.kotlin.nj2k.conversions
import com.intellij.psi.PsiMember
import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
import org.jetbrains.kotlin.nj2k.*
import org.jetbrains.kotlin.nj2k.tree.*
import org.jetbrains.kotlin.nj2k.tree.impl.psi
import org.jetbrains.kotlin.nj2k.visibility
class InternalDeclarationConversion(context: NewJ2kConverterContext) : RecursiveApplicableConversionBase(context) {
override fun applyToElement(element: JKTreeElement): JKTreeElement {
@@ -6,11 +6,9 @@
package org.jetbrains.kotlin.nj2k.conversions
import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
import org.jetbrains.kotlin.nj2k.copyTreeAndDetach
import org.jetbrains.kotlin.nj2k.tree.*
import org.jetbrains.kotlin.nj2k.tree.impl.JKAnnotationParameterImpl
import org.jetbrains.kotlin.nj2k.tree.impl.JKFieldAccessExpressionImpl
import org.jetbrains.kotlin.nj2k.tree.impl.JKKtLiteralExpressionImpl
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
class JavaAnnotationsConversion(context: NewJ2kConverterContext) : RecursiveApplicableConversionBase(context) {
@@ -32,15 +30,14 @@ class JavaAnnotationsConversion(context: NewJ2kConverterContext) : RecursiveAppl
annotation.classSymbol = symbolProvider.provideClassSymbol("kotlin.Deprecated")
if (annotation.arguments.isEmpty()) {
annotation.arguments +=
JKAnnotationParameterImpl(JKKtLiteralExpressionImpl("\"\"", JKLiteralExpression.LiteralType.STRING))
JKAnnotationParameterImpl(JKLiteralExpression("\"\"", JKLiteralExpression.LiteralType.STRING))
}
}
if (annotation.classSymbol.fqName == "java.lang.annotation.Target") {
annotation.classSymbol = symbolProvider.provideClassSymbol("kotlin.annotation.Target")
val arguments = annotation.arguments.singleOrNull()?.let { parameter ->
val value = parameter.value
when (value) {
when (val value = parameter.value) {
is JKKtAnnotationArrayInitializerExpression -> value.initializers
else -> listOf(value)
}
@@ -51,7 +48,7 @@ class JavaAnnotationsConversion(context: NewJ2kConverterContext) : RecursiveAppl
value.fieldAccessFqName()
?.let { targetMappings[it] }
?.map { fqName ->
JKFieldAccessExpressionImpl(symbolProvider.provideFieldSymbol(fqName))
JKFieldAccessExpression(symbolProvider.provideFieldSymbol(fqName))
} ?: listOf(value.copyTreeAndDetach())
}
annotation.arguments = newArguments.map { JKAnnotationParameterImpl(it) }
@@ -19,39 +19,21 @@ package org.jetbrains.kotlin.nj2k.conversions
import org.jetbrains.kotlin.j2k.ast.Nullability
import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
import org.jetbrains.kotlin.nj2k.throwAnnotation
import org.jetbrains.kotlin.nj2k.tree.*
import org.jetbrains.kotlin.nj2k.tree.impl.JKKtFunctionImpl
import org.jetbrains.kotlin.nj2k.tree.impl.psi
import org.jetbrains.kotlin.nj2k.tree.JKMethodImpl
import org.jetbrains.kotlin.nj2k.tree.JKTreeElement
import org.jetbrains.kotlin.nj2k.types.updateNullabilityRecursively
class JavaMethodToKotlinFunctionConversion(context: NewJ2kConverterContext) : RecursiveApplicableConversionBase(context) {
override fun applyToElement(element: JKTreeElement): JKTreeElement {
if (element !is JKJavaMethod) return recurse(element)
if (element !is JKMethodImpl) return recurse(element)
element.invalidate()
val kotlinFunction = JKKtFunctionImpl(
element.returnType,
element.name,
element.parameters,
element.block,
element.typeParameterList,
element.annotationList.also {
if (element.throwsList.isNotEmpty()) {
it.annotations +=
throwAnnotation(
element.throwsList.map { it.type.updateNullabilityRecursively(Nullability.NotNull) },
symbolProvider
)
}
},
element.otherModifierElements,
element.visibilityElement,
element.modalityElement
).also {
it.psi = element.psi
symbolProvider.transferSymbol(it, element)
it.leftParen.takeNonCodeElementsFrom(element.leftParen)
it.rightParen.takeNonCodeElementsFrom(element.rightParen)
}.withNonCodeElementsFrom(element)
return recurse(kotlinFunction)
if (element.throwsList.isNotEmpty()) {
element.annotationList.annotations +=
throwAnnotation(
element.throwsList.map { it.type.updateNullabilityRecursively(Nullability.NotNull) },
symbolProvider
)
}
return recurse(element)
}
}
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.nj2k.annotationByFqName
import org.jetbrains.kotlin.nj2k.jvmAnnotation
import org.jetbrains.kotlin.nj2k.tree.*
class JavaModifiersConversion(context: NewJ2kConverterContext) : RecursiveApplicableConversionBase(context) {
override fun applyToElement(element: JKTreeElement): JKTreeElement {
if (element is JKModalityOwner && element is JKAnnotationListOwner) {
@@ -9,16 +9,21 @@ import com.intellij.psi.PsiMethod
import org.jetbrains.kotlin.idea.refactoring.fqName.getKotlinFqName
import org.jetbrains.kotlin.j2k.ast.Nullability
import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
import org.jetbrains.kotlin.nj2k.modality
import org.jetbrains.kotlin.nj2k.psi
import org.jetbrains.kotlin.nj2k.symbols.JKUnresolvedClassSymbol
import org.jetbrains.kotlin.nj2k.tree.*
import org.jetbrains.kotlin.nj2k.tree.impl.*
import org.jetbrains.kotlin.nj2k.types.JKClassType
import org.jetbrains.kotlin.nj2k.types.JKClassTypeImpl
import org.jetbrains.kotlin.nj2k.types.JKJavaVoidType
import org.jetbrains.kotlin.nj2k.types.updateNullability
class JavaStandardMethodsConversion(context: NewJ2kConverterContext) : RecursiveApplicableConversionBase(context) {
override fun applyToElement(element: JKTreeElement): JKTreeElement {
if (element !is JKClass) return recurse(element)
for (declaration in element.classBody.declarations) {
if (declaration !is JKJavaMethodImpl) continue
if (declaration !is JKMethodImpl) continue
if (fixToStringMethod(declaration)) continue
if (fixFinalizeMethod(declaration, element)) continue
if (fixCloneMethod(declaration)) {
@@ -30,7 +35,7 @@ class JavaStandardMethodsConversion(context: NewJ2kConverterContext) : Recursive
} == true
if (hasNoCloneableInSuperClasses) {
element.inheritance.implements +=
JKTypeElementImpl(
JKTypeElement(
JKClassTypeImpl(
JKUnresolvedClassSymbol("Cloneable", typeFactory),
emptyList(), Nullability.NotNull
@@ -43,27 +48,27 @@ class JavaStandardMethodsConversion(context: NewJ2kConverterContext) : Recursive
return recurse(element)
}
private fun fixToStringMethod(method: JKJavaMethodImpl): Boolean {
private fun fixToStringMethod(method: JKMethodImpl): Boolean {
if (method.name.value != "toString") return false
if (method.parameters.isNotEmpty()) return false
val type = (method.returnType.type as? JKClassType)
?.takeIf { it.classReference.name == "String" }
?.updateNullability(Nullability.NotNull) ?: return false
method.returnType = JKTypeElementImpl(type)
method.returnType = JKTypeElement(type)
return true
}
private fun fixCloneMethod(method: JKJavaMethodImpl): Boolean {
private fun fixCloneMethod(method: JKMethodImpl): Boolean {
if (method.name.value != "clone") return false
if (method.parameters.isNotEmpty()) return false
val type = (method.returnType.type as? JKClassType)
?.takeIf { it.classReference.name == "Object" }
?.updateNullability(Nullability.NotNull) ?: return false
method.returnType = JKTypeElementImpl(type)
method.returnType = JKTypeElement(type)
return true
}
private fun fixFinalizeMethod(method: JKJavaMethodImpl, containingClass: JKClass): Boolean {
private fun fixFinalizeMethod(method: JKMethodImpl, containingClass: JKClass): Boolean {
if (method.name.value != "finalize") return false
if (method.parameters.isNotEmpty()) return false
if (method.returnType.type != JKJavaVoidType) return false
@@ -10,7 +10,7 @@ import org.jetbrains.kotlin.load.java.NOT_NULL_ANNOTATIONS
import org.jetbrains.kotlin.load.java.NULLABLE_ANNOTATIONS
import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
import org.jetbrains.kotlin.nj2k.tree.*
import org.jetbrains.kotlin.nj2k.tree.impl.JKTypeElementImpl
import org.jetbrains.kotlin.nj2k.types.updateNullability
class JetbrainsNullableAnnotationsConverter(context: NewJ2kConverterContext) : RecursiveApplicableConversionBase(context) {
@@ -23,11 +23,11 @@ class JetbrainsNullableAnnotationsConverter(context: NewJ2kConverterContext) : R
when (element) {
is JKVariable -> {
annotationsToRemove += annotation
element.type = JKTypeElementImpl(element.type.type.updateNullability(nullability))
element.type = JKTypeElement(element.type.type.updateNullability(nullability))
}
is JKMethod -> {
annotationsToRemove += annotation
element.returnType = JKTypeElementImpl(element.returnType.type.updateNullability(nullability))
element.returnType = JKTypeElement(element.returnType.type.updateNullability(nullability))
}
}
}
@@ -8,28 +8,27 @@ package org.jetbrains.kotlin.nj2k.conversions
import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
import org.jetbrains.kotlin.nj2k.asStatement
import org.jetbrains.kotlin.nj2k.tree.*
import org.jetbrains.kotlin.nj2k.tree.impl.JKBlockStatementWithoutBracketsImpl
import org.jetbrains.kotlin.nj2k.tree.impl.JKKtConvertedFromForLoopSyntheticWhileStatementImpl
import org.jetbrains.kotlin.nj2k.tree.impl.JKLabeledStatementImpl
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
class LabeledStatementConversion(context : NewJ2kConverterContext) : RecursiveApplicableConversionBase(context) {
override fun applyToElement(element: JKTreeElement): JKTreeElement {
if (element !is JKExpressionStatement) return recurse(element)
val labeledStatement = element.expression as? JKLabeledStatement ?: return recurse(element)
val labeledStatement = element.expression as? JKLabeledExpression ?: return recurse(element)
val convertedFromForLoopSyntheticWhileStatement = labeledStatement.statement
.safeAs<JKBlockStatement>()
?.block
?.statements
?.singleOrNull()
?.safeAs<JKKtConvertedFromForLoopSyntheticWhileStatementImpl>() ?: return recurse(element)
?.safeAs<JKKtConvertedFromForLoopSyntheticWhileStatement>() ?: return recurse(element)
return recurse(
JKBlockStatementWithoutBracketsImpl(
JKBlockStatementWithoutBrackets(
listOf(
convertedFromForLoopSyntheticWhileStatement::variableDeclaration.detached(),
JKLabeledStatementImpl(
JKLabeledExpression(
convertedFromForLoopSyntheticWhileStatement::whileStatement.detached(),
labeledStatement::labels.detached()
).asStatement()
@@ -5,90 +5,76 @@
package org.jetbrains.kotlin.nj2k.conversions
import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
import org.jetbrains.kotlin.nj2k.tree.*
import org.jetbrains.kotlin.nj2k.tree.impl.JKKtLiteralExpressionImpl
import org.jetbrains.kotlin.nj2k.tree.JKLiteralExpression
import org.jetbrains.kotlin.nj2k.tree.JKTreeElement
import java.math.BigInteger
class LiteralConversion(context : NewJ2kConverterContext) : RecursiveApplicableConversionBase(context) {
class LiteralConversion(context: NewJ2kConverterContext) : RecursiveApplicableConversionBase(context) {
override fun applyToElement(element: JKTreeElement): JKTreeElement {
if (element !is JKJavaLiteralExpression) return recurse(element)
return element.convertLiteral()
if (element !is JKLiteralExpression) return recurse(element)
element.convertLiteral()
return recurse(element)
}
private fun JKLiteralExpression.convertLiteral(): JKLiteralExpression =
when (type) {
private fun JKLiteralExpression.convertLiteral() {
literal = when (type) {
JKLiteralExpression.LiteralType.DOUBLE -> toDoubleLiteral()
JKLiteralExpression.LiteralType.FLOAT -> toFloatLiteral()
JKLiteralExpression.LiteralType.LONG -> toLongLiteral()
JKLiteralExpression.LiteralType.INT -> toIntLiteral()
JKLiteralExpression.LiteralType.CHAR -> convertCharLiteral()
JKLiteralExpression.LiteralType.STRING -> toStringLiteral()
else -> this
}.withNonCodeElementsFrom(this)
else -> return
}
}
private fun JKLiteralExpression.toDoubleLiteral() =
JKKtLiteralExpressionImpl(
literal.cleanFloatAndDoubleLiterals()
.let { text ->
if (!text.contains(".") && !text.contains("e", true))
"$text."
else text
}.let { text ->
if (text.endsWith(".")) "${text}0" else text
},
JKLiteralExpression.LiteralType.DOUBLE
)
literal.cleanFloatAndDoubleLiterals().let { text ->
if (!text.contains(".") && !text.contains("e", true))
"$text."
else text
}.let { text ->
if (text.endsWith(".")) "${text}0" else text
}
private fun JKLiteralExpression.toFloatLiteral() =
JKKtLiteralExpressionImpl(
literal.cleanFloatAndDoubleLiterals()
.let { text ->
if (!text.endsWith("f")) "${text}f"
else text
},
JKLiteralExpression.LiteralType.FLOAT
)
literal.cleanFloatAndDoubleLiterals().let { text ->
if (!text.endsWith("f")) "${text}f"
else text
}
private fun JKLiteralExpression.toStringLiteral() =
JKKtLiteralExpressionImpl(literal.replace("((?:\\\\)*)\\\\([0-3]?[0-7]{1,2})".toRegex()) { matchResult ->
literal.replace("""((?:\\)*)\\([0-3]?[0-7]{1,2})""".toRegex()) { matchResult ->
val leadingBackslashes = matchResult.groupValues[1]
if (leadingBackslashes.length % 2 == 0)
String.format("%s\\u%04x", leadingBackslashes, Integer.parseInt(matchResult.groupValues[2], 8))
else matchResult.value
}.replace("\\$([A-Za-z]+|\\{)".toRegex(), "\\\\$0"), JKLiteralExpression.LiteralType.STRING)
}.replace("""(?<!\\)\$([A-Za-z]+|\{)""".toRegex(), "\\\\$0")
private fun JKLiteralExpression.convertCharLiteral(): JKKtLiteralExpression =
JKKtLiteralExpressionImpl(
literal.replace("\\\\([0-3]?[0-7]{1,2})".toRegex()) {
String.format("\\u%04x", Integer.parseInt(it.groupValues[1], 8))
},
JKLiteralExpression.LiteralType.CHAR
)
private fun JKLiteralExpression.convertCharLiteral() =
literal.replace("""\\([0-3]?[0-7]{1,2})""".toRegex()) {
String.format("\\u%04x", Integer.parseInt(it.groupValues[1], 8))
}
private fun JKLiteralExpression.toIntLiteral(): JKKtLiteralExpression =
JKKtLiteralExpressionImpl(
literal
.cleanIntAndLongLiterals()
.convertHexLiteral(isLongLiteral = false)
.convertBinaryLiteral(isLongLiteral = false)
.convertOctalLiteral(isLongLiteral = false),
JKLiteralExpression.LiteralType.INT
)
private fun JKLiteralExpression.toIntLiteral() =
literal
.cleanIntAndLongLiterals()
.convertHexLiteral(isLongLiteral = false)
.convertBinaryLiteral(isLongLiteral = false)
.convertOctalLiteral(isLongLiteral = false)
private fun JKLiteralExpression.toLongLiteral(): JKKtLiteralExpression =
JKKtLiteralExpressionImpl(
literal
.cleanIntAndLongLiterals()
.convertHexLiteral(isLongLiteral = true)
.convertBinaryLiteral(isLongLiteral = true)
.convertOctalLiteral(isLongLiteral = true) + "L",
JKLiteralExpression.LiteralType.LONG
)
private fun JKLiteralExpression.toLongLiteral() =
literal
.cleanIntAndLongLiterals()
.convertHexLiteral(isLongLiteral = true)
.convertBinaryLiteral(isLongLiteral = true)
.convertOctalLiteral(isLongLiteral = true) + "L"
private fun String.convertHexLiteral(isLongLiteral: Boolean): String {
if (!startsWith("0x", ignoreCase = true)) return this
@@ -8,11 +8,9 @@ package org.jetbrains.kotlin.nj2k.conversions
import org.jetbrains.kotlin.j2k.ast.Nullability
import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
import org.jetbrains.kotlin.nj2k.tree.*
import org.jetbrains.kotlin.nj2k.tree.impl.JKAnnotationImpl
import org.jetbrains.kotlin.nj2k.tree.impl.JKJavaArrayTypeImpl
import org.jetbrains.kotlin.nj2k.tree.impl.JKTypeElementImpl
import org.jetbrains.kotlin.nj2k.types.JKClassType
import org.jetbrains.kotlin.nj2k.types.JKJavaArrayType
import org.jetbrains.kotlin.nj2k.types.updateNullability
//TODO temporary
@@ -24,14 +22,14 @@ class MainFunctionConversion(context: NewJ2kConverterContext) : RecursiveApplica
val oldType = type.type as JKJavaArrayType
val oldTypeParameter = oldType.type as JKClassType
val newType =
JKJavaArrayTypeImpl(
JKJavaArrayType(
oldTypeParameter.updateNullability(Nullability.NotNull),
Nullability.NotNull
)
type = JKTypeElementImpl(newType)
type = JKTypeElement(newType)
}
element.annotationList.annotations +=
JKAnnotationImpl(
JKAnnotation(
symbolProvider.provideClassSymbol("kotlin.jvm.JvmStatic"),
emptyList()
)
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
import org.jetbrains.kotlin.nj2k.SequentialBaseConversion
import org.jetbrains.kotlin.nj2k.tree.JKTreeElement
abstract class MatchBasedConversion(override val context: NewJ2kConverterContext) : SequentialBaseConversion {
fun <R : JKTreeElement, T> applyRecursive(element: R, data: T, func: (JKTreeElement, T) -> JKTreeElement): R =
org.jetbrains.kotlin.nj2k.tree.applyRecursive(element, data, ::onElementChanged, func)
@@ -7,16 +7,14 @@ package org.jetbrains.kotlin.nj2k.conversions
import com.intellij.lang.jvm.JvmModifier
import org.jetbrains.kotlin.codegen.kotlinType
import org.jetbrains.kotlin.codegen.optimization.common.analyze
import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
import org.jetbrains.kotlin.nj2k.nullIfStubExpression
import org.jetbrains.kotlin.nj2k.qualified
import org.jetbrains.kotlin.nj2k.symbols.*
import org.jetbrains.kotlin.nj2k.tree.*
import org.jetbrains.kotlin.nj2k.tree.impl.*
import org.jetbrains.kotlin.nj2k.types.JKClassType
import org.jetbrains.kotlin.nj2k.types.JKTypeParameterType
import org.jetbrains.kotlin.nj2k.types.*
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
@@ -37,11 +35,11 @@ class MethodReferenceToLambdaConversion(context: NewJ2kConverterContext) : Recur
?.safeAs<JKClassAccessExpression>()
?.takeIf { symbol.safeAs<JKMethodSymbol>()?.isStatic == false && !element.isConstructorCall }
?.let { classAccessExpression ->
JKParameterImpl(
JKTypeElementImpl(
JKParameter(
JKTypeElement(
parametersTypesByFunctionalInterface?.firstOrNull() ?: JKClassTypeImpl(classAccessExpression.identifier)
),
JKNameIdentifierImpl(RECEIVER_NAME),
JKNameIdentifier(RECEIVER_NAME),
isVarArgs = false
)
}
@@ -55,9 +53,9 @@ class MethodReferenceToLambdaConversion(context: NewJ2kConverterContext) : Recur
(symbol.parameterNames ?: return recurse(element)).zip(
explicitParameterTypesByFunctionalInterface ?: symbol.parameterTypes ?: return recurse(element)
) { name, type ->
JKParameterImpl(
JKTypeElementImpl(type),
JKNameIdentifierImpl(name),
JKParameter(
JKTypeElement(type),
JKNameIdentifier(name),
isVarArgs = false
)
}
@@ -65,32 +63,32 @@ class MethodReferenceToLambdaConversion(context: NewJ2kConverterContext) : Recur
val arguments = parameters.map { parameter ->
val parameterSymbol = symbolProvider.provideUniverseSymbol(parameter)
JKArgumentImpl(JKFieldAccessExpressionImpl(parameterSymbol))
JKArgumentImpl(JKFieldAccessExpression(parameterSymbol))
}
val callExpression =
when (symbol) {
is JKMethodSymbol ->
JKKtCallExpressionImpl(
JKCallExpressionImpl(
symbol,
JKArgumentListImpl(arguments)
JKArgumentList(arguments)
)
is JKClassSymbol -> JKJavaNewExpressionImpl(symbol, JKArgumentListImpl(), JKTypeArgumentListImpl())
is JKClassSymbol -> JKNewExpression(symbol, JKArgumentList(), JKTypeArgumentList())
is JKUnresolvedSymbol -> return recurse(element)
else -> error("Symbol should be either method symbol or class symbol, but it is ${symbol::class}")
}
val qualifier = when {
receiverParameter != null ->
JKFieldAccessExpressionImpl(symbolProvider.provideUniverseSymbol(receiverParameter))
JKFieldAccessExpression(symbolProvider.provideUniverseSymbol(receiverParameter))
element.isConstructorCall -> element.qualifier.safeAs<JKQualifiedExpression>()?.let { it::receiver.detached() }
else -> element::qualifier.detached().nullIfStubExpression()
}
val lambda = JKLambdaExpressionImpl(
JKExpressionStatementImpl(callExpression.qualified(qualifier)),
val lambda = JKLambdaExpression(
JKExpressionStatement(callExpression.qualified(qualifier)),
listOfNotNull(receiverParameter) + parameters,
element::functionalType.detached(),
JKTypeElementImpl(
JKTypeElement(
when (symbol) {
is JKMethodSymbol -> symbol.returnType ?: JKNoTypeImpl
is JKClassSymbol -> JKClassTypeImpl(symbol)
@@ -8,15 +8,16 @@ package org.jetbrains.kotlin.nj2k.conversions
import com.intellij.psi.PsiClass
import com.intellij.psi.PsiMethod
import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
import org.jetbrains.kotlin.nj2k.modality
import org.jetbrains.kotlin.nj2k.psi
import org.jetbrains.kotlin.nj2k.tree.*
import org.jetbrains.kotlin.nj2k.tree.impl.JKOtherModifierElementImpl
import org.jetbrains.kotlin.nj2k.tree.impl.psi
class ModalityConversion(context: NewJ2kConverterContext) : RecursiveApplicableConversionBase(context) {
override fun applyToElement(element: JKTreeElement): JKTreeElement {
when (element) {
is JKClass -> processClass(element)
is JKJavaMethod -> processMethod(element)
is JKMethod -> processMethod(element)
is JKField -> processField(element)
}
return recurse(element)
@@ -36,7 +37,7 @@ class ModalityConversion(context: NewJ2kConverterContext) : RecursiveApplicableC
}
}
private fun processMethod(method: JKJavaMethod) {
private fun processMethod(method: JKMethod) {
val psi = method.psi<PsiMethod>() ?: return
val containingClass = method.parentOfType<JKClass>() ?: return
when {
@@ -44,7 +45,7 @@ class ModalityConversion(context: NewJ2kConverterContext) : RecursiveApplicableC
&& psi.findSuperMethods().isNotEmpty() -> {
method.modality = Modality.FINAL
if (!method.hasOtherModifier(OtherModifier.OVERRIDE)) {
method.otherModifierElements += JKOtherModifierElementImpl(OtherModifier.OVERRIDE)
method.otherModifierElements += JKOtherModifierElement(OtherModifier.OVERRIDE)
}
}
method.modality == Modality.OPEN
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.nj2k.tree.JKClassBody
import org.jetbrains.kotlin.nj2k.tree.JKKtInitDeclaration
import org.jetbrains.kotlin.nj2k.tree.JKTreeElement
class MoveInitBlocksToTheEndConversion(context : NewJ2kConverterContext) : RecursiveApplicableConversionBase(context) {
override fun applyToElement(element: JKTreeElement): JKTreeElement {
if (element !is JKClassBody) return recurse(element)
@@ -9,7 +9,8 @@ import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
import org.jetbrains.kotlin.nj2k.tree.JKClass
import org.jetbrains.kotlin.nj2k.tree.JKTreeElement
class NonCodeElementsConversion(context : NewJ2kConverterContext) : RecursiveApplicableConversionBase(context) {
class NonCodeElementsConversion(context: NewJ2kConverterContext) : RecursiveApplicableConversionBase(context) {
override fun applyToElement(element: JKTreeElement): JKTreeElement {
when (element) {
is JKClass -> {
@@ -8,7 +8,8 @@ package org.jetbrains.kotlin.nj2k.conversions
import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
import org.jetbrains.kotlin.nj2k.callOn
import org.jetbrains.kotlin.nj2k.tree.*
import org.jetbrains.kotlin.nj2k.tree.impl.JKBinaryExpressionImpl
import org.jetbrains.kotlin.nj2k.types.isStringType
import org.jetbrains.kotlin.nj2k.types.type
class AnyWithStringConcatenationConversion(context: NewJ2kConverterContext) : RecursiveApplicableConversionBase(context) {
@@ -19,7 +20,7 @@ class AnyWithStringConcatenationConversion(context: NewJ2kConverterContext) : Re
&& element.left.type(typeFactory)?.isStringType() == false
) {
return recurse(
JKBinaryExpressionImpl(
JKBinaryExpression(
element::left.detached().callOn(symbolProvider.provideMethodSymbol("kotlin.Any.toString")),
element::right.detached(),
element.operator
@@ -9,9 +9,7 @@ import org.jetbrains.kotlin.j2k.ast.Nullability
import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
import org.jetbrains.kotlin.nj2k.hasWritableUsages
import org.jetbrains.kotlin.nj2k.tree.*
import org.jetbrains.kotlin.nj2k.tree.impl.*
import org.jetbrains.kotlin.nj2k.types.JKJavaPrimitiveType
import org.jetbrains.kotlin.nj2k.types.JKVarianceTypeParameterType
import org.jetbrains.kotlin.nj2k.types.*
class ParameterModificationInMethodCallsConversion(context: NewJ2kConverterContext) : RecursiveApplicableConversionBase(context) {
@@ -26,7 +24,7 @@ class ParameterModificationInMethodCallsConversion(context: NewJ2kConverterConte
symbolProvider.provideClassSymbol(parameter.type.type.arrayFqName()),
if (parameter.type.type is JKJavaPrimitiveType) emptyList()
else listOf(
JKVarianceTypeParameterTypeImpl(
JKVarianceTypeParameterType(
JKVarianceTypeParameterType.Variance.OUT,
parameter.type.type
)
@@ -35,16 +33,16 @@ class ParameterModificationInMethodCallsConversion(context: NewJ2kConverterConte
)
} else parameter.type.type
JKLocalVariableImpl(
JKTypeElementImpl(parameterType),
JKNameIdentifierImpl(parameter.name.value),
JKFieldAccessExpressionImpl(symbolProvider.provideUniverseSymbol(parameter)),
JKMutabilityModifierElementImpl(Mutability.MUTABLE)
JKLocalVariable(
JKTypeElement(parameterType),
JKNameIdentifier(parameter.name.value),
JKFieldAccessExpression(symbolProvider.provideUniverseSymbol(parameter)),
JKMutabilityModifierElement(Mutability.MUTABLE)
)
} else null
}
if (newVariables.isNotEmpty()) {
element.block.statements = listOf(JKDeclarationStatementImpl(newVariables)) + element.block.statements
element.block.statements = listOf(JKDeclarationStatement(newVariables)) + element.block.statements
}
return recurse(element)
}
@@ -6,10 +6,10 @@
package org.jetbrains.kotlin.nj2k.conversions
import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
import org.jetbrains.kotlin.nj2k.declarationList
import org.jetbrains.kotlin.nj2k.replace
import org.jetbrains.kotlin.nj2k.tree.*
import org.jetbrains.kotlin.nj2k.tree.impl.JKKtInitDeclarationImpl
import org.jetbrains.kotlin.nj2k.tree.impl.JKKtPrimaryConstructorImpl
class PrimaryConstructorDetectConversion(context: NewJ2kConverterContext) : RecursiveApplicableConversionBase(context) {
override fun applyToElement(element: JKTreeElement): JKTreeElement {
@@ -22,7 +22,7 @@ class PrimaryConstructorDetectConversion(context: NewJ2kConverterContext) : Recu
}
private fun processClass(element: JKClass) {
val constructors = element.declarationList.filterIsInstance<JKKtConstructor>()
val constructors = element.declarationList.filterIsInstance<JKConstructor>()
if (constructors.any { it is JKKtPrimaryConstructor }) return
val primaryConstructorCandidate = detectPrimaryConstructor(constructors) ?: return
val delegationCall = primaryConstructorCandidate.delegationCall as? JKDelegationConstructorCall
@@ -31,10 +31,10 @@ class PrimaryConstructorDetectConversion(context: NewJ2kConverterContext) : Recu
primaryConstructorCandidate.invalidate()
if (primaryConstructorCandidate.block.statements.isNotEmpty()) {
val initDeclaration = JKKtInitDeclarationImpl(primaryConstructorCandidate.block)
val initDeclaration = JKKtInitDeclaration(primaryConstructorCandidate.block)
.withNonCodeElementsFrom(primaryConstructorCandidate)
primaryConstructorCandidate.clearNonCodeElements()
for (modifierElement in primaryConstructorCandidate.modifierElements()) {
primaryConstructorCandidate.forEachModifier { modifierElement ->
modifierElement.clearNonCodeElements()
}
element.classBody.declarations =
@@ -44,7 +44,7 @@ class PrimaryConstructorDetectConversion(context: NewJ2kConverterContext) : Recu
}
val primaryConstructor =
JKKtPrimaryConstructorImpl(
JKKtPrimaryConstructor(
primaryConstructorCandidate.name,
primaryConstructorCandidate.parameters,
primaryConstructorCandidate.delegationCall,
@@ -59,7 +59,7 @@ class PrimaryConstructorDetectConversion(context: NewJ2kConverterContext) : Recu
element.classBody.declarations += primaryConstructor
}
private fun detectPrimaryConstructor(constructors: List<JKKtConstructor>): JKKtConstructor? {
private fun detectPrimaryConstructor(constructors: List<JKConstructor>): JKConstructor? {
val constructorsWithoutOtherConstructorCall =
constructors.filterNot { (it.delegationCall as? JKDelegationConstructorCall)?.expression is JKThisExpression }
return constructorsWithoutOtherConstructorCall.singleOrNull()
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.nj2k.conversions
import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
import org.jetbrains.kotlin.nj2k.tree.JKTreeElement
abstract class RecursiveApplicableConversionBase(context: NewJ2kConverterContext) : MatchBasedConversion(context) {
override fun onElementChanged(new: JKTreeElement, old: JKTreeElement) {
somethingChanged = true
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.nj2k.conversions
import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
import org.jetbrains.kotlin.nj2k.tree.*
class RemoveWrongExtraModifiersForSingleFunctionsConversion(context : NewJ2kConverterContext) : RecursiveApplicableConversionBase(context) {
override fun applyToElement(element: JKTreeElement): JKTreeElement {
if (element !is JKOtherModifiersOwner) return recurse(element)
@@ -7,11 +7,9 @@ package org.jetbrains.kotlin.nj2k.conversions
import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
import org.jetbrains.kotlin.nj2k.asStatement
import org.jetbrains.kotlin.nj2k.copyTreeAndDetach
import org.jetbrains.kotlin.nj2k.tree.*
import org.jetbrains.kotlin.nj2k.tree.impl.JKLabelTextImpl
import org.jetbrains.kotlin.nj2k.tree.impl.JKLabeledStatementImpl
import org.jetbrains.kotlin.nj2k.tree.impl.JKNameIdentifierImpl
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
class ReturnStatementInLambdaExpressionConversion(context : NewJ2kConverterContext) : RecursiveApplicableConversionBase(context) {
@@ -34,13 +32,13 @@ class ReturnStatementInLambdaExpressionConversion(context : NewJ2kConverterConte
statement.block.statements += last::expression.detached().asStatement()
}
}
val parentMethodName = element.parent?.parent?.parent.safeAs<JKMethodCallExpression>()?.identifier?.name
val parentMethodName = element.parent?.parent?.parent.safeAs<JKCallExpression>()?.identifier?.name
if (parentMethodName == null) {
val atLeastOneReturnStatementExists = applyLabelToAllReturnStatements(statement, element, DEFAULT_LABEL_NAME)
return if (atLeastOneReturnStatementExists) {
JKLabeledStatementImpl(
JKLabeledExpression(
recurse(element.copyTreeAndDetach()).asStatement(),
listOf(JKNameIdentifierImpl(DEFAULT_LABEL_NAME))
listOf(JKNameIdentifier(DEFAULT_LABEL_NAME))
)
} else recurse(element)
}
@@ -58,7 +56,7 @@ class ReturnStatementInLambdaExpressionConversion(context : NewJ2kConverterConte
fun addLabelToReturnStatement(returnStatement: JKReturnStatement) {
if (returnStatement.label is JKLabelEmpty && returnStatement.parentOfType<JKLambdaExpression>() == lambdaExpression) {
atLeastOneReturnStatementExists = true
returnStatement.label = JKLabelTextImpl(JKNameIdentifierImpl(label))
returnStatement.label = JKLabelText(JKNameIdentifier(label))
}
}
@@ -10,7 +10,7 @@ import org.jetbrains.kotlin.nj2k.createCompanion
import org.jetbrains.kotlin.nj2k.getCompanion
import org.jetbrains.kotlin.nj2k.replace
import org.jetbrains.kotlin.nj2k.tree.*
import org.jetbrains.kotlin.nj2k.tree.impl.JKKtInitDeclarationImpl
class StaticInitDeclarationConversion(context : NewJ2kConverterContext) : RecursiveApplicableConversionBase(context) {
override fun applyToElement(element: JKTreeElement): JKTreeElement {
@@ -34,5 +34,5 @@ class StaticInitDeclarationConversion(context : NewJ2kConverterContext) : Recurs
}
private fun JKJavaStaticInitDeclaration.toKtInitDeclaration() =
JKKtInitDeclarationImpl(::block.detached()).withNonCodeElementsFrom(this)
JKKtInitDeclaration(::block.detached()).withNonCodeElementsFrom(this)
}
@@ -5,25 +5,20 @@
package org.jetbrains.kotlin.nj2k.conversions
import com.intellij.lang.jvm.JvmModifier
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiModifierListOwner
import com.intellij.psi.util.parentOfType
import org.jetbrains.kotlin.j2k.getContainingClass
import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
import org.jetbrains.kotlin.nj2k.asQualifierWithThisAsSelector
import org.jetbrains.kotlin.nj2k.copyTreeAndDetach
import org.jetbrains.kotlin.nj2k.symbols.JKClassSymbol
import org.jetbrains.kotlin.nj2k.symbols.JKSymbol
import org.jetbrains.kotlin.nj2k.tree.*
import org.jetbrains.kotlin.nj2k.tree.impl.JKClassAccessExpressionImpl
import org.jetbrains.kotlin.nj2k.tree.impl.JKKtQualifierImpl
import org.jetbrains.kotlin.nj2k.tree.impl.JKQualifiedExpressionImpl
import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtObjectDeclaration
import org.jetbrains.kotlin.psi.psiUtil.containingClass
import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
@@ -33,16 +28,15 @@ class StaticMemberAccessConversion(context: NewJ2kConverterContext) : RecursiveA
val symbol =
when (element) {
is JKFieldAccessExpression -> element.identifier
is JKMethodCallExpression -> element.identifier
is JKCallExpression -> element.identifier
else -> null
} ?: return recurse(element)
if (element.asQualifierWithThisAsSelector() != null) return recurse(element)
if (symbol.isStaticMember()) {
val containingClassSymbol = symbol.containingClassSymbol() ?: return recurse(element)
return recurse(
JKQualifiedExpressionImpl(
JKClassAccessExpressionImpl(containingClassSymbol),
JKKtQualifierImpl.DOT,
JKQualifiedExpression(
JKClassAccessExpression(containingClassSymbol),
element.copyTreeAndDetach() as JKExpression
)
)
@@ -50,18 +44,15 @@ class StaticMemberAccessConversion(context: NewJ2kConverterContext) : RecursiveA
return recurse(element)
}
private fun JKSymbol.isStaticMember(): Boolean {
val target = target
return when (target) {
is PsiModifierListOwner -> target.hasModifier(JvmModifier.STATIC)
is KtElement -> target.getStrictParentOfType<KtClassOrObject>()
?.safeAs<KtObjectDeclaration>()
?.isCompanion() == true
is JKTreeElement ->
target.safeAs<JKOtherModifiersOwner>()?.hasOtherModifier(OtherModifier.STATIC) == true
|| target.parentOfType<JKClass>()?.classKind == JKClass.ClassKind.OBJECT
else -> false
}
private fun JKSymbol.isStaticMember(): Boolean = when (val target = target) {
is PsiModifierListOwner -> target.hasModifier(JvmModifier.STATIC)
is KtElement -> target.getStrictParentOfType<KtClassOrObject>()
?.safeAs<KtObjectDeclaration>()
?.isCompanion() == true
is JKTreeElement ->
target.safeAs<JKOtherModifiersOwner>()?.hasOtherModifier(OtherModifier.STATIC) == true
|| target.parentOfType<JKClass>()?.classKind == JKClass.ClassKind.OBJECT
else -> false
}
private fun JKSymbol.containingClassSymbol(): JKClassSymbol? {
@@ -6,10 +6,12 @@
package org.jetbrains.kotlin.nj2k.conversions
import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
import org.jetbrains.kotlin.nj2k.declarationList
import org.jetbrains.kotlin.nj2k.getOrCreateCompanionObject
import org.jetbrains.kotlin.nj2k.tree.*
class StaticsToCompanionExtractConversion(context : NewJ2kConverterContext) : RecursiveApplicableConversionBase(context) {
class StaticsToCompanionExtractConversion(context: NewJ2kConverterContext) : RecursiveApplicableConversionBase(context) {
override fun applyToElement(element: JKTreeElement): JKTreeElement {
if (element !is JKClass) return recurse(element)
if (element.classKind == JKClass.ClassKind.COMPANION || element.classKind == JKClass.ClassKind.OBJECT) return element
@@ -11,15 +11,14 @@ import com.intellij.psi.controlFlow.ControlFlowUtil
import com.intellij.psi.controlFlow.LocalsOrMyInstanceFieldsControlFlowPolicy
import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
import org.jetbrains.kotlin.nj2k.blockStatement
import org.jetbrains.kotlin.nj2k.copyTreeAndDetach
import org.jetbrains.kotlin.nj2k.runExpression
import org.jetbrains.kotlin.nj2k.tree.*
import org.jetbrains.kotlin.nj2k.tree.impl.*
class SwitchStatementConversion(context: NewJ2kConverterContext) : RecursiveApplicableConversionBase(context) {
override fun applyToElement(element: JKTreeElement): JKTreeElement {
if (element !is JKJavaSwitchStatementImpl) return recurse(element)
if (element !is JKJavaSwitchStatement) return recurse(element)
element.invalidate()
element.cases.forEach { case ->
case.statements.forEach { it.detach(case) }
@@ -28,7 +27,7 @@ class SwitchStatementConversion(context: NewJ2kConverterContext) : RecursiveAppl
}
}
val cases = switchCasesToWhenCases(element.cases).moveElseCaseToTheEnd()
val whenStatement = JKKtWhenStatementImpl(element.expression, cases)
val whenStatement = JKKtWhenStatement(element.expression, cases)
return recurse(whenStatement)
}
@@ -60,16 +59,16 @@ class SwitchStatementConversion(context: NewJ2kConverterContext) : RecursiveAppl
val statementLabels = javaLabels
.filterIsInstance<JKJavaLabelSwitchCase>()
.map { JKKtValueWhenLabelImpl(it.label) }
.map { JKKtValueWhenLabel(it.label) }
val elseLabel = javaLabels
.find { it is JKJavaDefaultSwitchCaseImpl }
?.let { JKKtElseWhenLabelImpl() }
.find { it is JKJavaDefaultSwitchCase }
?.let { JKKtElseWhenLabel() }
val elseWhenCase = elseLabel?.let { label ->
JKKtWhenCaseImpl(listOf(label), statements.map { it.copyTreeAndDetach() }.singleBlockOrWrapToRun())
JKKtWhenCase(listOf(label), statements.map { it.copyTreeAndDetach() }.singleBlockOrWrapToRun())
}
val mainWhenCase =
if (statementLabels.isNotEmpty()) {
JKKtWhenCaseImpl(statementLabels, statements.singleBlockOrWrapToRun())
JKKtWhenCase(statementLabels, statements.singleBlockOrWrapToRun())
} else null
listOfNotNull(mainWhenCase) +
listOfNotNull(elseWhenCase) +
@@ -81,11 +80,11 @@ class SwitchStatementConversion(context: NewJ2kConverterContext) : RecursiveAppl
private fun List<JKStatement>.singleBlockOrWrapToRun(): JKStatement =
singleOrNull()
?: JKBlockStatementImpl(
?: JKBlockStatement(
JKBlockImpl(map { statement ->
when (statement) {
is JKBlockStatement ->
JKExpressionStatementImpl(
JKExpressionStatement(
runExpression(statement, symbolProvider)
)
else -> statement
@@ -101,7 +100,7 @@ class SwitchStatementConversion(context: NewJ2kConverterContext) : RecursiveAppl
}
private fun isSwitchBreak(statement: JKStatement) =
statement is JKBreakStatement && statement !is JKBreakWithLabelStatement
statement is JKBreakStatement && statement.label is JKLabelEmpty
private fun List<JKStatement>.fallsThrough(): Boolean =
all { it.fallsThrough() }
@@ -113,7 +112,7 @@ class SwitchStatementConversion(context: NewJ2kConverterContext) : RecursiveAppl
this is JKReturnStatement ||
this is JKContinueStatement -> false
this is JKBlockStatement -> block.statements.fallsThrough()
this is JKIfStatement ||
this is JKIfElseStatement ||
this is JKJavaSwitchStatement ||
this is JKKtWhenStatement ->
this.psi!!.canCompleteNormally()
@@ -6,29 +6,26 @@
package org.jetbrains.kotlin.nj2k.conversions
import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
import org.jetbrains.kotlin.nj2k.tree.JKJavaSynchronizedStatement
import org.jetbrains.kotlin.nj2k.tree.JKTreeElement
import org.jetbrains.kotlin.nj2k.tree.impl.*
import org.jetbrains.kotlin.nj2k.tree.withNonCodeElementsFrom
import org.jetbrains.kotlin.nj2k.tree.*
class SynchronizedStatementConversion(context: NewJ2kConverterContext) : RecursiveApplicableConversionBase(context) {
override fun applyToElement(element: JKTreeElement): JKTreeElement {
if (element !is JKJavaSynchronizedStatement) return recurse(element)
element.invalidate()
val lambdaBody = JKLambdaExpressionImpl(
JKBlockStatementImpl(element.body),
val lambdaBody = JKLambdaExpression(
JKBlockStatement(element.body),
emptyList()
)
val synchronizedCall =
JKKtCallExpressionImpl(
JKCallExpressionImpl(
symbolProvider.provideMethodSymbol("kotlin.synchronized"),
JKArgumentListImpl(
JKArgumentList(
element.lockExpression,
lambdaBody
)
).withNonCodeElementsFrom(element)
return recurse(JKExpressionStatementImpl(synchronizedCall))
return recurse(JKExpressionStatement(synchronizedCall))
}
}
@@ -6,17 +6,12 @@
package org.jetbrains.kotlin.nj2k.conversions
import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
import org.jetbrains.kotlin.nj2k.tree.JKJavaThrowStatement
import org.jetbrains.kotlin.nj2k.tree.JKTreeElement
import org.jetbrains.kotlin.nj2k.tree.detached
import org.jetbrains.kotlin.nj2k.tree.impl.JKExpressionStatementImpl
import org.jetbrains.kotlin.nj2k.tree.impl.JKKtThrowExpressionImpl
import org.jetbrains.kotlin.nj2k.tree.*
class ThrowStatementConversion(context : NewJ2kConverterContext) : RecursiveApplicableConversionBase(context) {
class ThrowStatementConversion(context: NewJ2kConverterContext) : RecursiveApplicableConversionBase(context) {
override fun applyToElement(element: JKTreeElement): JKTreeElement {
if (element !is JKJavaThrowStatement) return recurse(element)
val throwExpression = JKKtThrowExpressionImpl(element::exception.detached())
return recurse(JKExpressionStatementImpl(throwExpression))
val throwExpression = JKKtThrowExpression(element::exception.detached())
return recurse(JKExpressionStatement(throwExpression))
}
}
@@ -7,10 +7,10 @@ package org.jetbrains.kotlin.nj2k.conversions
import org.jetbrains.kotlin.j2k.ast.Nullability
import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
import org.jetbrains.kotlin.nj2k.copyTreeAndDetach
import org.jetbrains.kotlin.nj2k.tree.*
import org.jetbrains.kotlin.nj2k.tree.impl.*
import org.jetbrains.kotlin.nj2k.types.JKJavaDisjunctionType
import org.jetbrains.kotlin.nj2k.types.updateNullability
import org.jetbrains.kotlin.nj2k.useExpression
@@ -23,8 +23,8 @@ class TryStatementConversion(context: NewJ2kConverterContext) : RecursiveApplica
}
private fun convertNoResourcesTryStatement(tryStatement: JKJavaTryStatement): JKStatement =
JKExpressionStatementImpl(
JKKtTryExpressionImpl(
JKExpressionStatement(
JKKtTryExpression(
tryStatement::tryBlock.detached(),
tryStatement::finallyBlock.detached(),
tryStatement.catchSections.flatMap(::convertCatchSection)
@@ -35,11 +35,11 @@ class TryStatementConversion(context: NewJ2kConverterContext) : RecursiveApplica
val body =
resourceDeclarationsToUseExpression(
tryStatement.resourceDeclarations,
JKBlockStatementImpl(tryStatement::tryBlock.detached())
JKBlockStatement(tryStatement::tryBlock.detached())
)
return if (tryStatement.finallyBlock !is JKBodyStub || tryStatement.catchSections.isNotEmpty()) {
JKExpressionStatementImpl(
JKKtTryExpressionImpl(
JKExpressionStatement(
JKKtTryExpression(
JKBlockImpl(listOf(body)),
tryStatement::finallyBlock.detached(),
tryStatement.catchSections.flatMap(::convertCatchSection)
@@ -55,7 +55,7 @@ class TryStatementConversion(context: NewJ2kConverterContext) : RecursiveApplica
resourceDeclarations
.reversed()
.fold(innerStatement) { inner, variable ->
JKExpressionStatementImpl(
JKExpressionStatement(
useExpression(
receiver = (variable as JKLocalVariable)::initializer.detached(),
variableIdentifier = variable::name.detached(),
@@ -70,11 +70,11 @@ class TryStatementConversion(context: NewJ2kConverterContext) : RecursiveApplica
return javaCatchSection.parameter.type.type.let {
(it as? JKJavaDisjunctionType)?.disjunctions ?: listOf(it)
}.map {
val parameter = JKParameterImpl(
JKTypeElementImpl(it.updateNullability(Nullability.NotNull)),
val parameter = JKParameter(
JKTypeElement(it.updateNullability(Nullability.NotNull)),
javaCatchSection.parameter.name.copyTreeAndDetach()
)
JKKtTryCatchSectionImpl(
JKKtTryCatchSection(
parameter,
javaCatchSection.block.copyTreeAndDetach()
).withNonCodeElementsFrom(javaCatchSection)
@@ -14,7 +14,6 @@ import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
import org.jetbrains.kotlin.nj2k.symbols.JKClassSymbol
import org.jetbrains.kotlin.nj2k.symbols.JKUniverseClassSymbol
import org.jetbrains.kotlin.nj2k.tree.*
import org.jetbrains.kotlin.nj2k.tree.impl.*
import org.jetbrains.kotlin.nj2k.types.*
import org.jetbrains.kotlin.psi.KtClass
@@ -24,14 +23,15 @@ class TypeMappingConversion(context: NewJ2kConverterContext) : RecursiveApplicab
is JKTypeElement -> {
element.type = element.type.mapType(element)
}
is JKJavaNewExpression -> {
is JKNewExpression -> {
val newClassSymbol = element.classSymbol.mapClassSymbol()
return recurse(
JKJavaNewExpressionImpl(
JKNewExpression(
newClassSymbol,
element::arguments.detached(),
element::typeArgumentList.detached().fixTypeArguments(newClassSymbol),
element::classBody.detached()
element::classBody.detached(),
element.isAnonymousClass
).withNonCodeElementsFrom(element)
)
}
@@ -41,16 +41,16 @@ class TypeMappingConversion(context: NewJ2kConverterContext) : RecursiveApplicab
private fun JKTypeArgumentList.fixTypeArguments(classSymbol: JKClassSymbol): JKTypeArgumentList {
if (typeArguments.isNotEmpty()) {
return JKTypeArgumentListImpl(
return JKTypeArgumentList(
typeArguments.map { typeArgument ->
JKTypeElementImpl(typeArgument.type.mapType(null))
JKTypeElement(typeArgument.type.mapType(null))
}
)
}
return when (val typeParametersCount = classSymbol.expectedTypeParametersCount()) {
0 -> this
else -> JKTypeArgumentListImpl(List(typeParametersCount) {
JKTypeElementImpl(typeFactory.types.nullableAny)
else -> JKTypeArgumentList(List(typeParametersCount) {
JKTypeElement(typeFactory.types.nullableAny)
})
}
}
@@ -58,7 +58,7 @@ class TypeMappingConversion(context: NewJ2kConverterContext) : RecursiveApplicab
private fun JKType.fixRawType(typeElement: JKTypeElement?) =
when (typeElement?.parent) {
is JKClassLiteralExpression -> this
is JKKtIsExpression ->
is JKIsExpression ->
addTypeParametersToRawProjectionType(JKStarProjectionTypeImpl)
.updateNullability(Nullability.NotNull)
is JKTypeCastExpression ->
@@ -80,7 +80,7 @@ class TypeMappingConversion(context: NewJ2kConverterContext) : RecursiveApplicab
nullability
)
is JKVarianceTypeParameterType ->
JKVarianceTypeParameterTypeImpl(
JKVarianceTypeParameterType(
variance,
boundType.mapType(null)
)
+108 -88
View File
@@ -5,20 +5,23 @@
package org.jetbrains.kotlin.nj2k
import com.intellij.psi.PsiElement
import com.intellij.psi.tree.TokenSet
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.nj2k.conversions.RecursiveApplicableConversionBase
import org.jetbrains.kotlin.nj2k.symbols.JKMethodSymbol
import org.jetbrains.kotlin.nj2k.symbols.JKUnresolvedMethod
import org.jetbrains.kotlin.nj2k.tree.*
import org.jetbrains.kotlin.nj2k.tree.impl.*
import org.jetbrains.kotlin.nj2k.types.JKNoType
import org.jetbrains.kotlin.nj2k.types.JKType
import org.jetbrains.kotlin.nj2k.types.JKTypeFactory
import org.jetbrains.kotlin.nj2k.types.replaceJavaClassWithKotlinClassType
import org.jetbrains.kotlin.utils.addToStdlib.cast
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
fun JKOperator.isEquals() =
(token as? JKKtSingleValueOperatorToken)?.psiToken in equalsOperators
token.safeAs<JKKtSingleValueOperatorToken>()?.psiToken in equalsOperators
private val equalsOperators =
TokenSet.create(
@@ -52,13 +55,12 @@ fun downToExpression(
conversionContext
)
fun JKExpression.parenthesizeIfBinaryExpression() =
when (this) {
is JKBinaryExpression -> JKParenthesizedExpressionImpl(this)
else -> this
}
fun JKExpression.parenthesizeIfBinaryExpression() = when (this) {
is JKBinaryExpression -> JKParenthesizedExpression(this)
else -> this
}
fun JKExpression.parenthesize() = JKParenthesizedExpressionImpl(this)
fun JKExpression.parenthesize() = JKParenthesizedExpression(this)
fun rangeExpression(
from: JKExpression,
@@ -66,7 +68,7 @@ fun rangeExpression(
operatorName: String,
conversionContext: NewJ2kConverterContext
): JKExpression =
JKBinaryExpressionImpl(
JKBinaryExpression(
from,
to,
JKKtOperatorImpl(
@@ -77,10 +79,10 @@ fun rangeExpression(
fun blockStatement(vararg statements: JKStatement) =
JKBlockStatementImpl(JKBlockImpl(statements.toList()))
JKBlockStatement(JKBlockImpl(statements.toList()))
fun blockStatement(statements: List<JKStatement>) =
JKBlockStatementImpl(JKBlockImpl(statements))
JKBlockStatement(JKBlockImpl(statements))
fun useExpression(
receiver: JKExpression,
@@ -90,41 +92,41 @@ fun useExpression(
): JKExpression {
val useSymbol = symbolProvider.provideMethodSymbol("kotlin.io.use")
val lambdaParameter =
JKParameterImpl(JKTypeElementImpl(JKNoTypeImpl), variableIdentifier)
JKParameter(JKTypeElement(JKNoType), variableIdentifier)
val lambda = JKLambdaExpressionImpl(
val lambda = JKLambdaExpression(
body,
listOf(lambdaParameter)
)
val methodCall =
JKJavaMethodCallExpressionImpl(
JKCallExpressionImpl(
useSymbol,
listOf(lambda).toArgumentList()
)
return JKQualifiedExpressionImpl(receiver, JKKtQualifierImpl.DOT, methodCall)
return JKQualifiedExpression(receiver, methodCall)
}
fun kotlinAssert(assertion: JKExpression, message: JKExpression?, typeFactory: JKTypeFactory) =
JKKtCallExpressionImpl(
JKCallExpressionImpl(
JKUnresolvedMethod(//TODO resolve assert
"assert",
typeFactory,
typeFactory.types.unit
),
(listOfNotNull(assertion, message)).toArgumentList()
listOfNotNull(assertion, message).toArgumentList()
)
fun jvmAnnotation(name: String, symbolProvider: JKSymbolProvider) =
JKAnnotationImpl(
JKAnnotation(
symbolProvider.provideClassSymbol("kotlin.jvm.$name")
)
fun throwAnnotation(throws: List<JKType>, symbolProvider: JKSymbolProvider) =
JKAnnotationImpl(
JKAnnotation(
symbolProvider.provideClassSymbol("kotlin.jvm.Throws"),
throws.map {
JKAnnotationParameterImpl(
JKClassLiteralExpressionImpl(JKTypeElementImpl(it), JKClassLiteralExpression.LiteralType.KOTLIN_CLASS)
JKClassLiteralExpression(JKTypeElement(it), JKClassLiteralExpression.ClassLiteralType.KOTLIN_CLASS)
)
}
)
@@ -136,9 +138,9 @@ fun stringLiteral(content: String, typeFactory: JKTypeFactory): JKExpression {
val lines = content.split('\n')
return lines.mapIndexed { i, line ->
val newlineSeparator = if (i == lines.size - 1) "" else "\\n"
JKKtLiteralExpressionImpl("\"$line$newlineSeparator\"", JKLiteralExpression.LiteralType.STRING)
}.reduce { acc: JKExpression, literalExpression: JKKtLiteralExpression ->
JKBinaryExpressionImpl(acc, literalExpression, JKKtOperatorImpl(JKOperatorToken.PLUS, typeFactory.types.string))
JKLiteralExpression("\"$line$newlineSeparator\"", JKLiteralExpression.LiteralType.STRING)
}.reduce { acc: JKExpression, literalExpression: JKLiteralExpression ->
JKBinaryExpression(acc, literalExpression, JKKtOperatorImpl(JKOperatorToken.PLUS, typeFactory.types.string))
}
}
@@ -168,11 +170,13 @@ fun JKExpression.unboxFieldReference(): JKFieldAccessExpression? = when {
}
fun JKFieldAccessExpression.asAssignmentFromTarget(): JKKtAssignmentStatement? =
(parent as? JKKtAssignmentStatement)
?.takeIf { it.field == this }
parent.safeAs<JKKtAssignmentStatement>()?.takeIf { it.field == this }
fun JKFieldAccessExpression.isInDecrementOrIncrement(): Boolean =
(parent as? JKUnaryExpression)?.operator?.token?.text in listOf("++", "--")
when (parent.safeAs<JKUnaryExpression>()?.operator?.token) {
JKOperatorToken.PLUSPLUS, JKOperatorToken.MINUSMINUS -> true
else -> false
}
fun JKVariable.hasWritableUsages(scope: JKTreeElement, context: NewJ2kConverterContext): Boolean =
findUsages(scope, context).any {
@@ -181,7 +185,7 @@ fun JKVariable.hasWritableUsages(scope: JKTreeElement, context: NewJ2kConverterC
}
fun equalsExpression(left: JKExpression, right: JKExpression, typeFactory: JKTypeFactory) =
JKBinaryExpressionImpl(
JKBinaryExpression(
left,
right,
JKKtOperatorImpl(
@@ -191,16 +195,16 @@ fun equalsExpression(left: JKExpression, right: JKExpression, typeFactory: JKTyp
)
fun createCompanion(declarations: List<JKDeclaration>): JKClass =
JKClassImpl(
JKNameIdentifierImpl(""),
JKInheritanceInfoImpl(emptyList(), emptyList()),
JKClass(
JKNameIdentifier(""),
JKInheritanceInfo(emptyList(), emptyList()),
JKClass.ClassKind.COMPANION,
JKTypeParameterListImpl(),
JKClassBodyImpl(declarations),
JKAnnotationListImpl(),
JKTypeParameterList(),
JKClassBody(declarations),
JKAnnotationList(),
emptyList(),
JKVisibilityModifierElementImpl(Visibility.PUBLIC),
JKModalityModifierElementImpl(Modality.FINAL)
JKVisibilityModifierElement(Visibility.PUBLIC),
JKModalityModifierElement(Modality.FINAL)
)
fun JKClass.getCompanion(): JKClass? =
@@ -208,26 +212,17 @@ fun JKClass.getCompanion(): JKClass? =
fun JKClass.getOrCreateCompanionObject(): JKClass =
getCompanion()
?: JKClassImpl(
JKNameIdentifierImpl(""),
JKInheritanceInfoImpl(emptyList(), emptyList()),
JKClass.ClassKind.COMPANION,
JKTypeParameterListImpl(),
JKClassBodyImpl(),
JKAnnotationListImpl(),
emptyList(),
JKVisibilityModifierElementImpl(Visibility.PUBLIC),
JKModalityModifierElementImpl(Modality.FINAL)
).also { classBody.declarations += it }
?: createCompanion(declarations = emptyList())
.also { classBody.declarations += it }
fun runExpression(body: JKStatement, symbolProvider: JKSymbolProvider): JKExpression {
val lambda = JKLambdaExpressionImpl(
val lambda = JKLambdaExpression(
body,
emptyList()
)
return JKKtCallExpressionImpl(
return JKCallExpressionImpl(
symbolProvider.provideMethodSymbol("kotlin.run"),
(listOf(lambda)).toArgumentList()
listOf(lambda).toArgumentList()
)
}
@@ -240,59 +235,57 @@ fun JKAnnotationMemberValue.toExpression(symbolProvider: JKSymbolProvider): JKEx
when (element) {
is JKClassLiteralExpression ->
element.also {
element.literalType = JKClassLiteralExpression.LiteralType.KOTLIN_CLASS
element.literalType = JKClassLiteralExpression.ClassLiteralType.KOTLIN_CLASS
}
is JKTypeElement ->
JKTypeElementImpl(element.type.replaceJavaClassWithKotlinClassType(symbolProvider))
JKTypeElement(element.type.replaceJavaClassWithKotlinClassType(symbolProvider))
else -> applyRecursive(element, ::handleAnnotationParameter)
}
return handleAnnotationParameter(
when {
this is JKStubExpression -> this
this is JKAnnotation ->
JKJavaNewExpressionImpl(
classSymbol,
JKArgumentListImpl(
arguments.map { argument ->
val value = argument.value.copyTreeAndDetach().toExpression(symbolProvider)
when (argument) {
is JKAnnotationNameParameter ->
JKNamedArgumentImpl(value, JKNameIdentifierImpl(argument.name.value))
else -> JKArgumentImpl(value)
}
when (this) {
is JKStubExpression -> this
is JKAnnotation -> JKNewExpression(
classSymbol,
JKArgumentList(
arguments.map { argument ->
val value = argument.value.copyTreeAndDetach().toExpression(symbolProvider)
when (argument) {
is JKAnnotationNameParameter ->
JKNamedArgument(value, JKNameIdentifier(argument.name.value))
else -> JKArgumentImpl(value)
}
),
JKTypeArgumentListImpl()
)
this is JKKtAnnotationArrayInitializerExpression ->
JKKtAnnotationArrayInitializerExpressionImpl(initializers.map { it.detached(this).toExpression(symbolProvider) })
this is JKExpression -> this
}
),
JKTypeArgumentList()
)
is JKKtAnnotationArrayInitializerExpression ->
JKKtAnnotationArrayInitializerExpression(initializers.map { it.detached(this).toExpression(symbolProvider) })
is JKExpression -> this
else -> error("Bad initializer")
}
) as JKExpression
}
fun JKExpression.asLiteralTextWithPrefix(): String? =
when {
this is JKPrefixExpression
&& (operator.token.text == "+" || operator.token.text == "-")
&& expression is JKLiteralExpression
-> operator.token.text + expression.cast<JKLiteralExpression>().literal
this is JKLiteralExpression -> literal
else -> null
}
fun JKExpression.asLiteralTextWithPrefix(): String? = when {
this is JKPrefixExpression
&& (operator.token == JKOperatorToken.MINUS || operator.token == JKOperatorToken.PLUS)
&& expression is JKLiteralExpression
-> operator.token.text + expression.cast<JKLiteralExpression>().literal
this is JKLiteralExpression -> literal
else -> null
}
fun JKClass.primaryConstructor(): JKKtPrimaryConstructor? = classBody.declarations.firstIsInstanceOrNull()
fun List<JKExpression>.toArgumentList(): JKArgumentList =
JKArgumentListImpl(map { JKArgumentImpl(it) })
JKArgumentList(map { JKArgumentImpl(it) })
fun JKExpression.asStatement(): JKExpressionStatement =
JKExpressionStatementImpl(this)
JKExpressionStatement(this)
fun <T : JKExpression> T.nullIfStubExpression(): T? =
if (this is JKStubExpression) null
@@ -300,20 +293,47 @@ fun <T : JKExpression> T.nullIfStubExpression(): T? =
fun JKExpression.qualified(qualifier: JKExpression?) =
if (qualifier != null && qualifier !is JKStubExpression) {
JKQualifiedExpressionImpl(qualifier, JKJavaQualifierImpl.DOT, this)
JKQualifiedExpression(qualifier, this)
} else this
fun JKExpression.callOn(
symbol: JKMethodSymbol,
arguments: List<JKExpression> = emptyList(),
typeArguments: List<JKTypeElement> = emptyList()
) = JKQualifiedExpressionImpl(
) = JKQualifiedExpression(
this,
JKKtQualifierImpl.DOT,
JKKtCallExpressionImpl(
JKCallExpressionImpl(
symbol,
JKArgumentListImpl(arguments.map { JKArgumentImpl(it) }),
JKTypeArgumentListImpl(typeArguments)
JKArgumentList(arguments.map { JKArgumentImpl(it) }),
JKTypeArgumentList(typeArguments)
)
)
val JKStatement.statements: List<JKStatement>
get() = when (this) {
is JKBlockStatement -> block.statements
else -> listOf(this)
}
val JKElement.psi: PsiElement?
get() = (this as? PsiOwner)?.psi
inline fun <reified Elem : PsiElement> JKElement.psi(): Elem? = (this as? PsiOwner)?.psi as? Elem
fun JKTypeElement.present(): Boolean = type != JKNoType
fun JKStatement.isEmpty(): Boolean = when (this) {
is JKEmptyStatement -> true
is JKBlockStatement -> block is JKBodyStub
is JKExpressionStatement -> expression is JKStubExpression
else -> false
}
fun JKInheritanceInfo.present(): Boolean =
extends.isNotEmpty() || implements.isNotEmpty()
fun JKClass.isLocalClass(): Boolean =
parent !is JKClassBody && parent !is JKFile
val JKClass.declarationList: List<JKDeclaration>
get() = classBody.declarations
@@ -14,8 +14,8 @@ import com.intellij.psi.util.PsiUtil
import org.jetbrains.kotlin.j2k.ReferenceSearcher
import org.jetbrains.kotlin.j2k.isNullLiteral
import org.jetbrains.kotlin.nj2k.tree.*
import org.jetbrains.kotlin.nj2k.tree.impl.JKModalityModifierElementImpl
import org.jetbrains.kotlin.nj2k.tree.impl.JKVisibilityModifierElementImpl
import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf
//copied from old j2k
@@ -57,11 +57,11 @@ internal fun PsiMember.visibility(
else -> null
}?.let {
JKVisibilityModifierElementImpl(it)
JKVisibilityModifierElement(it)
}?.also { modifier ->
assignNonCodeElements?.also { it(modifier, child) }
}
}?.firstOrNull() ?: JKVisibilityModifierElementImpl(Visibility.INTERNAL)
}?.firstOrNull() ?: JKVisibilityModifierElement(Visibility.INTERNAL)
fun PsiMember.modality(assignNonCodeElements: ((JKNonCodeElementsListOwner, PsiElement) -> Unit)?) =
@@ -73,11 +73,11 @@ fun PsiMember.modality(assignNonCodeElements: ((JKNonCodeElementsListOwner, PsiE
else -> null
}?.let {
JKModalityModifierElementImpl(it)
JKModalityModifierElement(it)
}?.also { modifier ->
assignNonCodeElements?.let { it(modifier, child) }
}
}?.firstOrNull() ?: JKModalityModifierElementImpl(Modality.OPEN)
}?.firstOrNull() ?: JKModalityModifierElement(Modality.OPEN)
private fun PsiMember.handleProtectedVisibility(referenceSearcher: ReferenceSearcher): Visibility {
@@ -9,11 +9,10 @@ package org.jetbrains.kotlin.nj2k.symbols
import com.intellij.psi.PsiVariable
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.j2k.ast.Nullability
import org.jetbrains.kotlin.nj2k.JKSymbolProvider
import org.jetbrains.kotlin.nj2k.tree.JKType
import org.jetbrains.kotlin.nj2k.tree.JKVariable
import org.jetbrains.kotlin.nj2k.tree.impl.JKClassTypeImpl
import org.jetbrains.kotlin.nj2k.tree.toJK
import org.jetbrains.kotlin.nj2k.types.toJK
import org.jetbrains.kotlin.nj2k.types.JKClassTypeImpl
import org.jetbrains.kotlin.nj2k.types.JKType
import org.jetbrains.kotlin.nj2k.types.JKTypeFactory
import org.jetbrains.kotlin.psi.KtCallableDeclaration
import org.jetbrains.kotlin.psi.KtEnumEntry
@@ -5,16 +5,20 @@
package org.jetbrains.kotlin.nj2k.symbols
import com.intellij.psi.PsiMethod
import com.intellij.psi.PsiReference
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.idea.refactoring.fqName.getKotlinFqName
import org.jetbrains.kotlin.j2k.ast.Nullability
import org.jetbrains.kotlin.nj2k.JKSymbolProvider
import org.jetbrains.kotlin.nj2k.tree.*
import org.jetbrains.kotlin.nj2k.tree.impl.JKClassTypeImpl
import org.jetbrains.kotlin.nj2k.tree.impl.JKNoTypeImpl
import org.jetbrains.kotlin.nj2k.tree.JKClass
import org.jetbrains.kotlin.nj2k.tree.JKMethod
import org.jetbrains.kotlin.nj2k.types.asType
import org.jetbrains.kotlin.nj2k.types.toJK
import org.jetbrains.kotlin.nj2k.types.JKClassTypeImpl
import org.jetbrains.kotlin.nj2k.types.JKNoTypeImpl
import org.jetbrains.kotlin.nj2k.types.JKType
import org.jetbrains.kotlin.nj2k.types.JKTypeFactory
import org.jetbrains.kotlin.psi.KtFunction
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
@@ -10,8 +10,11 @@ import com.intellij.psi.PsiMethod
import com.intellij.psi.PsiModifier
import org.jetbrains.kotlin.idea.refactoring.fqName.getKotlinFqName
import org.jetbrains.kotlin.idea.search.declarationsSearch.findDeepestSuperMethodsNoWrapping
import org.jetbrains.kotlin.nj2k.psi
import org.jetbrains.kotlin.nj2k.tree.*
import org.jetbrains.kotlin.nj2k.tree.impl.psi
import org.jetbrains.kotlin.nj2k.types.JKType
import org.jetbrains.kotlin.nj2k.types.arrayInnerType
import org.jetbrains.kotlin.psi.KtNamedFunction
import org.jetbrains.kotlin.psi.KtObjectDeclaration
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
@@ -27,11 +30,10 @@ fun JKSymbol.getDisplayName(): String {
}.fold(name) { acc, symbol -> "${symbol.name}.$acc" }
}
fun JKSymbol.fqNameToImport(): String? =
when {
this is JKClassSymbol && this !is JKUniverseClassSymbol -> fqName
else -> null
}
fun JKSymbol.fqNameToImport(): String? = when {
this is JKClassSymbol && this !is JKUniverseClassSymbol -> fqName
else -> null
}
fun JKSymbol.deepestFqName(): String? {
fun Any.deepestFqNameForTarget(): String? =
@@ -43,32 +45,3 @@ fun JKSymbol.deepestFqName(): String? {
}
return target.deepestFqNameForTarget() ?: fqName
}
val JKMethodSymbol.parameterNames: List<String>?
get() {
return when (this) {
is JKMultiverseFunctionSymbol -> target.valueParameters.map { it.name ?: return null }
is JKMultiverseMethodSymbol -> target.parameters.map { it.name ?: return null }
is JKUniverseMethodSymbol -> target.parameters.map { it.name.value }
is JKUnresolvedMethod -> null
}
}
val JKMethodSymbol.isStatic: Boolean
get() = when (this) {
is JKMultiverseFunctionSymbol -> target.parent is KtObjectDeclaration
is JKMultiverseMethodSymbol -> target.hasModifierProperty(PsiModifier.STATIC)
is JKUniverseMethodSymbol -> target.parent?.parent?.safeAs<JKClass>()?.classKind == JKClass.ClassKind.COMPANION
is JKUnresolvedMethod -> false
}
fun JKMethodSymbol.parameterTypesWithUnfoldedVarargs(): Sequence<JKType>? {
val realParameterTypes = parameterTypes ?: return null
if (realParameterTypes.isEmpty()) return emptySequence()
val lastArrayType = realParameterTypes.last().arrayInnerType() ?: return realParameterTypes.asSequence()
return realParameterTypes.dropLast(1).asSequence() + generateSequence { lastArrayType }
}
+141 -123
View File
@@ -5,137 +5,155 @@
package org.jetbrains.kotlin.nj2k.tree
import com.intellij.psi.JavaTokenType
import com.intellij.psi.tree.IElementType
import org.jetbrains.kotlin.j2k.ast.Nullability
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.nj2k.tree.impl.JKJavaOperatorToken
import org.jetbrains.kotlin.nj2k.tree.impl.JKKtSingleValueOperatorToken
import org.jetbrains.kotlin.nj2k.tree.impl.JKKtWordOperatorToken
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.nj2k.tree.visitors.JKVisitor
import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty
interface JKOperator {
val token: JKOperatorToken
val returnType: JKType
}
interface JKOperatorToken {
val text: String
@Suppress("MemberVisibilityCanBePrivate", "SpellCheckingInspection")
companion object {
fun fromElementType(elementType: IElementType) = elementTypeToToken.getValue(elementType)
val RANGE = JKKtSingleValueOperatorToken(KtTokens.RANGE)
val DIV = JKKtSingleValueOperatorToken(KtTokens.DIV)
val MINUS = JKKtSingleValueOperatorToken(KtTokens.MINUS)
val ANDAND = JKKtSingleValueOperatorToken(KtTokens.ANDAND)
val OROR = JKKtSingleValueOperatorToken(KtTokens.OROR)
val PLUS = JKKtSingleValueOperatorToken(KtTokens.PLUS)
val MUL = JKKtSingleValueOperatorToken(KtTokens.MUL)
val GT = JKKtSingleValueOperatorToken(KtTokens.GT)
val GTEQ = JKKtSingleValueOperatorToken(KtTokens.GTEQ)
val LT = JKKtSingleValueOperatorToken(KtTokens.LT)
val LTEQ = JKKtSingleValueOperatorToken(KtTokens.LTEQ)
val PERC = JKKtSingleValueOperatorToken(KtTokens.PERC)
val EQ = JKKtSingleValueOperatorToken(KtTokens.EQ)
val EQEQ = JKKtSingleValueOperatorToken(KtTokens.EQEQ)
val EXCLEQ = JKKtSingleValueOperatorToken(KtTokens.EXCLEQ)
val PLUSEQ = JKKtSingleValueOperatorToken(KtTokens.PLUSEQ)
val MINUSEQ = JKKtSingleValueOperatorToken(KtTokens.MINUSEQ)
val DIVEQ = JKKtSingleValueOperatorToken(KtTokens.DIVEQ)
val MULTEQ = JKKtSingleValueOperatorToken(KtTokens.MULTEQ)
val PERCEQ = JKKtSingleValueOperatorToken(KtTokens.PERCEQ)
val PLUSPLUS = JKKtSingleValueOperatorToken(KtTokens.PLUSPLUS)
val MINUSMINUS = JKKtSingleValueOperatorToken(KtTokens.MINUSMINUS)
val EXCL = JKKtSingleValueOperatorToken(KtTokens.EXCL)
val EQEQEQ = JKKtSingleValueOperatorToken(KtTokens.EQEQEQ)
val EXCLEQEQEQ = JKKtSingleValueOperatorToken(KtTokens.EXCLEQEQEQ)
val AND = JKKtWordOperatorToken("and")
val OR = JKKtWordOperatorToken("or")
val XOR = JKKtWordOperatorToken("xor")
val USHR = JKKtWordOperatorToken("ushr")
val SHR = JKKtWordOperatorToken("shr")
val SHL = JKKtWordOperatorToken("shl")
val ANDEQ = JKJavaOperatorToken(JavaTokenType.ANDEQ)
val OREQ = JKJavaOperatorToken(JavaTokenType.OREQ)
val XOREQ = JKJavaOperatorToken(JavaTokenType.XOREQ)
val LTLTEQ = JKJavaOperatorToken(JavaTokenType.LTLTEQ)
val GTGTEQ = JKJavaOperatorToken(JavaTokenType.GTGTEQ)
val GTGTGTEQ = JKJavaOperatorToken(JavaTokenType.GTGTGTEQ)
private val elementTypeToToken: Map<IElementType, JKOperatorToken> = mapOf(
JavaTokenType.DIV to DIV,
JavaTokenType.MINUS to MINUS,
JavaTokenType.ANDAND to ANDAND,
JavaTokenType.OROR to OROR,
JavaTokenType.PLUS to PLUS,
JavaTokenType.ASTERISK to MUL,
JavaTokenType.GT to GT,
JavaTokenType.GE to GTEQ,
JavaTokenType.LT to LT,
JavaTokenType.LE to LTEQ,
JavaTokenType.PERC to PERC,
JavaTokenType.EQ to EQ,
JavaTokenType.EQEQ to EQEQ,
JavaTokenType.NE to EXCLEQ,
JavaTokenType.PLUSEQ to PLUSEQ,
JavaTokenType.MINUSEQ to MINUSEQ,
JavaTokenType.DIVEQ to DIVEQ,
JavaTokenType.ASTERISKEQ to MULTEQ,
JavaTokenType.PLUSPLUS to PLUSPLUS,
JavaTokenType.MINUSMINUS to MINUSMINUS,
JavaTokenType.EXCL to EXCL,
KtTokens.EQEQEQ to EQEQEQ,
KtTokens.EXCLEQEQEQ to EXCLEQEQEQ,
JavaTokenType.AND to AND,
JavaTokenType.OR to OR,
JavaTokenType.XOR to XOR,
JavaTokenType.GTGTGT to USHR,
JavaTokenType.GTGT to SHR,
JavaTokenType.LTLT to SHL,
JavaTokenType.ANDEQ to ANDEQ,
JavaTokenType.OREQ to OREQ,
JavaTokenType.XOREQ to XOREQ,
JavaTokenType.PERCEQ to PERCEQ,
JavaTokenType.LTLTEQ to LTLTEQ,
JavaTokenType.GTGTEQ to GTGTEQ,
JavaTokenType.GTGTGTEQ to GTGTGTEQ
)
}
}
interface JKKtOperatorToken : JKOperatorToken
interface JKQualifier
interface JKElement {
val parent: JKElement?
fun detach(from: JKElement)
fun attach(to: JKElement)
}
private class JKChild<T : JKElement>(val value: Int) : ReadWriteProperty<JKTreeElement, T> {
override operator fun getValue(thisRef: JKTreeElement, property: KProperty<*>): T {
@Suppress("UNCHECKED_CAST")
return thisRef.children[value] as T
}
interface JKBranchElement : JKElement {
val children: List<Any>
val valid: Boolean
fun invalidate()
override operator fun setValue(thisRef: JKTreeElement, property: KProperty<*>, value: T) {
@Suppress("UNCHECKED_CAST")
(thisRef.children[this.value] as T).detach(thisRef)
thisRef.children[this.value] = value
value.attach(thisRef)
}
}
private class JKListChild<T : JKElement>(val value: Int) : ReadWriteProperty<JKTreeElement, List<T>> {
override operator fun getValue(thisRef: JKTreeElement, property: KProperty<*>): List<T> {
@Suppress("UNCHECKED_CAST")
return thisRef.children[value] as List<T>
}
override operator fun setValue(thisRef: JKTreeElement, property: KProperty<*>, value: List<T>) {
@Suppress("UNCHECKED_CAST")
(thisRef.children[this.value] as List<T>).forEach { it.detach(thisRef) }
thisRef.children[this.value] = value
value.forEach { it.attach(thisRef) }
}
}
abstract class JKTreeElement : JKElement, JKNonCodeElementsListOwner, Cloneable {
override val leftNonCodeElements: MutableList<JKNonCodeElement> = mutableListOf()
override val rightNonCodeElements: MutableList<JKNonCodeElement> = mutableListOf()
override var parent: JKElement? = null
override fun detach(from: JKElement) {
val prevParent = parent
require(from == prevParent)
parent = null
}
override fun attach(to: JKElement) {
check(parent == null)
parent = to
}
open fun accept(visitor: JKVisitor) = visitor.visitTreeElement(this)
private var childNum = 0
protected fun <T : JKTreeElement, U : T> child(v: U): ReadWriteProperty<JKTreeElement, T> {
children.add(childNum, v)
v.attach(this)
return JKChild(childNum++)
}
protected inline fun <reified T : JKTreeElement> children(): ReadWriteProperty<JKTreeElement, List<T>> {
return children(emptyList())
}
protected fun <T : JKTreeElement> children(v: List<T>): ReadWriteProperty<JKTreeElement, List<T>> {
children.add(childNum, v)
v.forEach { it.attach(this) }
return JKListChild(childNum++)
}
open fun acceptChildren(visitor: JKVisitor) {
forEachChild { it.accept(visitor) }
}
private inline fun forEachChild(block: (JKTreeElement) -> Unit) {
children.forEach {
@Suppress("UNCHECKED_CAST")
if (it is JKTreeElement)
block(it)
else
(it as? List<JKTreeElement>)?.forEach { block(it) }
}
}
private var valid: Boolean = true
fun invalidate() {
forEachChild { it.detach(this) }
valid = false
}
fun onAttach() {
check(valid)
}
var children: MutableList<Any> = mutableListOf()
private set
@Suppress("UNCHECKED_CAST")
open fun copy(): JKTreeElement {
val cloned = clone() as JKTreeElement
val deepClonedChildren =
cloned.children.map {
when (it) {
is JKTreeElement -> it.copy()
is List<*> -> (it as List<JKTreeElement>).map { it.copy() }
else -> error("Tree is corrupted")
}
}
deepClonedChildren.forEach { child ->
when (child) {
is JKTreeElement -> {
child.detach(this)
child.attach(cloned)
}
is List<*> -> (child as List<JKTreeElement>).forEach {
it.detach(this)
it.attach(cloned)
}
}
}
cloned.children = deepClonedChildren.toMutableList()
return cloned
}
}
abstract class JKAnnotationMemberValue : JKTreeElement()
interface PsiOwner {
var psi: PsiElement?
}
class PsiOwnerImpl(override var psi: PsiElement? = null) : PsiOwner
interface JKTypeArgumentListOwner : JKNonCodeElementsListOwner {
var typeArgumentList: JKTypeArgumentList
}
interface JKTypeParameterListOwner : JKNonCodeElementsListOwner {
var typeParameterList: JKTypeParameterList
}
interface JKType {
val nullability: Nullability
}
@@ -0,0 +1,246 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.nj2k.tree
import org.jetbrains.kotlin.nj2k.tree.visitors.JKVisitor
import org.jetbrains.kotlin.nj2k.types.JKNoTypeImpl
abstract class JKDeclaration : JKTreeElement(), PsiOwner by PsiOwnerImpl() {
abstract val name: JKNameIdentifier
}
class JKClass(
name: JKNameIdentifier,
inheritance: JKInheritanceInfo,
var classKind: ClassKind,
typeParameterList: JKTypeParameterList,
classBody: JKClassBody,
annotationList: JKAnnotationList,
otherModifierElements: List<JKOtherModifierElement>,
visibilityElement: JKVisibilityModifierElement,
modalityElement: JKModalityModifierElement
) : JKDeclaration(), JKVisibilityOwner, JKOtherModifiersOwner, JKModalityOwner, JKTypeParameterListOwner, JKAnnotationListOwner {
override fun accept(visitor: JKVisitor) = visitor.visitClass(this)
override var name by child(name)
val inheritance by child(inheritance)
override var typeParameterList: JKTypeParameterList by child(typeParameterList)
var classBody: JKClassBody by child(classBody)
override var annotationList: JKAnnotationList by child(annotationList)
override var otherModifierElements by children(otherModifierElements)
override var visibilityElement by child(visibilityElement)
override var modalityElement by child(modalityElement)
enum class ClassKind {
ANNOTATION, CLASS, ENUM, INTERFACE, OBJECT, COMPANION
}
}
abstract class JKVariable : JKDeclaration(), JKAnnotationListOwner {
abstract var type: JKTypeElement
abstract var initializer: JKExpression
}
class JKLocalVariable(
type: JKTypeElement,
name: JKNameIdentifier,
initializer: JKExpression,
mutabilityElement: JKMutabilityModifierElement,
annotationList: JKAnnotationList = JKAnnotationList()
) : JKVariable(), JKMutabilityOwner {
override var initializer by child(initializer)
override var name by child(name)
override var type by child(type)
override var annotationList by child(annotationList)
override var mutabilityElement by child(mutabilityElement)
override fun accept(visitor: JKVisitor) = visitor.visitLocalVariable(this)
}
class JKForLoopVariable(
type: JKTypeElement,
name: JKNameIdentifier,
initializer: JKExpression,
annotationList: JKAnnotationList = JKAnnotationList()
) : JKVariable() {
override var initializer by child(initializer)
override var name by child(name)
override var type by child(type)
override var annotationList by child(annotationList)
override fun accept(visitor: JKVisitor) = visitor.visitForLoopVariable(this)
}
class JKParameter(
type: JKTypeElement,
name: JKNameIdentifier,
var isVarArgs: Boolean = false,
initializer: JKExpression = JKStubExpression(),
annotationList: JKAnnotationList = JKAnnotationList()
) : JKVariable(), JKModifiersListOwner {
override var initializer by child(initializer)
override var name by child(name)
override var type by child(type)
override var annotationList by child(annotationList)
override fun accept(visitor: JKVisitor) = visitor.visitParameter(this)
}
class JKEnumConstant(
name: JKNameIdentifier,
arguments: JKArgumentList,
body: JKClassBody,
type: JKTypeElement,
annotationList: JKAnnotationList = JKAnnotationList()
) : JKVariable() {
override var name: JKNameIdentifier by child(name)
val arguments: JKArgumentList by child(arguments)
val body: JKClassBody by child(body)
override var type: JKTypeElement by child(type)
override var initializer: JKExpression by child(JKStubExpression())
override var annotationList by child(annotationList)
override fun accept(visitor: JKVisitor) = visitor.visitEnumConstant(this)
}
class JKTypeParameter(name: JKNameIdentifier, upperBounds: List<JKTypeElement>) : JKDeclaration() {
override var name: JKNameIdentifier by child(name)
var upperBounds: List<JKTypeElement> by children(upperBounds)
override fun accept(visitor: JKVisitor) = visitor.visitTypeParameter(this)
}
abstract class JKMethod : JKDeclaration(), JKVisibilityOwner, JKModalityOwner, JKOtherModifiersOwner, JKTypeParameterListOwner,
JKAnnotationListOwner {
abstract var parameters: List<JKParameter>
abstract var returnType: JKTypeElement
abstract var block: JKBlock
val leftParen = JKTokenElementImpl("(")
val rightParen = JKTokenElementImpl(")")
}
class JKMethodImpl(
returnType: JKTypeElement,
name: JKNameIdentifier,
parameters: List<JKParameter>,
block: JKBlock,
typeParameterList: JKTypeParameterList,
annotationList: JKAnnotationList,
throwsList: List<JKTypeElement>,
otherModifierElements: List<JKOtherModifierElement>,
visibilityElement: JKVisibilityModifierElement,
modalityElement: JKModalityModifierElement
) : JKMethod() {
override fun accept(visitor: JKVisitor) = visitor.visitMethod(this)
override var returnType: JKTypeElement by child(returnType)
override var name: JKNameIdentifier by child(name)
override var parameters: List<JKParameter> by children(parameters)
override var block: JKBlock by child(block)
override var typeParameterList: JKTypeParameterList by child(typeParameterList)
override var annotationList: JKAnnotationList by child(annotationList)
var throwsList: List<JKTypeElement> by children(throwsList)
override var otherModifierElements by children(otherModifierElements)
override var visibilityElement by child(visibilityElement)
override var modalityElement by child(modalityElement)
}
abstract class JKConstructor : JKMethod() {
abstract var delegationCall: JKExpression
}
class JKConstructorImpl(
name: JKNameIdentifier,
parameters: List<JKParameter>,
block: JKBlock,
delegationCall: JKExpression,
annotationList: JKAnnotationList,
otherModifierElements: List<JKOtherModifierElement>,
visibilityElement: JKVisibilityModifierElement,
modalityElement: JKModalityModifierElement
) : JKConstructor() {
override var returnType: JKTypeElement by child(JKTypeElement(JKNoTypeImpl))
override var name: JKNameIdentifier by child(name)
override var parameters: List<JKParameter> by children(parameters)
override var block: JKBlock by child(block)
override var delegationCall: JKExpression by child(delegationCall)
override var typeParameterList: JKTypeParameterList by child(JKTypeParameterList())
override var annotationList: JKAnnotationList by child(annotationList)
override var otherModifierElements by children(otherModifierElements)
override var visibilityElement by child(visibilityElement)
override var modalityElement by child(modalityElement)
override fun accept(visitor: JKVisitor) = visitor.visitConstructor(this)
}
class JKKtPrimaryConstructor(
name: JKNameIdentifier,
parameters: List<JKParameter>,
delegationCall: JKExpression,
annotationList: JKAnnotationList,
otherModifierElements: List<JKOtherModifierElement>,
visibilityElement: JKVisibilityModifierElement,
modalityElement: JKModalityModifierElement
) : JKConstructor() {
override var returnType: JKTypeElement by child(JKTypeElement(JKNoTypeImpl))
override var name: JKNameIdentifier by child(name)
override var parameters: List<JKParameter> by children(parameters)
override var block: JKBlock by child(JKBodyStub)
override var delegationCall: JKExpression by child(delegationCall)
override var typeParameterList: JKTypeParameterList by child(JKTypeParameterList())
override var annotationList: JKAnnotationList by child(annotationList)
override var otherModifierElements by children(otherModifierElements)
override var visibilityElement by child(visibilityElement)
override var modalityElement by child(modalityElement)
override fun accept(visitor: JKVisitor) = visitor.visitKtPrimaryConstructor(this)
}
class JKField(
type: JKTypeElement,
name: JKNameIdentifier,
initializer: JKExpression,
annotationList: JKAnnotationList,
otherModifierElements: List<JKOtherModifierElement>,
visibilityElement: JKVisibilityModifierElement,
modalityElement: JKModalityModifierElement,
mutabilityElement: JKMutabilityModifierElement
) : JKVariable(), JKVisibilityOwner, JKMutabilityOwner, JKModalityOwner, JKOtherModifiersOwner, JKAnnotationListOwner {
override var annotationList: JKAnnotationList by child(annotationList)
override var initializer: JKExpression by child(initializer)
override var type by child(type)
override var name: JKNameIdentifier by child(name)
override var otherModifierElements by children(otherModifierElements)
override var visibilityElement by child(visibilityElement)
override var modalityElement by child(modalityElement)
override var mutabilityElement by child(mutabilityElement)
override fun accept(visitor: JKVisitor) = visitor.visitField(this)
}
class JKKtInitDeclaration(block: JKBlock) : JKDeclaration() {
var block: JKBlock by child(block)
override val name: JKNameIdentifier by child(JKNameIdentifier("<init>"))
override fun accept(visitor: JKVisitor) = visitor.visitKtInitDeclaration(this)
}
class JKJavaStaticInitDeclaration(block: JKBlock) : JKDeclaration() {
var block: JKBlock by child(block)
override var name: JKNameIdentifier by child(JKNameIdentifier("<init>"))
override fun accept(visitor: JKVisitor) = visitor.visitJavaStaticInitDeclaration(this)
}
@@ -0,0 +1,251 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.nj2k.tree
import org.jetbrains.kotlin.nj2k.symbols.JKClassSymbol
import org.jetbrains.kotlin.nj2k.tree.visitors.JKVisitor
import org.jetbrains.kotlin.nj2k.types.JKType
class JKTreeRoot(element: JKTreeElement) : JKTreeElement() {
var element by child(element)
override fun accept(visitor: JKVisitor) = visitor.visitTreeRoot(this)
}
class JKFile(
packageDeclaration: JKPackageDeclaration,
importList: JKImportList,
declarationList: List<JKDeclaration>
) : JKTreeElement(), PsiOwner by PsiOwnerImpl() {
override fun accept(visitor: JKVisitor) = visitor.visitFile(this)
var packageDeclaration: JKPackageDeclaration by child(packageDeclaration)
var importList: JKImportList by child(importList)
var declarationList by children(declarationList)
}
class JKTypeElement(var type: JKType) : JKTreeElement() {
override fun accept(visitor: JKVisitor) = visitor.visitTypeElement(this)
}
abstract class JKBlock : JKTreeElement() {
abstract var statements: List<JKStatement>
val leftBrace = JKTokenElementImpl("{")
val rightBrace = JKTokenElementImpl("}")
}
object JKBodyStub : JKBlock() {
override val leftNonCodeElements: MutableList<JKNonCodeElement> = mutableListOf()
override val rightNonCodeElements: MutableList<JKNonCodeElement> = mutableListOf()
override fun copy(): JKTreeElement = this
override var statements: List<JKStatement>
get() = emptyList()
set(_) {}
override fun acceptChildren(visitor: JKVisitor) {}
override var parent: JKElement?
get() = null
set(_) {}
override fun detach(from: JKElement) {}
override fun attach(to: JKElement) {}
override fun accept(visitor: JKVisitor) = Unit
}
class JKInheritanceInfo(
extends: List<JKTypeElement>,
implements: List<JKTypeElement>
) : JKTreeElement() {
var extends: List<JKTypeElement> by children(extends)
var implements: List<JKTypeElement> by children(implements)
override fun accept(visitor: JKVisitor) = visitor.visitInheritanceInfo(this)
}
class JKPackageDeclaration(name: JKNameIdentifier) : JKTreeElement() {
var name: JKNameIdentifier by child(name)
override fun accept(visitor: JKVisitor) = visitor.visitPackageDeclaration(this)
}
abstract class JKLabel : JKTreeElement()
class JKLabelEmpty : JKLabel() {
override fun accept(visitor: JKVisitor) = visitor.visitLabelEmpty(this)
}
class JKLabelText(label: JKNameIdentifier) : JKLabel() {
val label: JKNameIdentifier by child(label)
override fun accept(visitor: JKVisitor) = visitor.visitLabelText(this)
}
class JKImportStatement(name: JKNameIdentifier) : JKTreeElement() {
val name: JKNameIdentifier by child(name)
override fun accept(visitor: JKVisitor) = visitor.visitImportStatement(this)
}
class JKImportList(imports: List<JKImportStatement>) : JKTreeElement() {
var imports by children(imports)
override fun accept(visitor: JKVisitor) = visitor.visitImportList(this)
}
abstract class JKAnnotationParameter : JKTreeElement() {
abstract var value: JKAnnotationMemberValue
}
class JKAnnotationParameterImpl(value: JKAnnotationMemberValue) : JKAnnotationParameter() {
override var value: JKAnnotationMemberValue by child(value)
override fun accept(visitor: JKVisitor) = visitor.visitAnnotationParameter(this)
}
class JKAnnotationNameParameter(
value: JKAnnotationMemberValue,
name: JKNameIdentifier
) : JKAnnotationParameter() {
override var value: JKAnnotationMemberValue by child(value)
val name: JKNameIdentifier by child(name)
override fun accept(visitor: JKVisitor) = visitor.visitAnnotationNameParameter(this)
}
abstract class JKArgument : JKTreeElement() {
abstract var value: JKExpression
}
class JKNamedArgument(
value: JKExpression,
name: JKNameIdentifier
) : JKArgument() {
override var value by child(value)
val name by child(name)
override fun accept(visitor: JKVisitor) = visitor.visitNamedArgument(this)
}
class JKArgumentImpl(value: JKExpression) : JKArgument() {
override var value by child(value)
override fun accept(visitor: JKVisitor) = visitor.visitArgument(this)
}
class JKArgumentList(arguments: List<JKArgument> = emptyList()) : JKTreeElement() {
constructor(vararg arguments: JKArgument) : this(arguments.toList())
constructor(vararg values: JKExpression) : this(values.map { JKArgumentImpl(it) })
var arguments by children(arguments)
override fun accept(visitor: JKVisitor) = visitor.visitArgumentList(this)
}
class JKTypeParameterList(typeParameters: List<JKTypeParameter> = emptyList()) : JKTreeElement() {
var typeParameters by children(typeParameters)
override fun accept(visitor: JKVisitor) = visitor.visitTypeParameterList(this)
}
class JKAnnotationList(annotations: List<JKAnnotation> = emptyList()) : JKTreeElement() {
var annotations: List<JKAnnotation> by children(annotations)
override fun accept(visitor: JKVisitor) = visitor.visitAnnotationList(this)
}
class JKAnnotation(
var classSymbol: JKClassSymbol,
arguments: List<JKAnnotationParameter> = emptyList()
) : JKAnnotationMemberValue() {
var arguments: List<JKAnnotationParameter> by children(arguments)
override fun accept(visitor: JKVisitor) = visitor.visitAnnotation(this)
}
class JKTypeArgumentList(typeArguments: List<JKTypeElement> = emptyList()) : JKTreeElement(), PsiOwner by PsiOwnerImpl() {
var typeArguments: List<JKTypeElement> by children(typeArguments)
override fun accept(visitor: JKVisitor) = visitor.visitTypeArgumentList(this)
}
class JKNameIdentifier(val value: String) : JKTreeElement() {
override fun accept(visitor: JKVisitor) = visitor.visitNameIdentifier(this)
}
interface JKAnnotationListOwner : JKNonCodeElementsListOwner {
var annotationList: JKAnnotationList
}
class JKBlockImpl(statements: List<JKStatement> = emptyList()) : JKBlock() {
constructor(vararg statements: JKStatement) : this(statements.toList())
override var statements by children(statements)
override fun accept(visitor: JKVisitor) = visitor.visitBlock(this)
}
class JKKtWhenCase(labels: List<JKKtWhenLabel>, statement: JKStatement) : JKTreeElement() {
var labels: List<JKKtWhenLabel> by children(labels)
var statement: JKStatement by child(statement)
override fun accept(visitor: JKVisitor) = visitor.visitKtWhenCase(this)
}
abstract class JKKtWhenLabel : JKTreeElement()
class JKKtElseWhenLabel : JKKtWhenLabel() {
override fun accept(visitor: JKVisitor) = visitor.visitKtElseWhenLabel(this)
}
class JKKtValueWhenLabel(expression: JKExpression) : JKKtWhenLabel() {
var expression: JKExpression by child(expression)
override fun accept(visitor: JKVisitor) = visitor.visitKtValueWhenLabel(this)
}
class JKClassBody(declarations: List<JKDeclaration> = emptyList()) : JKTreeElement() {
var declarations: List<JKDeclaration> by children(declarations)
override fun accept(visitor: JKVisitor) = visitor.visitClassBody(this)
val leftBrace = JKTokenElementImpl("{")
val rightBrace = JKTokenElementImpl("}")
}
class JKJavaTryCatchSection(
parameter: JKParameter,
block: JKBlock
) : JKStatement() {
var parameter: JKParameter by child(parameter)
var block: JKBlock by child(block)
override fun accept(visitor: JKVisitor) = visitor.visitJavaTryCatchSection(this)
}
abstract class JKJavaSwitchCase : JKTreeElement() {
abstract fun isDefault(): Boolean
abstract var statements: List<JKStatement>
}
class JKJavaDefaultSwitchCase(statements: List<JKStatement>) : JKJavaSwitchCase(), PsiOwner by PsiOwnerImpl() {
override var statements: List<JKStatement> by children(statements)
override fun isDefault(): Boolean = true
override fun accept(visitor: JKVisitor) = visitor.visitJavaDefaultSwitchCase(this)
}
class JKJavaLabelSwitchCase(
label: JKExpression,
statements: List<JKStatement>
) : JKJavaSwitchCase(), PsiOwner by PsiOwnerImpl() {
override var statements: List<JKStatement> by children(statements)
var label: JKExpression by child(label)
override fun isDefault(): Boolean = false
override fun accept(visitor: JKVisitor) = visitor.visitJavaLabelSwitchCase(this)
}
class JKKtTryCatchSection(
parameter: JKParameter,
block: JKBlock
) : JKTreeElement() {
var parameter: JKParameter by child(parameter)
var block: JKBlock by child(block)
override fun accept(visitor: JKVisitor) = visitor.visitKtTryCatchSection(this)
}
@@ -0,0 +1,315 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.nj2k.tree
import org.jetbrains.kotlin.nj2k.symbols.*
import org.jetbrains.kotlin.nj2k.tree.visitors.JKVisitor
import org.jetbrains.kotlin.nj2k.types.JKContextType
import org.jetbrains.kotlin.nj2k.types.JKNoTypeImpl
import org.jetbrains.kotlin.nj2k.types.JKType
abstract class JKExpression : JKAnnotationMemberValue(), PsiOwner by PsiOwnerImpl()
abstract class JKOperatorExpression : JKExpression() {
abstract var operator: JKOperator
}
class JKBinaryExpression(
left: JKExpression,
right: JKExpression,
override var operator: JKOperator
) : JKOperatorExpression() {
var right by child(right)
var left by child(left)
override fun accept(visitor: JKVisitor) = visitor.visitBinaryExpression(this)
}
abstract class JKUnaryExpression : JKOperatorExpression() {
abstract var expression: JKExpression
}
class JKPrefixExpression(expression: JKExpression, override var operator: JKOperator) : JKUnaryExpression() {
override var expression by child(expression)
override fun accept(visitor: JKVisitor) = visitor.visitPrefixExpression(this)
}
class JKPostfixExpression(expression: JKExpression, override var operator: JKOperator) : JKUnaryExpression() {
override var expression by child(expression)
override fun accept(visitor: JKVisitor) = visitor.visitPostfixExpression(this)
}
class JKQualifiedExpression(
receiver: JKExpression,
selector: JKExpression
) : JKExpression() {
var receiver: JKExpression by child(receiver)
var selector: JKExpression by child(selector)
override fun accept(visitor: JKVisitor) = visitor.visitQualifiedExpression(this)
}
class JKArrayAccessExpression(
expression: JKExpression,
indexExpression: JKExpression
) : JKExpression() {
var expression: JKExpression by child(expression)
var indexExpression: JKExpression by child(indexExpression)
override fun accept(visitor: JKVisitor) = visitor.visitArrayAccessExpression(this)
}
class JKParenthesizedExpression(expression: JKExpression) : JKExpression() {
var expression: JKExpression by child(expression)
override fun accept(visitor: JKVisitor) = visitor.visitParenthesizedExpression(this)
}
class JKTypeCastExpression(expression: JKExpression, type: JKTypeElement) : JKExpression() {
var expression by child(expression)
var type by child(type)
override fun accept(visitor: JKVisitor) = visitor.visitTypeCastExpression(this)
}
class JKLiteralExpression(
var literal: String,
val type: LiteralType
) : JKExpression() {
override fun accept(visitor: JKVisitor) = visitor.visitLiteralExpression(this)
enum class LiteralType {
STRING, CHAR, BOOLEAN, NULL, INT, LONG, FLOAT, DOUBLE
}
}
class JKStubExpression : JKExpression() {
override fun accept(visitor: JKVisitor) = visitor.visitStubExpression(this)
}
class JKThisExpression(qualifierLabel: JKLabel) : JKExpression() {
var qualifierLabel: JKLabel by child(qualifierLabel)
override fun accept(visitor: JKVisitor) = visitor.visitThisExpression(this)
}
class JKSuperExpression(qualifierLabel: JKLabel = JKLabelEmpty()) : JKExpression() {
var qualifierLabel: JKLabel by child(qualifierLabel)
override fun accept(visitor: JKVisitor) = visitor.visitSuperExpression(this)
}
class JKIfElseExpression(condition: JKExpression, thenBranch: JKExpression, elseBranch: JKExpression) : JKExpression() {
var condition by child(condition)
var thenBranch by child(thenBranch)
var elseBranch by child(elseBranch)
override fun accept(visitor: JKVisitor) = visitor.visitIfElseExpression(this)
}
class JKLambdaExpression(
statement: JKStatement,
parameters: List<JKParameter>,
functionalType: JKTypeElement = JKTypeElement(JKNoTypeImpl),
returnType: JKTypeElement = JKTypeElement(JKContextType)
) : JKExpression() {
var statement by child(statement)
var parameters by children(parameters)
var functionalType by child(functionalType)
val returnType by child(returnType)
override fun accept(visitor: JKVisitor) = visitor.visitLambdaExpression(this)
}
abstract class JKCallExpression : JKExpression(), JKTypeArgumentListOwner {
abstract val identifier: JKMethodSymbol
abstract var arguments: JKArgumentList
}
class JKDelegationConstructorCall(
override val identifier: JKMethodSymbol,
expression: JKExpression,
arguments: JKArgumentList
) : JKCallExpression() {
override var typeArgumentList: JKTypeArgumentList by child(JKTypeArgumentList())
val expression: JKExpression by child(expression)
override var arguments: JKArgumentList by child(arguments)
override fun accept(visitor: JKVisitor) = visitor.visitDelegationConstructorCall(this)
}
class JKCallExpressionImpl(
override val identifier: JKMethodSymbol,
arguments: JKArgumentList,
typeArgumentList: JKTypeArgumentList = JKTypeArgumentList()
) : JKCallExpression() {
override var typeArgumentList by child(typeArgumentList)
override var arguments by child(arguments)
override fun accept(visitor: JKVisitor) = visitor.visitCallExpressionImpl(this)
}
class JKNewExpression(
val classSymbol: JKClassSymbol,
arguments: JKArgumentList,
typeArgumentList: JKTypeArgumentList,
classBody: JKClassBody = JKClassBody(),
val isAnonymousClass: Boolean = false
) : JKExpression() {
var typeArgumentList by child(typeArgumentList)
var arguments by child(arguments)
var classBody by child(classBody)
override fun accept(visitor: JKVisitor) = visitor.visitNewExpression(this)
}
class JKFieldAccessExpression(var identifier: JKFieldSymbol) : JKExpression() {
override fun accept(visitor: JKVisitor) = visitor.visitFieldAccessExpression(this)
}
class JKPackageAccessExpression(var identifier: JKPackageSymbol) : JKExpression() {
override fun accept(visitor: JKVisitor) = visitor.visitPackageAccessExpression(this)
}
class JKClassAccessExpression(var identifier: JKClassSymbol) : JKExpression() {
override fun accept(visitor: JKVisitor) = visitor.visitClassAccessExpression(this)
}
class JKMethodReferenceExpression(
qualifier: JKExpression,
val identifier: JKSymbol,
functionalType: JKTypeElement,
val isConstructorCall: Boolean
) : JKExpression() {
val qualifier by child(qualifier)
val functionalType by child(functionalType)
override fun accept(visitor: JKVisitor) = visitor.visitMethodReferenceExpression(this)
}
class JKLabeledExpression(statement: JKStatement, labels: List<JKNameIdentifier>) : JKExpression() {
var statement: JKStatement by child(statement)
val labels: List<JKNameIdentifier> by children(labels)
override fun accept(visitor: JKVisitor) = visitor.visitLabeledExpression(this)
}
class JKClassLiteralExpression(
classType: JKTypeElement,
var literalType: ClassLiteralType
) : JKExpression() {
val classType: JKTypeElement by child(classType)
override fun accept(visitor: JKVisitor) = visitor.visitClassLiteralExpression(this)
enum class ClassLiteralType {
KOTLIN_CLASS,
JAVA_CLASS,
JAVA_PRIMITIVE_CLASS,
JAVA_VOID_TYPE
}
}
abstract class JKKtAssignmentChainLink : JKExpression() {
abstract val receiver: JKExpression
abstract val assignmentStatement: JKKtAssignmentStatement
abstract val field: JKExpression
}
class JKAssignmentChainAlsoLink(
receiver: JKExpression,
assignmentStatement: JKKtAssignmentStatement,
field: JKExpression
) : JKKtAssignmentChainLink() {
override val receiver by child(receiver)
override val assignmentStatement by child(assignmentStatement)
override val field by child(field)
override fun accept(visitor: JKVisitor) = visitor.visitAssignmentChainAlsoLink(this)
}
class JKAssignmentChainLetLink(
receiver: JKExpression,
assignmentStatement: JKKtAssignmentStatement,
field: JKExpression
) : JKKtAssignmentChainLink() {
override val receiver by child(receiver)
override val assignmentStatement by child(assignmentStatement)
override val field by child(field)
override fun accept(visitor: JKVisitor) = visitor.visitAssignmentChainLetLink(this)
}
class JKIsExpression(expression: JKExpression, type: JKTypeElement) : JKExpression() {
var type by child(type)
var expression by child(expression)
override fun accept(visitor: JKVisitor) = visitor.visitIsExpression(this)
}
class JKKtThrowExpression(exception: JKExpression) : JKExpression() {
var exception: JKExpression by child(exception)
override fun accept(visitor: JKVisitor) = visitor.visitKtThrowExpression(this)
}
class JKKtItExpression(val type: JKType) : JKExpression() {
override fun accept(visitor: JKVisitor) = visitor.visitKtItExpression(this)
}
class JKKtAnnotationArrayInitializerExpression(initializers: List<JKAnnotationMemberValue>) : JKExpression() {
constructor(vararg initializers: JKAnnotationMemberValue) : this(initializers.toList())
val initializers: List<JKAnnotationMemberValue> by children(initializers)
override fun accept(visitor: JKVisitor) = visitor.visitKtAnnotationArrayInitializerExpression(this)
}
class JKKtTryExpression(
tryBlock: JKBlock,
finallyBlock: JKBlock,
catchSections: List<JKKtTryCatchSection>
) : JKExpression() {
var tryBlock: JKBlock by child(tryBlock)
var finallyBlock: JKBlock by child(finallyBlock)
var catchSections: List<JKKtTryCatchSection> by children(catchSections)
override fun accept(visitor: JKVisitor) = visitor.visitKtTryExpression(this)
}
class JKKtTryCatchSection(
parameter: JKParameter,
block: JKBlock
) : JKTreeElement() {
var parameter: JKParameter by child(parameter)
var block: JKBlock by child(block)
override fun accept(visitor: JKVisitor) = visitor.visitKtTryCatchSection(this)
}
class JKJavaNewEmptyArray(initializer: List<JKExpression>, type: JKTypeElement) : JKExpression() {
val type by child(type)
var initializer by children(initializer)
override fun accept(visitor: JKVisitor) = visitor.visitJavaNewEmptyArray(this)
}
class JKJavaNewArray(initializer: List<JKExpression>, type: JKTypeElement) : JKExpression() {
val type by child(type)
var initializer by children(initializer)
override fun accept(visitor: JKVisitor) = visitor.visitJavaNewArray(this)
}
class JKJavaAssignmentExpression(
field: JKExpression,
expression: JKExpression,
var operator: JKOperator
) : JKExpression() {
var field by child(field)
var expression by child(expression)
override fun accept(visitor: JKVisitor) = visitor.visitJavaAssignmentExpression(this)
}
@@ -1,157 +0,0 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.nj2k.tree.impl
import org.jetbrains.kotlin.nj2k.tree.JKBranchElement
import org.jetbrains.kotlin.nj2k.tree.JKElement
import org.jetbrains.kotlin.nj2k.tree.JKNonCodeElement
import org.jetbrains.kotlin.nj2k.tree.JKTreeElement
import org.jetbrains.kotlin.nj2k.tree.visitors.JKVisitor
import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty
private class JKChild<T : JKElement>(val value: Int) : ReadWriteProperty<JKBranchElementBase, T> {
override operator fun getValue(thisRef: JKBranchElementBase, property: KProperty<*>): T {
@Suppress("UNCHECKED_CAST")
return thisRef.children[value] as T
}
override operator fun setValue(thisRef: JKBranchElementBase, property: KProperty<*>, value: T) {
@Suppress("UNCHECKED_CAST")
(thisRef.children[this.value] as T).detach(thisRef)
thisRef.children[this.value] = value
value.attach(thisRef)
}
}
private class JKListChild<T : JKElement>(val value: Int) : ReadWriteProperty<JKBranchElementBase, List<T>> {
override operator fun getValue(thisRef: JKBranchElementBase, property: KProperty<*>): List<T> {
@Suppress("UNCHECKED_CAST")
return thisRef.children[value] as List<T>
}
override operator fun setValue(thisRef: JKBranchElementBase, property: KProperty<*>, value: List<T>) {
@Suppress("UNCHECKED_CAST")
(thisRef.children[this.value] as List<T>).forEach { it.detach(thisRef) }
thisRef.children[this.value] = value
value.forEach { it.attach(thisRef) }
}
}
abstract class JKElementBase : JKTreeElement, Cloneable {
override val leftNonCodeElements: MutableList<JKNonCodeElement> = mutableListOf()
override val rightNonCodeElements: MutableList<JKNonCodeElement> = mutableListOf()
override var parent: JKElement? = null
override fun detach(from: JKElement) {
val prevParent = parent
require(from == prevParent)
parent = null
onDetach(prevParent)
}
open fun onDetach(from: JKElement) {
}
override fun attach(to: JKElement) {
check(parent == null)
parent = to
onAttach()
}
open fun onAttach() {
}
override fun accept(visitor: JKVisitor) = visitor.visitTreeElement(this)
override fun acceptChildren(visitor: JKVisitor) {}
override fun copy(): JKTreeElement =
clone() as JKTreeElement
}
abstract class JKBranchElementBase : JKElementBase(), JKBranchElement {
private var childNum = 0
protected fun <T : JKTreeElement, U : T> child(v: U): ReadWriteProperty<JKBranchElementBase, T> {
children.add(childNum, v)
v.attach(this)
return JKChild(childNum++)
}
protected inline fun <reified T : JKTreeElement> children(): ReadWriteProperty<JKBranchElementBase, List<T>> {
return children(emptyList())
}
protected fun <T : JKTreeElement> children(v: List<T>): ReadWriteProperty<JKBranchElementBase, List<T>> {
children.add(childNum, v)
v.forEach { it.attach(this) }
return JKListChild(childNum++)
}
override fun acceptChildren(visitor: JKVisitor) {
forEachChild { it.accept(visitor) }
}
protected inline fun forEachChild(block: (JKTreeElement) -> Unit) {
children.forEach {
@Suppress("UNCHECKED_CAST")
if (it is JKTreeElement)
block(it)
else
(it as? List<JKTreeElement>)?.forEach { block(it) }
}
}
final override var valid: Boolean = true
final override fun invalidate() {
forEachChild { it.detach(this) }
valid = false
}
override fun onAttach() {
check(valid)
}
final override var children: MutableList<Any> = mutableListOf()
private set
@Suppress("UNCHECKED_CAST")
override fun copy(): JKTreeElement {
val cloned = super.copy() as JKBranchElementBase
val deepClonedChildren =
cloned.children.map {
when (it) {
is JKElementBase -> it.copy()
is List<*> -> (it as List<JKTreeElement>).map { it.copy() }
else -> error("Tree is corrupted")
}
}
deepClonedChildren.forEach { child ->
when (child) {
is JKElementBase -> {
child.detach(this)
child.attach(cloned)
}
is List<*> -> (child as List<JKTreeElement>).forEach {
it.detach(this)
it.attach(cloned)
}
}
}
cloned.children = deepClonedChildren.toMutableList()
return cloned
}
}
@@ -1,639 +0,0 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.nj2k.tree.impl
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.j2k.ast.Nullability
import org.jetbrains.kotlin.nj2k.symbols.*
import org.jetbrains.kotlin.nj2k.tree.*
import org.jetbrains.kotlin.nj2k.tree.JKLiteralExpression.LiteralType
import org.jetbrains.kotlin.nj2k.tree.visitors.JKVisitor
import org.jetbrains.kotlin.nj2k.types.*
class JKTreeRootImpl(element: JKTreeElement) : JKTreeRoot, JKBranchElementBase() {
override var element by child(element)
override fun accept(visitor: JKVisitor) = visitor.visitTreeRoot(this)
}
class JKFileImpl(
packageDeclaration: JKPackageDeclaration,
importList: JKImportList,
declarationList: List<JKDeclaration>
) : JKFile, JKBranchElementBase(),
PsiOwner by PsiOwnerImpl() {
override fun accept(visitor: JKVisitor) = visitor.visitFile(this)
override var packageDeclaration: JKPackageDeclaration by child(packageDeclaration)
override var importList: JKImportList by child(importList)
override var declarationList by children(declarationList)
}
class JKClassImpl(
name: JKNameIdentifier,
inheritance: JKInheritanceInfo,
override var classKind: JKClass.ClassKind,
typeParameterList: JKTypeParameterList,
classBody: JKClassBody,
annotationList: JKAnnotationList,
otherModifierElements: List<JKOtherModifierElement>,
visibilityElement: JKVisibilityModifierElement,
modalityElement: JKModalityModifierElement
) : JKClass(), PsiOwner by PsiOwnerImpl() {
override fun accept(visitor: JKVisitor) = visitor.visitClass(this)
override var name by child(name)
override val inheritance by child(inheritance)
override var typeParameterList: JKTypeParameterList by child(typeParameterList)
override var classBody: JKClassBody by child(classBody)
override var annotationList: JKAnnotationList by child(annotationList)
override var otherModifierElements by children(otherModifierElements)
override var visibilityElement by child(visibilityElement)
override var modalityElement by child(modalityElement)
}
class JKNameIdentifierImpl(override val value: String) : JKNameIdentifier, JKElementBase(), PsiOwner by PsiOwnerImpl() {
override fun accept(visitor: JKVisitor) = visitor.visitNameIdentifier(this)
}
class JKForLoopVariableImpl(
type: JKTypeElement,
name: JKNameIdentifier,
initializer: JKExpression,
annotationList: JKAnnotationList = JKAnnotationListImpl()
) : JKForLoopVariable() {
override var initializer by child(initializer)
override var name by child(name)
override var type by child(type)
override var annotationList by child(annotationList)
override fun accept(visitor: JKVisitor) = visitor.visitForLoopVariable(this)
}
class JKParameterImpl(
type: JKTypeElement,
name: JKNameIdentifier,
override var isVarArgs: Boolean = false,
initializer: JKExpression = JKStubExpressionImpl(),
annotationList: JKAnnotationList = JKAnnotationListImpl()
) : JKParameter(), PsiOwner by PsiOwnerImpl() {
override fun accept(visitor: JKVisitor) = visitor.visitParameter(this)
override var initializer by child(initializer)
override var name by child(name)
override var type by child(type)
override var annotationList by child(annotationList)
}
class JKBlockImpl(statements: List<JKStatement> = emptyList()) : JKBlock(), PsiOwner by PsiOwnerImpl() {
constructor(vararg statements: JKStatement) : this(statements.toList())
override fun accept(visitor: JKVisitor) = visitor.visitBlock(this)
override var statements by children(statements)
}
class JKBinaryExpressionImpl(
left: JKExpression,
right: JKExpression,
override var operator: JKOperator
) : JKBinaryExpression, JKBranchElementBase(), PsiOwner by PsiOwnerImpl() {
override fun accept(visitor: JKVisitor) = visitor.visitBinaryExpression(this)
override var right by child(right)
override var left by child(left)
}
class JKPrefixExpressionImpl(expression: JKExpression, override var operator: JKOperator) : JKPrefixExpression, JKBranchElementBase(),
PsiOwner by PsiOwnerImpl() {
override fun accept(visitor: JKVisitor) = visitor.visitPrefixExpression(this)
override var expression by child(expression)
}
class JKPostfixExpressionImpl(expression: JKExpression, override var operator: JKOperator) : JKPostfixExpression, JKBranchElementBase(),
PsiOwner by PsiOwnerImpl() {
override fun accept(visitor: JKVisitor) = visitor.visitPostfixExpression(this)
override var expression by child(expression)
}
class JKExpressionListImpl(expressions: List<JKExpression> = emptyList()) : JKExpressionList, JKBranchElementBase(),
PsiOwner by PsiOwnerImpl() {
constructor(vararg expresions: JKExpression) : this(expresions.asList())
override fun accept(visitor: JKVisitor) = visitor.visitExpressionList(this)
override var expressions by children(expressions)
}
class JKQualifiedExpressionImpl(
receiver: JKExpression,
override var operator: JKQualifier,
selector: JKExpression
) : JKQualifiedExpression, JKBranchElementBase(), PsiOwner by PsiOwnerImpl() {
override fun accept(visitor: JKVisitor) = visitor.visitQualifiedExpression(this)
override var receiver: JKExpression by child(receiver)
override var selector: JKExpression by child(selector)
}
class JKExpressionStatementImpl(expression: JKExpression) : JKExpressionStatement(), PsiOwner by PsiOwnerImpl() {
override fun accept(visitor: JKVisitor) = visitor.visitExpressionStatement(this)
override var expression: JKExpression by child(expression)
}
class JKDeclarationStatementImpl(declaredStatements: List<JKDeclaration>) : JKDeclarationStatement(),
PsiOwner by PsiOwnerImpl() {
override val declaredStatements by children(declaredStatements)
override fun accept(visitor: JKVisitor) = visitor.visitDeclarationStatement(this)
override var rightNonCodeElements: MutableList<JKNonCodeElement> = mutableListOf(JKSpaceElementImpl("\n"))
}
class JKArrayAccessExpressionImpl(
expression: JKExpression,
indexExpression: JKExpression
) : JKArrayAccessExpression, JKBranchElementBase(), PsiOwner by PsiOwnerImpl() {
override fun accept(visitor: JKVisitor) = visitor.visitArrayAccessExpression(this)
override var expression: JKExpression by child(expression)
override var indexExpression: JKExpression by child(indexExpression)
}
class JKParenthesizedExpressionImpl(expression: JKExpression) : JKParenthesizedExpression, JKBranchElementBase(),
PsiOwner by PsiOwnerImpl() {
override fun accept(visitor: JKVisitor) = visitor.visitParenthesizedExpression(this)
override var expression: JKExpression by child(expression)
}
class JKTypeCastExpressionImpl(expression: JKExpression, type: JKTypeElement) : JKTypeCastExpression, JKBranchElementBase(),
PsiOwner by PsiOwnerImpl() {
override fun accept(visitor: JKVisitor) = visitor.visitTypeCastExpression(this)
override var expression by child(expression)
override var type by child(type)
}
class JKTypeElementImpl(override var type: JKType) : JKTypeElement, JKElementBase(), PsiOwner by PsiOwnerImpl() {
override fun accept(visitor: JKVisitor) = visitor.visitTypeElement(this)
}
data class JKClassTypeImpl(
override val classReference: JKClassSymbol,
override val parameters: List<JKType> = emptyList(),
override val nullability: Nullability = Nullability.Default
) : JKClassType
object JKNoTypeImpl : JKNoType {
override val nullability: Nullability = Nullability.NotNull
}
object JKStarProjectionTypeImpl : JKStarProjectionType
val JKType.fqName: String?
get() = when (this) {
is JKClassType -> classReference.fqName
is JKJavaPrimitiveType -> jvmPrimitiveType.name
else -> null
}
class JKNullLiteral : JKLiteralExpression, JKElementBase(), PsiOwner by PsiOwnerImpl() {
override val literal: String
get() = "null"
override val type: LiteralType
get() = LiteralType.NULL
override fun accept(visitor: JKVisitor) = visitor.visitLiteralExpression(this)
}
class JKBooleanLiteral(val value: Boolean) : JKLiteralExpression, JKElementBase(), PsiOwner by PsiOwnerImpl() {
override val literal: String
get() = value.toString()
override val type: LiteralType
get() = LiteralType.BOOLEAN
override fun accept(visitor: JKVisitor) = visitor.visitLiteralExpression(this)
}
fun LiteralType.toJkType(typeFactory: JKTypeFactory): JKType = when (this) {
LiteralType.CHAR -> typeFactory.types.char
LiteralType.BOOLEAN -> typeFactory.types.boolean
LiteralType.INT -> typeFactory.types.int
LiteralType.LONG -> typeFactory.types.long
LiteralType.FLOAT -> typeFactory.types.float
LiteralType.DOUBLE -> typeFactory.types.double
LiteralType.NULL -> typeFactory.types.nullableAny
LiteralType.STRING -> typeFactory.types.string
}
class JKLocalVariableImpl(
type: JKTypeElement,
name: JKNameIdentifier,
initializer: JKExpression,
mutabilityElement: JKMutabilityModifierElement,
annotationList: JKAnnotationList = JKAnnotationListImpl()
) : JKLocalVariable(), PsiOwner by PsiOwnerImpl() {
override var initializer by child(initializer)
override var name by child(name)
override var type by child(type)
override var annotationList by child(annotationList)
override var mutabilityElement by child(mutabilityElement)
override fun accept(visitor: JKVisitor) = visitor.visitLocalVariable(this)
}
class JKStubExpressionImpl : JKStubExpression, JKElementBase(), PsiOwner by PsiOwnerImpl() {
override fun accept(visitor: JKVisitor) = visitor.visitStubExpression(this)
}
object JKBodyStubImpl : JKBodyStub() {
override val leftNonCodeElements: MutableList<JKNonCodeElement> = mutableListOf()
override val rightNonCodeElements: MutableList<JKNonCodeElement> = mutableListOf()
override fun copy(): JKTreeElement = this
override var statements: List<JKStatement>
get() = emptyList()
set(value) {}
override fun accept(visitor: JKVisitor) = visitor.visitBodyStub(this)
override fun acceptChildren(visitor: JKVisitor) {}
override var parent: JKElement?
get() = null
set(it) {}
override fun detach(from: JKElement) {
}
override fun attach(to: JKElement) {
}
}
class JKBlockStatementImpl(block: JKBlock) : JKBlockStatement(), PsiOwner by PsiOwnerImpl() {
override var block by child(block)
override fun accept(visitor: JKVisitor) = visitor.visitBlockStatement(this)
}
class JKBlockStatementWithoutBracketsImpl(statements: List<JKStatement>) : JKBlockStatementWithoutBrackets(),
PsiOwner by PsiOwnerImpl() {
override var statements by children(statements)
override fun accept(visitor: JKVisitor) = visitor.visitBlockStatementWithoutBrackets(this)
}
class JKThisExpressionImpl(qualifierLabel: JKLabel) : JKThisExpression, JKBranchElementBase(), PsiOwner by PsiOwnerImpl() {
override var qualifierLabel: JKLabel by child(qualifierLabel)
override fun accept(visitor: JKVisitor) = visitor.visitThisExpression(this)
}
class JKSuperExpressionImpl(qualifierLabel: JKLabel = JKLabelEmptyImpl()) : JKSuperExpression, JKBranchElementBase(),
PsiOwner by PsiOwnerImpl() {
override var qualifierLabel: JKLabel by child(qualifierLabel)
override fun accept(visitor: JKVisitor) = visitor.visitSuperExpression(this)
}
class JKWhileStatementImpl(condition: JKExpression, body: JKStatement) : JKWhileStatement(),
PsiOwner by PsiOwnerImpl() {
override var condition by child(condition)
override var body by child(body)
override fun accept(visitor: JKVisitor) = visitor.visitWhileStatement(this)
}
class JKDoWhileStatementImpl(body: JKStatement, condition: JKExpression) : JKDoWhileStatement(),
PsiOwner by PsiOwnerImpl() {
override var condition by child(condition)
override var body by child(body)
override fun accept(visitor: JKVisitor) = visitor.visitDoWhileStatement(this)
}
class JKBreakStatementImpl : JKBreakStatement(), PsiOwner by PsiOwnerImpl() {
override fun accept(visitor: JKVisitor) = visitor.visitBreakStatement(this)
}
class JKBreakWithLabelStatementImpl(override var label: JKNameIdentifier) : JKBreakWithLabelStatement(),
PsiOwner by PsiOwnerImpl() {
override fun accept(visitor: JKVisitor) = visitor.visitBreakWithLabelStatement(this)
}
class JKIfStatementImpl(condition: JKExpression, thenBranch: JKStatement) : JKIfStatement(),
PsiOwner by PsiOwnerImpl() {
override var thenBranch by child(thenBranch)
override var condition by child(condition)
override fun accept(visitor: JKVisitor) = visitor.visitIfStatement(this)
}
class JKIfElseStatementImpl(condition: JKExpression, thenBranch: JKStatement, elseBranch: JKStatement) : JKIfElseStatement(),
PsiOwner by PsiOwnerImpl() {
override var elseBranch by child(elseBranch)
override var thenBranch by child(thenBranch)
override var condition by child(condition)
override fun accept(visitor: JKVisitor) = visitor.visitIfElseStatement(this)
}
class JKIfElseExpressionImpl(condition: JKExpression, thenBranch: JKExpression, elseBranch: JKExpression) : JKIfElseExpression,
JKBranchElementBase(), PsiOwner by PsiOwnerImpl() {
override var elseBranch by child(elseBranch)
override var thenBranch by child(thenBranch)
override var condition by child(condition)
override fun accept(visitor: JKVisitor) = visitor.visitIfElseExpression(this)
}
class JKClassAccessExpressionImpl(override var identifier: JKClassSymbol) : JKClassAccessExpression, JKElementBase(),
PsiOwner by PsiOwnerImpl() {
override fun accept(visitor: JKVisitor) = visitor.visitClassAccessExpression(this)
}
class JKLambdaExpressionImpl(
statement: JKStatement,
parameters: List<JKParameter>,
functionalType: JKTypeElement = JKTypeElementImpl(JKNoTypeImpl),
returnType: JKTypeElement = JKTypeElementImpl(JKContextType)//TODO use function type
) : JKLambdaExpression, JKBranchElementBase(), PsiOwner by PsiOwnerImpl() {
override var statement by child(statement)
override val returnType by child(returnType)
override var parameters by children(parameters)
override var functionalType by child(functionalType)
override fun accept(visitor: JKVisitor) = visitor.visitLambdaExpression(this)
}
class JKInheritanceInfoImpl(
extends: List<JKTypeElement>,
implements: List<JKTypeElement>
) : JKInheritanceInfo, JKBranchElementBase(), PsiOwner by PsiOwnerImpl() {
override var extends: List<JKTypeElement> by children(extends)
override var implements: List<JKTypeElement> by children(implements)
override fun accept(visitor: JKVisitor) = visitor.visitInheritanceInfo(this)
}
class JKDelegationConstructorCallImpl(
override val identifier: JKMethodSymbol,
expression: JKExpression,
arguments: JKArgumentList
) : JKBranchElementBase(), JKDelegationConstructorCall, PsiOwner by PsiOwnerImpl() {
override var typeArgumentList: JKTypeArgumentList by child(JKTypeArgumentListImpl())
override val expression: JKExpression by child(expression)
override var arguments: JKArgumentList by child(arguments)
override fun accept(visitor: JKVisitor) = visitor.visitDelegationConstructorCall(this)
}
class JKFieldAccessExpressionImpl(override var identifier: JKFieldSymbol) : JKFieldAccessExpression, JKElementBase(),
PsiOwner by PsiOwnerImpl() {
override fun accept(visitor: JKVisitor) = visitor.visitFieldAccessExpression(this)
}
class JKPackageAccessExpressionImpl(override var identifier: JKPackageSymbol) : JKPackageAccessExpression, JKElementBase(),
PsiOwner by PsiOwnerImpl() {
override fun accept(visitor: JKVisitor) = visitor.visitPackageAccessExpression(this)
}
val JKStatement.statements: List<JKStatement>
get() =
when (this) {
is JKBlockStatement -> block.statements
else -> listOf(this)
}
class JKLabelEmptyImpl : JKLabelEmpty, JKElementBase(), PsiOwner by PsiOwnerImpl() {
override fun accept(visitor: JKVisitor) = visitor.visitLabelEmpty(this)
}
class JKLabelTextImpl(label: JKNameIdentifier) : JKLabelText, JKBranchElementBase(), PsiOwner by PsiOwnerImpl() {
override val label: JKNameIdentifier by child(label)
override fun accept(visitor: JKVisitor) = visitor.visitLabelText(this)
}
class JKContinueStatementImpl(label: JKLabel) : JKContinueStatement(), PsiOwner by PsiOwnerImpl() {
override var label: JKLabel by child(label)
override fun accept(visitor: JKVisitor) = visitor.visitContinueStatement(this)
}
class JKLabeledStatementImpl(statement: JKStatement, labels: List<JKNameIdentifier>) : JKLabeledStatement, JKBranchElementBase(),
PsiOwner by PsiOwnerImpl() {
override var statement: JKStatement by child(statement)
override val labels: List<JKNameIdentifier> by children(labels)
override fun accept(visitor: JKVisitor) = visitor.visitLabeledStatement(this)
}
class JKEmptyStatementImpl : JKEmptyStatement(), PsiOwner by PsiOwnerImpl() {
override fun accept(visitor: JKVisitor) = visitor.visitEmptyStatement(this)
}
class PsiOwnerImpl(override var psi: PsiElement? = null) : PsiOwner
val JKElement.psi: PsiElement?
get() = (this as? PsiOwner)?.psi
inline fun <reified Elem : PsiElement> JKElement.psi(): Elem? = (this as? PsiOwner)?.psi as? Elem
class JKTypeParameterListImpl(typeParameters: List<JKTypeParameter> = emptyList()) : JKTypeParameterList, JKBranchElementBase() {
override var typeParameters by children(typeParameters)
override fun accept(visitor: JKVisitor) = visitor.visitTypeParameterList(this)
}
class JKTypeParameterImpl(name: JKNameIdentifier, upperBounds: List<JKTypeElement>) : JKTypeParameter() {
override var name: JKNameIdentifier by child(name)
override var upperBounds: List<JKTypeElement> by children(upperBounds)
override fun accept(visitor: JKVisitor) = visitor.visitTypeParameter(this)
}
data class JKVarianceTypeParameterTypeImpl(
override val variance: JKVarianceTypeParameterType.Variance,
override val boundType: JKType
) : JKVarianceTypeParameterType
data class JKTypeParameterTypeImpl(
override val identifier: JKTypeParameterSymbol,
override val nullability: Nullability = Nullability.Default
) : JKTypeParameterType
data class JKCapturedType(
val wildcardType: JKWildCardType,
override val nullability: Nullability = Nullability.Default
) : JKType
class JKEnumConstantImpl(
name: JKNameIdentifier,
arguments: JKArgumentList,
body: JKClassBody,
type: JKTypeElement,
annotationList: JKAnnotationList = JKAnnotationListImpl()
) : JKEnumConstant(), PsiOwner by PsiOwnerImpl() {
override var name: JKNameIdentifier by child(name)
override val arguments: JKArgumentList by child(arguments)
override val body: JKClassBody by child(body)
override var type: JKTypeElement by child(type)
override var initializer: JKExpression by child(JKStubExpressionImpl())
override var annotationList by child(annotationList)
override fun accept(visitor: JKVisitor) = visitor.visitEnumConstant(this)
}
fun JKTypeElement.present(): Boolean =
type != JKNoTypeImpl
class JKForInStatementImpl(declaration: JKDeclaration, iterationExpression: JKExpression, body: JKStatement) :
JKForInStatement(), PsiOwner by PsiOwnerImpl() {
override var declaration: JKDeclaration by child(declaration)
override var iterationExpression: JKExpression by child(iterationExpression)
override var body: JKStatement by child(body)
override fun accept(visitor: JKVisitor) = visitor.visitForInStatement(this)
}
fun JKStatement.isEmpty(): Boolean =
when (this) {
is JKEmptyStatement -> true
is JKBlockStatement -> block is JKBodyStubImpl
is JKExpressionStatement -> expression is JKStubExpression
else -> false
}
class JKPackageDeclarationImpl(name: JKNameIdentifier) : JKPackageDeclaration() {
override var name: JKNameIdentifier by child(name)
override fun accept(visitor: JKVisitor) = visitor.visitPackageDeclaration(this)
}
class JKAnnotationListImpl(annotations: List<JKAnnotation> = emptyList()) : JKAnnotationList, JKBranchElementBase() {
override var annotations: List<JKAnnotation> by children(annotations)
override fun accept(visitor: JKVisitor) = visitor.visitAnnotationList(this)
}
class JKAnnotationImpl(
override var classSymbol: JKClassSymbol,
arguments: List<JKAnnotationParameter> = emptyList()
) : JKAnnotation, JKBranchElementBase() {
override var arguments: List<JKAnnotationParameter> by children(arguments)
override fun accept(visitor: JKVisitor) = visitor.visitAnnotation(this)
override var rightNonCodeElements: MutableList<JKNonCodeElement> = mutableListOf(JKSpaceElementImpl("\n"))
}
class JKTypeArgumentListImpl(typeArguments: List<JKTypeElement> = emptyList()) : JKTypeArgumentList, JKBranchElementBase(),
PsiOwner by PsiOwnerImpl() {
override var typeArguments: List<JKTypeElement> by children(typeArguments)
override fun accept(visitor: JKVisitor) = visitor.visitTypeArgumentList(this)
}
class JKClassLiteralExpressionImpl(
classType: JKTypeElement,
override var literalType: JKClassLiteralExpression.LiteralType
) : JKClassLiteralExpression, JKBranchElementBase(), PsiOwner by PsiOwnerImpl() {
override val classType: JKTypeElement by child(classType)
override fun accept(visitor: JKVisitor) = visitor.visitClassLiteralExpression(this)
}
class JKImportStatementImpl(name: JKNameIdentifier) : JKImportStatement, JKBranchElementBase() {
override val name: JKNameIdentifier by child(name)
override fun accept(visitor: JKVisitor) = visitor.visitImportStatement(this)
override var rightNonCodeElements: MutableList<JKNonCodeElement> = mutableListOf(JKSpaceElementImpl("\n"))
}
class JKImportListImpl(imports: List<JKImportStatement>) : JKImportList, JKBranchElementBase() {
override var imports by children(imports)
override fun accept(visitor: JKVisitor) = visitor.visitImportList(this)
}
class JKAnnotationParameterImpl(value: JKAnnotationMemberValue) : JKAnnotationParameter, JKBranchElementBase() {
override var value: JKAnnotationMemberValue by child(value)
override fun accept(visitor: JKVisitor) = visitor.visitAnnotationParameter(this)
}
class JKAnnotationNameParameterImpl(
value: JKAnnotationMemberValue,
name: JKNameIdentifier
) : JKAnnotationNameParameter, JKBranchElementBase() {
override var value: JKAnnotationMemberValue by child(value)
override val name: JKNameIdentifier by child(name)
override fun accept(visitor: JKVisitor) = visitor.visitAnnotationNameParameter(this)
}
class JKNamedArgumentImpl(
value: JKExpression,
name: JKNameIdentifier
) : JKNamedArgument, JKBranchElementBase() {
override var value by child(value)
override val name by child(name)
override fun accept(visitor: JKVisitor) = visitor.visitNamedArgument(this)
}
class JKArgumentImpl(value: JKExpression) : JKArgument, JKBranchElementBase() {
override var value by child(value)
override fun accept(visitor: JKVisitor) = visitor.visitArgument(this)
}
class JKArgumentListImpl(arguments: List<JKArgument> = emptyList()) : JKArgumentList, JKBranchElementBase() {
constructor(vararg arguments: JKArgument) : this(arguments.toList())
constructor(vararg values: JKExpression) : this(values.map { JKArgumentImpl(it) })
override var arguments by children(arguments)
override fun accept(visitor: JKVisitor) = visitor.visitArgumentList(this)
}
class JKMutabilityModifierElementImpl(override var mutability: Mutability) : JKMutabilityModifierElement() {
override fun accept(visitor: JKVisitor) = visitor.visitMutabilityModifierElement(this)
}
class JKModalityModifierElementImpl(override var modality: Modality) : JKModalityModifierElement() {
override fun accept(visitor: JKVisitor) = visitor.visitModalityModifierElement(this)
}
class JKVisibilityModifierElementImpl(override var visibility: Visibility) : JKVisibilityModifierElement() {
override fun accept(visitor: JKVisitor) = visitor.visitVisibilityModifierElement(this)
}
class JKOtherModifierElementImpl(override var otherModifier: OtherModifier) : JKOtherModifierElement() {
override fun accept(visitor: JKVisitor) = visitor.visitOtherModifierElement(this)
}
class JKMethodReferenceExpressionImpl(
qualifier: JKExpression,
override val identifier: JKSymbol,
functionalType: JKTypeElement,
override val isConstructorCall: Boolean
) : JKMethodReferenceExpression, JKBranchElementBase(), PsiOwner by PsiOwnerImpl() {
override val qualifier by child(qualifier)
override val functionalType by child(functionalType)
override fun accept(visitor: JKVisitor) = visitor.visitMethodReferenceExpression(this)
}
@@ -1,327 +0,0 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.nj2k.tree.impl
import com.intellij.psi.JavaTokenType
import com.intellij.psi.impl.source.tree.ElementType.OPERATION_BIT_SET
import com.intellij.psi.tree.IElementType
import org.jetbrains.kotlin.j2k.ast.Nullability
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.nj2k.symbols.JKClassSymbol
import org.jetbrains.kotlin.nj2k.symbols.JKMethodSymbol
import org.jetbrains.kotlin.nj2k.tree.*
import org.jetbrains.kotlin.nj2k.tree.JKLiteralExpression.LiteralType.*
import org.jetbrains.kotlin.nj2k.tree.visitors.JKVisitor
import org.jetbrains.kotlin.nj2k.types.JKJavaArrayType
import org.jetbrains.kotlin.nj2k.types.JKJavaDisjunctionType
import org.jetbrains.kotlin.nj2k.types.JKJavaPrimitiveType
import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType
class JKJavaFieldImpl(
type: JKTypeElement,
name: JKNameIdentifier,
initializer: JKExpression,
annotationList: JKAnnotationList,
otherModifierElements: List<JKOtherModifierElement>,
visibilityElement: JKVisibilityModifierElement,
modalityElement: JKModalityModifierElement,
mutabilityElement: JKMutabilityModifierElement
) : JKJavaField(), PsiOwner by PsiOwnerImpl() {
override fun accept(visitor: JKVisitor) = visitor.visitJavaField(this)
override var annotationList: JKAnnotationList by child(annotationList)
override var initializer: JKExpression by child(initializer)
override var type by child(type)
override var name: JKNameIdentifier by child(name)
override var otherModifierElements by children(otherModifierElements)
override var visibilityElement by child(visibilityElement)
override var modalityElement by child(modalityElement)
override var mutabilityElement by child(mutabilityElement)
}
class JKJavaMethodImpl(
returnType: JKTypeElement,
name: JKNameIdentifier,
parameters: List<JKParameter>,
block: JKBlock,
typeParameterList: JKTypeParameterList,
annotationList: JKAnnotationList,
throwsList: List<JKTypeElement>,
otherModifierElements: List<JKOtherModifierElement>,
visibilityElement: JKVisibilityModifierElement,
modalityElement: JKModalityModifierElement
) : JKJavaMethod(), PsiOwner by PsiOwnerImpl() {
override fun accept(visitor: JKVisitor) = visitor.visitJavaMethod(this)
override var returnType: JKTypeElement by child(returnType)
override var name: JKNameIdentifier by child(name)
override var parameters: List<JKParameter> by children(parameters)
override var block: JKBlock by child(block)
override var typeParameterList: JKTypeParameterList by child(typeParameterList)
override var annotationList: JKAnnotationList by child(annotationList)
override var throwsList: List<JKTypeElement> by children(throwsList)
override var otherModifierElements by children(otherModifierElements)
override var visibilityElement by child(visibilityElement)
override var modalityElement by child(modalityElement)
}
class JKJavaLiteralExpressionImpl(
override val literal: String,
override val type: JKLiteralExpression.LiteralType
) : JKJavaLiteralExpression, JKElementBase(), PsiOwner by PsiOwnerImpl() {
override fun accept(visitor: JKVisitor) = visitor.visitJavaLiteralExpression(this)
init {
require(type in setOf(STRING, CHAR, INT, LONG, FLOAT, DOUBLE))
}
}
class JKJavaOperatorToken(val psiToken: IElementType) : JKOperatorToken {
override val text: String
get() = error("Java token should not be printed, it should be replaces with corresponding Kotlin one")
}
sealed class JKJavaQualifierImpl : JKQualifier {
object DOT : JKJavaQualifierImpl()
}
class JKJavaMethodCallExpressionImpl(
override var identifier: JKMethodSymbol,
arguments: JKArgumentList,
typeArgumentList: JKTypeArgumentList = JKTypeArgumentListImpl()
) : JKJavaMethodCallExpression, JKBranchElementBase(), PsiOwner by PsiOwnerImpl() {
override fun accept(visitor: JKVisitor) = visitor.visitJavaMethodCallExpression(this)
override var arguments: JKArgumentList by child(arguments)
override var typeArgumentList: JKTypeArgumentList by child(typeArgumentList)
}
class JKClassBodyImpl(declarations: List<JKDeclaration> = emptyList()) : JKClassBody() {
override var declarations: List<JKDeclaration> by children(declarations)
override fun accept(visitor: JKVisitor) = visitor.visitClassBody(this)
}
class JKEmptyClassBodyImpl : JKEmptyClassBody() {
override var declarations: List<JKDeclaration> by children(emptyList())
override fun accept(visitor: JKVisitor) = visitor.visitEmptyClassBody(this)
}
class JKJavaNewExpressionImpl(
override var classSymbol: JKClassSymbol,
arguments: JKArgumentList,
typeArgumentList: JKTypeArgumentList,
classBody: JKClassBody = JKEmptyClassBodyImpl()
) : JKJavaNewExpression, JKBranchElementBase(), PsiOwner by PsiOwnerImpl() {
override var arguments: JKArgumentList by child(arguments)
override var typeArgumentList: JKTypeArgumentList by child(typeArgumentList)
override var classBody: JKClassBody by child(classBody)
override fun accept(visitor: JKVisitor) = visitor.visitJavaNewExpression(this)
}
class JKJavaNewEmptyArrayImpl(initializer: List<JKExpression>, type: JKTypeElement) : JKJavaNewEmptyArray, JKBranchElementBase(),
PsiOwner by PsiOwnerImpl() {
override val type by child(type)
override var initializer by children(initializer)
override fun accept(visitor: JKVisitor) = visitor.visitJavaNewEmptyArray(this)
}
class JKJavaNewArrayImpl(initializer: List<JKExpression>, type: JKTypeElement) : JKJavaNewArray, JKBranchElementBase(),
PsiOwner by PsiOwnerImpl() {
override val type by child(type)
override var initializer by children(initializer)
override fun accept(visitor: JKVisitor) = visitor.visitJavaNewArray(this)
}
class JKJavaPrimitiveTypeImpl(override val jvmPrimitiveType: JvmPrimitiveType) : JKJavaPrimitiveType {
companion object {
val BOOLEAN = JKJavaPrimitiveTypeImpl(JvmPrimitiveType.BOOLEAN)
val CHAR = JKJavaPrimitiveTypeImpl(JvmPrimitiveType.CHAR)
val BYTE = JKJavaPrimitiveTypeImpl(JvmPrimitiveType.BYTE)
val SHORT = JKJavaPrimitiveTypeImpl(JvmPrimitiveType.SHORT)
val INT = JKJavaPrimitiveTypeImpl(JvmPrimitiveType.INT)
val FLOAT = JKJavaPrimitiveTypeImpl(JvmPrimitiveType.FLOAT)
val LONG = JKJavaPrimitiveTypeImpl(JvmPrimitiveType.LONG)
val DOUBLE = JKJavaPrimitiveTypeImpl(JvmPrimitiveType.DOUBLE)
val KEYWORD_TO_INSTANCE = listOf(
BOOLEAN, CHAR, BYTE, SHORT, INT, FLOAT, LONG, DOUBLE
).associate {
it.jvmPrimitiveType.javaKeywordName to it
} + ("void" to JKJavaVoidType)
}
}
object JKJavaVoidType : JKType {
override var nullability: Nullability
get() = Nullability.NotNull
set(it) {}
}
data class JKJavaArrayTypeImpl(override val type: JKType, override var nullability: Nullability = Nullability.Default) :
JKJavaArrayType {
}
class JKJavaDisjunctionTypeImpl(
override val disjunctions: List<JKType>,
override val nullability: Nullability = Nullability.Default
) : JKJavaDisjunctionType
class JKReturnStatementImpl(
expression: JKExpression,
label: JKLabel = JKLabelEmptyImpl()
) : JKReturnStatement(), PsiOwner by PsiOwnerImpl() {
override fun accept(visitor: JKVisitor) = visitor.visitReturnStatement(this)
override val expression by child(expression)
override var label by child(label)
}
class JKJavaAssertStatementImpl(condition: JKExpression, description: JKExpression) : JKJavaAssertStatement(),
PsiOwner by PsiOwnerImpl() {
override val description by child(description)
override val condition by child(condition)
override fun accept(visitor: JKVisitor) = visitor.visitJavaAssertStatement(this)
}
class JKJavaForLoopStatementImpl(initializer: JKStatement, condition: JKExpression, updaters: List<JKStatement>, body: JKStatement) :
JKJavaForLoopStatement(), PsiOwner by PsiOwnerImpl() {
override var body by child(body)
override var updaters by children(updaters)
override var condition by child(condition)
override var initializer by child(initializer)
override fun accept(visitor: JKVisitor) = visitor.visitJavaForLoopStatement(this)
}
class JKJavaPolyadicExpressionImpl(operands: List<JKExpression>, override var tokens: List<JKOperator>) : JKJavaPolyadicExpression,
JKBranchElementBase(), PsiOwner by PsiOwnerImpl() {
override var operands by children(operands)
override fun getTokenBeforeOperand(operand: JKExpression): JKOperator? {
val index = operands.indexOf(operand)
return if (index < 1 || index > tokens.size) null else tokens[index - 1]
}
override fun accept(visitor: JKVisitor) = visitor.visitJavaPolyadicExpression(this)
}
class JKJavaAssignmentExpressionImpl(
field: JKExpression,
expression: JKExpression,
override var operator: JKOperator
) : JKBranchElementBase(), JKJavaAssignmentExpression, PsiOwner by PsiOwnerImpl() {
override fun accept(visitor: JKVisitor) = visitor.visitJavaAssignmentExpression(this)
override var field by child(field)
override var expression by child(expression)
}
class JKJavaSwitchStatementImpl(
expression: JKExpression,
cases: List<JKJavaSwitchCase>
) : JKJavaSwitchStatement(), PsiOwner by PsiOwnerImpl() {
override var expression: JKExpression by child(expression)
override var cases: List<JKJavaSwitchCase> by children(cases)
override fun accept(visitor: JKVisitor) = visitor.visitJavaSwitchStatement(this)
}
class JKJavaDefaultSwitchCaseImpl(statements: List<JKStatement>) : JKJavaDefaultSwitchCase, JKBranchElementBase(),
PsiOwner by PsiOwnerImpl() {
override var statements: List<JKStatement> by children(statements)
override fun accept(visitor: JKVisitor) = visitor.visitJavaDefaultSwitchCase(this)
}
class JKJavaLabelSwitchCaseImpl(
label: JKExpression,
statements: List<JKStatement>
) : JKJavaLabelSwitchCase, JKBranchElementBase(), PsiOwner by PsiOwnerImpl() {
override var statements: List<JKStatement> by children(statements)
override var label: JKExpression by child(label)
override fun accept(visitor: JKVisitor) = visitor.visitJavaLabelSwitchCase(this)
}
class JKJavaThrowStatementImpl(exception: JKExpression) : JKJavaThrowStatement(), PsiOwner by PsiOwnerImpl() {
override var exception: JKExpression by child(exception)
override fun accept(visitor: JKVisitor) = visitor.visitJavaThrowStatement(this)
}
class JKJavaTryStatementImpl(
resourceDeclarations: List<JKDeclaration>,
tryBlock: JKBlock,
finallyBlock: JKBlock,
catchSections: List<JKJavaTryCatchSection>
) : JKJavaTryStatement(), PsiOwner by PsiOwnerImpl() {
override var resourceDeclarations: List<JKDeclaration> by children(resourceDeclarations)
override var tryBlock: JKBlock by child(tryBlock)
override var finallyBlock: JKBlock by child(finallyBlock)
override var catchSections: List<JKJavaTryCatchSection> by children(catchSections)
override fun accept(visitor: JKVisitor) = visitor.visitJavaTryStatement(this)
}
class JKJavaTryCatchSectionImpl(
parameter: JKParameter,
block: JKBlock
) : JKJavaTryCatchSection, JKBranchElementBase(), PsiOwner by PsiOwnerImpl() {
override var parameter: JKParameter by child(parameter)
override var block: JKBlock by child(block)
override fun accept(visitor: JKVisitor) = visitor.visitJavaTryCatchSection(this)
}
class JKJavaSynchronizedStatementImpl(
lockExpression: JKExpression,
body: JKBlock
) : JKJavaSynchronizedStatement(), PsiOwner by PsiOwnerImpl() {
override val lockExpression: JKExpression by child(lockExpression)
override val body: JKBlock by child(body)
override fun accept(visitor: JKVisitor) = visitor.visitJavaSynchronizedStatement(this)
}
class JKJavaAnnotationMethodImpl(
returnType: JKTypeElement,
name: JKNameIdentifier,
defaultValue: JKAnnotationMemberValue
) : JKJavaAnnotationMethod(), PsiOwner by PsiOwnerImpl() {
override var returnType: JKTypeElement by child(returnType)
override var name: JKNameIdentifier by child(name)
override var parameters: List<JKParameter> by children()
override var defaultValue: JKAnnotationMemberValue by child(defaultValue)
override var block: JKBlock by child(JKBodyStubImpl)
override var typeParameterList: JKTypeParameterList by child(JKTypeParameterListImpl())
override var annotationList: JKAnnotationList by child(JKAnnotationListImpl())
override fun accept(visitor: JKVisitor) = visitor.visitJavaAnnotationMethod(this)
}
class JKKtAnnotationArrayInitializerExpressionImpl(initializers: List<JKAnnotationMemberValue>) : JKKtAnnotationArrayInitializerExpression,
JKBranchElementBase() {
constructor(vararg initializers: JKAnnotationMemberValue) : this(initializers.toList())
override val initializers: List<JKAnnotationMemberValue> by children(initializers)
override fun accept(visitor: JKVisitor) = visitor.visitKtAnnotationArrayInitializerExpression(this)
}
class JKJavaStaticInitDeclarationImpl(block: JKBlock) : JKJavaStaticInitDeclaration() {
override var block: JKBlock by child(block)
override var name: JKNameIdentifier by child(JKNameIdentifierImpl("<init>"))
override fun accept(visitor: JKVisitor) = visitor.visitJavaStaticInitDeclaration(this)
}
@@ -1,312 +0,0 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.nj2k.tree.impl
import org.jetbrains.kotlin.j2k.ast.Nullability
import org.jetbrains.kotlin.lexer.KtSingleValueToken
import org.jetbrains.kotlin.nj2k.symbols.JKMethodSymbol
import org.jetbrains.kotlin.nj2k.tree.*
import org.jetbrains.kotlin.nj2k.tree.visitors.JKVisitor
class JKKtPropertyImpl(
type: JKTypeElement,
name: JKNameIdentifier,
initializer: JKExpression,
getter: JKKtGetterOrSetter,
setter: JKKtGetterOrSetter,
annotationList: JKAnnotationList,
otherModifierElements: List<JKOtherModifierElement>,
visibilityElement: JKVisibilityModifierElement,
modalityElement: JKModalityModifierElement,
mutabilityElement: JKMutabilityModifierElement
) : JKKtProperty(), PsiOwner by PsiOwnerImpl() {
override fun accept(visitor: JKVisitor) = visitor.visitKtProperty(this)
override var annotationList: JKAnnotationList by child(annotationList)
override var type by child(type)
override var name: JKNameIdentifier by child(name)
override var initializer: JKExpression by child(initializer)
override var getter: JKKtGetterOrSetter by child(getter)
override var setter: JKKtGetterOrSetter by child(setter)
override var otherModifierElements by children(otherModifierElements)
override var visibilityElement by child(visibilityElement)
override var modalityElement by child(modalityElement)
override var mutabilityElement by child(mutabilityElement)
override var rightNonCodeElements: MutableList<JKNonCodeElement> = mutableListOf(JKSpaceElementImpl("\n"))
}
class JKKtFunctionImpl(
returnType: JKTypeElement,
name: JKNameIdentifier,
parameters: List<JKParameter>,
block: JKBlock,
typeParameterList: JKTypeParameterList,
annotationList: JKAnnotationList,
otherModifierElements: List<JKOtherModifierElement>,
visibilityElement: JKVisibilityModifierElement,
modalityElement: JKModalityModifierElement
) : JKKtFunction(), PsiOwner by PsiOwnerImpl() {
override fun accept(visitor: JKVisitor) = visitor.visitKtFunction(this)
override var returnType: JKTypeElement by child(returnType)
override var name: JKNameIdentifier by child(name)
override var parameters: List<JKParameter> by children(parameters)
override var block: JKBlock by child(block)
override var typeParameterList: JKTypeParameterList by child(typeParameterList)
override var annotationList: JKAnnotationList by child(annotationList)
override var otherModifierElements by children(otherModifierElements)
override var visibilityElement by child(visibilityElement)
override var modalityElement by child(modalityElement)
}
sealed class JKKtQualifierImpl : JKQualifier, JKElementBase() {
object DOT : JKKtQualifierImpl()
object SAFE : JKKtQualifierImpl()
}
class JKKtCallExpressionImpl(
override val identifier: JKMethodSymbol,
arguments: JKArgumentList,
typeArgumentList: JKTypeArgumentList = JKTypeArgumentListImpl()
) : JKKtMethodCallExpression, JKBranchElementBase() {
override fun accept(visitor: JKVisitor) = visitor.visitKtMethodCallExpression(this)
override var arguments: JKArgumentList by child(arguments)
override var typeArgumentList: JKTypeArgumentList by child(typeArgumentList)
}
class JKKtLiteralExpressionImpl(
override val literal: String,
override val type: JKLiteralExpression.LiteralType
) : JKKtLiteralExpression,
JKElementBase() {
override fun accept(visitor: JKVisitor) = visitor.visitKtLiteralExpression(this)
}
class JKKtSingleValueOperatorToken(val psiToken: KtSingleValueToken) : JKKtOperatorToken {
override val text: String = psiToken.value
}
object JKKtSpreadOperatorToken : JKKtOperatorToken {
override val text: String = "*"
}
class JKKtSpreadOperator(override val returnType: JKType) : JKOperator {
override val token: JKOperatorToken = JKKtSpreadOperatorToken
}
class JKKtWordOperatorToken(override val text: String) : JKKtOperatorToken
class JKKtOperatorImpl(override val token: JKOperatorToken, override val returnType: JKType) : JKOperator
class JKAssignmentChainAlsoLinkImpl(
receiver: JKExpression,
assignmentStatement: JKKtAssignmentStatement,
field: JKExpression
) : JKAssignmentChainAlsoLink, JKBranchElementBase() {
override val receiver by child(receiver)
override val assignmentStatement by child(assignmentStatement)
override val field by child(field)
override fun accept(visitor: JKVisitor) = visitor.visitAssignmentChainAlsoLink(this)
}
class JKAssignmentChainLetLinkImpl(
receiver: JKExpression,
assignmentStatement: JKKtAssignmentStatement,
field: JKExpression
) : JKAssignmentChainLetLink, JKBranchElementBase() {
override val receiver by child(receiver)
override val assignmentStatement by child(assignmentStatement)
override val field by child(field)
override fun accept(visitor: JKVisitor) = visitor.visitAssignmentChainLetLink(this)
}
class JKKtAssignmentStatementImpl(
field: JKExpression,
expression: JKExpression,
override var token: JKOperatorToken
) : JKKtAssignmentStatement() {
override var field: JKExpression by child(field)
override var expression by child(expression)
override fun accept(visitor: JKVisitor) = visitor.visitKtAssignmentStatement(this)
override var rightNonCodeElements: MutableList<JKNonCodeElement> = mutableListOf(JKSpaceElementImpl("\n"))
}
object JKContextType : JKType {
override val nullability: Nullability
get() = Nullability.Default
}
class JKKtConstructorImpl(
name: JKNameIdentifier,
parameters: List<JKParameter>,
block: JKBlock,
delegationCall: JKExpression,
annotationList: JKAnnotationList,
otherModifierElements: List<JKOtherModifierElement>,
visibilityElement: JKVisibilityModifierElement,
modalityElement: JKModalityModifierElement
) : JKKtConstructor() {
override var returnType: JKTypeElement by child(JKTypeElementImpl(JKNoTypeImpl))
override var name: JKNameIdentifier by child(name)
override var parameters: List<JKParameter> by children(parameters)
override var block: JKBlock by child(block)
override var delegationCall: JKExpression by child(delegationCall)
override var typeParameterList: JKTypeParameterList by child(JKTypeParameterListImpl())
override var annotationList: JKAnnotationList by child(annotationList)
override var otherModifierElements by children(otherModifierElements)
override var visibilityElement by child(visibilityElement)
override var modalityElement by child(modalityElement)
override fun accept(visitor: JKVisitor) = visitor.visitKtConstructor(this)
}
class JKKtPrimaryConstructorImpl(
name: JKNameIdentifier,//TODO not needed
parameters: List<JKParameter>,
delegationCall: JKExpression,
annotationList: JKAnnotationList,
otherModifierElements: List<JKOtherModifierElement>,
visibilityElement: JKVisibilityModifierElement,
modalityElement: JKModalityModifierElement
) : JKKtPrimaryConstructor() {
override var returnType: JKTypeElement by child(JKTypeElementImpl(JKNoTypeImpl))
override var name: JKNameIdentifier by child(name)
override var parameters: List<JKParameter> by children(parameters)
override var block: JKBlock by child(JKBodyStubImpl)
override var delegationCall: JKExpression by child(delegationCall)
override var typeParameterList: JKTypeParameterList by child(JKTypeParameterListImpl())
override var annotationList: JKAnnotationList by child(annotationList)
override var otherModifierElements by children(otherModifierElements)
override var visibilityElement by child(visibilityElement)
override var modalityElement by child(modalityElement)
override fun accept(visitor: JKVisitor) = visitor.visitKtPrimaryConstructor(this)
}
class JKKtWhenStatementImpl(
expression: JKExpression,
cases: List<JKKtWhenCase>
) : JKKtWhenStatement() {
override var expression: JKExpression by child(expression)
override var cases: List<JKKtWhenCase> by children(cases)
override fun accept(visitor: JKVisitor) = visitor.visitKtWhenStatement(this)
}
class JKKtWhenCaseImpl(labels: List<JKKtWhenLabel>, statement: JKStatement) : JKKtWhenCase, JKBranchElementBase() {
override var labels: List<JKKtWhenLabel> by children(labels)
override var statement: JKStatement by child(statement)
override fun accept(visitor: JKVisitor) = visitor.visitKtWhenCase(this)
}
class JKKtElseWhenLabelImpl : JKKtElseWhenLabel, JKElementBase() {
override fun accept(visitor: JKVisitor) = visitor.visitKtElseWhenLabel(this)
}
class JKKtValueWhenLabelImpl(expression: JKExpression) : JKKtValueWhenLabel, JKBranchElementBase() {
override var expression: JKExpression by child(expression)
override fun accept(visitor: JKVisitor) = visitor.visitKtValueWhenLabel(this)
}
class JKKtIsExpressionImpl(expression: JKExpression, type: JKTypeElement) : JKKtIsExpression, JKBranchElementBase(),
PsiOwner by PsiOwnerImpl() {
override var type by child(type)
override var expression by child(expression)
override fun accept(visitor: JKVisitor) = visitor.visitKtIsExpression(this)
}
class JKKtInitDeclarationImpl(block: JKBlock) : JKKtInitDeclaration() {
override var block: JKBlock by child(block)
override val name: JKNameIdentifier by child(JKNameIdentifierImpl("<name>"))
override fun accept(visitor: JKVisitor) = visitor.visitKtInitDeclaration(this)
}
class JKKtConvertedFromForLoopSyntheticWhileStatementImpl(
variableDeclaration: JKStatement,
whileStatement: JKWhileStatement
) : JKKtConvertedFromForLoopSyntheticWhileStatement(), PsiOwner by PsiOwnerImpl() {
override var variableDeclaration: JKStatement by child(variableDeclaration)
override var whileStatement: JKWhileStatement by child(whileStatement)
override fun accept(visitor: JKVisitor) =
visitor.visitKtConvertedFromForLoopSyntheticWhileStatement(this)
}
class JKKtThrowExpressionImpl(exception: JKExpression) : JKKtThrowExpression, JKBranchElementBase() {
override var exception: JKExpression by child(exception)
override fun accept(visitor: JKVisitor) = visitor.visitKtThrowExpression(this)
}
class JKKtTryExpressionImpl(
tryBlock: JKBlock,
finallyBlock: JKBlock,
catchSections: List<JKKtTryCatchSection>
) : JKKtTryExpression, JKBranchElementBase() {
override var tryBlock: JKBlock by child(tryBlock)
override var finallyBlock: JKBlock by child(finallyBlock)
override var catchSections: List<JKKtTryCatchSection> by children(catchSections)
override fun accept(visitor: JKVisitor) = visitor.visitKtTryExpression(this)
}
class JKKtTryCatchSectionImpl(
parameter: JKParameter,
block: JKBlock
) : JKKtTryCatchSection, JKBranchElementBase() {
override var parameter: JKParameter by child(parameter)
override var block: JKBlock by child(block)
override fun accept(visitor: JKVisitor) = visitor.visitKtTryCatchSection(this)
}
class JKKtGetterOrSetterImpl(
body: JKStatement,
override val kind: JKKtGetterOrSetter.Kind,
visibilityElement: JKVisibilityModifierElement
) : JKKtGetterOrSetter, JKBranchElementBase() {
override var body: JKStatement by child(body)
override var visibilityElement by child(visibilityElement)
override fun accept(visitor: JKVisitor) = visitor.visitKtGetterOrSetter(this)
}
class JKKtEmptyGetterOrSetterImpl : JKKtEmptyGetterOrSetter, JKBranchElementBase() {
override var body: JKStatement by child(JKEmptyStatementImpl())
override val kind: JKKtGetterOrSetter.Kind
get() = error("Cannot get kind of JKKtEmptyGetterOrSetter")
override var visibilityElement by child(JKVisibilityModifierElementImpl(Visibility.PUBLIC))
override fun accept(visitor: JKVisitor) = visitor.visitKtEmptyGetterOrSetter(this)
}
class JKKtItExpressionImpl(override val type: JKType) : JKKtItExpression, JKBranchElementBase() {
override fun accept(visitor: JKVisitor) = visitor.visitKtItExpression(this)
}
@@ -1,22 +0,0 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.nj2k.tree.impl
import org.jetbrains.kotlin.nj2k.tree.JKCommentElement
import org.jetbrains.kotlin.nj2k.tree.JKNonCodeElement
import org.jetbrains.kotlin.nj2k.tree.JKSpaceElement
import org.jetbrains.kotlin.nj2k.tree.JKTokenElement
import org.jetbrains.kotlin.utils.SmartList
class JKSpaceElementImpl(override val text: String) : JKSpaceElement
class JKCommentElementImpl(override val text: String) : JKCommentElement
class JKTokenElementImpl(override val text: String) : JKTokenElement {
override val leftNonCodeElements: MutableList<JKNonCodeElement> = SmartList()
override val rightNonCodeElements: MutableList<JKNonCodeElement> = SmartList()
}
@@ -1,519 +0,0 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.nj2k.tree
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.nj2k.symbols.*
import org.jetbrains.kotlin.nj2k.tree.impl.JKBranchElementBase
import org.jetbrains.kotlin.nj2k.tree.impl.JKSpaceElementImpl
import org.jetbrains.kotlin.nj2k.tree.impl.JKTokenElementImpl
import org.jetbrains.kotlin.nj2k.tree.visitors.JKVisitor
interface JKTreeElement : JKElement, JKNonCodeElementsListOwner {
fun accept(visitor: JKVisitor)
fun acceptChildren(visitor: JKVisitor)
fun copy(): JKTreeElement
}
interface JKTreeRoot : JKTreeElement {
var element: JKTreeElement
}
interface PsiOwner {
var psi: PsiElement?
}
abstract class JKDeclaration : JKTreeElement, JKBranchElementBase() {
override val rightNonCodeElements = mutableListOf<JKNonCodeElement>(JKSpaceElementImpl("\n"))
abstract val name: JKNameIdentifier
}
interface JKImportStatement : JKTreeElement {
val name: JKNameIdentifier
}
interface JKImportList : JKTreeElement {
var imports: List<JKImportStatement>
}
interface JKFile : JKTreeElement, JKBranchElement {
var packageDeclaration: JKPackageDeclaration
var importList: JKImportList
var declarationList: List<JKDeclaration>
}
abstract class JKClass : JKDeclaration(), JKVisibilityOwner, JKOtherModifiersOwner, JKModalityOwner, JKTypeParameterListOwner,
JKAnnotationListOwner,
JKBranchElement {
abstract val inheritance: JKInheritanceInfo
abstract var classBody: JKClassBody
abstract var classKind: ClassKind
enum class ClassKind {
ANNOTATION, CLASS, ENUM, INTERFACE, OBJECT, COMPANION
}
}
fun JKClass.isLocalClass(): Boolean =
parent !is JKClassBody && parent !is JKFile
val JKClass.declarationList: List<JKDeclaration>
get() = classBody.declarations
interface JKInheritanceInfo : JKTreeElement, JKBranchElement {
var extends: List<JKTypeElement>
var implements: List<JKTypeElement>
}
fun JKInheritanceInfo.present(): Boolean =
extends.isNotEmpty() || implements.isNotEmpty()
interface JKAnnotationList : JKTreeElement {
var annotations: List<JKAnnotation>
}
interface JKAnnotation : JKAnnotationMemberValue {
var classSymbol: JKClassSymbol
var arguments: List<JKAnnotationParameter>
}
interface JKAnnotationParameter : JKTreeElement {
var value: JKAnnotationMemberValue
}
interface JKAnnotationNameParameter : JKAnnotationParameter {
val name: JKNameIdentifier
}
interface JKAnnotationListOwner : JKTreeElement {
var annotationList: JKAnnotationList
}
abstract class JKMethod : JKDeclaration(), JKVisibilityOwner, JKModalityOwner, JKOtherModifiersOwner, JKTypeParameterListOwner,
JKAnnotationListOwner {
abstract var parameters: List<JKParameter>
abstract var returnType: JKTypeElement
abstract var block: JKBlock
val leftParen = JKTokenElementImpl("(")
val rightParen = JKTokenElementImpl(")")
}
abstract class JKVariable : JKDeclaration(), JKAnnotationListOwner {
abstract var type: JKTypeElement
abstract var initializer: JKExpression
}
abstract class JKForLoopVariable : JKVariable()
abstract class JKLocalVariable : JKVariable(), JKMutabilityOwner
abstract class JKModifierElement : JKTreeElement, JKBranchElementBase(), JKNonCodeElementsListOwner
val JKModifierElement.modifier: Modifier
get() = when (this) {
is JKMutabilityModifierElement -> mutability
is JKModalityModifierElement -> modality
is JKVisibilityModifierElement -> visibility
is JKOtherModifierElement -> otherModifier
else -> error("")
}
abstract class JKMutabilityModifierElement : JKModifierElement() {
abstract var mutability: Mutability
}
abstract class JKModalityModifierElement : JKModifierElement() {
abstract var modality: Modality
}
abstract class JKVisibilityModifierElement : JKModifierElement() {
abstract var visibility: Visibility
}
abstract class JKOtherModifierElement : JKModifierElement() {
abstract var otherModifier: OtherModifier
}
interface Modifier {
val text: String
}
interface JKOtherModifiersOwner : JKModifiersListOwner {
var otherModifierElements: List<JKOtherModifierElement>
}
fun JKOtherModifiersOwner.elementByModifier(modifier: OtherModifier): JKOtherModifierElement? =
otherModifierElements.firstOrNull { it.otherModifier == modifier }
fun JKOtherModifiersOwner.hasOtherModifier(modifier: OtherModifier): Boolean =
otherModifierElements.any { it.otherModifier == modifier }
enum class OtherModifier(override val text: String) : Modifier {
OVERRIDE("override"),
ACTUAL("actual"),
ANNOTATION("annotation"),
COMPANION("companion"),
CONST("const"),
CROSSINLINE("crossinline"),
DATA("data"),
EXPECT("expect"),
EXTERNAL("external"),
INFIX("infix"),
INLINE("inline"),
INNER("inner"),
LATEINIT("lateinit"),
NOINLINE("noinline"),
OPERATOR("operator"),
OUT("out"),
REIFIED("reified"),
SEALED("sealed"),
SUSPEND("suspend"),
TAILREC("tailrec"),
VARARG("vararg"),
NATIVE("native"),
STATIC("static"),
STRICTFP("strictfp"),
SYNCHRONIZED("synchronized"),
TRANSIENT("transient"),
VOLATILE("volatile")
}
interface JKVisibilityOwner : JKModifiersListOwner {
val visibilityElement: JKVisibilityModifierElement
}
enum class Visibility(override val text: String) : Modifier {
PUBLIC("public"),
INTERNAL("internal"),
PROTECTED("protected"),
PRIVATE("private")
}
var JKVisibilityOwner.visibility: Visibility
get() = visibilityElement.visibility
set(value) {
visibilityElement.visibility = value
}
interface JKModalityOwner : JKModifiersListOwner {
val modalityElement: JKModalityModifierElement
}
enum class Modality(override val text: String) : Modifier {
OPEN("open"),
FINAL("final"),
ABSTRACT("abstract"),
}
var JKModalityOwner.modality: Modality
get() = modalityElement.modality
set(value) {
modalityElement.modality = value
}
interface JKMutabilityOwner : JKModifiersListOwner {
val mutabilityElement: JKMutabilityModifierElement
}
enum class Mutability(override val text: String) : Modifier {
MUTABLE("var"),
IMMUTABLE("val"),
UNKNOWN("var")//TODO ???
}
var JKMutabilityOwner.mutability: Mutability
get() = mutabilityElement.mutability
set(value) {
mutabilityElement.mutability = value
}
interface JKModifiersListOwner : JKTreeElement
fun JKModifiersListOwner.modifierElements(): List<JKModifierElement> =
listOfNotNull((this as? JKVisibilityOwner)?.visibilityElement) +
(this as? JKOtherModifiersOwner)?.otherModifierElements.orEmpty() +
listOfNotNull((this as? JKModalityOwner)?.modalityElement) +
listOfNotNull((this as? JKMutabilityOwner)?.mutabilityElement)
interface JKTypeElement : JKTreeElement {
var type: JKType
}
abstract class JKStatement : JKTreeElement, JKBranchElementBase() {
override var rightNonCodeElements: MutableList<JKNonCodeElement> = mutableListOf(JKSpaceElementImpl("\n"))
}
abstract class JKBlock : JKTreeElement, JKBranchElementBase() {
abstract var statements: List<JKStatement>
val leftBrace = JKTokenElementImpl("{")
val rightBrace = JKTokenElementImpl("}")
}
abstract class JKBodyStub : JKBlock() {
}
interface JKIdentifier : JKTreeElement
interface JKNameIdentifier : JKIdentifier {
val value: String
}
interface JKExpression : JKTreeElement, JKAnnotationMemberValue
interface JKMethodReferenceExpression : JKExpression, PsiOwner {
val qualifier: JKExpression
val identifier: JKSymbol
val functionalType: JKTypeElement
val isConstructorCall: Boolean
}
abstract class JKExpressionStatement : JKStatement() {
abstract var expression: JKExpression
}
abstract class JKDeclarationStatement : JKStatement() {
abstract val declaredStatements: List<JKDeclaration>
}
interface JKOperatorExpression : JKExpression {
var operator: JKOperator
}
//TODO make left & right to be immutable
interface JKBinaryExpression : JKOperatorExpression {
var left: JKExpression
var right: JKExpression
}
interface JKUnaryExpression : JKOperatorExpression {
var expression: JKExpression
}
interface JKPrefixExpression : JKUnaryExpression
interface JKPostfixExpression : JKUnaryExpression
interface JKQualifiedExpression : JKExpression {
var receiver: JKExpression
var operator: JKQualifier
var selector: JKExpression
}
interface JKTypeArgumentList : JKTreeElement {
var typeArguments: List<JKTypeElement>
}
interface JKTypeArgumentListOwner : JKTreeElement {
var typeArgumentList: JKTypeArgumentList
}
interface JKMethodCallExpression : JKExpression, JKTypeArgumentListOwner, JKBranchElement {
val identifier: JKMethodSymbol
var arguments: JKArgumentList
}
interface JKFieldAccessExpression : JKExpression {
val identifier: JKFieldSymbol
}
interface JKPackageAccessExpression : JKExpression {
val identifier: JKPackageSymbol
}
interface JKClassAccessExpression : JKExpression {
val identifier: JKClassSymbol
}
interface JKArrayAccessExpression : JKExpression {
var expression: JKExpression
var indexExpression: JKExpression
}
interface JKParenthesizedExpression : JKExpression {
val expression: JKExpression
}
interface JKTypeCastExpression : JKExpression {
val expression: JKExpression
val type: JKTypeElement
}
interface JKExpressionList : JKTreeElement, JKBranchElement {
var expressions: List<JKExpression>
}
interface JKArgument : JKTreeElement, JKBranchElement {
var value: JKExpression
}
interface JKNamedArgument : JKArgument {
val name: JKNameIdentifier
}
interface JKArgumentList : JKTreeElement, JKBranchElement {
var arguments: List<JKArgument>
}
interface JKLiteralExpression : JKExpression {
val literal: String
val type: LiteralType
enum class LiteralType {
STRING, CHAR, BOOLEAN, NULL, INT, LONG, FLOAT, DOUBLE
}
}
abstract class JKParameter : JKVariable(), JKModifiersListOwner {
abstract var isVarArgs: Boolean
override val rightNonCodeElements: MutableList<JKNonCodeElement> = mutableListOf()
}
interface JKStringLiteralExpression : JKLiteralExpression {
val text: String
}
interface JKStubExpression : JKExpression
abstract class JKLoopStatement : JKStatement() {
abstract var body: JKStatement
}
abstract class JKBlockStatement : JKStatement() {
abstract var block: JKBlock
}
abstract class JKBlockStatementWithoutBrackets : JKStatement() {
abstract var statements: List<JKStatement>
}
interface JKThisExpression : JKExpression {
var qualifierLabel: JKLabel
}
interface JKSuperExpression : JKExpression {
var qualifierLabel: JKLabel
}
abstract class JKWhileStatement : JKLoopStatement() {
abstract var condition: JKExpression
}
abstract class JKDoWhileStatement : JKLoopStatement() {
abstract var condition: JKExpression
}
abstract class JKBreakStatement : JKStatement()
abstract class JKBreakWithLabelStatement : JKBreakStatement() {
abstract var label: JKNameIdentifier
}
abstract class JKIfStatement : JKStatement() {
abstract var condition: JKExpression
abstract var thenBranch: JKStatement
}
abstract class JKIfElseStatement : JKIfStatement() {
abstract var elseBranch: JKStatement
}
interface JKIfElseExpression : JKExpression {
var condition: JKExpression
var thenBranch: JKExpression
var elseBranch: JKExpression
}
interface JKLambdaExpression : JKExpression {
var parameters: List<JKParameter>
val returnType: JKTypeElement
var statement: JKStatement
val functionalType: JKTypeElement
}
interface JKDelegationConstructorCall : JKMethodCallExpression {
override val identifier: JKMethodSymbol
val expression: JKExpression
override var arguments: JKArgumentList
}
interface JKLabel : JKTreeElement
interface JKLabelEmpty : JKLabel
interface JKLabelText : JKLabel {
val label: JKNameIdentifier
}
abstract class JKContinueStatement : JKStatement() {
abstract var label: JKLabel
}
interface JKLabeledStatement : JKExpression {
var statement: JKStatement
val labels: List<JKNameIdentifier>
}
abstract class JKEmptyStatement : JKStatement()
interface JKTypeParameterList : JKTreeElement {
var typeParameters: List<JKTypeParameter>
}
abstract class JKTypeParameter : JKDeclaration() {
abstract var upperBounds: List<JKTypeElement>
}
interface JKTypeParameterListOwner : JKTreeElement {
var typeParameterList: JKTypeParameterList
}
abstract class JKEnumConstant : JKVariable() {
abstract val arguments: JKArgumentList
abstract val body: JKClassBody
}
abstract class JKForInStatement : JKStatement() {
abstract var declaration: JKDeclaration
abstract var iterationExpression: JKExpression
abstract var body: JKStatement
}
abstract class JKPackageDeclaration : JKDeclaration()
interface JKClassLiteralExpression : JKExpression {
val classType: JKTypeElement
var literalType: LiteralType
enum class LiteralType {
KOTLIN_CLASS,
JAVA_CLASS,
JAVA_PRIMITIVE_CLASS,
JAVA_VOID_TYPE
}
}
interface JKAnnotationMemberValue : JKTreeElement
@@ -1,156 +0,0 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.nj2k.tree
import org.jetbrains.kotlin.nj2k.symbols.JKClassSymbol
import org.jetbrains.kotlin.nj2k.tree.impl.JKBranchElementBase
import org.jetbrains.kotlin.nj2k.tree.impl.JKModalityModifierElementImpl
import org.jetbrains.kotlin.nj2k.tree.impl.JKTokenElementImpl
import org.jetbrains.kotlin.nj2k.tree.impl.JKVisibilityModifierElementImpl
abstract class JKField : JKVariable(), JKVisibilityOwner, JKMutabilityOwner, JKModalityOwner, JKOtherModifiersOwner, JKAnnotationListOwner
abstract class JKJavaField : JKField()
abstract class JKJavaMethod : JKMethod(), JKBranchElement {
abstract var throwsList: List<JKTypeElement>
}
interface JKJavaMethodCallExpression : JKMethodCallExpression
abstract class JKClassBody : JKTreeElement, JKBranchElementBase() {
abstract var declarations: List<JKDeclaration>
val leftBrace = JKTokenElementImpl("{")
val rightBrace = JKTokenElementImpl("}")
}
abstract class JKEmptyClassBody : JKClassBody() {
override var declarations: List<JKDeclaration> = emptyList()
}
interface JKJavaNewExpression : JKExpression, JKTypeArgumentListOwner, PsiOwner {
var classSymbol: JKClassSymbol
var arguments: JKArgumentList
var classBody: JKClassBody
}
fun JKJavaNewExpression.isAnonymousClass() =
classBody !is JKEmptyClassBody
interface JKJavaDefaultNewExpression : JKExpression {
val classSymbol: JKClassSymbol
}
interface JKJavaNewEmptyArray : JKExpression {
val type: JKTypeElement
var initializer: List<JKExpression>
}
interface JKJavaNewArray : JKExpression {
val type: JKTypeElement
var initializer: List<JKExpression>
}
interface JKJavaLiteralExpression : JKLiteralExpression
abstract class JKReturnStatement : JKStatement() {
abstract val expression: JKExpression
abstract var label: JKLabel
}
abstract class JKJavaAssertStatement : JKStatement() {
abstract val condition: JKExpression
abstract val description: JKExpression
}
abstract class JKJavaForLoopStatement : JKLoopStatement() {
abstract var initializer: JKStatement
abstract var condition: JKExpression
abstract var updaters: List<JKStatement>
}
interface JKJavaPolyadicExpression : JKExpression {
var operands: List<JKExpression>
var tokens: List<JKOperator>
fun getTokenBeforeOperand(operand: JKExpression): JKOperator?
}
interface JKJavaAssignmentExpression : JKExpression, JKBranchElement {
var field: JKExpression
var expression: JKExpression
var operator: JKOperator
}
abstract class JKJavaThrowStatement : JKStatement() {
abstract var exception: JKExpression
}
abstract class JKJavaTryStatement : JKStatement() {
abstract var resourceDeclarations: List<JKDeclaration>
abstract var tryBlock: JKBlock
abstract var finallyBlock: JKBlock
abstract var catchSections: List<JKJavaTryCatchSection>
}
interface JKJavaTryCatchSection : JKTreeElement {
var parameter: JKParameter
var block: JKBlock
}
abstract class JKJavaSwitchStatement : JKStatement() {
abstract var expression: JKExpression
abstract var cases: List<JKJavaSwitchCase>
}
interface JKJavaSwitchCase : JKTreeElement {
fun isDefault(): Boolean
var statements: List<JKStatement>
}
interface JKJavaDefaultSwitchCase : JKJavaSwitchCase {
override fun isDefault(): Boolean = true
}
interface JKJavaLabelSwitchCase : JKJavaSwitchCase {
override fun isDefault(): Boolean = false
var label: JKExpression
}
abstract class JKJavaContinueStatement : JKStatement()
abstract class JKJavaSynchronizedStatement : JKStatement(), JKBranchElement {
abstract val lockExpression: JKExpression
abstract val body: JKBlock
}
abstract class JKJavaAnnotationMethod : JKMethod(), JKBranchElement {
abstract val defaultValue: JKAnnotationMemberValue
override var otherModifierElements by children<JKOtherModifierElement>()
override var visibilityElement by child(JKVisibilityModifierElementImpl(Visibility.PUBLIC))
override var modalityElement by child(JKModalityModifierElementImpl(Modality.FINAL))
}
abstract class JKJavaStaticInitDeclaration : JKDeclaration(), JKBranchElement {
abstract var block: JKBlock
}
@@ -1,120 +0,0 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.nj2k.tree
interface JKKtGetterOrSetter : JKTreeElement, JKVisibilityOwner, JKBranchElement {
var body: JKStatement
val kind: Kind
enum class Kind {
GETTER, SETTER
}
}
interface JKKtEmptyGetterOrSetter : JKKtGetterOrSetter
abstract class JKKtProperty : JKField(), PsiOwner {
abstract var getter: JKKtGetterOrSetter
abstract var setter: JKKtGetterOrSetter
}
abstract class JKKtFunction : JKMethod(), PsiOwner
abstract class JKKtConstructor : JKMethod(), JKOtherModifiersOwner {
abstract var delegationCall: JKExpression
}
abstract class JKKtPrimaryConstructor : JKKtConstructor()
abstract class JKKtAssignmentStatement : JKStatement() {
abstract var field: JKExpression
abstract var expression: JKExpression
abstract var token: JKOperatorToken
}
interface JKKtCall : JKMethodCallExpression
interface JKKtMethodCallExpression : JKMethodCallExpression
interface JKKtAssignmentChainLink : JKExpression {
val receiver: JKExpression
val assignmentStatement: JKKtAssignmentStatement
val field: JKExpression
}
interface JKAssignmentChainAlsoLink : JKKtAssignmentChainLink
interface JKAssignmentChainLetLink : JKKtAssignmentChainLink
interface JKKtLiteralExpression : JKLiteralExpression
abstract class JKKtWhenStatement : JKStatement() {
abstract var expression: JKExpression
abstract var cases: List<JKKtWhenCase>
}
interface JKKtWhenCase : JKTreeElement {
var labels: List<JKKtWhenLabel>
var statement: JKStatement
}
interface JKKtWhenLabel : JKTreeElement
interface JKKtElseWhenLabel : JKKtWhenLabel
interface JKKtValueWhenLabel : JKKtWhenLabel {
var expression: JKExpression
}
interface JKKtIsExpression : JKExpression, PsiOwner {
var expression: JKExpression
var type: JKTypeElement
}
abstract class JKKtInitDeclaration : JKDeclaration() {
abstract var block: JKBlock
}
abstract class JKKtConvertedFromForLoopSyntheticWhileStatement : JKStatement() {
abstract var variableDeclaration: JKStatement
abstract var whileStatement: JKWhileStatement
}
interface JKKtThrowExpression : JKExpression {
var exception: JKExpression
}
interface JKKtTryExpression : JKExpression {
var tryBlock: JKBlock
var finallyBlock: JKBlock
var catchSections: List<JKKtTryCatchSection>
}
interface JKKtTryCatchSection : JKTreeElement {
var parameter: JKParameter
var block: JKBlock
}
interface JKKtAnnotationArrayInitializerExpression : JKExpression, JKBranchElement {
val initializers: List<JKAnnotationMemberValue>
}
interface JKKtItExpression : JKExpression {
val type: JKType
}
@@ -0,0 +1,144 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.nj2k.tree
import org.jetbrains.kotlin.nj2k.tree.visitors.JKVisitor
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
interface Modifier {
val text: String
}
enum class OtherModifier(override val text: String) : Modifier {
OVERRIDE("override"),
ACTUAL("actual"),
ANNOTATION("annotation"),
COMPANION("companion"),
CONST("const"),
CROSSINLINE("crossinline"),
DATA("data"),
EXPECT("expect"),
EXTERNAL("external"),
INFIX("infix"),
INLINE("inline"),
INNER("inner"),
LATEINIT("lateinit"),
NOINLINE("noinline"),
OPERATOR("operator"),
OUT("out"),
REIFIED("reified"),
SEALED("sealed"),
SUSPEND("suspend"),
TAILREC("tailrec"),
VARARG("vararg"),
NATIVE("native"),
STATIC("static"),
STRICTFP("strictfp"),
SYNCHRONIZED("synchronized"),
TRANSIENT("transient"),
VOLATILE("volatile")
}
abstract class JKModifierElement : JKTreeElement()
interface JKOtherModifiersOwner : JKModifiersListOwner {
var otherModifierElements: List<JKOtherModifierElement>
}
class JKMutabilityModifierElement(var mutability: Mutability) : JKModifierElement() {
override fun accept(visitor: JKVisitor) = visitor.visitMutabilityModifierElement(this)
}
class JKModalityModifierElement(var modality: Modality) : JKModifierElement() {
override fun accept(visitor: JKVisitor) = visitor.visitModalityModifierElement(this)
}
class JKVisibilityModifierElement(var visibility: Visibility) : JKModifierElement() {
override fun accept(visitor: JKVisitor) = visitor.visitVisibilityModifierElement(this)
}
class JKOtherModifierElement(var otherModifier: OtherModifier) : JKModifierElement() {
override fun accept(visitor: JKVisitor) = visitor.visitOtherModifierElement(this)
}
interface JKVisibilityOwner : JKModifiersListOwner {
val visibilityElement: JKVisibilityModifierElement
}
enum class Visibility(override val text: String) : Modifier {
PUBLIC("public"),
INTERNAL("internal"),
PROTECTED("protected"),
PRIVATE("private")
}
interface JKModalityOwner : JKModifiersListOwner {
val modalityElement: JKModalityModifierElement
}
enum class Modality(override val text: String) : Modifier {
OPEN("open"),
FINAL("final"),
ABSTRACT("abstract"),
}
interface JKMutabilityOwner : JKModifiersListOwner {
val mutabilityElement: JKMutabilityModifierElement
}
enum class Mutability(override val text: String) : Modifier {
MUTABLE("var"),
IMMUTABLE("val"),
UNKNOWN("var")
}
interface JKModifiersListOwner : JKNonCodeElementsListOwner
fun JKOtherModifiersOwner.elementByModifier(modifier: OtherModifier): JKOtherModifierElement? =
otherModifierElements.firstOrNull { it.otherModifier == modifier }
fun JKOtherModifiersOwner.hasOtherModifier(modifier: OtherModifier): Boolean =
otherModifierElements.any { it.otherModifier == modifier }
var JKVisibilityOwner.visibility: Visibility
get() = visibilityElement.visibility
set(value) {
visibilityElement.visibility = value
}
var JKMutabilityOwner.mutability: Mutability
get() = mutabilityElement.mutability
set(value) {
mutabilityElement.mutability = value
}
var JKModalityOwner.modality: Modality
get() = modalityElement.modality
set(value) {
modalityElement.modality = value
}
val JKModifierElement.modifier: Modifier
get() = when (this) {
is JKMutabilityModifierElement -> mutability
is JKModalityModifierElement -> modality
is JKVisibilityModifierElement -> visibility
is JKOtherModifierElement -> otherModifier
else -> error("")
}
inline fun JKModifiersListOwner.forEachModifier(action: (JKModifierElement) -> Unit) {
safeAs<JKVisibilityOwner>()?.visibilityElement?.let(action)
safeAs<JKOtherModifiersOwner>()?.otherModifierElements?.forEach(action)
safeAs<JKModalityOwner>()?.modalityElement?.let(action)
safeAs<JKMutabilityOwner>()?.mutabilityElement?.let(action)
}
@@ -0,0 +1,137 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.nj2k.tree
import com.intellij.psi.JavaTokenType
import com.intellij.psi.tree.IElementType
import org.jetbrains.kotlin.lexer.KtSingleValueToken
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.nj2k.types.JKType
interface JKOperator {
val token: JKOperatorToken
val returnType: JKType
}
interface JKOperatorToken {
val text: String
@Suppress("MemberVisibilityCanBePrivate", "SpellCheckingInspection")
companion object {
fun fromElementType(elementType: IElementType) = elementTypeToToken.getValue(elementType)
val RANGE = JKKtSingleValueOperatorToken(KtTokens.RANGE)
val DIV = JKKtSingleValueOperatorToken(KtTokens.DIV)
val MINUS = JKKtSingleValueOperatorToken(KtTokens.MINUS)
val ANDAND = JKKtSingleValueOperatorToken(KtTokens.ANDAND)
val OROR = JKKtSingleValueOperatorToken(KtTokens.OROR)
val PLUS = JKKtSingleValueOperatorToken(KtTokens.PLUS)
val MUL = JKKtSingleValueOperatorToken(KtTokens.MUL)
val GT = JKKtSingleValueOperatorToken(KtTokens.GT)
val GTEQ = JKKtSingleValueOperatorToken(KtTokens.GTEQ)
val LT = JKKtSingleValueOperatorToken(KtTokens.LT)
val LTEQ = JKKtSingleValueOperatorToken(KtTokens.LTEQ)
val PERC = JKKtSingleValueOperatorToken(KtTokens.PERC)
val EQ = JKKtSingleValueOperatorToken(KtTokens.EQ)
val EQEQ = JKKtSingleValueOperatorToken(KtTokens.EQEQ)
val EXCLEQ = JKKtSingleValueOperatorToken(KtTokens.EXCLEQ)
val PLUSEQ = JKKtSingleValueOperatorToken(KtTokens.PLUSEQ)
val MINUSEQ = JKKtSingleValueOperatorToken(KtTokens.MINUSEQ)
val DIVEQ = JKKtSingleValueOperatorToken(KtTokens.DIVEQ)
val MULTEQ = JKKtSingleValueOperatorToken(KtTokens.MULTEQ)
val PERCEQ = JKKtSingleValueOperatorToken(KtTokens.PERCEQ)
val PLUSPLUS = JKKtSingleValueOperatorToken(KtTokens.PLUSPLUS)
val MINUSMINUS = JKKtSingleValueOperatorToken(KtTokens.MINUSMINUS)
val EXCL = JKKtSingleValueOperatorToken(KtTokens.EXCL)
val EQEQEQ = JKKtSingleValueOperatorToken(KtTokens.EQEQEQ)
val EXCLEQEQEQ = JKKtSingleValueOperatorToken(KtTokens.EXCLEQEQEQ)
val AND = JKKtWordOperatorToken("and")
val OR = JKKtWordOperatorToken("or")
val XOR = JKKtWordOperatorToken("xor")
val USHR = JKKtWordOperatorToken("ushr")
val SHR = JKKtWordOperatorToken("shr")
val SHL = JKKtWordOperatorToken("shl")
val ANDEQ = JKJavaOperatorToken(JavaTokenType.ANDEQ)
val OREQ = JKJavaOperatorToken(JavaTokenType.OREQ)
val XOREQ = JKJavaOperatorToken(JavaTokenType.XOREQ)
val LTLTEQ = JKJavaOperatorToken(JavaTokenType.LTLTEQ)
val GTGTEQ = JKJavaOperatorToken(JavaTokenType.GTGTEQ)
val GTGTGTEQ = JKJavaOperatorToken(JavaTokenType.GTGTGTEQ)
private val elementTypeToToken: Map<IElementType, JKOperatorToken> = mapOf(
JavaTokenType.DIV to DIV,
JavaTokenType.MINUS to MINUS,
JavaTokenType.ANDAND to ANDAND,
JavaTokenType.OROR to OROR,
JavaTokenType.PLUS to PLUS,
JavaTokenType.ASTERISK to MUL,
JavaTokenType.GT to GT,
JavaTokenType.GE to GTEQ,
JavaTokenType.LT to LT,
JavaTokenType.LE to LTEQ,
JavaTokenType.PERC to PERC,
JavaTokenType.EQ to EQ,
JavaTokenType.EQEQ to EQEQ,
JavaTokenType.NE to EXCLEQ,
JavaTokenType.PLUSEQ to PLUSEQ,
JavaTokenType.MINUSEQ to MINUSEQ,
JavaTokenType.DIVEQ to DIVEQ,
JavaTokenType.ASTERISKEQ to MULTEQ,
JavaTokenType.PLUSPLUS to PLUSPLUS,
JavaTokenType.MINUSMINUS to MINUSMINUS,
JavaTokenType.EXCL to EXCL,
KtTokens.EQEQEQ to EQEQEQ,
KtTokens.EXCLEQEQEQ to EXCLEQEQEQ,
JavaTokenType.AND to AND,
JavaTokenType.OR to OR,
JavaTokenType.XOR to XOR,
JavaTokenType.GTGTGT to USHR,
JavaTokenType.GTGT to SHR,
JavaTokenType.LTLT to SHL,
JavaTokenType.ANDEQ to ANDEQ,
JavaTokenType.OREQ to OREQ,
JavaTokenType.XOREQ to XOREQ,
JavaTokenType.PERCEQ to PERCEQ,
JavaTokenType.LTLTEQ to LTLTEQ,
JavaTokenType.GTGTEQ to GTGTEQ,
JavaTokenType.GTGTGTEQ to GTGTGTEQ
)
}
}
class JKKtWordOperatorToken(override val text: String) : JKKtOperatorToken
class JKKtOperatorImpl(override val token: JKOperatorToken, override val returnType: JKType) : JKOperator
interface JKKtOperatorToken : JKOperatorToken
class JKJavaOperatorToken(val psiToken: IElementType) : JKOperatorToken {
override val text: String
get() = error("Java token should not be printed, it should be replaces with corresponding Kotlin one")
}
class JKKtSingleValueOperatorToken(val psiToken: KtSingleValueToken) : JKKtOperatorToken {
override val text: String = psiToken.value
}
object JKKtSpreadOperatorToken : JKKtOperatorToken {
override val text: String = "*"
}
class JKKtSpreadOperator(override val returnType: JKType) : JKOperator {
override val token: JKOperatorToken = JKKtSpreadOperatorToken
}
@@ -0,0 +1,191 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.nj2k.tree
import org.jetbrains.kotlin.nj2k.tree.visitors.JKVisitor
abstract class JKStatement : JKTreeElement(), PsiOwner by PsiOwnerImpl()
class JKEmptyStatement : JKStatement() {
override fun accept(visitor: JKVisitor) = visitor.visitEmptyStatement(this)
}
abstract class JKLoopStatement : JKStatement() {
abstract var body: JKStatement
}
class JKWhileStatement(condition: JKExpression, body: JKStatement) : JKLoopStatement() {
var condition by child(condition)
override var body by child(body)
override fun accept(visitor: JKVisitor) = visitor.visitWhileStatement(this)
}
class JKDoWhileStatement(body: JKStatement, condition: JKExpression) : JKLoopStatement() {
var condition by child(condition)
override var body by child(body)
override fun accept(visitor: JKVisitor) = visitor.visitDoWhileStatement(this)
}
class JKForInStatement(declaration: JKDeclaration, iterationExpression: JKExpression, body: JKStatement) : JKStatement() {
var declaration: JKDeclaration by child(declaration)
var iterationExpression: JKExpression by child(iterationExpression)
var body: JKStatement by child(body)
override fun accept(visitor: JKVisitor) = visitor.visitForInStatement(this)
}
class JKIfElseStatement(condition: JKExpression, thenBranch: JKStatement, elseBranch: JKStatement) : JKStatement() {
var condition by child(condition)
var thenBranch by child(thenBranch)
var elseBranch by child(elseBranch)
override fun accept(visitor: JKVisitor) = visitor.visitIfElseStatement(this)
}
class JKBreakStatement(label: JKLabel) : JKStatement() {
val label: JKLabel by child(label)
override fun accept(visitor: JKVisitor) = visitor.visitBreakStatement(this)
}
class JKContinueStatement(label: JKLabel) : JKStatement() {
var label: JKLabel by child(label)
override fun accept(visitor: JKVisitor) = visitor.visitContinueStatement(this)
}
class JKBlockStatement(block: JKBlock) : JKStatement() {
var block by child(block)
override fun accept(visitor: JKVisitor) = visitor.visitBlockStatement(this)
}
class JKBlockStatementWithoutBrackets(statements: List<JKStatement>) : JKStatement() {
var statements by children(statements)
override fun accept(visitor: JKVisitor) = visitor.visitBlockStatementWithoutBrackets(this)
}
class JKExpressionStatement(expression: JKExpression) : JKStatement() {
var expression: JKExpression by child(expression)
override fun accept(visitor: JKVisitor) = visitor.visitExpressionStatement(this)
}
class JKDeclarationStatement(declaredStatements: List<JKDeclaration>) : JKStatement() {
val declaredStatements by children(declaredStatements)
override fun accept(visitor: JKVisitor) = visitor.visitDeclarationStatement(this)
}
class JKKtWhenStatement(
expression: JKExpression,
cases: List<JKKtWhenCase>
) : JKStatement() {
var expression: JKExpression by child(expression)
var cases: List<JKKtWhenCase> by children(cases)
override fun accept(visitor: JKVisitor) = visitor.visitKtWhenStatement(this)
}
class JKKtConvertedFromForLoopSyntheticWhileStatement(
variableDeclaration: JKStatement,
whileStatement: JKWhileStatement
) : JKStatement() {
var variableDeclaration: JKStatement by child(variableDeclaration)
var whileStatement: JKWhileStatement by child(whileStatement)
override fun accept(visitor: JKVisitor) = visitor.visitKtConvertedFromForLoopSyntheticWhileStatement(this)
}
class JKKtAssignmentStatement(
field: JKExpression,
expression: JKExpression,
var token: JKOperatorToken
) : JKStatement() {
var field: JKExpression by child(field)
var expression by child(expression)
override fun accept(visitor: JKVisitor) = visitor.visitKtAssignmentStatement(this)
}
class JKReturnStatement(
expression: JKExpression,
label: JKLabel = JKLabelEmpty()
) : JKStatement() {
val expression by child(expression)
var label by child(label)
override fun accept(visitor: JKVisitor) = visitor.visitReturnStatement(this)
}
class JKJavaSwitchStatement(
expression: JKExpression,
cases: List<JKJavaSwitchCase>
) : JKStatement() {
var expression: JKExpression by child(expression)
var cases: List<JKJavaSwitchCase> by children(cases)
override fun accept(visitor: JKVisitor) = visitor.visitJavaSwitchStatement(this)
}
class JKJavaThrowStatement(exception: JKExpression) : JKStatement() {
var exception: JKExpression by child(exception)
override fun accept(visitor: JKVisitor) = visitor.visitJavaThrowStatement(this)
}
class JKJavaTryStatement(
resourceDeclarations: List<JKDeclaration>,
tryBlock: JKBlock,
finallyBlock: JKBlock,
catchSections: List<JKJavaTryCatchSection>
) : JKStatement() {
var resourceDeclarations: List<JKDeclaration> by children(resourceDeclarations)
var tryBlock: JKBlock by child(tryBlock)
var finallyBlock: JKBlock by child(finallyBlock)
var catchSections: List<JKJavaTryCatchSection> by children(catchSections)
override fun accept(visitor: JKVisitor) = visitor.visitJavaTryStatement(this)
}
class JKJavaSynchronizedStatement(
lockExpression: JKExpression,
body: JKBlock
) : JKStatement() {
val lockExpression: JKExpression by child(lockExpression)
val body: JKBlock by child(body)
override fun accept(visitor: JKVisitor) = visitor.visitJavaSynchronizedStatement(this)
}
class JKJavaAssertStatement(condition: JKExpression, description: JKExpression) : JKStatement() {
val description by child(description)
val condition by child(condition)
override fun accept(visitor: JKVisitor) = visitor.visitJavaAssertStatement(this)
}
class JKJavaForLoopStatement(
initializer: JKStatement,
condition: JKExpression,
updaters: List<JKStatement>,
body: JKStatement
) : JKLoopStatement() {
override var body by child(body)
var updaters by children(updaters)
var condition by child(condition)
var initializer by child(initializer)
override fun accept(visitor: JKVisitor) = visitor.visitJavaForLoopStatement(this)
}
class JKJavaAnnotationMethod(
returnType: JKTypeElement,
name: JKNameIdentifier,
defaultValue: JKAnnotationMemberValue,
otherModifierElements: List<JKOtherModifierElement>,
visibilityElement: JKVisibilityModifierElement,
modalityElement: JKModalityModifierElement
) : JKMethod(), JKAnnotationListOwner, JKTypeParameterListOwner {
override var returnType: JKTypeElement by child(returnType)
override var name: JKNameIdentifier by child(name)
override var parameters: List<JKParameter> by children()
var defaultValue: JKAnnotationMemberValue by child(defaultValue)
override var block: JKBlock by child(JKBodyStub)
override var typeParameterList: JKTypeParameterList by child(JKTypeParameterList())
override var annotationList: JKAnnotationList by child(JKAnnotationList())
override var otherModifierElements by children(otherModifierElements)
override var visibilityElement by child(visibilityElement)
override var modalityElement by child(modalityElement)
override fun accept(visitor: JKVisitor) = visitor.visitJavaAnnotationMethod(this)
}
@@ -5,21 +5,20 @@
package org.jetbrains.kotlin.nj2k.tree
import org.jetbrains.kotlin.utils.SmartList
interface JKNonCodeElement {
val text: String
}
interface JKSpaceElement : JKNonCodeElement
interface JKCommentElement : JKNonCodeElement
fun JKCommentElement.isMultiline() =
text.startsWith("/*")
fun JKCommentElement.isSingleline() =
text.startsWith("//")
class JKSpaceElement(override val text: String) : JKNonCodeElement
class JKCommentElement(override val text: String) : JKNonCodeElement
class JKTokenElementImpl(override val text: String) : JKTokenElement {
override val leftNonCodeElements: MutableList<JKNonCodeElement> = SmartList()
override val rightNonCodeElements: MutableList<JKNonCodeElement> = SmartList()
}
interface JKNonCodeElementsListOwner {
val leftNonCodeElements: MutableList<JKNonCodeElement>
@@ -31,20 +30,6 @@ fun JKNonCodeElementsListOwner.takeNonCodeElementsFrom(other: JKNonCodeElementsL
rightNonCodeElements += other.rightNonCodeElements
}
fun List<JKNonCodeElement>.dropSpacesAtBeginning() =
dropWhile { it is JKSpaceElement }
fun JKTreeElement.commentsFromInside(): List<JKCommentElement> {
val comments = mutableListOf<JKCommentElement>()
fun recurse(element: JKTreeElement): JKTreeElement {
comments += (element.leftNonCodeElements + element.rightNonCodeElements).filterIsInstance<JKCommentElement>()
return applyRecursive(element, ::recurse)
}
applyRecursive(this, ::recurse)
return comments
}
inline fun <reified T : JKNonCodeElementsListOwner> T.withNonCodeElementsFrom(other: JKNonCodeElementsListOwner): T =
also { it.takeNonCodeElementsFrom(other) }
@@ -16,7 +16,7 @@
package org.jetbrains.kotlin.nj2k.tree
import org.jetbrains.kotlin.nj2k.tree.impl.JKBranchElementBase
import kotlin.jvm.internal.CallableReference
import kotlin.reflect.KProperty0
@@ -44,9 +44,6 @@ fun <T : JKElement> KProperty0<List<T>>.detached(): List<T> =
fun <T : JKElement> T.detached(from: JKElement): T =
also { it.detach(from) }
fun <T : JKBranchElement> T.invalidated(): T =
also { it.invalidate() }
fun <R : JKTreeElement, T> applyRecursive(
element: R,
data: T,
@@ -76,25 +73,23 @@ fun <R : JKTreeElement, T> applyRecursive(
return newChild
}
if (element is JKBranchElementBase) {
val iter = element.children.listIterator()
while (iter.hasNext()) {
val child = iter.next()
val iter = element.children.listIterator()
while (iter.hasNext()) {
val child = iter.next()
if (child is List<*>) {
@Suppress("UNCHECKED_CAST")
iter.set(applyRecursiveToList(element, child as List<JKTreeElement>, iter, data, func))
} else if (child is JKTreeElement) {
val newChild = func(child, data)
if (child !== newChild) {
child.detach(element)
iter.set(newChild)
newChild.attach(element)
onElementChanged(newChild, child)
}
} else {
error("unsupported child type: ${child::class}")
if (child is List<*>) {
@Suppress("UNCHECKED_CAST")
iter.set(applyRecursiveToList(element, child as List<JKTreeElement>, iter, data, func))
} else if (child is JKTreeElement) {
val newChild = func(child, data)
if (child !== newChild) {
child.detach(element)
iter.set(newChild)
newChild.attach(element)
onElementChanged(newChild, child)
}
} else {
error("unsupported child type: ${child::class}")
}
}
return element
@@ -106,4 +101,11 @@ fun <R : JKTreeElement> applyRecursive(
): R = applyRecursive(element, null, { _, _ -> }) { it, _ -> func(it) }
inline fun <reified T : JKTreeElement> T.copyTree(): T =
copy().withNonCodeElementsFrom(this) as T
inline fun <reified T : JKTreeElement> T.copyTreeAndDetach(): T =
copyTree().also {
if (it.parent != null) it.detach(it.parent!!)
}
@@ -3,146 +3,146 @@ package org.jetbrains.kotlin.nj2k.tree.visitors
import org.jetbrains.kotlin.nj2k.tree.*
abstract class JKVisitor {
abstract fun visitTreeElement(treeElement: JKTreeElement)
open fun visitTreeRoot(treeRoot: JKTreeRoot) = visitTreeElement(treeRoot)
abstract fun visitTreeElement(treeElement: JKTreeElement)
open fun visitDeclaration(declaration: JKDeclaration) = visitTreeElement(declaration)
open fun visitClass(klass: JKClass) = visitDeclaration(klass)
open fun visitVariable(variable: JKVariable) = visitDeclaration(variable)
open fun visitLocalVariable(localVariable: JKLocalVariable) = visitVariable(localVariable)
open fun visitForLoopVariable(forLoopVariable: JKForLoopVariable) = visitVariable(forLoopVariable)
open fun visitParameter(parameter: JKParameter) = visitVariable(parameter)
open fun visitEnumConstant(enumConstant: JKEnumConstant) = visitVariable(enumConstant)
open fun visitTypeParameter(typeParameter: JKTypeParameter) = visitDeclaration(typeParameter)
open fun visitMethod(method: JKMethod) = visitDeclaration(method)
open fun visitMethodImpl(methodImpl: JKMethodImpl) = visitMethod(methodImpl)
open fun visitConstructor(constructor: JKConstructor) = visitMethod(constructor)
open fun visitConstructorImpl(constructorImpl: JKConstructorImpl) = visitConstructor(constructorImpl)
open fun visitKtPrimaryConstructor(ktPrimaryConstructor: JKKtPrimaryConstructor) = visitConstructor(ktPrimaryConstructor)
open fun visitField(field: JKField) = visitVariable(field)
open fun visitKtInitDeclaration(ktInitDeclaration: JKKtInitDeclaration) = visitDeclaration(ktInitDeclaration)
open fun visitJavaStaticInitDeclaration(javaStaticInitDeclaration: JKJavaStaticInitDeclaration) =
visitDeclaration(javaStaticInitDeclaration)
open fun visitTreeRoot(treeRoot: JKTreeRoot) = visitTreeElement(treeRoot)
open fun visitFile(file: JKFile) = visitTreeElement(file)
open fun visitTypeElement(typeElement: JKTypeElement) = visitTreeElement(typeElement)
open fun visitBlock(block: JKBlock) = visitTreeElement(block)
open fun visitInheritanceInfo(inheritanceInfo: JKInheritanceInfo) = visitTreeElement(inheritanceInfo)
open fun visitPackageDeclaration(packageDeclaration: JKPackageDeclaration) = visitTreeElement(packageDeclaration)
open fun visitLabel(label: JKLabel) = visitTreeElement(label)
open fun visitLabelEmpty(labelEmpty: JKLabelEmpty) = visitLabel(labelEmpty)
open fun visitLabelText(labelText: JKLabelText) = visitLabel(labelText)
open fun visitImportStatement(importStatement: JKImportStatement) = visitTreeElement(importStatement)
open fun visitImportList(importList: JKImportList) = visitTreeElement(importList)
open fun visitFile(file: JKFile) = visitTreeElement(file)
open fun visitClass(klass: JKClass) = visitDeclaration(klass)
open fun visitInheritanceInfo(inheritanceInfo: JKInheritanceInfo) = visitTreeElement(inheritanceInfo)
open fun visitAnnotationList(annotationList: JKAnnotationList) = visitTreeElement(annotationList)
open fun visitAnnotation(annotation: JKAnnotation) = visitAnnotationMemberValue(annotation)
open fun visitAnnotationParameter(annotationParameter: JKAnnotationParameter) = visitTreeElement(annotationParameter)
open fun visitAnnotationNameParameter(annotationNameParameter: JKAnnotationNameParameter) = visitAnnotationParameter(annotationNameParameter)
open fun visitAnnotationListOwner(annotationListOwner: JKAnnotationListOwner) = visitTreeElement(annotationListOwner)
open fun visitMethod(method: JKMethod) = visitDeclaration(method)
open fun visitVariable(variable: JKVariable) = visitDeclaration(variable)
open fun visitForLoopVariable(forLoopVariable: JKForLoopVariable) = visitVariable(forLoopVariable)
open fun visitLocalVariable(localVariable: JKLocalVariable) = visitVariable(localVariable)
open fun visitModifierElement(modifierElement: JKModifierElement) = visitTreeElement(modifierElement)
open fun visitMutabilityModifierElement(mutabilityModifierElement: JKMutabilityModifierElement) = visitModifierElement(mutabilityModifierElement)
open fun visitModalityModifierElement(modalityModifierElement: JKModalityModifierElement) = visitModifierElement(modalityModifierElement)
open fun visitVisibilityModifierElement(visibilityModifierElement: JKVisibilityModifierElement) = visitModifierElement(visibilityModifierElement)
open fun visitOtherModifierElement(otherModifierElement: JKOtherModifierElement) = visitModifierElement(otherModifierElement)
open fun visitOtherModifiersOwner(otherModifiersOwner: JKOtherModifiersOwner) = visitModifiersListOwner(otherModifiersOwner)
open fun visitVisibilityOwner(visibilityOwner: JKVisibilityOwner) = visitModifiersListOwner(visibilityOwner)
open fun visitModalityOwner(modalityOwner: JKModalityOwner) = visitModifiersListOwner(modalityOwner)
open fun visitMutabilityOwner(mutabilityOwner: JKMutabilityOwner) = visitModifiersListOwner(mutabilityOwner)
open fun visitModifiersListOwner(modifiersListOwner: JKModifiersListOwner) = visitTreeElement(modifiersListOwner)
open fun visitTypeElement(typeElement: JKTypeElement) = visitTreeElement(typeElement)
open fun visitStatement(statement: JKStatement) = visitTreeElement(statement)
open fun visitBlock(block: JKBlock) = visitTreeElement(block)
open fun visitBodyStub(bodyStub: JKBodyStub) = visitBlock(bodyStub)
open fun visitIdentifier(identifier: JKIdentifier) = visitTreeElement(identifier)
open fun visitNameIdentifier(nameIdentifier: JKNameIdentifier) = visitIdentifier(nameIdentifier)
open fun visitAnnotationParameterImpl(annotationParameterImpl: JKAnnotationParameterImpl) =
visitAnnotationParameter(annotationParameterImpl)
open fun visitAnnotationNameParameter(annotationNameParameter: JKAnnotationNameParameter) =
visitAnnotationParameter(annotationNameParameter)
open fun visitArgument(argument: JKArgument) = visitTreeElement(argument)
open fun visitNamedArgument(namedArgument: JKNamedArgument) = visitArgument(namedArgument)
open fun visitArgumentImpl(argumentImpl: JKArgumentImpl) = visitArgument(argumentImpl)
open fun visitArgumentList(argumentList: JKArgumentList) = visitTreeElement(argumentList)
open fun visitTypeParameterList(typeParameterList: JKTypeParameterList) = visitTreeElement(typeParameterList)
open fun visitAnnotationList(annotationList: JKAnnotationList) = visitTreeElement(annotationList)
open fun visitAnnotation(annotation: JKAnnotation) = visitTreeElement(annotation)
open fun visitTypeArgumentList(typeArgumentList: JKTypeArgumentList) = visitTreeElement(typeArgumentList)
open fun visitNameIdentifier(nameIdentifier: JKNameIdentifier) = visitTreeElement(nameIdentifier)
open fun visitBlockImpl(blockImpl: JKBlockImpl) = visitBlock(blockImpl)
open fun visitKtWhenCase(ktWhenCase: JKKtWhenCase) = visitTreeElement(ktWhenCase)
open fun visitKtWhenLabel(ktWhenLabel: JKKtWhenLabel) = visitTreeElement(ktWhenLabel)
open fun visitKtElseWhenLabel(ktElseWhenLabel: JKKtElseWhenLabel) = visitKtWhenLabel(ktElseWhenLabel)
open fun visitKtValueWhenLabel(ktValueWhenLabel: JKKtValueWhenLabel) = visitKtWhenLabel(ktValueWhenLabel)
open fun visitClassBody(classBody: JKClassBody) = visitTreeElement(classBody)
open fun visitJavaTryCatchSection(javaTryCatchSection: JKJavaTryCatchSection) = visitStatement(javaTryCatchSection)
open fun visitJavaSwitchCase(javaSwitchCase: JKJavaSwitchCase) = visitTreeElement(javaSwitchCase)
open fun visitJavaDefaultSwitchCase(javaDefaultSwitchCase: JKJavaDefaultSwitchCase) = visitJavaSwitchCase(javaDefaultSwitchCase)
open fun visitJavaLabelSwitchCase(javaLabelSwitchCase: JKJavaLabelSwitchCase) = visitJavaSwitchCase(javaLabelSwitchCase)
open fun visitExpression(expression: JKExpression) = visitTreeElement(expression)
open fun visitMethodReferenceExpression(methodReferenceExpression: JKMethodReferenceExpression) = visitExpression(methodReferenceExpression)
open fun visitExpressionStatement(expressionStatement: JKExpressionStatement) = visitStatement(expressionStatement)
open fun visitDeclarationStatement(declarationStatement: JKDeclarationStatement) = visitStatement(declarationStatement)
open fun visitOperatorExpression(operatorExpression: JKOperatorExpression) = visitExpression(operatorExpression)
open fun visitBinaryExpression(binaryExpression: JKBinaryExpression) = visitOperatorExpression(binaryExpression)
open fun visitUnaryExpression(unaryExpression: JKUnaryExpression) = visitOperatorExpression(unaryExpression)
open fun visitPrefixExpression(prefixExpression: JKPrefixExpression) = visitUnaryExpression(prefixExpression)
open fun visitPostfixExpression(postfixExpression: JKPostfixExpression) = visitUnaryExpression(postfixExpression)
open fun visitQualifiedExpression(qualifiedExpression: JKQualifiedExpression) = visitExpression(qualifiedExpression)
open fun visitTypeArgumentList(typeArgumentList: JKTypeArgumentList) = visitTreeElement(typeArgumentList)
open fun visitTypeArgumentListOwner(typeArgumentListOwner: JKTypeArgumentListOwner) = visitTreeElement(typeArgumentListOwner)
open fun visitMethodCallExpression(methodCallExpression: JKMethodCallExpression) = visitExpression(methodCallExpression)
open fun visitFieldAccessExpression(fieldAccessExpression: JKFieldAccessExpression) = visitAssignableExpression(fieldAccessExpression)
open fun visitPackageAccessExpression(packageAccessExpression: JKPackageAccessExpression) = visitAssignableExpression(packageAccessExpression)
open fun visitClassAccessExpression(classAccessExpression: JKClassAccessExpression) = visitExpression(classAccessExpression)
open fun visitArrayAccessExpression(arrayAccessExpression: JKArrayAccessExpression) = visitAssignableExpression(arrayAccessExpression)
open fun visitParenthesizedExpression(parenthesizedExpression: JKParenthesizedExpression) = visitExpression(parenthesizedExpression)
open fun visitTypeCastExpression(typeCastExpression: JKTypeCastExpression) = visitExpression(typeCastExpression)
open fun visitExpressionList(expressionList: JKExpressionList) = visitTreeElement(expressionList)
open fun visitArgument(argument: JKArgument) = visitTreeElement(argument)
open fun visitNamedArgument(namedArgument: JKNamedArgument) = visitArgument(namedArgument)
open fun visitArgumentList(argumentList: JKArgumentList) = visitTreeElement(argumentList)
open fun visitLiteralExpression(literalExpression: JKLiteralExpression) = visitExpression(literalExpression)
open fun visitParameter(parameter: JKParameter) = visitVariable(parameter)
open fun visitStringLiteralExpression(stringLiteralExpression: JKStringLiteralExpression) = visitLiteralExpression(stringLiteralExpression)
open fun visitStubExpression(stubExpression: JKStubExpression) = visitExpression(stubExpression)
open fun visitLoopStatement(loopStatement: JKLoopStatement) = visitStatement(loopStatement)
open fun visitBlockStatement(blockStatement: JKBlockStatement) = visitStatement(blockStatement)
open fun visitBlockStatementWithoutBrackets(blockStatementWithoutBrackets: JKBlockStatementWithoutBrackets) = visitStatement(blockStatementWithoutBrackets)
open fun visitThisExpression(thisExpression: JKThisExpression) = visitExpression(thisExpression)
open fun visitSuperExpression(superExpression: JKSuperExpression) = visitExpression(superExpression)
open fun visitWhileStatement(whileStatement: JKWhileStatement) = visitLoopStatement(whileStatement)
open fun visitDoWhileStatement(doWhileStatement: JKDoWhileStatement) = visitLoopStatement(doWhileStatement)
open fun visitBreakStatement(breakStatement: JKBreakStatement) = visitStatement(breakStatement)
open fun visitBreakWithLabelStatement(breakWithLabelStatement: JKBreakWithLabelStatement) = visitBreakStatement(breakWithLabelStatement)
open fun visitIfStatement(ifStatement: JKIfStatement) = visitStatement(ifStatement)
open fun visitIfElseStatement(ifElseStatement: JKIfElseStatement) = visitIfStatement(ifElseStatement)
open fun visitIfElseExpression(ifElseExpression: JKIfElseExpression) = visitExpression(ifElseExpression)
open fun visitAssignableExpression(assignableExpression: JKExpression) = visitExpression(assignableExpression)
open fun visitLambdaExpression(lambdaExpression: JKLambdaExpression) = visitExpression(lambdaExpression)
open fun visitDelegationConstructorCall(delegationConstructorCall: JKDelegationConstructorCall) = visitMethodCallExpression(delegationConstructorCall)
open fun visitLabel(label: JKLabel) = visitTreeElement(label)
open fun visitLabelEmpty(labelEmpty: JKLabelEmpty) = visitLabel(labelEmpty)
open fun visitLabelText(labelText: JKLabelText) = visitLabel(labelText)
open fun visitContinueStatement(continueStatement: JKContinueStatement) = visitStatement(continueStatement)
open fun visitLabeledStatement(labeledStatement: JKLabeledStatement) = visitExpression(labeledStatement)
open fun visitEmptyStatement(emptyStatement: JKEmptyStatement) = visitStatement(emptyStatement)
open fun visitTypeParameterList(typeParameterList: JKTypeParameterList) = visitTreeElement(typeParameterList)
open fun visitTypeParameter(typeParameter: JKTypeParameter) = visitDeclaration(typeParameter)
open fun visitTypeParameterListOwner(typeParameterListOwner: JKTypeParameterListOwner) = visitTreeElement(typeParameterListOwner)
open fun visitEnumConstant(enumConstant: JKEnumConstant) = visitVariable(enumConstant)
open fun visitForInStatement(forInStatement: JKForInStatement) = visitStatement(forInStatement)
open fun visitPackageDeclaration(packageDeclaration: JKPackageDeclaration) = visitDeclaration(packageDeclaration)
open fun visitCallExpression(callExpression: JKCallExpression) = visitExpression(callExpression)
open fun visitDelegationConstructorCall(delegationConstructorCall: JKDelegationConstructorCall) =
visitCallExpression(delegationConstructorCall)
open fun visitCallExpressionImpl(callExpressionImpl: JKCallExpressionImpl) = visitCallExpression(callExpressionImpl)
open fun visitNewExpression(newExpression: JKNewExpression) = visitExpression(newExpression)
open fun visitFieldAccessExpression(fieldAccessExpression: JKFieldAccessExpression) = visitExpression(fieldAccessExpression)
open fun visitPackageAccessExpression(packageAccessExpression: JKPackageAccessExpression) = visitExpression(packageAccessExpression)
open fun visitClassAccessExpression(classAccessExpression: JKClassAccessExpression) = visitExpression(classAccessExpression)
open fun visitMethodReferenceExpression(methodReferenceExpression: JKMethodReferenceExpression) =
visitExpression(methodReferenceExpression)
open fun visitLabeledExpression(labeledExpression: JKLabeledExpression) = visitExpression(labeledExpression)
open fun visitClassLiteralExpression(classLiteralExpression: JKClassLiteralExpression) = visitExpression(classLiteralExpression)
open fun visitAnnotationMemberValue(annotationMemberValue: JKAnnotationMemberValue) = visitTreeElement(annotationMemberValue)
open fun visitField(field: JKField) = visitVariable(field)
open fun visitJavaField(javaField: JKJavaField) = visitField(javaField)
open fun visitJavaMethod(javaMethod: JKJavaMethod) = visitMethod(javaMethod)
open fun visitJavaMethodCallExpression(javaMethodCallExpression: JKJavaMethodCallExpression) = visitMethodCallExpression(javaMethodCallExpression)
open fun visitClassBody(classBody: JKClassBody) = visitTreeElement(classBody)
open fun visitEmptyClassBody(emptyClassBody: JKEmptyClassBody) = visitClassBody(emptyClassBody)
open fun visitJavaNewExpression(javaNewExpression: JKJavaNewExpression) = visitExpression(javaNewExpression)
open fun visitJavaDefaultNewExpression(javaDefaultNewExpression: JKJavaDefaultNewExpression) = visitExpression(javaDefaultNewExpression)
open fun visitJavaNewEmptyArray(javaNewEmptyArray: JKJavaNewEmptyArray) = visitExpression(javaNewEmptyArray)
open fun visitJavaNewArray(javaNewArray: JKJavaNewArray) = visitExpression(javaNewArray)
open fun visitJavaLiteralExpression(javaLiteralExpression: JKJavaLiteralExpression) = visitLiteralExpression(javaLiteralExpression)
open fun visitReturnStatement(returnStatement: JKReturnStatement) = visitStatement(returnStatement)
open fun visitJavaAssertStatement(javaAssertStatement: JKJavaAssertStatement) = visitStatement(javaAssertStatement)
open fun visitJavaForLoopStatement(javaForLoopStatement: JKJavaForLoopStatement) = visitLoopStatement(javaForLoopStatement)
open fun visitJavaPolyadicExpression(javaPolyadicExpression: JKJavaPolyadicExpression) = visitExpression(javaPolyadicExpression)
open fun visitJavaAssignmentExpression(javaAssignmentExpression: JKJavaAssignmentExpression) = visitExpression(javaAssignmentExpression)
open fun visitJavaThrowStatement(javaThrowStatement: JKJavaThrowStatement) = visitStatement(javaThrowStatement)
open fun visitJavaTryStatement(javaTryStatement: JKJavaTryStatement) = visitStatement(javaTryStatement)
open fun visitJavaTryCatchSection(javaTryCatchSection: JKJavaTryCatchSection) = visitTreeElement(javaTryCatchSection)
open fun visitJavaSwitchStatement(javaSwitchStatement: JKJavaSwitchStatement) = visitStatement(javaSwitchStatement)
open fun visitJavaSwitchCase(javaSwitchCase: JKJavaSwitchCase) = visitTreeElement(javaSwitchCase)
open fun visitJavaDefaultSwitchCase(javaDefaultSwitchCase: JKJavaDefaultSwitchCase) = visitJavaSwitchCase(javaDefaultSwitchCase)
open fun visitJavaLabelSwitchCase(javaLabelSwitchCase: JKJavaLabelSwitchCase) = visitJavaSwitchCase(javaLabelSwitchCase)
open fun visitJavaContinueStatement(javaContinueStatement: JKJavaContinueStatement) = visitStatement(javaContinueStatement)
open fun visitJavaSynchronizedStatement(javaSynchronizedStatement: JKJavaSynchronizedStatement) = visitStatement(javaSynchronizedStatement)
open fun visitJavaAnnotationMethod(javaAnnotationMethod: JKJavaAnnotationMethod) = visitMethod(javaAnnotationMethod)
open fun visitJavaStaticInitDeclaration(javaStaticInitDeclaration: JKJavaStaticInitDeclaration) = visitDeclaration(javaStaticInitDeclaration)
open fun visitKtGetterOrSetter(ktGetterOrSetter: JKKtGetterOrSetter) = visitTreeElement(ktGetterOrSetter)
open fun visitKtEmptyGetterOrSetter(ktEmptyGetterOrSetter: JKKtEmptyGetterOrSetter) = visitKtGetterOrSetter(ktEmptyGetterOrSetter)
open fun visitKtProperty(ktProperty: JKKtProperty) = visitField(ktProperty)
open fun visitKtFunction(ktFunction: JKKtFunction) = visitMethod(ktFunction)
open fun visitKtConstructor(ktConstructor: JKKtConstructor) = visitMethod(ktConstructor)
open fun visitKtPrimaryConstructor(ktPrimaryConstructor: JKKtPrimaryConstructor) = visitKtConstructor(ktPrimaryConstructor)
open fun visitKtAssignmentStatement(ktAssignmentStatement: JKKtAssignmentStatement) = visitStatement(ktAssignmentStatement)
open fun visitKtCall(ktCall: JKKtCall) = visitMethodCallExpression(ktCall)
open fun visitKtMethodCallExpression(ktMethodCallExpression: JKKtMethodCallExpression) = visitMethodCallExpression(ktMethodCallExpression)
open fun visitKtAssignmentChainLink(ktAssignmentChainLink: JKKtAssignmentChainLink) = visitExpression(ktAssignmentChainLink)
open fun visitAssignmentChainAlsoLink(assignmentChainAlsoLink: JKAssignmentChainAlsoLink) = visitKtAssignmentChainLink(assignmentChainAlsoLink)
open fun visitAssignmentChainLetLink(assignmentChainLetLink: JKAssignmentChainLetLink) = visitKtAssignmentChainLink(assignmentChainLetLink)
open fun visitKtLiteralExpression(ktLiteralExpression: JKKtLiteralExpression) = visitLiteralExpression(ktLiteralExpression)
open fun visitKtWhenStatement(ktWhenStatement: JKKtWhenStatement) = visitStatement(ktWhenStatement)
open fun visitKtWhenCase(ktWhenCase: JKKtWhenCase) = visitTreeElement(ktWhenCase)
open fun visitKtWhenLabel(ktWhenLabel: JKKtWhenLabel) = visitTreeElement(ktWhenLabel)
open fun visitKtElseWhenLabel(ktElseWhenLabel: JKKtElseWhenLabel) = visitKtWhenLabel(ktElseWhenLabel)
open fun visitKtValueWhenLabel(ktValueWhenLabel: JKKtValueWhenLabel) = visitKtWhenLabel(ktValueWhenLabel)
open fun visitKtIsExpression(ktIsExpression: JKKtIsExpression) = visitExpression(ktIsExpression)
open fun visitKtInitDeclaration(ktInitDeclaration: JKKtInitDeclaration) = visitDeclaration(ktInitDeclaration)
open fun visitKtConvertedFromForLoopSyntheticWhileStatement(ktConvertedFromForLoopSyntheticWhileStatement: JKKtConvertedFromForLoopSyntheticWhileStatement) = visitStatement(ktConvertedFromForLoopSyntheticWhileStatement)
open fun visitAssignmentChainAlsoLink(assignmentChainAlsoLink: JKAssignmentChainAlsoLink) =
visitKtAssignmentChainLink(assignmentChainAlsoLink)
open fun visitAssignmentChainLetLink(assignmentChainLetLink: JKAssignmentChainLetLink) =
visitKtAssignmentChainLink(assignmentChainLetLink)
open fun visitIsExpression(isExpression: JKIsExpression) = visitExpression(isExpression)
open fun visitKtThrowExpression(ktThrowExpression: JKKtThrowExpression) = visitExpression(ktThrowExpression)
open fun visitKtItExpression(ktItExpression: JKKtItExpression) = visitExpression(ktItExpression)
open fun visitKtAnnotationArrayInitializerExpression(ktAnnotationArrayInitializerExpression: JKKtAnnotationArrayInitializerExpression) =
visitExpression(ktAnnotationArrayInitializerExpression)
open fun visitKtTryExpression(ktTryExpression: JKKtTryExpression) = visitExpression(ktTryExpression)
open fun visitKtTryCatchSection(ktTryCatchSection: JKKtTryCatchSection) = visitTreeElement(ktTryCatchSection)
open fun visitKtAnnotationArrayInitializerExpression(ktAnnotationArrayInitializerExpression: JKKtAnnotationArrayInitializerExpression) = visitExpression(ktAnnotationArrayInitializerExpression)
open fun visitKtItExpression(ktItExpression: JKKtItExpression) = visitExpression(ktItExpression)
open fun visitJavaNewEmptyArray(javaNewEmptyArray: JKJavaNewEmptyArray) = visitExpression(javaNewEmptyArray)
open fun visitJavaNewArray(javaNewArray: JKJavaNewArray) = visitExpression(javaNewArray)
open fun visitJavaAssignmentExpression(javaAssignmentExpression: JKJavaAssignmentExpression) = visitExpression(javaAssignmentExpression)
open fun visitModifierElement(modifierElement: JKModifierElement) = visitTreeElement(modifierElement)
open fun visitMutabilityModifierElement(mutabilityModifierElement: JKMutabilityModifierElement) =
visitModifierElement(mutabilityModifierElement)
open fun visitModalityModifierElement(modalityModifierElement: JKModalityModifierElement) =
visitModifierElement(modalityModifierElement)
open fun visitVisibilityModifierElement(visibilityModifierElement: JKVisibilityModifierElement) =
visitModifierElement(visibilityModifierElement)
open fun visitOtherModifierElement(otherModifierElement: JKOtherModifierElement) = visitModifierElement(otherModifierElement)
open fun visitStatement(statement: JKStatement) = visitTreeElement(statement)
open fun visitEmptyStatement(emptyStatement: JKEmptyStatement) = visitStatement(emptyStatement)
open fun visitLoopStatement(loopStatement: JKLoopStatement) = visitStatement(loopStatement)
open fun visitWhileStatement(whileStatement: JKWhileStatement) = visitLoopStatement(whileStatement)
open fun visitDoWhileStatement(doWhileStatement: JKDoWhileStatement) = visitLoopStatement(doWhileStatement)
open fun visitForInStatement(forInStatement: JKForInStatement) = visitStatement(forInStatement)
open fun visitIfElseStatement(ifElseStatement: JKIfElseStatement) = visitStatement(ifElseStatement)
open fun visitBreakStatement(breakStatement: JKBreakStatement) = visitStatement(breakStatement)
open fun visitContinueStatement(continueStatement: JKContinueStatement) = visitStatement(continueStatement)
open fun visitBlockStatement(blockStatement: JKBlockStatement) = visitStatement(blockStatement)
open fun visitBlockStatementWithoutBrackets(blockStatementWithoutBrackets: JKBlockStatementWithoutBrackets) =
visitStatement(blockStatementWithoutBrackets)
open fun visitExpressionStatement(expressionStatement: JKExpressionStatement) = visitStatement(expressionStatement)
open fun visitDeclarationStatement(declarationStatement: JKDeclarationStatement) = visitStatement(declarationStatement)
open fun visitKtWhenStatement(ktWhenStatement: JKKtWhenStatement) = visitStatement(ktWhenStatement)
open fun visitKtConvertedFromForLoopSyntheticWhileStatement(ktConvertedFromForLoopSyntheticWhileStatement: JKKtConvertedFromForLoopSyntheticWhileStatement) =
visitStatement(ktConvertedFromForLoopSyntheticWhileStatement)
open fun visitKtAssignmentStatement(ktAssignmentStatement: JKKtAssignmentStatement) = visitStatement(ktAssignmentStatement)
open fun visitReturnStatement(returnStatement: JKReturnStatement) = visitStatement(returnStatement)
open fun visitJavaSwitchStatement(javaSwitchStatement: JKJavaSwitchStatement) = visitStatement(javaSwitchStatement)
open fun visitJavaThrowStatement(javaThrowStatement: JKJavaThrowStatement) = visitStatement(javaThrowStatement)
open fun visitJavaTryStatement(javaTryStatement: JKJavaTryStatement) = visitStatement(javaTryStatement)
open fun visitJavaSynchronizedStatement(javaSynchronizedStatement: JKJavaSynchronizedStatement) = visitStatement(javaSynchronizedStatement)
open fun visitJavaAssertStatement(javaAssertStatement: JKJavaAssertStatement) = visitStatement(javaAssertStatement)
open fun visitJavaForLoopStatement(javaForLoopStatement: JKJavaForLoopStatement) = visitLoopStatement(javaForLoopStatement)
open fun visitJavaAnnotationMethod(javaAnnotationMethod: JKJavaAnnotationMethod) = visitMethod(javaAnnotationMethod)
}
File diff suppressed because it is too large Load Diff
@@ -11,15 +11,11 @@ import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.j2k.ast.Nullability
import org.jetbrains.kotlin.js.descriptorUtils.getJetTypeFqName
import org.jetbrains.kotlin.js.resolve.diagnostics.findPsi
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.FqNameUnsafe
import org.jetbrains.kotlin.nj2k.JKSymbolProvider
import org.jetbrains.kotlin.nj2k.symbols.JKClassSymbol
import org.jetbrains.kotlin.nj2k.symbols.JKTypeParameterSymbol
import org.jetbrains.kotlin.nj2k.symbols.JKUnresolvedClassSymbol
import org.jetbrains.kotlin.nj2k.tree.JKClass
import org.jetbrains.kotlin.nj2k.tree.JKType
import org.jetbrains.kotlin.nj2k.tree.impl.*
import org.jetbrains.kotlin.psi.KtTypeParameter
import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType
import org.jetbrains.kotlin.types.KotlinType
@@ -8,26 +8,14 @@ package org.jetbrains.kotlin.nj2k.types
import org.jetbrains.kotlin.j2k.ast.Nullability
import org.jetbrains.kotlin.nj2k.symbols.JKClassSymbol
import org.jetbrains.kotlin.nj2k.symbols.JKTypeParameterSymbol
import org.jetbrains.kotlin.nj2k.tree.JKType
import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType
interface JKType {
val nullability: Nullability
}
interface JKWildCardType : JKType
interface JKVarianceTypeParameterType : JKWildCardType {
val variance: Variance
val boundType: JKType
override val nullability: Nullability
get() = Nullability.Default
enum class Variance {
IN, OUT
}
}
interface JKTypeParameterType : JKType {
val identifier: JKTypeParameterSymbol
}
interface JKNoType : JKType
interface JKParametrizedType : JKType {
@@ -39,21 +27,82 @@ interface JKClassType : JKParametrizedType {
override val nullability: Nullability
}
interface JKJavaPrimitiveType : JKType {
val jvmPrimitiveType: JvmPrimitiveType
override val nullability: Nullability
get() = Nullability.NotNull
}
interface JKJavaArrayType : JKType {
val type: JKType
}
interface JKStarProjectionType : JKWildCardType {
override val nullability: Nullability
get() = Nullability.NotNull
}
interface JKJavaDisjunctionType : JKType {
val disjunctions: List<JKType>
}
object JKNoTypeImpl : JKNoType {
override val nullability: Nullability = Nullability.NotNull
}
data class JKClassTypeImpl(
override val classReference: JKClassSymbol,
override val parameters: List<JKType> = emptyList(),
override val nullability: Nullability = Nullability.Default
) : JKClassType
object JKStarProjectionTypeImpl : JKStarProjectionType
object JKContextType : JKType {
override val nullability: Nullability
get() = Nullability.Default
}
data class JKVarianceTypeParameterType(
val variance: Variance,
val boundType: JKType
) : JKWildCardType {
override val nullability: Nullability
get() = Nullability.Default
enum class Variance {
IN, OUT
}
}
data class JKTypeParameterType(
val identifier: JKTypeParameterSymbol,
override val nullability: Nullability = Nullability.Default
) : JKType
data class JKCapturedType(
val wildcardType: JKWildCardType,
override val nullability: Nullability = Nullability.Default
) : JKType
class JKJavaPrimitiveType(val jvmPrimitiveType: JvmPrimitiveType) : JKType {
override val nullability: Nullability
get() = Nullability.NotNull
companion object {
val BOOLEAN = JKJavaPrimitiveType(JvmPrimitiveType.BOOLEAN)
val CHAR = JKJavaPrimitiveType(JvmPrimitiveType.CHAR)
val BYTE = JKJavaPrimitiveType(JvmPrimitiveType.BYTE)
val SHORT = JKJavaPrimitiveType(JvmPrimitiveType.SHORT)
val INT = JKJavaPrimitiveType(JvmPrimitiveType.INT)
val FLOAT = JKJavaPrimitiveType(JvmPrimitiveType.FLOAT)
val LONG = JKJavaPrimitiveType(JvmPrimitiveType.LONG)
val DOUBLE = JKJavaPrimitiveType(JvmPrimitiveType.DOUBLE)
val KEYWORD_TO_INSTANCE = listOf(
BOOLEAN, CHAR, BYTE, SHORT, INT, FLOAT, LONG, DOUBLE
).associateBy { it.jvmPrimitiveType.javaKeywordName } + ("void" to JKJavaVoidType)
}
}
data class JKJavaArrayType(
val type: JKType,
override var nullability: Nullability = Nullability.Default
) : JKType
data class JKJavaDisjunctionType(
val disjunctions: List<JKType>,
override val nullability: Nullability = Nullability.Default
) : JKType
object JKJavaVoidType : JKType {
override val nullability: Nullability
get() = Nullability.NotNull
}
@@ -1,9 +1,9 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.nj2k.tree
package org.jetbrains.kotlin.nj2k.types
import com.intellij.psi.CommonClassNames
import com.intellij.psi.PsiClass
@@ -16,8 +16,9 @@ import org.jetbrains.kotlin.idea.refactoring.fqName.getKotlinFqName
import org.jetbrains.kotlin.j2k.ast.Nullability
import org.jetbrains.kotlin.nj2k.JKSymbolProvider
import org.jetbrains.kotlin.nj2k.symbols.JKClassSymbol
import org.jetbrains.kotlin.nj2k.tree.impl.*
import org.jetbrains.kotlin.nj2k.types.*
import org.jetbrains.kotlin.nj2k.toJkType
import org.jetbrains.kotlin.nj2k.tree.*
import org.jetbrains.kotlin.psi.KtClass
import org.jetbrains.kotlin.psi.KtTypeReference
import org.jetbrains.kotlin.resolve.BindingContext
@@ -35,14 +36,13 @@ fun JKExpression.type(typeFactory: JKTypeFactory): JKType? =
else -> error("Cannot get type of ${operator::class}, it should be first converted to KtOperator")
}
}
is JKMethodCallExpression -> identifier.returnType
is JKFieldAccessExpressionImpl -> identifier.fieldType
is JKQualifiedExpressionImpl -> selector.type(typeFactory)
is JKCallExpression -> identifier.returnType
is JKFieldAccessExpression -> identifier.fieldType
is JKQualifiedExpression -> selector.type(typeFactory)
is JKKtThrowExpression -> typeFactory.types.nothing
is JKClassAccessExpression ->
JKClassTypeImpl(identifier, emptyList(), Nullability.NotNull)
is JKJavaNewExpression -> JKClassTypeImpl(classSymbol)
is JKKtIsExpression -> typeFactory.types.boolean
is JKIsExpression -> typeFactory.types.boolean
is JKParenthesizedExpression -> expression.type(typeFactory)
is JKTypeCastExpression -> type.type
is JKThisExpression -> null// TODO return actual type
@@ -53,28 +53,27 @@ fun JKExpression.type(typeFactory: JKTypeFactory): JKType? =
(expression.type(typeFactory) as? JKParametrizedType)?.parameters?.lastOrNull()
is JKClassLiteralExpression -> {
val symbol = when (literalType) {
JKClassLiteralExpression.LiteralType.KOTLIN_CLASS ->
JKClassLiteralExpression.ClassLiteralType.KOTLIN_CLASS ->
typeFactory.symbolProvider.provideClassSymbol(KotlinBuiltIns.FQ_NAMES.kClass.toSafe())
JKClassLiteralExpression.LiteralType.JAVA_CLASS,
JKClassLiteralExpression.LiteralType.JAVA_PRIMITIVE_CLASS, JKClassLiteralExpression.LiteralType.JAVA_VOID_TYPE ->
JKClassLiteralExpression.ClassLiteralType.JAVA_CLASS,
JKClassLiteralExpression.ClassLiteralType.JAVA_PRIMITIVE_CLASS, JKClassLiteralExpression.ClassLiteralType.JAVA_VOID_TYPE ->
typeFactory.symbolProvider.provideClassSymbol("java.lang.Class")
}
JKClassTypeImpl(symbol, listOf(classType.type), Nullability.NotNull)
}
is JKKtAnnotationArrayInitializerExpression -> JKNoTypeImpl //TODO
is JKLambdaExpression -> returnType.type
is JKLabeledStatement ->
statement.safeAs<JKExpressionStatement>()?.expression?.type(typeFactory)
is JKLabeledExpression -> typeFactory.types.unit
is JKMethodReferenceExpression -> JKNoTypeImpl //TODO
is JKAssignmentChainAlsoLink -> receiver.type(typeFactory)
is JKAssignmentChainLetLink -> field.type(typeFactory)
is JKKtAssignmentStatement -> typeFactory.types.unit
is JKKtItExpression -> type
is JKNewExpression -> JKClassTypeImpl(classSymbol)
else -> TODO(this::class.java.toString())
}
fun JKType.asTypeElement() =
JKTypeElementImpl(this)
JKTypeElement(this)
fun JKClassSymbol.asType(nullability: Nullability = Nullability.Default): JKClassType =
JKClassTypeImpl(this, emptyList(), nullability)
@@ -112,7 +111,7 @@ private val jvmPrimitiveTypesPriority =
fun JKType.applyRecursive(transform: (JKType) -> JKType?): JKType =
transform(this) ?: when (this) {
is JKTypeParameterTypeImpl -> this
is JKTypeParameterType -> this
is JKClassTypeImpl ->
JKClassTypeImpl(
classReference,
@@ -122,10 +121,10 @@ fun JKType.applyRecursive(transform: (JKType) -> JKType?): JKType =
is JKNoType -> this
is JKJavaVoidType -> this
is JKJavaPrimitiveType -> this
is JKJavaArrayType -> JKJavaArrayTypeImpl(type.applyRecursive(transform), nullability)
is JKJavaArrayType -> JKJavaArrayType(type.applyRecursive(transform), nullability)
is JKContextType -> JKContextType
is JKJavaDisjunctionType ->
JKJavaDisjunctionTypeImpl(disjunctions.map { it.applyRecursive(transform) }, nullability)
JKJavaDisjunctionType(disjunctions.map { it.applyRecursive(transform) }, nullability)
is JKStarProjectionType -> this
else -> TODO(this::class.toString())
}
@@ -133,12 +132,12 @@ fun JKType.applyRecursive(transform: (JKType) -> JKType?): JKType =
inline fun <reified T : JKType> T.updateNullability(newNullability: Nullability): T =
if (nullability == newNullability) this
else when (this) {
is JKTypeParameterTypeImpl -> JKTypeParameterTypeImpl(identifier, newNullability)
is JKTypeParameterType -> JKTypeParameterType(identifier, newNullability)
is JKClassTypeImpl -> JKClassTypeImpl(classReference, parameters, newNullability)
is JKNoType -> this
is JKJavaVoidType -> this
is JKJavaPrimitiveType -> this
is JKJavaArrayType -> JKJavaArrayTypeImpl(type, newNullability)
is JKJavaArrayType -> JKJavaArrayType(type, newNullability)
is JKContextType -> JKContextType
is JKJavaDisjunctionType -> this
else -> TODO(this::class.toString())
@@ -148,14 +147,14 @@ inline fun <reified T : JKType> T.updateNullability(newNullability: Nullability)
fun <T : JKType> T.updateNullabilityRecursively(newNullability: Nullability): T =
applyRecursive {
when (it) {
is JKTypeParameterTypeImpl -> JKTypeParameterTypeImpl(it.identifier, newNullability)
is JKTypeParameterType -> JKTypeParameterType(it.identifier, newNullability)
is JKClassTypeImpl ->
JKClassTypeImpl(
it.classReference,
it.parameters.map { it.updateNullabilityRecursively(newNullability) },
newNullability
)
is JKJavaArrayType -> JKJavaArrayTypeImpl(it.type.updateNullabilityRecursively(newNullability), newNullability)
is JKJavaArrayType -> JKJavaArrayType(it.type.updateNullabilityRecursively(newNullability), newNullability)
else -> null
}
} as T
@@ -183,14 +182,14 @@ fun JKJavaPrimitiveType.toLiteralType(): JKLiteralExpression.LiteralType? =
fun JKType.asPrimitiveType(): JKJavaPrimitiveType? =
if (this is JKJavaPrimitiveType) this
else when ((this as? JKClassType)?.classReference?.fqName) {
KotlinBuiltIns.FQ_NAMES._char.asString(), CommonClassNames.JAVA_LANG_CHARACTER -> JKJavaPrimitiveTypeImpl.CHAR
KotlinBuiltIns.FQ_NAMES._boolean.asString(), CommonClassNames.JAVA_LANG_BOOLEAN -> JKJavaPrimitiveTypeImpl.BOOLEAN
KotlinBuiltIns.FQ_NAMES._int.asString(), CommonClassNames.JAVA_LANG_INTEGER -> JKJavaPrimitiveTypeImpl.INT
KotlinBuiltIns.FQ_NAMES._long.asString(), CommonClassNames.JAVA_LANG_LONG -> JKJavaPrimitiveTypeImpl.LONG
KotlinBuiltIns.FQ_NAMES._float.asString(), CommonClassNames.JAVA_LANG_FLOAT -> JKJavaPrimitiveTypeImpl.FLOAT
KotlinBuiltIns.FQ_NAMES._double.asString(), CommonClassNames.JAVA_LANG_DOUBLE -> JKJavaPrimitiveTypeImpl.DOUBLE
KotlinBuiltIns.FQ_NAMES._byte.asString(), CommonClassNames.JAVA_LANG_BYTE -> JKJavaPrimitiveTypeImpl.BYTE
KotlinBuiltIns.FQ_NAMES._short.asString(), CommonClassNames.JAVA_LANG_SHORT -> JKJavaPrimitiveTypeImpl.SHORT
KotlinBuiltIns.FQ_NAMES._char.asString(), CommonClassNames.JAVA_LANG_CHARACTER -> JKJavaPrimitiveType.CHAR
KotlinBuiltIns.FQ_NAMES._boolean.asString(), CommonClassNames.JAVA_LANG_BOOLEAN -> JKJavaPrimitiveType.BOOLEAN
KotlinBuiltIns.FQ_NAMES._int.asString(), CommonClassNames.JAVA_LANG_INTEGER -> JKJavaPrimitiveType.INT
KotlinBuiltIns.FQ_NAMES._long.asString(), CommonClassNames.JAVA_LANG_LONG -> JKJavaPrimitiveType.LONG
KotlinBuiltIns.FQ_NAMES._float.asString(), CommonClassNames.JAVA_LANG_FLOAT -> JKJavaPrimitiveType.FLOAT
KotlinBuiltIns.FQ_NAMES._double.asString(), CommonClassNames.JAVA_LANG_DOUBLE -> JKJavaPrimitiveType.DOUBLE
KotlinBuiltIns.FQ_NAMES._byte.asString(), CommonClassNames.JAVA_LANG_BYTE -> JKJavaPrimitiveType.BYTE
KotlinBuiltIns.FQ_NAMES._short.asString(), CommonClassNames.JAVA_LANG_SHORT -> JKJavaPrimitiveType.SHORT
else -> null
}
@@ -221,7 +220,7 @@ fun JKType.arrayFqName(): String =
fun JKClassSymbol.isArrayType(): Boolean =
fqName in arrayFqNames
private val arrayFqNames = JKJavaPrimitiveTypeImpl.KEYWORD_TO_INSTANCE.values
private val arrayFqNames = JKJavaPrimitiveType.KEYWORD_TO_INSTANCE.values
.filterIsInstance<JKJavaPrimitiveType>()
.map { PrimitiveType.valueOf(it.jvmPrimitiveType.name).arrayTypeFqName.asString() } +
KotlinBuiltIns.FQ_NAMES.array.asString()
+1 -1
View File
@@ -29,6 +29,6 @@ internal class A {
fun foo(param1: String?, param2: String?, param3: String?) {}
companion object {
/*it's public*/ /*and static*/ const val/*and final*/ C = 1
/*it's public*/ /*and static*/ /*and final*/ const val C = 1
}
}