use of com.intellij.dupLocator.iterators.CountingNodeIterator in project intellij-community by JetBrains.
the class DeclarationStatementHandler method match.
@Override
public boolean match(PsiElement patternNode, PsiElement matchedNode, MatchContext context) {
if (patternNode instanceof PsiComment) {
return myCommentHandler.match(patternNode, matchedNode, context);
}
if (!super.match(patternNode, matchedNode, context))
return false;
final PsiDeclarationStatement dcl = (PsiDeclarationStatement) patternNode;
if (matchedNode instanceof PsiDeclarationStatement) {
return context.getMatcher().matchSequentially(new SsrFilteringNodeIterator(patternNode.getFirstChild()), new SsrFilteringNodeIterator(matchedNode.getFirstChild()));
}
final PsiElement[] declared = dcl.getDeclaredElements();
// declaration statement could wrap class or dcl
if (declared.length > 0 && !(matchedNode.getParent() instanceof PsiDeclarationStatement)) /* skip twice matching for child*/
{
if (!(matchedNode instanceof PsiField)) {
return context.getMatcher().matchSequentially(new ArrayBackedNodeIterator(declared), new CountingNodeIterator(declared.length, new SsrFilteringNodeIterator(matchedNode)));
}
// special handling for multiple fields in single declaration
final PsiElement sibling = PsiTreeUtil.skipSiblingsBackward(matchedNode, PsiWhiteSpace.class);
if (PsiUtil.isJavaToken(sibling, JavaTokenType.COMMA)) {
return false;
}
final List<PsiElement> matchNodes = new ArrayList<>();
matchNodes.add(matchedNode);
PsiElement node = matchedNode;
node = PsiTreeUtil.skipSiblingsForward(node, PsiWhiteSpace.class);
while (PsiUtil.isJavaToken(node, JavaTokenType.COMMA)) {
node = PsiTreeUtil.skipSiblingsForward(node, PsiWhiteSpace.class);
if (node instanceof PsiField) {
matchNodes.add(node);
}
node = PsiTreeUtil.skipSiblingsForward(node, PsiWhiteSpace.class);
}
boolean result = context.getMatcher().matchSequentially(new ArrayBackedNodeIterator(declared), new ArrayBackedNodeIterator(matchNodes.toArray(new PsiElement[matchNodes.size()])));
if (result && declared[0] instanceof PsiVariable) {
// we may have comments behind to match!
final PsiElement lastChild = dcl.getLastChild();
if (lastChild instanceof PsiComment) {
final PsiElement[] fieldChildren = matchedNode.getChildren();
result = context.getPattern().getHandler(lastChild).match(lastChild, fieldChildren[fieldChildren.length - 1], context);
}
}
return result;
}
return false;
}
use of com.intellij.dupLocator.iterators.CountingNodeIterator in project intellij-community by JetBrains.
the class SSBasedInspection method buildVisitor.
@NotNull
@Override
public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, final boolean isOnTheFly) {
final Map<Configuration, MatchContext> compiledOptions = SSBasedInspectionCompiledPatternsCache.getCompiledOptions(myConfigurations, holder.getProject());
if (compiledOptions.isEmpty())
return super.buildVisitor(holder, isOnTheFly);
return new PsiElementVisitor() {
final Matcher matcher = new Matcher(holder.getManager().getProject());
final PairProcessor<MatchResult, Configuration> processor = (matchResult, configuration) -> {
PsiElement element = matchResult.getMatch();
String name = configuration.getName();
LocalQuickFix fix = createQuickFix(holder.getManager().getProject(), matchResult, configuration);
holder.registerProblem(holder.getManager().createProblemDescriptor(element, name, fix, ProblemHighlightType.GENERIC_ERROR_OR_WARNING, isOnTheFly));
return true;
};
@Override
public void visitElement(PsiElement element) {
synchronized (LOCK) {
if (LexicalNodesFilter.getInstance().accepts(element))
return;
final SsrFilteringNodeIterator matchedNodes = new SsrFilteringNodeIterator(element);
for (Map.Entry<Configuration, MatchContext> entry : compiledOptions.entrySet()) {
Configuration configuration = entry.getKey();
MatchContext context = entry.getValue();
if (MatcherImpl.checkIfShouldAttemptToMatch(context, matchedNodes)) {
final int nodeCount = context.getPattern().getNodeCount();
try {
matcher.processMatchesInElement(context, configuration, new CountingNodeIterator(nodeCount, matchedNodes), processor);
} catch (StructuralSearchException e) {
if (myProblemsReported.add(configuration.getName())) {
// don't overwhelm the user with messages
Notifications.Bus.notify(new Notification(SSRBundle.message("structural.search.title"), SSRBundle.message("template.problem", configuration.getName()), e.getMessage(), NotificationType.ERROR), element.getProject());
}
}
matchedNodes.reset();
}
}
}
}
};
}
Aggregations