README.md
  1  # Source Map
  2  
  3  [![Build Status](https://travis-ci.org/mozilla/source-map.png?branch=master)](https://travis-ci.org/mozilla/source-map)
  4  
  5  [![NPM](https://nodei.co/npm/source-map.png?downloads=true&downloadRank=true)](https://www.npmjs.com/package/source-map)
  6  
  7  This is a library to generate and consume the source map format
  8  [described here][format].
  9  
 10  [format]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit
 11  
 12  ## Use with Node
 13  
 14      $ npm install source-map
 15  
 16  ## Use on the Web
 17  
 18      <script src="https://raw.githubusercontent.com/mozilla/source-map/master/dist/source-map.min.js" defer></script>
 19  
 20  --------------------------------------------------------------------------------
 21  
 22  <!-- `npm run toc` to regenerate the Table of Contents -->
 23  
 24  <!-- START doctoc generated TOC please keep comment here to allow auto update -->
 25  <!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
 26  ## Table of Contents
 27  
 28  - [Examples](#examples)
 29    - [Consuming a source map](#consuming-a-source-map)
 30    - [Generating a source map](#generating-a-source-map)
 31      - [With SourceNode (high level API)](#with-sourcenode-high-level-api)
 32      - [With SourceMapGenerator (low level API)](#with-sourcemapgenerator-low-level-api)
 33  - [API](#api)
 34    - [SourceMapConsumer](#sourcemapconsumer)
 35      - [new SourceMapConsumer(rawSourceMap)](#new-sourcemapconsumerrawsourcemap)
 36      - [SourceMapConsumer.prototype.computeColumnSpans()](#sourcemapconsumerprototypecomputecolumnspans)
 37      - [SourceMapConsumer.prototype.originalPositionFor(generatedPosition)](#sourcemapconsumerprototypeoriginalpositionforgeneratedposition)
 38      - [SourceMapConsumer.prototype.generatedPositionFor(originalPosition)](#sourcemapconsumerprototypegeneratedpositionfororiginalposition)
 39      - [SourceMapConsumer.prototype.allGeneratedPositionsFor(originalPosition)](#sourcemapconsumerprototypeallgeneratedpositionsfororiginalposition)
 40      - [SourceMapConsumer.prototype.hasContentsOfAllSources()](#sourcemapconsumerprototypehascontentsofallsources)
 41      - [SourceMapConsumer.prototype.sourceContentFor(source[, returnNullOnMissing])](#sourcemapconsumerprototypesourcecontentforsource-returnnullonmissing)
 42      - [SourceMapConsumer.prototype.eachMapping(callback, context, order)](#sourcemapconsumerprototypeeachmappingcallback-context-order)
 43    - [SourceMapGenerator](#sourcemapgenerator)
 44      - [new SourceMapGenerator([startOfSourceMap])](#new-sourcemapgeneratorstartofsourcemap)
 45      - [SourceMapGenerator.fromSourceMap(sourceMapConsumer)](#sourcemapgeneratorfromsourcemapsourcemapconsumer)
 46      - [SourceMapGenerator.prototype.addMapping(mapping)](#sourcemapgeneratorprototypeaddmappingmapping)
 47      - [SourceMapGenerator.prototype.setSourceContent(sourceFile, sourceContent)](#sourcemapgeneratorprototypesetsourcecontentsourcefile-sourcecontent)
 48      - [SourceMapGenerator.prototype.applySourceMap(sourceMapConsumer[, sourceFile[, sourceMapPath]])](#sourcemapgeneratorprototypeapplysourcemapsourcemapconsumer-sourcefile-sourcemappath)
 49      - [SourceMapGenerator.prototype.toString()](#sourcemapgeneratorprototypetostring)
 50    - [SourceNode](#sourcenode)
 51      - [new SourceNode([line, column, source[, chunk[, name]]])](#new-sourcenodeline-column-source-chunk-name)
 52      - [SourceNode.fromStringWithSourceMap(code, sourceMapConsumer[, relativePath])](#sourcenodefromstringwithsourcemapcode-sourcemapconsumer-relativepath)
 53      - [SourceNode.prototype.add(chunk)](#sourcenodeprototypeaddchunk)
 54      - [SourceNode.prototype.prepend(chunk)](#sourcenodeprototypeprependchunk)
 55      - [SourceNode.prototype.setSourceContent(sourceFile, sourceContent)](#sourcenodeprototypesetsourcecontentsourcefile-sourcecontent)
 56      - [SourceNode.prototype.walk(fn)](#sourcenodeprototypewalkfn)
 57      - [SourceNode.prototype.walkSourceContents(fn)](#sourcenodeprototypewalksourcecontentsfn)
 58      - [SourceNode.prototype.join(sep)](#sourcenodeprototypejoinsep)
 59      - [SourceNode.prototype.replaceRight(pattern, replacement)](#sourcenodeprototypereplacerightpattern-replacement)
 60      - [SourceNode.prototype.toString()](#sourcenodeprototypetostring)
 61      - [SourceNode.prototype.toStringWithSourceMap([startOfSourceMap])](#sourcenodeprototypetostringwithsourcemapstartofsourcemap)
 62  
 63  <!-- END doctoc generated TOC please keep comment here to allow auto update -->
 64  
 65  ## Examples
 66  
 67  ### Consuming a source map
 68  
 69  ```js
 70  var rawSourceMap = {
 71    version: 3,
 72    file: 'min.js',
 73    names: ['bar', 'baz', 'n'],
 74    sources: ['one.js', 'two.js'],
 75    sourceRoot: 'http://example.com/www/js/',
 76    mappings: 'CAAC,IAAI,IAAM,SAAUA,GAClB,OAAOC,IAAID;CCDb,IAAI,IAAM,SAAUE,GAClB,OAAOA'
 77  };
 78  
 79  var smc = new SourceMapConsumer(rawSourceMap);
 80  
 81  console.log(smc.sources);
 82  // [ 'http://example.com/www/js/one.js',
 83  //   'http://example.com/www/js/two.js' ]
 84  
 85  console.log(smc.originalPositionFor({
 86    line: 2,
 87    column: 28
 88  }));
 89  // { source: 'http://example.com/www/js/two.js',
 90  //   line: 2,
 91  //   column: 10,
 92  //   name: 'n' }
 93  
 94  console.log(smc.generatedPositionFor({
 95    source: 'http://example.com/www/js/two.js',
 96    line: 2,
 97    column: 10
 98  }));
 99  // { line: 2, column: 28 }
100  
101  smc.eachMapping(function (m) {
102    // ...
103  });
104  ```
105  
106  ### Generating a source map
107  
108  In depth guide:
109  [**Compiling to JavaScript, and Debugging with Source Maps**](https://hacks.mozilla.org/2013/05/compiling-to-javascript-and-debugging-with-source-maps/)
110  
111  #### With SourceNode (high level API)
112  
113  ```js
114  function compile(ast) {
115    switch (ast.type) {
116    case 'BinaryExpression':
117      return new SourceNode(
118        ast.location.line,
119        ast.location.column,
120        ast.location.source,
121        [compile(ast.left), " + ", compile(ast.right)]
122      );
123    case 'Literal':
124      return new SourceNode(
125        ast.location.line,
126        ast.location.column,
127        ast.location.source,
128        String(ast.value)
129      );
130    // ...
131    default:
132      throw new Error("Bad AST");
133    }
134  }
135  
136  var ast = parse("40 + 2", "add.js");
137  console.log(compile(ast).toStringWithSourceMap({
138    file: 'add.js'
139  }));
140  // { code: '40 + 2',
141  //   map: [object SourceMapGenerator] }
142  ```
143  
144  #### With SourceMapGenerator (low level API)
145  
146  ```js
147  var map = new SourceMapGenerator({
148    file: "source-mapped.js"
149  });
150  
151  map.addMapping({
152    generated: {
153      line: 10,
154      column: 35
155    },
156    source: "foo.js",
157    original: {
158      line: 33,
159      column: 2
160    },
161    name: "christopher"
162  });
163  
164  console.log(map.toString());
165  // '{"version":3,"file":"source-mapped.js","sources":["foo.js"],"names":["christopher"],"mappings":";;;;;;;;;mCAgCEA"}'
166  ```
167  
168  ## API
169  
170  Get a reference to the module:
171  
172  ```js
173  // Node.js
174  var sourceMap = require('source-map');
175  
176  // Browser builds
177  var sourceMap = window.sourceMap;
178  
179  // Inside Firefox
180  const sourceMap = require("devtools/toolkit/sourcemap/source-map.js");
181  ```
182  
183  ### SourceMapConsumer
184  
185  A SourceMapConsumer instance represents a parsed source map which we can query
186  for information about the original file positions by giving it a file position
187  in the generated source.
188  
189  #### new SourceMapConsumer(rawSourceMap)
190  
191  The only parameter is the raw source map (either as a string which can be
192  `JSON.parse`'d, or an object). According to the spec, source maps have the
193  following attributes:
194  
195  * `version`: Which version of the source map spec this map is following.
196  
197  * `sources`: An array of URLs to the original source files.
198  
199  * `names`: An array of identifiers which can be referenced by individual
200    mappings.
201  
202  * `sourceRoot`: Optional. The URL root from which all sources are relative.
203  
204  * `sourcesContent`: Optional. An array of contents of the original source files.
205  
206  * `mappings`: A string of base64 VLQs which contain the actual mappings.
207  
208  * `file`: Optional. The generated filename this source map is associated with.
209  
210  ```js
211  var consumer = new sourceMap.SourceMapConsumer(rawSourceMapJsonData);
212  ```
213  
214  #### SourceMapConsumer.prototype.computeColumnSpans()
215  
216  Compute the last column for each generated mapping. The last column is
217  inclusive.
218  
219  ```js
220  // Before:
221  consumer.allGeneratedPositionsFor({ line: 2, source: "foo.coffee" })
222  // [ { line: 2,
223  //     column: 1 },
224  //   { line: 2,
225  //     column: 10 },
226  //   { line: 2,
227  //     column: 20 } ]
228  
229  consumer.computeColumnSpans();
230  
231  // After:
232  consumer.allGeneratedPositionsFor({ line: 2, source: "foo.coffee" })
233  // [ { line: 2,
234  //     column: 1,
235  //     lastColumn: 9 },
236  //   { line: 2,
237  //     column: 10,
238  //     lastColumn: 19 },
239  //   { line: 2,
240  //     column: 20,
241  //     lastColumn: Infinity } ]
242  
243  ```
244  
245  #### SourceMapConsumer.prototype.originalPositionFor(generatedPosition)
246  
247  Returns the original source, line, and column information for the generated
248  source's line and column positions provided. The only argument is an object with
249  the following properties:
250  
251  * `line`: The line number in the generated source.
252  
253  * `column`: The column number in the generated source.
254  
255  * `bias`: Either `SourceMapConsumer.GREATEST_LOWER_BOUND` or
256    `SourceMapConsumer.LEAST_UPPER_BOUND`. Specifies whether to return the closest
257    element that is smaller than or greater than the one we are searching for,
258    respectively, if the exact element cannot be found.  Defaults to
259    `SourceMapConsumer.GREATEST_LOWER_BOUND`.
260  
261  and an object is returned with the following properties:
262  
263  * `source`: The original source file, or null if this information is not
264    available.
265  
266  * `line`: The line number in the original source, or null if this information is
267    not available.
268  
269  * `column`: The column number in the original source, or null if this
270    information is not available.
271  
272  * `name`: The original identifier, or null if this information is not available.
273  
274  ```js
275  consumer.originalPositionFor({ line: 2, column: 10 })
276  // { source: 'foo.coffee',
277  //   line: 2,
278  //   column: 2,
279  //   name: null }
280  
281  consumer.originalPositionFor({ line: 99999999999999999, column: 999999999999999 })
282  // { source: null,
283  //   line: null,
284  //   column: null,
285  //   name: null }
286  ```
287  
288  #### SourceMapConsumer.prototype.generatedPositionFor(originalPosition)
289  
290  Returns the generated line and column information for the original source,
291  line, and column positions provided. The only argument is an object with
292  the following properties:
293  
294  * `source`: The filename of the original source.
295  
296  * `line`: The line number in the original source.
297  
298  * `column`: The column number in the original source.
299  
300  and an object is returned with the following properties:
301  
302  * `line`: The line number in the generated source, or null.
303  
304  * `column`: The column number in the generated source, or null.
305  
306  ```js
307  consumer.generatedPositionFor({ source: "example.js", line: 2, column: 10 })
308  // { line: 1,
309  //   column: 56 }
310  ```
311  
312  #### SourceMapConsumer.prototype.allGeneratedPositionsFor(originalPosition)
313  
314  Returns all generated line and column information for the original source, line,
315  and column provided. If no column is provided, returns all mappings
316  corresponding to a either the line we are searching for or the next closest line
317  that has any mappings. Otherwise, returns all mappings corresponding to the
318  given line and either the column we are searching for or the next closest column
319  that has any offsets.
320  
321  The only argument is an object with the following properties:
322  
323  * `source`: The filename of the original source.
324  
325  * `line`: The line number in the original source.
326  
327  * `column`: Optional. The column number in the original source.
328  
329  and an array of objects is returned, each with the following properties:
330  
331  * `line`: The line number in the generated source, or null.
332  
333  * `column`: The column number in the generated source, or null.
334  
335  ```js
336  consumer.allGeneratedpositionsfor({ line: 2, source: "foo.coffee" })
337  // [ { line: 2,
338  //     column: 1 },
339  //   { line: 2,
340  //     column: 10 },
341  //   { line: 2,
342  //     column: 20 } ]
343  ```
344  
345  #### SourceMapConsumer.prototype.hasContentsOfAllSources()
346  
347  Return true if we have the embedded source content for every source listed in
348  the source map, false otherwise.
349  
350  In other words, if this method returns `true`, then
351  `consumer.sourceContentFor(s)` will succeed for every source `s` in
352  `consumer.sources`.
353  
354  ```js
355  // ...
356  if (consumer.hasContentsOfAllSources()) {
357    consumerReadyCallback(consumer);
358  } else {
359    fetchSources(consumer, consumerReadyCallback);
360  }
361  // ...
362  ```
363  
364  #### SourceMapConsumer.prototype.sourceContentFor(source[, returnNullOnMissing])
365  
366  Returns the original source content for the source provided. The only
367  argument is the URL of the original source file.
368  
369  If the source content for the given source is not found, then an error is
370  thrown. Optionally, pass `true` as the second param to have `null` returned
371  instead.
372  
373  ```js
374  consumer.sources
375  // [ "my-cool-lib.clj" ]
376  
377  consumer.sourceContentFor("my-cool-lib.clj")
378  // "..."
379  
380  consumer.sourceContentFor("this is not in the source map");
381  // Error: "this is not in the source map" is not in the source map
382  
383  consumer.sourceContentFor("this is not in the source map", true);
384  // null
385  ```
386  
387  #### SourceMapConsumer.prototype.eachMapping(callback, context, order)
388  
389  Iterate over each mapping between an original source/line/column and a
390  generated line/column in this source map.
391  
392  * `callback`: The function that is called with each mapping. Mappings have the
393    form `{ source, generatedLine, generatedColumn, originalLine, originalColumn,
394    name }`
395  
396  * `context`: Optional. If specified, this object will be the value of `this`
397    every time that `callback` is called.
398  
399  * `order`: Either `SourceMapConsumer.GENERATED_ORDER` or
400    `SourceMapConsumer.ORIGINAL_ORDER`. Specifies whether you want to iterate over
401    the mappings sorted by the generated file's line/column order or the
402    original's source/line/column order, respectively. Defaults to
403    `SourceMapConsumer.GENERATED_ORDER`.
404  
405  ```js
406  consumer.eachMapping(function (m) { console.log(m); })
407  // ...
408  // { source: 'illmatic.js',
409  //   generatedLine: 1,
410  //   generatedColumn: 0,
411  //   originalLine: 1,
412  //   originalColumn: 0,
413  //   name: null }
414  // { source: 'illmatic.js',
415  //   generatedLine: 2,
416  //   generatedColumn: 0,
417  //   originalLine: 2,
418  //   originalColumn: 0,
419  //   name: null }
420  // ...
421  ```
422  ### SourceMapGenerator
423  
424  An instance of the SourceMapGenerator represents a source map which is being
425  built incrementally.
426  
427  #### new SourceMapGenerator([startOfSourceMap])
428  
429  You may pass an object with the following properties:
430  
431  * `file`: The filename of the generated source that this source map is
432    associated with.
433  
434  * `sourceRoot`: A root for all relative URLs in this source map.
435  
436  * `skipValidation`: Optional. When `true`, disables validation of mappings as
437    they are added. This can improve performance but should be used with
438    discretion, as a last resort. Even then, one should avoid using this flag when
439    running tests, if possible.
440  
441  ```js
442  var generator = new sourceMap.SourceMapGenerator({
443    file: "my-generated-javascript-file.js",
444    sourceRoot: "http://example.com/app/js/"
445  });
446  ```
447  
448  #### SourceMapGenerator.fromSourceMap(sourceMapConsumer)
449  
450  Creates a new `SourceMapGenerator` from an existing `SourceMapConsumer` instance.
451  
452  * `sourceMapConsumer` The SourceMap.
453  
454  ```js
455  var generator = sourceMap.SourceMapGenerator.fromSourceMap(consumer);
456  ```
457  
458  #### SourceMapGenerator.prototype.addMapping(mapping)
459  
460  Add a single mapping from original source line and column to the generated
461  source's line and column for this source map being created. The mapping object
462  should have the following properties:
463  
464  * `generated`: An object with the generated line and column positions.
465  
466  * `original`: An object with the original line and column positions.
467  
468  * `source`: The original source file (relative to the sourceRoot).
469  
470  * `name`: An optional original token name for this mapping.
471  
472  ```js
473  generator.addMapping({
474    source: "module-one.scm",
475    original: { line: 128, column: 0 },
476    generated: { line: 3, column: 456 }
477  })
478  ```
479  
480  #### SourceMapGenerator.prototype.setSourceContent(sourceFile, sourceContent)
481  
482  Set the source content for an original source file.
483  
484  * `sourceFile` the URL of the original source file.
485  
486  * `sourceContent` the content of the source file.
487  
488  ```js
489  generator.setSourceContent("module-one.scm",
490                             fs.readFileSync("path/to/module-one.scm"))
491  ```
492  
493  #### SourceMapGenerator.prototype.applySourceMap(sourceMapConsumer[, sourceFile[, sourceMapPath]])
494  
495  Applies a SourceMap for a source file to the SourceMap.
496  Each mapping to the supplied source file is rewritten using the
497  supplied SourceMap. Note: The resolution for the resulting mappings
498  is the minimum of this map and the supplied map.
499  
500  * `sourceMapConsumer`: The SourceMap to be applied.
501  
502  * `sourceFile`: Optional. The filename of the source file.
503    If omitted, sourceMapConsumer.file will be used, if it exists.
504    Otherwise an error will be thrown.
505  
506  * `sourceMapPath`: Optional. The dirname of the path to the SourceMap
507    to be applied. If relative, it is relative to the SourceMap.
508  
509    This parameter is needed when the two SourceMaps aren't in the same
510    directory, and the SourceMap to be applied contains relative source
511    paths. If so, those relative source paths need to be rewritten
512    relative to the SourceMap.
513  
514    If omitted, it is assumed that both SourceMaps are in the same directory,
515    thus not needing any rewriting. (Supplying `'.'` has the same effect.)
516  
517  #### SourceMapGenerator.prototype.toString()
518  
519  Renders the source map being generated to a string.
520  
521  ```js
522  generator.toString()
523  // '{"version":3,"sources":["module-one.scm"],"names":[],"mappings":"...snip...","file":"my-generated-javascript-file.js","sourceRoot":"http://example.com/app/js/"}'
524  ```
525  
526  ### SourceNode
527  
528  SourceNodes provide a way to abstract over interpolating and/or concatenating
529  snippets of generated JavaScript source code, while maintaining the line and
530  column information associated between those snippets and the original source
531  code. This is useful as the final intermediate representation a compiler might
532  use before outputting the generated JS and source map.
533  
534  #### new SourceNode([line, column, source[, chunk[, name]]])
535  
536  * `line`: The original line number associated with this source node, or null if
537    it isn't associated with an original line.
538  
539  * `column`: The original column number associated with this source node, or null
540    if it isn't associated with an original column.
541  
542  * `source`: The original source's filename; null if no filename is provided.
543  
544  * `chunk`: Optional. Is immediately passed to `SourceNode.prototype.add`, see
545    below.
546  
547  * `name`: Optional. The original identifier.
548  
549  ```js
550  var node = new SourceNode(1, 2, "a.cpp", [
551    new SourceNode(3, 4, "b.cpp", "extern int status;\n"),
552    new SourceNode(5, 6, "c.cpp", "std::string* make_string(size_t n);\n"),
553    new SourceNode(7, 8, "d.cpp", "int main(int argc, char** argv) {}\n"),
554  ]);
555  ```
556  
557  #### SourceNode.fromStringWithSourceMap(code, sourceMapConsumer[, relativePath])
558  
559  Creates a SourceNode from generated code and a SourceMapConsumer.
560  
561  * `code`: The generated code
562  
563  * `sourceMapConsumer` The SourceMap for the generated code
564  
565  * `relativePath` The optional path that relative sources in `sourceMapConsumer`
566    should be relative to.
567  
568  ```js
569  var consumer = new SourceMapConsumer(fs.readFileSync("path/to/my-file.js.map", "utf8"));
570  var node = SourceNode.fromStringWithSourceMap(fs.readFileSync("path/to/my-file.js"),
571                                                consumer);
572  ```
573  
574  #### SourceNode.prototype.add(chunk)
575  
576  Add a chunk of generated JS to this source node.
577  
578  * `chunk`: A string snippet of generated JS code, another instance of
579     `SourceNode`, or an array where each member is one of those things.
580  
581  ```js
582  node.add(" + ");
583  node.add(otherNode);
584  node.add([leftHandOperandNode, " + ", rightHandOperandNode]);
585  ```
586  
587  #### SourceNode.prototype.prepend(chunk)
588  
589  Prepend a chunk of generated JS to this source node.
590  
591  * `chunk`: A string snippet of generated JS code, another instance of
592     `SourceNode`, or an array where each member is one of those things.
593  
594  ```js
595  node.prepend("/** Build Id: f783haef86324gf **/\n\n");
596  ```
597  
598  #### SourceNode.prototype.setSourceContent(sourceFile, sourceContent)
599  
600  Set the source content for a source file. This will be added to the
601  `SourceMap` in the `sourcesContent` field.
602  
603  * `sourceFile`: The filename of the source file
604  
605  * `sourceContent`: The content of the source file
606  
607  ```js
608  node.setSourceContent("module-one.scm",
609                        fs.readFileSync("path/to/module-one.scm"))
610  ```
611  
612  #### SourceNode.prototype.walk(fn)
613  
614  Walk over the tree of JS snippets in this node and its children. The walking
615  function is called once for each snippet of JS and is passed that snippet and
616  the its original associated source's line/column location.
617  
618  * `fn`: The traversal function.
619  
620  ```js
621  var node = new SourceNode(1, 2, "a.js", [
622    new SourceNode(3, 4, "b.js", "uno"),
623    "dos",
624    [
625      "tres",
626      new SourceNode(5, 6, "c.js", "quatro")
627    ]
628  ]);
629  
630  node.walk(function (code, loc) { console.log("WALK:", code, loc); })
631  // WALK: uno { source: 'b.js', line: 3, column: 4, name: null }
632  // WALK: dos { source: 'a.js', line: 1, column: 2, name: null }
633  // WALK: tres { source: 'a.js', line: 1, column: 2, name: null }
634  // WALK: quatro { source: 'c.js', line: 5, column: 6, name: null }
635  ```
636  
637  #### SourceNode.prototype.walkSourceContents(fn)
638  
639  Walk over the tree of SourceNodes. The walking function is called for each
640  source file content and is passed the filename and source content.
641  
642  * `fn`: The traversal function.
643  
644  ```js
645  var a = new SourceNode(1, 2, "a.js", "generated from a");
646  a.setSourceContent("a.js", "original a");
647  var b = new SourceNode(1, 2, "b.js", "generated from b");
648  b.setSourceContent("b.js", "original b");
649  var c = new SourceNode(1, 2, "c.js", "generated from c");
650  c.setSourceContent("c.js", "original c");
651  
652  var node = new SourceNode(null, null, null, [a, b, c]);
653  node.walkSourceContents(function (source, contents) { console.log("WALK:", source, ":", contents); })
654  // WALK: a.js : original a
655  // WALK: b.js : original b
656  // WALK: c.js : original c
657  ```
658  
659  #### SourceNode.prototype.join(sep)
660  
661  Like `Array.prototype.join` except for SourceNodes. Inserts the separator
662  between each of this source node's children.
663  
664  * `sep`: The separator.
665  
666  ```js
667  var lhs = new SourceNode(1, 2, "a.rs", "my_copy");
668  var operand = new SourceNode(3, 4, "a.rs", "=");
669  var rhs = new SourceNode(5, 6, "a.rs", "orig.clone()");
670  
671  var node = new SourceNode(null, null, null, [ lhs, operand, rhs ]);
672  var joinedNode = node.join(" ");
673  ```
674  
675  #### SourceNode.prototype.replaceRight(pattern, replacement)
676  
677  Call `String.prototype.replace` on the very right-most source snippet. Useful
678  for trimming white space from the end of a source node, etc.
679  
680  * `pattern`: The pattern to replace.
681  
682  * `replacement`: The thing to replace the pattern with.
683  
684  ```js
685  // Trim trailing white space.
686  node.replaceRight(/\s*$/, "");
687  ```
688  
689  #### SourceNode.prototype.toString()
690  
691  Return the string representation of this source node. Walks over the tree and
692  concatenates all the various snippets together to one string.
693  
694  ```js
695  var node = new SourceNode(1, 2, "a.js", [
696    new SourceNode(3, 4, "b.js", "uno"),
697    "dos",
698    [
699      "tres",
700      new SourceNode(5, 6, "c.js", "quatro")
701    ]
702  ]);
703  
704  node.toString()
705  // 'unodostresquatro'
706  ```
707  
708  #### SourceNode.prototype.toStringWithSourceMap([startOfSourceMap])
709  
710  Returns the string representation of this tree of source nodes, plus a
711  SourceMapGenerator which contains all the mappings between the generated and
712  original sources.
713  
714  The arguments are the same as those to `new SourceMapGenerator`.
715  
716  ```js
717  var node = new SourceNode(1, 2, "a.js", [
718    new SourceNode(3, 4, "b.js", "uno"),
719    "dos",
720    [
721      "tres",
722      new SourceNode(5, 6, "c.js", "quatro")
723    ]
724  ]);
725  
726  node.toStringWithSourceMap({ file: "my-output-file.js" })
727  // { code: 'unodostresquatro',
728  //   map: [object SourceMapGenerator] }
729  ```