Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 6e1c995

Browse files
committed
JS: Merge consecutive constants in RegExps
1 parent 0e1246c commit 6e1c995

1 file changed

Lines changed: 23 additions & 3 deletions

File tree

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

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -314,9 +314,29 @@ private RegExpTerm parseAtom() {
314314
return this.finishTerm(new Group(loc, capture, number, name, dis));
315315
}
316316

317-
char c = this.nextChar();
318-
if ("^$\\.*+?()[]{}|".indexOf(c) != -1) this.error(Error.UNEXPECTED_CHARACTER, this.pos - 1);
319-
return this.finishTerm(new Constant(loc, String.valueOf(c)));
317+
// Parse consecutive constants into a single Constant node.
318+
// Due to speculative parsing of string literals, this part of the code is fairly hot.
319+
int startPos = this.pos;
320+
int endPos = startPos;
321+
while (endPos < src.length()) {
322+
if ("^$\\.*+?()[]{}|".indexOf(src.charAt(endPos)) != -1) break;
323+
++endPos;
324+
}
325+
if (startPos == endPos) {
326+
this.error(Error.UNEXPECTED_CHARACTER, endPos);
327+
endPos = startPos + 1; // To ensure progress, make sure we parse at least one character.
328+
}
329+
if (endPos != startPos + 1
330+
&& endPos < src.length()
331+
&& "*+?{".indexOf(src.charAt(endPos)) != -1) {
332+
endPos--; // Last constant belongs under an upcoming quantifier.
333+
}
334+
String str = src.substring(startPos, endPos);
335+
this.pos = endPos;
336+
loc.setEnd(pos());
337+
loc.setSource(str);
338+
// Do not call finishTerm as it will create another copy of 'str'.
339+
return new Constant(loc, str);
320340
}
321341

322342
private RegExpTerm parseAtomEscape(SourceLocation loc, boolean inCharClass) {

0 commit comments

Comments
 (0)