New J2K: Add anonymous object creation support JKNewExpression
This commit is contained in:
committed by
Ilya Kirillov
parent
f58d791a05
commit
e1108e1764
@@ -173,43 +173,43 @@ class JavaToJKTreeBuilder(var symbolProvider: JKSymbolProvider) {
|
|||||||
|
|
||||||
fun PsiNewExpression.toJK(): JKExpression {
|
fun PsiNewExpression.toJK(): JKExpression {
|
||||||
require(this is PsiNewExpressionImpl)
|
require(this is PsiNewExpressionImpl)
|
||||||
if (findChildByRole(ChildRole.LBRACKET) != null) {
|
val newExpression =
|
||||||
return arrayInitializer?.toJK() ?: run {
|
if (findChildByRole(ChildRole.LBRACKET) != null) {
|
||||||
val dimensions = mutableListOf<PsiExpression?>()
|
arrayInitializer?.toJK() ?: run {
|
||||||
var child = firstChild
|
val dimensions = mutableListOf<PsiExpression?>()
|
||||||
while (child != null) {
|
var child = firstChild
|
||||||
if (child.node.elementType == JavaTokenType.LBRACKET) {
|
while (child != null) {
|
||||||
child = child.nextSibling
|
if (child.node.elementType == JavaTokenType.LBRACKET) {
|
||||||
dimensions += if (child.node.elementType == JavaTokenType.RBRACKET) {
|
child = child.nextSibling
|
||||||
null
|
dimensions += if (child.node.elementType == JavaTokenType.RBRACKET) {
|
||||||
} else {
|
null
|
||||||
child as PsiExpression? //TODO
|
} else {
|
||||||
|
child as PsiExpression? //TODO
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
child = child.nextSibling
|
||||||
|
}
|
||||||
|
JKJavaNewEmptyArrayImpl(
|
||||||
|
dimensions.map { it?.toJK() ?: JKStubExpressionImpl() },
|
||||||
|
JKTypeElementImpl(generateSequence(type?.toJK(symbolProvider)) { it.safeAs<JKJavaArrayType>()?.type }.last())
|
||||||
|
).also {
|
||||||
|
it.psi = this
|
||||||
}
|
}
|
||||||
child = child.nextSibling
|
|
||||||
}
|
|
||||||
JKJavaNewEmptyArrayImpl(
|
|
||||||
dimensions.map { it?.toJK() ?: JKStubExpressionImpl() },
|
|
||||||
JKTypeElementImpl(generateSequence(type?.toJK(symbolProvider)) { it.safeAs<JKJavaArrayType>()?.type }.last())
|
|
||||||
).also {
|
|
||||||
it.psi = this
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
val classSymbol =
|
||||||
|
classOrAnonymousClassReference?.resolve()?.let {
|
||||||
|
symbolProvider.provideDirectSymbol(it) as JKClassSymbol
|
||||||
|
} ?: JKUnresolvedClassSymbol(classOrAnonymousClassReference!!.text)
|
||||||
|
|
||||||
|
JKJavaNewExpressionImpl(
|
||||||
|
classSymbol,
|
||||||
|
argumentList.toJK(),
|
||||||
|
typeArgumentList.toJK(),
|
||||||
|
with(declarationMapper) { anonymousClass?.createClassBody() } ?: JKEmptyClassBodyImpl()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
return qualifier?.let { JKQualifiedExpressionImpl(it.toJK(), JKJavaQualifierImpl.DOT, newExpression) } ?: newExpression
|
||||||
val constructedClass = classOrAnonymousClassReference?.resolve()
|
|
||||||
val constructor = constructorFakeReference.resolve()
|
|
||||||
if (constructor == null && constructedClass != null) {
|
|
||||||
return JKJavaDefaultNewExpressionImpl(
|
|
||||||
symbolProvider.provideDirectSymbol(constructedClass) as JKClassSymbol
|
|
||||||
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
return JKJavaNewExpressionImpl(
|
|
||||||
symbolProvider.provideDirectSymbol(constructor!!) as JKMethodSymbol,
|
|
||||||
argumentList.toJK(),
|
|
||||||
typeArgumentList.toJK()
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun PsiReferenceParameterList.toJK(): JKTypeArgumentList =
|
fun PsiReferenceParameterList.toJK(): JKTypeArgumentList =
|
||||||
@@ -268,16 +268,22 @@ class JavaToJKTreeBuilder(var symbolProvider: JKSymbolProvider) {
|
|||||||
JKNameIdentifierImpl(name!!),
|
JKNameIdentifierImpl(name!!),
|
||||||
JKInheritanceInfoImpl(extTypes + implTypes),
|
JKInheritanceInfoImpl(extTypes + implTypes),
|
||||||
classKind,
|
classKind,
|
||||||
typeParameterList?.toJK() ?: JKTypeParameterListImpl()
|
typeParameterList?.toJK() ?: JKTypeParameterListImpl(),
|
||||||
|
createClassBody()
|
||||||
).also { jkClassImpl ->
|
).also { jkClassImpl ->
|
||||||
jkClassImpl.declarationList = children.mapNotNull {
|
|
||||||
ElementVisitor().apply { it.accept(this) }.resultElement as? JKDeclaration
|
|
||||||
}
|
|
||||||
jkClassImpl.psi = this
|
jkClassImpl.psi = this
|
||||||
symbolProvider.provideUniverseSymbol(this, jkClassImpl)
|
symbolProvider.provideUniverseSymbol(this, jkClassImpl)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun PsiClass.createClassBody() =
|
||||||
|
JKClassBodyImpl(
|
||||||
|
children.mapNotNull {
|
||||||
|
ElementVisitor().apply { it.accept(this) }.resultElement as? JKDeclaration
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
fun PsiEnumConstant.toJK(): JKEnumConstant =
|
fun PsiEnumConstant.toJK(): JKEnumConstant =
|
||||||
JKEnumConstantImpl(
|
JKEnumConstantImpl(
|
||||||
JKNameIdentifierImpl(name),
|
JKNameIdentifierImpl(name),
|
||||||
|
|||||||
@@ -16,8 +16,6 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.j2k
|
package org.jetbrains.kotlin.j2k
|
||||||
|
|
||||||
import com.intellij.psi.PsiMethod
|
|
||||||
import org.jetbrains.kotlin.idea.refactoring.fqName.getKotlinFqName
|
|
||||||
import org.jetbrains.kotlin.j2k.NewCodeBuilder.ParenthesisKind.*
|
import org.jetbrains.kotlin.j2k.NewCodeBuilder.ParenthesisKind.*
|
||||||
import org.jetbrains.kotlin.j2k.ast.Mutability
|
import org.jetbrains.kotlin.j2k.ast.Mutability
|
||||||
import org.jetbrains.kotlin.j2k.ast.Nullability
|
import org.jetbrains.kotlin.j2k.ast.Nullability
|
||||||
@@ -25,8 +23,6 @@ import org.jetbrains.kotlin.j2k.tree.*
|
|||||||
import org.jetbrains.kotlin.j2k.tree.impl.*
|
import org.jetbrains.kotlin.j2k.tree.impl.*
|
||||||
import org.jetbrains.kotlin.j2k.tree.visitors.JKVisitorVoid
|
import org.jetbrains.kotlin.j2k.tree.visitors.JKVisitorVoid
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.psi.KtFunction
|
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
|
|
||||||
import org.jetbrains.kotlin.utils.Printer
|
import org.jetbrains.kotlin.utils.Printer
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
|
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
|
||||||
|
|
||||||
@@ -241,15 +237,7 @@ class NewCodeBuilder {
|
|||||||
//TODO should it be here?
|
//TODO should it be here?
|
||||||
renderExtraTypeParametersUpperBounds(klass.typeParameterList)
|
renderExtraTypeParametersUpperBounds(klass.typeParameterList)
|
||||||
|
|
||||||
val declarationsToPrint = klass.declarationList.filterNot { it is JKKtPrimaryConstructor}
|
klass.classBody.accept(this)
|
||||||
if (declarationsToPrint.isNotEmpty()) {
|
|
||||||
printer.block(multiline = true) {
|
|
||||||
renderEnumConstants(declarationsToPrint.filterIsInstance())
|
|
||||||
renderNonEnumClassDeclarations(declarationsToPrint.filterNot { it is JKEnumConstant })
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
printer.println()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun renderEnumConstants(enumConstants: List<JKEnumConstant>) {
|
private fun renderEnumConstants(enumConstants: List<JKEnumConstant>) {
|
||||||
@@ -619,13 +607,36 @@ class NewCodeBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun visitJavaNewExpression(javaNewExpression: JKJavaNewExpression) {
|
override fun visitJavaNewExpression(javaNewExpression: JKJavaNewExpression) {
|
||||||
printer.printWithNoIndent(javaNewExpression.identifier.name)
|
if (javaNewExpression.isAnonymousClass()) {
|
||||||
|
printer.printWithNoIndent("object : ")
|
||||||
|
}
|
||||||
|
printer.printWithNoIndent(javaNewExpression.classSymbol.name)
|
||||||
javaNewExpression.typeArgumentList.accept(this)
|
javaNewExpression.typeArgumentList.accept(this)
|
||||||
printer.par(ROUND) {
|
if (javaNewExpression.constructorIsPresent()) {
|
||||||
javaNewExpression.arguments.accept(this)
|
printer.par(ROUND) {
|
||||||
|
javaNewExpression.arguments.accept(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (javaNewExpression.isAnonymousClass()) {
|
||||||
|
javaNewExpression.classBody.accept(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
override fun visitClassBody(classBody: JKClassBody) {
|
||||||
|
val declarationsToPrint = classBody.declarations.filterNot { it is JKKtPrimaryConstructor }
|
||||||
|
if (declarationsToPrint.isNotEmpty()) {
|
||||||
|
printer.block(multiline = true) {
|
||||||
|
renderEnumConstants(declarationsToPrint.filterIsInstance())
|
||||||
|
renderNonEnumClassDeclarations(declarationsToPrint.filterNot { it is JKEnumConstant })
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
printer.println()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitEmptyClassBody(emptyClassBody: JKEmptyClassBody) {}
|
||||||
|
|
||||||
override fun visitTypeElement(typeElement: JKTypeElement) {
|
override fun visitTypeElement(typeElement: JKTypeElement) {
|
||||||
renderType(typeElement.type)
|
renderType(typeElement.type)
|
||||||
}
|
}
|
||||||
@@ -687,7 +698,7 @@ class NewCodeBuilder {
|
|||||||
|
|
||||||
override fun visitKtPrimaryConstructor(ktPrimaryConstructor: JKKtPrimaryConstructor) {
|
override fun visitKtPrimaryConstructor(ktPrimaryConstructor: JKKtPrimaryConstructor) {
|
||||||
val hasInitDeclaration =
|
val hasInitDeclaration =
|
||||||
(ktPrimaryConstructor.parent as JKClass).declarationList.any { it is JKKtInitDeclaration }
|
(ktPrimaryConstructor.parent as JKClassBody).declarations.any { it is JKKtInitDeclaration }
|
||||||
val hasAccessModifier =
|
val hasAccessModifier =
|
||||||
ktPrimaryConstructor.modifierList.modifiers.any { it is JKAccessModifier }
|
ktPrimaryConstructor.modifierList.modifiers.any { it is JKAccessModifier }
|
||||||
if (hasAccessModifier && hasInitDeclaration && ktPrimaryConstructor.parameters.isNotEmpty()) {
|
if (hasAccessModifier && hasInitDeclaration && ktPrimaryConstructor.parameters.isNotEmpty()) {
|
||||||
@@ -802,13 +813,7 @@ class NewCodeBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun visitJavaNewExpression(javaNewExpression: JKJavaNewExpression) {
|
override fun visitJavaNewExpression(javaNewExpression: JKJavaNewExpression) {
|
||||||
val psiConstructor = javaNewExpression.identifier.target
|
collectedFqNames.add(FqName(javaNewExpression.classSymbol.fqName!!))
|
||||||
val fqName = when (psiConstructor) {
|
|
||||||
is PsiMethod -> psiConstructor.containingClass?.getKotlinFqName()!!
|
|
||||||
is KtFunction -> psiConstructor.containingClassOrObject?.fqName!!
|
|
||||||
else -> TODO(psiConstructor::class.toString())
|
|
||||||
}
|
|
||||||
collectedFqNames.add(fqName)
|
|
||||||
javaNewExpression.acceptChildren(this)
|
javaNewExpression.acceptChildren(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -834,9 +839,9 @@ private inline fun <T> List<T>.headTail(): Pair<T?, List<T>?> {
|
|||||||
return head to tail
|
return head to tail
|
||||||
}
|
}
|
||||||
|
|
||||||
private inline fun JKClass.primaryConstructor(): JKKtPrimaryConstructor? {
|
private inline fun JKClass.primaryConstructor(): JKKtPrimaryConstructor? =
|
||||||
return this.declarationList.firstIsInstanceOrNull()
|
classBody.declarations.firstIsInstanceOrNull()
|
||||||
}
|
|
||||||
|
|
||||||
private inline fun JKDelegationConstructorCall.isCallOfConstructorOf(type: JKType): Boolean {
|
private inline fun JKDelegationConstructorCall.isCallOfConstructorOf(type: JKType): Boolean {
|
||||||
return when (type) {
|
return when (type) {
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.j2k.ConversionContext
|
|||||||
import org.jetbrains.kotlin.j2k.tree.JKClass
|
import org.jetbrains.kotlin.j2k.tree.JKClass
|
||||||
import org.jetbrains.kotlin.j2k.tree.JKKtPrimaryConstructor
|
import org.jetbrains.kotlin.j2k.tree.JKKtPrimaryConstructor
|
||||||
import org.jetbrains.kotlin.j2k.tree.JKTreeElement
|
import org.jetbrains.kotlin.j2k.tree.JKTreeElement
|
||||||
|
import org.jetbrains.kotlin.j2k.tree.declarationList
|
||||||
import org.jetbrains.kotlin.j2k.tree.impl.JKClassImpl
|
import org.jetbrains.kotlin.j2k.tree.impl.JKClassImpl
|
||||||
import org.jetbrains.kotlin.j2k.tree.impl.psi
|
import org.jetbrains.kotlin.j2k.tree.impl.psi
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
|
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
|
||||||
@@ -38,10 +39,9 @@ class ClassToObjectPromotionConversion(private val context: ConversionContext) :
|
|||||||
element.name,
|
element.name,
|
||||||
element.inheritance,
|
element.inheritance,
|
||||||
JKClass.ClassKind.OBJECT,
|
JKClass.ClassKind.OBJECT,
|
||||||
element.typeParameterList
|
element.typeParameterList,
|
||||||
).apply {
|
companion.classBody
|
||||||
declarationList = companion.declarationList
|
)
|
||||||
}
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ class DefaultArgumentsConversion(private val context: ConversionContext) : Recur
|
|||||||
parameter.initializer = remapParameterSymbol(defaultValue) as JKExpression
|
parameter.initializer = remapParameterSymbol(defaultValue) as JKExpression
|
||||||
}
|
}
|
||||||
|
|
||||||
element.declarationList -= method
|
element.classBody.declarations -= method
|
||||||
}
|
}
|
||||||
|
|
||||||
return recurse(element)
|
return recurse(element)
|
||||||
|
|||||||
+1
-1
@@ -18,7 +18,7 @@ class FieldInitializersInPrimaryFromParamsConversion(private val context: Conver
|
|||||||
if (primaryConstructorConversion.initDeclarationStatements.isNotEmpty()) {
|
if (primaryConstructorConversion.initDeclarationStatements.isNotEmpty()) {
|
||||||
element.getOrCreateInitDeclaration().block = JKBlockImpl(primaryConstructorConversion.initDeclarationStatements)
|
element.getOrCreateInitDeclaration().block = JKBlockImpl(primaryConstructorConversion.initDeclarationStatements)
|
||||||
}
|
}
|
||||||
element.declarationList -= primaryConstructorConversion.declarationsToRemove
|
element.classBody.declarations -= primaryConstructorConversion.declarationsToRemove
|
||||||
return recurse(element)
|
return recurse(element)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||||
* that can be found in the license/LICENSE.txt file.
|
* that can be found in the license/LICENSE.txt file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.jetbrains.kotlin.j2k.conversions
|
package org.jetbrains.kotlin.j2k.conversions
|
||||||
|
|
||||||
@@ -135,7 +135,7 @@ class FieldToPropertyConversion(private val context: ConversionContext) : Recurs
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
element.declarationList =
|
element.classBody.declarations =
|
||||||
declarations.mapNotNull { declaration ->
|
declarations.mapNotNull { declaration ->
|
||||||
when (declaration) {
|
when (declaration) {
|
||||||
is JKJavaField -> propertyInfoFor(declaration.name.value).toKtProperty()
|
is JKJavaField -> propertyInfoFor(declaration.name.value).toKtProperty()
|
||||||
|
|||||||
+1
-1
@@ -25,7 +25,7 @@ class InsertDefaultPrimaryConstructorConversion(private val context: ConversionC
|
|||||||
JKStubExpressionImpl()
|
JKStubExpressionImpl()
|
||||||
)
|
)
|
||||||
|
|
||||||
element.declarationList += constructor
|
element.classBody.declarations += constructor
|
||||||
|
|
||||||
val superClassSymbol = element.inheritance.inherit.map { it.type }
|
val superClassSymbol = element.inheritance.inherit.map { it.type }
|
||||||
.filterIsInstance<JKClassType>()
|
.filterIsInstance<JKClassType>()
|
||||||
|
|||||||
+4
-3
@@ -17,6 +17,7 @@
|
|||||||
package org.jetbrains.kotlin.j2k.conversions
|
package org.jetbrains.kotlin.j2k.conversions
|
||||||
|
|
||||||
import org.jetbrains.kotlin.j2k.tree.JKClass
|
import org.jetbrains.kotlin.j2k.tree.JKClass
|
||||||
|
import org.jetbrains.kotlin.j2k.tree.JKClassBody
|
||||||
import org.jetbrains.kotlin.j2k.tree.JKJavaMethod
|
import org.jetbrains.kotlin.j2k.tree.JKJavaMethod
|
||||||
import org.jetbrains.kotlin.j2k.tree.JKTreeElement
|
import org.jetbrains.kotlin.j2k.tree.JKTreeElement
|
||||||
import org.jetbrains.kotlin.j2k.tree.impl.JKKtFunctionImpl
|
import org.jetbrains.kotlin.j2k.tree.impl.JKKtFunctionImpl
|
||||||
@@ -26,9 +27,9 @@ class JavaMethodToKotlinFunctionConversion : TransformerBasedConversion() {
|
|||||||
element.acceptChildren(this, null)
|
element.acceptChildren(this, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitClass(klass: JKClass) {
|
override fun visitClassBody(classBody: JKClassBody) {
|
||||||
somethingChanged = true
|
somethingChanged = true
|
||||||
klass.declarationList = klass.declarationList.map {
|
classBody.declarations = classBody.declarations.map {
|
||||||
if (it is JKJavaMethod) {
|
if (it is JKJavaMethod) {
|
||||||
it.invalidate()
|
it.invalidate()
|
||||||
JKKtFunctionImpl(
|
JKKtFunctionImpl(
|
||||||
@@ -44,6 +45,6 @@ class JavaMethodToKotlinFunctionConversion : TransformerBasedConversion() {
|
|||||||
it
|
it
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
klass.acceptChildren(this)
|
classBody.acceptChildren(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+2
-2
@@ -24,7 +24,7 @@ class PrimaryConstructorDetectConversion(private val context: ConversionContext)
|
|||||||
val delegationCall = primaryConstructorCandidate.delegationCall as? JKDelegationConstructorCall
|
val delegationCall = primaryConstructorCandidate.delegationCall as? JKDelegationConstructorCall
|
||||||
if (delegationCall?.expression is JKThisExpression) return
|
if (delegationCall?.expression is JKThisExpression) return
|
||||||
|
|
||||||
element.declarationList -= primaryConstructorCandidate
|
element.classBody.declarations -= primaryConstructorCandidate
|
||||||
|
|
||||||
primaryConstructorCandidate.invalidate()
|
primaryConstructorCandidate.invalidate()
|
||||||
|
|
||||||
@@ -39,7 +39,7 @@ class PrimaryConstructorDetectConversion(private val context: ConversionContext)
|
|||||||
|
|
||||||
context.symbolProvider.transferSymbol(primaryConstructor, primaryConstructorCandidate)
|
context.symbolProvider.transferSymbol(primaryConstructor, primaryConstructorCandidate)
|
||||||
|
|
||||||
element.declarationList += primaryConstructor
|
element.classBody.declarations += primaryConstructor
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun detectPrimaryConstructor(constructors: List<JKKtConstructor>): JKKtConstructor? {
|
private fun detectPrimaryConstructor(constructors: List<JKKtConstructor>): JKKtConstructor? {
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import org.jetbrains.kotlin.j2k.tree.*
|
|||||||
class SortClassMembersConversion : RecursiveApplicableConversionBase() {
|
class SortClassMembersConversion : RecursiveApplicableConversionBase() {
|
||||||
override fun applyToElement(element: JKTreeElement): JKTreeElement {
|
override fun applyToElement(element: JKTreeElement): JKTreeElement {
|
||||||
if (element !is JKClass) return recurse(element)
|
if (element !is JKClass) return recurse(element)
|
||||||
element.declarationList = element.declarationList
|
element.classBody.declarations = element.declarationList
|
||||||
.sortedByDescending { it is JKField }
|
.sortedByDescending { it is JKField }
|
||||||
return recurse(element)
|
return recurse(element)
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-4
@@ -21,8 +21,8 @@ class StaticsToCompanionExtractConversion : RecursiveApplicableConversionBase()
|
|||||||
val companion = findOrCreateCompanion(element)
|
val companion = findOrCreateCompanion(element)
|
||||||
|
|
||||||
|
|
||||||
element.declarationList -= statics
|
element.classBody.declarations -= statics
|
||||||
companion.declarationList += statics.onEach { declaration ->
|
companion.classBody.declarations += statics.onEach { declaration ->
|
||||||
(declaration as JKModifierListOwner)
|
(declaration as JKModifierListOwner)
|
||||||
declaration.modifierList.modifiers =
|
declaration.modifierList.modifiers =
|
||||||
declaration.modifierList.modifiers.filterNot { it is JKJavaModifier && it.type == JKJavaModifier.JavaModifierType.STATIC }
|
declaration.modifierList.modifiers.filterNot { it is JKJavaModifier && it.type == JKJavaModifier.JavaModifierType.STATIC }
|
||||||
@@ -49,7 +49,8 @@ class StaticsToCompanionExtractConversion : RecursiveApplicableConversionBase()
|
|||||||
JKNameIdentifierImpl(""),
|
JKNameIdentifierImpl(""),
|
||||||
JKInheritanceInfoImpl(emptyList()),
|
JKInheritanceInfoImpl(emptyList()),
|
||||||
JKClass.ClassKind.COMPANION,
|
JKClass.ClassKind.COMPANION,
|
||||||
JKTypeParameterListImpl()
|
JKTypeParameterListImpl(),
|
||||||
).also { element.declarationList += it }
|
JKClassBodyImpl()
|
||||||
|
).also { element.classBody.declarations += it }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -192,13 +192,27 @@ class JKJavaMethodCallExpressionImpl(
|
|||||||
override var typeArgumentList: JKTypeArgumentList by child(typeArgumentList)
|
override var typeArgumentList: JKTypeArgumentList by child(typeArgumentList)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class JKClassBodyImpl(declarations: List<JKDeclaration> = emptyList()) : JKClassBody, JKBranchElementBase() {
|
||||||
|
override var declarations: List<JKDeclaration> by children(declarations)
|
||||||
|
override fun <R, D> accept(visitor: JKVisitor<R, D>, data: D): R = visitor.visitClassBody(this, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
class JKEmptyClassBodyImpl : JKEmptyClassBody, JKBranchElementBase() {
|
||||||
|
override var declarations: List<JKDeclaration> by children(emptyList())
|
||||||
|
|
||||||
|
override fun <R, D> accept(visitor: JKVisitor<R, D>, data: D): R = visitor.visitEmptyClassBody(this, data)
|
||||||
|
}
|
||||||
|
|
||||||
class JKJavaNewExpressionImpl(
|
class JKJavaNewExpressionImpl(
|
||||||
override var identifier: JKMethodSymbol,
|
override var classSymbol: JKClassSymbol,
|
||||||
arguments: JKExpressionList,
|
arguments: JKExpressionList,
|
||||||
typeArgumentList: JKTypeArgumentList
|
typeArgumentList: JKTypeArgumentList,
|
||||||
|
classBody: JKClassBody = JKEmptyClassBodyImpl()
|
||||||
) : JKJavaNewExpression, JKBranchElementBase(), PsiOwner by PsiOwnerImpl() {
|
) : JKJavaNewExpression, JKBranchElementBase(), PsiOwner by PsiOwnerImpl() {
|
||||||
override val arguments: JKExpressionList by child(arguments)
|
override var arguments: JKExpressionList by child(arguments)
|
||||||
override var typeArgumentList: JKTypeArgumentList by child(typeArgumentList)
|
override var typeArgumentList: JKTypeArgumentList by child(typeArgumentList)
|
||||||
|
override var classBody: JKClassBody by child(classBody)
|
||||||
|
|
||||||
override fun <R, D> accept(visitor: JKVisitor<R, D>, data: D): R = visitor.visitJavaNewExpression(this, data)
|
override fun <R, D> accept(visitor: JKVisitor<R, D>, data: D): R = visitor.visitJavaNewExpression(this, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -292,12 +306,12 @@ class JKJavaPolyadicExpressionImpl(operands: List<JKExpression>, override var to
|
|||||||
}
|
}
|
||||||
|
|
||||||
class JKJavaAssignmentExpressionImpl(
|
class JKJavaAssignmentExpressionImpl(
|
||||||
override var field: JKAssignableExpression,
|
field: JKAssignableExpression,
|
||||||
expression: JKExpression,
|
expression: JKExpression,
|
||||||
override var operator: JKOperator
|
override var operator: JKOperator
|
||||||
) : JKBranchElementBase(), JKJavaAssignmentExpression, PsiOwner by PsiOwnerImpl() {
|
) : JKBranchElementBase(), JKJavaAssignmentExpression, PsiOwner by PsiOwnerImpl() {
|
||||||
override fun <R, D> accept(visitor: JKVisitor<R, D>, data: D): R = visitor.visitJavaAssignmentExpression(this, data)
|
override fun <R, D> accept(visitor: JKVisitor<R, D>, data: D): R = visitor.visitJavaAssignmentExpression(this, data)
|
||||||
|
override var field: JKAssignableExpression by child(field)
|
||||||
override var expression: JKExpression by child(expression)
|
override var expression: JKExpression by child(expression)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -44,15 +44,16 @@ class JKClassImpl(
|
|||||||
name: JKNameIdentifier,
|
name: JKNameIdentifier,
|
||||||
inheritance: JKInheritanceInfo,
|
inheritance: JKInheritanceInfo,
|
||||||
override var classKind: JKClass.ClassKind,
|
override var classKind: JKClass.ClassKind,
|
||||||
typeParameterList: JKTypeParameterList
|
typeParameterList: JKTypeParameterList,
|
||||||
|
classBody: JKClassBody
|
||||||
) : JKClass, JKBranchElementBase(), PsiOwner by PsiOwnerImpl() {
|
) : JKClass, JKBranchElementBase(), PsiOwner by PsiOwnerImpl() {
|
||||||
override fun <R, D> accept(visitor: JKVisitor<R, D>, data: D): R = visitor.visitClass(this, data)
|
override fun <R, D> accept(visitor: JKVisitor<R, D>, data: D): R = visitor.visitClass(this, data)
|
||||||
|
|
||||||
override var name by child(name)
|
override var name by child(name)
|
||||||
override var modifierList by child(modifierList)
|
override var modifierList by child(modifierList)
|
||||||
override var declarationList by children<JKDeclaration>()
|
|
||||||
override val inheritance by child(inheritance)
|
override val inheritance by child(inheritance)
|
||||||
override var typeParameterList: JKTypeParameterList by child(typeParameterList)
|
override var typeParameterList: JKTypeParameterList by child(typeParameterList)
|
||||||
|
override var classBody: JKClassBody by child(classBody)
|
||||||
}
|
}
|
||||||
|
|
||||||
class JKNameIdentifierImpl(override val value: String) : JKNameIdentifier, JKElementBase(), PsiOwner by PsiOwnerImpl() {
|
class JKNameIdentifierImpl(override val value: String) : JKNameIdentifier, JKElementBase(), PsiOwner by PsiOwnerImpl() {
|
||||||
|
|||||||
@@ -241,7 +241,7 @@ fun JKClass.getOrCreateInitDeclaration(): JKKtInitDeclaration {
|
|||||||
val existingDeclaration = declarationList.filterIsInstance<JKKtInitDeclaration>().firstOrNull()
|
val existingDeclaration = declarationList.filterIsInstance<JKKtInitDeclaration>().firstOrNull()
|
||||||
if (existingDeclaration != null) return existingDeclaration
|
if (existingDeclaration != null) return existingDeclaration
|
||||||
val newDeclaration = JKKtInitDeclarationImpl(JKBlockImpl())
|
val newDeclaration = JKKtInitDeclarationImpl(JKBlockImpl())
|
||||||
declarationList += newDeclaration
|
classBody.declarations += newDeclaration
|
||||||
return newDeclaration
|
return newDeclaration
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,8 +16,9 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.j2k.tree
|
package org.jetbrains.kotlin.j2k.tree
|
||||||
|
|
||||||
import org.jetbrains.kotlin.j2k.tree.impl.JKClassSymbol
|
import org.jetbrains.kotlin.idea.search.usagesSearch.constructor
|
||||||
import org.jetbrains.kotlin.j2k.tree.impl.JKMethodSymbol
|
import org.jetbrains.kotlin.j2k.tree.impl.*
|
||||||
|
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstance
|
||||||
|
|
||||||
interface JKJavaField : JKField, JKBranchElement
|
interface JKJavaField : JKField, JKBranchElement
|
||||||
|
|
||||||
@@ -26,7 +27,32 @@ interface JKJavaMethod : JKMethod, JKBranchElement {
|
|||||||
|
|
||||||
interface JKJavaMethodCallExpression : JKMethodCallExpression
|
interface JKJavaMethodCallExpression : JKMethodCallExpression
|
||||||
|
|
||||||
interface JKJavaNewExpression : JKMethodCallExpression
|
interface JKClassBody : JKTreeElement, JKBranchElement {
|
||||||
|
var declarations: List<JKDeclaration>
|
||||||
|
}
|
||||||
|
|
||||||
|
interface JKEmptyClassBody : JKClassBody
|
||||||
|
|
||||||
|
interface JKJavaNewExpression : JKExpression, JKTypeArgumentListOwner {
|
||||||
|
val classSymbol: JKClassSymbol
|
||||||
|
var arguments: JKExpressionList
|
||||||
|
var classBody: JKClassBody
|
||||||
|
}
|
||||||
|
|
||||||
|
fun JKJavaNewExpression.isAnonymousClass() =
|
||||||
|
classBody !is JKEmptyClassBody
|
||||||
|
|
||||||
|
fun JKJavaNewExpression.constructorIsPresent(): Boolean {
|
||||||
|
if (arguments.expressions.isNotEmpty()) return true
|
||||||
|
val symbol = classSymbol
|
||||||
|
return when (symbol) {
|
||||||
|
is JKMultiverseClassSymbol -> symbol.target.constructors.isNotEmpty()
|
||||||
|
is JKMultiverseKtClassSymbol -> symbol.target.constructor != null
|
||||||
|
is JKUniverseClassSymbol -> symbol.target.classBody.declarations.any { it is JKKtConstructor }
|
||||||
|
is JKUnresolvedClassSymbol -> true //TODO ???
|
||||||
|
else -> TODO(symbol::class.toString())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
interface JKJavaDefaultNewExpression : JKExpression {
|
interface JKJavaDefaultNewExpression : JKExpression {
|
||||||
val classSymbol: JKClassSymbol
|
val classSymbol: JKClassSymbol
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ interface JKClass : JKDeclaration, JKModifierListOwner, JKTypeParameterListOwner
|
|||||||
|
|
||||||
val inheritance: JKInheritanceInfo
|
val inheritance: JKInheritanceInfo
|
||||||
|
|
||||||
var declarationList: List<JKDeclaration>
|
var classBody: JKClassBody
|
||||||
var classKind: ClassKind
|
var classKind: ClassKind
|
||||||
|
|
||||||
enum class ClassKind {
|
enum class ClassKind {
|
||||||
@@ -58,6 +58,10 @@ interface JKClass : JKDeclaration, JKModifierListOwner, JKTypeParameterListOwner
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val JKClass.declarationList: List<JKDeclaration>
|
||||||
|
get() = classBody.declarations
|
||||||
|
|
||||||
|
|
||||||
interface JKInheritanceInfo : JKTreeElement, JKBranchElement {
|
interface JKInheritanceInfo : JKTreeElement, JKBranchElement {
|
||||||
val inherit: List<JKTypeElement>
|
val inherit: List<JKTypeElement>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -130,4 +130,7 @@ fun <T : JKElement> KProperty0<List<T>>.detached(): List<T> =
|
|||||||
get().also { list -> list.forEach { detach(it) } }
|
get().also { list -> list.forEach { detach(it) } }
|
||||||
|
|
||||||
fun <T : JKElement> T.detached(from: JKElement): T =
|
fun <T : JKElement> T.detached(from: JKElement): T =
|
||||||
also { it.detach(from) }
|
also { it.detach(from) }
|
||||||
|
|
||||||
|
fun <T : JKBranchElement> T.invalidated(): T =
|
||||||
|
also { it.invalidate() }
|
||||||
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.util.*
|
import org.jetbrains.kotlin.idea.caches.resolve.util.*
|
||||||
import org.jetbrains.kotlin.j2k.kotlinTypeByName
|
import org.jetbrains.kotlin.j2k.kotlinTypeByName
|
||||||
|
import org.jetbrains.kotlin.psi.KtNullableType
|
||||||
|
|
||||||
fun JKExpression.type(context: ConversionContext): JKType =
|
fun JKExpression.type(context: ConversionContext): JKType =
|
||||||
when (this) {
|
when (this) {
|
||||||
@@ -109,6 +110,8 @@ fun KtTypeElement.toJK(symbolProvider: JKSymbolProvider): JKType =
|
|||||||
|
|
||||||
JKClassTypeImpl(symbol, typeParameters)
|
JKClassTypeImpl(symbol, typeParameters)
|
||||||
}
|
}
|
||||||
|
is KtNullableType ->
|
||||||
|
innerType!!.toJK(symbolProvider).updateNullability(Nullability.Nullable)
|
||||||
else -> TODO(this::class.java.toString())
|
else -> TODO(this::class.java.toString())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -75,7 +75,9 @@ interface JKVisitor<out R, in D> {
|
|||||||
fun visitJavaField(javaField: JKJavaField, data: D): R = visitField(javaField, data)
|
fun visitJavaField(javaField: JKJavaField, data: D): R = visitField(javaField, data)
|
||||||
fun visitJavaMethod(javaMethod: JKJavaMethod, data: D): R = visitMethod(javaMethod, data)
|
fun visitJavaMethod(javaMethod: JKJavaMethod, data: D): R = visitMethod(javaMethod, data)
|
||||||
fun visitJavaMethodCallExpression(javaMethodCallExpression: JKJavaMethodCallExpression, data: D): R = visitMethodCallExpression(javaMethodCallExpression, data)
|
fun visitJavaMethodCallExpression(javaMethodCallExpression: JKJavaMethodCallExpression, data: D): R = visitMethodCallExpression(javaMethodCallExpression, data)
|
||||||
fun visitJavaNewExpression(javaNewExpression: JKJavaNewExpression, data: D): R = visitMethodCallExpression(javaNewExpression, data)
|
fun visitClassBody(classBody: JKClassBody, data: D): R = visitTreeElement(classBody, data)
|
||||||
|
fun visitEmptyClassBody(emptyClassBody: JKEmptyClassBody, data: D): R = visitClassBody(emptyClassBody, data)
|
||||||
|
fun visitJavaNewExpression(javaNewExpression: JKJavaNewExpression, data: D): R = visitExpression(javaNewExpression, data)
|
||||||
fun visitJavaDefaultNewExpression(javaDefaultNewExpression: JKJavaDefaultNewExpression, data: D): R = visitExpression(javaDefaultNewExpression, data)
|
fun visitJavaDefaultNewExpression(javaDefaultNewExpression: JKJavaDefaultNewExpression, data: D): R = visitExpression(javaDefaultNewExpression, data)
|
||||||
fun visitJavaModifier(javaModifier: JKJavaModifier, data: D): R = visitModifier(javaModifier, data)
|
fun visitJavaModifier(javaModifier: JKJavaModifier, data: D): R = visitModifier(javaModifier, data)
|
||||||
fun visitJavaNewEmptyArray(javaNewEmptyArray: JKJavaNewEmptyArray, data: D): R = visitExpression(javaNewEmptyArray, data)
|
fun visitJavaNewEmptyArray(javaNewEmptyArray: JKJavaNewEmptyArray, data: D): R = visitExpression(javaNewEmptyArray, data)
|
||||||
|
|||||||
@@ -147,7 +147,11 @@ interface JKVisitorVoid : JKVisitor<Unit, Nothing?> {
|
|||||||
override fun visitJavaMethod(javaMethod: JKJavaMethod, data: Nothing?) = visitJavaMethod(javaMethod)
|
override fun visitJavaMethod(javaMethod: JKJavaMethod, data: Nothing?) = visitJavaMethod(javaMethod)
|
||||||
fun visitJavaMethodCallExpression(javaMethodCallExpression: JKJavaMethodCallExpression) = visitMethodCallExpression(javaMethodCallExpression, null)
|
fun visitJavaMethodCallExpression(javaMethodCallExpression: JKJavaMethodCallExpression) = visitMethodCallExpression(javaMethodCallExpression, null)
|
||||||
override fun visitJavaMethodCallExpression(javaMethodCallExpression: JKJavaMethodCallExpression, data: Nothing?) = visitJavaMethodCallExpression(javaMethodCallExpression)
|
override fun visitJavaMethodCallExpression(javaMethodCallExpression: JKJavaMethodCallExpression, data: Nothing?) = visitJavaMethodCallExpression(javaMethodCallExpression)
|
||||||
fun visitJavaNewExpression(javaNewExpression: JKJavaNewExpression) = visitMethodCallExpression(javaNewExpression, null)
|
fun visitClassBody(classBody: JKClassBody) = visitTreeElement(classBody, null)
|
||||||
|
override fun visitClassBody(classBody: JKClassBody, data: Nothing?) = visitClassBody(classBody)
|
||||||
|
fun visitEmptyClassBody(emptyClassBody: JKEmptyClassBody) = visitClassBody(emptyClassBody, null)
|
||||||
|
override fun visitEmptyClassBody(emptyClassBody: JKEmptyClassBody, data: Nothing?) = visitEmptyClassBody(emptyClassBody)
|
||||||
|
fun visitJavaNewExpression(javaNewExpression: JKJavaNewExpression) = visitExpression(javaNewExpression, null)
|
||||||
override fun visitJavaNewExpression(javaNewExpression: JKJavaNewExpression, data: Nothing?) = visitJavaNewExpression(javaNewExpression)
|
override fun visitJavaNewExpression(javaNewExpression: JKJavaNewExpression, data: Nothing?) = visitJavaNewExpression(javaNewExpression)
|
||||||
fun visitJavaDefaultNewExpression(javaDefaultNewExpression: JKJavaDefaultNewExpression) = visitExpression(javaDefaultNewExpression, null)
|
fun visitJavaDefaultNewExpression(javaDefaultNewExpression: JKJavaDefaultNewExpression) = visitExpression(javaDefaultNewExpression, null)
|
||||||
override fun visitJavaDefaultNewExpression(javaDefaultNewExpression: JKJavaDefaultNewExpression, data: Nothing?) = visitJavaDefaultNewExpression(javaDefaultNewExpression)
|
override fun visitJavaDefaultNewExpression(javaDefaultNewExpression: JKJavaDefaultNewExpression, data: Nothing?) = visitJavaDefaultNewExpression(javaDefaultNewExpression)
|
||||||
|
|||||||
Reference in New Issue
Block a user