从 Kotlin Psi API 检索继承类全名

     2023-02-26     263

关键词:

【中文标题】从 Kotlin Psi API 检索继承类全名【英文标题】:Retrieve Inheritance class full name from Kotlin Psi API 【发布时间】:2021-11-05 18:12:19 【问题描述】:

我正在尝试开发一个 codegen IDEA-Plugin。这个插件应该分析KtClassInheritance并获取所有继承类全名(如com.example.config.TestConfig)

我试图通过查看 PsiViewer 找到任何有用的信息。我发现所有 KtClass的继承信息存放在KtSuperTypeEntry,我尽量得到继承类的全名。

Dest

data class Dest(
    val stringValue: String = "123",
    override val stringConfig: String = "123",
    override val iConfigStr: String = "123",
    val b: B = B(),
    val c: List<List<Set<Map<String, out Any?>>>> = listOf(),
    val config: Config? = Config()
) : Config()
    superTypeListEntry.typeAsUserType.referenceExpression.getReferencedName() -return-> "Config" superTypeListEntry.importReceiverMembers() -return-> null

貌似 SuperTypeListEntry 只包含继承类简单名称信息。

我也尝试通过KtFile查找继承类全名,但是不知道这个KtFile中的继承类是什么时候作为通配符导入的:

fun KtSuperTypeListEntry.getType(ktFile: KtFile): String 
    val simpleName = superTypeListEntry.text

    // try to find by declared KtClass ...
    ktFile.children.filterIsInstance<KtClass>().filter  it.name == simpleName 

    // try to find by import ...
    ktFile.importDirectives.filter  it.importPath.toString().contains(simpleName) 

    
    // try to find by import wildcards ...
    ktFile.importDirectives.filter  it.importPath.toString().endWith("*") .forEach 
        val split = it.importPath.split(".")
        split.set(split.size - 1, simpleName)
        val maybeFullName = split.joinToString(",")  it 
        // confused on how to detect "maybeFullName" is correct ...
    

问题

如何从 Kotlin Psi API 检索所有继承类全名?谢谢!

【问题讨论】:

【参考方案1】:

千方百计的排查调试,发现通过BindingContext可以找到一个类的继承类。 BindingContext 可以分析一个 TypeReference 并找到KotlinType 的引用。代码可能是这样的:

ktClass.superTypeListEntries.map  superTypeEntry ->
    val typeReference = superTypeEntry.typeReference
    val bindingContext = typeReference.analyze()
    bindingContext.get(BindingContext.TYPE, typeReference)
.forEach  kotlinType ->
    val classId = kotlinType.constructor.declarationDescriptor.classId
    val packageName = classId.packageFqName
    val simpleName = classId.relativeClassName
    // It can also get the generics of this class by KotlinType.arguments
    val generics = kotlinType.arguments

另外,你可以通过KtLightClass获取类的超类型全名,代码可能是这样的:

val ktLightClass = ktClass.toLightClass()
val superTypesFullName = ktLightClass?.supers?.forEach  superType ->
    val packageName = superType.qualifiedName
    val simpleName = superType.name
    // you can get as KtClass by this, which can help you unify design of interface.
    val ktClass = superType.kotlinOrigin

【讨论】:

kotlin继承

Kotlin中所有类都继承该Any类,它是所有类的超类,对于没有超类型声明的类是默认超类:classExample//从Any隐式继承Any默认提供了三个函数:equals()hashCode()toString()注意:Any不是java.lang.Object。如果一个类要被继承,可以使用open关键... 查看详情

OkHttpClient 成功从 API 检索数据,但在 Kotlin Android 应用程序中调用了入队 onFailure

】OkHttpClient成功从API检索数据,但在KotlinAndroid应用程序中调用了入队onFailure【英文标题】:OkHttpClientsuccessfullyretrievesdatafromAPI,butonenqueueonFailureiscalledinKotlinAndroidapplication【发布时间】:2021-04-1521:31:39【问题描述】:我正在尝试在A... 查看详情

kotlin初学者继承(extend)(代码片段)

Kotlin继承(extend)        Kotlin允许一个类继承自另一个类        Kotlin中所有类都继承自Any类        Any类是所有类的超类,对于没有超类型声明的类是默认超类        Kotlin类默认都是封闭的,要让某个类... 查看详情

使用 AD 和 Apache shiro 从 LDAP 服务器检索全名或显示名

】使用AD和Apacheshiro从LDAP服务器检索全名或显示名【英文标题】:RetrieveFullnameorDisplaynamefromLDAPserverusingADandApacheshiro【发布时间】:2018-03-2013:50:01【问题描述】:我正在尝试针对LDAP服务器验证一组凭据,并且我能够成功验证它们... 查看详情

有啥方法可以在 Kotlin 中从同一个通用接口继承两次(使用不同的类型)?

】有啥方法可以在Kotlin中从同一个通用接口继承两次(使用不同的类型)?【英文标题】:Anywaytoinheritfromsamegenericinterfacetwice(withseparatetypes)inKotlin?有什么方法可以在Kotlin中从同一个通用接口继承两次(使用不同的类型)?【发布... 查看详情

