Awesome!
This is exactly the type of problem I was talking about solving in
http://fitzgeraldnick.com/weblog/55/
From what I've seen, the JS code generated by the TypeScript compiler
is pretty similar to the original TypeScript source. Because of that, it
may be tempting to take shortcuts that gloss over some details that
other compilers doing more extreme transformations (such as emscripten)
will have to deal with, but TypeScript doesn't. At first glance, I don't
see anything jumping out at me other than the object fields that Brian
brought up, but this is something we need to be vigilant about.
Let's definitely do this, but let's make sure we do this Right(tm) :)
Still going over this, but I have some questions:
* Why repeat starting line/column in the scope when that data is almost
assuredly already encoded in an existing mapping? Instead, can this
reference a start mapping (via an index into the mappings) on which the
scope begins?
* This isn't spelled out explicitly, but it seems that the locals data
is parallel to the scopes data, right? As in, the first scope's locals
are in the first segment in x_ms_locals, and the second scope's locals
are in the second segment of x_ms_locals, etc... One thing we didn't
originally do, but would be incredibly valuable moving forward would be
to specify algorithms for using the data, rather than just describing
the format of the encoded data. Would love to see the algorithm for this
here.
* In x_ms_locals, the second field is "a base 64 VLQ relative to the
first field in this segment." Why relative to the first field? Why not
relative to the last value? It seems like the latter would save more
space, but maybe I'm wrong?
* In x_ms_locals, the second field "is an identifier or expression for
the scope". Do you mean it is an identifier or expression to evaluate to
get the value of the given local binding? The wording would lead to me
believe that it describes the name of the scope, but this seems like the
wrong place for that. Which leads me to
* Is there a way to name a scope? Give it the
function/method/object/module/whatever name? This seems like something
that should be supported, if not now then in the future, which leads me to
* How do you imagine future extensions interacting with this? What if we
want to extend the locals data with a way to specify how the debugger
should display the given value (for example the value is a mori[0]
immutable map, but the debugger should display it's key-value pairs
directly instead of its internal representation. It seems to me that
object field renaming is a simple version of this problem. It's ok not
to solve every problem now, but the format must be future extensible to
accommodate when we start solving those other problems.
[0]
https://swannodette.github.io/mori/
General thoughts:
* I like how you encode the scopes as an implicit tree, the same way
DWARF does with its DIEs[1]. I think this is definitely the way to go.
[1]
http://eli.thegreenplace.net/2011/09/29/an-interesting-tree-serialization-algorithm-from-dwarf
* I like using arbitrary JS expressions to get the value bound to a
local. A compiler is free to do whatever transformations and
optimizations it wants as long as the semantics remain the same, this
includes debugging-hostile things like exploding a struct's fields into
individual registers so there is no single place where the struct
exists. To deal with this kind of thing, DWARF uses its own location
operations and language that is Turing complete (and I hear from ex-GDB
maintainers that a fuzzer would likely knock down GDB's implementation
in a few minutes, but I digress). LDB[2] uses PostScript generated by
compilers to deal with this, re-target-ability, and multi-language
support. Its a hairy problem that pretty much requires evaluating
arbitrary code from the compiler. We already have a battle-hardened,
thoroughly-fuzzed, and sandboxed language that is implemented by all
browser vendors: JS. Big plus one for providing JS expressions to
evaluate and get a binding's value.
* Given that last point, I think it would make sense to also have a JS
prologue that would give compilers a chance to define common functions
that are re-used in the individual expressions used to get a binding's
value. This is going to cut down on space a bunch.
Looking forward to your thoughts,
Nick
On 9/20/14, 10:16 AM, Andy Sterland wrote:
> Hi all,
>
> One of the things that we (well mostly Ron) have been working on is an extension to the source map spec to enable debuggers to resolve identifiers that have been renamed during compilation. In TypeScript the classic of example is the this pointer which in TS is different from the JS this pointer. Of course renaming identifiers is also one of the primary functions of a minifier.
>
> I've uploaded a gist (
https://gist.github.com/asterland/edf028ed7947c8c258d1) with details of the extension we've implemented and it would be great to hear what folk think. Both of the specific extension and the general idea.
>
> I'm happy to share the modified TypeScript compiler and private F12 bits if you're curious about trying out the proposal. Just email me.
>
> -Andy
> _______________________________________________
> dev-js-sourcemap mailing list
>
dev-js-s...@lists.mozilla.org
>
https://lists.mozilla.org/listinfo/dev-js-sourcemap