Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Segment ending column confusion

68 views
Skip to first unread message

Simon Lydell

unread,
Jan 24, 2014, 2:32:03 PM1/24/14
to dev-js-s...@lists.mozilla.org
According to a comment in the source map spec by John Lenz (Oct 19,
2012), “the ending column is the start of the next segment **or the end
of the line**” (emphasis mine). However, a source map can’t know where
line endings are, can it? So shouldn’t that be "the ending column is the
start of the next segment (or the end of the file)"?

Brian Slesinsky

unread,
Jan 24, 2014, 3:18:33 PM1/24/14
to Simon Lydell, dev-js-s...@lists.mozilla.org
No, it really does extend to the end of the line.

It can be a bit inconvenient if you're representing a range as a pair of
(line, column) positions. I found it easier to use the first column of the
next line as the ending position. (That is, include the newline character
in the range and consider the range to stop just before the second position
in the pair). The spec doesn't explicitly say whether the newline is
included, but it doesn't seem to matter in practice.

If you want to convert (line, column) pairs to byte offsets or determine
the length of a range, you're going to need the JavaScript source code to
get the line endings.

- Brian
> _______________________________________________
> dev-js-sourcemap mailing list
> dev-js-s...@lists.mozilla.org
> https://lists.mozilla.org/listinfo/dev-js-sourcemap
>

Simon Lydell

unread,
Jan 25, 2014, 2:29:08 AM1/25/14
to Brian Slesinsky, dev-js-s...@lists.mozilla.org
Thanks for clarifying. I think I understand now.

So when you query a source map for the original location for line L, column C, it will look for a mapping with the same line L and a column X, such that X≤C and X is as large as possible. If it finds such a mapping it returns the corresponding line and column from the source file. Is this correct?

Simon Lydell

unread,
Jan 25, 2014, 4:21:39 AM1/25/14
to Brian Slesinsky, dev-js-s...@lists.mozilla.org
But what about querying the other way around – from original to generated code? An example:

CoffeeScript has multi-line strings. The compilation of a multi-line string is one line of JavaScript. Then it makes sense to put a mapping from the start of the compiled string to the start of the multi line string, doesn't it? Then any character in the compiled string maps back to the start of the multi line string, which makes sense to me.

However, if you'd like to go from line 2 of the multi line string to the compiled string, you can't because that line has no mapping. I'd expect to be taken to the beginning of the compiled string. One could argue that you should add one mapping to every line of the multi line string from the corresponding point in the compiled string – but is it really worth the extra complexity in the compiler? Or is this not an issue at all, since we usually just query from generated to original and not the other way around?

Simon Lydell

unread,
Jan 28, 2014, 3:23:08 PM1/28/14
to dev-js-s...@lists.mozilla.org
The reason why I started talking about going from source to compiled is because I tested the mozilla/source-map module. It let's you go both from compiled to source, and the other way around. It does not comply with the spec when going from compiled to source: It does not consider mappings to end at the end of the line. Instead it thinks mappings always go on to the next mapping. Then the question is if it complies with the spec when going from source to compiled. I thought about that the last days. Here is my conclusion:

In that case, there is no spec to follow, right? The spec only defines the use case of going from compiled to source. The mozilla/source-map module does let you go the other way, too, if you wish. Fine. Let it do so. And let mappings go over EOLs in that case, since it is useful.

Is that sensible?

Brian Slesinsky

unread,
Jan 28, 2014, 4:05:25 PM1/28/14
to Simon Lydell, dev-js-s...@lists.mozilla.org
Technically the mapping is from a range of JavaScript to a position in the
source file (line number and column). If you're going in the other
direction, there may not be a mapping for a source position, so instead you
need to find the closest position. I don't think there's any standard for
this.
Typically in a debugger, you set breakpoints on lines, not positions, so
searching forward on the same line until you find a mapped position makes
sense. If there's no position on the same line as the breakpoint then in
the debugger UI, you could disallow setting a breakpoint on that line.

(Chrome just keeps a reverse mapping from source line numbers to JavaScript
ranges and throws away the source column. [1] It doesn't seem to do
anything special to resolve conflicts when multiple JavaScript ranges map
to the same source line; the policy seems to be that the first mapping it
sees wins. This is likely to be the first position if the JavaScript ranges
for any single line are in the same order as the source code.)

In the example of a source-language statement that spans multiple lines and
maps to a single JavaScript statement, ideally the compiler would output a
single mapping from the entire JavaScript statement to the start of the
first line of the corresponding statement in the source file. However,
compilers aren't consistent about this and it can make setting breakpoints
a bit flaky at times. For some examples of flakiness see my GWT.create
presentation. [2]

- Brian

[1]
https://code.google.com/p/chromium/codesearch#chromium/src/third_party/WebKit/Source/devtools/front_end/SourceMap.js&q=Sourcemap.js&sq=package:chromium&l=275
[2]
https://docs.google.com/a/google.com/presentation/d/1DTWZ_06dQsTPhinIwzHSdoPMndRr92wpZoZWicK97YQ/edit#slide=id.g257376c54_0261
0 new messages