New J2K: WIP: Introduce symbols instead of references

This commit is contained in:
Simon Ogorodnik
2018-05-16 01:00:03 +03:00
committed by Ilya Kirillov
parent 4b3fdbcb0b
commit edd23c7a83
10 changed files with 141 additions and 176 deletions
@@ -23,41 +23,10 @@ import com.intellij.psi.impl.source.tree.java.PsiLiteralExpressionImpl
import com.intellij.psi.impl.source.tree.java.PsiNewExpressionImpl import com.intellij.psi.impl.source.tree.java.PsiNewExpressionImpl
import com.intellij.psi.impl.source.tree.java.PsiReferenceExpressionImpl import com.intellij.psi.impl.source.tree.java.PsiReferenceExpressionImpl
import org.jetbrains.kotlin.j2k.tree.* import org.jetbrains.kotlin.j2k.tree.*
import org.jetbrains.kotlin.j2k.tree.multiverse.JKMDeclarationList
import org.jetbrains.kotlin.j2k.tree.multiverse.JKMultiverseClass
import org.jetbrains.kotlin.j2k.tree.multiverse.ReferenceTargetProvider
import org.jetbrains.kotlin.j2k.tree.impl.* import org.jetbrains.kotlin.j2k.tree.impl.*
class JavaToJKTreeBuilder : ReferenceTargetProvider { class JavaToJKTreeBuilder {
override fun resolveClassReference(clazz: PsiClass): JKClass {
val name = clazz.qualifiedName ?: TODO()
return universe[name] ?: multiverse[name] ?: run {
val clazz = JKMultiverseClass(JKNameIdentifierImpl(name), JKMDeclarationList(emptyList()), JKClass.ClassKind.CLASS, JKModifierListImpl())
multiverse[name] = clazz
clazz
}
}
override fun resolveClassReference(identifier: String): JKClass {
return universe[identifier] ?: multiverse[identifier] ?: run {
val clazz =
JKMultiverseClass(JKNameIdentifierImpl(identifier), JKMDeclarationList(emptyList()), JKClass.ClassKind.CLASS, JKModifierListImpl())
multiverse[identifier] = clazz
clazz
}
}
override fun putUniverseClass(clazz: JKClass) {
universe[clazz.name.name] = clazz
}
override fun putMultiverseClass(clazz: JKMultiverseClass) {
multiverse[clazz.name.name] = clazz
}
private val universe = mutableMapOf<String, JKClass>()
private val multiverse = mutableMapOf<String, JKMultiverseClass>()
private val expressionTreeMapper = ExpressionTreeMapper() private val expressionTreeMapper = ExpressionTreeMapper()
@@ -65,6 +34,18 @@ class JavaToJKTreeBuilder : ReferenceTargetProvider {
private val modifierMapper = ModifierMapper() private val modifierMapper = ModifierMapper()
val symbols = mutableMapOf<PsiElement, JKBindableSymbol<*>>()
fun bindSymbol(psi: PsiElement, element: JKElement) {
provideSymbol(psi).bind(element)
}
fun <T : JKElement> provideSymbol(psi: PsiElement): JKBindableSymbol<T> {
return symbols.getOrPut(psi) {
DelayedPsiSymbol<T>(psi)
} as JKBindableSymbol<T>
}
private inner class ExpressionTreeMapper { private inner class ExpressionTreeMapper {
fun PsiExpression.toJK(): JKExpression { fun PsiExpression.toJK(): JKExpression {
when (this) { when (this) {
@@ -98,8 +79,17 @@ class JavaToJKTreeBuilder : ReferenceTargetProvider {
is PsiParenthesizedExpression -> { is PsiParenthesizedExpression -> {
return toJK() return toJK()
} }
is PsiAssignmentExpression -> {
return toJK()
}
else -> {
throw RuntimeException("Not supported: ${this::class}")
}
} }
throw RuntimeException("Not supported") }
fun PsiAssignmentExpression.toJK(): JKJavaAssignmentExpression {
return JKJavaAssignmentExpressionImpl(lExpression.toJK(), rExpression?.toJK() ?: TODO())
} }
fun PsiBinaryExpression.toJK(): JKExpression { fun PsiBinaryExpression.toJK(): JKExpression {
@@ -137,7 +127,7 @@ class JavaToJKTreeBuilder : ReferenceTargetProvider {
fun PsiMethodCallExpression.toJK(): JKExpression { fun PsiMethodCallExpression.toJK(): JKExpression {
val method = methodExpression as PsiReferenceExpressionImpl val method = methodExpression as PsiReferenceExpressionImpl
val identifier = method.resolve().convertReference() val identifier = JKMethodReferenceImpl({ method.reference?.resolve() })
val call = JKJavaMethodCallExpressionImpl(identifier as JKMethodReference, argumentList.toJK()) val call = JKJavaMethodCallExpressionImpl(identifier as JKMethodReference, argumentList.toJK())
return if (method.findChildByRole(ChildRole.DOT) != null) { return if (method.findChildByRole(ChildRole.DOT) != null) {
JKQualifiedExpressionImpl((method.qualifier as PsiExpression).toJK(), JKJavaQualifierImpl.DOT, call) JKQualifiedExpressionImpl((method.qualifier as PsiExpression).toJK(), JKJavaQualifierImpl.DOT, call)
@@ -148,8 +138,7 @@ class JavaToJKTreeBuilder : ReferenceTargetProvider {
fun PsiReferenceExpression.toJK(): JKExpression { fun PsiReferenceExpression.toJK(): JKExpression {
val impl = this as PsiReferenceExpressionImpl val impl = this as PsiReferenceExpressionImpl
val identifier = impl.resolve().convertReference() as JKFieldReference val access = JKJavaFieldAccessExpressionImpl(JKFieldReferenceImpl({ impl.resolve() }))
val access = JKJavaFieldAccessExpressionImpl(identifier)
return if (impl.findChildByRole(ChildRole.DOT) != null) { return if (impl.findChildByRole(ChildRole.DOT) != null) {
JKQualifiedExpressionImpl((impl.qualifier as PsiExpression).toJK(), JKJavaQualifierImpl.DOT, access) JKQualifiedExpressionImpl((impl.qualifier as PsiExpression).toJK(), JKJavaQualifierImpl.DOT, access)
} else { } else {
@@ -180,7 +169,7 @@ class JavaToJKTreeBuilder : ReferenceTargetProvider {
return JKJavaNewEmptyArrayImpl(dimensions.map { it?.toJK() }) return JKJavaNewEmptyArrayImpl(dimensions.map { it?.toJK() })
} }
} }
return JKJavaNewExpressionImpl(classReference?.resolve().convertReference() as JKClassReference, argumentList.toJK()) return JKJavaNewExpressionImpl(provideSymbol(constructorFakeReference.resolve()!!), argumentList.toJK())
} }
fun PsiArrayAccessExpression.toJK(): JKExpression { fun PsiArrayAccessExpression.toJK(): JKExpression {
@@ -199,39 +188,9 @@ class JavaToJKTreeBuilder : ReferenceTargetProvider {
return JKExpressionListImpl(this?.expressions?.map { it.toJK() } ?: emptyList()) return JKExpressionListImpl(this?.expressions?.map { it.toJK() } ?: emptyList())
} }
fun PsiElement?.convertReference(): JKReference = when (this) {
is PsiMethod -> convertMethodReference()
is PsiField -> convertFieldReference()
is PsiClass -> convertClassReference()
else -> throw Exception("Invalid PSI")
}
fun PsiMethod.convertMethodReference(): JKMethodReference {
val clazz = this@JavaToJKTreeBuilder.resolveClassReference(containingClass ?: TODO())
return JKMethodReferenceImpl(
this@JavaToJKTreeBuilder.resolveMethodReference(clazz, this),
if (clazz is JKMultiverseClass) JKReference.JKReferenceType.U2M else JKReference.JKReferenceType.U2U
)
}
fun PsiField.convertFieldReference(): JKFieldReference {
val clazz = this@JavaToJKTreeBuilder.resolveClassReference(containingClass ?: TODO())
return JKFieldReferenceImpl(
this@JavaToJKTreeBuilder.resolveFieldReference(clazz, this),
if (clazz is JKMultiverseClass) JKReference.JKReferenceType.U2M else JKReference.JKReferenceType.U2U
)
}
fun PsiClass.convertClassReference(): JKClassReference {
val clazz = this@JavaToJKTreeBuilder.resolveClassReference(this)
return JKClassReferenceImpl(
clazz, if (clazz is JKMultiverseClass) JKReference.JKReferenceType.U2M else JKReference.JKReferenceType.U2U
)
}
fun PsiType.toJK(): JKType { fun PsiType.toJK(): JKType {
return when (this) { return when (this) {
is PsiClassType -> JKClassTypeImpl(resolve()!!.convertClassReference(), parameters.map { it.toJK() }) is PsiClassType -> JKClassTypeImpl(resolve()?.let { provideSymbol<JKClass>(it) }, parameters.map { it.toJK() })
is PsiArrayType -> JKJavaArrayTypeImpl(componentType.toJK()) is PsiArrayType -> JKJavaArrayTypeImpl(componentType.toJK())
is PsiPrimitiveType -> when (presentableText) { is PsiPrimitiveType -> when (presentableText) {
"int" -> JKJavaPrimitiveTypeImpl.INT "int" -> JKJavaPrimitiveTypeImpl.INT
@@ -254,25 +213,39 @@ class JavaToJKTreeBuilder : ReferenceTargetProvider {
else -> JKClass.ClassKind.CLASS else -> JKClass.ClassKind.CLASS
} }
val psi = this val psi = this
return JKClassImpl(with(modifierMapper) { modifierList.toJK() }, JKNameIdentifierImpl(name!!), classKind).apply { return JKClassImpl(
declarationList.apply { with(modifierMapper) { modifierList.toJK() },
JKNameIdentifierImpl(name!!),
classKind
).also {
it.declarationList.apply {
declarations = psi.children.mapNotNull { declarations = psi.children.mapNotNull {
ElementVisitor(this@DeclarationMapper).apply { it.accept(this) }.resultElement as? JKUniverseDeclaration ElementVisitor(this@DeclarationMapper).apply { it.accept(this) }.resultElement as? JKUniverseDeclaration
} }
} }
bindSymbol(this, it)
} }
} }
fun PsiField.toJK(): JKJavaField { fun PsiField.toJK(): JKJavaField {
return JKJavaFieldImpl(with(modifierMapper) { modifierList.toJK() }, with(expressionTreeMapper) { type.toJK() }, return JKJavaFieldImpl(
JKNameIdentifierImpl(this.name), with(expressionTreeMapper) { initializer?.toJK() } ?: TODO()) with(modifierMapper) { modifierList.toJK() },
with(expressionTreeMapper) { type.toJK() },
JKNameIdentifierImpl(this.name),
with(expressionTreeMapper) { initializer?.toJK() } ?: TODO()
).also {
bindSymbol(this, it)
}
} }
fun PsiMethod.toJK(): JKJavaMethod { fun PsiMethod.toJK(): JKJavaMethod {
return JKJavaMethodImpl( return JKJavaMethodImpl(
with(modifierMapper) { modifierList.toJK() }, JKNameIdentifierImpl(name), with(modifierMapper) { modifierList.toJK() }, JKNameIdentifierImpl(name),
parameterList.parameters.map { it -> it.toJK() }, body?.toJK() ?: TODO() parameterList.parameters.map { it -> it.toJK() }, body?.toJK() ?: TODO()
) ).also {
bindSymbol(this, it)
}
} }
fun PsiMember.toJK(): JKDeclaration? = when (this) { fun PsiMember.toJK(): JKDeclaration? = when (this) {
@@ -293,6 +266,9 @@ class JavaToJKTreeBuilder : ReferenceTargetProvider {
if (this is PsiExpressionStatement) { if (this is PsiExpressionStatement) {
return JKExpressionStatementImpl(with(expressionTreeMapper) { expression.toJK() }) return JKExpressionStatementImpl(with(expressionTreeMapper) { expression.toJK() })
} }
if (this is PsiReturnStatement) {
return JKReturnStatementImpl(with(expressionTreeMapper) { returnValue?.toJK() ?: TODO() })
}
TODO() TODO()
} }
} }
@@ -44,7 +44,7 @@ class NewCodeBuilder {
override fun visitUniverseClass(universeClass: JKUniverseClass, data: Unit) { override fun visitUniverseClass(universeClass: JKUniverseClass, data: Unit) {
printer.print(classKindString(universeClass.classKind)) printer.print(classKindString(universeClass.classKind))
builder.append(" ") builder.append(" ")
printer.print(universeClass.name.name) printer.print(universeClass.name.value)
if (universeClass.declarationList.declarations.isNotEmpty()) { if (universeClass.declarationList.declarations.isNotEmpty()) {
printer.println("{") printer.println("{")
printer.pushIndent() printer.pushIndent()
@@ -16,6 +16,7 @@
package org.jetbrains.kotlin.j2k.tree package org.jetbrains.kotlin.j2k.tree
import org.jetbrains.kotlin.j2k.tree.impl.JKBindableSymbol
import org.jetbrains.kotlin.j2k.tree.visitors.JKVisitorVoid import org.jetbrains.kotlin.j2k.tree.visitors.JKVisitorVoid
import org.jetbrains.kotlin.utils.Printer import org.jetbrains.kotlin.utils.Printer
@@ -73,26 +74,17 @@ private class DebugTreePrinter : JKVisitorVoid {
printer.println("]") printer.println("]")
} }
override fun visitMethodReference(methodReference: JKMethodReference) {
printer.println(methodReference.classNameWithoutJK())
printer.println(methodReference.target.parent.let { (it as? JKClass)?.name?.name ?: "null" }, "@", methodReference.target.name.name)
}
override fun visitFieldReference(fieldReference: JKFieldReference) {
printer.println(fieldReference.classNameWithoutJK())
printer.println(fieldReference.target.parent.let { (it as? JKClass)?.name?.name ?: "null" }, "@", fieldReference.target.name.name)
}
override fun visitClassReference(classReference: JKClassReference) {
printer.println(classReference.classNameWithoutJK())
printer.println(classReference.target.name.name)
}
override fun visitType(type: JKType) { override fun visitType(type: JKType) {
printer.println(type.classNameWithoutJK(), " \"") printer.println(type.classNameWithoutJK(), " \"")
printer.indented { printer.indented {
if (type is JKClassType) if (type is JKClassType) {
printer.println(type.classReference.target.name.name) if ((type.classReference as? JKBindableSymbol)?.isBound == true) {
printer.println(type.classReference?.element?.name?.value)
} else {
printer.println("Unbound")
}
}
} }
printer.println("\"") printer.println("\"")
} }
@@ -96,13 +96,12 @@ class JKJavaFieldAccessExpressionImpl(override var identifier: JKFieldReference)
} }
class JKJavaNewExpressionImpl( class JKJavaNewExpressionImpl(
override var identifier: JKClassReference, override var arguments: JKExpressionList override val constructorSymbol: JKSymbol<JKMethod>,
) : JKJavaNewExpression, JKElementBase() { arguments: JKExpressionList
) : JKJavaNewExpression, JKBranchElementBase() {
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)
override fun <D> acceptChildren(visitor: JKVisitor<Unit, D>, data: D) { override var arguments by child(arguments)
identifier.accept(visitor, data)
}
} }
class JKJavaNewEmptyArrayImpl(override var initializer: List<JKLiteralExpression?>) : JKJavaNewEmptyArray, JKElementBase() { class JKJavaNewEmptyArrayImpl(override var initializer: List<JKLiteralExpression?>) : JKJavaNewEmptyArray, JKElementBase() {
@@ -140,3 +139,17 @@ class JKJavaArrayTypeImpl(override val type: JKType) : JKJavaArrayType, JKElemen
} }
} }
class JKReturnStatementImpl(expression: JKExpression) : JKBranchElementBase(), JKReturnStatement {
// TODO accept
override val expression by child(expression)
}
class JKJavaAssignmentExpressionImpl(
lExpression: JKExpression,
rExpression: JKExpression/*,
TODO operation:? */
) : JKBranchElementBase(), JKJavaAssignmentExpression {
override var lExpression: JKExpression by child(lExpression)
override var rExpression: JKExpression by child(rExpression)
}
@@ -18,8 +18,8 @@ package org.jetbrains.kotlin.j2k.tree.impl
import org.jetbrains.kotlin.j2k.ast.Nullability import org.jetbrains.kotlin.j2k.ast.Nullability
import org.jetbrains.kotlin.j2k.tree.* import org.jetbrains.kotlin.j2k.tree.*
import org.jetbrains.kotlin.j2k.tree.JKReference.JKReferenceType
import org.jetbrains.kotlin.j2k.tree.visitors.JKVisitor import org.jetbrains.kotlin.j2k.tree.visitors.JKVisitor
import com.intellij.psi.PsiElement
import kotlin.properties.ReadWriteProperty import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty import kotlin.reflect.KProperty
@@ -72,6 +72,7 @@ abstract class JKBranchElementBase : JKElementBase(), JKMutableBranchElement {
protected var childNum = 0 protected var childNum = 0
protected fun <T : JKTreeElement, U : T> child(v: U): ReadWriteProperty<JKMutableBranchElement, T> { protected fun <T : JKTreeElement, U : T> child(v: U): ReadWriteProperty<JKMutableBranchElement, T> {
children.add(childNum, v)
return JKChild(childNum++) return JKChild(childNum++)
} }
@@ -89,6 +90,10 @@ abstract class JKElementListBase: JKElementBase(), JKMutableBranchElement {
children.addAll(v) children.addAll(v)
return JKListChild() return JKListChild()
} }
override fun <D> acceptChildren(visitor: JKVisitor<Unit, D>, data: D) {
children.forEach { it.accept(visitor, data) }
}
} }
class JKUDeclarationListImpl : JKElementListBase(), JKUDeclarationList { class JKUDeclarationListImpl : JKElementListBase(), JKUDeclarationList {
@@ -110,7 +115,7 @@ class JKClassImpl(modifierList: JKModifierList, name: JKNameIdentifier, override
} }
class JKNameIdentifierImpl(override val name: String) : JKNameIdentifier, JKElementBase() {} class JKNameIdentifierImpl(override val value: String) : JKNameIdentifier, JKElementBase() {}
class JKModifierListImpl(modifiers: List<JKModifier> = emptyList()) : JKModifierList, JKElementListBase() { class JKModifierListImpl(modifiers: List<JKModifier> = emptyList()) : JKModifierList, JKElementListBase() {
override var modifiers: List<JKModifier> by children(modifiers) override var modifiers: List<JKModifier> by children(modifiers)
@@ -192,7 +197,7 @@ class JKTypeCastExpressionImpl(override var expression: JKExpression, override v
} }
class JKClassTypeImpl( class JKClassTypeImpl(
override val classReference: JKClassReference, override val classReference: JKSymbol<JKClass>?,
override val parameters: List<JKType>, override val parameters: List<JKType>,
override val nullability: Nullability = Nullability.Default override val nullability: Nullability = Nullability.Default
) : JKClassType, JKElementBase() { ) : JKClassType, JKElementBase() {
@@ -204,28 +209,21 @@ class JKClassTypeImpl(
} }
} }
class JKFieldReferenceImpl(override val target: JKField, override val referenceType: JKReferenceType) : JKFieldReference, JKElementBase() {
abstract class JKReferenceBase<T : JKReferenceTarget>(val resolve: () -> PsiElement?) : JKElementBase(), JKReference {
override fun <R, D> accept(visitor: JKVisitor<R, D>, data: D): R = visitor.visitReference(this, data)
override var target: T? = null
}
class JKFieldReferenceImpl(resolve: () -> PsiElement?) : JKFieldReference, JKReferenceBase<JKField>(resolve) {
override fun <R, D> accept(visitor: JKVisitor<R, D>, data: D): R = visitor.visitFieldReference(this, data) override fun <R, D> accept(visitor: JKVisitor<R, D>, data: D): R = visitor.visitFieldReference(this, data)
override fun <D> acceptChildren(visitor: JKVisitor<Unit, D>, data: D) {
}
} }
class JKClassReferenceImpl(override val target: JKClass, override val referenceType: JKReferenceType) : JKClassReference, class JKClassReferenceImpl(resolve: () -> PsiElement?) : JKClassReference, JKReferenceBase<JKClass>(resolve) {
JKElementBase() {
override fun <R, D> accept(visitor: JKVisitor<R, D>, data: D): R = visitor.visitClassReference(this, data) override fun <R, D> accept(visitor: JKVisitor<R, D>, data: D): R = visitor.visitClassReference(this, data)
override fun <D> acceptChildren(visitor: JKVisitor<Unit, D>, data: D) {
}
} }
class JKMethodReferenceImpl(override val target: JKMethod, override val referenceType: JKReferenceType) : JKMethodReference, class JKMethodReferenceImpl(resolve: () -> PsiElement?) : JKMethodReference, JKReferenceBase<JKMethod>(resolve) {
JKElementBase() {
override fun <R, D> accept(visitor: JKVisitor<R, D>, data: D): R = visitor.visitMethodReference(this, data) override fun <R, D> accept(visitor: JKVisitor<R, D>, data: D): R = visitor.visitMethodReference(this, data)
override fun <D> acceptChildren(visitor: JKVisitor<Unit, D>, data: D) {
}
} }
@@ -0,0 +1,24 @@
/*
* 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.tree.impl
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.j2k.tree.JKElement
import org.jetbrains.kotlin.j2k.tree.JKSymbol
abstract class JKBindableSymbol<E : JKElement> : JKSymbol<E> {
final override lateinit var element: E
private set
val isBound get() = ::element.isInitialized
fun bind(new: E) {
element = new
}
}
class DelayedPsiSymbol<E : JKElement>(val psi: PsiElement) : JKBindableSymbol<E>()
@@ -26,7 +26,10 @@ interface JKJavaMethod : JKUniverseDeclaration, JKMethod {
interface JKJavaForLoop : JKLoop interface JKJavaForLoop : JKLoop
interface JKJavaAssignmentExpression : JKExpression interface JKJavaAssignmentExpression : JKExpression {
var lExpression: JKExpression
var rExpression: JKExpression
}
interface JKJavaPrimitiveType : JKType { interface JKJavaPrimitiveType : JKType {
val name: String val name: String
@@ -41,7 +44,7 @@ interface JKJavaMethodCallExpression : JKMethodCallExpression
interface JKJavaFieldAccessExpression : JKFieldAccessExpression interface JKJavaFieldAccessExpression : JKFieldAccessExpression
interface JKJavaNewExpression : JKExpression { interface JKJavaNewExpression : JKExpression {
val identifier: JKClassReference val constructorSymbol: JKSymbol<JKMethod>
val arguments: JKExpressionList val arguments: JKExpressionList
} }
@@ -70,3 +73,7 @@ interface JKJavaNewArray : JKExpression {
} }
interface JKJavaLiteralExpression : JKLiteralExpression interface JKJavaLiteralExpression : JKLiteralExpression
interface JKReturnStatement : JKStatement {
val expression: JKExpression
}
+7 -11
View File
@@ -50,30 +50,26 @@ interface JKAccessModifier : JKModifier
interface JKModalityModifier : JKModifier interface JKModalityModifier : JKModifier
interface JKReference : JKTreeElement { interface JKReference : JKTreeElement {
val target: JKReferenceTarget val target: JKReferenceTarget?
val referenceType: JKReferenceType val isBound get() = target != null
enum class JKReferenceType {
U2U, U2M, M2U
}
} }
interface JKMethodReference : JKReference { interface JKMethodReference : JKReference {
override val target: JKMethod override val target: JKMethod?
} }
interface JKFieldReference : JKReference { interface JKFieldReference : JKReference {
override val target: JKField override val target: JKField?
} }
interface JKClassReference : JKReference { interface JKClassReference : JKReference {
override val target: JKClass override val target: JKClass?
} }
interface JKType : JKTreeElement interface JKType : JKTreeElement
interface JKClassType : JKType { interface JKClassType : JKType {
val classReference: JKClassReference val classReference: JKSymbol<JKClass>?
val nullability: Nullability val nullability: Nullability
val parameters: List<JKType> val parameters: List<JKType>
} }
@@ -89,7 +85,7 @@ interface JKBlock : JKTreeElement {
interface JKIdentifier : JKTreeElement interface JKIdentifier : JKTreeElement
interface JKNameIdentifier : JKIdentifier { interface JKNameIdentifier : JKIdentifier {
val name: String val value: String
} }
interface JKExpression : JKTreeElement interface JKExpression : JKTreeElement
@@ -58,3 +58,7 @@ interface JKField : JKDeclaration, JKModifierListOwner {
val type: JKType val type: JKType
val name: JKNameIdentifier val name: JKNameIdentifier
} }
interface JKSymbol<E : JKElement> {
val element: E
}
@@ -1,45 +0,0 @@
/*
* Copyright 2010-2018 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.j2k.tree.multiverse
import com.intellij.psi.PsiClass
import com.intellij.psi.PsiField
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.JKJavaField
import org.jetbrains.kotlin.j2k.tree.JKMethod
import org.jetbrains.kotlin.j2k.tree.impl.JKNameIdentifierImpl
import org.jetbrains.kotlin.utils.addToStdlib.cast
interface ReferenceTargetProvider {
fun resolveClassReference(identifier: String): JKClass
fun resolveClassReference(clazz: PsiClass): JKClass
fun putUniverseClass(clazz: JKClass)
fun putMultiverseClass(clazz: JKMultiverseClass)
fun resolveMethodReference(clazz: JKClass, method: PsiMethod): JKMethod {
return clazz.declarations.asSequence().filter { it is JKMethod && it.name.name == method.name }.firstOrNull() as JKMethod?
?: JKMultiverseMethod(JKNameIdentifierImpl(method.name)).also { clazz.cast<JKMultiverseClass>().declarations += it }
}
fun resolveFieldReference(clazz: JKClass, field: PsiField): JKField {
return clazz.declarationList.declarations.asSequence().filter { it is JKJavaField && it.name.name == field.name }.firstOrNull() as JKField?
?: JKMultiverseField(JKNameIdentifierImpl(field.name)).also {
clazz.cast<JKMultiverseClass>().declarationList.declarations += it
}
}
}