mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-12-12 03:20:56 -06:00
Reduce stack depth due to substitution
This commit is contained in:
parent
3b20d82ba6
commit
a295aa8fd1
@ -37,7 +37,7 @@ namespace ts {
|
||||
|
||||
// transform hooks
|
||||
onEmitNode: transform.emitNodeWithNotification,
|
||||
onSubstituteNode: transform.emitNodeWithSubstitution,
|
||||
substituteNode: transform.substituteNode,
|
||||
|
||||
// sourcemap hooks
|
||||
onEmitSourceMapOfNode: sourceMap.emitNodeWithSourceMap,
|
||||
@ -198,7 +198,7 @@ namespace ts {
|
||||
onEmitNode,
|
||||
onEmitHelpers,
|
||||
onSetSourceFile,
|
||||
onSubstituteNode,
|
||||
substituteNode,
|
||||
} = handlers;
|
||||
|
||||
const newLine = getNewLineCharacter(printerOptions);
|
||||
@ -327,8 +327,8 @@ namespace ts {
|
||||
setWriter(/*output*/ undefined);
|
||||
}
|
||||
|
||||
function emit(node: Node, hint = EmitHint.Unspecified) {
|
||||
pipelineEmitWithNotification(hint, node);
|
||||
function emit(node: Node) {
|
||||
pipelineEmitWithNotification(EmitHint.Unspecified, node);
|
||||
}
|
||||
|
||||
function emitIdentifierName(node: Identifier) {
|
||||
@ -349,6 +349,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function pipelineEmitWithComments(hint: EmitHint, node: Node) {
|
||||
node = trySubstituteNode(hint, node);
|
||||
if (emitNodeWithComments && hint !== EmitHint.SourceFile) {
|
||||
emitNodeWithComments(hint, node, pipelineEmitWithSourceMap);
|
||||
}
|
||||
@ -359,16 +360,7 @@ namespace ts {
|
||||
|
||||
function pipelineEmitWithSourceMap(hint: EmitHint, node: Node) {
|
||||
if (onEmitSourceMapOfNode && hint !== EmitHint.SourceFile && hint !== EmitHint.IdentifierName) {
|
||||
onEmitSourceMapOfNode(hint, node, pipelineEmitWithSubstitution);
|
||||
}
|
||||
else {
|
||||
pipelineEmitWithSubstitution(hint, node);
|
||||
}
|
||||
}
|
||||
|
||||
function pipelineEmitWithSubstitution(hint: EmitHint, node: Node) {
|
||||
if (onSubstituteNode) {
|
||||
onSubstituteNode(hint, node, pipelineEmitWithHint);
|
||||
onEmitSourceMapOfNode(hint, node, pipelineEmitWithHint);
|
||||
}
|
||||
else {
|
||||
pipelineEmitWithHint(hint, node);
|
||||
@ -634,7 +626,7 @@ namespace ts {
|
||||
// If the node is an expression, try to emit it as an expression with
|
||||
// substitution.
|
||||
if (isExpression(node)) {
|
||||
return pipelineEmitWithSubstitution(EmitHint.Expression, node);
|
||||
return pipelineEmitExpression(trySubstituteNode(EmitHint.Expression, node));
|
||||
}
|
||||
}
|
||||
|
||||
@ -731,6 +723,10 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function trySubstituteNode(hint: EmitHint, node: Node) {
|
||||
return node && substituteNode && substituteNode(hint, node) || node;
|
||||
}
|
||||
|
||||
function emitBodyIndirect(node: Node, elements: NodeArray<Node>, emitCallback: (node: Node) => void): void {
|
||||
if (emitBodyWithDetachedComments) {
|
||||
emitBodyWithDetachedComments(node, elements, emitCallback);
|
||||
|
||||
@ -159,7 +159,7 @@ namespace ts {
|
||||
|
||||
return {
|
||||
transformed,
|
||||
emitNodeWithSubstitution,
|
||||
substituteNode,
|
||||
emitNodeWithNotification,
|
||||
dispose
|
||||
};
|
||||
@ -191,14 +191,9 @@ namespace ts {
|
||||
* @param node The node to emit.
|
||||
* @param emitCallback The callback used to emit the node or its substitute.
|
||||
*/
|
||||
function emitNodeWithSubstitution(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void) {
|
||||
Debug.assert(state < TransformationState.Disposed, "Cannot invoke TransformationResult callbacks after the result is disposed.");
|
||||
if (node) {
|
||||
if (isSubstitutionEnabled(node)) {
|
||||
node = onSubstituteNode(hint, node) || node;
|
||||
}
|
||||
emitCallback(hint, node);
|
||||
}
|
||||
function substituteNode(hint: EmitHint, node: Node) {
|
||||
Debug.assert(state < TransformationState.Disposed, "Cannot substitute a node after the result is disposed.");
|
||||
return node && isSubstitutionEnabled(node) && onSubstituteNode(hint, node) || node;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -3549,7 +3549,7 @@ namespace ts {
|
||||
if (enabledSubstitutions & ES2015SubstitutionFlags.BlockScopedBindings) {
|
||||
const original = getParseTreeNode(node, isIdentifier);
|
||||
if (original && isNameOfDeclarationWithCollidingName(original)) {
|
||||
return getGeneratedNameForNode(original);
|
||||
return setTextRange(getGeneratedNameForNode(original), node);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3602,7 +3602,7 @@ namespace ts {
|
||||
if (enabledSubstitutions & ES2015SubstitutionFlags.BlockScopedBindings) {
|
||||
const declaration = resolver.getReferencedDeclarationWithCollidingName(node);
|
||||
if (declaration) {
|
||||
return getGeneratedNameForNode(declaration.name);
|
||||
return setTextRange(getGeneratedNameForNode(declaration.name), node);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -3322,8 +3322,6 @@ namespace ts {
|
||||
: getTextOfNode(node.argumentExpression);
|
||||
|
||||
addSyntheticTrailingComment(substitute, SyntaxKind.MultiLineCommentTrivia, ` ${propertyName} `);
|
||||
// wrap the substituted node so that it emits its own comments.
|
||||
return createPartiallyEmittedExpression(substitute);
|
||||
}
|
||||
|
||||
return substitute;
|
||||
|
||||
@ -3901,13 +3901,12 @@
|
||||
diagnostics?: Diagnostic[];
|
||||
|
||||
/**
|
||||
* Emits the substitute for a node, if one is available; otherwise, emits the node.
|
||||
* Gets a substitute for a node, if one is available; otherwise, returns the original node.
|
||||
*
|
||||
* @param hint A hint as to the intended usage of the node.
|
||||
* @param node The node to substitute.
|
||||
* @param emitCallback A callback used to emit the node or its substitute.
|
||||
*/
|
||||
emitNodeWithSubstitution(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void): void;
|
||||
substituteNode(hint: EmitHint, node: Node): Node;
|
||||
|
||||
/**
|
||||
* Emits a node with possible notification.
|
||||
@ -3998,23 +3997,20 @@
|
||||
/**
|
||||
* A hook used by the Printer to perform just-in-time substitution of a node. This is
|
||||
* primarily used by node transformations that need to substitute one node for another,
|
||||
* such as replacing `myExportedVar` with `exports.myExportedVar`. A compatible
|
||||
* implementation **must** invoke `emitCallback` eith the provided `hint` and either
|
||||
* the provided `node`, or its substitute.
|
||||
* such as replacing `myExportedVar` with `exports.myExportedVar`.
|
||||
* @param hint A hint indicating the intended purpose of the node.
|
||||
* @param node The node to emit.
|
||||
* @param emitCallback A callback that, when invoked, will emit the node.
|
||||
* @example
|
||||
* ```ts
|
||||
* var printer = createPrinter(printerOptions, {
|
||||
* onSubstituteNode(hint, node, emitCallback) {
|
||||
* substituteNode(hint, node) {
|
||||
* // perform substitution if necessary...
|
||||
* emitCallback(hint, node);
|
||||
* return node;
|
||||
* }
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
onSubstituteNode?(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void): void;
|
||||
substituteNode?(hint: EmitHint, node: Node): Node;
|
||||
/*@internal*/ onEmitSourceMapOfNode?: (hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void) => void;
|
||||
/*@internal*/ onEmitSourceMapOfToken?: (node: Node, token: SyntaxKind, pos: number, emitCallback: (token: SyntaxKind, pos: number) => number) => number;
|
||||
/*@internal*/ onEmitSourceMapOfPosition?: (pos: number) => void;
|
||||
|
||||
@ -709,7 +709,7 @@ namespace ts {
|
||||
return node ? f(initial, node) : initial;
|
||||
}
|
||||
|
||||
function reduceNodeArray<T>(nodes: Node[], f: (memo: T, nodes: Node[]) => T, initial: T) {
|
||||
function reduceNodeArray<T>(nodes: NodeArray<Node>, f: (memo: T, nodes: NodeArray<Node>) => T, initial: T) {
|
||||
return nodes ? f(initial, nodes) : initial;
|
||||
}
|
||||
|
||||
@ -721,12 +721,12 @@ namespace ts {
|
||||
* @param initial The initial value to supply to the reduction.
|
||||
* @param f The callback function
|
||||
*/
|
||||
export function reduceEachChild<T>(node: Node, initial: T, cbNode: (memo: T, node: Node) => T, cbNodeArray?: (memo: T, nodes: Node[]) => T): T {
|
||||
export function reduceEachChild<T>(node: Node, initial: T, cbNode: (memo: T, node: Node) => T, cbNodeArray?: (memo: T, nodes: NodeArray<Node>) => T): T {
|
||||
if (node === undefined) {
|
||||
return initial;
|
||||
}
|
||||
|
||||
const reduceNodes: (nodes: Node[], f: (memo: T, node: Node | Node[]) => T, initial: T) => T = cbNodeArray ? reduceNodeArray : reduceLeft;
|
||||
const reduceNodes: (nodes: NodeArray<Node>, f: (memo: T, node: Node | NodeArray<Node>) => T, initial: T) => T = cbNodeArray ? reduceNodeArray : reduceLeft;
|
||||
const cbNodes = cbNodeArray || cbNode;
|
||||
const kind = node.kind;
|
||||
|
||||
|
||||
@ -9,7 +9,7 @@ namespace ts {
|
||||
const transformed = transform(createSourceFile("source.ts", source, ScriptTarget.ES2015), transformers);
|
||||
const printer = createPrinter({ newLine: NewLineKind.CarriageReturnLineFeed }, {
|
||||
onEmitNode: transformed.emitNodeWithNotification,
|
||||
onSubstituteNode: transformed.emitNodeWithSubstitution
|
||||
substituteNode: transformed.substituteNode
|
||||
});
|
||||
const result = printer.printBundle(createBundle(transformed.transformed));
|
||||
transformed.dispose();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user