mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
SSR: scope matching for xml/html (IDEA-190055)
This commit is contained in:
+11
-5
@@ -51,6 +51,12 @@ public class XmlStructuralSearchProfile extends StructuralSearchProfile {
|
||||
return element instanceof XmlToken && ((XmlToken)element).getTokenType() == XmlTokenType.XML_NAME;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getTypedVarString(PsiElement element) {
|
||||
return element instanceof XmlText ? element.getText().trim() : super.getTypedVarString(element);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public NodeFilter getLexicalNodesFilter() {
|
||||
@@ -85,8 +91,8 @@ public class XmlStructuralSearchProfile extends StructuralSearchProfile {
|
||||
boolean physical) {
|
||||
final String ext = extension != null ? extension : fileType.getDefaultExtension();
|
||||
String text1 = context == PatternTreeContext.File ? text : "<QQQ>" + text + "</QQQ>";
|
||||
final PsiFile fileFromText = PsiFileFactory.getInstance(project)
|
||||
.createFileFromText("dummy." + ext, fileType, text1, LocalTimeCounter.currentTime(), physical, true);
|
||||
final PsiFile fileFromText =
|
||||
PsiFileFactory.getInstance(project).createFileFromText("dummy." + ext, fileType, text1, LocalTimeCounter.currentTime(), physical, true);
|
||||
|
||||
final XmlDocument document = HtmlUtil.getRealXmlDocument(((XmlFile)fileFromText).getDocument());
|
||||
if (context == PatternTreeContext.File) {
|
||||
@@ -147,13 +153,13 @@ public class XmlStructuralSearchProfile extends StructuralSearchProfile {
|
||||
|
||||
@Override
|
||||
public StructuralReplaceHandler getReplaceHandler(@NotNull ReplacementContext context) {
|
||||
return new MyReplaceHandler(context);
|
||||
return new XmlReplaceHandler(context);
|
||||
}
|
||||
|
||||
private static class MyReplaceHandler extends StructuralReplaceHandler {
|
||||
private static class XmlReplaceHandler extends StructuralReplaceHandler {
|
||||
private final ReplacementContext myContext;
|
||||
|
||||
MyReplaceHandler(ReplacementContext context) {
|
||||
XmlReplaceHandler(ReplacementContext context) {
|
||||
myContext = context;
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -1,3 +1,4 @@
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.structuralsearch.impl.matcher;
|
||||
|
||||
import com.intellij.structuralsearch.impl.matcher.strategies.XmlMatchingStrategy;
|
||||
@@ -17,6 +18,6 @@ public class XmlCompiledPattern extends CompiledPattern {
|
||||
}
|
||||
|
||||
public boolean isTypedVar(final String str) {
|
||||
return str.startsWith(XML_TYPED_VAR_PREFIX);
|
||||
return str.trim().startsWith(XML_TYPED_VAR_PREFIX);
|
||||
}
|
||||
}
|
||||
|
||||
+16
-16
@@ -8,6 +8,7 @@ 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;
|
||||
import com.intellij.xml.util.XmlUtil;
|
||||
|
||||
/**
|
||||
* @author Eugene.Kudelevsky
|
||||
@@ -21,16 +22,15 @@ public class XmlMatchingVisitor extends XmlElementVisitor {
|
||||
|
||||
@Override public void visitXmlAttribute(XmlAttribute attribute) {
|
||||
final XmlAttribute another = (XmlAttribute)myMatchingVisitor.getElement();
|
||||
final boolean isTypedVar = myMatchingVisitor.getMatchContext().getPattern().isTypedVar(attribute.getName());
|
||||
|
||||
if (!myMatchingVisitor.setResult(isTypedVar || myMatchingVisitor.matchText(attribute.getName(), another.getName()))) return;
|
||||
final XmlAttributeValue valueElement = attribute.getValueElement();
|
||||
if (valueElement != null && !myMatchingVisitor.setResult(myMatchingVisitor.match(valueElement, another.getValueElement()))) return;
|
||||
|
||||
if (isTypedVar) {
|
||||
final SubstitutionHandler handler =
|
||||
(SubstitutionHandler)myMatchingVisitor.getMatchContext().getPattern().getHandler(attribute.getName());
|
||||
myMatchingVisitor.setResult(handler.handle(another, myMatchingVisitor.getMatchContext()));
|
||||
myMatchingVisitor.getMatchContext().pushResult();
|
||||
final XmlElement name = attribute.getNameElement();
|
||||
final boolean isTypedVar = myMatchingVisitor.getMatchContext().getPattern().isTypedVar(name);
|
||||
try {
|
||||
if (!myMatchingVisitor.setResult(isTypedVar || myMatchingVisitor.matchText(name, another.getNameElement()))) return;
|
||||
final XmlAttributeValue valueElement = attribute.getValueElement();
|
||||
myMatchingVisitor.setResult(valueElement == null || myMatchingVisitor.matchSingle(valueElement, another.getValueElement()));
|
||||
} finally {
|
||||
myMatchingVisitor.scopeMatch(name, isTypedVar, another);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,7 +50,9 @@ public class XmlMatchingVisitor extends XmlElementVisitor {
|
||||
|
||||
@Override public void visitXmlTag(XmlTag tag) {
|
||||
final XmlTag another = (XmlTag)myMatchingVisitor.getElement();
|
||||
final boolean isTypedVar = myMatchingVisitor.getMatchContext().getPattern().isTypedVar(tag.getName());
|
||||
final CompiledPattern pattern = myMatchingVisitor.getMatchContext().getPattern();
|
||||
final XmlToken name = XmlUtil.getTokenOfType(tag, XmlTokenType.XML_NAME);
|
||||
final boolean isTypedVar = pattern.isTypedVar(name);
|
||||
|
||||
if (!myMatchingVisitor.setResult((isTypedVar || myMatchingVisitor.matchText(tag.getName(), another.getName())) &&
|
||||
myMatchingVisitor.matchInAnyOrder(tag.getAttributes(), another.getAttributes()))) return;
|
||||
@@ -63,11 +65,9 @@ public class XmlMatchingVisitor extends XmlElementVisitor {
|
||||
}
|
||||
|
||||
if (isTypedVar) {
|
||||
final PsiElement[] children = another.getChildren();
|
||||
if (children.length > 1) {
|
||||
final SubstitutionHandler handler = (SubstitutionHandler)myMatchingVisitor.getMatchContext().getPattern().getHandler(tag.getName());
|
||||
myMatchingVisitor.setResult(handler.handle(children[1], myMatchingVisitor.getMatchContext()));
|
||||
}
|
||||
final SubstitutionHandler handler = (SubstitutionHandler)pattern.getHandler(name);
|
||||
myMatchingVisitor.setResult(handler.handle(XmlUtil.getTokenOfType(another, XmlTokenType.XML_NAME),
|
||||
myMatchingVisitor.getMatchContext()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+7
-7
@@ -1,13 +1,10 @@
|
||||
// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.structuralsearch.impl.matcher.compiler;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.XmlRecursiveElementVisitor;
|
||||
import com.intellij.psi.XmlRecursiveElementWalkingVisitor;
|
||||
import com.intellij.psi.xml.XmlAttribute;
|
||||
import com.intellij.psi.xml.XmlTag;
|
||||
import com.intellij.psi.xml.XmlText;
|
||||
import com.intellij.psi.xml.XmlToken;
|
||||
import com.intellij.psi.xml.*;
|
||||
import com.intellij.structuralsearch.impl.matcher.CompiledPattern;
|
||||
import com.intellij.structuralsearch.impl.matcher.filters.TagValueFilter;
|
||||
import com.intellij.structuralsearch.impl.matcher.handlers.TopLevelMatchingHandler;
|
||||
@@ -59,13 +56,16 @@ public class XmlCompilingVisitor extends XmlRecursiveElementVisitor {
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void visitElement(PsiElement element) {
|
||||
@Override
|
||||
public void visitElement(PsiElement element) {
|
||||
myCompilingVisitor.handle(element);
|
||||
super.visitElement(element);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitXmlToken(XmlToken token) {}
|
||||
public void visitXmlToken(XmlToken token) {
|
||||
if (token.getTokenType() == XmlTokenType.XML_NAME) super.visitXmlToken(token);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitXmlText(XmlText text) {
|
||||
|
||||
+14
-6
@@ -39,6 +39,14 @@ public class XmlStructuralSearchTest extends StructuralSearchTestCase {
|
||||
|
||||
String in = "<img src=\"foobar.jpg\" alt=\"alt\" width=\"108\" height=\"71\" style=\"display:block\" >";
|
||||
assertEquals(1, findMatchesCount(in, "<img alt '_other+ >", StdFileTypes.HTML));
|
||||
assertEquals(1, findMatchesCount(in, "<img '_alt:alt = \"'_value\" '_other+ >", StdFileTypes.HTML));
|
||||
assertEquals(1, findMatchesCount(in, "<img '_name{2,100} = '_value >", StdFileTypes.HTML));
|
||||
|
||||
String in2 = "<input readonly>" +
|
||||
"<input readonly>" +
|
||||
"<input type=button>";
|
||||
assertEquals("should find tags without any attributes without value", 1, findMatchesCount(in2, "<input '_name{0,0} = '_value{0,0} >", StdFileTypes.HTML));
|
||||
assertEquals("should find tags with any attributes without value", 2, findMatchesCount(in2, "<input '_name{1,1}='_value{0,0} >", StdFileTypes.HTML));
|
||||
}
|
||||
|
||||
public void testHtmlSearchCaseInsensitive() {
|
||||
@@ -161,10 +169,10 @@ public class XmlStructuralSearchTest extends StructuralSearchTestCase {
|
||||
return PlatformTestUtil.getCommunityPath() + "/platform/structuralsearch/testData/html/";
|
||||
}
|
||||
|
||||
//public void testXmlSearch2() {
|
||||
// String s1 = "<body><p class=\"11\"> AAA </p><p class=\"22\"></p> <p> ZZZ </p> <p/> <p/> <p/> </body>";
|
||||
// String s2 = "<p '_a?=\"'_t:[ regex( 11 ) ]\"> 'content? </p>";
|
||||
//
|
||||
// assertEquals(5,findMatchesCount(s1,s2,false,StdFileTypes.XML));
|
||||
//}
|
||||
public void testXmlSearch2() {
|
||||
String s1 = "<body><p class=\"11\"> AAA </p><p class=\"22\"></p> <p> ZZZ </p> <p/> <p/> <p/> </body>";
|
||||
String s2 = "<p '_a{0,0}=\"'_t:[ regex( 11 ) ]\"> 'content? </p>";
|
||||
|
||||
assertEquals(5, findMatchesCount(s1, s2, StdFileTypes.XML));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user