implement n level back-tracking and then don't absorb a parenthesis, fixing both issues with 2 new test cases

This commit is contained in:
Luke Page
2014-02-12 23:10:52 +00:00
parent e3168e3434
commit e3576b9c01
3 changed files with 30 additions and 7 deletions

View File

@@ -43,9 +43,7 @@ less.Parser = function Parser(env) {
var input, // LeSS input string
i, // current index in `input`
j, // current chunk
temp, // temporarily holds a chunk's state, for backtracking
memo, // temporarily holds `i`, when backtracking
memoChunk, // `j`
saveStack = [], // holds state for backtracking
furthest, // furthest index the parser has gone to
chunks, // chunkified input
current, // current chunk
@@ -112,8 +110,9 @@ less.Parser = function Parser(env) {
}
};
function save() { temp = current; memo = currentPos = i; memoChunk = j; }
function restore() { current = temp; currentPos = i = memo; j = memoChunk; }
function save() { currentPos = i; saveStack.push( { current: current, i: i, j: j }); }
function restore() { var state = saveStack.pop(); current = state.current; currentPos = i = state.i; j = state.j; }
function forget() { saveStack.pop(); }
function sync() {
if (i > currentPos) {
@@ -1126,6 +1125,7 @@ less.Parser = function Parser(env) {
}
if (parsers.end()) {
forget();
return new(tree.mixin.Call)(elements, args, index, env.currentFileInfo, important);
}
}
@@ -1297,6 +1297,7 @@ less.Parser = function Parser(env) {
ruleset = parsers.block();
if (ruleset) {
forget();
return new(tree.mixin.Definition)(name, params, ruleset, cond, variadic);
} else {
restore();
@@ -1364,10 +1365,16 @@ less.Parser = function Parser(env) {
this.entities.variableCurly();
if (! e) {
save();
if ($char('(')) {
if ((v = this.selector()) && $char(')')) {
e = new(tree.Paren)(v);
forget();
} else {
restore();
}
} else {
forget();
}
}
@@ -1508,6 +1515,7 @@ less.Parser = function Parser(env) {
}
if (selectors && (rules = this.block())) {
forget();
var ruleset = new(tree.Ruleset)(selectors, rules, env.strictImports);
if (env.dumpLineNumbers) {
ruleset.debugInfo = debugInfo;
@@ -1520,7 +1528,7 @@ less.Parser = function Parser(env) {
}
},
rule: function (tryAnonymous) {
var name, value, c = input.charAt(i), important, merge, isVariable;
var name, value, startOfRule = i, c = input.charAt(startOfRule), important, merge, isVariable;
save();
if (c === '.' || c === '#' || c === '&') { return; }
@@ -1549,7 +1557,7 @@ less.Parser = function Parser(env) {
}
if (value && this.end()) {
return new (tree.Rule)(name, value, important, merge, memo, env.currentFileInfo);
return new (tree.Rule)(name, value, important, merge, startOfRule, env.currentFileInfo);
} else {
furthest = i;
restore();
@@ -1557,6 +1565,8 @@ less.Parser = function Parser(env) {
return this.rule(true);
}
}
} else {
forget();
}
},
anonymousValue: function () {
@@ -1590,6 +1600,7 @@ less.Parser = function Parser(env) {
if (dir && (path = this.entities.quoted() || this.entities.url())) {
features = this.mediaFeatures();
if ($char(';')) {
forget();
features = features && new(tree.Value)(features);
return new(tree.Import)(path, features, options, index, env.currentFileInfo);
}
@@ -1790,6 +1801,7 @@ less.Parser = function Parser(env) {
}
if (rules || (!hasBlock && value && $char(';'))) {
forget();
return new(tree.Directive)(name, value, rules, index, env.currentFileInfo,
env.dumpLineNumbers ? getDebugInfo(index, input, env) : null);
}