microsoft/vscode-react-native

Public

mirrored from https://github.com/microsoft/vscode-react-nativeAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
0.4.1

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

src/debugger/sourceMapsCombinator.ts

118lines · modecode

1// Copyright (c) Microsoft Corporation. All rights reserved.
2// Licensed under the MIT license. See LICENSE file in the project root for details.
3
4import * as fs from "fs";
5import * as path from "path";
6import { SourceMapConsumer, RawSourceMap, SourceMapGenerator, MappingItem, Mapping, Position, MappedPosition } from "source-map";
7import sourceMapResolve = require("source-map-resolve");
8
9const DISK_LETTER_RE: RegExp = /^[a-z]:/i;
10
11export class SourceMapsCombinator {
12
13 public convert(rawBundleSourcemap: RawSourceMap): RawSourceMap {
14
15 // Find user files from bundle files list
16 const consumers: { [key: string]: SourceMapConsumer } = rawBundleSourcemap.sources
17 .reduce((result, file) => {
18 // Skip files inside node_modules
19 if (file.indexOf("node_modules") >= 0) return result;
20
21 try {
22 let consumer: SourceMapConsumer = this.getSourceMapConsumerFrom(file);
23 if (consumer)
24 result[file] = consumer;
25 } finally {
26 return result;
27 }
28 }, {});
29
30 if (Object.keys(consumers).length === 0) {
31 // Sourcemaps not found, so return original bundle sourcemap
32 return rawBundleSourcemap;
33 }
34
35 const generator = new SourceMapGenerator();
36 const bundleConsumer = new SourceMapConsumer(rawBundleSourcemap);
37
38 bundleConsumer.eachMapping((item: MappingItem) => {
39 if (item.source === null) {
40 // Some mappings in react native bundle have no sources
41 return;
42 }
43
44 // Copy mappings
45 let mapping: Mapping = {
46 generated: { line: item.generatedLine, column: item.generatedColumn },
47 original: { line: item.originalLine, column: item.originalColumn },
48 source: item.source,
49 name: item.name,
50 };
51
52 if (consumers[item.source]) {
53 let jsPosition: Position = { line: item.originalLine, column: item.originalColumn };
54 let tsPosition: MappedPosition = consumers[item.source].originalPositionFor(jsPosition);
55
56 if (tsPosition.source === null) {
57 // Some positions from react native generated bundle can not translate to TS source positions
58 // skip them
59 return;
60 }
61
62 // Resolve TS source path to absolute because it might be relative to generated JS
63 // (this depends on whether "sourceRoot" option is specified in tsconfig.json)
64 if (!tsPosition.source.match(DISK_LETTER_RE)) { // This check for Windows tests which were run on MacOs
65 tsPosition.source = path.resolve(
66 rawBundleSourcemap.sourceRoot,
67 path.dirname(item.source),
68 tsPosition.source
69 );
70 }
71
72 // Update mapping w/ mapped position values
73 mapping = {
74 ...mapping, ...tsPosition,
75 original: { line: tsPosition.line, column: tsPosition.column },
76 };
77 }
78
79 try {
80 generator.addMapping(mapping);
81 } catch (err) {
82
83 }
84 });
85
86 return generator.toJSON();
87 }
88
89 private getSourceMapConsumerFrom(generatedFile: string): SourceMapConsumer | null {
90 let code = fs.readFileSync(generatedFile);
91
92 let consumer = this.readSourcemap(generatedFile, code.toString());
93 return consumer;
94 }
95
96 private readSourcemap(file: string, code: string): SourceMapConsumer | null {
97 let result = sourceMapResolve.resolveSync(code, file, readFileSync.bind(null, getDiskLetter(file)));
98 if (result === null) {
99 return null;
100 }
101 return new SourceMapConsumer(result.map);
102 }
103}
104
105// Hack for source-map-resolve and cutted disk letter
106// https://github.com/lydell/source-map-resolve/issues/9
107function readFileSync(diskLetter: string, filePath: string) {
108 if (filePath.match(DISK_LETTER_RE)) {
109 return fs.readFileSync(filePath);
110 } else {
111 return fs.readFileSync(`${diskLetter}${filePath}`);
112 }
113}
114
115function getDiskLetter(filePath: string): string {
116 const matched = filePath.match(DISK_LETTER_RE);
117 return matched ? matched[0] : "";
118}