microsoft/vscode-react-native

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
9f75364d9ab474cb5ea5041b52ac55efb269012e

Branches

Tags

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

Clone

HTTPS

Download ZIP

src/debugger/sourceMapsCombinator.ts

118lines · modeblame

48644043Dmitry Zinovyev9 years ago1// 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";
954784f3Vladimir Kotikov8 years ago5import * as path from "path";
48644043Dmitry Zinovyev9 years ago6import { SourceMapConsumer, RawSourceMap, SourceMapGenerator, MappingItem, Mapping, Position, MappedPosition } from "source-map";
70bb7c83Vladimir Kotikov8 years ago7import sourceMapResolve = require("source-map-resolve");
48644043Dmitry Zinovyev9 years ago8
9f75364dArtem Egorov8 years ago9const DISK_LETTER_RE: RegExp = /^[a-z]:/i;
10
48644043Dmitry Zinovyev9 years ago11export class SourceMapsCombinator {
12
13public convert(rawBundleSourcemap: RawSourceMap): RawSourceMap {
14
15// Find user files from bundle files list
70bb7c83Vladimir Kotikov8 years ago16const consumers: { [key: string]: SourceMapConsumer } = rawBundleSourcemap.sources
17.reduce((result, file) => {
18// Skip files inside node_modules
19if (file.indexOf("node_modules") >= 0) return result;
48644043Dmitry Zinovyev9 years ago20
70bb7c83Vladimir Kotikov8 years ago21try {
22let consumer: SourceMapConsumer = this.getSourceMapConsumerFrom(file);
23if (consumer)
24result[file] = consumer;
25} finally {
26return result;
27}
28}, {});
48644043Dmitry Zinovyev9 years ago29
30if (Object.keys(consumers).length === 0) {
70bb7c83Vladimir Kotikov8 years ago31// Sourcemaps not found, so return original bundle sourcemap
48644043Dmitry Zinovyev9 years ago32return rawBundleSourcemap;
33}
34
70bb7c83Vladimir Kotikov8 years ago35const generator = new SourceMapGenerator();
36const bundleConsumer = new SourceMapConsumer(rawBundleSourcemap);
48644043Dmitry Zinovyev9 years ago37
38bundleConsumer.eachMapping((item: MappingItem) => {
39if (item.source === null) {
40// Some mappings in react native bundle have no sources
41return;
42}
43
70bb7c83Vladimir Kotikov8 years ago44// Copy mappings
45let mapping: Mapping = {
46generated: { line: item.generatedLine, column: item.generatedColumn },
47original: { line: item.originalLine, column: item.originalColumn },
48source: item.source,
49name: item.name,
50};
51
52if (consumers[item.source]) {
53let jsPosition: Position = { line: item.originalLine, column: item.originalColumn };
48644043Dmitry Zinovyev9 years ago54let tsPosition: MappedPosition = consumers[item.source].originalPositionFor(jsPosition);
55
56if (tsPosition.source === null) {
57// Some positions from react native generated bundle can not translate to TS source positions
58// skip them
59return;
60}
61
954784f3Vladimir Kotikov8 years ago62// 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)
9f75364dArtem Egorov8 years ago64if (!tsPosition.source.match(DISK_LETTER_RE)) { // This check for Windows tests which were run on MacOs
65tsPosition.source = path.resolve(
66rawBundleSourcemap.sourceRoot,
67path.dirname(item.source),
68tsPosition.source
69);
70}
954784f3Vladimir Kotikov8 years ago71
70bb7c83Vladimir Kotikov8 years ago72// Update mapping w/ mapped position values
73mapping = {
74...mapping, ...tsPosition,
48644043Dmitry Zinovyev9 years ago75original: { line: tsPosition.line, column: tsPosition.column },
70bb7c83Vladimir Kotikov8 years ago76};
77}
48644043Dmitry Zinovyev9 years ago78
70bb7c83Vladimir Kotikov8 years ago79try {
80generator.addMapping(mapping);
81} catch (err) {
48644043Dmitry Zinovyev9 years ago82
83}
84});
85
86return generator.toJSON();
87}
88
89private getSourceMapConsumerFrom(generatedFile: string): SourceMapConsumer | null {
90let code = fs.readFileSync(generatedFile);
91
92let consumer = this.readSourcemap(generatedFile, code.toString());
93return consumer;
94}
95
96private readSourcemap(file: string, code: string): SourceMapConsumer | null {
9f75364dArtem Egorov8 years ago97let result = sourceMapResolve.resolveSync(code, file, readFileSync.bind(null, getDiskLetter(file)));
48644043Dmitry Zinovyev9 years ago98if (result === null) {
99return null;
100}
101return new SourceMapConsumer(result.map);
102}
103}
9f75364dArtem Egorov8 years ago104
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) {
108if (filePath.match(DISK_LETTER_RE)) {
109return fs.readFileSync(filePath);
110} else {
111return fs.readFileSync(`${diskLetter}${filePath}`);
112}
113}
114
115function getDiskLetter(filePath: string): string {
116const matched = filePath.match(DISK_LETTER_RE);
117return matched ? matched[0] : "";
118}