mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-05 16:38:05 -06:00
Optimize sourcemap application more (#25425)
* Optimize sourcemap application more * Remove test-only memory hog sourceMapDecodedMappings field * Update for style, remove unused function that triggers warnings in node 10 * Avoid all raw buffer constructor calls * Small TDZ fix
This commit is contained in:
parent
065e695a28
commit
5b92678285
@ -156,7 +156,6 @@ namespace ts {
|
||||
sourceMapNames: [],
|
||||
sourceMapMappings: "",
|
||||
sourceMapSourcesContent: compilerOptions.inlineSources ? [] : undefined,
|
||||
sourceMapDecodedMappings: []
|
||||
};
|
||||
|
||||
// Normalize source root and make sure it has trailing "/" so that it can be used to combine paths with the
|
||||
@ -299,7 +298,6 @@ namespace ts {
|
||||
}
|
||||
|
||||
lastEncodedSourceMapSpan = lastRecordedSourceMapSpan;
|
||||
sourceMapData.sourceMapDecodedMappings.push(lastEncodedSourceMapSpan);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -393,24 +391,29 @@ namespace ts {
|
||||
|
||||
const sourcesDirectoryPath = compilerOptions.sourceRoot ? host.getCommonSourceDirectory() : sourceMapDir;
|
||||
const resolvedPathCache = createMap<string>();
|
||||
sourcemaps.calculateDecodedMappings(originalMap, (raw): void => {
|
||||
const absolutePathCache = createMap<string>();
|
||||
const sourcemapIterator = sourcemaps.decodeMappings(originalMap);
|
||||
for (let { value: raw, done } = sourcemapIterator.next(); !done; { value: raw, done } = sourcemapIterator.next()) {
|
||||
const pathCacheKey = "" + raw.sourceIndex;
|
||||
// Apply offsets to each position and fixup source entries
|
||||
const rawPath = originalMap.sources[raw.sourceIndex];
|
||||
const relativePath = originalMap.sourceRoot ? combinePaths(originalMap.sourceRoot, rawPath) : rawPath;
|
||||
const combinedPath = combinePaths(getDirectoryPath(node.sourceMapPath!), relativePath);
|
||||
if (!resolvedPathCache.has(combinedPath)) {
|
||||
resolvedPathCache.set(combinedPath, getRelativePathToDirectoryOrUrl(
|
||||
if (!resolvedPathCache.has(pathCacheKey)) {
|
||||
const rawPath = originalMap.sources[raw.sourceIndex];
|
||||
const relativePath = originalMap.sourceRoot ? combinePaths(originalMap.sourceRoot, rawPath) : rawPath;
|
||||
const combinedPath = combinePaths(getDirectoryPath(node.sourceMapPath!), relativePath);
|
||||
const resolvedPath = getRelativePathToDirectoryOrUrl(
|
||||
sourcesDirectoryPath,
|
||||
combinedPath,
|
||||
host.getCurrentDirectory(),
|
||||
host.getCanonicalFileName,
|
||||
/*isAbsolutePathAnUrl*/ true
|
||||
));
|
||||
);
|
||||
resolvedPathCache.set(pathCacheKey, resolvedPath);
|
||||
absolutePathCache.set(pathCacheKey, getNormalizedAbsolutePath(resolvedPath, sourcesDirectoryPath));
|
||||
}
|
||||
const resolvedPath = resolvedPathCache.get(combinedPath)!;
|
||||
const absolutePath = getNormalizedAbsolutePath(resolvedPath, sourcesDirectoryPath);
|
||||
const resolvedPath = resolvedPathCache.get(pathCacheKey)!;
|
||||
const absolutePath = absolutePathCache.get(pathCacheKey)!;
|
||||
// tslint:disable-next-line:no-null-keyword
|
||||
setupSourceEntry(absolutePath, originalMap.sourcesContent ? originalMap.sourcesContent[raw.sourceIndex] : null); // TODO: Lookup content for inlining?
|
||||
setupSourceEntry(absolutePath, originalMap.sourcesContent ? originalMap.sourcesContent[raw.sourceIndex] : null, resolvedPath); // TODO: Lookup content for inlining?
|
||||
const newIndex = sourceMapData.sourceMapSources.indexOf(resolvedPath);
|
||||
// Then reencode all the updated spans into the overall map
|
||||
encodeLastRecordedSourceMapSpan();
|
||||
@ -420,7 +423,7 @@ namespace ts {
|
||||
emittedColumn: raw.emittedLine === 0 ? (raw.emittedColumn + firstLineColumnOffset) : raw.emittedColumn,
|
||||
sourceIndex: newIndex,
|
||||
};
|
||||
});
|
||||
}
|
||||
// And actually emit the text these sourcemaps are for
|
||||
return emitCallback(hint, node);
|
||||
}
|
||||
@ -519,17 +522,19 @@ namespace ts {
|
||||
setupSourceEntry(sourceFile.fileName, sourceFile.text);
|
||||
}
|
||||
|
||||
function setupSourceEntry(fileName: string, content: string | null) {
|
||||
// Add the file to tsFilePaths
|
||||
// If sourceroot option: Use the relative path corresponding to the common directory path
|
||||
// otherwise source locations relative to map file location
|
||||
const sourcesDirectoryPath = compilerOptions.sourceRoot ? host.getCommonSourceDirectory() : sourceMapDir;
|
||||
function setupSourceEntry(fileName: string, content: string | null, source?: string) {
|
||||
if (!source) {
|
||||
// Add the file to tsFilePaths
|
||||
// If sourceroot option: Use the relative path corresponding to the common directory path
|
||||
// otherwise source locations relative to map file location
|
||||
const sourcesDirectoryPath = compilerOptions.sourceRoot ? host.getCommonSourceDirectory() : sourceMapDir;
|
||||
|
||||
const source = getRelativePathToDirectoryOrUrl(sourcesDirectoryPath,
|
||||
fileName,
|
||||
host.getCurrentDirectory(),
|
||||
host.getCanonicalFileName,
|
||||
/*isAbsolutePathAnUrl*/ true);
|
||||
source = getRelativePathToDirectoryOrUrl(sourcesDirectoryPath,
|
||||
fileName,
|
||||
host.getCurrentDirectory(),
|
||||
host.getCanonicalFileName,
|
||||
/*isAbsolutePathAnUrl*/ true);
|
||||
}
|
||||
|
||||
sourceMapSourceIndex = sourceMapData.sourceMapSources.indexOf(source);
|
||||
if (sourceMapSourceIndex === -1) {
|
||||
|
||||
@ -190,7 +190,7 @@ namespace ts.sourcemaps {
|
||||
};
|
||||
}
|
||||
|
||||
export function calculateDecodedMappings<T>(map: SourceMapData, processPosition: (position: RawSourceMapPosition) => T, host?: { log?(s: string): void }): T[] {
|
||||
function calculateDecodedMappings<T>(map: SourceMapData, processPosition: (position: RawSourceMapPosition) => T, host?: { log?(s: string): void }): T[] {
|
||||
const decoder = decodeMappings(map);
|
||||
const positions = arrayFrom(decoder, processPosition);
|
||||
if (decoder.error) {
|
||||
|
||||
@ -2844,7 +2844,6 @@ namespace ts {
|
||||
inputSourceFileNames: string[]; // Input source file (which one can use on program to get the file), 1:1 mapping with the sourceMapSources list
|
||||
sourceMapNames?: string[]; // Source map's names field - list of names that can be indexed in this source map
|
||||
sourceMapMappings: string; // Source map's mapping field - encoded source map spans
|
||||
sourceMapDecodedMappings: SourceMapSpan[]; // Raw source map spans that were encoded into the sourceMapMappings
|
||||
}
|
||||
|
||||
/** Return code used by getEmitOutput function to indicate status of the function */
|
||||
|
||||
@ -148,7 +148,7 @@ namespace documents {
|
||||
|
||||
public static fromUrl(url: string) {
|
||||
const match = SourceMap._dataURLRegExp.exec(url);
|
||||
return match ? new SourceMap(/*mapFile*/ undefined, new Buffer(match[1], "base64").toString("utf8")) : undefined;
|
||||
return match ? new SourceMap(/*mapFile*/ undefined, (Buffer.from ? Buffer.from(match[1], "base64") : new Buffer(match[1], "base64")).toString("utf8")) : undefined;
|
||||
}
|
||||
|
||||
public static fromSource(text: string): SourceMap | undefined {
|
||||
|
||||
@ -305,7 +305,8 @@ namespace Harness.SourceMapRecorder {
|
||||
}
|
||||
|
||||
SourceMapSpanWriter.initializeSourceMapSpanWriter(sourceMapRecorder, sourceMapData, currentFile);
|
||||
for (const decodedSourceMapping of sourceMapData.sourceMapDecodedMappings) {
|
||||
const mapper = ts.sourcemaps.decodeMappings({ mappings: sourceMapData.sourceMapMappings, sources: sourceMapData.sourceMapSources });
|
||||
for (let { value: decodedSourceMapping, done } = mapper.next(); !done; { value: decodedSourceMapping, done } = mapper.next()) {
|
||||
const currentSourceFile = program.getSourceFile(sourceMapData.inputSourceFileNames[decodedSourceMapping.sourceIndex])!;
|
||||
if (currentSourceFile !== prevSourceFile) {
|
||||
SourceMapSpanWriter.recordNewSourceFileSpan(decodedSourceMapping, currentSourceFile.text);
|
||||
|
||||
@ -63,10 +63,6 @@ namespace utils {
|
||||
return indentation;
|
||||
}
|
||||
|
||||
export function toUtf8(text: string): string {
|
||||
return new Buffer(text).toString("utf8");
|
||||
}
|
||||
|
||||
export function getByteOrderMarkLength(text: string): number {
|
||||
if (text.length >= 1) {
|
||||
const ch0 = text.charCodeAt(0);
|
||||
|
||||
@ -20,6 +20,7 @@ namespace Harness.Parallel.Host {
|
||||
// tslint:disable-next-line:variable-name
|
||||
const FailedTestReporter = require(path.resolve(__dirname, "../../scripts/failed-tests")) as typeof import("../../../scripts/failed-tests");
|
||||
|
||||
const perfdataFileNameFragment = ".parallelperf";
|
||||
const perfData = readSavedPerfData(configOption);
|
||||
const newTasks: Task[] = [];
|
||||
let tasks: Task[] = [];
|
||||
@ -175,8 +176,6 @@ namespace Harness.Parallel.Host {
|
||||
}
|
||||
}
|
||||
|
||||
const perfdataFileNameFragment = ".parallelperf";
|
||||
|
||||
function perfdataFileName(target?: string) {
|
||||
return `${perfdataFileNameFragment}${target ? `.${target}` : ""}.json`;
|
||||
}
|
||||
|
||||
@ -2,7 +2,7 @@ namespace ts {
|
||||
describe("convertToBase64", () => {
|
||||
function runTest(input: string): void {
|
||||
const actual = convertToBase64(input);
|
||||
const expected = new Buffer(input).toString("base64");
|
||||
const expected = (Buffer.from ? Buffer.from(input) : new Buffer(input)).toString("base64");
|
||||
assert.equal(actual, expected, "Encoded string using convertToBase64 does not match buffer.toString('base64')");
|
||||
}
|
||||
|
||||
|
||||
@ -199,7 +199,7 @@ namespace ts.server {
|
||||
|
||||
private write(s: string) {
|
||||
if (this.fd >= 0) {
|
||||
const buf = new Buffer(s);
|
||||
const buf = Buffer.from ? Buffer.from(s) : new Buffer(s);
|
||||
// tslint:disable-next-line no-null-keyword
|
||||
fs.writeSync(this.fd, buf, 0, buf.length, /*position*/ null!); // TODO: GH#18217
|
||||
}
|
||||
@ -869,7 +869,7 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
// Override sys.write because fs.writeSync is not reliable on Node 4
|
||||
sys.write = (s: string) => writeMessage(new Buffer(s, "utf8"));
|
||||
sys.write = (s: string) => writeMessage(Buffer.from ? Buffer.from(s, "utf8") : new Buffer(s, "utf8"));
|
||||
sys.watchFile = (fileName, callback) => {
|
||||
const watchedFile = pollingWatchedFileSet.addFile(fileName, callback);
|
||||
return {
|
||||
|
||||
@ -2544,7 +2544,6 @@ declare namespace ts {
|
||||
inputSourceFileNames: string[];
|
||||
sourceMapNames?: string[];
|
||||
sourceMapMappings: string;
|
||||
sourceMapDecodedMappings: SourceMapSpan[];
|
||||
}
|
||||
/** Return code used by getEmitOutput function to indicate status of the function */
|
||||
enum ExitStatus {
|
||||
@ -8604,17 +8603,6 @@ declare namespace ts.sourcemaps {
|
||||
readonly lastSpan: SourceMapSpan;
|
||||
}
|
||||
function decodeMappings(map: SourceMapData): MappingsDecoder;
|
||||
function calculateDecodedMappings<T>(map: SourceMapData, processPosition: (position: RawSourceMapPosition) => T, host?: {
|
||||
log?(s: string): void;
|
||||
}): T[];
|
||||
interface RawSourceMapPosition {
|
||||
emittedLine: number;
|
||||
emittedColumn: number;
|
||||
sourceLine: number;
|
||||
sourceColumn: number;
|
||||
sourceIndex: number;
|
||||
nameIndex?: number;
|
||||
}
|
||||
}
|
||||
declare namespace ts {
|
||||
function getOriginalNodeId(node: Node): number;
|
||||
|
||||
@ -1822,7 +1822,6 @@ declare namespace ts {
|
||||
inputSourceFileNames: string[];
|
||||
sourceMapNames?: string[];
|
||||
sourceMapMappings: string;
|
||||
sourceMapDecodedMappings: SourceMapSpan[];
|
||||
}
|
||||
/** Return code used by getEmitOutput function to indicate status of the function */
|
||||
enum ExitStatus {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user