use of com.intellij.structuralsearch.impl.matcher.CompiledPattern in project intellij-community by JetBrains.
the class MatchingHandler method matchInAnyOrder.
public boolean matchInAnyOrder(NodeIterator patternNodes, NodeIterator matchedNodes, final MatchContext context) {
final MatchResultImpl saveResult = context.hasResult() ? context.getResult() : null;
context.setResult(null);
try {
if (patternNodes.hasNext() && !matchedNodes.hasNext()) {
return validateSatisfactionOfHandlers(patternNodes, context);
}
Set<PsiElement> matchedElements = null;
for (; patternNodes.hasNext(); patternNodes.advance()) {
final PsiElement patternNode = patternNodes.current();
final CompiledPattern pattern = context.getPattern();
final MatchingHandler handler = pattern.getHandler(patternNode);
final PsiElement startMatching = matchedNodes.current();
do {
final PsiElement element = handler.getPinnedNode(null);
final PsiElement matchedNode = element != null ? element : matchedNodes.current();
if (element == null)
matchedNodes.advance();
if (!matchedNodes.hasNext())
matchedNodes.reset();
if (matchedElements == null || !matchedElements.contains(matchedNode)) {
if (handler.match(patternNode, matchedNode, context)) {
if (matchedElements == null)
matchedElements = new HashSet<>();
matchedElements.add(matchedNode);
if (handler.shouldAdvanceThePatternFor(patternNode, matchedNode)) {
break;
}
} else if (element != null) {
return false;
}
// clear state of dependent objects
clearingVisitor.clearState(pattern, patternNode);
}
// passed of elements and does not found the match
if (startMatching == matchedNodes.current()) {
final boolean result = validateSatisfactionOfHandlers(patternNodes, context);
if (result && context.getMatchedElementsListener() != null) {
context.getMatchedElementsListener().matchedElements(matchedElements);
}
return result;
}
} while (true);
if (!handler.shouldAdvanceThePatternFor(patternNode, null)) {
patternNodes.rewind();
}
}
final boolean result = validateSatisfactionOfHandlers(patternNodes, context);
if (result && context.getMatchedElementsListener() != null) {
context.getMatchedElementsListener().matchedElements(matchedElements);
}
return result;
} finally {
if (saveResult != null) {
if (context.hasResult()) {
saveResult.getMatches().addAll(context.getResult().getMatches());
}
context.setResult(saveResult);
}
}
}
use of com.intellij.structuralsearch.impl.matcher.CompiledPattern in project intellij-community by JetBrains.
the class SubstitutionHandler method matchInAnyOrder.
public boolean matchInAnyOrder(NodeIterator patternNodes, NodeIterator matchedNodes, final MatchContext context) {
final MatchResultImpl saveResult = context.hasResult() ? context.getResult() : null;
context.setResult(null);
try {
if (patternNodes.hasNext() && !matchedNodes.hasNext()) {
return validateSatisfactionOfHandlers(patternNodes, context);
}
Set<PsiElement> matchedElements = null;
for (; patternNodes.hasNext(); patternNodes.advance()) {
int matchedOccurs = 0;
final PsiElement patternNode = patternNodes.current();
final CompiledPattern pattern = context.getPattern();
final MatchingHandler handler = pattern.getHandler(patternNode);
final PsiElement startMatching = matchedNodes.current();
do {
final PsiElement element = handler.getPinnedNode(null);
final PsiElement matchedNode = (element != null) ? element : matchedNodes.current();
if (element == null)
matchedNodes.advance();
if (!matchedNodes.hasNext())
matchedNodes.reset();
if (matchedOccurs <= maxOccurs && (matchedElements == null || !matchedElements.contains(matchedNode))) {
if (handler.match(patternNode, matchedNode, context)) {
++matchedOccurs;
if (matchedElements == null)
matchedElements = new HashSet<>();
matchedElements.add(matchedNode);
if (handler.shouldAdvanceThePatternFor(patternNode, matchedNode)) {
break;
}
} else if (element != null) {
return false;
}
// clear state of dependent objects
clearingVisitor.clearState(pattern, patternNode);
}
// passed of elements and does not found the match
if (startMatching == matchedNodes.current()) {
final boolean result = validateSatisfactionOfHandlers(patternNodes, context) && matchedOccurs >= minOccurs && matchedOccurs <= maxOccurs;
if (result && context.getMatchedElementsListener() != null) {
context.getMatchedElementsListener().matchedElements(matchedElements);
}
return result;
}
} while (true);
if (!handler.shouldAdvanceThePatternFor(patternNode, null)) {
patternNodes.rewind();
}
}
final boolean result = validateSatisfactionOfHandlers(patternNodes, context);
if (result && context.getMatchedElementsListener() != null) {
context.getMatchedElementsListener().matchedElements(matchedElements);
}
return result;
} finally {
if (saveResult != null) {
if (context.hasResult()) {
saveResult.getMatches().addAll(context.getResult().getMatches());
}
context.setResult(saveResult);
}
}
}
use of com.intellij.structuralsearch.impl.matcher.CompiledPattern in project intellij-community by JetBrains.
the class StructuralSearchProfileBase method checkReplacementPattern.
@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");
}
}
use of com.intellij.structuralsearch.impl.matcher.CompiledPattern in project intellij-community by JetBrains.
the class XmlCompilingVisitor method visitXmlTag.
@Override
public void visitXmlTag(XmlTag xmlTag) {
myCompilingVisitor.setCodeBlockLevel(myCompilingVisitor.getCodeBlockLevel() + 1);
super.visitXmlTag(xmlTag);
myCompilingVisitor.setCodeBlockLevel(myCompilingVisitor.getCodeBlockLevel() - 1);
if (myCompilingVisitor.getCodeBlockLevel() == 1) {
final CompiledPattern pattern = myCompilingVisitor.getContext().getPattern();
pattern.setStrategy(XmlMatchingStrategy.getInstance());
pattern.setHandler(xmlTag, new TopLevelMatchingHandler(pattern.getHandler(xmlTag)));
}
}
use of com.intellij.structuralsearch.impl.matcher.CompiledPattern in project intellij-community by JetBrains.
the class StructuralSearchProfileBase method compile.
@Override
public void compile(PsiElement[] elements, @NotNull final GlobalCompilingVisitor globalVisitor) {
final PsiElement topElement = elements[0].getParent();
final PsiElement element = elements.length > 1 ? topElement : elements[0];
element.accept(new MyCompilingVisitor(globalVisitor, topElement));
element.accept(new PsiRecursiveElementVisitor() {
@Override
public void visitElement(PsiElement element) {
super.visitElement(element);
if (DuplocatorUtil.isIgnoredNode(element)) {
return;
}
CompiledPattern pattern = globalVisitor.getContext().getPattern();
MatchingHandler handler = pattern.getHandler(element);
if (!(handler instanceof SubstitutionHandler) && !(handler instanceof TopLevelMatchingHandler) && !(handler instanceof LightTopLevelMatchingHandler)) {
pattern.setHandler(element, new SkippingHandler(handler));
}
/*
place skipping handler under top-level handler, because when we skip top-level node we can get non top-level handler, so
depth matching won't be done!;
*/
if (handler instanceof LightTopLevelMatchingHandler) {
MatchingHandler delegate = ((LightTopLevelMatchingHandler) handler).getDelegate();
if (!(delegate instanceof SubstitutionHandler)) {
pattern.setHandler(element, new LightTopLevelMatchingHandler(new SkippingHandler(delegate)));
}
}
}
});
final Language baseLanguage = element.getContainingFile().getLanguage();
// todo: try to optimize it: too heavy strategy!
globalVisitor.getContext().getPattern().setStrategy(new MatchingStrategy() {
@Override
public boolean continueMatching(PsiElement start) {
Language language = start.getLanguage();
PsiFile file = start.getContainingFile();
if (file != null) {
Language fileLanguage = file.getLanguage();
if (fileLanguage.isKindOf(language)) {
// dialect
language = fileLanguage;
}
}
return language == baseLanguage;
}
@Override
public boolean shouldSkip(PsiElement element, PsiElement elementToMatchWith) {
return DuplocatorUtil.shouldSkip(element, elementToMatchWith);
}
});
}
Aggregations