mirror of
https://github.com/github/codeql.git
synced 2026-01-04 18:20:18 +01:00
add support for private fields in classes
This commit is contained in:
@@ -5,6 +5,7 @@ import static com.semmle.jcorn.Whitespace.lineBreak;
|
||||
|
||||
import com.semmle.jcorn.Identifiers.Dialect;
|
||||
import com.semmle.jcorn.Options.AllowReserved;
|
||||
import com.semmle.jcorn.TokenType.Properties;
|
||||
import com.semmle.js.ast.ArrayExpression;
|
||||
import com.semmle.js.ast.ArrayPattern;
|
||||
import com.semmle.js.ast.ArrowFunctionExpression;
|
||||
@@ -44,6 +45,7 @@ import com.semmle.js.ast.INode;
|
||||
import com.semmle.js.ast.IPattern;
|
||||
import com.semmle.js.ast.Identifier;
|
||||
import com.semmle.js.ast.IfStatement;
|
||||
import com.semmle.js.ast.FieldDefinition;
|
||||
import com.semmle.js.ast.ImportDeclaration;
|
||||
import com.semmle.js.ast.ImportDefaultSpecifier;
|
||||
import com.semmle.js.ast.ImportNamespaceSpecifier;
|
||||
@@ -124,6 +126,7 @@ public class Parser {
|
||||
private boolean inModule;
|
||||
protected boolean inFunction;
|
||||
protected boolean inGenerator;
|
||||
protected boolean inClass;
|
||||
protected boolean inAsync;
|
||||
protected boolean inTemplateElement;
|
||||
protected int pos;
|
||||
@@ -240,8 +243,8 @@ public class Parser {
|
||||
// Used to signify the start of a potential arrow function
|
||||
this.potentialArrowAt = -1;
|
||||
|
||||
// Flags to track whether we are in a function, a generator, an async function.
|
||||
this.inFunction = this.inGenerator = this.inAsync = false;
|
||||
// Flags to track whether we are in a function, a generator, an async function, a class.
|
||||
this.inFunction = this.inGenerator = this.inAsync = this.inClass = false;
|
||||
// Positions to delayed-check that yield/await does not exist in default parameters.
|
||||
this.yieldPos = this.awaitPos = 0;
|
||||
// Labels in scope.
|
||||
@@ -651,6 +654,9 @@ public class Parser {
|
||||
case 58:
|
||||
++this.pos;
|
||||
return this.finishToken(TokenType.colon);
|
||||
case 35:
|
||||
++this.pos;
|
||||
return this.finishToken(TokenType.pound);
|
||||
case 63:
|
||||
return this.readToken_question();
|
||||
|
||||
@@ -2191,6 +2197,7 @@ public class Parser {
|
||||
// identifiers.
|
||||
protected Identifier parseIdent(boolean liberal) {
|
||||
Position startLoc = this.startLoc;
|
||||
boolean isPrivateField = liberal && this.eat(TokenType.pound);
|
||||
if (liberal && this.options.allowReserved() == AllowReserved.NEVER) liberal = false;
|
||||
String name = null;
|
||||
if (this.type == TokenType.name) {
|
||||
@@ -2199,9 +2206,9 @@ public class Parser {
|
||||
&& (this.options.ecmaVersion() >= 6
|
||||
|| inputSubstring(this.start, this.end).indexOf("\\") == -1))
|
||||
this.raiseRecoverable(this.start, "The keyword '" + this.value + "' is reserved");
|
||||
if (this.inGenerator && this.value.equals("yield"))
|
||||
if (!isPrivateField && this.inGenerator && this.value.equals("yield"))
|
||||
this.raiseRecoverable(this.start, "Can not use 'yield' as identifier inside a generator");
|
||||
if (this.inAsync && this.value.equals("await"))
|
||||
if (!isPrivateField && this.inAsync && this.value.equals("await"))
|
||||
this.raiseRecoverable(
|
||||
this.start, "Can not use 'await' as identifier inside an async function");
|
||||
name = String.valueOf(this.value);
|
||||
@@ -2213,6 +2220,12 @@ public class Parser {
|
||||
this.unexpected();
|
||||
}
|
||||
this.next();
|
||||
if (isPrivateField) {
|
||||
if (!this.inClass) {
|
||||
this.raiseRecoverable(this.start, "Cannot use private fields outside a class");
|
||||
}
|
||||
name = "#" + name;
|
||||
}
|
||||
Identifier node = new Identifier(new SourceLocation(startLoc), name);
|
||||
return this.finishNode(node);
|
||||
}
|
||||
@@ -3127,6 +3140,8 @@ public class Parser {
|
||||
// Parse a class declaration or literal (depending on the
|
||||
// `isStatement` parameter).
|
||||
protected Node parseClass(Position startLoc, boolean isStatement) {
|
||||
boolean oldInClass = this.inClass;
|
||||
this.inClass = true;
|
||||
SourceLocation loc = new SourceLocation(startLoc);
|
||||
this.next();
|
||||
Identifier id = this.parseClassId(isStatement);
|
||||
@@ -3145,6 +3160,8 @@ public class Parser {
|
||||
Node node;
|
||||
if (isStatement) node = new ClassDeclaration(loc, id, superClass, classBody);
|
||||
else node = new ClassExpression(loc, id, superClass, classBody);
|
||||
|
||||
this.inClass = oldInClass;
|
||||
return this.finishNode(node);
|
||||
}
|
||||
|
||||
|
||||
@@ -85,6 +85,7 @@ public class TokenType {
|
||||
dot = new TokenType(new Properties(".")),
|
||||
questiondot = new TokenType(new Properties("?.")),
|
||||
question = new TokenType(new Properties("?").beforeExpr()),
|
||||
pound = new TokenType(kw("#")),
|
||||
arrow = new TokenType(new Properties("=>").beforeExpr()),
|
||||
template = new TokenType(new Properties("template")),
|
||||
invalidTemplate = new TokenType(new Properties("invalidTemplate")),
|
||||
|
||||
Reference in New Issue
Block a user