Projekt

Obecné

Profil

Stáhnout (22.9 KB) Statistiky
| Větev: | Revize:
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
```
(3-3/5)