mirror of
https://github.com/mamoe/mirai.git
synced 2025-02-05 08:14:40 +08:00
Introduce inspection NOT_CONSTRUCTABLE_TYPE for PluginData.value
This commit is contained in:
parent
e4f37b9a52
commit
7244cb76c4
@ -12,16 +12,17 @@
|
|||||||
package net.mamoe.mirai.console.compiler.common
|
package net.mamoe.mirai.console.compiler.common
|
||||||
|
|
||||||
import net.mamoe.mirai.console.util.ConsoleExperimentalApi
|
import net.mamoe.mirai.console.util.ConsoleExperimentalApi
|
||||||
|
import kotlin.annotation.AnnotationTarget.*
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 标记一个参数的语境类型, 用于帮助编译器和 IntelliJ 插件进行语境推断.
|
* 标记一个参数的语境类型, 用于帮助编译器和 IntelliJ 插件进行语境推断.
|
||||||
*/
|
*/
|
||||||
@ConsoleExperimentalApi
|
@ConsoleExperimentalApi
|
||||||
@Target(
|
@Target(
|
||||||
AnnotationTarget.VALUE_PARAMETER,
|
VALUE_PARAMETER,
|
||||||
AnnotationTarget.PROPERTY,
|
PROPERTY, FIELD,
|
||||||
AnnotationTarget.FIELD,
|
FUNCTION,
|
||||||
//AnnotationTarget.EXPRESSION
|
TYPE, TYPE_PARAMETER
|
||||||
)
|
)
|
||||||
@Retention(AnnotationRetention.BINARY)
|
@Retention(AnnotationRetention.BINARY)
|
||||||
public annotation class ResolveContext(
|
public annotation class ResolveContext(
|
||||||
@ -34,5 +35,10 @@ public annotation class ResolveContext(
|
|||||||
PLUGIN_ID,
|
PLUGIN_ID,
|
||||||
PLUGIN_NAME,
|
PLUGIN_NAME,
|
||||||
PLUGIN_VERSION,
|
PLUGIN_VERSION,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Custom serializers allowed
|
||||||
|
*/
|
||||||
|
RESTRICTED_NO_ARG_CONSTRUCTOR
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -18,9 +18,13 @@
|
|||||||
package net.mamoe.mirai.console.data
|
package net.mamoe.mirai.console.data
|
||||||
|
|
||||||
import kotlinx.serialization.KSerializer
|
import kotlinx.serialization.KSerializer
|
||||||
|
import net.mamoe.mirai.console.compiler.common.ResolveContext
|
||||||
|
import net.mamoe.mirai.console.compiler.common.ResolveContext.Kind.RESTRICTED_NO_ARG_CONSTRUCTOR
|
||||||
import net.mamoe.mirai.console.data.java.JAutoSavePluginData
|
import net.mamoe.mirai.console.data.java.JAutoSavePluginData
|
||||||
import net.mamoe.mirai.console.internal.data.*
|
import net.mamoe.mirai.console.internal.data.*
|
||||||
|
import net.mamoe.mirai.console.plugin.jvm.AbstractJvmPlugin
|
||||||
import net.mamoe.mirai.console.plugin.jvm.JvmPlugin
|
import net.mamoe.mirai.console.plugin.jvm.JvmPlugin
|
||||||
|
import net.mamoe.mirai.console.plugin.jvm.reloadPluginData
|
||||||
import net.mamoe.mirai.console.util.ConsoleExperimentalApi
|
import net.mamoe.mirai.console.util.ConsoleExperimentalApi
|
||||||
import kotlin.internal.LowPriorityInOverloadResolution
|
import kotlin.internal.LowPriorityInOverloadResolution
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
@ -98,7 +102,7 @@ import kotlin.reflect.full.findAnnotation
|
|||||||
*
|
*
|
||||||
* 要查看详细的解释,请查看 [docs/PluginData.md](https://github.com/mamoe/mirai-console/blob/master/docs/PluginData.md)
|
* 要查看详细的解释,请查看 [docs/PluginData.md](https://github.com/mamoe/mirai-console/blob/master/docs/PluginData.md)
|
||||||
*
|
*
|
||||||
* @see JvmPlugin.reloadPluginData 通过 [JvmPlugin] 获取指定 [PluginData] 实例.
|
* @see AbstractJvmPlugin.reloadPluginData 通过 [JvmPlugin] 获取指定 [PluginData] 实例.
|
||||||
* @see PluginDataStorage [PluginData] 存储仓库
|
* @see PluginDataStorage [PluginData] 存储仓库
|
||||||
* @see PluginDataExtensions 相关 [SerializerAwareValue] 映射函数
|
* @see PluginDataExtensions 相关 [SerializerAwareValue] 映射函数
|
||||||
*/
|
*/
|
||||||
@ -321,6 +325,7 @@ public inline fun <reified T> PluginData.value(
|
|||||||
* 通过具体化类型创建一个 [SerializerAwareValue].
|
* 通过具体化类型创建一个 [SerializerAwareValue].
|
||||||
* @see valueFromKType 查看更多实现信息
|
* @see valueFromKType 查看更多实现信息
|
||||||
*/
|
*/
|
||||||
|
@ResolveContext(RESTRICTED_NO_ARG_CONSTRUCTOR)
|
||||||
@LowPriorityInOverloadResolution
|
@LowPriorityInOverloadResolution
|
||||||
public inline fun <reified T> PluginData.value(apply: T.() -> Unit = {}): SerializerAwareValue<T> =
|
public inline fun <reified T> PluginData.value(apply: T.() -> Unit = {}): SerializerAwareValue<T> =
|
||||||
valueImpl<T>(typeOf0<T>(), T::class).also { it.value.apply() }
|
valueImpl<T>(typeOf0<T>(), T::class).also { it.value.apply() }
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
object Versions {
|
object Versions {
|
||||||
const val core = "1.3.0"
|
const val core = "1.3.0"
|
||||||
const val console = "1.0-RC-dev-2"
|
const val console = "1.0-RC-dev-3"
|
||||||
const val consoleGraphical = "0.0.7"
|
const val consoleGraphical = "0.0.7"
|
||||||
const val consoleTerminal = "0.1.0"
|
const val consoleTerminal = "0.1.0"
|
||||||
const val consolePure = console
|
const val consolePure = console
|
||||||
|
@ -17,6 +17,7 @@ import static org.jetbrains.kotlin.diagnostics.Severity.ERROR;
|
|||||||
|
|
||||||
public interface MiraiConsoleErrors {
|
public interface MiraiConsoleErrors {
|
||||||
DiagnosticFactory1<PsiElement, String> ILLEGAL_PLUGIN_DESCRIPTION = DiagnosticFactory1.create(ERROR);
|
DiagnosticFactory1<PsiElement, String> ILLEGAL_PLUGIN_DESCRIPTION = DiagnosticFactory1.create(ERROR);
|
||||||
|
DiagnosticFactory1<PsiElement, String> NOT_CONSTRUCTABLE_TYPE = DiagnosticFactory1.create(ERROR);
|
||||||
|
|
||||||
@Deprecated
|
@Deprecated
|
||||||
Object _init = new Object() {
|
Object _init = new Object() {
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
package net.mamoe.mirai.console.compiler.common.diagnostics
|
package net.mamoe.mirai.console.compiler.common.diagnostics
|
||||||
|
|
||||||
import net.mamoe.mirai.console.compiler.common.diagnostics.MiraiConsoleErrors.ILLEGAL_PLUGIN_DESCRIPTION
|
import net.mamoe.mirai.console.compiler.common.diagnostics.MiraiConsoleErrors.ILLEGAL_PLUGIN_DESCRIPTION
|
||||||
|
import net.mamoe.mirai.console.compiler.common.diagnostics.MiraiConsoleErrors.NOT_CONSTRUCTABLE_TYPE
|
||||||
import org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages
|
import org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages
|
||||||
import org.jetbrains.kotlin.diagnostics.rendering.DiagnosticFactoryToRendererMap
|
import org.jetbrains.kotlin.diagnostics.rendering.DiagnosticFactoryToRendererMap
|
||||||
import org.jetbrains.kotlin.diagnostics.rendering.Renderers
|
import org.jetbrains.kotlin.diagnostics.rendering.Renderers
|
||||||
@ -21,6 +22,12 @@ object MiraiConsoleErrorsRendering : DefaultErrorMessages.Extension {
|
|||||||
"{0}",
|
"{0}",
|
||||||
Renderers.STRING
|
Renderers.STRING
|
||||||
)
|
)
|
||||||
|
|
||||||
|
put(
|
||||||
|
NOT_CONSTRUCTABLE_TYPE,
|
||||||
|
"类型 {0} 无法通过反射直接构造, 需要提供默认值.",
|
||||||
|
Renderers.STRING
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getMap() = MAP
|
override fun getMap() = MAP
|
||||||
|
@ -30,6 +30,12 @@ val PLUGIN_FQ_NAME = FqName("net.mamoe.mirai.console.plugin.Plugin")
|
|||||||
val JVM_PLUGIN_DESCRIPTION_FQ_NAME = FqName("net.mamoe.mirai.console.plugin.jvm.JvmPluginDescription")
|
val JVM_PLUGIN_DESCRIPTION_FQ_NAME = FqName("net.mamoe.mirai.console.plugin.jvm.JvmPluginDescription")
|
||||||
val SIMPLE_JVM_PLUGIN_DESCRIPTION_FQ_NAME = FqName("net.mamoe.mirai.console.plugin.jvm.JvmPluginDescription")
|
val SIMPLE_JVM_PLUGIN_DESCRIPTION_FQ_NAME = FqName("net.mamoe.mirai.console.plugin.jvm.JvmPluginDescription")
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
// PluginData
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
val PLUGIN_DATA_VALUE_FUNCTIONS_FQ_FQ_NAME = FqName("net.mamoe.mirai.console.data.value")
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// Resolve
|
// Resolve
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
@ -44,6 +50,7 @@ enum class ResolveContextKind {
|
|||||||
PLUGIN_NAME,
|
PLUGIN_NAME,
|
||||||
PLUGIN_VERSION,
|
PLUGIN_VERSION,
|
||||||
|
|
||||||
|
RESTRICTED_NO_ARG_CONSTRUCTOR
|
||||||
;
|
;
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
@ -9,8 +9,41 @@
|
|||||||
|
|
||||||
package net.mamoe.mirai.console.compiler.common.resolve
|
package net.mamoe.mirai.console.compiler.common.resolve
|
||||||
|
|
||||||
|
import com.intellij.psi.PsiElement
|
||||||
|
import com.intellij.psi.PsiFile
|
||||||
|
import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.Annotated
|
import org.jetbrains.kotlin.descriptors.annotations.Annotated
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.components.hasDefaultValue
|
||||||
|
|
||||||
fun Annotated.hasAnnotation(fqName: FqName) = this.annotations.hasAnnotation(fqName)
|
fun Annotated.hasAnnotation(fqName: FqName) = this.annotations.hasAnnotation(fqName)
|
||||||
fun Annotated.findAnnotation(fqName: FqName) = this.annotations.findAnnotation(fqName)
|
fun Annotated.findAnnotation(fqName: FqName) = this.annotations.findAnnotation(fqName)
|
||||||
|
|
||||||
|
|
||||||
|
val PsiElement.allChildrenWithSelf: Sequence<PsiElement>
|
||||||
|
get() = sequence {
|
||||||
|
yield(this@allChildrenWithSelf)
|
||||||
|
for (child in children) {
|
||||||
|
yieldAll(child.allChildrenWithSelf)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline fun <reified E> PsiElement.findParent(): E? = this.parents.filterIsInstance<E>().firstOrNull()
|
||||||
|
|
||||||
|
|
||||||
|
val PsiElement.parents: Sequence<PsiElement>
|
||||||
|
get() {
|
||||||
|
val seed = if (this is PsiFile) null else parent
|
||||||
|
return generateSequence(seed) { if (it is PsiFile) null else it.parent }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun ClassDescriptor.findNoArgConstructor(): ClassConstructorDescriptor? {
|
||||||
|
return constructors.find { desc ->
|
||||||
|
desc.valueParameters.all { it.hasDefaultValue() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun ClassDescriptor.hasNoArgConstructor(): Boolean = this.findNoArgConstructor() != null
|
@ -22,7 +22,7 @@ dependencies {
|
|||||||
compileOnly(kotlin("stdlib-jdk8"))
|
compileOnly(kotlin("stdlib-jdk8"))
|
||||||
|
|
||||||
val core = "1.3.0"
|
val core = "1.3.0"
|
||||||
val console = "1.0-RC-dev-2"
|
val console = "1.0-RC-dev-3"
|
||||||
|
|
||||||
compileOnly("net.mamoe:mirai-console:$console")
|
compileOnly("net.mamoe:mirai-console:$console")
|
||||||
compileOnly("net.mamoe:mirai-core:$core")
|
compileOnly("net.mamoe:mirai-core:$core")
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package org.example.myplugin
|
package org.example.myplugin
|
||||||
|
|
||||||
|
import net.mamoe.mirai.console.data.AutoSavePluginConfig
|
||||||
|
import net.mamoe.mirai.console.data.value
|
||||||
import net.mamoe.mirai.console.plugin.jvm.JvmPluginDescription
|
import net.mamoe.mirai.console.plugin.jvm.JvmPluginDescription
|
||||||
import net.mamoe.mirai.console.plugin.jvm.KotlinPlugin
|
import net.mamoe.mirai.console.plugin.jvm.KotlinPlugin
|
||||||
|
|
||||||
@ -19,16 +21,15 @@ object MyPluginMain : KotlinPlugin(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
object MyPluginMain2 : KotlinPlugin(
|
object DataTest : AutoSavePluginConfig() {
|
||||||
JvmPluginDescription(
|
val p by value<HasDefaultValue>()
|
||||||
"",
|
val pp by value<NoDefaultValue>()
|
||||||
"0.1.0",
|
|
||||||
) {
|
|
||||||
name(".")
|
|
||||||
id("")
|
|
||||||
}
|
|
||||||
) {
|
|
||||||
fun test() {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data class HasDefaultValue(
|
||||||
|
val x: Int = 0,
|
||||||
|
)
|
||||||
|
|
||||||
|
data class NoDefaultValue(
|
||||||
|
val y: Int,
|
||||||
|
)
|
@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
package net.mamoe.mirai.console.intellij
|
package net.mamoe.mirai.console.intellij
|
||||||
|
|
||||||
|
import net.mamoe.mirai.console.intellij.diagnostics.PluginDataValuesChecker
|
||||||
import net.mamoe.mirai.console.intellij.diagnostics.PluginDescriptionChecker
|
import net.mamoe.mirai.console.intellij.diagnostics.PluginDescriptionChecker
|
||||||
import org.jetbrains.kotlin.container.StorageComponentContainer
|
import org.jetbrains.kotlin.container.StorageComponentContainer
|
||||||
import org.jetbrains.kotlin.container.useInstance
|
import org.jetbrains.kotlin.container.useInstance
|
||||||
@ -22,5 +23,6 @@ class IDEContainerContributor : StorageComponentContainerContributor {
|
|||||||
moduleDescriptor: ModuleDescriptor,
|
moduleDescriptor: ModuleDescriptor,
|
||||||
) {
|
) {
|
||||||
container.useInstance(PluginDescriptionChecker())
|
container.useInstance(PluginDescriptionChecker())
|
||||||
|
container.useInstance(PluginDataValuesChecker())
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -0,0 +1,64 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020 Mamoe Technologies and contributors.
|
||||||
|
*
|
||||||
|
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||||
|
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||||
|
*
|
||||||
|
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.mamoe.mirai.console.intellij.diagnostics
|
||||||
|
|
||||||
|
import com.intellij.psi.PsiElement
|
||||||
|
import net.mamoe.mirai.console.compiler.common.castOrNull
|
||||||
|
import net.mamoe.mirai.console.compiler.common.diagnostics.MiraiConsoleErrors
|
||||||
|
import net.mamoe.mirai.console.compiler.common.resolve.PLUGIN_DATA_VALUE_FUNCTIONS_FQ_FQ_NAME
|
||||||
|
import net.mamoe.mirai.console.compiler.common.resolve.ResolveContextKind
|
||||||
|
import net.mamoe.mirai.console.compiler.common.resolve.hasNoArgConstructor
|
||||||
|
import net.mamoe.mirai.console.compiler.common.resolve.resolveContextKind
|
||||||
|
import net.mamoe.mirai.console.intellij.resolve.resolveAllCallsWithElement
|
||||||
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
|
import org.jetbrains.kotlin.idea.inspections.collections.isCalling
|
||||||
|
import org.jetbrains.kotlin.idea.refactoring.fqName.fqName
|
||||||
|
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||||
|
import org.jetbrains.kotlin.resolve.checkers.DeclarationChecker
|
||||||
|
import org.jetbrains.kotlin.resolve.checkers.DeclarationCheckerContext
|
||||||
|
import org.jetbrains.kotlin.types.SimpleType
|
||||||
|
|
||||||
|
|
||||||
|
class PluginDataValuesChecker : DeclarationChecker {
|
||||||
|
override fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor, context: DeclarationCheckerContext) {
|
||||||
|
val bindingContext = context.bindingContext
|
||||||
|
declaration.resolveAllCallsWithElement(bindingContext)
|
||||||
|
.filter { (call) -> call.isCalling(PLUGIN_DATA_VALUE_FUNCTIONS_FQ_FQ_NAME) }
|
||||||
|
.filter { (call) ->
|
||||||
|
call.resultingDescriptor.resolveContextKind == ResolveContextKind.RESTRICTED_NO_ARG_CONSTRUCTOR
|
||||||
|
}.flatMap { (call, element) ->
|
||||||
|
call.typeArguments.entries.associateWith { element }.asSequence()
|
||||||
|
}.filter { (e, _) ->
|
||||||
|
val (p, t) = e
|
||||||
|
(p.isReified || p.resolveContextKind == ResolveContextKind.RESTRICTED_NO_ARG_CONSTRUCTOR)
|
||||||
|
&& t is SimpleType
|
||||||
|
}.forEach { (e, callExpr) ->
|
||||||
|
val (_, t) = e
|
||||||
|
val classDescriptor = t.constructor.declarationDescriptor?.castOrNull<ClassDescriptor>()
|
||||||
|
|
||||||
|
fun getInspectionTarget(): PsiElement {
|
||||||
|
return callExpr.typeArguments.find { it.references.firstOrNull()?.canonicalText == t.fqName?.toString() } ?: callExpr
|
||||||
|
}
|
||||||
|
|
||||||
|
fun reportInspection() {
|
||||||
|
context.report(MiraiConsoleErrors.NOT_CONSTRUCTABLE_TYPE.on(
|
||||||
|
getInspectionTarget(),
|
||||||
|
t.fqName?.asString().toString())
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
when {
|
||||||
|
classDescriptor == null -> reportInspection()
|
||||||
|
!classDescriptor.hasNoArgConstructor() -> reportInspection()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -17,10 +17,10 @@ import com.intellij.openapi.editor.markup.GutterIconRenderer
|
|||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import com.intellij.util.castSafelyTo
|
import com.intellij.util.castSafelyTo
|
||||||
import net.mamoe.mirai.console.compiler.common.resolve.PLUGIN_FQ_NAME
|
import net.mamoe.mirai.console.compiler.common.resolve.PLUGIN_FQ_NAME
|
||||||
|
import net.mamoe.mirai.console.compiler.common.resolve.parents
|
||||||
import net.mamoe.mirai.console.intellij.Icons
|
import net.mamoe.mirai.console.intellij.Icons
|
||||||
import net.mamoe.mirai.console.intellij.resolve.allSuperNames
|
import net.mamoe.mirai.console.intellij.resolve.allSuperNames
|
||||||
import net.mamoe.mirai.console.intellij.resolve.getElementForLineMark
|
import net.mamoe.mirai.console.intellij.resolve.getElementForLineMark
|
||||||
import net.mamoe.mirai.console.intellij.resolve.parents
|
|
||||||
import org.jetbrains.kotlin.nj2k.postProcessing.resolve
|
import org.jetbrains.kotlin.nj2k.postProcessing.resolve
|
||||||
import org.jetbrains.kotlin.psi.KtClass
|
import org.jetbrains.kotlin.psi.KtClass
|
||||||
import org.jetbrains.kotlin.psi.KtConstructor
|
import org.jetbrains.kotlin.psi.KtConstructor
|
||||||
|
@ -11,10 +11,11 @@ package net.mamoe.mirai.console.intellij.resolve
|
|||||||
|
|
||||||
import com.intellij.psi.PsiDeclarationStatement
|
import com.intellij.psi.PsiDeclarationStatement
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import com.intellij.psi.PsiFile
|
|
||||||
import net.mamoe.mirai.console.compiler.common.castOrNull
|
import net.mamoe.mirai.console.compiler.common.castOrNull
|
||||||
import net.mamoe.mirai.console.compiler.common.resolve.COMPOSITE_COMMAND_SUB_COMMAND_FQ_NAME
|
import net.mamoe.mirai.console.compiler.common.resolve.COMPOSITE_COMMAND_SUB_COMMAND_FQ_NAME
|
||||||
import net.mamoe.mirai.console.compiler.common.resolve.SIMPLE_COMMAND_HANDLER_COMMAND_FQ_NAME
|
import net.mamoe.mirai.console.compiler.common.resolve.SIMPLE_COMMAND_HANDLER_COMMAND_FQ_NAME
|
||||||
|
import net.mamoe.mirai.console.compiler.common.resolve.allChildrenWithSelf
|
||||||
|
import net.mamoe.mirai.console.compiler.common.resolve.findParent
|
||||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.VariableDescriptor
|
import org.jetbrains.kotlin.descriptors.VariableDescriptor
|
||||||
@ -67,16 +68,8 @@ fun KtConstructorCalleeExpression.getTypeAsUserType(): KtUserType? {
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun <reified E> PsiElement.findParent(): E? = this.parents.filterIsInstance<E>().firstOrNull()
|
|
||||||
|
|
||||||
val KtClassOrObject.allSuperNames: Sequence<FqName> get() = allSuperTypes.mapNotNull { it.getKotlinFqName() }
|
val KtClassOrObject.allSuperNames: Sequence<FqName> get() = allSuperTypes.mapNotNull { it.getKotlinFqName() }
|
||||||
|
|
||||||
val PsiElement.parents: Sequence<PsiElement>
|
|
||||||
get() {
|
|
||||||
val seed = if (this is PsiFile) null else parent
|
|
||||||
return generateSequence(seed) { if (it is PsiFile) null else it.parent }
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getElementForLineMark(callElement: PsiElement): PsiElement =
|
fun getElementForLineMark(callElement: PsiElement): PsiElement =
|
||||||
when (callElement) {
|
when (callElement) {
|
||||||
is KtSimpleNameExpression -> callElement.getReferencedNameElement()
|
is KtSimpleNameExpression -> callElement.getReferencedNameElement()
|
||||||
@ -92,20 +85,23 @@ val KtAnnotationEntry.annotationClass: KtClass?
|
|||||||
fun KtAnnotated.hasAnnotation(fqName: FqName): Boolean =
|
fun KtAnnotated.hasAnnotation(fqName: FqName): Boolean =
|
||||||
this.annotationEntries.any { it.annotationClass?.getKotlinFqName() == fqName }
|
this.annotationEntries.any { it.annotationClass?.getKotlinFqName() == fqName }
|
||||||
|
|
||||||
val PsiElement.allChildrenWithSelf: Sequence<PsiElement>
|
|
||||||
get() = sequence {
|
|
||||||
yield(this@allChildrenWithSelf)
|
|
||||||
for (child in children) {
|
|
||||||
yieldAll(child.allChildrenWithSelf)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun KtDeclaration.resolveAllCalls(bindingContext: BindingContext): Sequence<ResolvedCall<*>> {
|
fun KtDeclaration.resolveAllCalls(bindingContext: BindingContext): Sequence<ResolvedCall<*>> {
|
||||||
return allChildrenWithSelf
|
return allChildrenWithSelf
|
||||||
.filterIsInstance<KtCallExpression>()
|
.filterIsInstance<KtCallExpression>()
|
||||||
.mapNotNull { it.calleeExpression?.getResolvedCallOrResolveToCall(bindingContext) }
|
.mapNotNull { it.calleeExpression?.getResolvedCallOrResolveToCall(bindingContext) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun KtDeclaration.resolveAllCallsWithElement(bindingContext: BindingContext): Sequence<Pair<ResolvedCall<out CallableDescriptor>, KtCallExpression>> {
|
||||||
|
return allChildrenWithSelf
|
||||||
|
.filterIsInstance<KtCallExpression>()
|
||||||
|
.mapNotNull {
|
||||||
|
val callee = it.calleeExpression ?: return@mapNotNull null
|
||||||
|
val resolved = callee.getResolvedCallOrResolveToCall(bindingContext) ?: return@mapNotNull null
|
||||||
|
|
||||||
|
resolved to it
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun ResolvedCall<*>.valueParametersWithArguments(): List<Pair<ValueParameterDescriptor, ValueArgument>> {
|
fun ResolvedCall<*>.valueParametersWithArguments(): List<Pair<ValueParameterDescriptor, ValueArgument>> {
|
||||||
return this.valueParameters.zip(this.valueArgumentsByIndex?.mapNotNull { it.arguments.firstOrNull() }.orEmpty())
|
return this.valueParameters.zip(this.valueArgumentsByIndex?.mapNotNull { it.arguments.firstOrNull() }.orEmpty())
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user