FIR/UAST: commonize abstraction of Kotlin UClass
This commit is contained in:
committed by
Ilya Kirillov
parent
0c011f4e73
commit
06c20bb10e
+57
@@ -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
-55
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user