Improve performance

This commit is contained in:
Him188 2020-09-18 11:11:31 +08:00
parent 0c1bf9ce9b
commit e299ecffb9
2 changed files with 41 additions and 29 deletions

View File

@ -13,14 +13,12 @@ import com.intellij.psi.PsiElement
import net.mamoe.mirai.console.compiler.common.diagnostics.MiraiConsoleErrors import net.mamoe.mirai.console.compiler.common.diagnostics.MiraiConsoleErrors
import net.mamoe.mirai.console.compiler.common.resolve.ResolveContextKind import net.mamoe.mirai.console.compiler.common.resolve.ResolveContextKind
import net.mamoe.mirai.console.compiler.common.resolve.resolveContextKind import net.mamoe.mirai.console.compiler.common.resolve.resolveContextKind
import net.mamoe.mirai.console.intellij.resolve.allChildrenWithSelf import net.mamoe.mirai.console.intellij.resolve.resolveAllCalls
import net.mamoe.mirai.console.intellij.resolve.findChild
import net.mamoe.mirai.console.intellij.resolve.resolveStringConstantValue import net.mamoe.mirai.console.intellij.resolve.resolveStringConstantValue
import net.mamoe.mirai.console.intellij.resolve.valueParameters import net.mamoe.mirai.console.intellij.resolve.valueParametersWithArguments
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.diagnostics.Diagnostic import org.jetbrains.kotlin.diagnostics.Diagnostic
import org.jetbrains.kotlin.idea.search.usagesSearch.descriptor import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.checkers.DeclarationChecker import org.jetbrains.kotlin.resolve.checkers.DeclarationChecker
import org.jetbrains.kotlin.resolve.checkers.DeclarationCheckerContext import org.jetbrains.kotlin.resolve.checkers.DeclarationCheckerContext
import java.util.* import java.util.*
@ -84,29 +82,30 @@ class PluginDescriptionChecker : DeclarationChecker {
put(ResolveContextKind.PLUGIN_VERSION, ::checkPluginVersion) put(ResolveContextKind.PLUGIN_VERSION, ::checkPluginVersion)
} }
fun check(
expression: KtCallExpression,
context: DeclarationCheckerContext,
) {
val call = expression.calleeExpression.getResolvedCallOrResolveToCall(context) ?: return // unresolved
for ((parameter, argument) in call.valueParameters.zip(call.valueArgumentsByIndex?.mapNotNull { it.arguments.firstOrNull() }.orEmpty())) {
val parameterContextKind = parameter.resolveContextKind
if (checkersMap.containsKey(parameterContextKind)) {
val value = argument.getArgumentExpression()
?.resolveStringConstantValue(context.bindingContext) ?: continue
for ((kind, fn) in checkersMap) {
if (parameterContextKind == kind) fn(argument.asElement(), value)?.let { context.report(it) }
}
}
}
}
override fun check( override fun check(
declaration: KtDeclaration, declaration: KtDeclaration,
descriptor: DeclarationDescriptor, descriptor: DeclarationDescriptor,
context: DeclarationCheckerContext, context: DeclarationCheckerContext,
) { ) {
println("${declaration::class.qualifiedName} $declaration") declaration.resolveAllCalls(context.bindingContext)
.flatMap { call ->
call.valueParametersWithArguments().asSequence()
}
.mapNotNull { (p, a) ->
p.resolveContextKind?.takeIf { it in checkersMap }?.let { it to a }
}
.mapNotNull { (kind, argument) ->
argument.resolveStringConstantValue(context.bindingContext)?.let { const ->
Triple(kind, argument, const)
}
}
.forEach { (parameterContextKind, argument, resolvedConstant) ->
for ((kind, fn) in checkersMap) {
if (parameterContextKind == kind) fn(argument.asElement(), resolvedConstant)?.let { context.report(it) }
}
}
return
/*
when (declaration) { when (declaration) {
is KtClassOrObject -> { is KtClassOrObject -> {
// check super type constructor // check super type constructor
@ -140,6 +139,6 @@ class PluginDescriptionChecker : DeclarationChecker {
} }
} }
} }
} }*/
} }
} }

View File

@ -25,7 +25,6 @@ import org.jetbrains.kotlin.idea.search.usagesSearch.descriptor
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.nj2k.postProcessing.resolve import org.jetbrains.kotlin.nj2k.postProcessing.resolve
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.allChildren
import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.calls.callUtil.getCall import org.jetbrains.kotlin.resolve.calls.callUtil.getCall
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
@ -94,13 +93,27 @@ 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> val PsiElement.allChildrenWithSelf: Sequence<PsiElement>
get() { get() = sequence {
return sequence { yield(this@allChildrenWithSelf)
yield(this@allChildrenWithSelf) for (child in children) {
yieldAll(allChildren) yieldAll(child.allChildrenWithSelf)
} }
} }
fun KtDeclaration.resolveAllCalls(bindingContext: BindingContext): Sequence<ResolvedCall<*>> {
return allChildrenWithSelf
.filterIsInstance<KtCallExpression>()
.mapNotNull { it.calleeExpression?.getResolvedCallOrResolveToCall(bindingContext) }
}
fun ResolvedCall<*>.valueParametersWithArguments(): List<Pair<ValueParameterDescriptor, ValueArgument>> {
return this.valueParameters.zip(this.valueArgumentsByIndex?.mapNotNull { it.arguments.firstOrNull() }.orEmpty())
}
fun ValueArgument.resolveStringConstantValue(bindingContext: BindingContext): String? {
return this.getArgumentExpression()?.resolveStringConstantValue(bindingContext)
}
val PsiElement.allChildrenFlat: Sequence<PsiElement> val PsiElement.allChildrenFlat: Sequence<PsiElement>
get() { get() {
return sequence { return sequence {