michael@0: load(libdir + "match.js"); michael@0: load(libdir + "asserts.js"); michael@0: michael@0: var { Pattern, MatchError } = Match; michael@0: michael@0: program = (elts) => Pattern({ michael@0: type: "Program", michael@0: body: elts michael@0: }) michael@0: exportDeclaration = (declaration, specifiers, source) => Pattern({ michael@0: type: "ExportDeclaration", michael@0: declaration: declaration, michael@0: specifiers: specifiers, michael@0: source: source michael@0: }); michael@0: exportSpecifier = (id, name) => Pattern({ michael@0: type: "ExportSpecifier", michael@0: id: id, michael@0: name: name michael@0: }); michael@0: exportBatchSpecifier = () => Pattern({ michael@0: type: "ExportBatchSpecifier" michael@0: }); michael@0: blockStatement = (body) => Pattern({ michael@0: type: "BlockStatement", michael@0: body: body michael@0: }); michael@0: functionDeclaration = (id, params, body) => Pattern({ michael@0: type: "FunctionDeclaration", michael@0: id: id, michael@0: params: params, michael@0: defaults: [], michael@0: body: body, michael@0: rest: null, michael@0: generator: false michael@0: }); michael@0: variableDeclaration = (decls) => Pattern({ michael@0: type: "VariableDeclaration", michael@0: kind: "var", michael@0: declarations: decls michael@0: }); michael@0: constDeclaration = (decls) => Pattern({ michael@0: type: "VariableDeclaration", michael@0: kind: "const", michael@0: declarations: decls michael@0: }); michael@0: letDeclaration = (decls) => Pattern({ michael@0: type: "VariableDeclaration", michael@0: kind: "let", michael@0: declarations: decls michael@0: }); michael@0: ident = (name) => Pattern({ michael@0: type: "Identifier", michael@0: name: name michael@0: }); michael@0: lit = (val) => Pattern({ michael@0: type: "Literal", michael@0: value: val michael@0: }); michael@0: michael@0: program([ michael@0: exportDeclaration( michael@0: null, michael@0: [], michael@0: null michael@0: ) michael@0: ]).assert(Reflect.parse("export {}")); michael@0: michael@0: program([ michael@0: exportDeclaration( michael@0: null, michael@0: [ michael@0: exportSpecifier( michael@0: ident("a"), michael@0: ident("a") michael@0: ) michael@0: ], michael@0: null michael@0: ) michael@0: ]).assert(Reflect.parse("export { a }")); michael@0: michael@0: program([ michael@0: exportDeclaration( michael@0: null, michael@0: [ michael@0: exportSpecifier( michael@0: ident("a"), michael@0: ident("b") michael@0: ) michael@0: ], michael@0: null michael@0: ) michael@0: ]).assert(Reflect.parse("export { a as b }")); michael@0: michael@0: program([ michael@0: exportDeclaration( michael@0: null, michael@0: [ michael@0: exportSpecifier( michael@0: ident("as"), michael@0: ident("as") michael@0: ) michael@0: ], michael@0: null michael@0: ) michael@0: ]).assert(Reflect.parse("export { as as as }")); michael@0: michael@0: program([ michael@0: exportDeclaration( michael@0: null, michael@0: [ michael@0: exportSpecifier( michael@0: ident("a"), michael@0: ident("true") michael@0: ) michael@0: ], michael@0: null michael@0: ) michael@0: ]).assert(Reflect.parse("export { a as true }")); michael@0: michael@0: program([ michael@0: exportDeclaration( michael@0: null, michael@0: [ michael@0: exportSpecifier( michael@0: ident("a"), michael@0: ident("a") michael@0: ), michael@0: exportSpecifier( michael@0: ident("b"), michael@0: ident("b") michael@0: ), michael@0: ], michael@0: null michael@0: ) michael@0: ]).assert(Reflect.parse("export { a, b }")); michael@0: michael@0: program([ michael@0: exportDeclaration( michael@0: null, michael@0: [ michael@0: exportSpecifier( michael@0: ident("a"), michael@0: ident("b") michael@0: ), michael@0: exportSpecifier( michael@0: ident("c"), michael@0: ident("d") michael@0: ), michael@0: ], michael@0: null michael@0: ) michael@0: ]).assert(Reflect.parse("export { a as b, c as d }")); michael@0: michael@0: program([ michael@0: exportDeclaration( michael@0: null, michael@0: [ michael@0: exportBatchSpecifier() michael@0: ], michael@0: null michael@0: ) michael@0: ]).assert(Reflect.parse("export *")); michael@0: michael@0: program([ michael@0: exportDeclaration( michael@0: null, michael@0: [ michael@0: exportBatchSpecifier() michael@0: ], michael@0: lit("a") michael@0: ) michael@0: ]).assert(Reflect.parse("export * from 'a'")); michael@0: michael@0: program([ michael@0: exportDeclaration( michael@0: functionDeclaration( michael@0: ident("f"), michael@0: [], michael@0: blockStatement([]) michael@0: ), michael@0: null, michael@0: null michael@0: ) michael@0: ]).assert(Reflect.parse("export function f() {}")); michael@0: michael@0: program([ michael@0: exportDeclaration( michael@0: variableDeclaration([ michael@0: { michael@0: id: ident("a"), michael@0: init: lit(1) michael@0: }, { michael@0: id: ident("b"), michael@0: init: lit(2) michael@0: } michael@0: ]), michael@0: null, michael@0: null michael@0: ) michael@0: ]).assert(Reflect.parse("export var a = 1, b = 2;")); michael@0: michael@0: program([ michael@0: exportDeclaration( michael@0: constDeclaration([ michael@0: { michael@0: id: ident("a"), michael@0: init: lit(1) michael@0: }, { michael@0: id: ident("b"), michael@0: init: lit(2) michael@0: } michael@0: ]), michael@0: null, michael@0: null michael@0: ) michael@0: ]).assert(Reflect.parse("export const a = 1, b = 2;")); michael@0: michael@0: // FIXME: In scripts, top level lets are converted back to vars. Fix this when michael@0: // we implement compiling scripts as modules. michael@0: program([ michael@0: exportDeclaration( michael@0: variableDeclaration([ michael@0: { michael@0: id: ident("a"), michael@0: init: lit(1) michael@0: }, { michael@0: id: ident("b"), michael@0: init: lit(2) michael@0: } michael@0: ]), michael@0: null, michael@0: null michael@0: ) michael@0: ]).assert(Reflect.parse("export let a = 1, b = 2;")); michael@0: michael@0: // NOTE: binding lists are treated as if they were let declarations by esprima, michael@0: // so we follow that convention. michael@0: program([ michael@0: exportDeclaration( michael@0: variableDeclaration([ michael@0: { michael@0: id: ident("a"), michael@0: init: lit(1) michael@0: }, { michael@0: id: ident("b"), michael@0: init: lit(2) michael@0: } michael@0: ]), michael@0: null, michael@0: null michael@0: ) michael@0: ]).assert(Reflect.parse("export a = 1, b = 2;")); michael@0: michael@0: var loc = Reflect.parse("export { a as b } from 'c'", { michael@0: loc: true michael@0: }).body[0].loc; michael@0: michael@0: assertEq(loc.start.line, 1); michael@0: assertEq(loc.start.column, 0); michael@0: assertEq(loc.start.line, 1); michael@0: assertEq(loc.end.column, 26); michael@0: michael@0: assertThrowsInstanceOf(function () { michael@0: Reflect.parse("function f() { export a }"); michael@0: }, SyntaxError); michael@0: michael@0: assertThrowsInstanceOf(function () { michael@0: Reflect.parse("if (true) export a"); michael@0: }, SyntaxError); michael@0: michael@0: assertThrowsInstanceOf(function() { michael@0: Reflect.parse("export {"); michael@0: }, SyntaxError); michael@0: michael@0: assertThrowsInstanceOf(function() { michael@0: Reflect.parse("export {} from"); michael@0: }, SyntaxError); michael@0: michael@0: assertThrowsInstanceOf(function() { michael@0: Reflect.parse("export {,} from 'a'"); michael@0: }, SyntaxError); michael@0: michael@0: assertThrowsInstanceOf(function() { michael@0: Reflect.parse("export { true as a } from 'b'"); michael@0: }, SyntaxError); michael@0: michael@0: assertThrowsInstanceOf(function () { michael@0: Reflect.parse("export { a } from 'b' f();"); michael@0: }, SyntaxError); michael@0: michael@0: assertThrowsInstanceOf(function () { michael@0: Reflect.parse("export * from 'b' f();"); michael@0: }, SyntaxError); michael@0: michael@0: assertThrowsInstanceOf(function() { michael@0: Reflect.parse("export {}\nfrom ()"); michael@0: }, SyntaxError);