kotlin中级---kotlin类之的继承.md

Kotlin继承类1.超类(Any)在Kotlin中,所有的类都是继承自Any类,这是一个没有父类型的类。即当我们定义各类时,它默认是继承于Any类的例如:classPerson因为Any这个类只是给我们提供了equals、hashcode、toString三个方法&#x... 查看详情

使用 KOTLIN 从 firebase 检索数据时出错

】使用KOTLIN从firebase检索数据时出错【英文标题】:errorretrievingdatafromfirebasewithKOTLIN【发布时间】:2020-10-2611:29:16【问题描述】:我正在尝试从firebase检索数据,但我得到:java.lang.ClassCastException:java.util.HashMap无法转换为com.android.... 查看详情

如何在 Kotlin 中用继承的类覆盖方法?

】如何在Kotlin中用继承的类覆盖方法?【英文标题】:HowtooverridemethodwithinheritedclassinKotlin?【发布时间】:2022-01-1209:16:14【问题描述】:我正在探索并积极在Kotlin的生产环境中使用泛型。Kotlin+泛型对我来说是一个很大的难题,所... 查看详情

kotlin学习之路:继承(代码片段)

...承二.继承中的构造函数2.1继承中Java的构造函数2.2继承中Kotlin的构造函数2.3Kotlin多个构造函数的情况三.重写和重载3.1方法的重写3.2属性的重写四.super关键字4.1简单用法4.2复杂情况下的用法4.2.1子类重写方法中使用super4.2.2子类选择... 查看详情

如何通过 Java/Kotlin API 从 KeyCloak 请求 JWT 令牌

】如何通过Java/KotlinAPI从KeyCloak请求JWT令牌【英文标题】:HowtorequestJWTTokenfromKeyCloakviaJava/KotlinAPI【发布时间】:2020-08-1411:11:35【问题描述】:我想要的是在单元测试中来自我的KeyCloak-Server的JWT-Token来测试我的Rest-API如何通过Java-API... 查看详情

从 Kotlin Native 继承 UIView

】从KotlinNative继承UIView【英文标题】:SubclassingUIViewfromKotlinNative【发布时间】:2021-11-1420:34:13【问题描述】:UIKit旨在通过子类和重写方法使用。通常,UIView的drawRectobjective-C方法在SWIFT中是这样实现的:importUIKitimportFoundationclassSm... 查看详情

如何从文本 kotlin 中检索特定字符串?

】如何从文本kotlin中检索特定字符串?【英文标题】:Howtoretrieveparticularstringfromatextkotlin?【发布时间】:2021-09-0423:20:37【问题描述】:我正在以字符串形式获取扫描结果,例如---DriverId=60cb1daa20056c0c92ebe457,Amount=10.0我想从此字符串... 查看详情

当有唯一键 Kotlin 时如何从 Firebase 检索孩子

】当有唯一键Kotlin时如何从Firebase检索孩子【英文标题】:HowtoretrieveachildfromFirebasewhenthereisauniquekeyKotlin【发布时间】:2020-08-0811:24:20【问题描述】:我想从Firebase实时数据库中检索特定的子值,例如(电话号码、名字、姓氏)但... 查看详情

kotlin类与继承

类Kotlin使用class关键字声明类,类声明由类名、类头(指定其类型参数、主构造函数等)和由大括号包围的类体组成。类头和类体都是可选的,如果一个类没有类体大括号可省略class NoBody类的构造函数一类可以有一个主构造... 查看详情

从 Firebase 实时数据库 Kotlin 中检索有序数据

】从Firebase实时数据库Kotlin中检索有序数据【英文标题】:Retrievingordereddatafromfirebasereal-timedatabaseKotlin【发布时间】:2020-09-1819:06:48【问题描述】:我有一个看起来像这样的实时Firebase数据库。图像中显示了许多元素,其中3与这3... 查看详情

kotlin类属性方法继承多态(代码片段)

Kotlin类、属性、方法、继承、多态一、Kotlin类1.kotlin定义类使用open修饰类,表明可被子类继承使用open修饰属性,表明可被子类覆写/***Kotlin使用class定义类Phone,使用open修饰类,表明可被继承*主构造器参数为system... 查看详情

kotlin类的继承①(使用open关键字开启类的继承|使用open关键字开启方法重写)(代码片段)

...open关键字开启方法重写一、使用open关键字开启类的继承Kotlin中的类默认都是封闭的,无法被继承,如果要想类被继承,需要在定义类时使用open关键字;定义一个普通的Kotlin类:classPerson(valname:String,valage:Int)funinfo()println("name:$name,age:$... 查看详情

kotlin类的继承①(使用open关键字开启类的继承|使用open关键字开启方法重写)(代码片段)

...open关键字开启方法重写一、使用open关键字开启类的继承Kotlin中的类默认都是封闭的,无法被继承,如果要想类被继承,需要在定义类时使用open关键字;定义一个普通的Kotlin类:classPerson(valname:String,valage:Int)funinfo()println("name:$name,age:$... 查看详情