add directives property to Program and BlockStatement

This commit is contained in:
Sebastian McKenzie 2015-09-15 06:16:07 +01:00
parent 5ea5d47d7f
commit dae16fa192
2 changed files with 42 additions and 29 deletions

View File

@ -13,18 +13,8 @@ const pp = Parser.prototype;
pp.parseTopLevel = function (file, program) { pp.parseTopLevel = function (file, program) {
program.sourceType = this.options.sourceType; program.sourceType = this.options.sourceType;
program.body = [];
let first = true; this.parseBlockBody(program, true, tt.eof);
while (!this.match(tt.eof)) {
let stmt = this.parseStatement(true, true);
program.body.push(stmt);
if (first) {
if (this.isUseStrict(stmt)) this.setStrict(true);
first = false;
}
}
this.next();
file.program = this.finishNode(program, "Program"); file.program = this.finishNode(program, "Program");
file.comments = this.state.comments; file.comments = this.state.comments;
@ -35,6 +25,16 @@ pp.parseTopLevel = function (file, program) {
const loopLabel = {kind: "loop"}, switchLabel = {kind: "switch"}; const loopLabel = {kind: "loop"}, switchLabel = {kind: "switch"};
// TODO
pp.parseDirective = function () {
let node = this.startNode();
node.raw = this.input.slice(this.state.start, this.state.end);
node.value = node.raw.slice(1, -1); // remove quotes
this.next();
return this.finishNode(node, "Directive");
};
// Parse a single statement. // Parse a single statement.
// //
// If expecting a statement and finding a slash operator, parse a // If expecting a statement and finding a slash operator, parse a
@ -415,22 +415,41 @@ pp.parseExpressionStatement = function (node, expr) {
// function bodies). // function bodies).
pp.parseBlock = function (allowStrict) { pp.parseBlock = function (allowStrict) {
let node = this.startNode(), first = true, oldStrict; let node = this.startNode();
node.body = [];
this.expect(tt.braceL); this.expect(tt.braceL);
while (!this.eat(tt.braceR)) { this.parseBlockBody(node, allowStrict, tt.braceR);
let stmt = this.parseStatement(true);
node.body.push(stmt);
if (first && allowStrict && this.isUseStrict(stmt)) {
oldStrict = this.state.strict;
this.setStrict(this.state.strict = true);
}
first = false;
}
if (oldStrict === false) this.setStrict(false);
return this.finishNode(node, "BlockStatement"); return this.finishNode(node, "BlockStatement");
}; };
// TODO
pp.parseBlockBody = function (node, allowStrict, end) {
node.body = [];
node.directives = [];
let parsedNonDirective = false;
let oldStrict;
while (!this.eat(end)) {
if (!parsedNonDirective && this.match(tt.string)) {
let stmt = this.parseDirective();
node.directives.push(stmt);
if (allowStrict && stmt.value === "use strict") {
oldStrict = this.state.strict;
this.setStrict(this.state.strict = true);
}
} else {
parsedNonDirective = true;
node.body.push(this.parseStatement(true));
}
}
if (oldStrict === false) {
this.setStrict(false);
}
};
// Parse a regular `for` loop. The disambiguation code in // Parse a regular `for` loop. The disambiguation code in
// `parseStatement` will already have parsed the init statement or // `parseStatement` will already have parsed the init statement or
// expression. // expression.

View File

@ -6,12 +6,6 @@ const pp = Parser.prototype;
// ## Parser utilities // ## Parser utilities
// Test whether a statement node is the string literal `"use strict"`.
pp.isUseStrict = function (stmt) {
return stmt.type === "ExpressionStatement" && stmt.expression.type === "StringLiteral" && stmt.expression.raw.slice(1, -1) === "use strict";
};
// TODO // TODO
pp.isRelational = function (op) { pp.isRelational = function (op) {