Skip to content

Commit

Permalink
fixing up sourcemap line numbering
Browse files Browse the repository at this point in the history
Can now compile the tests with sourcemaps enabled. Line info is now
being updated only at the point of macro expansion a single time.
  • Loading branch information
disnet committed Nov 21, 2013
1 parent bee554a commit 3336448
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 29 deletions.
4 changes: 1 addition & 3 deletions Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,7 @@ module.exports = function(grunt) {
},
test: {
options: {
// bug in source mapping is causing test
// compilation to fail
sourceMap: false
sourceMap: true
},
src: "test/*.js",
dest: "build/"
Expand Down
50 changes: 36 additions & 14 deletions src/expander.js
Original file line number Diff line number Diff line change
Expand Up @@ -805,26 +805,39 @@
};
}

function adjustLineContext (stx, original) {
var last = stx[0] && typeof stx[0].token.range == "undefined" ? original : stx[0];
function adjustLineContext(stx, original, current) {
current = current || {
lastLineNumber: original.token.lineNumber,
lineNumber: original.token.lineNumber - 1
};

return _.map(stx, function(stx) {
if (typeof stx.token.range == "undefined") {
stx.token.range = last.token.range
}
if (stx.token.type === parser.Token.Delimiter) {
stx.token.sm_startLineNumber = original.token.lineNumber;
stx.token.sm_endLineNumber = original.token.lineNumber;
stx.token.sm_startLineStart = original.token.lineStart;
stx.token.sm_endLineStart = original.token.lineStart;
stx.token.sm_startLineNumber = stx.token.sm_startLineNumber || stx.token.startLineNumber;
stx.token.sm_endLineNumber = stx.token.sm_endLineNumber || stx.token.endLineNumber;
stx.token.sm_startLineStart = stx.token.sm_startLineStart || stx.token.startLineStart;
stx.token.sm_endLineStart = stx.token.sm_endLineStart || stx.token.endLineStart;

stx.token.startLineNumber = original.token.lineNumber;

if (stx.token.inner.length > 0) {
stx.token.inner = adjustLineContext(stx.token.inner, original);
stx.token.inner = adjustLineContext(stx.token.inner, original, current);
}
last = stx;
return stx;
}
stx.token.sm_lineNumber = original.token.lineNumber;
stx.token.sm_lineStart = original.token.lineStart;
last = stx;
// Only set the sourcemap line info once. Necessary because a single
// syntax object can go through expansion multiple times. If at some point
// we want to write an expansion stepper this might be a good place to store
// intermediate expansion line info (ie push to a stack instead of
// just write once).
stx.token.sm_lineNumber = stx.token.sm_lineNumber || stx.token.lineNumber;
stx.token.sm_lineStart = stx.token.sm_lineStart || stx.token.lineStart;
stx.token.sm_range = stx.token.sm_range || _.clone(stx.token.range);

// move the line info to line up with the macro name
// (line info starting from the macro name)
stx.token.lineNumber = original.token.lineNumber;

return stx;
});
}
Expand Down Expand Up @@ -1582,6 +1595,9 @@
type: parser.Token.Punctuator,
value: stx.token.value[0],
range: stx.token.startRange,
sm_range: (stx.token.sm_range
? stx.token.sm_range
: stx.token.startRange),
lineNumber: stx.token.startLineNumber,
sm_lineNumber: (stx.token.sm_startLineNumber
? stx.token.sm_startLineNumber
Expand All @@ -1595,6 +1611,9 @@
type: parser.Token.Punctuator,
value: stx.token.value[1],
range: stx.token.endRange,
sm_range: (stx.token.sm_range
? stx.token.sm_range
: stx.token.endRange),
lineNumber: stx.token.endLineNumber,
sm_lineNumber: (stx.token.sm_endLineNumber
? stx.token.sm_endLineNumber
Expand All @@ -1621,6 +1640,9 @@
stx.token.sm_lineStart = stx.token.sm_lineStart
? stx.token.sm_lineStart
: stx.token.lineStart;
stx.token.sm_range = stx.token.sm_range
? stx.token.sm_range
: stx.token.range;
return acc.concat(stx);
}, []);
}
Expand Down
4 changes: 2 additions & 2 deletions src/parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -3381,7 +3381,7 @@ to decide on the correct name for identifiers.
locInfo = {
start: {
line: curr.sm_lineNumber,
column: curr.range[0] - curr.sm_lineStart
column: curr.sm_range[0] - curr.sm_lineStart
}
};

