IDEA-CR-41633: [uast] UastHintedVisitorAdapter as a more performant version of UastVisitorAdapter

(cherry picked from commit 08572d72766b9a557aa360832e5300b7c77ea215)
This commit is contained in:
Nicolay Mitropolsky
2018-12-24 19:18:43 +03:00
committed by Nicolay Mitropolsky
parent 437eb026dd
commit 5c90b501e1
5 changed files with 72 additions and 13 deletions

View File

@@ -5,21 +5,31 @@ import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.Conditions;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.uast.UastVisitorAdapter;
import com.intellij.uast.UastHintedVisitorAdapter;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.uast.UClass;
import org.jetbrains.uast.UField;
import org.jetbrains.uast.UFile;
import org.jetbrains.uast.UMethod;
import org.jetbrains.uast.*;
import org.jetbrains.uast.visitor.AbstractUastNonRecursiveVisitor;
import java.util.Arrays;
import java.util.List;
public abstract class AbstractBaseUastLocalInspectionTool extends LocalInspectionTool {
private static final Condition<PsiElement> PROBLEM_ELEMENT_CONDITION =
Conditions.and(Conditions.instanceOf(PsiFile.class, PsiClass.class, PsiMethod.class, PsiField.class),
Conditions.notInstanceOf(PsiTypeParameter.class));
private final List<Class<? extends UElement>> myUElementsTypesHint;
protected AbstractBaseUastLocalInspectionTool() {
myUElementsTypesHint = Arrays.asList(UFile.class, UClass.class, UMethod.class, UField.class);
}
protected AbstractBaseUastLocalInspectionTool(Class<? extends UElement>... uElementsTypesHint) {
myUElementsTypesHint = Arrays.asList(uElementsTypesHint);
}
/**
* Override this to report problems at method level.
*
@@ -62,7 +72,7 @@ public abstract class AbstractBaseUastLocalInspectionTool extends LocalInspectio
@Override
@NotNull
public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, final boolean isOnTheFly) {
return new UastVisitorAdapter(new AbstractUastNonRecursiveVisitor() {
return UastHintedVisitorAdapter.create(holder.getFile().getLanguage(), new AbstractUastNonRecursiveVisitor() {
@Override
public boolean visitClass(@NotNull UClass node) {
addDescriptors(checkClass(node, holder.getManager(), isOnTheFly));
@@ -94,7 +104,7 @@ public abstract class AbstractBaseUastLocalInspectionTool extends LocalInspectio
}
}
}
}, true);
}, myUElementsTypesHint);
}
@Override

View File

@@ -0,0 +1,38 @@
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.uast
import com.intellij.lang.Language
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiElementVisitor
import org.jetbrains.uast.UElement
import org.jetbrains.uast.UastLanguagePlugin
import org.jetbrains.uast.visitor.AbstractUastNonRecursiveVisitor
open class UastHintedVisitorAdapter(private val plugin: UastLanguagePlugin,
private val visitor: AbstractUastNonRecursiveVisitor,
private val directOnly: Boolean,
private val uElementTypesHint: List<Class<out UElement>>
) : PsiElementVisitor() {
override fun visitElement(element: PsiElement) {
super.visitElement(element)
val uElement = plugin.convertElementWithParent(element, uElementTypesHint) ?: return
if (directOnly && uElement.sourcePsi !== element) return
uElement.accept(visitor)
}
companion object {
@JvmStatic
@JvmOverloads
fun create(language: Language,
visitor: AbstractUastNonRecursiveVisitor,
uElementTypesHint: List<Class<out UElement>>,
directOnly: Boolean = true): PsiElementVisitor {
val uastLanguagePlugin = UastLanguagePlugin.byLanguage(language) ?: return EMPTY_VISITOR
return UastHintedVisitorAdapter(uastLanguagePlugin, visitor, directOnly, uElementTypesHint)
}
}
}