fix Runtime error reports from imported files

This commit is contained in:
Alexis Sellier
2012-01-11 00:55:14 +01:00
parent 2cc1b018fe
commit aefd310514
5 changed files with 35 additions and 20 deletions

View File

@@ -110,7 +110,7 @@ less.Parser.importer = function (file, paths, callback) {
paths: [path.dirname(pathname)].concat(paths),
filename: pathname
}).parse(data, function (e, root) {
callback(e, root);
callback(e, root, data);
});
});
} else {

View File

@@ -73,6 +73,7 @@ less.Parser = function Parser(env) {
paths: env && env.paths || [], // Search paths, when importing
queue: [], // Files which haven't been imported yet
files: {}, // Holds the imported parse trees
contents: {}, // Holds the imported file contents
mime: env && env.mime, // MIME type of .less files
error: null, // Error in parsing/evaluating an import
push: function (path, callback) {
@@ -82,9 +83,10 @@ less.Parser = function Parser(env) {
//
// Import a file asynchronously
//
less.Parser.importer(path, this.paths, function (e, root) {
less.Parser.importer(path, this.paths, function (e, root, contents) {
that.queue.splice(that.queue.indexOf(path), 1); // Remove the path from the queue
that.files[path] = root; // Store the root
that.contents[path] = contents;
if (e && !that.error) { that.error = e }
callback(e, root);
@@ -189,7 +191,15 @@ less.Parser = function Parser(env) {
}
}
function getLocation(index) {
function getInput(e, env) {
if (e.filename && env.filename && (e.filename !== env.filename)) {
return parser.imports.contents[e.filename];
} else {
return input;
}
}
function getLocation(index, input) {
for (var n = index, column = -1;
n >= 0 && input.charAt(n) !== '\n';
n--) { column++ }
@@ -199,18 +209,19 @@ less.Parser = function Parser(env) {
}
function LessError(e, env) {
var lines = input.split('\n'),
loc = getLocation(e.index),
var input = getInput(e, env),
loc = getLocation(e.index, input),
line = loc.line,
col = loc.column;
col = loc.column,
lines = input.split('\n');
this.type = e.type || 'SyntaxError';
this.type = e.type || 'Syntax';
this.message = e.message;
this.filename = e.filename || env.filename;
this.index = e.index;
this.line = typeof(line) === 'number' ? line + 1 : null;
this.callLine = e.call && (getLocation(e.call) + 1);
this.callExtract = lines[getLocation(e.call)];
this.callLine = e.call && (getLocation(e.call, input) + 1);
this.callExtract = lines[getLocation(e.call, input)];
this.stack = e.stack;
this.column = col;
this.extract = [
@@ -559,7 +570,7 @@ less.Parser = function Parser(env) {
if (! $(')')) return;
if (name) { return new(tree.Call)(name, args, index) }
if (name) { return new(tree.Call)(name, args, index, env.filename) }
},
arguments: function () {
var args = [], arg;
@@ -635,7 +646,7 @@ less.Parser = function Parser(env) {
var name, index = i;
if (input.charAt(i) === '@' && (name = $(/^@@?[\w-]+/))) {
return new(tree.Variable)(name, index);
return new(tree.Variable)(name, index, env.filename);
}
},
@@ -746,7 +757,7 @@ less.Parser = function Parser(env) {
}
if (elements.length > 0 && ($(';') || peek('}'))) {
return new(tree.mixin.Call)(elements, args, index, important);
return new(tree.mixin.Call)(elements, args, index, env.filename, important);
}
},

View File

@@ -3,10 +3,11 @@
//
// A function call node.
//
tree.Call = function (name, args, index) {
tree.Call = function (name, args, index, filename) {
this.name = name;
this.args = args;
this.index = index;
this.filename = filename;
};
tree.Call.prototype = {
//
@@ -31,7 +32,7 @@ tree.Call.prototype = {
throw { type: e.type || "Runtime",
message: "error evaluating function `" + this.name + "`" +
(e.message ? ': ' + e.message : ''),
index: this.index };
index: this.index, filename: this.filename };
}
} else { // 2.
return new(tree.Anonymous)(this.name +

View File

@@ -1,10 +1,11 @@
(function (tree) {
tree.mixin = {};
tree.mixin.Call = function (elements, args, index, important) {
tree.mixin.Call = function (elements, args, index, filename, important) {
this.selector = new(tree.Selector)(elements);
this.arguments = args;
this.index = index;
this.filename = filename;
this.important = important;
};
tree.mixin.Call.prototype = {
@@ -21,7 +22,7 @@ tree.mixin.Call.prototype = {
rules, mixins[m].eval(env, this.arguments, this.important).rules);
match = true;
} catch (e) {
throw { message: e.message, index: e.index, stack: e.stack, call: this.index };
throw { message: e.message, index: e.index, filename: this.filename, stack: e.stack, call: this.index };
}
}
}
@@ -34,13 +35,13 @@ tree.mixin.Call.prototype = {
this.arguments.map(function (a) {
return a.toCSS();
}).join(', ') + ")`",
index: this.index };
index: this.index, filename: this.filename };
}
}
}
throw { type: 'Name',
message: this.selector.toCSS().trim() + " is undefined",
index: this.index };
index: this.index, filename: this.filename };
}
};

View File

@@ -1,6 +1,6 @@
(function (tree) {
tree.Variable = function (name, index) { this.name = name, this.index = index };
tree.Variable = function (name, index, file) { this.name = name, this.index = index, this.file = file };
tree.Variable.prototype = {
eval: function (env) {
var variable, v, name = this.name;
@@ -15,7 +15,9 @@ tree.Variable.prototype = {
}
})) { return variable }
else {
throw { message: "variable " + name + " is undefined",
throw { type: 'Name',
message: "variable " + name + " is undefined",
filename: this.file,
index: this.index };
}
}