Lint: fix Lint additional checkers with the custom handlers

This commit is contained in:
Yan Zhulanow
2016-03-22 19:45:55 +03:00
parent 37a4d78347
commit 5cf5024d08
2 changed files with 36 additions and 24 deletions
@@ -1445,7 +1445,6 @@ public class LintDriver {
if (ideaProject == null) { if (ideaProject == null) {
return; return;
} }
List<UastLanguagePlugin> plugins = mClient.getLanguagePlugins();
for (JavaContext context : contexts) { for (JavaContext context : contexts) {
fireEvent(LintListener.EventType.SCANNING_FILE, context); fireEvent(LintListener.EventType.SCANNING_FILE, context);
@@ -1456,10 +1455,10 @@ public class LintDriver {
UastVisitor customVisitor = scanner.createUastVisitor(context); UastVisitor customVisitor = scanner.createUastVisitor(context);
if (customVisitor != null) { if (customVisitor != null) {
UastChecker.INSTANCE.checkWithCustomHandler( UastChecker.INSTANCE.checkWithCustomHandler(
ideaProject, context.file, plugins, customVisitor); ideaProject, context.file, context, customVisitor);
} else { } else {
UastChecker.INSTANCE.check( UastChecker.INSTANCE.check(
ideaProject, context.file, (UastScanner)check, plugins, context); ideaProject, context.file, (UastScanner)check, context);
} }
} }
} }
@@ -1516,9 +1515,9 @@ public class LintDriver {
for (UastScanner detector : detectors) { for (UastScanner detector : detectors) {
UastVisitor customHandler = detector.createUastVisitor(context); UastVisitor customHandler = detector.createUastVisitor(context);
if (customHandler != null) { if (customHandler != null) {
checker.checkWithCustomHandler(intellijProject, file, plugins, customHandler); checker.checkWithCustomHandler(intellijProject, file, context, customHandler);
} else { } else {
checker.check(intellijProject, file, detector, plugins, context); checker.check(intellijProject, file, detector, context);
} }
} }
} }
@@ -41,13 +41,24 @@ object UastChecker {
fun checkWithCustomHandler( fun checkWithCustomHandler(
project: Project, project: Project,
file: File, file: File,
converters: List<UastLanguagePlugin>, context: UastAndroidContext,
visitor: UastVisitor) { visitor: UastVisitor) {
check(project, file, converters, UastHandler { visitor.handle(it) }) check(project, file, context, UastHandler { visitor.handle(it) })
} }
fun check(project: Project, file: File, plugins: List<UastLanguagePlugin>, handler: UastHandler) { fun check(project: Project, file: File, context: UastAndroidContext, handler: UastHandler) {
val vfile = VirtualFileManager.getInstance().findFileByUrl("file://" + file.absolutePath) ?: return val vfile = VirtualFileManager.getInstance().findFileByUrl("file://" + file.absolutePath) ?: return
val plugins = context.languagePlugins
val additionalCheckers = plugins.fold(mutableListOf<UastAdditionalChecker>()) { list, plugin ->
for (checker in plugin.additionalCheckers) {
if (checker is AndroidUastAdditionalChecker) list += checker
}
list
}
val handlerWrapper = HandlerWrapper(handler, additionalCheckers, context)
ApplicationManager.getApplication().runReadAction { ApplicationManager.getApplication().runReadAction {
val psiFile = PsiManager.getInstance(project).findFile(vfile) val psiFile = PsiManager.getInstance(project).findFile(vfile)
@@ -55,12 +66,12 @@ object UastChecker {
when (psiFile) { when (psiFile) {
is PsiJavaFile -> { is PsiJavaFile -> {
val ufile = JavaUastLanguagePlugin.converter.convertWithParent(psiFile) val ufile = JavaUastLanguagePlugin.converter.convertWithParent(psiFile)
ufile?.handleTraverse(handler) ufile?.handleTraverse(handlerWrapper)
} }
else -> for (plugin in plugins) { else -> for (plugin in plugins) {
val ufile = plugin.converter.convertWithParent(psiFile) val ufile = plugin.converter.convertWithParent(psiFile)
if (ufile != null) { if (ufile != null) {
ufile.handleTraverse(handler) ufile.handleTraverse(handlerWrapper)
break break
} }
} }
@@ -69,21 +80,27 @@ object UastChecker {
} }
} }
fun check(project: Project, file: File, scanner: UastScanner, plugins: List<UastLanguagePlugin>, context: UastAndroidContext) { private class HandlerWrapper(
val original: UastHandler,
val additionalCheckers: List<UastAdditionalChecker>,
val context: UastAndroidContext
) : UastHandler {
override fun invoke(element: UElement) {
original(element)
for (checker in additionalCheckers) {
checker(element, this, context)
}
}
}
fun check(project: Project, file: File, scanner: UastScanner, context: UastAndroidContext) {
val applicableFunctionNames = scanner.applicableFunctionNames ?: emptyList() val applicableFunctionNames = scanner.applicableFunctionNames ?: emptyList()
val applicableSuperClasses = scanner.applicableSuperClasses ?: emptyList() val applicableSuperClasses = scanner.applicableSuperClasses ?: emptyList()
val applicableConstructorTypes = scanner.applicableConstructorTypes ?: emptyList() val applicableConstructorTypes = scanner.applicableConstructorTypes ?: emptyList()
val appliesToResourcesRefs = scanner.appliesToResourceRefs() val appliesToResourcesRefs = scanner.appliesToResourceRefs()
val additionalCheckers = plugins.fold(mutableListOf<UastAdditionalChecker>()) { list, plugin -> var handler: UastHandler?
for (checker in plugin.additionalCheckers) {
if (checker is AndroidUastAdditionalChecker) list += checker
}
list
}
var handler: UastHandler? = null
handler = UastHandler { element -> handler = UastHandler { element ->
when (element) { when (element) {
is UCallExpression -> { is UCallExpression -> {
@@ -131,13 +148,9 @@ object UastChecker {
} }
} }
} }
for (checker in additionalCheckers) {
checker(element, handler!!, context)
}
} }
check(project, file, plugins, handler) check(project, file, context, handler)
} }
} }