Update AST location info to match SpiderMonkey

Part of #889
This commit is contained in:
kpdecker
2014-11-26 09:01:03 -06:00
parent 3a9440f954
commit 61dd721ca2
9 changed files with 94 additions and 93 deletions
+14 -22
View File
@@ -1,16 +1,8 @@
import Exception from "../exception";
function LocationInfo(locInfo) {
locInfo = locInfo || {};
this.firstLine = locInfo.first_line;
this.firstColumn = locInfo.first_column;
this.lastColumn = locInfo.last_column;
this.lastLine = locInfo.last_line;
}
var AST = {
ProgramNode: function(statements, blockParams, strip, locInfo) {
LocationInfo.call(this, locInfo);
this.loc = locInfo;
this.type = "program";
this.statements = statements;
this.blockParams = blockParams;
@@ -18,7 +10,7 @@ var AST = {
},
MustacheNode: function(rawParams, hash, open, strip, locInfo) {
LocationInfo.call(this, locInfo);
this.loc = locInfo;
this.type = "mustache";
this.strip = strip;
@@ -47,7 +39,7 @@ var AST = {
},
SexprNode: function(rawParams, hash, locInfo) {
LocationInfo.call(this, locInfo);
this.loc = locInfo;
this.type = "sexpr";
this.hash = hash;
@@ -70,7 +62,7 @@ var AST = {
},
PartialNode: function(partialName, context, hash, strip, locInfo) {
LocationInfo.call(this, locInfo);
this.loc = locInfo;
this.type = "partial";
this.partialName = partialName;
this.context = context;
@@ -81,7 +73,7 @@ var AST = {
},
BlockNode: function(sexpr, program, inverse, strip, locInfo) {
LocationInfo.call(this, locInfo);
this.loc = locInfo;
this.type = 'block';
this.sexpr = sexpr;
@@ -95,19 +87,19 @@ var AST = {
},
ContentNode: function(string, locInfo) {
LocationInfo.call(this, locInfo);
this.loc = locInfo;
this.type = "content";
this.original = this.string = string;
},
HashNode: function(pairs, locInfo) {
LocationInfo.call(this, locInfo);
this.loc = locInfo;
this.type = "hash";
this.pairs = pairs;
},
IdNode: function(parts, locInfo) {
LocationInfo.call(this, locInfo);
this.loc = locInfo;
this.type = "ID";
var original = "",
@@ -147,13 +139,13 @@ var AST = {
},
PartialNameNode: function(name, locInfo) {
LocationInfo.call(this, locInfo);
this.loc = locInfo;
this.type = "PARTIAL_NAME";
this.name = name.original;
},
DataNode: function(id, locInfo) {
LocationInfo.call(this, locInfo);
this.loc = locInfo;
this.type = "DATA";
this.id = id;
this.stringModeValue = id.stringModeValue;
@@ -161,7 +153,7 @@ var AST = {
},
StringNode: function(string, locInfo) {
LocationInfo.call(this, locInfo);
this.loc = locInfo;
this.type = "STRING";
this.original =
this.string =
@@ -169,7 +161,7 @@ var AST = {
},
NumberNode: function(number, locInfo) {
LocationInfo.call(this, locInfo);
this.loc = locInfo;
this.type = "NUMBER";
this.original =
this.number = number;
@@ -177,14 +169,14 @@ var AST = {
},
BooleanNode: function(bool, locInfo) {
LocationInfo.call(this, locInfo);
this.loc = locInfo;
this.type = "BOOLEAN";
this.bool = bool;
this.stringModeValue = bool === "true";
},
CommentNode: function(comment, strip, locInfo) {
LocationInfo.call(this, locInfo);
this.loc = locInfo;
this.type = "comment";
this.comment = comment;
+6 -1
View File
@@ -8,11 +8,16 @@ export { parser };
var yy = {};
extend(yy, Helpers, AST);
export function parse(input) {
export function parse(input, options) {
// Just return if an already-compile AST was passed in.
if (input.constructor === AST.ProgramNode) { return input; }
parser.yy = yy;
// Altering the shared object here, but this is ok as parser is a sync operation
yy.locInfo = function(locInfo) {
return new yy.SourceLocation(options && options.srcName, locInfo);
};
return parser.parse(input);
}
+4 -4
View File
@@ -79,18 +79,18 @@ CodeGen.prototype = {
},
empty: function(loc) {
loc = loc || this.currentLocation || {};
return new SourceNode(loc.firstLine, loc.firstColumn, this.srcFile);
loc = loc || this.currentLocation || {start:{}};
return new SourceNode(loc.start.line, loc.start.column, this.srcFile);
},
wrap: function(chunk, loc) {
if (chunk instanceof SourceNode) {
return chunk;
}
loc = loc || this.currentLocation || {};
loc = loc || this.currentLocation || {start:{}};
chunk = castChunk(chunk, this, loc);
return new SourceNode(loc.firstLine, loc.firstColumn, this.srcFile, chunk);
return new SourceNode(loc.start.line, loc.start.column, this.srcFile, chunk);
},
functionCall: function(fn, type, params) {
+3 -7
View File
@@ -298,11 +298,7 @@ Compiler.prototype = {
// HELPERS
opcode: function(name, node) {
var loc = {
firstLine: node.firstLine, firstColumn: node.firstColumn,
lastLine: node.lastLine, lastColumn: node.lastColumn
};
this.opcodes.push({ opcode: name, args: slice.call(arguments, 2), loc: loc });
this.opcodes.push({ opcode: name, args: slice.call(arguments, 2), loc: node.loc });
},
addDepth: function(depth) {
@@ -393,7 +389,7 @@ export function precompile(input, options, env) {
options.useDepths = true;
}
var ast = env.parse(input);
var ast = env.parse(input, options);
var environment = new env.Compiler().compile(ast, options);
return new env.JavaScriptCompiler().compile(environment, options);
}
@@ -415,7 +411,7 @@ export function compile(input, options, env) {
var compiled;
function compileInput() {
var ast = env.parse(input);
var ast = env.parse(input, options);
var environment = new env.Compiler().compile(ast, options);
var templateSpec = new env.JavaScriptCompiler().compile(environment, options, undefined, true);
return env.template(templateSpec);
+14 -8
View File
@@ -1,5 +1,17 @@
import Exception from "../exception";
export function SourceLocation(source, locInfo) {
this.source = source;
this.start = {
line: locInfo.first_line,
column: locInfo.first_column
};
this.end = {
line: locInfo.last_line,
column: locInfo.last_column
};
}
export function stripFlags(open, close) {
return {
left: open.charAt(2) === '~',
@@ -15,10 +27,7 @@ export function stripComment(comment) {
export function prepareRawBlock(openRawBlock, content, close, locInfo) {
/*jshint -W040 */
if (openRawBlock.sexpr.id.original !== close) {
var errorNode = {
firstLine: openRawBlock.sexpr.firstLine,
firstColumn: openRawBlock.sexpr.firstColumn
};
var errorNode = {loc: openRawBlock.sexpr.loc};
throw new Exception(openRawBlock.sexpr.id.original + " doesn't match " + close, errorNode);
}
@@ -32,10 +41,7 @@ export function prepareBlock(openBlock, program, inverseAndProgram, close, inver
/*jshint -W040 */
// When we are chaining inverse calls, we will not have a close path
if (close && close.path && openBlock.sexpr.id.original !== close.path.original) {
var errorNode = {
firstLine: openBlock.sexpr.firstLine,
firstColumn: openBlock.sexpr.firstColumn
};
var errorNode = {loc: openBlock.sexpr.loc};
throw new Exception(openBlock.sexpr.id.original + ' doesn\'t match ' + close.path.original, errorNode);
}
@@ -136,7 +136,7 @@ JavaScriptCompiler.prototype = {
if (!asObject) {
ret.compiler = JSON.stringify(ret.compiler);
this.source.currentLocation = {firstLine: 1, firstColumn: 0};
this.source.currentLocation = {start: {line: 1, column: 0}};
ret = this.objectLiteral(ret);
if (options.srcName) {
+9 -6
View File
@@ -2,11 +2,14 @@
var errorProps = ['description', 'fileName', 'lineNumber', 'message', 'name', 'number', 'stack'];
function Exception(message, node) {
var line;
if (node && node.firstLine) {
line = node.firstLine;
var loc = node && node.loc,
line,
column;
if (loc) {
line = loc.start.line;
column = loc.start.column;
message += ' - ' + line + ':' + node.firstColumn;
message += ' - ' + line + ':' + column;
}
var tmp = Error.prototype.constructor.call(this, message);
@@ -16,9 +19,9 @@ function Exception(message, node) {
this[errorProps[idx]] = tmp[errorProps[idx]];
}
if (line) {
if (loc) {
this.lineNumber = line;
this.column = node.firstColumn;
this.column = column;
}
}