Expand All @@ -3397,7 +3397,7 @@ to decide on the correct name for identifiers.
if (loc) {
locInfo.end = {
line: last.sm_lineNumber,
column: last.range[0] - curr.sm_lineStart
column: last.sm_range[0] - last.sm_lineStart
};
node.loc = locInfo;
}
Expand Down
11 changes: 5 additions & 6 deletions src/patterns.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@
next = syntaxFromToken({
type: parser.Token.Delimiter,
value: to.token.value,
inner: to.token.inner,
inner: takeLineContext(from, to.token.inner),
startRange: from.token.startRange,
endRange: from.token.endRange,
startLineNumber: from.token.startLineNumber,
Expand All @@ -102,7 +102,7 @@
next = syntaxFromToken({
type: parser.Token.Delimiter,
value: to.token.value,
inner: to.token.inner,
inner: takeLineContext(from, to.token.inner),
startRange: from.token.range,
endRange: from.token.range,
startLineNumber: from.token.lineNumber,
Expand Down Expand Up @@ -630,7 +630,7 @@
macroBody);
newBody.token.inner = transcribe(bodyStx.token.inner,
macroNameStx, env);
return acc.concat(takeLineContext(macroNameStx, [newBody]));
return acc.concat([newBody]);
}
if (isPatternVar(bodyStx) &&
Object.prototype.hasOwnProperty.bind(env)(bodyStx.token.value)) {
Expand All @@ -641,10 +641,9 @@
throw new Error("Ellipses level for " + bodyStx.token.value +
" does not match in the template");
}
return acc.concat(takeLineContext(macroNameStx,
env[bodyStx.token.value].match));
return acc.concat(env[bodyStx.token.value].match);
}
return acc.concat(takeLineContext(macroNameStx, [bodyStx]));
return acc.concat([bodyStx]);
}
}, []).value();
}
Expand Down
27 changes: 23 additions & 4 deletions test/test_sourcemaps.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ function run(code, originalLoc) {
describe "source mapping" {
it "should work for a single line" {
var pos = run("var x;", {
// ^
// var x;
// ^
line: 1,
Expand All @@ -44,6 +45,7 @@ describe "source mapping" {

it "should work for multiple lines" {
var pos = run("var x;\nvar y;", {
// ^
// var x;
// var y;
// ^
Expand All @@ -57,24 +59,41 @@ describe "source mapping" {

it "should work with a simple rule macro" {
var pos = run("macro id { rule { $x } => { $x }}\nid 42;", {
// ^
// 42;
// ^
line: 1,
column:0
});

expect(pos.line).to.be(2);
expect(pos.column).to.be(0);
expect(pos.column).to.be(3);
}

it "should work with a case macro" {
var pos = run("macro m {\ncase {_ } => {\nreturn withSyntax($y = [makeValue(42, #{here})]) {\n return #{$y}\n}\n}\n}\nm;", {
var pos = run("macro m {case {_ } => {return withSyntax($y = [makeValue(42, #{here})]) { return #{$y}}}}\nm;", {
// ^
// 42
// ^
line: 1,
column: 0
});

expect(pos.line).to.be(8);
expect(pos.column).to.be(0);
expect(pos.line).to.be(1);
expect(pos.column).to.be(63);
}

it "should work with nested delimiters in a macro expansion" {
var pos = run("macro m {case{_} => {return #{[[42]]}}}\nm", {
// ^
// [[42]]
// ^
line: 1,
column: 2
});

expect(pos.line).to.be(1);
expect(pos.column).to.be(32);
}


Expand Down

0 comments on commit 3336448

Please sign in to comment.