From c5e0f992e515d9158d99da50aa5018daf4ede97f Mon Sep 17 00:00:00 2001 From: Yan Zhulanow Date: Wed, 18 May 2016 19:24:37 +0300 Subject: [PATCH] KT-12387 Fix Performance problem with Lint in IDE Call checkCanceled() before running Lint diagnostics (UastScanner) (cherry picked from commit c6e328a) (cherry picked from commit 696475e) --- .../klint/AndroidLintInspectionBase.java | 3 +++ .../src/org/jetbrains/uast/check/UastChecker.kt | 15 ++++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/AndroidLintInspectionBase.java b/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/AndroidLintInspectionBase.java index 24a070651dd..5119d1a551b 100644 --- a/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/AndroidLintInspectionBase.java +++ b/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/AndroidLintInspectionBase.java @@ -16,6 +16,7 @@ import com.intellij.lang.annotation.ProblemGroup; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.colors.TextAttributesKey; +import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.TextRange; import com.intellij.openapi.vfs.LocalFileSystem; @@ -156,6 +157,8 @@ public abstract class AndroidLintInspectionBase extends GlobalInspectionTool { private ProblemDescriptor[] computeProblemDescriptors(@NotNull PsiElement psiFile, @NotNull InspectionManager manager, @NotNull List problems) { + ProgressManager.checkCanceled(); + final List result = new ArrayList(); for (ProblemData problemData : problems) { diff --git a/plugins/lint/uast-android/src/org/jetbrains/uast/check/UastChecker.kt b/plugins/lint/uast-android/src/org/jetbrains/uast/check/UastChecker.kt index 0b3aca8c759..85671fed926 100644 --- a/plugins/lint/uast-android/src/org/jetbrains/uast/check/UastChecker.kt +++ b/plugins/lint/uast-android/src/org/jetbrains/uast/check/UastChecker.kt @@ -19,6 +19,8 @@ import com.android.tools.klint.detector.api.Issue import com.android.tools.klint.detector.api.JavaContext import com.android.tools.klint.detector.api.Location import com.intellij.openapi.application.ApplicationManager +import com.intellij.openapi.progress.ProgressManager +import com.intellij.openapi.project.DumbService import com.intellij.openapi.project.Project import com.intellij.openapi.vfs.VirtualFileManager import com.intellij.psi.PsiJavaFile @@ -41,12 +43,18 @@ interface UastAndroidContext : UastContext { object UastChecker { fun check(project: Project, file: File, context: UastAndroidContext, visitor: UastVisitor) { + ProgressManager.checkCanceled() + val vfile = VirtualFileManager.getInstance().findFileByUrl("file://" + file.absolutePath) ?: return val plugins = context.languagePlugins val extendableVisitor = UastExtendableVisitor(visitor, context, plugins.flatMap { it.visitorExtensions }) - ApplicationManager.getApplication().runReadAction { + val instance = DumbService.getInstance(project) + // Do not check anything in dumb mode + if (instance.isDumb) return + + instance.runReadActionInSmartMode { val psiFile = PsiManager.getInstance(project).findFile(vfile) if (psiFile != null) { @@ -78,6 +86,7 @@ object UastChecker { override fun visitCallExpression(node: UCallExpression): Boolean { if (applicableFunctionNames.isNotEmpty()) { if (node.kind == FUNCTION_CALL && node.functionName in applicableFunctionNames) { + ProgressManager.checkCanceled() scanner.visitCall(context, node) } } @@ -86,6 +95,7 @@ object UastChecker { if (node.kind == CONSTRUCTOR_CALL) { node.resolve(context)?.let { constructor -> if (constructor.getContainingClass()?.fqName in applicableConstructorTypes) { + ProgressManager.checkCanceled() scanner.visitConstructor(context, node, constructor) } } @@ -98,6 +108,7 @@ object UastChecker { override fun visitClass(node: UClass): Boolean { if (applicableSuperClasses.isNotEmpty()) { if (applicableSuperClasses.any { node.isSubclassOf(it) }) { + ProgressManager.checkCanceled() scanner.visitClass(context, node) } } @@ -107,6 +118,8 @@ object UastChecker { override fun visitQualifiedExpression(node: UQualifiedExpression): Boolean { if (appliesToResourcesRefs && node.receiver is UQualifiedExpression) { + ProgressManager.checkCanceled() + val parentQualifiedExpr = node.receiver as UQualifiedExpression val resourceName = node.selector val resourceType = parentQualifiedExpr.selector