Skip to content

Commit 3664d50

Browse files
committed
Added support for -- subtraction opetor.
1 parent ee83c42 commit 3664d50

File tree

5 files changed

+180
-198
lines changed

5 files changed

+180
-198
lines changed
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package com.semmle.js.ast.regexp;
2+
3+
import com.semmle.js.ast.SourceLocation;
4+
import java.util.List;
5+
6+
public class CharacterClassSubtraction extends RegExpTerm {
7+
private final List<RegExpTerm> subtraction;
8+
9+
public CharacterClassSubtraction(SourceLocation loc, List<RegExpTerm> subtraction) {
10+
super(loc, "CharacterClassSubtraction");
11+
this.subtraction = subtraction;
12+
}
13+
14+
@Override
15+
public void accept(Visitor v) {
16+
v.visit(this);
17+
}
18+
19+
public List<RegExpTerm> getSubtraction() {
20+
return subtraction;
21+
}
22+
}

javascript/extractor/src/com/semmle/js/ast/regexp/Visitor.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,4 +65,6 @@ public interface Visitor {
6565
public void visit(CharacterClassQuotedString nd);
6666

6767
public void visit(CharacterClassIntersection nd);
68+
69+
public void visit(CharacterClassSubtraction nd);
6870
}

javascript/extractor/src/com/semmle/js/extractor/RegExpExtractor.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import com.semmle.js.ast.regexp.CharacterClassEscape;
1313
import com.semmle.js.ast.regexp.CharacterClassQuotedString;
1414
import com.semmle.js.ast.regexp.CharacterClassRange;
15+
import com.semmle.js.ast.regexp.CharacterClassSubtraction;
1516
import com.semmle.js.ast.regexp.Constant;
1617
import com.semmle.js.ast.regexp.ControlEscape;
1718
import com.semmle.js.ast.regexp.ControlLetter;
@@ -96,6 +97,7 @@ public RegExpExtractor(TrapWriter trapwriter, LocationManager locationManager) {
9697
termkinds.put("UnicodePropertyEscape", 27);
9798
termkinds.put("CharacterClassQuotedString", 28);
9899
termkinds.put("CharacterClassIntersection", 29);
100+
termkinds.put("CharacterClassSubtraction", 30);
99101
}
100102

101103
private static final String[] errmsgs =
@@ -362,6 +364,14 @@ public void visit(CharacterClassIntersection nd) {
362364
for (RegExpTerm element : nd.getIntersections())
363365
visit(element, lbl, i++);
364366
}
367+
368+
@Override
369+
public void visit(CharacterClassSubtraction nd) {
370+
Label lbl = extractTerm(nd, parent, idx);
371+
int i = 0;
372+
for (RegExpTerm element : nd.getSubtraction())
373+
visit(element, lbl, i++);
374+
}
365375
}
366376

367377
public void extract(String src, SourceMap sourceMap, Node parent, boolean isSpeculativeParsing, String flags) {

javascript/extractor/src/com/semmle/js/parser/RegExpParser.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import com.semmle.js.ast.regexp.CharacterClassEscape;
99
import com.semmle.js.ast.regexp.CharacterClassQuotedString;
1010
import com.semmle.js.ast.regexp.CharacterClassRange;
11+
import com.semmle.js.ast.regexp.CharacterClassSubtraction;
1112
import com.semmle.js.ast.regexp.Constant;
1213
import com.semmle.js.ast.regexp.ControlEscape;
1314
import com.semmle.js.ast.regexp.ControlLetter;
@@ -566,6 +567,7 @@ private RegExpTerm parseCharacterClass() {
566567
private enum CharacterClassType {
567568
STANDARD,
568569
INTERSECTION,
570+
SUBTRACTION,
569571
}
570572

571573
// ECMA 2024 `v` flag allows nested character classes.
@@ -588,6 +590,10 @@ else if (lookahead("&&")) {
588590
this.match("&&");
589591
classType = CharacterClassType.INTERSECTION;
590592
}
593+
else if (lookahead("--")) {
594+
this.match("--");
595+
classType = CharacterClassType.SUBTRACTION;
596+
}
591597
else {
592598
elements.add(this.parseCharacterClassElement());
593599
}
@@ -597,6 +603,8 @@ else if (lookahead("&&")) {
597603
switch (classType) {
598604
case INTERSECTION:
599605
return this.finishTerm(new CharacterClass(loc, Collections.singletonList(new CharacterClassIntersection(loc, elements)), inverted));
606+
case SUBTRACTION:
607+
return this.finishTerm(new CharacterClass(loc, Collections.singletonList(new CharacterClassSubtraction(loc, elements)), inverted));
600608
case STANDARD:
601609
default:
602610
return this.finishTerm(new CharacterClass(loc, elements, inverted));
@@ -614,7 +622,7 @@ private RegExpTerm parseCharacterClassElement() {
614622
return atom;
615623
}
616624
}
617-
if (!this.lookahead("-]") && this.match("-") && !(atom instanceof CharacterClassEscape))
625+
if (!this.lookahead("-]") && !this.lookahead("--") && this.match("-") && !(atom instanceof CharacterClassEscape))
618626
return this.finishTerm(new CharacterClassRange(loc, atom, this.parseCharacterClassAtom()));
619627
return atom;
620628
}

0 commit comments

Comments
 (0)