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:
Wesley Wigham 2018-07-05 15:12:10 -07:00 committed by GitHub
parent 065e695a28
commit 5b92678285
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 36 additions and 49 deletions

View File

@ -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) {

View File

@ -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) {

View File

@ -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 */

View File

@ -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 {

View File

@ -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);

View File

@ -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);

View File

@ -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`;
}

View File

@ -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')");
}

View File

@ -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 {

View File

@ -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;

View File

@ -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 {