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 -> {
|
is KtLightClass -> {
|
||||||
// TODO: differentiate enum entry
|
// TODO: differentiate enum entry
|
||||||
el<UClass> { AbstractFirKotlinUClass.create(original, givenParent) }
|
el<UClass> { FirKotlinUClass.create(original, givenParent) }
|
||||||
}
|
}
|
||||||
is KtClassOrObject -> {
|
is KtClassOrObject -> {
|
||||||
convertClassOrObject(original, givenParent, requiredTypes).firstOrNull()
|
convertClassOrObject(original, givenParent, requiredTypes).firstOrNull()
|
||||||
@@ -126,7 +126,7 @@ internal object FirKotlinConverter : BaseKotlinConverter {
|
|||||||
// File
|
// File
|
||||||
alternative { KotlinUFile(element, firKotlinUastPlugin) },
|
alternative { KotlinUFile(element, firKotlinUastPlugin) },
|
||||||
// Facade
|
// 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>>
|
requiredTypes: Array<out Class<out UElement>>
|
||||||
): Sequence<UElement> {
|
): Sequence<UElement> {
|
||||||
val ktLightClass = element.toLightClass() ?: return emptySequence()
|
val ktLightClass = element.toLightClass() ?: return emptySequence()
|
||||||
val uClass = AbstractFirKotlinUClass.create(ktLightClass, givenParent)
|
val uClass = FirKotlinUClass.create(ktLightClass, givenParent)
|
||||||
return requiredTypes.accommodate(
|
return requiredTypes.accommodate(
|
||||||
// Class
|
// Class
|
||||||
alternative { uClass },
|
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.load.java.JvmAbi
|
||||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||||
import org.jetbrains.kotlin.psi.KtDelegatedSuperTypeEntry
|
|
||||||
import org.jetbrains.kotlin.psi.KtObjectDeclaration
|
import org.jetbrains.kotlin.psi.KtObjectDeclaration
|
||||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||||
import org.jetbrains.uast.*
|
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
|
// TODO: can be commonized once *KotlinUClass is commonized
|
||||||
class FirKotlinUClass(
|
class FirKotlinUClass(
|
||||||
override val javaPsi: KtLightClass,
|
override val javaPsi: KtLightClass,
|
||||||
givenParent: UElement?,
|
givenParent: UElement?,
|
||||||
) : AbstractFirKotlinUClass(givenParent), PsiClass by javaPsi {
|
) : AbstractKotlinUClass(givenParent), PsiClass by javaPsi {
|
||||||
override val ktClass: KtClassOrObject? = javaPsi.kotlinOrigin
|
override val ktClass: KtClassOrObject? = javaPsi.kotlinOrigin
|
||||||
|
|
||||||
override val psi = unwrap<UClass, PsiClass>(javaPsi)
|
override val psi = unwrap<UClass, PsiClass>(javaPsi)
|
||||||
@@ -168,6 +114,17 @@ class FirKotlinUClass(
|
|||||||
|
|
||||||
return result.toTypedArray()
|
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 ?
|
// TODO: FirKotlinUAnonymousClass or FirKotlinUAnonymousObject ?
|
||||||
|
|||||||
@@ -26,54 +26,10 @@ import org.jetbrains.kotlin.load.java.JvmAbi
|
|||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||||
import org.jetbrains.uast.*
|
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 {
|
open class KotlinUClass(
|
||||||
|
psi: KtLightClass,
|
||||||
override val uastDeclarations by lz {
|
givenParent: UElement?
|
||||||
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?
|
|
||||||
) : AbstractKotlinUClass(givenParent), PsiClass by psi {
|
) : AbstractKotlinUClass(givenParent), PsiClass by psi {
|
||||||
|
|
||||||
final override val ktClass = psi.kotlinOrigin
|
final override val ktClass = psi.kotlinOrigin
|
||||||
|
|||||||
Reference in New Issue
Block a user