mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
SSR: more robust xml/html matching when only whitespace is different
This commit is contained in:
+7
-1
@@ -65,7 +65,13 @@ public class XmlStructuralSearchProfile extends StructuralSearchProfile {
|
||||
@NotNull
|
||||
@Override
|
||||
public NodeFilter getLexicalNodesFilter() {
|
||||
return element -> element instanceof PsiWhiteSpace || element instanceof PsiErrorElement;
|
||||
return element -> {
|
||||
if (element instanceof XmlText) {
|
||||
final PsiElement child = element.getFirstChild();
|
||||
return child == element.getLastChild() && child instanceof PsiWhiteSpace;
|
||||
}
|
||||
return element instanceof PsiWhiteSpace || element instanceof PsiErrorElement;
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+39
-53
@@ -1,16 +1,26 @@
|
||||
/*
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.structuralsearch.impl.matcher;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiWhiteSpace;
|
||||
import com.intellij.psi.XmlElementVisitor;
|
||||
import com.intellij.psi.util.PsiUtilCore;
|
||||
import com.intellij.psi.xml.*;
|
||||
import com.intellij.structuralsearch.impl.matcher.handlers.MatchingHandler;
|
||||
import com.intellij.structuralsearch.impl.matcher.handlers.SubstitutionHandler;
|
||||
import com.intellij.dupLocator.iterators.ArrayBackedNodeIterator;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.XmlElementVisitor;
|
||||
import com.intellij.psi.xml.*;
|
||||
import com.intellij.structuralsearch.impl.matcher.handlers.SubstitutionHandler;
|
||||
import com.intellij.structuralsearch.impl.matcher.iterators.SsrFilteringNodeIterator;
|
||||
|
||||
/**
|
||||
* @author Eugene.Kudelevsky
|
||||
@@ -40,8 +50,9 @@ public class XmlMatchingVisitor extends XmlElementVisitor {
|
||||
}
|
||||
|
||||
if (myMatchingVisitor.getResult() && isTypedVar) {
|
||||
MatchingHandler handler = myMatchingVisitor.getMatchContext().getPattern().getHandler(attribute.getName());
|
||||
myMatchingVisitor.setResult(((SubstitutionHandler)handler).handle(another, myMatchingVisitor.getMatchContext()));
|
||||
final SubstitutionHandler handler =
|
||||
(SubstitutionHandler)myMatchingVisitor.getMatchContext().getPattern().getHandler(attribute.getName());
|
||||
myMatchingVisitor.setResult(handler.handle(another, myMatchingVisitor.getMatchContext()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,14 +60,11 @@ public class XmlMatchingVisitor extends XmlElementVisitor {
|
||||
final XmlAttributeValue another = (XmlAttributeValue)myMatchingVisitor.getElement();
|
||||
final String text = value.getValue();
|
||||
|
||||
final boolean isTypedVar = myMatchingVisitor.getMatchContext().getPattern().isTypedVar(text);
|
||||
MatchingHandler handler;
|
||||
|
||||
if (isTypedVar && (handler = myMatchingVisitor.getMatchContext().getPattern().getHandler( text )) instanceof SubstitutionHandler) {
|
||||
String text2 = another.getText();
|
||||
int offset = text2.length() > 0 && ( text2.charAt(0) == '"' || text2.charAt(0) == '\'') ? 1:0;
|
||||
myMatchingVisitor.setResult(((SubstitutionHandler)handler).handle(another, offset, text2.length() - offset,
|
||||
myMatchingVisitor.getMatchContext()));
|
||||
if (myMatchingVisitor.getMatchContext().getPattern().isTypedVar(text)) {
|
||||
final SubstitutionHandler handler = (SubstitutionHandler)myMatchingVisitor.getMatchContext().getPattern().getHandler(text);
|
||||
final String text2 = another.getText();
|
||||
final int offset = text2.length() > 0 && (text2.charAt(0) == '"' || text2.charAt(0) == '\'') ? 1 : 0;
|
||||
myMatchingVisitor.setResult(handler.handle(another, offset, text2.length() - offset, myMatchingVisitor.getMatchContext()));
|
||||
} else {
|
||||
myMatchingVisitor.setResult(matches(text, another.getValue()));
|
||||
}
|
||||
@@ -70,55 +78,33 @@ public class XmlMatchingVisitor extends XmlElementVisitor {
|
||||
myMatchingVisitor.matchInAnyOrder(tag.getAttributes(), another.getAttributes()));
|
||||
|
||||
if(myMatchingVisitor.getResult()) {
|
||||
final XmlTagChild[] contentChildren = tag.getValue().getChildren();
|
||||
final XmlTagChild[] children = tag.getValue().getChildren();
|
||||
|
||||
if (contentChildren.length > 0) {
|
||||
PsiElement[] patternNodes = contentChildren;
|
||||
PsiElement[] matchedNodes = another.getValue().getChildren();
|
||||
|
||||
if (contentChildren.length != 1) {
|
||||
patternNodes = filterOutWhitespace(patternNodes);
|
||||
matchedNodes = filterOutWhitespace(matchedNodes);
|
||||
}
|
||||
|
||||
final boolean result = myMatchingVisitor.matchSequentially(
|
||||
new ArrayBackedNodeIterator(patternNodes),
|
||||
new ArrayBackedNodeIterator(matchedNodes)
|
||||
);
|
||||
myMatchingVisitor.setResult(result);
|
||||
final SsrFilteringNodeIterator patternNodes = new SsrFilteringNodeIterator(new ArrayBackedNodeIterator(children));
|
||||
if (patternNodes.current() != null) {
|
||||
final SsrFilteringNodeIterator matchNodes =
|
||||
new SsrFilteringNodeIterator(new ArrayBackedNodeIterator(another.getValue().getChildren()));
|
||||
myMatchingVisitor.setResult(myMatchingVisitor.matchSequentially(patternNodes, matchNodes));
|
||||
}
|
||||
}
|
||||
|
||||
if (myMatchingVisitor.getResult() && isTypedVar) {
|
||||
final PsiElement[] children = another.getChildren();
|
||||
if (children.length > 1) {
|
||||
MatchingHandler handler = myMatchingVisitor.getMatchContext().getPattern().getHandler( tag.getName() );
|
||||
myMatchingVisitor.setResult(((SubstitutionHandler)handler).handle(children[1], myMatchingVisitor.getMatchContext()));
|
||||
final SubstitutionHandler handler = (SubstitutionHandler)myMatchingVisitor.getMatchContext().getPattern().getHandler(tag.getName());
|
||||
myMatchingVisitor.setResult(handler.handle(children[1], myMatchingVisitor.getMatchContext()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static PsiElement[] filterOutWhitespace(PsiElement[] children) {
|
||||
final List<PsiElement> result = new ArrayList<>(children.length);
|
||||
for(PsiElement child : children) {
|
||||
if (child instanceof XmlText) {
|
||||
final PsiElement[] grandChildren = child.getChildren();
|
||||
if (grandChildren.length == 1 && grandChildren[0] instanceof PsiWhiteSpace) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
result.add(child);
|
||||
}
|
||||
return PsiUtilCore.toPsiElementArray(result);
|
||||
}
|
||||
|
||||
@Override public void visitXmlText(XmlText text) {
|
||||
final boolean isTypedVar = myMatchingVisitor.getMatchContext().getPattern().isTypedVar(text);
|
||||
final PsiElement element = myMatchingVisitor.getElement();
|
||||
if (isTypedVar) {
|
||||
myMatchingVisitor.setResult(myMatchingVisitor.handleTypedElement(text, element));
|
||||
} else {
|
||||
myMatchingVisitor.setResult(matches(text.getText(), element.getText()));
|
||||
}
|
||||
else {
|
||||
myMatchingVisitor.setResult(element instanceof XmlText && matches(text.getText().trim(), element.getText().trim()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user