Skip to content
This repository has been archived by the owner on May 19, 2018. It is now read-only.

Commit

Permalink
keywords are not allowed as local specifier
Browse files Browse the repository at this point in the history
Also fix some error messages to be more specific
  • Loading branch information
danez committed Jan 20, 2017
1 parent 0a00aff commit fe21e06
Show file tree
Hide file tree
Showing 21 changed files with 59 additions and 29 deletions.
9 changes: 4 additions & 5 deletions src/parser/expression.js
Expand Up @@ -1018,14 +1018,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();
Expand Down
7 changes: 6 additions & 1 deletion src/parser/statement.js
Expand Up @@ -1075,7 +1075,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"));
};
Expand Down
26 changes: 13 additions & 13 deletions src/plugins/flow.js
Expand Up @@ -1221,9 +1221,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;
Expand All @@ -1232,23 +1233,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();
Expand All @@ -1261,6 +1259,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"));
};
Expand Down
@@ -0,0 +1 @@
import { default } from "foo";
@@ -0,0 +1,4 @@
{
"plugins": ["flow"],
"throws": "default is a reserved word (1:9)"
}
@@ -0,0 +1 @@
import { typeof } from "foo";
@@ -0,0 +1,4 @@
{
"plugins": ["flow"],
"throws": "typeof is a reserved word (1:9)"
}
@@ -0,0 +1 @@
import { typeof } from "foo";
@@ -0,0 +1,3 @@
{
"throws": "typeof is a reserved word (1:9)"
}
@@ -0,0 +1 @@
import { debugger } from "foo";
@@ -0,0 +1,3 @@
{
"throws": "debugger is a reserved word (1:9)"
}
@@ -1,3 +1,3 @@
{
"throws": "Unexpected token (1:26)"
}
"throws": "yield is a reserved word (1:26)"
}
@@ -1,3 +1,3 @@
{
"throws": "Unexpected token (1:25)"
}
"throws": "yield is a reserved word (1:25)"
}
@@ -1,3 +1,3 @@
{
"throws": "Unexpected token (1:46)"
}
"throws": "yield is a reserved word (1:46)"
}
@@ -1,3 +1,3 @@
{
"throws": "Unexpected token (1:29)"
"throws": "yield is a reserved word (1:29)"
}
@@ -1,3 +1,3 @@
{
"throws": "Unexpected token (1:28)"
}
"throws": "yield is a reserved word (1:28)"
}
@@ -0,0 +1 @@
import { type as debugger } from "foo";
@@ -0,0 +1,3 @@
{
"throws": "debugger is a reserved word (1:17)"
}
@@ -0,0 +1 @@
import { type debugger } from "foo";
@@ -0,0 +1,3 @@
{
"throws": "debugger is a reserved word (1:9)"
}
@@ -1,4 +1,4 @@
{
"throws": "Unexpected token (1:14)",
"throws": "delete is a reserved word (1:14)",
"plugins": ["flow", "jsx"]
}

0 comments on commit fe21e06

Please sign in to comment.