mirror of
https://github.com/github/codeql.git
synced 2026-01-06 19:20:25 +01:00
JS(extractor): support nullish coalescing operators
This commit is contained in:
@@ -508,8 +508,12 @@ public class Parser {
|
||||
private Token readToken_question() { // '?'
|
||||
int next = charAt(this.pos + 1);
|
||||
int next2 = charAt(this.pos + 2);
|
||||
if (this.options.esnext() && next == '.' && !('0' <= next2 && next2 <= '9')) // '?.', but not '?.X' where X is a digit
|
||||
return this.finishOp(TokenType.questiondot, 2);
|
||||
if (this.options.esnext()) {
|
||||
if (next == '.' && !('0' <= next2 && next2 <= '9')) // '?.', but not '?.X' where X is a digit
|
||||
return this.finishOp(TokenType.questiondot, 2);
|
||||
if (next == '?') // '??'
|
||||
return this.finishOp(TokenType.questionquestion, 2);
|
||||
}
|
||||
return this.finishOp(TokenType.question, 1);
|
||||
}
|
||||
|
||||
|
||||
@@ -123,6 +123,7 @@ public class TokenType {
|
||||
}
|
||||
},
|
||||
prefix = new TokenType(new Properties("prefix").beforeExpr().prefix().startsExpr()),
|
||||
questionquestion = new TokenType(binop("??", 1)),
|
||||
logicalOR = new TokenType(binop("||", 1)),
|
||||
logicalAND = new TokenType(binop("&&", 2)),
|
||||
bitwiseOR = new TokenType(binop("|", 3)),
|
||||
|
||||
@@ -331,9 +331,11 @@ public class CFGExtractor {
|
||||
return nd.getKey().accept(this, v);
|
||||
}
|
||||
|
||||
// for binary operators, the operands come first (but not for LogicalExpression, see above)
|
||||
// for binary operators, the operands come first (but not for short-circuiting expressions), see above)
|
||||
@Override
|
||||
public Node visit(BinaryExpression nd, Void v) {
|
||||
if ("??".equals(nd.getOperator()))
|
||||
return nd;
|
||||
return nd.getLeft().accept(this, v);
|
||||
}
|
||||
|
||||
@@ -1583,8 +1585,16 @@ public class CFGExtractor {
|
||||
|
||||
@Override
|
||||
public Void visit(BinaryExpression nd, SuccessorInfo i) {
|
||||
this.seq(nd.getLeft(), nd.getRight(), nd);
|
||||
succ(nd, i.getGuardedSuccessors(nd));
|
||||
if ("??".equals(nd.getOperator())) {
|
||||
// the nullish coalescing operator is short-circuiting, but we do not add guards for it
|
||||
succ(nd, First.of(nd.getLeft()));
|
||||
Object leftSucc = union(First.of(nd.getRight()), i.getAllSuccessors()); // short-circuiting happens with both truthy and falsy values
|
||||
visit(nd.getLeft(), leftSucc, null);
|
||||
nd.getRight().accept(this, i);
|
||||
} else {
|
||||
this.seq(nd.getLeft(), nd.getRight(), nd);
|
||||
succ(nd, i.getGuardedSuccessors(nd));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -72,6 +72,7 @@ public class ExprKinds {
|
||||
binOpKinds.put("&=", 58);
|
||||
binOpKinds.put("**", 87);
|
||||
binOpKinds.put("**=", 88);
|
||||
binOpKinds.put("??", 107);
|
||||
}
|
||||
|
||||
private static final Map<String, Integer> unOpKinds = new LinkedHashMap<String, Integer>();
|
||||
|
||||
@@ -41,7 +41,7 @@ public class Main {
|
||||
* such a way that it may produce different tuples for the same file under the same
|
||||
* {@link ExtractorConfig}.
|
||||
*/
|
||||
public static final String EXTRACTOR_VERSION = "2018-11-22_a";
|
||||
public static final String EXTRACTOR_VERSION = "2018-11-23";
|
||||
|
||||
public static final Pattern NEWLINE = Pattern.compile("\n");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user