Update test262 test script and a few keyword escape fixes (#7503)

* Update test262 and whitelist

* Use test262-stream

* Check escapes in contextual keywords

* Check escapes when parsing new.target

* Check escapes for getters/setters

* Check escapes for static class methods

* Check escapes on async arrow and functions
This commit is contained in:
Brian Ng
2018-03-08 09:10:00 -06:00
committed by GitHub
parent 2a0071028d
commit f97d4313c9
9 changed files with 1974 additions and 1224 deletions

View File

@@ -572,6 +572,7 @@ export default class ExpressionParser extends LValParser {
atPossibleAsync(base: N.Expression): boolean {
return (
!this.state.containsEsc &&
this.state.potentialArrowAt === base.start &&
base.type === "Identifier" &&
base.name === "async" &&
@@ -739,6 +740,7 @@ export default class ExpressionParser extends LValParser {
case tt.name: {
node = this.startNode();
const allowAwait = this.state.value === "await" && this.state.inAsync;
const containsEsc = this.state.containsEsc;
const allowYield = this.shouldAllowYieldIdentifier();
const id = this.parseIdentifier(allowAwait || allowYield);
@@ -747,6 +749,7 @@ export default class ExpressionParser extends LValParser {
return this.parseAwait(node);
}
} else if (
!containsEsc &&
id.name === "async" &&
this.match(tt._function) &&
!this.canInsertSemicolon()
@@ -915,9 +918,11 @@ export default class ExpressionParser extends LValParser {
}
}
const containsEsc = this.state.containsEsc;
node.property = this.parseIdentifier(true);
if (node.property.name !== propertyName) {
if (node.property.name !== propertyName || containsEsc) {
this.raise(
node.property.start,
`The only valid meta property for ${meta.name} is ${
@@ -1304,6 +1309,8 @@ export default class ExpressionParser extends LValParser {
isGenerator = this.eat(tt.star);
}
const containsEsc = this.state.containsEsc;
if (!isPattern && this.isContextual("async")) {
if (isGenerator) this.unexpected();
@@ -1338,6 +1345,7 @@ export default class ExpressionParser extends LValParser {
isAsync,
isPattern,
refShorthandDefaultPos,
containsEsc,
);
this.checkPropClash(prop, propHash);
@@ -1408,6 +1416,7 @@ export default class ExpressionParser extends LValParser {
isGenerator: boolean,
isAsync: boolean,
isPattern: boolean,
containsEsc: boolean,
): ?N.ObjectMethod {
if (isAsync || isGenerator || this.match(tt.parenL)) {
if (isPattern) this.unexpected();
@@ -1422,7 +1431,7 @@ export default class ExpressionParser extends LValParser {
);
}
if (this.isGetterOrSetterMethod(prop, isPattern)) {
if (!containsEsc && this.isGetterOrSetterMethod(prop, isPattern)) {
if (isGenerator || isAsync) this.unexpected();
prop.kind = prop.key.name;
this.parsePropertyName(prop);
@@ -1490,9 +1499,16 @@ export default class ExpressionParser extends LValParser {
isAsync: boolean,
isPattern: boolean,
refShorthandDefaultPos: ?Pos,
containsEsc: boolean,
): void {
const node =
this.parseObjectMethod(prop, isGenerator, isAsync, isPattern) ||
this.parseObjectMethod(
prop,
isGenerator,
isAsync,
isPattern,
containsEsc,
) ||
this.parseObjectProperty(
prop,
startPos,

View File

@@ -155,7 +155,7 @@ export default class StatementParser extends ExpressionParser {
return result;
}
case tt.name:
if (this.state.value === "async") {
if (this.isContextual("async")) {
// peek ahead and see if next token is a function
const state = this.state.clone();
this.next();
@@ -970,8 +970,11 @@ export default class StatementParser extends ExpressionParser {
state: { hadConstructor: boolean },
): void {
let isStatic = false;
const containsEsc = this.state.containsEsc;
if (this.match(tt.name) && this.state.value === "static") {
const key = this.parseIdentifier(true); // eats 'static'
if (this.isClassMethod()) {
const method: N.ClassMethod = (member: any);
@@ -997,7 +1000,10 @@ export default class StatementParser extends ExpressionParser {
prop.static = false;
classBody.body.push(this.parseClassProperty(prop));
return;
} else if (containsEsc) {
throw this.unexpected();
}
// otherwise something static
isStatic = true;
}

View File

@@ -46,7 +46,11 @@ export default class UtilParser extends Tokenizer {
// Tests whether parsed token is a contextual keyword.
isContextual(name: string): boolean {
return this.match(tt.name) && this.state.value === name;
return (
this.match(tt.name) &&
this.state.value === name &&
!this.state.containsEsc
);
}
isLookaheadContextual(name: string): boolean {
@@ -57,7 +61,7 @@ export default class UtilParser extends Tokenizer {
// Consumes contextual keyword if possible.
eatContextual(name: string): boolean {
return this.state.value === name && this.eat(tt.name);
return this.isContextual(name) && this.eat(tt.name);
}
// Asserts that following token is given contextual keyword.