keywords are not allowed as local specifier (#307)

Also fix some error messages to be more specific
This commit is contained in:
Daniel Tschinder 2017-02-10 14:58:44 +01:00 committed by GitHub
parent e049ec3456
commit 4bd682e90b
21 changed files with 59 additions and 29 deletions

View File

@ -1039,14 +1039,13 @@ pp.parseExprListItem = function (allowEmpty, refShorthandDefaultPos) {
pp.parseIdentifier = function (liberal) {
const node = this.startNode();
if (!liberal) {
this.checkReservedWord(this.state.value, this.state.start, !!this.state.type.keyword, false);
}
if (this.match(tt.name)) {
if (!liberal) {
this.checkReservedWord(this.state.value, this.state.start, false, false);
}
node.name = this.state.value;
} else if (liberal && this.state.type.keyword) {
} else if (this.state.type.keyword) {
node.name = this.state.type.keyword;
} else {
this.unexpected();

View File

@ -1074,7 +1074,12 @@ pp.parseImportSpecifiers = function (node) {
pp.parseImportSpecifier = function (node) {
const specifier = this.startNode();
specifier.imported = this.parseIdentifier(true);
specifier.local = this.eatContextual("as") ? this.parseIdentifier() : specifier.imported.__clone();
if (this.eatContextual("as")) {
specifier.local = this.parseIdentifier();
} else {
this.checkReservedWord(specifier.imported.name, specifier.start, true, true);
specifier.local = specifier.imported.__clone();
}
this.checkLVal(specifier.local, true, undefined, "import specifier");
node.specifiers.push(this.finishNode(specifier, "ImportSpecifier"));
};

View File

@ -1267,9 +1267,10 @@ export default function (instance) {
specifierTypeKind = "typeof";
}
let isBinding = false;
if (this.isContextual("as")) {
const as_ident = this.parseIdentifier(true);
if (specifierTypeKind !== null && !this.match(tt.name)) {
if (specifierTypeKind !== null && !this.match(tt.name) && !this.state.type.keyword) {
// `import {type as ,` or `import {type as }`
specifier.imported = as_ident;
specifier.importKind = specifierTypeKind;
@ -1278,23 +1279,20 @@ export default function (instance) {
// `import {type as foo`
specifier.imported = firstIdent;
specifier.importKind = null;
specifier.local = this.parseIdentifier(false);
specifier.local = this.parseIdentifier();
}
} else if (specifierTypeKind !== null && this.match(tt.name)) {
} else if (specifierTypeKind !== null && (this.match(tt.name) || this.state.type.keyword)) {
// `import {type foo`
specifier.imported = this.parseIdentifier(true);
specifier.importKind = specifierTypeKind;
specifier.local =
this.eatContextual("as")
? this.parseIdentifier(false)
: specifier.imported.__clone();
} else {
if (firstIdent.name === "typeof") {
this.unexpected(
firstIdentLoc,
"Cannot import a variable named `typeof`"
);
if (this.eatContextual("as")) {
specifier.local = this.parseIdentifier();
} else {
isBinding = true;
specifier.local = specifier.imported.__clone();
}
} else {
isBinding = true;
specifier.imported = firstIdent;
specifier.importKind = null;
specifier.local = specifier.imported.__clone();
@ -1307,6 +1305,8 @@ export default function (instance) {
this.raise(firstIdentLoc, "`The `type` and `typeof` keywords on named imports can only be used on regular `import` statements. It cannot be used with `import type` or `import typeof` statements`");
}
if (isBinding) this.checkReservedWord(specifier.local.name, specifier.start, true, true);
this.checkLVal(specifier.local, true, undefined, "import specifier");
node.specifiers.push(this.finishNode(specifier, "ImportSpecifier"));
};

View File

@ -0,0 +1 @@
import { default } from "foo";

View File

@ -0,0 +1,4 @@
{
"plugins": ["flow"],
"throws": "default is a reserved word (1:9)"
}

View File

@ -0,0 +1 @@
import { typeof } from "foo";

View File

@ -0,0 +1,4 @@
{
"plugins": ["flow"],
"throws": "typeof is a reserved word (1:9)"
}

View File

@ -0,0 +1 @@
import { typeof } from "foo";

View File

@ -0,0 +1,3 @@
{
"throws": "typeof is a reserved word (1:9)"
}

View File

@ -0,0 +1 @@
import { debugger } from "foo";

View File

@ -0,0 +1,3 @@
{
"throws": "debugger is a reserved word (1:9)"
}

View File

@ -1,3 +1,3 @@
{
"throws": "Unexpected token (1:26)"
}
"throws": "yield is a reserved word (1:26)"
}

View File

@ -1,3 +1,3 @@
{
"throws": "Unexpected token (1:25)"
}
"throws": "yield is a reserved word (1:25)"
}

View File

@ -1,3 +1,3 @@
{
"throws": "Unexpected token (1:46)"
}
"throws": "yield is a reserved word (1:46)"
}

View File

@ -1,3 +1,3 @@
{
"throws": "Unexpected token (1:29)"
"throws": "yield is a reserved word (1:29)"
}

View File

@ -1,3 +1,3 @@
{
"throws": "Unexpected token (1:28)"
}
"throws": "yield is a reserved word (1:28)"
}

View File

@ -0,0 +1 @@
import { type as debugger } from "foo";

View File

@ -0,0 +1,3 @@
{
"throws": "debugger is a reserved word (1:17)"
}

View File

@ -0,0 +1 @@
import { type debugger } from "foo";

View File

@ -0,0 +1,3 @@
{
"throws": "debugger is a reserved word (1:9)"
}

View File

@ -1,4 +1,4 @@
{
"throws": "Unexpected token (1:14)",
"throws": "delete is a reserved word (1:14)",
"plugins": ["flow", "jsx"]
}