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.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.findChild
import net.mamoe.mirai.console.intellij.resolve.resolveAllCalls
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.diagnostics.Diagnostic
import org.jetbrains.kotlin.idea.search.usagesSearch.descriptor
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.resolve.checkers.DeclarationChecker
import org.jetbrains.kotlin.resolve.checkers.DeclarationCheckerContext
import java.util.*
@ -84,29 +82,30 @@ class PluginDescriptionChecker : DeclarationChecker {
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(
declaration: KtDeclaration,
descriptor: DeclarationDescriptor,
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) {
is KtClassOrObject -> {
// 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.nj2k.postProcessing.resolve
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.allChildren
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.calls.callUtil.getCall
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 }
val PsiElement.allChildrenWithSelf: Sequence<PsiElement>
get() {
return sequence {
yield(this@allChildrenWithSelf)
yieldAll(allChildren)
get() = sequence {
yield(this@allChildrenWithSelf)
for (child in children) {
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>
get() {
return sequence {