mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-06 02:13:31 -06:00
Merge branch 'transforms-visitEachChildPerf' into transforms-binderPerf
This commit is contained in:
commit
7da8f74eca
@ -86,9 +86,9 @@ namespace ts {
|
||||
const binder = createBinder();
|
||||
|
||||
export function bindSourceFile(file: SourceFile, options: CompilerOptions) {
|
||||
performance.mark("bindStart");
|
||||
const bindStart = performance.mark();
|
||||
binder(file, options);
|
||||
performance.measure("bindTime", "bindStart");
|
||||
performance.measure("bindTime", bindStart);
|
||||
}
|
||||
|
||||
function createBinder(): (file: SourceFile, options: CompilerOptions) => void {
|
||||
|
||||
@ -16512,11 +16512,11 @@ namespace ts {
|
||||
}
|
||||
|
||||
function checkSourceFile(node: SourceFile) {
|
||||
performance.mark("checkStart");
|
||||
const checkStart = performance.mark();
|
||||
|
||||
checkSourceFileWorker(node);
|
||||
|
||||
performance.measure("checkTime", "checkStart");
|
||||
performance.measure("checkTime", checkStart);
|
||||
}
|
||||
|
||||
// Fully type check a source file and collect the relevant diagnostics.
|
||||
|
||||
@ -82,12 +82,9 @@ namespace ts {
|
||||
function getLeadingComments(range: TextRange): CommentRange[];
|
||||
function getLeadingComments(range: TextRange, contextNode: Node, ignoreNodeCallback: (contextNode: Node) => boolean, getTextRangeCallback: (contextNode: Node) => TextRange): CommentRange[];
|
||||
function getLeadingComments(range: TextRange, contextNode?: Node, ignoreNodeCallback?: (contextNode: Node) => boolean, getTextRangeCallback?: (contextNode: Node) => TextRange) {
|
||||
let comments: CommentRange[] = [];
|
||||
let ignored = false;
|
||||
if (contextNode) {
|
||||
range = getTextRangeCallback(contextNode) || range;
|
||||
if (ignoreNodeCallback(contextNode)) {
|
||||
ignored = true;
|
||||
// If the node will not be emitted in JS, remove all the comments (normal,
|
||||
// pinned and `///`) associated with the node, unless it is a triple slash
|
||||
// comment at the top of the file.
|
||||
@ -101,16 +98,14 @@ namespace ts {
|
||||
// The first `///` will NOT be removed while the second one will be removed
|
||||
// even though both nodes will not be emitted.
|
||||
if (range.pos === 0) {
|
||||
comments = filter(getLeadingCommentsOfPosition(0), isTripleSlashComment);
|
||||
return filter(getLeadingCommentsOfPosition(0), isTripleSlashComment);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ignored) {
|
||||
comments = getLeadingCommentsOfPosition(range.pos);
|
||||
}
|
||||
|
||||
return comments;
|
||||
return getLeadingCommentsOfPosition(range.pos);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -277,42 +272,42 @@ namespace ts {
|
||||
reset,
|
||||
setSourceFile,
|
||||
getLeadingComments(range: TextRange, contextNode?: Node, ignoreNodeCallback?: (contextNode: Node) => boolean, getTextRangeCallback?: (contextNode: Node) => TextRange): CommentRange[] {
|
||||
performance.mark("commentStart");
|
||||
const commentStart = performance.mark();
|
||||
const comments = getLeadingComments(range, contextNode, ignoreNodeCallback, getTextRangeCallback);
|
||||
performance.measure("commentTime", "commentStart");
|
||||
performance.measure("commentTime", commentStart);
|
||||
return comments;
|
||||
},
|
||||
getTrailingComments(range: TextRange, contextNode?: Node, ignoreNodeCallback?: (contextNode: Node) => boolean, getTextRangeCallback?: (contextNode: Node) => TextRange): CommentRange[] {
|
||||
performance.mark("commentStart");
|
||||
const commentStart = performance.mark();
|
||||
const comments = getTrailingComments(range, contextNode, ignoreNodeCallback, getTextRangeCallback);
|
||||
performance.measure("commentTime", "commentStart");
|
||||
performance.measure("commentTime", commentStart);
|
||||
return comments;
|
||||
},
|
||||
getTrailingCommentsOfPosition(pos: number): CommentRange[] {
|
||||
performance.mark("commentStart");
|
||||
const commentStart = performance.mark();
|
||||
const comments = getTrailingCommentsOfPosition(pos);
|
||||
performance.measure("commentTime", "commentStart");
|
||||
performance.measure("commentTime", commentStart);
|
||||
return comments;
|
||||
},
|
||||
emitLeadingComments(range: TextRange, comments: CommentRange[], contextNode?: Node, getTextRangeCallback?: (contextNode: Node) => TextRange): void {
|
||||
performance.mark("commentStart");
|
||||
const commentStart = performance.mark();
|
||||
emitLeadingComments(range, comments, contextNode, getTextRangeCallback);
|
||||
performance.measure("commentTime", "commentStart");
|
||||
performance.measure("commentTime", commentStart);
|
||||
},
|
||||
emitTrailingComments(range: TextRange, comments: CommentRange[]): void {
|
||||
performance.mark("commentStart");
|
||||
emitLeadingComments(range, comments);
|
||||
performance.measure("commentTime", "commentStart");
|
||||
const commentStart = performance.mark();
|
||||
emitTrailingComments(range, comments);
|
||||
performance.measure("commentTime", commentStart);
|
||||
},
|
||||
emitLeadingDetachedComments(range: TextRange, contextNode?: Node, ignoreNodeCallback?: (contextNode: Node) => boolean): void {
|
||||
performance.mark("commentStart");
|
||||
const commentStart = performance.mark();
|
||||
emitLeadingDetachedComments(range, contextNode, ignoreNodeCallback);
|
||||
performance.measure("commentTime", "commentStart");
|
||||
performance.measure("commentTime", commentStart);
|
||||
},
|
||||
emitTrailingDetachedComments(range: TextRange, contextNode?: Node, ignoreNodeCallback?: (contextNode: Node) => boolean): void {
|
||||
performance.mark("commentStart");
|
||||
const commentStart = performance.mark();
|
||||
emitTrailingDetachedComments(range, contextNode, ignoreNodeCallback);
|
||||
performance.measure("commentTime", "commentStart");
|
||||
performance.measure("commentTime", commentStart);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@ -1120,6 +1120,18 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
export function getEnvironmentVariable(name: string, host?: CompilerHost) {
|
||||
if (host && host.getEnvironmentVariable) {
|
||||
return host.getEnvironmentVariable(name);
|
||||
}
|
||||
|
||||
if (sys && sys.getEnvironmentVariable) {
|
||||
return sys.getEnvironmentVariable(name);
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
export function copyListRemovingItem<T>(item: T, list: T[]) {
|
||||
const copiedList: T[] = [];
|
||||
for (const e of list) {
|
||||
@ -1139,168 +1151,77 @@ namespace ts {
|
||||
/** Performance measurements for the compiler. */
|
||||
/*@internal*/
|
||||
export namespace performance {
|
||||
interface MarkData {
|
||||
markName: string;
|
||||
timestamp: number;
|
||||
}
|
||||
|
||||
interface MeasureData {
|
||||
measureName: string;
|
||||
startMarkName: string;
|
||||
endMarkName: string;
|
||||
timestamp: number;
|
||||
marksOffset: number;
|
||||
}
|
||||
|
||||
export interface Measure {
|
||||
name: string;
|
||||
startTime: number;
|
||||
duration: number;
|
||||
}
|
||||
|
||||
const markTimestamps: Map<number> = {};
|
||||
const markCounts: Map<number> = {};
|
||||
const measureDurations: Map<number> = {};
|
||||
|
||||
let start = now();
|
||||
let enabled = false;
|
||||
|
||||
/** Gets the current timer for performance measurements. */
|
||||
export function now() {
|
||||
return Date.now();
|
||||
}
|
||||
let counters: Map<number>;
|
||||
let measures: Map<number>;
|
||||
|
||||
/**
|
||||
* Adds a performance mark with the specified name.
|
||||
* Increments a counter with the specified name.
|
||||
*
|
||||
* @param markName The name of the performance mark.
|
||||
* @param counterName The name of the counter.
|
||||
*/
|
||||
export function mark(markName: string) {
|
||||
if (enabled) {
|
||||
markTimestamps[markName] = now();
|
||||
markCounts[markName] = getCount(markName) + 1;
|
||||
export function increment(counterName: string) {
|
||||
if (counters) {
|
||||
counters[counterName] = (getProperty(counters, counterName) || 0) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the names of all marks.
|
||||
* Gets the value of the counter with the specified name.
|
||||
*
|
||||
* @param counterName The name of the counter.
|
||||
*/
|
||||
export function getMarkNames() {
|
||||
return getKeys(markCounts);
|
||||
export function getCount(counterName: string) {
|
||||
return counters && getProperty(counters, counterName) || 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number of marks with the specified name.
|
||||
*
|
||||
* @param markName The name of the marks that should be counted.
|
||||
* Marks the start of a performance measurement.
|
||||
*/
|
||||
export function getCount(markName: string) {
|
||||
return enabled && getProperty(markCounts, markName) || 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the most recent timestamp for the marks with the specified name.
|
||||
*
|
||||
* @param markName The name of the mark.
|
||||
*/
|
||||
export function getTimestamp(markName: string) {
|
||||
return enabled && getProperty(markTimestamps, markName) || 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears performance marks.
|
||||
*
|
||||
* @param markName The name of the mark whose time values should be cleared. If not
|
||||
* specified, all marks will be cleared.
|
||||
*/
|
||||
export function clearMarks(markName?: string) {
|
||||
if (markName === undefined) {
|
||||
forEachKey(markTimestamps, clearMark);
|
||||
}
|
||||
else {
|
||||
clearMark(markName);
|
||||
}
|
||||
}
|
||||
|
||||
function clearMark(markName: string) {
|
||||
if (delete markTimestamps[markName]) {
|
||||
delete markCounts[markName];
|
||||
}
|
||||
export function mark() {
|
||||
return measures ? Date.now() : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a performance measurement with the specified name.
|
||||
*
|
||||
* @param measureName The name of the performance measurement.
|
||||
* @param startMarkName The name of the starting mark.
|
||||
* If provided, the most recent time value of the start mark is used.
|
||||
* If not specified, the value is the time that the performance service was
|
||||
* initialized or the last time it was reset.
|
||||
* @param endMarkName The name of the ending mark.
|
||||
* If provided, the most recent time value of the end mark is used.
|
||||
* If not specified, the current time is used.
|
||||
* @param marker The timestamp of the starting mark.
|
||||
*/
|
||||
export function measure(measureName: string, startMarkName?: string, endMarkName?: string) {
|
||||
if (enabled) {
|
||||
const startTime = startMarkName ? getTimestamp(startMarkName) : start;
|
||||
const endTime = endMarkName ? getTimestamp(endMarkName) : now();
|
||||
const duration = endTime - startTime;
|
||||
measureDurations[measureName] = getDuration(measureName) + duration;
|
||||
export function measure(measureName: string, marker: number) {
|
||||
if (measures) {
|
||||
measures[measureName] = (getProperty(measures, measureName) || 0) + (mark() - marker);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the names of all recorded measures.
|
||||
*/
|
||||
export function getMeasureNames() {
|
||||
return getKeys(measureDurations);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the total duration of all measurements with the supplied name.
|
||||
*
|
||||
* @param measureName The name of the measure whose durations should be accumulated.
|
||||
*/
|
||||
export function getDuration(measureName: string) {
|
||||
return enabled && getProperty(measureDurations, measureName) || 0;
|
||||
return measures && getProperty(measures, measureName) || 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears performance measures.
|
||||
*
|
||||
* @param measureName The name of the measure whose durations should be cleared. If not
|
||||
* specified, all measures will be cleared.
|
||||
*/
|
||||
export function clearMeasures(measureName?: string) {
|
||||
if (measureName === undefined) {
|
||||
forEachKey(measureDurations, clearMeasure);
|
||||
}
|
||||
else {
|
||||
clearMeasure(measureName);
|
||||
}
|
||||
}
|
||||
|
||||
function clearMeasure(measureName: string) {
|
||||
delete measureDurations[measureName];
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets all marks and measurements in the performance service.
|
||||
*/
|
||||
export function reset() {
|
||||
clearMarks();
|
||||
clearMeasures();
|
||||
start = now();
|
||||
}
|
||||
|
||||
/** Enables performance measurements for the compiler. */
|
||||
/** Enables (and resets) performance measurements for the compiler. */
|
||||
export function enable() {
|
||||
enabled = true;
|
||||
counters = { };
|
||||
measures = {
|
||||
programTime: 0,
|
||||
parseTime: 0,
|
||||
bindTime: 0,
|
||||
emitTime: 0,
|
||||
ioReadTime: 0,
|
||||
ioWriteTime: 0,
|
||||
printTime: 0,
|
||||
commentTime: 0,
|
||||
sourceMapTime: 0
|
||||
};
|
||||
}
|
||||
|
||||
/** Disables performance measurements for the compiler. */
|
||||
/** Disables (and clears) performance measurements for the compiler. */
|
||||
export function disable() {
|
||||
enabled = false;
|
||||
counters = undefined;
|
||||
measures = undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,8 +3,6 @@
|
||||
|
||||
/* @internal */
|
||||
namespace ts {
|
||||
const synthesizedLocation: TextRange = { pos: -1, end: -1 };
|
||||
|
||||
let NodeConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node;
|
||||
let SourceFileConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node;
|
||||
|
||||
@ -105,16 +103,6 @@ namespace ts {
|
||||
return clone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a clone of a node with a unique node ID.
|
||||
*/
|
||||
export function getUniqueClone<T extends Node>(node: T): T {
|
||||
const clone = getMutableClone(node);
|
||||
clone.id = 0;
|
||||
getNodeId(clone);
|
||||
return clone;
|
||||
}
|
||||
|
||||
// Literals
|
||||
|
||||
export function createLiteral(textSource: StringLiteral | Identifier, location?: TextRange): StringLiteral;
|
||||
@ -161,7 +149,8 @@ namespace ts {
|
||||
name.text = "";
|
||||
name.originalKeywordKind = SyntaxKind.Unknown;
|
||||
name.autoGenerateKind = GeneratedIdentifierKind.Auto;
|
||||
name.autoGenerateId = nextAutoGenerateId++;
|
||||
name.autoGenerateId = nextAutoGenerateId;
|
||||
nextAutoGenerateId++;
|
||||
if (recordTempVariable) {
|
||||
recordTempVariable(name);
|
||||
}
|
||||
@ -173,7 +162,8 @@ namespace ts {
|
||||
name.text = "";
|
||||
name.originalKeywordKind = SyntaxKind.Unknown;
|
||||
name.autoGenerateKind = GeneratedIdentifierKind.Loop;
|
||||
name.autoGenerateId = nextAutoGenerateId++;
|
||||
name.autoGenerateId = nextAutoGenerateId;
|
||||
nextAutoGenerateId++;
|
||||
return name;
|
||||
}
|
||||
|
||||
@ -182,7 +172,8 @@ namespace ts {
|
||||
name.text = text;
|
||||
name.originalKeywordKind = SyntaxKind.Unknown;
|
||||
name.autoGenerateKind = GeneratedIdentifierKind.Unique;
|
||||
name.autoGenerateId = nextAutoGenerateId++;
|
||||
name.autoGenerateId = nextAutoGenerateId;
|
||||
nextAutoGenerateId++;
|
||||
return name;
|
||||
}
|
||||
|
||||
@ -192,7 +183,8 @@ namespace ts {
|
||||
name.text = "";
|
||||
name.originalKeywordKind = SyntaxKind.Unknown;
|
||||
name.autoGenerateKind = GeneratedIdentifierKind.Node;
|
||||
name.autoGenerateId = nextAutoGenerateId++;
|
||||
name.autoGenerateId = nextAutoGenerateId;
|
||||
nextAutoGenerateId++;
|
||||
return name;
|
||||
}
|
||||
|
||||
@ -1035,8 +1027,9 @@ namespace ts {
|
||||
}
|
||||
|
||||
function createReactNamespace(reactNamespace: string, parent: JsxOpeningLikeElement) {
|
||||
// Create an identifier and give it a parent. This allows us to resolve the react
|
||||
// namespace during emit.
|
||||
// To ensure the emit resolver can properly resolve the namespace, we need to
|
||||
// treat this identifier as if it were a source tree node by clearing the `Synthesized`
|
||||
// flag and setting a parent node.
|
||||
const react = createIdentifier(reactNamespace || "React");
|
||||
react.flags &= ~NodeFlags.Synthesized;
|
||||
react.parent = parent;
|
||||
|
||||
@ -281,9 +281,9 @@ const _super = (function (geti, seti) {
|
||||
}
|
||||
|
||||
function printSourceFileWithExtendedDiagnostics(node: SourceFile) {
|
||||
performance.mark("printStart");
|
||||
const printStart = performance.mark();
|
||||
printSourceFile(node);
|
||||
performance.measure("printTime", "printStart");
|
||||
performance.measure("printTime", printStart);
|
||||
return node;
|
||||
}
|
||||
|
||||
|
||||
@ -783,9 +783,9 @@ namespace ts {
|
||||
function getSourceFile(fileName: string, languageVersion: ScriptTarget, onError?: (message: string) => void): SourceFile {
|
||||
let text: string;
|
||||
try {
|
||||
performance.mark("ioReadStart");
|
||||
const ioReadStart = performance.mark();
|
||||
text = sys.readFile(fileName, options.charset);
|
||||
performance.measure("ioReadTime", "ioReadStart");
|
||||
performance.measure("ioReadTime", ioReadStart);
|
||||
}
|
||||
catch (e) {
|
||||
if (onError) {
|
||||
@ -852,7 +852,7 @@ namespace ts {
|
||||
|
||||
function writeFile(fileName: string, data: string, writeByteOrderMark: boolean, onError?: (message: string) => void) {
|
||||
try {
|
||||
performance.mark("ioWriteStart");
|
||||
const ioWriteStart = performance.mark();
|
||||
ensureDirectoriesExist(getDirectoryPath(normalizePath(fileName)));
|
||||
|
||||
if (isWatchSet(options) && sys.createHash && sys.getModifiedTime) {
|
||||
@ -862,7 +862,7 @@ namespace ts {
|
||||
sys.writeFile(fileName, data, writeByteOrderMark);
|
||||
}
|
||||
|
||||
performance.measure("ioWriteTime", "ioWriteStart");
|
||||
performance.measure("ioWriteTime", ioWriteStart);
|
||||
}
|
||||
catch (e) {
|
||||
if (onError) {
|
||||
@ -997,7 +997,7 @@ namespace ts {
|
||||
let resolvedTypeReferenceDirectives: Map<ResolvedTypeReferenceDirective> = {};
|
||||
let fileProcessingDiagnostics = createDiagnosticCollection();
|
||||
|
||||
performance.mark("programStart");
|
||||
const programStart = performance.mark();
|
||||
|
||||
host = host || createCompilerHost(options);
|
||||
|
||||
@ -1094,7 +1094,7 @@ namespace ts {
|
||||
|
||||
verifyCompilerOptions();
|
||||
|
||||
performance.measure("programTime", "programStart");
|
||||
performance.measure("programTime", programStart);
|
||||
|
||||
return program;
|
||||
|
||||
@ -1335,7 +1335,7 @@ namespace ts {
|
||||
// checked is to not pass the file to getEmitResolver.
|
||||
const emitResolver = getDiagnosticsProducingTypeChecker().getEmitResolver((options.outFile || options.out) ? undefined : sourceFile);
|
||||
|
||||
performance.mark("emitStart");
|
||||
const emitStart = performance.mark();
|
||||
|
||||
// TODO(rbuckton): remove USE_TRANSFORMS condition when we switch to transforms permanently.
|
||||
let useLegacyEmitter = options.useLegacyEmitter;
|
||||
@ -1349,7 +1349,7 @@ namespace ts {
|
||||
getEmitHost(writeFileCallback),
|
||||
sourceFile);
|
||||
|
||||
performance.measure("emitTime", "emitStart");
|
||||
performance.measure("emitTime", emitStart);
|
||||
|
||||
return emitResult;
|
||||
}
|
||||
|
||||
@ -508,10 +508,6 @@ namespace ts {
|
||||
return skipTrivia(currentSourceText, rangeHasDecorators ? (range as Node).decorators.end : range.pos);
|
||||
}
|
||||
|
||||
function getStartPos(range: TextRange) {
|
||||
return skipTrivia(currentSourceText, range.pos);
|
||||
}
|
||||
|
||||
/**
|
||||
* Emits a mapping for the start of a range.
|
||||
*
|
||||
@ -782,30 +778,30 @@ namespace ts {
|
||||
getSourceMapData,
|
||||
setSourceFile,
|
||||
emitPos(pos: number): void {
|
||||
performance.mark("sourcemapStart");
|
||||
const sourcemapStart = performance.mark();
|
||||
emitPos(pos);
|
||||
performance.measure("sourcemapTime", "sourcemapStart");
|
||||
performance.measure("sourceMapTime", sourcemapStart);
|
||||
},
|
||||
emitStart(range: TextRange, contextNode?: Node, ignoreNodeCallback?: (node: Node) => boolean, ignoreChildrenCallback?: (node: Node) => boolean, getTextRangeCallback?: (node: Node) => TextRange): void {
|
||||
performance.mark("sourcemapStart");
|
||||
const sourcemapStart = performance.mark();
|
||||
emitStart(range, contextNode, ignoreNodeCallback, ignoreChildrenCallback, getTextRangeCallback);
|
||||
performance.measure("sourcemapTime", "sourcemapStart");
|
||||
performance.measure("sourceMapTime", sourcemapStart);
|
||||
},
|
||||
emitEnd(range: TextRange, contextNode?: Node, ignoreNodeCallback?: (node: Node) => boolean, ignoreChildrenCallback?: (node: Node) => boolean, getTextRangeCallback?: (node: Node) => TextRange): void {
|
||||
performance.mark("sourcemapStart");
|
||||
const sourcemapStart = performance.mark();
|
||||
emitEnd(range, contextNode, ignoreNodeCallback, ignoreChildrenCallback, getTextRangeCallback);
|
||||
performance.measure("sourcemapTime", "sourcemapStart");
|
||||
performance.measure("sourceMapTime", sourcemapStart);
|
||||
},
|
||||
emitTokenStart(token: SyntaxKind, tokenStartPos: number, contextNode?: Node, ignoreTokenCallback?: (node: Node) => boolean, getTokenTextRangeCallback?: (node: Node, token: SyntaxKind) => TextRange): number {
|
||||
performance.mark("sourcemapStart");
|
||||
const sourcemapStart = performance.mark();
|
||||
tokenStartPos = emitTokenStart(token, tokenStartPos, contextNode, ignoreTokenCallback, getTokenTextRangeCallback);
|
||||
performance.measure("sourcemapTime", "sourcemapStart");
|
||||
performance.measure("sourceMapTime", sourcemapStart);
|
||||
return tokenStartPos;
|
||||
},
|
||||
emitTokenEnd(token: SyntaxKind, tokenEndPos: number, contextNode?: Node, ignoreTokenCallback?: (node: Node) => boolean, getTokenTextRangeCallback?: (node: Node, token: SyntaxKind) => TextRange): number {
|
||||
performance.mark("sourcemapStart");
|
||||
const sourcemapStart = performance.mark();
|
||||
tokenEndPos = emitTokenEnd(token, tokenEndPos, contextNode, ignoreTokenCallback, getTokenTextRangeCallback);
|
||||
performance.measure("sourcemapTime", "sourcemapStart");
|
||||
performance.measure("sourceMapTime", sourcemapStart);
|
||||
return tokenEndPos;
|
||||
},
|
||||
changeEmitSourcePos,
|
||||
|
||||
@ -23,6 +23,100 @@ namespace ts {
|
||||
EmitNotifications = 1 << 1,
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export interface TransformationContext extends LexicalEnvironment {
|
||||
getCompilerOptions(): CompilerOptions;
|
||||
getEmitResolver(): EmitResolver;
|
||||
getEmitHost(): EmitHost;
|
||||
|
||||
/**
|
||||
* Gets flags used to customize later transformations or emit.
|
||||
*/
|
||||
getNodeEmitFlags(node: Node): NodeEmitFlags;
|
||||
|
||||
/**
|
||||
* Sets flags used to customize later transformations or emit.
|
||||
*/
|
||||
setNodeEmitFlags<T extends Node>(node: T, flags: NodeEmitFlags): T;
|
||||
|
||||
/**
|
||||
* Gets the TextRange to use for source maps for the node.
|
||||
*/
|
||||
getSourceMapRange(node: Node): TextRange;
|
||||
|
||||
/**
|
||||
* Sets the TextRange to use for source maps for the node.
|
||||
*/
|
||||
setSourceMapRange<T extends Node>(node: T, range: TextRange): T;
|
||||
|
||||
/**
|
||||
* Gets the TextRange to use for source maps for a token of a node.
|
||||
*/
|
||||
getTokenSourceMapRange(node: Node, token: SyntaxKind): TextRange;
|
||||
|
||||
/**
|
||||
* Sets the TextRange to use for source maps for a token of a node.
|
||||
*/
|
||||
setTokenSourceMapRange<T extends Node>(node: T, token: SyntaxKind, range: TextRange): T;
|
||||
|
||||
/**
|
||||
* Gets the TextRange to use for comments for the node.
|
||||
*/
|
||||
getCommentRange(node: Node): TextRange;
|
||||
|
||||
/**
|
||||
* Sets the TextRange to use for comments for the node.
|
||||
*/
|
||||
setCommentRange<T extends Node>(node: T, range: TextRange): T;
|
||||
|
||||
/**
|
||||
* Hoists a function declaration to the containing scope.
|
||||
*/
|
||||
hoistFunctionDeclaration(node: FunctionDeclaration): void;
|
||||
|
||||
/**
|
||||
* Hoists a variable declaration to the containing scope.
|
||||
*/
|
||||
hoistVariableDeclaration(node: Identifier): void;
|
||||
|
||||
/**
|
||||
* Enables expression substitutions in the pretty printer for the provided SyntaxKind.
|
||||
*/
|
||||
enableSubstitution(kind: SyntaxKind): void;
|
||||
|
||||
/**
|
||||
* Determines whether expression substitutions are enabled for the provided node.
|
||||
*/
|
||||
isSubstitutionEnabled(node: Node): boolean;
|
||||
|
||||
/**
|
||||
* Hook used by transformers to substitute expressions just before they
|
||||
* are emitted by the pretty printer.
|
||||
*/
|
||||
onSubstituteNode?: (node: Node, isExpression: boolean) => Node;
|
||||
|
||||
/**
|
||||
* Enables before/after emit notifications in the pretty printer for the provided
|
||||
* SyntaxKind.
|
||||
*/
|
||||
enableEmitNotification(kind: SyntaxKind): void;
|
||||
|
||||
/**
|
||||
* Determines whether before/after emit notifications should be raised in the pretty
|
||||
* printer when it emits a node.
|
||||
*/
|
||||
isEmitNotificationEnabled(node: Node): boolean;
|
||||
|
||||
/**
|
||||
* Hook used to allow transformers to capture state before or after
|
||||
* the printer emits a node.
|
||||
*/
|
||||
onEmitNode?: (node: Node, emit: (node: Node) => void) => void;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export type Transformer = (context: TransformationContext) => (node: SourceFile) => SourceFile;
|
||||
|
||||
export function getTransformers(compilerOptions: CompilerOptions) {
|
||||
const jsx = compilerOptions.jsx;
|
||||
const languageVersion = getEmitScriptTarget(compilerOptions);
|
||||
@ -62,7 +156,9 @@ namespace ts {
|
||||
* @param transforms An array of Transformers.
|
||||
*/
|
||||
export function transformFiles(resolver: EmitResolver, host: EmitHost, sourceFiles: SourceFile[], transformers: Transformer[]) {
|
||||
const transformId = nextTransformId++;
|
||||
const transformId = nextTransformId;
|
||||
nextTransformId++;
|
||||
|
||||
const tokenSourceMapRanges: Map<TextRange> = { };
|
||||
const lexicalEnvironmentVariableDeclarationsStack: VariableDeclaration[][] = [];
|
||||
const lexicalEnvironmentFunctionDeclarationsStack: FunctionDeclaration[][] = [];
|
||||
|
||||
@ -1009,7 +1009,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
// `declarationName` is the name of the local declaration for the parameter.
|
||||
const declarationName = getUniqueClone(<Identifier>parameter.name);
|
||||
const declarationName = getMutableClone(<Identifier>parameter.name);
|
||||
setNodeEmitFlags(declarationName, NodeEmitFlags.NoSourceMap);
|
||||
|
||||
// `expressionName` is the name of the parameter used in expressions.
|
||||
@ -2918,20 +2918,6 @@ namespace ts {
|
||||
return getDeclarationName(node, allowComments, allowSourceMaps, NodeEmitFlags.LocalName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the export name for a declaration for use in expressions.
|
||||
*
|
||||
* An export name will *always* be prefixed with an module or namespace export modifier
|
||||
* like "exports." if one is required.
|
||||
*
|
||||
* @param node The declaration.
|
||||
* @param allowComments A value indicating whether comments may be emitted for the name.
|
||||
* @param allowSourceMaps A value indicating whether source maps may be emitted for the name.
|
||||
*/
|
||||
function getExportName(node: ClassDeclaration | ClassExpression | FunctionDeclaration, allowComments?: boolean, allowSourceMaps?: boolean) {
|
||||
return getDeclarationName(node, allowComments, allowSourceMaps, NodeEmitFlags.ExportName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of a declaration, without source map or comments.
|
||||
*
|
||||
@ -2940,7 +2926,7 @@ namespace ts {
|
||||
*/
|
||||
function getDeclarationName(node: DeclarationStatement | ClassExpression, allowComments?: boolean, allowSourceMaps?: boolean, emitFlags?: NodeEmitFlags) {
|
||||
if (node.name && !isGeneratedIdentifier(node.name)) {
|
||||
const name = getUniqueClone(node.name);
|
||||
const name = getMutableClone(node.name);
|
||||
emitFlags |= getNodeEmitFlags(node.name);
|
||||
if (!allowSourceMaps) {
|
||||
emitFlags |= NodeEmitFlags.NoSourceMap;
|
||||
|
||||
@ -50,7 +50,7 @@ namespace ts {
|
||||
return undefined; // do not emit export equals for ES6
|
||||
}
|
||||
const original = getOriginalNode(node);
|
||||
return nodeIsSynthesized(original) || resolver.isValueAliasDeclaration(original) ? node: undefined;
|
||||
return nodeIsSynthesized(original) || resolver.isValueAliasDeclaration(original) ? node : undefined;
|
||||
}
|
||||
|
||||
function visitExportDeclaration(node: ExportDeclaration): ExportDeclaration {
|
||||
@ -64,7 +64,7 @@ namespace ts {
|
||||
if (node.exportClause === newExportClause) {
|
||||
return node;
|
||||
}
|
||||
return newExportClause
|
||||
return newExportClause
|
||||
? createExportDeclaration(newExportClause, node.moduleSpecifier)
|
||||
: undefined;
|
||||
}
|
||||
@ -106,12 +106,12 @@ namespace ts {
|
||||
const newNamedBindings = visitNode(node.namedBindings, visitor, isNamedImportBindings, /*optional*/ true);
|
||||
return newDefaultImport !== node.name || newNamedBindings !== node.namedBindings
|
||||
? createImportClause(newDefaultImport, newNamedBindings)
|
||||
: node;
|
||||
: node;
|
||||
}
|
||||
|
||||
function visitNamedBindings(node: NamedImportBindings): VisitResult<NamedImportBindings> {
|
||||
if (node.kind === SyntaxKind.NamespaceImport) {
|
||||
return resolver.isReferencedAliasDeclaration(node) ? node: undefined;
|
||||
return resolver.isReferencedAliasDeclaration(node) ? node : undefined;
|
||||
}
|
||||
else {
|
||||
const newNamedImportElements = visitNodes((<NamedImports>node).elements, visitor, isImportSpecifier);
|
||||
|
||||
@ -619,7 +619,7 @@ namespace ts {
|
||||
if (hasModifier(node, ModifierFlags.Export)) {
|
||||
const variables = getInitializedVariables(node.declarationList);
|
||||
if (variables.length > 0) {
|
||||
let inlineAssignments = createStatement(
|
||||
const inlineAssignments = createStatement(
|
||||
inlineExpressions(
|
||||
map(variables, transformInitializedVariable)
|
||||
),
|
||||
@ -648,7 +648,7 @@ namespace ts {
|
||||
function addExportMemberAssignmentsForBindingName(resultStatements: Statement[], name: BindingName): void {
|
||||
if (isBindingPattern(name)) {
|
||||
for (const element of name.elements) {
|
||||
addExportMemberAssignmentsForBindingName(resultStatements, element.name)
|
||||
addExportMemberAssignmentsForBindingName(resultStatements, element.name);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
@ -12,10 +12,6 @@ namespace ts {
|
||||
const {
|
||||
getNodeEmitFlags,
|
||||
setNodeEmitFlags,
|
||||
getCommentRange,
|
||||
setCommentRange,
|
||||
getSourceMapRange,
|
||||
setSourceMapRange,
|
||||
startLexicalEnvironment,
|
||||
endLexicalEnvironment,
|
||||
hoistVariableDeclaration,
|
||||
|
||||
@ -933,10 +933,10 @@ namespace ts {
|
||||
function transformParameterWithPropertyAssignment(node: ParameterDeclaration) {
|
||||
Debug.assert(isIdentifier(node.name));
|
||||
const name = node.name as Identifier;
|
||||
const propertyName = getUniqueClone(name);
|
||||
const propertyName = getMutableClone(name);
|
||||
setNodeEmitFlags(propertyName, NodeEmitFlags.NoComments | NodeEmitFlags.NoSourceMap);
|
||||
|
||||
const localName = getUniqueClone(name);
|
||||
const localName = getMutableClone(name);
|
||||
setNodeEmitFlags(localName, NodeEmitFlags.NoComments);
|
||||
|
||||
return startOnNewLine(
|
||||
@ -2953,7 +2953,7 @@ namespace ts {
|
||||
*/
|
||||
function getDeclarationName(node: DeclarationStatement | ClassExpression, allowComments?: boolean, allowSourceMaps?: boolean, emitFlags?: NodeEmitFlags) {
|
||||
if (node.name) {
|
||||
const name = getUniqueClone(node.name);
|
||||
const name = getMutableClone(node.name);
|
||||
emitFlags |= getNodeEmitFlags(node.name);
|
||||
if (!allowSourceMaps) {
|
||||
emitFlags |= NodeEmitFlags.NoSourceMap;
|
||||
@ -2974,19 +2974,6 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function getDeclarationNameExpression(node: DeclarationStatement) {
|
||||
const name = getDeclarationName(node);
|
||||
if (isNamespaceExport(node)) {
|
||||
return getNamespaceMemberName(name);
|
||||
}
|
||||
else {
|
||||
// We set the "ExportName" flag to indicate to any module transformer
|
||||
// downstream that any `exports.` prefix should be added.
|
||||
setNodeEmitFlags(name, getNodeEmitFlags(name) | NodeEmitFlags.ExportName);
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
function getClassPrototype(node: ClassExpression | ClassDeclaration) {
|
||||
return createPropertyAccess(getDeclarationName(node), "prototype");
|
||||
}
|
||||
@ -3090,7 +3077,7 @@ namespace ts {
|
||||
currentDecoratedClassAliases[getOriginalNodeId(node)] = decoratedClassAliases[getOriginalNodeId(node)];
|
||||
}
|
||||
else if (node.kind === SyntaxKind.Identifier) {
|
||||
const declaration = resolver.getReferencedValueDeclaration(<Identifier>node)
|
||||
const declaration = resolver.getReferencedValueDeclaration(<Identifier>node);
|
||||
if (declaration && isClassWithDecorators(declaration)) {
|
||||
currentDecoratedClassAliases[getOriginalNodeId(declaration)] = decoratedClassAliases[getOriginalNodeId(declaration)];
|
||||
}
|
||||
|
||||
@ -11,16 +11,6 @@ namespace ts {
|
||||
value: string;
|
||||
}
|
||||
|
||||
interface Mark {
|
||||
markName: string;
|
||||
count: number;
|
||||
}
|
||||
|
||||
interface Measure {
|
||||
measureName: string;
|
||||
duration: number;
|
||||
}
|
||||
|
||||
let reportDiagnostic = reportDiagnosticSimply;
|
||||
|
||||
function reportDiagnostics(diagnostics: Diagnostic[], host: CompilerHost): void {
|
||||
@ -560,7 +550,6 @@ namespace ts {
|
||||
let statistics: Statistic[];
|
||||
if (compilerOptions.diagnostics || compilerOptions.extendedDiagnostics) {
|
||||
performance.enable();
|
||||
performance.reset();
|
||||
statistics = [];
|
||||
}
|
||||
|
||||
@ -586,6 +575,12 @@ namespace ts {
|
||||
reportStatisticalValue("Memory used", Math.round(memoryUsed / 1000) + "K");
|
||||
}
|
||||
|
||||
if (compilerOptions.extendedDiagnostics) {
|
||||
reportTimeStatistic("Print time", performance.getDuration("printTime"));
|
||||
reportTimeStatistic("Comment time", performance.getDuration("commentTime"));
|
||||
reportTimeStatistic("SourceMap time", performance.getDuration("sourceMapTime"));
|
||||
}
|
||||
|
||||
// Individual component times.
|
||||
// Note: To match the behavior of previous versions of the compiler, the reported parse time includes
|
||||
// I/O read time and processing time for triple-slash references and module imports, and the reported
|
||||
@ -601,47 +596,9 @@ namespace ts {
|
||||
reportTimeStatistic("Check time", checkTime);
|
||||
reportTimeStatistic("Emit time", emitTime);
|
||||
reportTimeStatistic("Total time", programTime + bindTime + checkTime + emitTime);
|
||||
|
||||
if (compilerOptions.extendedDiagnostics) {
|
||||
sys.write("Extended Diagnostics:" + sys.newLine);
|
||||
const marks: Mark[] = [];
|
||||
for (const markName of performance.getMarkNames()) {
|
||||
if (/^(ioReadStart|ioWriteStart|programStart|bindStart|checkStart|emitStart)$/.test(markName)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
marks.push({ markName, count: performance.getCount(markName) });
|
||||
}
|
||||
|
||||
if (marks.length) {
|
||||
marks.sort((x, y) => -compareValues(x.count, y.count));
|
||||
sys.write("Marks:" + sys.newLine);
|
||||
for (const { markName, count } of marks) {
|
||||
reportCountStatistic(" " + markName, count);
|
||||
}
|
||||
}
|
||||
|
||||
const measures: Measure[] = [];
|
||||
for (const measureName of performance.getMeasureNames()) {
|
||||
if (/^(ioReadTime|ioWriteTime|programTime|bindTime|checkTime|emitTime)$/.test(measureName)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
measures.push({ measureName, duration: performance.getDuration(measureName) });
|
||||
}
|
||||
|
||||
if (measures.length) {
|
||||
measures.sort((x, y) => -compareValues(x.duration, y.duration));
|
||||
sys.write("Measures:" + sys.newLine);
|
||||
for (const { measureName, duration } of measures) {
|
||||
reportTimeStatistic(" " + measureName, duration);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
reportStatistics();
|
||||
|
||||
performance.disable();
|
||||
performance.reset();
|
||||
}
|
||||
|
||||
return { program, exitStatus };
|
||||
|
||||
@ -3024,99 +3024,6 @@ namespace ts {
|
||||
endLexicalEnvironment(): Statement[];
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export interface TransformationContext extends LexicalEnvironment {
|
||||
getCompilerOptions(): CompilerOptions;
|
||||
getEmitResolver(): EmitResolver;
|
||||
getEmitHost(): EmitHost;
|
||||
|
||||
/**
|
||||
* Gets flags used to customize later transformations or emit.
|
||||
*/
|
||||
getNodeEmitFlags(node: Node): NodeEmitFlags;
|
||||
|
||||
/**
|
||||
* Sets flags used to customize later transformations or emit.
|
||||
*/
|
||||
setNodeEmitFlags<T extends Node>(node: T, flags: NodeEmitFlags): T;
|
||||
|
||||
/**
|
||||
* Gets the TextRange to use for source maps for the node.
|
||||
*/
|
||||
getSourceMapRange(node: Node): TextRange;
|
||||
|
||||
/**
|
||||
* Sets the TextRange to use for source maps for the node.
|
||||
*/
|
||||
setSourceMapRange<T extends Node>(node: T, range: TextRange): T;
|
||||
|
||||
/**
|
||||
* Gets the TextRange to use for source maps for a token of a node.
|
||||
*/
|
||||
getTokenSourceMapRange(node: Node, token: SyntaxKind): TextRange;
|
||||
|
||||
/**
|
||||
* Sets the TextRange to use for source maps for a token of a node.
|
||||
*/
|
||||
setTokenSourceMapRange<T extends Node>(node: T, token: SyntaxKind, range: TextRange): T;
|
||||
|
||||
/**
|
||||
* Gets the TextRange to use for comments for the node.
|
||||
*/
|
||||
getCommentRange(node: Node): TextRange;
|
||||
|
||||
/**
|
||||
* Sets the TextRange to use for comments for the node.
|
||||
*/
|
||||
setCommentRange<T extends Node>(node: T, range: TextRange): T;
|
||||
|
||||
/**
|
||||
* Hoists a function declaration to the containing scope.
|
||||
*/
|
||||
hoistFunctionDeclaration(node: FunctionDeclaration): void;
|
||||
|
||||
/**
|
||||
* Hoists a variable declaration to the containing scope.
|
||||
*/
|
||||
hoistVariableDeclaration(node: Identifier): void;
|
||||
|
||||
/**
|
||||
* Enables expression substitutions in the pretty printer for the provided SyntaxKind.
|
||||
*/
|
||||
enableSubstitution(kind: SyntaxKind): void;
|
||||
|
||||
/**
|
||||
* Determines whether expression substitutions are enabled for the provided node.
|
||||
*/
|
||||
isSubstitutionEnabled(node: Node): boolean;
|
||||
|
||||
/**
|
||||
* Hook used by transformers to substitute expressions just before they
|
||||
* are emitted by the pretty printer.
|
||||
*/
|
||||
onSubstituteNode?: (node: Node, isExpression: boolean) => Node;
|
||||
|
||||
/**
|
||||
* Enables before/after emit notifications in the pretty printer for the provided
|
||||
* SyntaxKind.
|
||||
*/
|
||||
enableEmitNotification(kind: SyntaxKind): void;
|
||||
|
||||
/**
|
||||
* Determines whether before/after emit notifications should be raised in the pretty
|
||||
* printer when it emits a node.
|
||||
*/
|
||||
isEmitNotificationEnabled(node: Node): boolean;
|
||||
|
||||
/**
|
||||
* Hook used to allow transformers to capture state before or after
|
||||
* the printer emits a node.
|
||||
*/
|
||||
onEmitNode?: (node: Node, emit: (node: Node) => void) => void;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export type Transformer = (context: TransformationContext) => (node: SourceFile) => SourceFile;
|
||||
|
||||
export interface TextSpan {
|
||||
start: number;
|
||||
|
||||
@ -226,18 +226,6 @@ namespace ts {
|
||||
return `${ file.fileName }(${ loc.line + 1 },${ loc.character + 1 })`;
|
||||
}
|
||||
|
||||
export function getEnvironmentVariable(name: string, host?: CompilerHost) {
|
||||
if (host && host.getEnvironmentVariable) {
|
||||
return host.getEnvironmentVariable(name);
|
||||
}
|
||||
|
||||
if (sys && sys.getEnvironmentVariable) {
|
||||
return sys.getEnvironmentVariable(name);
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
export function getStartPosOfNode(node: Node): number {
|
||||
return node.pos;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user