change some things to expectPlugin

This commit is contained in:
Henry Zhu 2017-08-03 11:13:00 -04:00
parent cf3ebacf4f
commit 2dbba25d1a
22 changed files with 110 additions and 48 deletions

View File

@ -433,12 +433,7 @@ export default class ExpressionParser extends LValParser {
noCalls,
);
} else if (this.match(tt.questionDot)) {
if (!this.hasPlugin("optionalChaining")) {
this.raise(
startPos,
"You can only use optional-chaining when the 'optionalChaining' plugin is enabled.",
);
}
this.expectPlugin("optionalChaining");
if (noCalls && this.lookahead().type == tt.parenL) {
state.stop = true;
@ -660,11 +655,11 @@ export default class ExpressionParser extends LValParser {
return this.finishNode(node, "Super");
case tt._import:
if (this.hasPlugin("importMeta") && this.lookahead().type === tt.dot) {
if (this.lookahead().type === tt.dot) {
return this.parseImportMetaProperty();
}
if (!this.hasPlugin("dynamicImport")) this.unexpected();
this.expectPlugin("dynamicImport");
node = this.startNode();
this.next();
@ -712,7 +707,9 @@ export default class ExpressionParser extends LValParser {
return id;
case tt._do:
if (this.hasPlugin("doExpressions")) {
// TODO
if (true) {
this.expectPlugin("doExpressions");
const node = this.startNode();
this.next();
const oldInFunction = this.state.inFunction;
@ -825,11 +822,7 @@ export default class ExpressionParser extends LValParser {
parseFunctionExpression(): N.FunctionExpression | N.MetaProperty {
const node = this.startNode();
const meta = this.parseIdentifier(true);
if (
this.state.inGenerator &&
this.hasPlugin("functionSent") &&
this.eat(tt.dot)
) {
if (this.state.inGenerator && this.eat(tt.dot)) {
return this.parseMetaProperty(node, meta, "sent");
}
return this.parseFunction(node, false);
@ -841,6 +834,16 @@ export default class ExpressionParser extends LValParser {
propertyName: string,
): N.MetaProperty {
node.meta = meta;
if (meta.name === "function" && propertyName === "sent") {
if (this.isContextual(propertyName)) {
this.expectPlugin("functionSent");
} else if (!this.hasPlugin("functionSent")) {
// They didn't actually say `function.sent`, just `function.`, so a simple error would be less confusing.
this.unexpected();
}
}
node.property = this.parseIdentifier(true);
if (node.property.name !== propertyName) {
@ -857,6 +860,18 @@ export default class ExpressionParser extends LValParser {
const node = this.startNode();
const id = this.parseIdentifier(true);
this.expect(tt.dot);
if (id.name === "import") {
if (this.isContextual("meta")) {
this.expectPlugin("importMeta");
} else if (!this.hasPlugin("importMeta")) {
this.raise(
null,
`Dynamic imports require a parameter: import('a.js').then`,
);
}
}
if (!this.inModule) {
this.raise(
id.start,
@ -1141,7 +1156,8 @@ export default class ExpressionParser extends LValParser {
decorators = [];
}
if (this.hasPlugin("objectRestSpread") && this.match(tt.ellipsis)) {
if (this.match(tt.ellipsis)) {
this.expectPlugin("objectRestSpread");
prop = this.parseSpread(isPattern ? { start: 0 } : undefined);
if (isPattern) {
this.toAssignable(prop, true, "object pattern");
@ -1199,8 +1215,11 @@ export default class ExpressionParser extends LValParser {
prop.computed = false;
} else {
isAsync = true;
if (this.hasPlugin("asyncGenerators"))
isGenerator = this.eat(tt.star);
if (this.match(tt.star)) {
this.expectPlugin("asyncGenerators");
this.next();
isGenerator = true;
}
this.parsePropertyName(prop);
}
} else {

View File

@ -10,7 +10,11 @@ import CommentsParser from "./comments";
// message.
export default class LocationParser extends CommentsParser {
raise(pos: number, message: string, missingPluginName: string): empty {
raise(
pos: number,
message: string,
missingPluginNames?: Array<string>,
): empty {
const loc = getLineInfo(this.input, pos);
message += ` (${loc.line}:${loc.column})`;
// $FlowIgnore
@ -19,8 +23,8 @@ export default class LocationParser extends CommentsParser {
);
err.pos = pos;
err.loc = loc;
if (missingPluginName) {
err.missingPlugin = missingPluginName;
if (missingPluginNames) {
err.missingPlugin = missingPluginNames;
}
throw err;
}

View File

@ -237,9 +237,7 @@ export default class StatementParser extends ExpressionParser {
}
parseDecorator(): N.Decorator {
if (!(this.hasPlugin("decorators") || this.hasPlugin("decorators2"))) {
this.unexpected();
}
this.expectOnePlugin(["decorators", "decorators2"]);
const node = this.startNode();
this.next();
@ -340,11 +338,8 @@ export default class StatementParser extends ExpressionParser {
this.state.labels.push(loopLabel);
let forAwait = false;
if (
this.hasPlugin("asyncGenerators") &&
this.state.inAsync &&
this.isContextual("await")
) {
if (this.state.inAsync && this.isContextual("await")) {
this.expectPlugin("asyncGenerators");
forAwait = true;
this.next();
}
@ -489,12 +484,13 @@ export default class StatementParser extends ExpressionParser {
if (this.match(tt._catch)) {
const clause = this.startNode();
this.next();
if (this.match(tt.parenL) || !this.hasPlugin("optionalCatchBinding")) {
if (this.match(tt.parenL)) {
this.expect(tt.parenL);
clause.param = this.parseBindingAtom();
this.checkLVal(clause.param, true, Object.create(null), "catch clause");
this.expect(tt.parenR);
} else {
this.expectPlugin("optionalCatchBinding");
clause.param = null;
}
clause.body = this.parseBlock();
@ -782,12 +778,11 @@ export default class StatementParser extends ExpressionParser {
this.initFunction(node, isAsync);
if (this.match(tt.star)) {
if (node.async && !this.hasPlugin("asyncGenerators")) {
this.unexpected();
} else {
node.generator = true;
this.next();
if (node.async) {
this.expectPlugin("asyncGenerators");
}
node.generator = true;
this.next();
}
if (
@ -960,8 +955,9 @@ export default class StatementParser extends ExpressionParser {
isStatic = true;
}
if (this.hasPlugin("classPrivateProperties") && this.match(tt.hash)) {
if (this.match(tt.hash)) {
// Private property
this.expectPlugin("classPrivateProperties");
this.next();
const privateProp: N.ClassPrivateProperty = memberAny;
privateProp.key = this.parseIdentifier(true);
@ -1047,8 +1043,12 @@ export default class StatementParser extends ExpressionParser {
this.pushClassProperty(classBody, prop);
} else if (isSimple && key.name === "async" && !this.isLineTerminator()) {
// an async method
const isGenerator =
this.hasPlugin("asyncGenerators") && this.eat(tt.star);
let isGenerator = false;
if (this.match(tt.star)) {
this.expectPlugin("asyncGenerators");
this.next();
isGenerator = true;
}
method.kind = "method";
this.parsePropertyName(method);
if (this.isNonstaticConstructor(method)) {

View File

@ -114,8 +114,20 @@ export default class UtilParser extends Tokenizer {
if (!this.hasPlugin(name)) {
throw this.raise(
this.state.start,
`This experimental syntax requires enabling the parser plugin: ${name}`,
name,
`This experimental syntax requires enabling the parser plugin: '${name}'`,
[name],
);
}
}
expectOnePlugin(names: Array<string>): void {
if (!names.some(n => this.hasPlugin(n))) {
throw this.raise(
this.state.start,
`This experimental syntax requires enabling the parser plugin(s): '${names.join(
", ",
)}'`,
names,
);
}
}

View File

@ -1,3 +1,3 @@
{
"throws": "Unexpected token, expected ( (2:15)"
"throws": "Dynamic imports require a parameter: import('a.js').then (1:0)"
}

View File

@ -1,3 +1,3 @@
{
"throws": "Unexpected token, expected ( (2:10)"
"throws": "This experimental syntax requires enabling the parser plugin: 'functionSent' (2:11)"
}

View File

@ -1,3 +1,3 @@
{
"throws": "Unexpected token, expected ( (2:11)"
"throws": "This experimental syntax requires enabling the parser plugin: 'functionSent' (2:12)"
}

View File

@ -1,3 +1,3 @@
{
"throws": "Unexpected token, expected ( (2:17)"
"throws": "This experimental syntax requires enabling the parser plugin: 'functionSent' (2:18)"
}

View File

@ -1,4 +1,4 @@
{
"throws": "Unexpected token (1:15)",
"throws": "This experimental syntax requires enabling the parser plugin: 'asyncGenerators' (1:15)",
"plugins": []
}
}

View File

@ -0,0 +1,2 @@
@memoize
function() {}

View File

@ -0,0 +1,4 @@
{
"throws": "This experimental syntax requires enabling the parser plugin(s): 'decorators, decorators2' (1:0)",
"plugins": []
}

View File

@ -0,0 +1 @@
(do {x})

View File

@ -0,0 +1,4 @@
{
"throws": "This experimental syntax requires enabling the parser plugin: 'doExpressions' (1:1)",
"plugins": []
}

View File

@ -0,0 +1 @@
var $ = import("jquery");

View File

@ -0,0 +1,4 @@
{
"throws": "This experimental syntax requires enabling the parser plugin: 'dynamicImport' (1:8)",
"plugins": []
}

View File

@ -0,0 +1 @@
const x = import.meta;

View File

@ -0,0 +1,5 @@
{
"throws": "This experimental syntax requires enabling the parser plugin: 'importMeta' (1:17)",
"sourceType": "module",
"plugins": []
}

View File

@ -0,0 +1 @@
({...x})

View File

@ -0,0 +1,4 @@
{
"throws": "This experimental syntax requires enabling the parser plugin: 'objectRestSpread' (1:2)",
"plugins": []
}

View File

@ -1,3 +1,3 @@
{
"throws": "Unexpected token, expected ( (4:6)"
"throws": "This experimental syntax requires enabling the parser plugin: 'optionalCatchBinding' (4:6)"
}

View File

@ -1,3 +1,3 @@
{
"throws": "Unexpected token, expected ( (4:6)"
"throws": "This experimental syntax requires enabling the parser plugin: 'optionalCatchBinding' (4:6)"
}

View File

@ -1,3 +1,3 @@
{
"throws": "You can only use optional-chaining when the 'optionalChaining' plugin is enabled. (1:0)"
"throws": "This experimental syntax requires enabling the parser plugin: 'optionalChaining' (1:1)"
}