UNPKG

14.9 kBSource Map (JSON)View Raw
1{"version":3,"file":"SourceMapper.js","sourceRoot":"","sources":["../../src/collector/SourceMapper.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport * as path from 'path';\nimport { SourceMapConsumer, RawSourceMap, MappingItem, Position } from 'source-map';\nimport { FileSystem, InternalError, JsonFile, NewlineKind } from '@rushstack/node-core-library';\nimport ts from 'typescript';\n\ninterface ISourceMap {\n sourceMapConsumer: SourceMapConsumer;\n\n // SourceMapConsumer.originalPositionFor() is useless because the mapping contains numerous gaps,\n // and the API provides no way to find the nearest match. So instead we extract all the mapping items\n // and search them using SourceMapper._findNearestMappingItem().\n mappingItems: MappingItem[];\n}\n\ninterface IOriginalFileInfo {\n // Whether the .ts file exists\n fileExists: boolean;\n\n // This is used to check whether the guessed position is out of bounds.\n // Since column/line numbers are 1-based, the 0th item in this array is unused.\n maxColumnForLine: number[];\n}\n\nexport interface ISourceLocation {\n /**\n * The absolute path to the source file.\n */\n sourceFilePath: string;\n\n /**\n * The line number in the source file. The first line number is 1.\n */\n sourceFileLine: number;\n\n /**\n * The column number in the source file. The first column number is 1.\n */\n sourceFileColumn: number;\n}\n\nexport interface IGetSourceLocationOptions {\n /**\n * The source file to get the source location from.\n */\n sourceFile: ts.SourceFile;\n\n /**\n * The position within the source file to get the source location from.\n */\n pos: number;\n\n /**\n * If `false` or not provided, then we attempt to follow source maps in order to resolve the\n * location to the original `.ts` file. If resolution isn't possible for some reason, we fall\n * back to the `.d.ts` location.\n *\n * If `true`, then we don't bother following source maps, and the location refers to the `.d.ts`\n * location.\n */\n useDtsLocation?: boolean;\n}\n\nexport class SourceMapper {\n // Map from .d.ts file path --> ISourceMap if a source map was found, or null if not found\n private _sourceMapByFilePath: Map<string, ISourceMap | null> = new Map<string, ISourceMap | null>();\n\n // Cache the FileSystem.exists() result for mapped .ts files\n private _originalFileInfoByPath: Map<string, IOriginalFileInfo> = new Map<string, IOriginalFileInfo>();\n\n /**\n * Given a `.d.ts` source file and a specific position within the file, return the corresponding\n * `ISourceLocation`.\n */\n public getSourceLocation(options: IGetSourceLocationOptions): ISourceLocation {\n const lineAndCharacter: ts.LineAndCharacter = options.sourceFile.getLineAndCharacterOfPosition(\n options.pos\n );\n const sourceLocation: ISourceLocation = {\n sourceFilePath: options.sourceFile.fileName,\n sourceFileLine: lineAndCharacter.line + 1,\n sourceFileColumn: lineAndCharacter.character + 1\n };\n\n if (options.useDtsLocation) {\n return sourceLocation;\n }\n\n const mappedSourceLocation: ISourceLocation | undefined = this._getMappedSourceLocation(sourceLocation);\n return mappedSourceLocation || sourceLocation;\n }\n\n private _getMappedSourceLocation(sourceLocation: ISourceLocation): ISourceLocation | undefined {\n const { sourceFilePath, sourceFileLine, sourceFileColumn } = sourceLocation;\n\n if (!FileSystem.exists(sourceFilePath)) {\n // Sanity check\n throw new InternalError('The referenced path was not found: ' + sourceFilePath);\n }\n\n const sourceMap: ISourceMap | null = this._getSourceMap(sourceFilePath);\n if (!sourceMap) return;\n\n const nearestMappingItem: MappingItem | undefined = SourceMapper._findNearestMappingItem(\n sourceMap.mappingItems,\n {\n line: sourceFileLine,\n column: sourceFileColumn\n }\n );\n\n if (!nearestMappingItem) return;\n\n const mappedFilePath: string = path.resolve(path.dirname(sourceFilePath), nearestMappingItem.source);\n\n // Does the mapped filename exist? Use a cache to remember the answer.\n let originalFileInfo: IOriginalFileInfo | undefined = this._originalFileInfoByPath.get(mappedFilePath);\n if (originalFileInfo === undefined) {\n originalFileInfo = {\n fileExists: FileSystem.exists(mappedFilePath),\n maxColumnForLine: []\n };\n\n if (originalFileInfo.fileExists) {\n // Read the file and measure the length of each line\n originalFileInfo.maxColumnForLine = FileSystem.readFile(mappedFilePath, {\n convertLineEndings: NewlineKind.Lf\n })\n .split('\\n')\n .map((x) => x.length + 1); // +1 since columns are 1-based\n originalFileInfo.maxColumnForLine.unshift(0); // Extra item since lines are 1-based\n }\n\n this._originalFileInfoByPath.set(mappedFilePath, originalFileInfo);\n }\n\n // Don't translate coordinates to a file that doesn't exist\n if (!originalFileInfo.fileExists) return;\n\n // The nearestMappingItem anchor may be above/left of the real position, due to gaps in the mapping. Calculate\n // the delta and apply it to the original position.\n const guessedPosition: Position = {\n line: nearestMappingItem.originalLine + sourceFileLine - nearestMappingItem.generatedLine,\n column: nearestMappingItem.originalColumn + sourceFileColumn - nearestMappingItem.generatedColumn\n };\n\n // Verify that the result is not out of bounds, in cause our heuristic failed\n if (\n guessedPosition.line >= 1 &&\n guessedPosition.line < originalFileInfo.maxColumnForLine.length &&\n guessedPosition.column >= 1 &&\n guessedPosition.column <= originalFileInfo.maxColumnForLine[guessedPosition.line]\n ) {\n return {\n sourceFilePath: mappedFilePath,\n sourceFileLine: guessedPosition.line,\n sourceFileColumn: guessedPosition.column\n };\n } else {\n // The guessed position was out of bounds, so use the nearestMappingItem position instead.\n return {\n sourceFilePath: mappedFilePath,\n sourceFileLine: nearestMappingItem.originalLine,\n sourceFileColumn: nearestMappingItem.originalColumn\n };\n }\n }\n\n private _getSourceMap(sourceFilePath: string): ISourceMap | null {\n let sourceMap: ISourceMap | null | undefined = this._sourceMapByFilePath.get(sourceFilePath);\n\n if (sourceMap === undefined) {\n // Normalize the path and redo the lookup\n const normalizedPath: string = FileSystem.getRealPath(sourceFilePath);\n\n sourceMap = this._sourceMapByFilePath.get(normalizedPath);\n if (sourceMap !== undefined) {\n // Copy the result from the normalized to the non-normalized key\n this._sourceMapByFilePath.set(sourceFilePath, sourceMap);\n } else {\n // Given \"folder/file.d.ts\", check for a corresponding \"folder/file.d.ts.map\"\n const sourceMapPath: string = normalizedPath + '.map';\n if (FileSystem.exists(sourceMapPath)) {\n // Load up the source map\n const rawSourceMap: RawSourceMap = JsonFile.load(sourceMapPath) as RawSourceMap;\n\n const sourceMapConsumer: SourceMapConsumer = new SourceMapConsumer(rawSourceMap);\n const mappingItems: MappingItem[] = [];\n\n // Extract the list of mapping items\n sourceMapConsumer.eachMapping(\n (mappingItem: MappingItem) => {\n mappingItems.push({\n ...mappingItem,\n // The \"source-map\" package inexplicably uses 1-based line numbers but 0-based column numbers.\n // Fix that up proactively so we don't have to deal with it later.\n generatedColumn: mappingItem.generatedColumn + 1,\n originalColumn: mappingItem.originalColumn + 1\n });\n },\n this,\n SourceMapConsumer.GENERATED_ORDER\n );\n\n sourceMap = { sourceMapConsumer, mappingItems };\n } else {\n // No source map for this filename\n sourceMap = null;\n }\n\n this._sourceMapByFilePath.set(normalizedPath, sourceMap);\n if (sourceFilePath !== normalizedPath) {\n // Add both keys to the map\n this._sourceMapByFilePath.set(sourceFilePath, sourceMap);\n }\n }\n }\n\n return sourceMap;\n }\n\n // The `mappingItems` array is sorted by generatedLine/generatedColumn (GENERATED_ORDER).\n // The _findNearestMappingItem() lookup is a simple binary search that returns the previous item\n // if there is no exact match.\n private static _findNearestMappingItem(\n mappingItems: MappingItem[],\n position: Position\n ): MappingItem | undefined {\n if (mappingItems.length === 0) {\n return undefined;\n }\n\n let startIndex: number = 0;\n let endIndex: number = mappingItems.length - 1;\n\n while (startIndex <= endIndex) {\n const middleIndex: number = startIndex + Math.floor((endIndex - startIndex) / 2);\n\n const diff: number = SourceMapper._compareMappingItem(mappingItems[middleIndex], position);\n\n if (diff < 0) {\n startIndex = middleIndex + 1;\n } else if (diff > 0) {\n endIndex = middleIndex - 1;\n } else {\n // Exact match\n return mappingItems[middleIndex];\n }\n }\n\n // If we didn't find an exact match, then endIndex < startIndex.\n // Take endIndex because it's the smaller value.\n return mappingItems[endIndex];\n }\n\n private static _compareMappingItem(mappingItem: MappingItem, position: Position): number {\n const diff: number = mappingItem.generatedLine - position.line;\n if (diff !== 0) {\n return diff;\n }\n return mappingItem.generatedColumn - position.column;\n }\n}\n"]}
\No newline at end of file