Uast: making AbstractKotlinUClass not inherit from AbstractJavaUClass

This commit is contained in:
Nicolay Mitropolsky
2017-12-04 17:58:45 +03:00
committed by Nikolay Krasko
parent 084da3665a
commit e22e466485
8 changed files with 119 additions and 19 deletions
@@ -18,6 +18,7 @@ package org.jetbrains.uast.kotlin
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.asJava.LightClassUtil
import org.jetbrains.kotlin.asJava.classes.KtLightClassForLocalDeclaration
import org.jetbrains.kotlin.asJava.toLightGetter
import org.jetbrains.kotlin.asJava.toLightSetter
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
@@ -40,6 +41,14 @@ abstract class KotlinAbstractUElement(private val givenParent: UElement?) : UEle
val psi = psi
var parent = psi?.parent ?: psi?.containingFile
if (psi is KtLightClassForLocalDeclaration) {
val originParent = psi.kotlinOrigin.parent
parent = when (originParent) {
is KtClassBody -> originParent.parent
else -> originParent
}
}
if (psi is KtAnnotationEntry) {
val parentUnwrapped = KotlinConverter.unwrapElements(parent) ?: return null
val target = psi.useSiteTarget?.getAnnotationUseSiteTarget()
@@ -18,7 +18,6 @@ package org.jetbrains.uast.kotlin
import com.intellij.psi.*
import org.jetbrains.kotlin.asJava.classes.KtLightClass
import org.jetbrains.kotlin.asJava.classes.KtLightClassForLocalDeclaration
import org.jetbrains.kotlin.asJava.classes.KtLightClassForScript
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
import org.jetbrains.kotlin.load.java.JvmAbi
@@ -27,21 +26,38 @@ import org.jetbrains.kotlin.utils.SmartList
import org.jetbrains.kotlin.utils.addIfNotNull
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
import org.jetbrains.uast.*
import org.jetbrains.uast.java.AbstractJavaUClass
import org.jetbrains.uast.kotlin.declarations.KotlinUMethod
import org.jetbrains.uast.kotlin.declarations.UastLightIdentifier
abstract class AbstractKotlinUClass(private val givenParent: UElement?) : AbstractJavaUClass(), JvmDeclarationUElement {
override val uastParent: UElement? by lz { givenParent ?: convertParent() }
abstract class AbstractKotlinUClass(givenParent: UElement?) : KotlinAbstractUElement(givenParent), UClass, JvmDeclarationUElement {
override val uastDeclarations by lz {
mutableListOf<UDeclaration>().apply {
addAll(fields)
addAll(initializers)
addAll(methods)
addAll(innerClasses)
}
}
override val uastSuperTypes: List<UTypeReferenceExpression>
get() {
val ktClass = (psi as? KtLightClass)?.kotlinOrigin ?: return emptyList()
return ktClass.superTypeListEntries.mapNotNull { it.typeReference }.map {
LazyKotlinUTypeReferenceExpression(it, this)
}
}
override val uastAnchor: UElement?
get() = UIdentifier(psi.nameIdentifier, this)
override val annotations: List<UAnnotation> by lz {
(sourcePsi as? KtModifierListOwner)?.annotationEntries.orEmpty().map { KotlinUAnnotation(it, this) }
}
override fun equals(other: Any?) = other is AbstractKotlinUClass && psi == other.psi
override fun hashCode() = psi.hashCode()
//TODO: should be merged with KotlinAbstractUElement.convertParent() after detaching from AbstractJavaUClass
override fun convertParent(): UElement? =
(this.psi as? KtLightClassForLocalDeclaration)?.kotlinOrigin?.parent?.let {
when (it) {
is KtClassBody -> it.parent.toUElement() // TODO: it seems that `class_body`-s are never created in kotlin uast in top-down walk, probably they should be completely skipped and always unwrapped
else -> it.toUElement()
}
} ?: (psi.parent ?: psi.containingFile).toUElement()
}
open class KotlinUClass private constructor(
@@ -63,9 +79,6 @@ open class KotlinUClass private constructor(
override fun getContainingFile(): PsiFile? = unwrapFakeFileForLightClass(psi.containingFile)
override val annotations: List<UAnnotation>
get() = ktClass?.annotationEntries?.map { KotlinUAnnotation(it, this) } ?: emptyList()
override val uastAnchor: UElement
get() = UIdentifier(nameIdentifier, this)
@@ -209,8 +222,8 @@ class KotlinUAnonymousClass(
class KotlinScriptUClass(
psi: KtLightClassForScript,
override val uastParent: UElement?
) : AbstractJavaUClass(), PsiClass by psi {
givenParent: UElement?
) : AbstractKotlinUClass(givenParent), PsiClass by psi {
override fun getContainingFile(): PsiFile = unwrapFakeFileForLightClass(psi.containingFile)
override fun getNameIdentifier(): PsiIdentifier? = UastLightIdentifier(psi, psi.kotlinOrigin)
+22
View File
@@ -0,0 +1,22 @@
@Test
class A
annotation class MyAnnotation(val text: String)
@MyAnnotation("class")
class B {
@MyAnnotation("inB class")
class InB {
}
@MyAnnotation("companion")
companion object {
}
}
@MyAnnotation("object")
object Obj
+30
View File
@@ -0,0 +1,30 @@
UFile (package = )
UClass (name = A)
UAnnotation (fqName = null)
UAnnotationMethod (name = A)
UClass (name = MyAnnotation)
UAnnotationMethod (name = text)
UClass (name = B)
UAnnotation (fqName = MyAnnotation)
UNamedExpression (name = text)
ULiteralExpression (value = "class")
UField (name = Companion)
UAnnotation (fqName = null)
UAnnotationMethod (name = B)
UClass (name = InB)
UAnnotation (fqName = MyAnnotation)
UNamedExpression (name = text)
ULiteralExpression (value = "inB class")
UAnnotationMethod (name = InB)
UClass (name = Companion)
UAnnotation (fqName = MyAnnotation)
UNamedExpression (name = text)
ULiteralExpression (value = "companion")
UAnnotationMethod (name = Companion)
UClass (name = Obj)
UAnnotation (fqName = MyAnnotation)
UNamedExpression (name = text)
ULiteralExpression (value = "object")
UField (name = INSTANCE)
UAnnotation (fqName = null)
UAnnotationMethod (name = Obj)
+23
View File
@@ -0,0 +1,23 @@
public final class A {
public fun A() = UastEmptyExpression
}
public abstract annotation MyAnnotation {
public abstract fun text() : java.lang.String = UastEmptyExpression
}
public final class B {
@null public static final var Companion: B.Companion
public fun B() = UastEmptyExpression
public static final class InB {
public fun InB() = UastEmptyExpression
}
public static final class Companion {
private fun Companion() = UastEmptyExpression
}
}
public final class Obj {
@null public static final var INSTANCE: Obj
private fun Obj() = UastEmptyExpression
}
+1 -1
View File
@@ -1,4 +1,4 @@
public class SimpleScript : kotlin.script.templates.standard.ScriptTemplateWithArgs {
public class SimpleScript {
public final fun getBarOrNull(@org.jetbrains.annotations.NotNull flag: boolean) : SimpleScript.Bar {
return if (flag) <init>(42) else null
}
@@ -26,7 +26,7 @@ UFile (package = ) [public abstract interface Callback {...]
ULambdaExpression [{ ...}] : PsiType:<ErrorType>
UBlockExpression [{...}]
UObjectLiteralExpression [anonymous object : Callback {... }] : PsiType:Callback
UClass (name = null) [final class null {...}]
UClass (name = null) [final class null : Callback {...}]
UAnnotationMethod (name = onError) [public fun onError(@org.jetbrains.annotations.NotNull throwable: java.lang.Throwable) : void {...}]
UParameter (name = throwable) [@org.jetbrains.annotations.NotNull var throwable: java.lang.Throwable]
UAnnotation (fqName = org.jetbrains.annotations.NotNull) [@org.jetbrains.annotations.NotNull]
@@ -61,4 +61,7 @@ class SimpleKotlinRenderLogTest : AbstractKotlinRenderLogTest() {
@Test
fun testConstructors() = doTest("Constructors")
@Test
fun testClassAnnotation() = doTest("ClassAnnotation")
}