From b38c15a94bca0077b8f8ba07f67f1d02eb440663 Mon Sep 17 00:00:00 2001
From: Ingvar Stepanyan
The keywords that denote values.
var _null = {keyword: "null", atomValue: null}, _true = {keyword: "true", atomValue: true};
+ var _class = {keyword: "class"}, _extends = {keyword: "extends", beforeExpr: true}, _static = {keyword: "static"};
+ var _module = {keyword: "module"}, _export = {keyword: "export"};
+ var _import = {keyword: "import"}, _from = {keyword: "from"}, _as = {keyword: "as"};The keywords that denote values.
var _null = {keyword: "null", atomValue: null}, _true = {keyword: "true", atomValue: true};
var _false = {keyword: "false", atomValue: false};Some keywords are treated as regular operators. in sometimes
(when parsing for) needs to be tested against specifically, so
we assign a variable name to it for quick comparing.
var _in = {keyword: "in", binop: 7, beforeExpr: true};
@@ -193,7 +195,9 @@ we assign a variable name to it for quick comparing. Punctuation token types. Again, the type property is purely for debugging.
var _bracketL = {type: "[", beforeExpr: true}, _bracketR = {type: "]"}, _braceL = {type: "{", beforeExpr: true};
+ "class": _class, "extends": _extends, "static": _static, "of": _of,
+ "module": _module, "export": _export, "import": _import,
+ "from": _from, "as": _as};Punctuation token types. Again, the type property is purely for debugging.
var _bracketL = {type: "[", beforeExpr: true}, _bracketR = {type: "]"}, _braceL = {type: "{", beforeExpr: true};
var _braceR = {type: "}"}, _parenL = {type: "(", beforeExpr: true}, _parenR = {type: ")"};
var _comma = {type: ",", beforeExpr: true}, _semi = {type: ";", beforeExpr: true};
var _colon = {type: ":", beforeExpr: true}, _dot = {type: "."}, _ellipsis = {type: "..."}, _question = {type: "?", beforeExpr: true};
@@ -268,7 +272,7 @@ switch first dispatches on the lengths, to save on comparisons.
var isEcma5AndLessKeyword = makePredicate(ecma5AndLessKeywords);
- var isEcma6Keyword = makePredicate(ecma5AndLessKeywords + " let const class extends static of");
+ var isEcma6Keyword = makePredicate(ecma5AndLessKeywords + " let const class extends static of module export import from as");
var isKeyword = isEcma5AndLessKeyword;Big ugly regular expressions that match characters in the whitespace, identifier, and identifier-start categories. These @@ -909,7 +913,8 @@ complexity.
If the statement does not start with a statement keyword or a + case _semi: return parseEmptyStatement(node); + case _export: return parseExport(node);
If the statement does not start with a statement keyword or a brace, it's an ExpressionStatement or LabeledStatement. We simply start parsing an expression, and afterwards, if the next token is a colon and the expression was a simple @@ -1684,6 +1689,51 @@ if possible.
Checks if node can be assignable spread argument.
function checkSpreadAssign(node) {
if (node.type !== "Identifier" && node.type !== "ArrayPattern")
unexpected(node.start);
+ }Parses module export declaration.
function parseExport(node) {
+ next();
+ if (tokType === _var || tokType === _const || tokType === _let || tokType === _function || tokType === _class) {
+ node.declaration = parseStatement();
+ node.default = false;
+ node.specifiers = null;
+ node.source = null;
+ } else
+ if (eat(_default)) {
+ node.declaration = parseExpression(true);
+ node.default = true;
+ node.specifiers = null;
+ node.source = null;
+ semicolon();
+ } else
+ if (tokVal === '*') {
+ node.declaration = null;
+ node.default = false;
+ var specifier = startNode();
+ next();
+ node.specifiers = [finishNode(specifier, "ExportBatchSpecifier")];
+ expect(_from);
+ node.source = tokType === _string ? parseExprAtom() : unexpected();
+ } else
+ if (eat(_braceL)) {
+ node.declaration = null;
+ node.default = false;
+ node.specifiers = parseModuleSpecifiers("ExportSpecifier");
+ node.source = eat(_from) ? (tokType === _string ? parseExprAtom() : unexpected()) : null;
+ } else unexpected();
+ return finishNode(node, "ExportDeclaration");
+ }Parses a comma-separated list of module imports/exports.
function parseModuleSpecifiers(type) {
+ var nodes = [], first = true;
+ while (!eat(_braceR)) {
+ if (!first) {
+ expect(_comma);
+ if (options.allowTrailingCommas && eat(_braceR)) break;
+ } else first = false;
+
+ var node = startNode();
+ node.id = parseIdent();
+ node.name = eat(_as) ? parseIdent(true) : null;
+ nodes.push(finishNode(node, type));
+ }
+ return nodes;
}
});
diff --git a/test/tests-harmony.js b/test/tests-harmony.js
index f69ae66f52..eed92440bd 100644
--- a/test/tests-harmony.js
+++ b/test/tests-harmony.js
@@ -4965,6 +4965,7 @@ test("export var document", {
end: {line: 1, column: 19}
}
},
+ default: false,
specifiers: null,
source: null,
range: [0, 19],
@@ -5023,6 +5024,7 @@ test("export var document = { }", {
end: {line: 1, column: 25}
}
},
+ default: false,
specifiers: null,
source: null,
range: [0, 25],
@@ -5073,6 +5075,7 @@ test("export let document", {
end: {line: 1, column: 19}
}
},
+ default: false,
specifiers: null,
source: null,
range: [0, 19],
@@ -5131,6 +5134,7 @@ test("export let document = { }", {
end: {line: 1, column: 25}
}
},
+ default: false,
specifiers: null,
source: null,
range: [0, 25],
@@ -5189,6 +5193,7 @@ test("export const document = { }", {
end: {line: 1, column: 27}
}
},
+ default: false,
specifiers: null,
source: null,
range: [0, 27],
@@ -5243,6 +5248,7 @@ test("export function parse() { }", {
end: {line: 1, column: 27}
}
},
+ default: false,
specifiers: null,
source: null,
range: [0, 27],
@@ -5293,6 +5299,7 @@ test("export class Class {}", {
end: {line: 1, column: 21}
}
},
+ default: false,
specifiers: null,
source: null,
range: [0, 21],
@@ -5312,49 +5319,33 @@ test("export class Class {}", {
locations: true
});
-test("export default = 42", {
+test("export default 42", {
type: "Program",
body: [{
type: "ExportDeclaration",
- declaration: [{
- type: "VariableDeclarator",
- id: {
- type: "Identifier",
- name: "default",
- range: [7, 14],
- loc: {
- start: {line: 1, column: 7},
- end: {line: 1, column: 14}
- }
- },
- init: {
- type: "Literal",
- value: 42,
- raw: "42",
- range: [17, 19],
- loc: {
- start: {line: 1, column: 17},
- end: {line: 1, column: 19}
- }
- },
- range: [7, 19],
+ declaration: {
+ type: "Literal",
+ value: 42,
+ raw: "42",
+ range: [15, 17],
loc: {
- start: {line: 1, column: 7},
- end: {line: 1, column: 19}
+ start: {line: 1, column: 15},
+ end: {line: 1, column: 17}
}
- }],
+ },
+ default: true,
specifiers: null,
source: null,
- range: [0, 19],
+ range: [0, 17],
loc: {
start: {line: 1, column: 0},
- end: {line: 1, column: 19}
+ end: {line: 1, column: 17}
}
}],
- range: [0, 19],
+ range: [0, 17],
loc: {
start: {line: 1, column: 0},
- end: {line: 1, column: 19}
+ end: {line: 1, column: 17}
}
}, {
ecmaVersion: 6,
@@ -5362,36 +5353,7 @@ test("export default = 42", {
locations: true
});
-test("export *", {
- type: "Program",
- body: [{
- type: "ExportDeclaration",
- declaration: null,
- specifiers: [{
- type: "ExportBatchSpecifier",
- range: [7, 8],
- loc: {
- start: {line: 1, column: 7},
- end: {line: 1, column: 8}
- }
- }],
- source: null,
- range: [0, 8],
- loc: {
- start: {line: 1, column: 0},
- end: {line: 1, column: 8}
- }
- }],
- range: [0, 8],
- loc: {
- start: {line: 1, column: 0},
- end: {line: 1, column: 8}
- }
-}, {
- ecmaVersion: 6,
- ranges: true,
- locations: true
-});
+testFail("export *", "Unexpected token (1:8)", {ecmaVersion: 6});
test("export * from \"crypto\"", {
type: "Program",