mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
SSR: implement explicit support for repeated variables (IDEA-195166)
This commit is contained in:
+12
-1
@@ -56,7 +56,18 @@ public class MatchContext {
|
||||
}
|
||||
|
||||
public MatchResultImpl getPreviousResult() {
|
||||
return previousResults.isEmpty() ? null : previousResults.peek();
|
||||
if (previousResults.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
int index = previousResults.size() - 1;
|
||||
MatchResultImpl result = previousResults.get(index); // may contain nulls
|
||||
while (result == null && index > 0) {
|
||||
index--;
|
||||
result = previousResults.get(index);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
public MatchResultImpl getResult() {
|
||||
|
||||
+13
@@ -136,6 +136,19 @@ public final class MatchResultImpl extends MatchResult {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static MatchResultImpl findChildDeep(MatchResult match , String name) {
|
||||
for (MatchResult child : match.getChildren()) {
|
||||
if (name.equals(child.getName())) {
|
||||
return (MatchResultImpl)child;
|
||||
}
|
||||
final MatchResultImpl deep = findChildDeep(child, name);
|
||||
if (deep != null) {
|
||||
return deep;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public MatchResult removeChild(String typedVar) {
|
||||
// @todo this could be performance bottleneck, replace with hash lookup!
|
||||
for (int i = 0, size = myChildren.size(); i < size; i++) {
|
||||
|
||||
+7
-3
@@ -424,7 +424,6 @@ public class PatternCompiler {
|
||||
final int segmentsCount = template.getSegmentsCount();
|
||||
final String text = template.getTemplateText();
|
||||
int prevOffset = 0;
|
||||
final Set<String> seen = ContainerUtil.newTroveSet();
|
||||
final Set<String> variableNames = ContainerUtil.newTroveSet();
|
||||
|
||||
for(int i = 0; i < segmentsCount; i++) {
|
||||
@@ -439,8 +438,12 @@ public class PatternCompiler {
|
||||
final String compiledName = prefix + name;
|
||||
buf.append(text, prevOffset, offset).append(compiledName);
|
||||
|
||||
variableNames.add(name);
|
||||
if (seen.add(compiledName)) {
|
||||
final boolean repeated = !variableNames.add(name);
|
||||
final SubstitutionHandler existing = (SubstitutionHandler)result.getHandler(compiledName);
|
||||
if (existing != null) {
|
||||
existing.setRepeatedVar(repeated);
|
||||
}
|
||||
else {
|
||||
// the same variable can occur multiple times in a single template
|
||||
// no need to process it more than once
|
||||
|
||||
@@ -460,6 +463,7 @@ public class PatternCompiler {
|
||||
constraint.getMaxCount(),
|
||||
constraint.isGreedy()
|
||||
);
|
||||
handler.setRepeatedVar(repeated);
|
||||
|
||||
if (constraint.isWithinHierarchy()) {
|
||||
handler.setSubtype(true);
|
||||
|
||||
+14
-3
@@ -39,6 +39,7 @@ public class SubstitutionHandler extends MatchingHandler {
|
||||
private int matchedOccurs;
|
||||
private int totalMatchedOccurs = -1;
|
||||
private MatchResultImpl myNestedResult;
|
||||
private boolean myRepeatedVar = false;
|
||||
|
||||
private static final NodeFilter VARS_DELIM_FILTER = new NodeFilter() {
|
||||
@Override
|
||||
@@ -95,6 +96,10 @@ public class SubstitutionHandler extends MatchingHandler {
|
||||
return findRegExpPredicate(getPredicate());
|
||||
}
|
||||
|
||||
public void setRepeatedVar(boolean repeatedVar) {
|
||||
myRepeatedVar = repeatedVar;
|
||||
}
|
||||
|
||||
private static RegExpPredicate findRegExpPredicate(MatchPredicate start) {
|
||||
if (start==null) return null;
|
||||
if (start instanceof RegExpPredicate) return (RegExpPredicate)start;
|
||||
@@ -111,7 +116,10 @@ public class SubstitutionHandler extends MatchingHandler {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static boolean validateOneMatch(final PsiElement match, int start, int end, final MatchResult result, final MatchContext matchContext) {
|
||||
private boolean validateOneMatch(final PsiElement match, int start, int end, final MatchResult result, final MatchContext matchContext) {
|
||||
if (!myRepeatedVar) {
|
||||
return true;
|
||||
}
|
||||
if (match != null) {
|
||||
if (start == 0 && end == -1 && result.getStart() == 0 && result.getEnd() == -1) {
|
||||
return matchContext.getMatcher().match(match, result.getMatch());
|
||||
@@ -134,8 +142,11 @@ public class SubstitutionHandler extends MatchingHandler {
|
||||
|
||||
MatchResult result = context.hasResult() ? context.getResult().findChild(name) : null;
|
||||
|
||||
if (result == null && context.getPreviousResult() != null) {
|
||||
result = context.getPreviousResult().findChild(name);
|
||||
if (result == null) {
|
||||
final MatchResultImpl previous = context.getPreviousResult();
|
||||
if (previous != null) {
|
||||
result = MatchResultImpl.findChildDeep(previous, name);
|
||||
}
|
||||
}
|
||||
|
||||
if (result != null) {
|
||||
|
||||
+24
@@ -3092,4 +3092,28 @@ public class StructuralSearchTest extends StructuralSearchTestCase {
|
||||
assertEquals("should find defaults", 3, findMatchesCount(in, "default:"));
|
||||
assertEquals("should find cases", 8, findMatchesCount(in, "case '_a :"));
|
||||
}
|
||||
|
||||
public void testRepeatedVars() {
|
||||
String in = "class SomePageObject {\n" +
|
||||
" @FindBy(name = \"first-name\")\n" +
|
||||
" private WebElement name;\n" +
|
||||
"\n" +
|
||||
" @FindBy(name = \"first-name\")\n" +
|
||||
" private WebElement firstName;\n" +
|
||||
"}" +
|
||||
"class SomePageObject2 {\n" +
|
||||
" @FindBy(name = \"last-name\")\n" +
|
||||
" private WebElement name;\n" +
|
||||
"\n" +
|
||||
" @FindBy(name = \"first-name\")\n" +
|
||||
" private WebElement firstName;\n" +
|
||||
"}";
|
||||
|
||||
assertEquals("find repeated annotation value", 1, findMatchesCount(in, "class '_Class {\n" +
|
||||
" @FindBy(name='_value)\n" +
|
||||
" '_FieldType '_field = '_init?;\n" +
|
||||
" @FindBy(name='_value)\n" +
|
||||
" '_FieldType2 'field2 = '_init2?;\n" +
|
||||
"}"));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user