New J2K: WIP: Type mapper
This commit is contained in:
committed by
Ilya Kirillov
parent
f64c32fd71
commit
7cccb99982
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.j2k
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.j2k.tree.JKElement
|
||||
|
||||
data class ConversionContext(
|
||||
val symbolProvider: JKSymbolProvider,
|
||||
val project: Project,
|
||||
val backAnnotator: (JKElement) -> PsiElement?
|
||||
)
|
||||
@@ -18,15 +18,17 @@ package org.jetbrains.kotlin.j2k
|
||||
|
||||
import org.jetbrains.kotlin.j2k.conversions.FieldToPropertyConversion
|
||||
import org.jetbrains.kotlin.j2k.conversions.JavaMethodToKotlinFunctionConversion
|
||||
import org.jetbrains.kotlin.j2k.conversions.TypeMappingConversion
|
||||
import org.jetbrains.kotlin.j2k.tree.JKTreeElement
|
||||
|
||||
object ConversionsRunner {
|
||||
|
||||
fun doApply(trees: List<JKTreeElement>) {
|
||||
fun doApply(trees: List<JKTreeElement>, context: ConversionContext) {
|
||||
|
||||
trees.forEach {
|
||||
FieldToPropertyConversion().runConversion(it)
|
||||
JavaMethodToKotlinFunctionConversion().runConversion(it)
|
||||
FieldToPropertyConversion().runConversion(it, context)
|
||||
TypeMappingConversion(context).runConversion(it, context)
|
||||
JavaMethodToKotlinFunctionConversion().runConversion(it, context)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.j2k
|
||||
|
||||
|
||||
class JKSymbolProvider {
|
||||
//
|
||||
//
|
||||
// fun provideSymbol(clz: PsiClass): JKClassSymbol {
|
||||
//
|
||||
// }
|
||||
//
|
||||
// fun provideSymbol(clz: KtClassOrObject): JKClassSymbol {
|
||||
//
|
||||
// }
|
||||
}
|
||||
@@ -34,6 +34,8 @@ class JavaToJKTreeBuilder {
|
||||
|
||||
private val modifierMapper = ModifierMapper()
|
||||
|
||||
val backAnnotation = mutableMapOf<JKElement, PsiElement>()
|
||||
|
||||
val symbols = mutableMapOf<PsiElement, JKSymbol>()
|
||||
|
||||
val symbolsByDeclaration = mutableMapOf<JKDeclaration, JKSymbol>()
|
||||
@@ -152,11 +154,16 @@ class JavaToJKTreeBuilder {
|
||||
|
||||
fun PsiReferenceExpression.toJK(): JKExpression {
|
||||
val impl = this as PsiReferenceExpressionImpl
|
||||
if (impl.resolve() !is PsiField) {
|
||||
return JKNullLiteral() // TODO !!!
|
||||
}
|
||||
|
||||
val access = JKJavaFieldAccessExpressionImpl(JKMultiverseFieldSymbol(impl.resolve() as PsiField))
|
||||
return if (impl.findChildByRole(ChildRole.DOT) != null) {
|
||||
JKQualifiedExpressionImpl((impl.qualifier as PsiExpression).toJK(), JKJavaQualifierImpl.DOT, access)
|
||||
} else {
|
||||
access
|
||||
return when {
|
||||
impl.findChildByRole(ChildRole.DOT) != null &&
|
||||
(impl.qualifierExpression as? PsiReferenceExpression)?.resolve() !is PsiClass ->
|
||||
JKQualifiedExpressionImpl((impl.qualifier as PsiExpression).toJK(), JKJavaQualifierImpl.DOT, access)
|
||||
else -> access
|
||||
}
|
||||
}
|
||||
|
||||
@@ -191,7 +198,7 @@ class JavaToJKTreeBuilder {
|
||||
}
|
||||
|
||||
fun PsiTypeCastExpression.toJK(): JKExpression {
|
||||
return JKTypeCastExpressionImpl(operand?.toJK() ?: TODO(), castType?.type?.toJK() ?: TODO())
|
||||
return JKTypeCastExpressionImpl(operand?.toJK() ?: TODO(), castType?.toJK() ?: TODO())
|
||||
}
|
||||
|
||||
fun PsiParenthesizedExpression.toJK(): JKExpression {
|
||||
@@ -202,9 +209,18 @@ class JavaToJKTreeBuilder {
|
||||
return JKExpressionListImpl(this?.expressions?.map { it.toJK() } ?: emptyList())
|
||||
}
|
||||
|
||||
fun PsiTypeElement.toJK(): JKType {
|
||||
return type.toJK().also {
|
||||
backAnnotation[it] = this
|
||||
}
|
||||
}
|
||||
|
||||
fun PsiType.toJK(): JKType {
|
||||
return when (this) {
|
||||
is PsiClassType -> JKClassTypeImpl(resolve()?.let { provideSymbol(it) as? JKClassSymbol }!!, parameters.map { it.toJK() })
|
||||
is PsiClassType -> JKClassTypeImpl(
|
||||
resolve()?.let { provideSymbol(it) as? JKClassSymbol }!!,
|
||||
parameters.map { it.toJK() }
|
||||
)
|
||||
is PsiArrayType -> JKJavaArrayTypeImpl(componentType.toJK())
|
||||
is PsiPrimitiveType -> when (presentableText) {
|
||||
"int" -> JKJavaPrimitiveTypeImpl.INT
|
||||
@@ -238,7 +254,7 @@ class JavaToJKTreeBuilder {
|
||||
fun PsiField.toJK(): JKJavaField {
|
||||
return JKJavaFieldImpl(
|
||||
with(modifierMapper) { modifierList.toJK() },
|
||||
with(expressionTreeMapper) { type.toJK() },
|
||||
with(expressionTreeMapper) { typeElement?.toJK() } ?: TODO(),
|
||||
JKNameIdentifierImpl(this.name),
|
||||
with(expressionTreeMapper) { initializer?.toJK() } ?: TODO()
|
||||
).also {
|
||||
@@ -262,7 +278,7 @@ class JavaToJKTreeBuilder {
|
||||
}
|
||||
|
||||
fun PsiParameter.toJK(): JKValueArgumentImpl {
|
||||
return JKValueArgumentImpl(with(expressionTreeMapper) { type.toJK() }, name!!)
|
||||
return JKValueArgumentImpl(with(expressionTreeMapper) { typeElement?.toJK() } ?: TODO(), name!!)
|
||||
}
|
||||
|
||||
fun PsiCodeBlock.toJK(): JKBlock {
|
||||
|
||||
@@ -42,7 +42,13 @@ class NewJavaToKotlinConverter(
|
||||
|
||||
println(fileTrees.prettyPrintTrees())
|
||||
|
||||
ConversionsRunner.doApply(fileTrees)
|
||||
val context = ConversionContext(
|
||||
JKSymbolProvider(),
|
||||
project,
|
||||
{ treeBuilder.backAnnotation[it] }
|
||||
)
|
||||
|
||||
ConversionsRunner.doApply(fileTrees, context)
|
||||
|
||||
val resultTree = fileTrees.prettyPrintTrees()
|
||||
|
||||
|
||||
@@ -16,12 +16,13 @@
|
||||
|
||||
package org.jetbrains.kotlin.j2k.conversions
|
||||
|
||||
import org.jetbrains.kotlin.j2k.ConversionContext
|
||||
import org.jetbrains.kotlin.j2k.tree.JKTreeElement
|
||||
|
||||
abstract class BaseConversion {
|
||||
/**
|
||||
* @return true if something changed
|
||||
*/
|
||||
abstract fun runConversion(treeRoot: JKTreeElement): Boolean
|
||||
abstract fun runConversion(treeRoot: JKTreeElement, context: ConversionContext): Boolean
|
||||
|
||||
}
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.j2k.conversions
|
||||
|
||||
import org.jetbrains.kotlin.j2k.ConversionContext
|
||||
import org.jetbrains.kotlin.j2k.tree.*
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
|
||||
@@ -16,7 +17,7 @@ class FieldToPropertyConversion : MatchBasedConversion() {
|
||||
|
||||
var somethingChanged = false
|
||||
|
||||
override fun runConversion(treeRoot: JKTreeElement): Boolean {
|
||||
override fun runConversion(treeRoot: JKTreeElement, context: ConversionContext): Boolean {
|
||||
val root = applyToElement(treeRoot)
|
||||
assert(root === treeRoot)
|
||||
return somethingChanged
|
||||
|
||||
@@ -16,13 +16,14 @@
|
||||
|
||||
package org.jetbrains.kotlin.j2k.conversions
|
||||
|
||||
import org.jetbrains.kotlin.j2k.ConversionContext
|
||||
import org.jetbrains.kotlin.j2k.tree.JKTreeElement
|
||||
import org.jetbrains.kotlin.j2k.tree.visitors.JKVisitorVoid
|
||||
|
||||
abstract class TransformerBasedConversion : BaseConversion(), JKVisitorVoid {
|
||||
protected var somethingChanged = false
|
||||
|
||||
override fun runConversion(treeRoot: JKTreeElement): Boolean {
|
||||
override fun runConversion(treeRoot: JKTreeElement, context: ConversionContext): Boolean {
|
||||
somethingChanged = false
|
||||
treeRoot.accept(this, null)
|
||||
return somethingChanged
|
||||
|
||||
@@ -5,17 +5,32 @@
|
||||
|
||||
package org.jetbrains.kotlin.j2k.conversions
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiReferenceExpression
|
||||
import org.jetbrains.kotlin.j2k.ConversionContext
|
||||
import org.jetbrains.kotlin.j2k.ast.Nullability
|
||||
import org.jetbrains.kotlin.j2k.tree.JKClassType
|
||||
import org.jetbrains.kotlin.j2k.tree.JKJavaPrimitiveType
|
||||
import org.jetbrains.kotlin.j2k.tree.JKTreeElement
|
||||
import org.jetbrains.kotlin.j2k.tree.JKType
|
||||
import org.jetbrains.kotlin.j2k.tree.impl.JKClassSymbol
|
||||
import org.jetbrains.kotlin.j2k.tree.impl.JKClassTypeImpl
|
||||
import org.jetbrains.kotlin.j2k.tree.impl.JKMultiverseKtClassSymbol
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.platform.JavaToKotlinClassMap
|
||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||
import org.jetbrains.kotlin.psi.KtPsiFactory
|
||||
import org.jetbrains.kotlin.resolve.ImportPath
|
||||
import org.jetbrains.kotlin.resolve.QualifiedExpressionResolver
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType
|
||||
|
||||
class TypeMappingConversion : MatchBasedConversion() {
|
||||
class TypeMappingConversion(val context: ConversionContext) : MatchBasedConversion() {
|
||||
override fun onElementChanged(new: JKTreeElement, old: JKTreeElement) {
|
||||
somethingChanged = true
|
||||
}
|
||||
|
||||
override fun runConversion(treeRoot: JKTreeElement): Boolean {
|
||||
override fun runConversion(treeRoot: JKTreeElement, context: ConversionContext): Boolean {
|
||||
val root = applyToElement(treeRoot)
|
||||
assert(root === treeRoot)
|
||||
return somethingChanged
|
||||
@@ -32,14 +47,37 @@ class TypeMappingConversion : MatchBasedConversion() {
|
||||
}
|
||||
}
|
||||
|
||||
fun fqNameRef(classId: ClassId, element: PsiElement): PsiReferenceExpression? {
|
||||
return KtPsiFactory(element)
|
||||
.createExpressionCodeFragment(classId.asString(), element)
|
||||
.findChildByClass(PsiReferenceExpression::class.java)
|
||||
}
|
||||
|
||||
fun classTypeByFqName(
|
||||
contextElement: PsiElement?,
|
||||
fqName: ClassId,
|
||||
parameters: List<JKType>,
|
||||
nullability: Nullability = Nullability.Default
|
||||
): JKType? {
|
||||
contextElement ?: return null
|
||||
val newTarget = fqNameRef(fqName, contextElement)?.resolve() as? KtClassOrObject ?: return null
|
||||
|
||||
val newSymbol = JKMultiverseKtClassSymbol(newTarget)
|
||||
|
||||
return JKClassTypeImpl(newSymbol, parameters, nullability)
|
||||
}
|
||||
|
||||
fun mapClassType(type: JKClassType): JKType {
|
||||
// if (type.classReference?.target) {
|
||||
//
|
||||
// }
|
||||
return type
|
||||
val fqNameStr = (type.classReference as? JKClassSymbol)?.fqName ?: return type
|
||||
|
||||
val newFqName = JavaToKotlinClassMap.mapJavaToKotlin(FqName(fqNameStr)) ?: return type
|
||||
|
||||
return classTypeByFqName(context.backAnnotator(type), newFqName, type.parameters, type.nullability) ?: type
|
||||
}
|
||||
|
||||
fun mapPrimitiveType(type: JKJavaPrimitiveType): JKType {
|
||||
return type
|
||||
val fqName = JvmPrimitiveType.get(type.name).primitiveType.typeFqName
|
||||
|
||||
return classTypeByFqName(context.backAnnotator(type), ClassId.topLevel(fqName), emptyList()) ?: type
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.j2k.tree
|
||||
|
||||
import org.jetbrains.kotlin.j2k.tree.impl.JKClassSymbol
|
||||
import org.jetbrains.kotlin.j2k.tree.visitors.JKVisitorVoid
|
||||
import org.jetbrains.kotlin.utils.Printer
|
||||
|
||||
@@ -77,12 +78,7 @@ private class DebugTreePrinter : JKVisitorVoid {
|
||||
printer.println(type.classNameWithoutJK(), " \"")
|
||||
printer.indented {
|
||||
if (type is JKClassType) {
|
||||
/*if ((type.classReference as? JKBindableSymbol)?.isBound == true) {
|
||||
printer.println(type.classReference?.element?.name?.value)
|
||||
|
||||
} else {
|
||||
printer.println("Unbound")
|
||||
}*/
|
||||
printer.println((type.classReference as? JKClassSymbol)?.fqName ?: type.classReference?.let { it::class } ?: "Unbound")
|
||||
}
|
||||
}
|
||||
printer.println("\"")
|
||||
|
||||
@@ -20,21 +20,21 @@ import org.jetbrains.kotlin.j2k.tree.*
|
||||
import org.jetbrains.kotlin.j2k.tree.visitors.JKVisitor
|
||||
|
||||
class JKJavaFieldImpl(
|
||||
override var modifierList: JKModifierList,
|
||||
override var type: JKType,
|
||||
override var name: JKNameIdentifier,
|
||||
override var initializer: JKExpression
|
||||
) : JKJavaField, JKElementBase() {
|
||||
modifierList: JKModifierList,
|
||||
type: JKType,
|
||||
name: JKNameIdentifier,
|
||||
initializer: JKExpression
|
||||
) : JKJavaField, JKBranchElementBase() {
|
||||
override val valid: Boolean
|
||||
get() = true
|
||||
|
||||
override fun <R, D> accept(visitor: JKVisitor<R, D>, data: D): R = visitor.visitJavaField(this, data)
|
||||
|
||||
override fun <D> acceptChildren(visitor: JKVisitor<Unit, D>, data: D) {
|
||||
type.accept(visitor, data)
|
||||
name.accept(visitor, data)
|
||||
initializer.accept(visitor, data)
|
||||
}
|
||||
override var initializer: JKExpression by child(initializer)
|
||||
override var modifierList: JKModifierList by child(modifierList)
|
||||
override var name: JKNameIdentifier by child(name)
|
||||
override var type: JKType by child(type)
|
||||
|
||||
}
|
||||
|
||||
class JKJavaLiteralExpressionImpl(
|
||||
|
||||
@@ -204,13 +204,13 @@ class JKTypeCastExpressionImpl(override var expression: JKExpression, override v
|
||||
|
||||
class JKClassTypeImpl(
|
||||
override val classReference: JKClassSymbol,
|
||||
override val parameters: List<JKType>,
|
||||
parameters: List<JKType>,
|
||||
override val nullability: Nullability = Nullability.Default
|
||||
) : JKClassType, JKElementBase() {
|
||||
) : JKClassType, JKBranchElementBase() {
|
||||
|
||||
override fun <R, D> accept(visitor: JKVisitor<R, D>, data: D): R = visitor.visitClassType(this, data)
|
||||
|
||||
override fun <D> acceptChildren(visitor: JKVisitor<Unit, D>, data: D) {
|
||||
override var parameters: List<JKType> by children(parameters)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
class JKNullLiteral : JKExpression, JKElementBase()
|
||||
@@ -11,6 +11,8 @@ import com.intellij.psi.PsiMethod
|
||||
import org.jetbrains.kotlin.j2k.tree.JKClass
|
||||
import org.jetbrains.kotlin.j2k.tree.JKField
|
||||
import org.jetbrains.kotlin.j2k.tree.JKMethod
|
||||
import org.jetbrains.kotlin.psi.KtClass
|
||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||
|
||||
interface JKSymbol {
|
||||
val target: Any
|
||||
@@ -18,7 +20,7 @@ interface JKSymbol {
|
||||
}
|
||||
|
||||
interface JKClassSymbol : JKSymbol {
|
||||
val fqName: String
|
||||
val fqName: String?
|
||||
}
|
||||
|
||||
interface JKMethodSymbol : JKSymbol {
|
||||
@@ -39,8 +41,15 @@ class JKUniverseClassSymbol(override val target: JKClass) : JKClassSymbol {
|
||||
class JKMultiverseClassSymbol(override val target: PsiClass) : JKClassSymbol {
|
||||
override val declaredIn: JKSymbol
|
||||
get() = TODO("not implemented") //To change initializer of created properties use File | Settings | File Templates.
|
||||
override val fqName: String
|
||||
get() = target.name!!
|
||||
override val fqName: String?
|
||||
get() = target.qualifiedName
|
||||
}
|
||||
|
||||
class JKMultiverseKtClassSymbol(override val target: KtClassOrObject): JKClassSymbol {
|
||||
override val declaredIn: JKSymbol
|
||||
get() = TODO("not implemented")
|
||||
override val fqName: String?
|
||||
get() = target.fqName?.asString()
|
||||
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user