@Override public void checkReplacementPattern(Project project, ReplaceOptions options) { final CompiledPattern compiledPattern = PatternCompiler.compilePattern(project, options.getMatchOptions()); if (compiledPattern == null) { return; } final NodeIterator it = compiledPattern.getNodes(); if (!it.hasNext()) { return; } final PsiElement root = it.current().getParent(); if (!checkOptionalChildren(root) || !checkErrorElements(root)) { throw new UnsupportedPatternException(": Partial and expression patterns are not supported"); } }
private void doVisitElement(PsiElement element) { CompiledPattern pattern = myGlobalVisitor.getContext().getPattern(); if (myGlobalVisitor.getCodeBlockLevel() == 0) { initTopLevelElement(element); return; } if (canBePatternVariable(element) && pattern.isRealTypedVar(element)) { myGlobalVisitor.handle(element); final MatchingHandler handler = pattern.getHandler(element); handler.setFilter( new NodeFilter() { public boolean accepts(PsiElement other) { return canBePatternVariableValue(other); } }); super.visitElement(element); return; } super.visitElement(element); if (myGlobalVisitor.getContext().getSearchHelper().doOptimizing() && element instanceof LeafElement) { ParserDefinition parserDefinition = LanguageParserDefinitions.INSTANCE.forLanguage(element.getLanguage()); if (parserDefinition != null) { String text = element.getText(); // todo: support variables inside comments boolean flag = true; if (StringUtil.isJavaIdentifier(text) && flag) { myGlobalVisitor.processTokenizedName( text, true, GlobalCompilingVisitor.OccurenceKind.CODE); } } } }
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))); } }