Keep track of directives while tokenizing

This commit is contained in:
Anthony Van de Gejuchte 2016-05-20 10:25:35 +02:00
parent 27eedbc302
commit e2014eca2a

View File

@ -681,7 +681,9 @@ function parse($TEXT, options) {
in_function : 0, in_function : 0,
in_directives : true, in_directives : true,
in_loop : 0, in_loop : 0,
labels : [] labels : [],
directives : {},
directive_stack : []
}; };
S.token = next(); S.token = next();
@ -738,6 +740,26 @@ function parse($TEXT, options) {
function expect(punc) { return expect_token("punc", punc); }; function expect(punc) { return expect_token("punc", punc); };
function push_directives_stack() {
S.directive_stack.push([]);
S.in_directives = true;
}
function pop_directives_stack() {
var directives = S.directive_stack[S.directive_stack.length - 1];
for (var i = 0; i < directives.length; i++) {
S.directives[directives[i]]--;
}
S.directive_stack.pop();
}
function has_directive(directive) {
return S.directives[directive] !== undefined &&
S.directives[directive] > 0;
}
function can_insert_semicolon() { function can_insert_semicolon() {
return !options.strict && ( return !options.strict && (
S.token.nlb || is("eof") || is("punc", "}") S.token.nlb || is("eof") || is("punc", "}")
@ -780,8 +802,15 @@ function parse($TEXT, options) {
switch (S.token.type) { switch (S.token.type) {
case "string": case "string":
var dir = S.in_directives, stat = simple_statement(); var dir = S.in_directives, stat = simple_statement();
// XXXv2: decide how to fix directives
if (dir && stat.body instanceof AST_String && !is("punc", ",")) { if (dir && stat.body instanceof AST_String && !is("punc", ",")) {
S.directive_stack[S.directive_stack.length - 1].push(stat.body.value);
if (S.directives[stat.body.value] === undefined) {
S.directives[stat.body.value] = 1;
} else {
S.directives[stat.body.value]++;
}
return new AST_Directive({ return new AST_Directive({
start : stat.body.start, start : stat.body.start,
end : stat.body.end, end : stat.body.end,
@ -1009,10 +1038,11 @@ function parse($TEXT, options) {
})(true, []), })(true, []),
body: (function(loop, labels){ body: (function(loop, labels){
++S.in_function; ++S.in_function;
S.in_directives = true; push_directives_stack();
S.in_loop = 0; S.in_loop = 0;
S.labels = []; S.labels = [];
var a = block_(); var a = block_();
pop_directives_stack();
--S.in_function; --S.in_function;
S.in_loop = loop; S.in_loop = loop;
S.labels = labels; S.labels = labels;
@ -1512,8 +1542,10 @@ function parse($TEXT, options) {
return (function(){ return (function(){
var start = S.token; var start = S.token;
var body = []; var body = [];
push_directives_stack();
while (!is("eof")) while (!is("eof"))
body.push(statement()); body.push(statement());
pop_directives_stack();
var end = prev(); var end = prev();
var toplevel = options.toplevel; var toplevel = options.toplevel;
if (toplevel) { if (toplevel) {