@Override public void visitElement(PsiElement element) { super.visitElement(element); final EquivalenceDescriptorProvider descriptorProvider = EquivalenceDescriptorProvider.getInstance(element); if (descriptorProvider != null) { final EquivalenceDescriptor descriptor1 = descriptorProvider.buildDescriptor(element); final EquivalenceDescriptor descriptor2 = descriptorProvider.buildDescriptor(myGlobalVisitor.getElement()); if (descriptor1 != null && descriptor2 != null) { final boolean result = DuplocatorUtil.match( descriptor1, descriptor2, myGlobalVisitor, Collections.<PsiElementRole>emptySet(), null); myGlobalVisitor.setResult(result); return; } } if (isLiteral(element)) { visitLiteral(element); return; } if (canBePatternVariable(element) && myGlobalVisitor.getMatchContext().getPattern().isRealTypedVar(element) && !shouldIgnoreVarNode(element)) { PsiElement matchedElement = myGlobalVisitor.getElement(); PsiElement newElement = SkippingHandler.skipNodeIfNeccessary(matchedElement); while (newElement != matchedElement) { matchedElement = newElement; newElement = SkippingHandler.skipNodeIfNeccessary(matchedElement); } myGlobalVisitor.setResult(myGlobalVisitor.handleTypedElement(element, matchedElement)); } else if (element instanceof LeafElement) { myGlobalVisitor.setResult(element.getText().equals(myGlobalVisitor.getElement().getText())); } else if (element.getFirstChild() == null && element.getTextLength() == 0) { myGlobalVisitor.setResult(true); } else { PsiElement patternChild = element.getFirstChild(); PsiElement matchedChild = myGlobalVisitor.getElement().getFirstChild(); FilteringNodeIterator patternIterator = new SsrFilteringNodeIterator(patternChild); FilteringNodeIterator matchedIterator = new SsrFilteringNodeIterator(matchedChild); boolean matched = myGlobalVisitor.matchSequentially(patternIterator, matchedIterator); myGlobalVisitor.setResult(matched); } }
private void initTopLevelElement(PsiElement element) { CompiledPattern pattern = myGlobalVisitor.getContext().getPattern(); PsiElement newElement = SkippingHandler.skipNodeIfNeccessary(element); if (element != newElement && newElement != null) { // way to support partial matching (ex. if ($condition$) ) newElement.accept(this); pattern.setHandler(element, new LightTopLevelMatchingHandler(pattern.getHandler(element))); } else { myGlobalVisitor.setCodeBlockLevel(myGlobalVisitor.getCodeBlockLevel() + 1); for (PsiElement el = element.getFirstChild(); el != null; el = el.getNextSibling()) { if (GlobalCompilingVisitor.getFilter().accepts(el)) { if (el instanceof PsiWhiteSpace) { myGlobalVisitor.addLexicalNode(el); } } else { el.accept(this); MatchingHandler matchingHandler = pattern.getHandler(el); pattern.setHandler( el, element == myTopElement ? new TopLevelMatchingHandler(matchingHandler) : new LightTopLevelMatchingHandler(matchingHandler)); /* do not assign light-top-level handlers through skipping, because it is incorrect; src: if (...) { st1; st2; } pattern: if (...) {$a$;} $a$ will have top-level handler, so matching will be considered as correct, although "st2;" is left! */ } } myGlobalVisitor.setCodeBlockLevel(myGlobalVisitor.getCodeBlockLevel() - 1); pattern.setHandler(element, new TopLevelMatchingHandler(pattern.getHandler(element))); } }