FIR/UAST: commonize abstraction of Kotlin UClass

This commit is contained in:
Jinseong Jeon
2021-06-17 23:01:22 -07:00
committed by Ilya Kirillov
parent 0c011f4e73
commit 06c20bb10e
4 changed files with 75 additions and 105 deletions
@@ -0,0 +1,57 @@
/*
* Copyright 2010-2021 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.uast.kotlin
import org.jetbrains.kotlin.asJava.classes.KtLightClass
import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.psi.KtDelegatedSuperTypeEntry
import org.jetbrains.kotlin.psi.KtModifierListOwner
import org.jetbrains.uast.*
import org.jetbrains.uast.internal.acceptList
import org.jetbrains.uast.visitor.UastVisitor
abstract class AbstractKotlinUClass(
givenParent: UElement?
) : KotlinAbstractUElement(givenParent), UClass, UAnchorOwner {
override val uastDeclarations by lz {
mutableListOf<UDeclaration>().apply {
addAll(fields)
addAll(initializers)
addAll(methods)
addAll(innerClasses)
}
}
open val ktClass: KtClassOrObject? get() = (psi as? KtLightClass)?.kotlinOrigin
override val uastSuperTypes: List<UTypeReferenceExpression>
get() = ktClass?.superTypeListEntries.orEmpty().mapNotNull { it.typeReference }.map {
KotlinUTypeReferenceExpression(it, this)
}
val delegateExpressions: List<UExpression>
get() = ktClass?.superTypeListEntries.orEmpty()
.filterIsInstance<KtDelegatedSuperTypeEntry>()
.map { KotlinSupertypeDelegationUExpression(it, this) }
override fun accept(visitor: UastVisitor) {
if (visitor.visitClass(this)) return
delegateExpressions.acceptList(visitor)
uAnnotations.acceptList(visitor)
uastDeclarations.acceptList(visitor)
visitor.afterVisitClass(this)
}
override val uAnnotations: List<UAnnotation> by lz {
(sourcePsi as? KtModifierListOwner)?.annotationEntries.orEmpty().map {
baseResolveProviderService.baseKotlinConverter.convertAnnotation(it, this)
}
}
override fun equals(other: Any?) = other is AbstractKotlinUClass && psi == other.psi
override fun hashCode() = psi.hashCode()
}
@@ -71,7 +71,7 @@ internal object FirKotlinConverter : BaseKotlinConverter {
is KtLightClass -> {
// TODO: differentiate enum entry
el<UClass> { AbstractFirKotlinUClass.create(original, givenParent) }
el<UClass> { FirKotlinUClass.create(original, givenParent) }
}
is KtClassOrObject -> {
convertClassOrObject(original, givenParent, requiredTypes).firstOrNull()
@@ -126,7 +126,7 @@ internal object FirKotlinConverter : BaseKotlinConverter {
// File
alternative { KotlinUFile(element, firKotlinUastPlugin) },
// Facade
alternative { element.findFacadeClass()?.let { AbstractFirKotlinUClass.create(it, givenParent) } }
alternative { element.findFacadeClass()?.let { FirKotlinUClass.create(it, givenParent) } }
)
}
@@ -136,7 +136,7 @@ internal object FirKotlinConverter : BaseKotlinConverter {
requiredTypes: Array<out Class<out UElement>>
): Sequence<UElement> {
val ktLightClass = element.toLightClass() ?: return emptySequence()
val uClass = AbstractFirKotlinUClass.create(ktLightClass, givenParent)
val uClass = FirKotlinUClass.create(ktLightClass, givenParent)
return requiredTypes.accommodate(
// Class
alternative { uClass },
@@ -12,69 +12,15 @@ import org.jetbrains.kotlin.asJava.elements.KtLightMethod
import org.jetbrains.kotlin.load.java.JvmAbi
import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.KtDelegatedSuperTypeEntry
import org.jetbrains.kotlin.psi.KtObjectDeclaration
import org.jetbrains.kotlin.utils.addIfNotNull
import org.jetbrains.uast.*
import org.jetbrains.uast.internal.acceptList
import org.jetbrains.uast.visitor.UastVisitor
// TODO: can be commonized once annotation is handled
sealed class AbstractFirKotlinUClass(
givenParent: UElement?
) : KotlinAbstractUElement(givenParent), UClass, UAnchorOwner {
override val uAnnotations: List<UAnnotation>
get() {
// TODO: Not yet implemented
return emptyList()
}
override val uastDeclarations: List<UDeclaration> by lz {
mutableListOf<UDeclaration>().apply {
addAll(fields)
addAll(initializers)
addAll(methods)
addAll(innerClasses)
}
}
abstract val ktClass: KtClassOrObject?
override val uastSuperTypes: List<UTypeReferenceExpression>
get() = ktClass?.superTypeListEntries.orEmpty().mapNotNull { it.typeReference }.map {
KotlinUTypeReferenceExpression(it, this)
}
val delegateExpressions: List<UExpression>
get() = ktClass?.superTypeListEntries.orEmpty()
.filterIsInstance<KtDelegatedSuperTypeEntry>()
.map { KotlinSupertypeDelegationUExpression(it, this) }
override fun accept(visitor: UastVisitor) {
if (visitor.visitClass(this)) return
delegateExpressions.acceptList(visitor)
uAnnotations.acceptList(visitor)
uastDeclarations.acceptList(visitor)
visitor.afterVisitClass(this)
}
companion object {
fun create(psi: KtLightClass, givenParent: UElement?): UClass {
return when (psi) {
// TODO: PsiAnonymousClass
// TODO: Script
else ->
FirKotlinUClass(psi, givenParent)
}
}
}
}
// TODO: can be commonized once *KotlinUClass is commonized
class FirKotlinUClass(
override val javaPsi: KtLightClass,
givenParent: UElement?,
) : AbstractFirKotlinUClass(givenParent), PsiClass by javaPsi {
) : AbstractKotlinUClass(givenParent), PsiClass by javaPsi {
override val ktClass: KtClassOrObject? = javaPsi.kotlinOrigin
override val psi = unwrap<UClass, PsiClass>(javaPsi)
@@ -168,6 +114,17 @@ class FirKotlinUClass(
return result.toTypedArray()
}
companion object {
fun create(psi: KtLightClass, givenParent: UElement?): UClass {
return when (psi) {
// TODO: PsiAnonymousClass
// TODO: Script
else ->
FirKotlinUClass(psi, givenParent)
}
}
}
}
// TODO: FirKotlinUAnonymousClass or FirKotlinUAnonymousObject ?
@@ -26,54 +26,10 @@ import org.jetbrains.kotlin.load.java.JvmAbi
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.utils.addIfNotNull
import org.jetbrains.uast.*
import org.jetbrains.uast.internal.acceptList
import org.jetbrains.uast.visitor.UastVisitor
abstract class AbstractKotlinUClass(givenParent: UElement?) : KotlinAbstractUElement(givenParent), UClassTypeSpecific, UAnchorOwner {
override val uastDeclarations by lz {
mutableListOf<UDeclaration>().apply {
addAll(fields)
addAll(initializers)
addAll(methods)
addAll(innerClasses)
}
}
open val ktClass: KtClassOrObject? get() = (psi as? KtLightClass)?.kotlinOrigin
override val uastSuperTypes: List<UTypeReferenceExpression>
get() = ktClass?.superTypeListEntries.orEmpty().mapNotNull { it.typeReference }.map {
KotlinUTypeReferenceExpression(it, this)
}
val delegateExpressions: List<UExpression>
get() = ktClass?.superTypeListEntries.orEmpty()
.filterIsInstance<KtDelegatedSuperTypeEntry>()
.map { KotlinSupertypeDelegationUExpression(it, this) }
override fun accept(visitor: UastVisitor) {
if (visitor.visitClass(this)) return
delegateExpressions.acceptList(visitor)
uAnnotations.acceptList(visitor)
uastDeclarations.acceptList(visitor)
visitor.afterVisitClass(this)
}
override val uAnnotations: List<UAnnotation> by lz {
(sourcePsi as? KtModifierListOwner)?.annotationEntries.orEmpty().map {
baseResolveProviderService.baseKotlinConverter.convertAnnotation(it, this)
}
}
override fun equals(other: Any?) = other is AbstractKotlinUClass && psi == other.psi
override fun hashCode() = psi.hashCode()
}
open class KotlinUClass private constructor(
psi: KtLightClass,
givenParent: UElement?
open class KotlinUClass(
psi: KtLightClass,
givenParent: UElement?
) : AbstractKotlinUClass(givenParent), PsiClass by psi {
final override val ktClass = psi.kotlinOrigin