Extract emit-specific properties into EmitNode

This commit is contained in:
Ron Buckton 2016-09-26 11:20:24 -07:00
parent b7d1d11ba3
commit f2de4508df
16 changed files with 492 additions and 500 deletions

View File

@ -2592,7 +2592,7 @@ namespace ts {
}
// Currently, we only support generators that were originally async function bodies.
if (asteriskToken && node.emitFlags & NodeEmitFlags.AsyncFunctionBody) {
if (asteriskToken && getEmitFlags(node) & EmitFlags.AsyncFunctionBody) {
transformFlags |= TransformFlags.AssertGenerator;
}
@ -2667,7 +2667,7 @@ namespace ts {
// down-level generator.
// Currently we do not support transforming any other generator fucntions
// down level.
if (asteriskToken && node.emitFlags & NodeEmitFlags.AsyncFunctionBody) {
if (asteriskToken && getEmitFlags(node) & EmitFlags.AsyncFunctionBody) {
transformFlags |= TransformFlags.AssertGenerator;
}
}
@ -2698,7 +2698,7 @@ namespace ts {
// down-level generator.
// Currently we do not support transforming any other generator fucntions
// down level.
if (asteriskToken && node.emitFlags & NodeEmitFlags.AsyncFunctionBody) {
if (asteriskToken && getEmitFlags(node) & EmitFlags.AsyncFunctionBody) {
transformFlags |= TransformFlags.AssertGenerator;
}

View File

@ -41,11 +41,11 @@ namespace ts {
}
if (node) {
const { pos, end } = node.commentRange || node;
const emitFlags = node.emitFlags;
const { pos, end } = getCommentRange(node);
const emitFlags = getEmitFlags(node);
if ((pos < 0 && end < 0) || (pos === end)) {
// Both pos and end are synthesized, so just emit the node without comments.
if (emitFlags & NodeEmitFlags.NoNestedComments) {
if (emitFlags & EmitFlags.NoNestedComments) {
disableCommentsAndEmit(node, emitCallback);
}
else {
@ -58,8 +58,8 @@ namespace ts {
}
const isEmittedNode = node.kind !== SyntaxKind.NotEmittedStatement;
const skipLeadingComments = pos < 0 || (emitFlags & NodeEmitFlags.NoLeadingComments) !== 0;
const skipTrailingComments = end < 0 || (emitFlags & NodeEmitFlags.NoTrailingComments) !== 0;
const skipLeadingComments = pos < 0 || (emitFlags & EmitFlags.NoLeadingComments) !== 0;
const skipTrailingComments = end < 0 || (emitFlags & EmitFlags.NoTrailingComments) !== 0;
// Emit leading comments if the position is not synthesized and the node
// has not opted out from emitting leading comments.
@ -90,7 +90,7 @@ namespace ts {
performance.measure("commentTime", "preEmitNodeWithComment");
}
if (emitFlags & NodeEmitFlags.NoNestedComments) {
if (emitFlags & EmitFlags.NoNestedComments) {
disableCommentsAndEmit(node, emitCallback);
}
else {
@ -125,9 +125,9 @@ namespace ts {
}
const { pos, end } = detachedRange;
const emitFlags = node.emitFlags;
const skipLeadingComments = pos < 0 || (emitFlags & NodeEmitFlags.NoLeadingComments) !== 0;
const skipTrailingComments = disabled || end < 0 || (emitFlags & NodeEmitFlags.NoTrailingComments) !== 0;
const emitFlags = getEmitFlags(node);
const skipLeadingComments = pos < 0 || (emitFlags & EmitFlags.NoLeadingComments) !== 0;
const skipTrailingComments = disabled || end < 0 || (emitFlags & EmitFlags.NoTrailingComments) !== 0;
if (!skipLeadingComments) {
emitDetachedCommentsAndUpdateCommentsInfo(detachedRange);
@ -137,7 +137,7 @@ namespace ts {
performance.measure("commentTime", "preEmitBodyWithDetachedComments");
}
if (emitFlags & NodeEmitFlags.NoNestedComments) {
if (emitFlags & EmitFlags.NoNestedComments) {
disableCommentsAndEmit(node, emitCallback);
}
else {

View File

@ -824,6 +824,72 @@ namespace ts {
};
}
/**
* High-order function, creates a function that executes a function composition.
* For example, `chain(a, b)` is the equivalent of `x => ((a', b') => y => b'(a'(y)))(a(x), b(x))`
*
* @param args The functions to chain.
*/
export function chain<T, U>(...args: ((t: T) => (u: U) => U)[]): (t: T) => (u: U) => U;
export function chain<T, U>(a: (t: T) => (u: U) => U, b: (t: T) => (u: U) => U, c: (t: T) => (u: U) => U, d: (t: T) => (u: U) => U, e: (t: T) => (u: U) => U): (t: T) => (u: U) => U {
if (e) {
const args: ((t: T) => (u: U) => U)[] = [];
for (let i = 0; i < arguments.length; i++) {
args[i] = arguments[i];
}
return t => compose(...map(args, f => f(t)));
}
else if (d) {
return t => compose(a(t), b(t), c(t), d(t));
}
else if (c) {
return t => compose(a(t), b(t), c(t));
}
else if (b) {
return t => compose(a(t), b(t));
}
else if (a) {
return t => compose(a(t));
}
else {
return t => u => u;
}
}
/**
* High-order function, composes functions. Note that functions are composed inside-out;
* for example, `compose(a, b)` is the equivalent of `x => b(a(x))`.
*
* @param args The functions to compose.
*/
export function compose<T>(...args: ((t: T) => T)[]): (t: T) => T;
export function compose<T>(a: (t: T) => T, b: (t: T) => T, c: (t: T) => T, d: (t: T) => T, e: (t: T) => T): (t: T) => T {
if (e) {
const args: ((t: T) => T)[] = [];
for (let i = 0; i < arguments.length; i++) {
args[i] = arguments[i];
}
return t => reduceLeft<(t: T) => T, T>(args, (u, f) => f(u), t);
}
else if (d) {
return t => d(c(b(a(t))));
}
else if (c) {
return t => c(b(a(t)));
}
else if (b) {
return t => b(a(t));
}
else if (a) {
return t => a(t);
}
else {
return t => t;
}
}
function formatStringFromArgs(text: string, args: { [index: number]: any; }, baseIndex?: number): string {
baseIndex = baseIndex || 0;
@ -1715,7 +1781,6 @@ namespace ts {
this.transformFlags = TransformFlags.None;
this.parent = undefined;
this.original = undefined;
this.transformId = 0;
}
export let objectAllocator: ObjectAllocator = {

View File

@ -244,7 +244,6 @@ const _super = (function (geti, seti) {
// Extract helpers from the result
const {
getTokenSourceMapRange,
isSubstitutionEnabled,
isEmitNotificationEnabled,
onSubstituteNode,
@ -351,7 +350,7 @@ const _super = (function (geti, seti) {
currentFileIdentifiers = node.identifiers;
sourceMap.setSourceFile(node);
comments.setSourceFile(node);
emitNodeWithNotification(node, emitWorker);
emitNodeWithNotification(node, emitWithSubstitution);
}
/**
@ -361,7 +360,6 @@ const _super = (function (geti, seti) {
emitNodeWithNotification(node, emitWithComments);
}
/**
* Emits a node with comments.
*
@ -379,17 +377,37 @@ const _super = (function (geti, seti) {
* and should only be called indirectly from emitWithComments.
*/
function emitWithSourceMap(node: Node) {
emitNodeWithSourceMap(node, emitWorker);
emitNodeWithSourceMap(node, emitWithSubstitution);
}
/**
* Emits a node with possible substitution.
*
* NOTE: Do not call this method directly. It is part of the emit pipeline
* and should only be called indirectly from emitWithSourceMap or
* emitIdentifierNameWithComments.
*/
function emitWithSubstitution(node: Node) {
emitNodeWithSubstitution(node, /*isExpression*/ false, emitWorker);
}
/**
* Emits an IdentifierName.
*/
function emitIdentifierName(node: Identifier) {
if (node) {
emitNodeWithNotification(node, emitIdentifierNameWithComments);
}
}
/**
* Emits an IdentifierName with possible comments.
*
* NOTE: Do not call this method directly. It is part of the emit pipeline
* and should only be called indirectly from emitIdentifierName.
*/
function emitIdentifierNameWithComments(node: Identifier) {
emitNodeWithComments(node, emitWorker);
emitNodeWithComments(node, emitWithSubstitution);
}
/**
@ -410,18 +428,30 @@ const _super = (function (geti, seti) {
}
/**
* Emits an expression with source maps.
* Emits an expression with possible source maps.
*
* NOTE: Do not call this method directly. It is part of the emitExpression pipeline
* and should only be called indirectly from emitExpressionWithComments.
*/
function emitExpressionWithSourceMap(node: Expression) {
emitNodeWithSourceMap(node, emitExpressionWorker);
emitNodeWithSourceMap(node, emitExpressionWithSubstitution);
}
/**
* Emits a node with emit notification if available.
* Emits an expression with possible substitution.
*
* NOTE: Do not call this method directly. It is part of the emitExpression pipeline
* and should only be called indirectly from emitExpressionWithSourceMap or
* from emitWorker.
*/
function emitExpressionWithSubstitution(node: Expression) {
emitNodeWithSubstitution(node, /*isExpression*/ true, emitExpressionWorker);
}
/**
* Emits a node with possible emit notification.
*/
// TODO(rbuckton): Move this into transformer.ts
function emitNodeWithNotification(node: Node, emitCallback: (node: Node) => void) {
if (node) {
if (isEmitNotificationEnabled(node)) {
@ -433,6 +463,10 @@ const _super = (function (geti, seti) {
}
}
/**
* Emits a node with possible source maps.
*/
// TODO(rbuckton): Move this into sourcemap.ts
function emitNodeWithSourceMap(node: Node, emitCallback: (node: Node) => void) {
if (node) {
emitStart(/*range*/ node, /*contextNode*/ node, shouldSkipLeadingSourceMapForNode, shouldSkipSourceMapForChildren, getSourceMapRange);
@ -441,10 +475,6 @@ const _super = (function (geti, seti) {
}
}
function getSourceMapRange(node: Node) {
return node.sourceMapRange || node;
}
/**
* Determines whether to skip leading comment emit for a node.
*
@ -453,9 +483,10 @@ const _super = (function (geti, seti) {
*
* @param node A Node.
*/
// TODO(rbuckton): Move this into comments.ts
function shouldSkipLeadingCommentsForNode(node: Node) {
return isNotEmittedStatement(node)
|| (node.emitFlags & NodeEmitFlags.NoLeadingComments) !== 0;
|| (getEmitFlags(node) & EmitFlags.NoLeadingComments) !== 0;
}
/**
@ -466,12 +497,12 @@ const _super = (function (geti, seti) {
*
* @param node A Node.
*/
// TODO(rbuckton): Move this into sourcemap.ts
function shouldSkipLeadingSourceMapForNode(node: Node) {
return isNotEmittedStatement(node)
|| (node.emitFlags & NodeEmitFlags.NoLeadingSourceMap) !== 0;
|| (getEmitFlags(node) & EmitFlags.NoLeadingSourceMap) !== 0;
}
/**
* Determines whether to skip source map emit for the end position of a node.
*
@ -480,9 +511,10 @@ const _super = (function (geti, seti) {
*
* @param node A Node.
*/
// TODO(rbuckton): Move this into sourcemap.ts
function shouldSkipTrailingSourceMapForNode(node: Node) {
return isNotEmittedStatement(node)
|| (node.emitFlags & NodeEmitFlags.NoTrailingSourceMap) !== 0;
|| (getEmitFlags(node) & EmitFlags.NoTrailingSourceMap) !== 0;
}
/**
@ -490,15 +522,34 @@ const _super = (function (geti, seti) {
*
* We do not emit source maps for a node that has NodeEmitFlags.NoNestedSourceMaps.
*/
// TODO(rbuckton): Move this into sourcemap.ts
function shouldSkipSourceMapForChildren(node: Node) {
return (node.emitFlags & NodeEmitFlags.NoNestedSourceMaps) !== 0;
return (getEmitFlags(node) & EmitFlags.NoNestedSourceMaps) !== 0;
}
function emitWorker(node: Node): void {
if (tryEmitSubstitute(node, emitWorker, /*isExpression*/ false)) {
return;
/**
* Emits a node with possible substitution.
*/
// TODO(rbuckton): Move this into transformer.ts
function emitNodeWithSubstitution(node: Node, isExpression: boolean, emitCallback: (node: Node) => void) {
if (isSubstitutionEnabled(node) && (getEmitFlags(node) & EmitFlags.NoSubstitution) === 0) {
const substitute = onSubstituteNode(node, isExpression);
if (substitute !== node) {
emitCallback(substitute);
return;
}
}
emitCallback(node);
}
/**
* Emits a node.
*
* NOTE: Do not call this method directly. It is part of the emit pipeline
* and should only be called indirectly from emitNodeWithSubstitution.
*/
function emitWorker(node: Node): void {
const kind = node.kind;
switch (kind) {
// Pseudo-literals
@ -749,15 +800,17 @@ const _super = (function (geti, seti) {
}
if (isExpression(node)) {
return emitExpressionWorker(node);
return emitExpressionWithSubstitution(node);
}
}
/**
* Emits an expression.
*
* NOTE: Do not call this method directly. It is part of the emitExpression pipeline
* and should only be called indirectly from emitExpressionWithNotification.
*/
function emitExpressionWorker(node: Node) {
if (tryEmitSubstitute(node, emitExpressionWorker, /*isExpression*/ true)) {
return;
}
const kind = node.kind;
switch (kind) {
// Literals
@ -881,7 +934,7 @@ const _super = (function (geti, seti) {
//
function emitIdentifier(node: Identifier) {
if (node.emitFlags & NodeEmitFlags.UMDDefine) {
if (getEmitFlags(node) & EmitFlags.UMDDefine) {
writeLines(umdHelper);
}
else {
@ -1154,7 +1207,7 @@ const _super = (function (geti, seti) {
write("{}");
}
else {
const indentedFlag = node.emitFlags & NodeEmitFlags.Indented;
const indentedFlag = getEmitFlags(node) & EmitFlags.Indented;
if (indentedFlag) {
increaseIndent();
}
@ -1176,7 +1229,7 @@ const _super = (function (geti, seti) {
let indentBeforeDot = false;
let indentAfterDot = false;
if (!(node.emitFlags & NodeEmitFlags.NoIndentation)) {
if (!(getEmitFlags(node) & EmitFlags.NoIndentation)) {
const dotRangeStart = node.expression.end;
const dotRangeEnd = skipTrivia(currentText, node.expression.end) + 1;
const dotToken = <Node>{ kind: SyntaxKind.DotToken, pos: dotRangeStart, end: dotRangeEnd };
@ -1419,7 +1472,7 @@ const _super = (function (geti, seti) {
}
function emitBlockStatements(node: Block) {
if (node.emitFlags & NodeEmitFlags.SingleLine) {
if (getEmitFlags(node) & EmitFlags.SingleLine) {
emitList(node, node.statements, ListFormat.SingleLineBlockStatements);
}
else {
@ -1623,12 +1676,12 @@ const _super = (function (geti, seti) {
const body = node.body;
if (body) {
if (isBlock(body)) {
const indentedFlag = node.emitFlags & NodeEmitFlags.Indented;
const indentedFlag = getEmitFlags(node) & EmitFlags.Indented;
if (indentedFlag) {
increaseIndent();
}
if (node.emitFlags & NodeEmitFlags.ReuseTempVariableScope) {
if (getEmitFlags(node) & EmitFlags.ReuseTempVariableScope) {
emitSignatureHead(node);
emitBlockFunctionBody(node, body);
}
@ -1672,7 +1725,7 @@ const _super = (function (geti, seti) {
// * A non-synthesized body's start and end position are on different lines.
// * Any statement in the body starts on a new line.
if (body.emitFlags & NodeEmitFlags.SingleLine) {
if (getEmitFlags(body) & EmitFlags.SingleLine) {
return true;
}
@ -1743,7 +1796,7 @@ const _super = (function (geti, seti) {
write("class");
emitNodeWithPrefix(" ", node.name, emitIdentifierName);
const indentedFlag = node.emitFlags & NodeEmitFlags.Indented;
const indentedFlag = getEmitFlags(node) & EmitFlags.Indented;
if (indentedFlag) {
increaseIndent();
}
@ -2077,7 +2130,7 @@ const _super = (function (geti, seti) {
// but rather a trailing comment on the previous node.
const initializer = node.initializer;
if (!shouldSkipLeadingCommentsForNode(initializer)) {
const commentRange = initializer.commentRange || initializer;
const commentRange = getCommentRange(initializer);
emitTrailingCommentsOfPosition(commentRange.pos);
}
@ -2149,23 +2202,23 @@ const _super = (function (geti, seti) {
}
function emitHelpers(node: Node) {
const emitFlags = node.emitFlags;
const emitFlags = getEmitFlags(node);
let helpersEmitted = false;
if (emitFlags & NodeEmitFlags.EmitEmitHelpers) {
if (emitFlags & EmitFlags.EmitEmitHelpers) {
helpersEmitted = emitEmitHelpers(currentSourceFile);
}
if (emitFlags & NodeEmitFlags.EmitExportStar) {
if (emitFlags & EmitFlags.EmitExportStar) {
writeLines(exportStarHelper);
helpersEmitted = true;
}
if (emitFlags & NodeEmitFlags.EmitSuperHelper) {
if (emitFlags & EmitFlags.EmitSuperHelper) {
writeLines(superHelper);
helpersEmitted = true;
}
if (emitFlags & NodeEmitFlags.EmitAdvancedSuperHelper) {
if (emitFlags & EmitFlags.EmitAdvancedSuperHelper) {
writeLines(advancedSuperHelper);
helpersEmitted = true;
}
@ -2287,19 +2340,7 @@ const _super = (function (geti, seti) {
}
}
function tryEmitSubstitute(node: Node, emitNode: (node: Node) => void, isExpression: boolean) {
if (isSubstitutionEnabled(node) && (node.emitFlags & NodeEmitFlags.NoSubstitution) === 0) {
const substitute = onSubstituteNode(node, isExpression);
if (substitute !== node) {
substitute.emitFlags |= NodeEmitFlags.NoSubstitution;
emitNode(substitute);
return true;
}
}
return false;
}
// TODO(rbuckton): Move this into a transformer
function tryEmitConstantValue(node: PropertyAccessExpression | ElementAccessExpression): boolean {
const constantValue = tryGetConstEnumValue(node);
if (constantValue !== undefined) {
@ -2440,7 +2481,7 @@ const _super = (function (geti, seti) {
}
if (shouldEmitInterveningComments) {
const commentRange = child.commentRange || child;
const commentRange = getCommentRange(child);
emitTrailingCommentsOfPosition(commentRange.pos);
}
else {
@ -2502,11 +2543,11 @@ const _super = (function (geti, seti) {
}
function shouldSkipLeadingSourceMapForToken(contextNode: Node) {
return (contextNode.emitFlags & NodeEmitFlags.NoTokenLeadingSourceMaps) !== 0;
return (getEmitFlags(contextNode) & EmitFlags.NoTokenLeadingSourceMaps) !== 0;
}
function shouldSkipTrailingSourceMapForToken(contextNode: Node) {
return (contextNode.emitFlags & NodeEmitFlags.NoTokenTrailingSourceMaps) !== 0;
return (getEmitFlags(contextNode) & EmitFlags.NoTokenTrailingSourceMaps) !== 0;
}
function writeTokenText(token: SyntaxKind, pos?: number) {

View File

@ -76,7 +76,7 @@ namespace ts {
// the original node. We also need to exclude specific properties and only include own-
// properties (to skip members already defined on the shared prototype).
const clone = <T>createNode(node.kind, /*location*/ undefined, node.flags);
clone.original = node;
setOriginalNode(clone, node);
for (const key in node) {
if (clone.hasOwnProperty(key) || !node.hasOwnProperty(key)) {
@ -435,7 +435,7 @@ namespace ts {
export function createPropertyAccess(expression: Expression, name: string | Identifier, location?: TextRange, flags?: NodeFlags) {
const node = <PropertyAccessExpression>createNode(SyntaxKind.PropertyAccessExpression, location, flags);
node.expression = parenthesizeForAccess(expression);
node.emitFlags = NodeEmitFlags.NoIndentation;
(node.emitNode || (node.emitNode = {})).flags |= EmitFlags.NoIndentation;
node.name = typeof name === "string" ? createIdentifier(name) : name;
return node;
}
@ -444,7 +444,7 @@ namespace ts {
if (node.expression !== expression || node.name !== name) {
const propertyAccess = createPropertyAccess(expression, name, /*location*/ node, node.flags);
// Because we are updating existed propertyAccess we want to inherit its emitFlags instead of using default from createPropertyAccess
propertyAccess.emitFlags = node.emitFlags;
(propertyAccess.emitNode || (propertyAccess.emitNode = {})).flags = getEmitFlags(node);
return updateNode(propertyAccess, node);
}
return node;
@ -1551,7 +1551,7 @@ namespace ts {
}
else {
const expression = isIdentifier(memberName) ? createPropertyAccess(target, memberName, location) : createElementAccess(target, memberName, location);
expression.emitFlags |= NodeEmitFlags.NoNestedSourceMaps;
(expression.emitNode || (expression.emitNode = {})).flags |= EmitFlags.NoNestedSourceMaps;
return expression;
}
}
@ -1744,7 +1744,7 @@ namespace ts {
);
// Mark this node as originally an async function
generatorFunc.emitFlags |= NodeEmitFlags.AsyncFunctionBody;
(generatorFunc.emitNode || (generatorFunc.emitNode = {})).flags |= EmitFlags.AsyncFunctionBody;
return createCall(
createHelperName(externalHelpersModuleName, "__awaiter"),
@ -2222,7 +2222,7 @@ namespace ts {
target.push(startOnNewLine(createStatement(createLiteral("use strict"))));
foundUseStrict = true;
}
if (statement.emitFlags & NodeEmitFlags.CustomPrologue) {
if (getEmitFlags(statement) & EmitFlags.CustomPrologue) {
target.push(visitor ? visitNode(statement, visitor, isStatement) : statement);
}
else {
@ -2643,14 +2643,28 @@ namespace ts {
export function setOriginalNode<T extends Node>(node: T, original: Node): T {
node.original = original;
if (original) {
const { emitFlags, commentRange, sourceMapRange } = original;
if (emitFlags) node.emitFlags = emitFlags;
if (commentRange) node.commentRange = commentRange;
if (sourceMapRange) node.sourceMapRange = sourceMapRange;
const emitNode = original.emitNode;
if (emitNode) node.emitNode = mergeEmitNode(emitNode, node.emitNode);
}
return node;
}
function mergeEmitNode(sourceEmitNode: EmitNode, destEmitNode: EmitNode) {
const { flags, commentRange, sourceMapRange, tokenSourceMapRanges } = sourceEmitNode;
if (!destEmitNode && (flags || commentRange || sourceMapRange || tokenSourceMapRanges)) destEmitNode = {};
if (flags) destEmitNode.flags = flags;
if (commentRange) destEmitNode.commentRange = commentRange;
if (sourceMapRange) destEmitNode.sourceMapRange = sourceMapRange;
if (tokenSourceMapRanges) destEmitNode.tokenSourceMapRanges = mergeTokenSourceMapRanges(tokenSourceMapRanges, destEmitNode.tokenSourceMapRanges);
return destEmitNode;
}
function mergeTokenSourceMapRanges(sourceRanges: Map<TextRange>, destRanges: Map<TextRange>) {
if (!destRanges) destRanges = createMap<TextRange>();
copyProperties(sourceRanges, destRanges);
return destRanges;
}
export function setTextRange<T extends TextRange>(node: T, location: TextRange): T {
if (location) {
node.pos = location.pos;

View File

@ -30,11 +30,6 @@ namespace ts {
*/
getSourceFiles(): SourceFile[];
/**
* Gets the TextRange to use for source maps for a token of a node.
*/
getTokenSourceMapRange(node: Node, token: SyntaxKind): TextRange;
/**
* Determines whether expression substitutions are enabled for the provided node.
*/
@ -75,46 +70,6 @@ namespace ts {
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.
*/
@ -187,12 +142,137 @@ namespace ts {
}
/**
* Tracks a monotonically increasing transformation id used to associate a node with a specific
* transformation. This ensures transient properties related to transformations can be safely
* stored on source tree nodes that may be reused across multiple transformations (such as
* with compile-on-save).
* Clears any EmitNode entries from parse-tree nodes.
* @param sourceFile A source file.
*/
let nextTransformId = 1;
export function disposeEmitNodes(sourceFile: SourceFile) {
// During transformation we may need to annotate a parse tree node with transient
// transformation properties. As parse tree nodes live longer than transformation
// nodes, we need to make sure we reclaim any memory allocated for custom ranges
// from these nodes to ensure we do not hold onto entire subtrees just for position
// information. We also need to reset these nodes to a pre-transformation state
// for incremental parsing scenarios so that we do not impact later emit.
sourceFile = getSourceFileOfNode(getParseTreeNode(sourceFile));
const emitNode = sourceFile && sourceFile.emitNode;
const annotatedNodes = emitNode && emitNode.annotatedNodes;
if (annotatedNodes) {
for (const node of annotatedNodes) {
node.emitNode = undefined;
}
}
}
/**
* Associates a node with the current transformation, initializing
* various transient transformation properties.
*
* @param node The node.
*/
function getOrCreateEmitNode(node: Node) {
if (!node.emitNode) {
if (isParseTreeNode(node)) {
// To avoid holding onto transformation artifacts, we keep track of any
// parse tree node we are annotating. This allows us to clean them up after
// all transformations have completed.
if (node.kind === SyntaxKind.SourceFile) {
return node.emitNode = { annotatedNodes: [node] };
}
const sourceFile = getSourceFileOfNode(node);
getOrCreateEmitNode(sourceFile).annotatedNodes.push(node);
}
node.emitNode = {};
}
return node.emitNode;
}
/**
* Gets flags that control emit behavior of a node.
*
* @param node The node.
*/
export function getEmitFlags(node: Node) {
const emitNode = node.emitNode;
return emitNode && emitNode.flags;
}
/**
* Sets flags that control emit behavior of a node.
*
* @param node The node.
* @param emitFlags The NodeEmitFlags for the node.
*/
export function setEmitFlags<T extends Node>(node: T, emitFlags: EmitFlags) {
getOrCreateEmitNode(node).flags = emitFlags;
return node;
}
/**
* Sets a custom text range to use when emitting source maps.
*
* @param node The node.
* @param range The text range.
*/
export function setSourceMapRange<T extends Node>(node: T, range: TextRange) {
getOrCreateEmitNode(node).sourceMapRange = range;
return node;
}
/**
* Sets the TextRange to use for source maps for a token of a node.
*
* @param node The node.
* @param token The token.
* @param range The text range.
*/
export function setTokenSourceMapRange<T extends Node>(node: T, token: SyntaxKind, range: TextRange) {
const emitNode = getOrCreateEmitNode(node);
const tokenSourceMapRanges = emitNode.tokenSourceMapRanges || (emitNode.tokenSourceMapRanges = createMap<TextRange>());
tokenSourceMapRanges[token] = range;
return node;
}
/**
* Sets a custom text range to use when emitting comments.
*/
export function setCommentRange<T extends Node>(node: T, range: TextRange) {
getOrCreateEmitNode(node).commentRange = range;
return node;
}
/**
* Gets a custom text range to use when emitting comments.
*
* @param node The node.
*/
export function getCommentRange(node: Node) {
const emitNode = node.emitNode;
return (emitNode && emitNode.commentRange) || node;
}
/**
* Gets a custom text range to use when emitting source maps.
*
* @param node The node.
*/
export function getSourceMapRange(node: Node) {
const emitNode = node.emitNode;
return (emitNode && emitNode.sourceMapRange) || node;
}
/**
* Gets the TextRange to use for source maps for a token of a node.
*
* @param node The node.
* @param token The token.
*/
export function getTokenSourceMapRange(node: Node, token: SyntaxKind) {
const emitNode = node.emitNode;
const tokenSourceMapRanges = emitNode && emitNode.tokenSourceMapRanges;
return tokenSourceMapRanges && tokenSourceMapRanges[token];
}
/**
* Transforms an array of SourceFiles by passing them through each transformer.
@ -203,18 +283,10 @@ namespace ts {
* @param transforms An array of Transformers.
*/
export function transformFiles(resolver: EmitResolver, host: EmitHost, sourceFiles: SourceFile[], transformers: Transformer[]): TransformationResult {
const transformId = nextTransformId;
nextTransformId++;
const tokenSourceMapRanges = createMap<TextRange>();
const lexicalEnvironmentVariableDeclarationsStack: VariableDeclaration[][] = [];
const lexicalEnvironmentFunctionDeclarationsStack: FunctionDeclaration[][] = [];
const enabledSyntaxKindFeatures = new Array<SyntaxKindFeatureFlags>(SyntaxKind.Count);
const parseTreeNodesWithAnnotations: Node[] = [];
let lastTokenSourceMapRangeNode: Node;
let lastTokenSourceMapRangeToken: SyntaxKind;
let lastTokenSourceMapRange: TextRange;
let lexicalEnvironmentStackOffset = 0;
let hoistedVariableDeclarations: VariableDeclaration[];
let hoistedFunctionDeclarations: FunctionDeclaration[];
@ -226,14 +298,6 @@ namespace ts {
getCompilerOptions: () => host.getCompilerOptions(),
getEmitResolver: () => resolver,
getEmitHost: () => host,
getNodeEmitFlags,
setNodeEmitFlags,
getSourceMapRange,
setSourceMapRange,
getTokenSourceMapRange,
setTokenSourceMapRange,
getCommentRange,
setCommentRange,
hoistVariableDeclaration,
hoistFunctionDeclaration,
startLexicalEnvironment,
@ -257,7 +321,6 @@ namespace ts {
return {
getSourceFiles: () => transformed,
getTokenSourceMapRange,
isSubstitutionEnabled,
isEmitNotificationEnabled,
onSubstituteNode: context.onSubstituteNode,
@ -269,16 +332,9 @@ namespace ts {
// from these nodes to ensure we do not hold onto entire subtrees just for position
// information. We also need to reset these nodes to a pre-transformation state
// for incremental parsing scenarios so that we do not impact later emit.
for (const node of parseTreeNodesWithAnnotations) {
if (node.transformId === transformId) {
node.transformId = 0;
node.emitFlags = 0;
node.commentRange = undefined;
node.sourceMapRange = undefined;
}
for (const sourceFile of sourceFiles) {
disposeEmitNodes(sourceFile);
}
parseTreeNodesWithAnnotations.length = 0;
}
};
@ -333,7 +389,7 @@ namespace ts {
*/
function isEmitNotificationEnabled(node: Node) {
return (enabledSyntaxKindFeatures[node.kind] & SyntaxKindFeatureFlags.EmitNotifications) !== 0
|| (getNodeEmitFlags(node) & NodeEmitFlags.AdviseOnEmitNode) !== 0;
|| (getEmitFlags(node) & EmitFlags.AdviseOnEmitNode) !== 0;
}
/**
@ -346,143 +402,6 @@ namespace ts {
emit(node);
}
/**
* Associates a node with the current transformation, initializing
* various transient transformation properties.
*
* @param node The node.
*/
function beforeSetAnnotation(node: Node) {
if ((node.flags & NodeFlags.Synthesized) === 0 && node.transformId !== transformId) {
// To avoid holding onto transformation artifacts, we keep track of any
// parse tree node we are annotating. This allows us to clean them up after
// all transformations have completed.
parseTreeNodesWithAnnotations.push(node);
node.transformId = transformId;
}
}
/**
* Gets flags that control emit behavior of a node.
*
* If the node does not have its own NodeEmitFlags set, the node emit flags of its
* original pointer are used.
*
* @param node The node.
*/
function getNodeEmitFlags(node: Node) {
return node.emitFlags;
}
/**
* Sets flags that control emit behavior of a node.
*
* @param node The node.
* @param emitFlags The NodeEmitFlags for the node.
*/
function setNodeEmitFlags<T extends Node>(node: T, emitFlags: NodeEmitFlags) {
beforeSetAnnotation(node);
node.emitFlags = emitFlags;
return node;
}
/**
* Gets a custom text range to use when emitting source maps.
*
* If a node does not have its own custom source map text range, the custom source map
* text range of its original pointer is used.
*
* @param node The node.
*/
function getSourceMapRange(node: Node) {
return node.sourceMapRange || node;
}
/**
* Sets a custom text range to use when emitting source maps.
*
* @param node The node.
* @param range The text range.
*/
function setSourceMapRange<T extends Node>(node: T, range: TextRange) {
beforeSetAnnotation(node);
node.sourceMapRange = range;
return node;
}
/**
* Gets the TextRange to use for source maps for a token of a node.
*
* If a node does not have its own custom source map text range for a token, the custom
* source map text range for the token of its original pointer is used.
*
* @param node The node.
* @param token The token.
*/
function getTokenSourceMapRange(node: Node, token: SyntaxKind) {
// As a performance optimization, use the cached value of the most recent node.
// This helps for cases where this function is called repeatedly for the same node.
if (lastTokenSourceMapRangeNode === node && lastTokenSourceMapRangeToken === token) {
return lastTokenSourceMapRange;
}
// Get the custom token source map range for a node or from one of its original nodes.
// Custom token ranges are not stored on the node to avoid the GC burden.
let range: TextRange;
let current = node;
while (current) {
range = current.id ? tokenSourceMapRanges[current.id + "-" + token] : undefined;
if (range !== undefined) {
break;
}
current = current.original;
}
// Cache the most recently requested value.
lastTokenSourceMapRangeNode = node;
lastTokenSourceMapRangeToken = token;
lastTokenSourceMapRange = range;
return range;
}
/**
* Sets the TextRange to use for source maps for a token of a node.
*
* @param node The node.
* @param token The token.
* @param range The text range.
*/
function setTokenSourceMapRange<T extends Node>(node: T, token: SyntaxKind, range: TextRange) {
// Cache the most recently requested value.
lastTokenSourceMapRangeNode = node;
lastTokenSourceMapRangeToken = token;
lastTokenSourceMapRange = range;
tokenSourceMapRanges[getNodeId(node) + "-" + token] = range;
return node;
}
/**
* Gets a custom text range to use when emitting comments.
*
* If a node does not have its own custom source map text range, the custom source map
* text range of its original pointer is used.
*
* @param node The node.
*/
function getCommentRange(node: Node) {
return node.commentRange || node;
}
/**
* Sets a custom text range to use when emitting comments.
*/
function setCommentRange<T extends Node>(node: T, range: TextRange) {
beforeSetAnnotation(node);
node.commentRange = range;
return node;
}
/**
* Records a hoisted variable declaration for the provided name within a lexical environment.
*/
@ -563,70 +482,4 @@ namespace ts {
return statements;
}
}
/**
* High-order function, creates a function that executes a function composition.
* For example, `chain(a, b)` is the equivalent of `x => ((a', b') => y => b'(a'(y)))(a(x), b(x))`
*
* @param args The functions to chain.
*/
function chain<T, U>(...args: ((t: T) => (u: U) => U)[]): (t: T) => (u: U) => U;
function chain<T, U>(a: (t: T) => (u: U) => U, b: (t: T) => (u: U) => U, c: (t: T) => (u: U) => U, d: (t: T) => (u: U) => U, e: (t: T) => (u: U) => U): (t: T) => (u: U) => U {
if (e) {
const args: ((t: T) => (u: U) => U)[] = [];
for (let i = 0; i < arguments.length; i++) {
args[i] = arguments[i];
}
return t => compose(...map(args, f => f(t)));
}
else if (d) {
return t => compose(a(t), b(t), c(t), d(t));
}
else if (c) {
return t => compose(a(t), b(t), c(t));
}
else if (b) {
return t => compose(a(t), b(t));
}
else if (a) {
return t => compose(a(t));
}
else {
return t => u => u;
}
}
/**
* High-order function, composes functions. Note that functions are composed inside-out;
* for example, `compose(a, b)` is the equivalent of `x => b(a(x))`.
*
* @param args The functions to compose.
*/
function compose<T>(...args: ((t: T) => T)[]): (t: T) => T;
function compose<T>(a: (t: T) => T, b: (t: T) => T, c: (t: T) => T, d: (t: T) => T, e: (t: T) => T): (t: T) => T {
if (e) {
const args: ((t: T) => T)[] = [];
for (let i = 0; i < arguments.length; i++) {
args[i] = arguments[i];
}
return t => reduceLeft<(t: T) => T, T>(args, (u, f) => f(u), t);
}
else if (d) {
return t => d(c(b(a(t))));
}
else if (c) {
return t => c(b(a(t)));
}
else if (b) {
return t => b(a(t));
}
else if (a) {
return t => a(t);
}
else {
return t => t;
}
}
}

View File

@ -66,7 +66,7 @@ namespace ts {
// NOTE: this completely disables source maps, but aligns with the behavior of
// `emitAssignment` in the old emitter.
context.setNodeEmitFlags(expression, NodeEmitFlags.NoNestedSourceMaps);
setEmitFlags(expression, EmitFlags.NoNestedSourceMaps);
aggregateTransformFlags(expression);
expressions.push(expression);
@ -102,7 +102,7 @@ namespace ts {
// NOTE: this completely disables source maps, but aligns with the behavior of
// `emitAssignment` in the old emitter.
context.setNodeEmitFlags(declaration, NodeEmitFlags.NoNestedSourceMaps);
setEmitFlags(declaration, EmitFlags.NoNestedSourceMaps);
aggregateTransformFlags(declaration);
declarations.push(declaration);
@ -139,7 +139,7 @@ namespace ts {
// NOTE: this completely disables source maps, but aligns with the behavior of
// `emitAssignment` in the old emitter.
context.setNodeEmitFlags(declaration, NodeEmitFlags.NoNestedSourceMaps);
setEmitFlags(declaration, EmitFlags.NoNestedSourceMaps);
declarations.push(declaration);
aggregateTransformFlags(declaration);
@ -192,7 +192,7 @@ namespace ts {
// NOTE: this completely disables source maps, but aligns with the behavior of
// `emitAssignment` in the old emitter.
context.setNodeEmitFlags(expression, NodeEmitFlags.NoNestedSourceMaps);
setEmitFlags(expression, EmitFlags.NoNestedSourceMaps);
pendingAssignments.push(expression);
return expression;
@ -252,8 +252,8 @@ namespace ts {
}
else {
const name = getMutableClone(<Identifier>target);
context.setSourceMapRange(name, target);
context.setCommentRange(name, target);
setSourceMapRange(name, target);
setCommentRange(name, target);
emitAssignment(name, value, location, /*original*/ undefined);
}
}

View File

@ -144,13 +144,6 @@ namespace ts {
startLexicalEnvironment,
endLexicalEnvironment,
hoistVariableDeclaration,
getNodeEmitFlags,
setNodeEmitFlags,
getCommentRange,
setCommentRange,
getSourceMapRange,
setSourceMapRange,
setTokenSourceMapRange,
} = context;
const resolver = context.getEmitResolver();
@ -190,6 +183,10 @@ namespace ts {
return transformSourceFile;
function transformSourceFile(node: SourceFile) {
if (isDeclarationFile(node)) {
return node;
}
currentSourceFile = node;
currentText = node.text;
return visitNode(node, visitor, isSourceFile);
@ -427,7 +424,7 @@ namespace ts {
case SyntaxKind.SetAccessor:
case SyntaxKind.FunctionDeclaration:
containingNonArrowFunction = <FunctionLikeDeclaration>currentParent;
if (!(containingNonArrowFunction.emitFlags & NodeEmitFlags.AsyncFunctionBody)) {
if (!(getEmitFlags(containingNonArrowFunction) & EmitFlags.AsyncFunctionBody)) {
superScopeContainer = containingNonArrowFunction;
}
break;
@ -669,19 +666,19 @@ namespace ts {
// To preserve the behavior of the old emitter, we explicitly indent
// the body of the function here if it was requested in an earlier
// transformation.
if (getNodeEmitFlags(node) & NodeEmitFlags.Indented) {
setNodeEmitFlags(classFunction, NodeEmitFlags.Indented);
if (getEmitFlags(node) & EmitFlags.Indented) {
setEmitFlags(classFunction, EmitFlags.Indented);
}
// "inner" and "outer" below are added purely to preserve source map locations from
// the old emitter
const inner = createPartiallyEmittedExpression(classFunction);
inner.end = node.end;
setNodeEmitFlags(inner, NodeEmitFlags.NoComments);
setEmitFlags(inner, EmitFlags.NoComments);
const outer = createPartiallyEmittedExpression(inner);
outer.end = skipTrivia(currentText, node.pos);
setNodeEmitFlags(outer, NodeEmitFlags.NoComments);
setEmitFlags(outer, EmitFlags.NoComments);
return createParen(
createCall(
@ -715,17 +712,17 @@ namespace ts {
// emit with the original emitter.
const outer = createPartiallyEmittedExpression(localName);
outer.end = closingBraceLocation.end;
setNodeEmitFlags(outer, NodeEmitFlags.NoComments);
setEmitFlags(outer, EmitFlags.NoComments);
const statement = createReturn(outer);
statement.pos = closingBraceLocation.pos;
setNodeEmitFlags(statement, NodeEmitFlags.NoComments | NodeEmitFlags.NoTokenSourceMaps);
setEmitFlags(statement, EmitFlags.NoComments | EmitFlags.NoTokenSourceMaps);
statements.push(statement);
addRange(statements, endLexicalEnvironment());
const block = createBlock(createNodeArray(statements, /*location*/ node.members), /*location*/ undefined, /*multiLine*/ true);
setNodeEmitFlags(block, NodeEmitFlags.NoComments);
setEmitFlags(block, EmitFlags.NoComments);
return block;
}
@ -828,7 +825,7 @@ namespace ts {
);
if (!constructor) {
setNodeEmitFlags(block, NodeEmitFlags.NoComments);
setEmitFlags(block, EmitFlags.NoComments);
}
return block;
@ -965,27 +962,27 @@ namespace ts {
// of an initializer, we must emit that expression to preserve side effects.
if (name.elements.length > 0) {
statements.push(
setNodeEmitFlags(
setEmitFlags(
createVariableStatement(
/*modifiers*/ undefined,
createVariableDeclarationList(
flattenParameterDestructuring(context, parameter, temp, visitor)
)
),
NodeEmitFlags.CustomPrologue
EmitFlags.CustomPrologue
)
);
}
else if (initializer) {
statements.push(
setNodeEmitFlags(
setEmitFlags(
createStatement(
createAssignment(
temp,
visitNode(initializer, visitor, isExpression)
)
),
NodeEmitFlags.CustomPrologue
EmitFlags.CustomPrologue
)
);
}
@ -1006,23 +1003,23 @@ namespace ts {
getSynthesizedClone(name),
createVoidZero()
),
setNodeEmitFlags(
setEmitFlags(
createBlock([
createStatement(
createAssignment(
setNodeEmitFlags(getMutableClone(name), NodeEmitFlags.NoSourceMap),
setNodeEmitFlags(initializer, NodeEmitFlags.NoSourceMap | getNodeEmitFlags(initializer)),
setEmitFlags(getMutableClone(name), EmitFlags.NoSourceMap),
setEmitFlags(initializer, EmitFlags.NoSourceMap | getEmitFlags(initializer)),
/*location*/ parameter
)
)
], /*location*/ parameter),
NodeEmitFlags.SingleLine | NodeEmitFlags.NoTrailingSourceMap | NodeEmitFlags.NoTokenSourceMaps
EmitFlags.SingleLine | EmitFlags.NoTrailingSourceMap | EmitFlags.NoTokenSourceMaps
),
/*elseStatement*/ undefined,
/*location*/ parameter
);
statement.startsOnNewLine = true;
setNodeEmitFlags(statement, NodeEmitFlags.NoTokenSourceMaps | NodeEmitFlags.NoTrailingSourceMap | NodeEmitFlags.CustomPrologue);
setEmitFlags(statement, EmitFlags.NoTokenSourceMaps | EmitFlags.NoTrailingSourceMap | EmitFlags.CustomPrologue);
statements.push(statement);
}
@ -1055,7 +1052,7 @@ namespace ts {
// `declarationName` is the name of the local declaration for the parameter.
const declarationName = getMutableClone(<Identifier>parameter.name);
setNodeEmitFlags(declarationName, NodeEmitFlags.NoSourceMap);
setEmitFlags(declarationName, EmitFlags.NoSourceMap);
// `expressionName` is the name of the parameter used in expressions.
const expressionName = getSynthesizedClone(<Identifier>parameter.name);
@ -1064,7 +1061,7 @@ namespace ts {
// var param = [];
statements.push(
setNodeEmitFlags(
setEmitFlags(
createVariableStatement(
/*modifiers*/ undefined,
createVariableDeclarationList([
@ -1076,7 +1073,7 @@ namespace ts {
]),
/*location*/ parameter
),
NodeEmitFlags.CustomPrologue
EmitFlags.CustomPrologue
)
);
@ -1109,7 +1106,7 @@ namespace ts {
])
);
setNodeEmitFlags(forStatement, NodeEmitFlags.CustomPrologue);
setEmitFlags(forStatement, EmitFlags.CustomPrologue);
startOnNewLine(forStatement);
statements.push(forStatement);
}
@ -1134,7 +1131,7 @@ namespace ts {
])
);
setNodeEmitFlags(captureThisStatement, NodeEmitFlags.NoComments | NodeEmitFlags.CustomPrologue);
setEmitFlags(captureThisStatement, EmitFlags.NoComments | EmitFlags.CustomPrologue);
setSourceMapRange(captureThisStatement, node);
statements.push(captureThisStatement);
}
@ -1198,7 +1195,7 @@ namespace ts {
const sourceMapRange = getSourceMapRange(member);
const func = transformFunctionLikeToExpression(member, /*location*/ member, /*name*/ undefined);
setNodeEmitFlags(func, NodeEmitFlags.NoComments);
setEmitFlags(func, EmitFlags.NoComments);
setSourceMapRange(func, sourceMapRange);
const statement = createStatement(
@ -1219,7 +1216,7 @@ namespace ts {
// The location for the statement is used to emit comments only.
// No source map should be emitted for this statement to align with the
// old emitter.
setNodeEmitFlags(statement, NodeEmitFlags.NoSourceMap);
setEmitFlags(statement, EmitFlags.NoSourceMap);
return statement;
}
@ -1238,7 +1235,7 @@ namespace ts {
// The location for the statement is used to emit source maps only.
// No comments should be emitted for this statement to align with the
// old emitter.
setNodeEmitFlags(statement, NodeEmitFlags.NoComments);
setEmitFlags(statement, EmitFlags.NoComments);
return statement;
}
@ -1252,11 +1249,11 @@ namespace ts {
// To align with source maps in the old emitter, the receiver and property name
// arguments are both mapped contiguously to the accessor name.
const target = getMutableClone(receiver);
setNodeEmitFlags(target, NodeEmitFlags.NoComments | NodeEmitFlags.NoTrailingSourceMap);
setEmitFlags(target, EmitFlags.NoComments | EmitFlags.NoTrailingSourceMap);
setSourceMapRange(target, firstAccessor.name);
const propertyName = createExpressionForPropertyName(visitNode(firstAccessor.name, visitor, isPropertyName));
setNodeEmitFlags(propertyName, NodeEmitFlags.NoComments | NodeEmitFlags.NoLeadingSourceMap);
setEmitFlags(propertyName, EmitFlags.NoComments | EmitFlags.NoLeadingSourceMap);
setSourceMapRange(propertyName, firstAccessor.name);
const properties: ObjectLiteralElement[] = [];
@ -1312,7 +1309,7 @@ namespace ts {
const func = transformFunctionLikeToExpression(node, /*location*/ node, /*name*/ undefined);
useCapturedThis = savedUseCapturedThis;
setNodeEmitFlags(func, NodeEmitFlags.CapturesThis);
setEmitFlags(func, EmitFlags.CapturesThis);
return func;
}
@ -1437,7 +1434,7 @@ namespace ts {
const expression = visitNode(body, visitor, isExpression);
const returnStatement = createReturn(expression, /*location*/ body);
setNodeEmitFlags(returnStatement, NodeEmitFlags.NoTokenSourceMaps | NodeEmitFlags.NoTrailingSourceMap | NodeEmitFlags.NoTrailingComments);
setEmitFlags(returnStatement, EmitFlags.NoTokenSourceMaps | EmitFlags.NoTrailingSourceMap | EmitFlags.NoTrailingComments);
statements.push(returnStatement);
// To align with the source map emit for the old emitter, we set a custom
@ -1455,7 +1452,7 @@ namespace ts {
const block = createBlock(createNodeArray(statements, statementsLocation), node.body, multiLine);
if (!multiLine && singleLine) {
setNodeEmitFlags(block, NodeEmitFlags.SingleLine);
setEmitFlags(block, EmitFlags.SingleLine);
}
if (closeBraceLocation) {
@ -1875,7 +1872,7 @@ namespace ts {
}
// The old emitter does not emit source maps for the expression
setNodeEmitFlags(expression, NodeEmitFlags.NoSourceMap | getNodeEmitFlags(expression));
setEmitFlags(expression, EmitFlags.NoSourceMap | getEmitFlags(expression));
// The old emitter does not emit source maps for the block.
// We add the location to preserve comments.
@ -1884,7 +1881,7 @@ namespace ts {
/*location*/ bodyLocation
);
setNodeEmitFlags(body, NodeEmitFlags.NoSourceMap | NodeEmitFlags.NoTokenSourceMaps);
setEmitFlags(body, EmitFlags.NoSourceMap | EmitFlags.NoTokenSourceMaps);
const forStatement = createFor(
createVariableDeclarationList([
@ -1902,7 +1899,7 @@ namespace ts {
);
// Disable trailing source maps for the OpenParenToken to align source map emit with the old emitter.
setNodeEmitFlags(forStatement, NodeEmitFlags.NoTokenTrailingSourceMaps);
setEmitFlags(forStatement, EmitFlags.NoTokenTrailingSourceMaps);
return forStatement;
}
@ -1938,13 +1935,13 @@ namespace ts {
const expressions: Expression[] = [];
const assignment = createAssignment(
temp,
setNodeEmitFlags(
setEmitFlags(
createObjectLiteral(
visitNodes(properties, visitor, isObjectLiteralElement, 0, numInitialProperties),
/*location*/ undefined,
node.multiLine
),
NodeEmitFlags.Indented
EmitFlags.Indented
)
);
if (node.multiLine) {
@ -2067,16 +2064,16 @@ namespace ts {
const isAsyncBlockContainingAwait =
containingNonArrowFunction
&& (containingNonArrowFunction.emitFlags & NodeEmitFlags.AsyncFunctionBody) !== 0
&& (getEmitFlags(containingNonArrowFunction) & EmitFlags.AsyncFunctionBody) !== 0
&& (node.statement.transformFlags & TransformFlags.ContainsYield) !== 0;
let loopBodyFlags: NodeEmitFlags = 0;
let loopBodyFlags: EmitFlags = 0;
if (currentState.containsLexicalThis) {
loopBodyFlags |= NodeEmitFlags.CapturesThis;
loopBodyFlags |= EmitFlags.CapturesThis;
}
if (isAsyncBlockContainingAwait) {
loopBodyFlags |= NodeEmitFlags.AsyncFunctionBody;
loopBodyFlags |= EmitFlags.AsyncFunctionBody;
}
const convertedLoopVariable =
@ -2087,7 +2084,7 @@ namespace ts {
createVariableDeclaration(
functionName,
/*type*/ undefined,
setNodeEmitFlags(
setEmitFlags(
createFunctionExpression(
isAsyncBlockContainingAwait ? createToken(SyntaxKind.AsteriskToken) : undefined,
/*name*/ undefined,
@ -2480,7 +2477,7 @@ namespace ts {
// Methods with computed property names are handled in visitObjectLiteralExpression.
Debug.assert(!isComputedPropertyName(node.name));
const functionExpression = transformFunctionLikeToExpression(node, /*location*/ moveRangePos(node, -1), /*name*/ undefined);
setNodeEmitFlags(functionExpression, NodeEmitFlags.NoLeadingComments | getNodeEmitFlags(functionExpression));
setEmitFlags(functionExpression, EmitFlags.NoLeadingComments | getEmitFlags(functionExpression));
return createPropertyAssignment(
node.name,
functionExpression,
@ -2861,7 +2858,7 @@ namespace ts {
if (enabledSubstitutions & ES6SubstitutionFlags.CapturedThis && isFunctionLike(node)) {
// If we are tracking a captured `this`, push a bit that indicates whether the
// containing function is an arrow function.
useCapturedThis = (getNodeEmitFlags(node) & NodeEmitFlags.CapturesThis) !== 0;
useCapturedThis = (getEmitFlags(node) & EmitFlags.CapturesThis) !== 0;
}
previousOnEmitNode(node, emit);
@ -3012,7 +3009,7 @@ namespace ts {
* @param allowSourceMaps A value indicating whether source maps may be emitted for the name.
*/
function getLocalName(node: ClassDeclaration | ClassExpression | FunctionDeclaration, allowComments?: boolean, allowSourceMaps?: boolean) {
return getDeclarationName(node, allowComments, allowSourceMaps, NodeEmitFlags.LocalName);
return getDeclarationName(node, allowComments, allowSourceMaps, EmitFlags.LocalName);
}
/**
@ -3021,18 +3018,18 @@ namespace ts {
* @param node The declaration.
* @param allowComments Allow comments for the name.
*/
function getDeclarationName(node: DeclarationStatement | ClassExpression, allowComments?: boolean, allowSourceMaps?: boolean, emitFlags?: NodeEmitFlags) {
function getDeclarationName(node: DeclarationStatement | ClassExpression, allowComments?: boolean, allowSourceMaps?: boolean, emitFlags?: EmitFlags) {
if (node.name && !isGeneratedIdentifier(node.name)) {
const name = getMutableClone(node.name);
emitFlags |= getNodeEmitFlags(node.name);
emitFlags |= getEmitFlags(node.name);
if (!allowSourceMaps) {
emitFlags |= NodeEmitFlags.NoSourceMap;
emitFlags |= EmitFlags.NoSourceMap;
}
if (!allowComments) {
emitFlags |= NodeEmitFlags.NoComments;
emitFlags |= EmitFlags.NoComments;
}
if (emitFlags) {
setNodeEmitFlags(name, emitFlags);
setEmitFlags(name, emitFlags);
}
return name;
}

View File

@ -9,6 +9,10 @@ namespace ts {
return transformSourceFile;
function transformSourceFile(node: SourceFile) {
if (isDeclarationFile(node)) {
return node;
}
return visitEachChild(node, visitor, context);
}

View File

@ -231,9 +231,6 @@ namespace ts {
endLexicalEnvironment,
hoistFunctionDeclaration,
hoistVariableDeclaration,
setSourceMapRange,
setCommentRange,
setNodeEmitFlags
} = context;
const compilerOptions = context.getCompilerOptions();
@ -294,6 +291,10 @@ namespace ts {
return transformSourceFile;
function transformSourceFile(node: SourceFile) {
if (isDeclarationFile(node)) {
return node;
}
if (node.transformFlags & TransformFlags.ContainsGenerator) {
currentSourceFile = node;
node = visitEachChild(node, visitor, context);
@ -444,7 +445,7 @@ namespace ts {
*/
function visitFunctionDeclaration(node: FunctionDeclaration): Statement {
// Currently, we only support generators that were originally async functions.
if (node.asteriskToken && node.emitFlags & NodeEmitFlags.AsyncFunctionBody) {
if (node.asteriskToken && getEmitFlags(node) & EmitFlags.AsyncFunctionBody) {
node = setOriginalNode(
createFunctionDeclaration(
/*decorators*/ undefined,
@ -492,7 +493,7 @@ namespace ts {
*/
function visitFunctionExpression(node: FunctionExpression): Expression {
// Currently, we only support generators that were originally async functions.
if (node.asteriskToken && node.emitFlags & NodeEmitFlags.AsyncFunctionBody) {
if (node.asteriskToken && getEmitFlags(node) & EmitFlags.AsyncFunctionBody) {
node = setOriginalNode(
createFunctionExpression(
/*asteriskToken*/ undefined,
@ -2580,7 +2581,7 @@ namespace ts {
/*typeArguments*/ undefined,
[
createThis(),
setNodeEmitFlags(
setEmitFlags(
createFunctionExpression(
/*asteriskToken*/ undefined,
/*name*/ undefined,
@ -2593,7 +2594,7 @@ namespace ts {
/*multiLine*/ buildResult.length > 0
)
),
NodeEmitFlags.ReuseTempVariableScope
EmitFlags.ReuseTempVariableScope
)
]
);

View File

@ -16,6 +16,10 @@ namespace ts {
* @param node A SourceFile node.
*/
function transformSourceFile(node: SourceFile) {
if (isDeclarationFile(node)) {
return node;
}
currentSourceFile = node;
node = visitEachChild(node, visitor, context);
currentSourceFile = undefined;

View File

@ -12,6 +12,10 @@ namespace ts {
return transformSourceFile;
function transformSourceFile(node: SourceFile) {
if (isDeclarationFile(node)) {
return node;
}
if (isExternalModule(node) || compilerOptions.isolatedModules) {
currentSourceFile = node;
return visitEachChild(node, visitor, context);

View File

@ -15,9 +15,6 @@ namespace ts {
startLexicalEnvironment,
endLexicalEnvironment,
hoistVariableDeclaration,
setNodeEmitFlags,
getNodeEmitFlags,
setSourceMapRange,
} = context;
const compilerOptions = context.getCompilerOptions();
@ -54,6 +51,10 @@ namespace ts {
* @param node The SourceFile node.
*/
function transformSourceFile(node: SourceFile) {
if (isDeclarationFile(node)) {
return node;
}
if (isExternalModule(node) || compilerOptions.isolatedModules) {
currentSourceFile = node;
@ -92,7 +93,7 @@ namespace ts {
const updated = updateSourceFile(node, statements);
if (hasExportStarsToExportValues) {
setNodeEmitFlags(updated, NodeEmitFlags.EmitExportStar | getNodeEmitFlags(node));
setEmitFlags(updated, EmitFlags.EmitExportStar | getEmitFlags(node));
}
return updated;
@ -116,7 +117,7 @@ namespace ts {
*/
function transformUMDModule(node: SourceFile) {
const define = createIdentifier("define");
setNodeEmitFlags(define, NodeEmitFlags.UMDDefine);
setEmitFlags(define, EmitFlags.UMDDefine);
return transformAsynchronousModule(node, define, /*moduleName*/ undefined, /*includeNonAmdDependencies*/ false);
}
@ -220,7 +221,7 @@ namespace ts {
if (hasExportStarsToExportValues) {
// If we have any `export * from ...` declarations
// we need to inform the emitter to add the __export helper.
setNodeEmitFlags(body, NodeEmitFlags.EmitExportStar);
setEmitFlags(body, EmitFlags.EmitExportStar);
}
return body;
@ -234,7 +235,7 @@ namespace ts {
/*location*/ exportEquals
);
setNodeEmitFlags(statement, NodeEmitFlags.NoTokenSourceMaps | NodeEmitFlags.NoComments);
setEmitFlags(statement, EmitFlags.NoTokenSourceMaps | EmitFlags.NoComments);
statements.push(statement);
}
else {
@ -249,7 +250,7 @@ namespace ts {
/*location*/ exportEquals
);
setNodeEmitFlags(statement, NodeEmitFlags.NoComments);
setEmitFlags(statement, EmitFlags.NoComments);
statements.push(statement);
}
}
@ -388,7 +389,7 @@ namespace ts {
// Set emitFlags on the name of the importEqualsDeclaration
// This is so the printer will not substitute the identifier
setNodeEmitFlags(node.name, NodeEmitFlags.NoSubstitution);
setEmitFlags(node.name, EmitFlags.NoSubstitution);
const statements: Statement[] = [];
if (moduleKind !== ModuleKind.AMD) {
if (hasModifier(node, ModifierFlags.Export)) {
@ -598,7 +599,7 @@ namespace ts {
}
else {
statements.push(
createExportStatement(node.name, setNodeEmitFlags(getSynthesizedClone(node.name), NodeEmitFlags.LocalName), /*location*/ node)
createExportStatement(node.name, setEmitFlags(getSynthesizedClone(node.name), EmitFlags.LocalName), /*location*/ node)
);
}
}
@ -813,7 +814,7 @@ namespace ts {
)],
/*location*/ node
);
setNodeEmitFlags(transformedStatement, NodeEmitFlags.NoComments);
setEmitFlags(transformedStatement, EmitFlags.NoComments);
statements.push(transformedStatement);
}
@ -890,7 +891,7 @@ namespace ts {
// If the left-hand-side of the binaryExpression is an identifier and its is export through export Specifier
if (isIdentifier(left) && isAssignmentOperator(node.operatorToken.kind)) {
if (bindingNameExportSpecifiersMap && hasProperty(bindingNameExportSpecifiersMap, left.text)) {
setNodeEmitFlags(node, NodeEmitFlags.NoSubstitution);
setEmitFlags(node, EmitFlags.NoSubstitution);
let nestedExportAssignment: BinaryExpression;
for (const specifier of bindingNameExportSpecifiersMap[left.text]) {
nestedExportAssignment = nestedExportAssignment ?
@ -910,7 +911,7 @@ namespace ts {
const operand = node.operand;
if (isIdentifier(operand) && bindingNameExportSpecifiersForFileMap) {
if (bindingNameExportSpecifiersMap && hasProperty(bindingNameExportSpecifiersMap, operand.text)) {
setNodeEmitFlags(node, NodeEmitFlags.NoSubstitution);
setEmitFlags(node, EmitFlags.NoSubstitution);
let transformedUnaryExpression: BinaryExpression;
if (node.kind === SyntaxKind.PostfixUnaryExpression) {
transformedUnaryExpression = createBinary(
@ -920,7 +921,7 @@ namespace ts {
/*location*/ node
);
// We have to set no substitution flag here to prevent visit the binary expression and substitute it again as we will preform all necessary substitution in here
setNodeEmitFlags(transformedUnaryExpression, NodeEmitFlags.NoSubstitution);
setEmitFlags(transformedUnaryExpression, EmitFlags.NoSubstitution);
}
let nestedExportAssignment: BinaryExpression;
for (const specifier of bindingNameExportSpecifiersMap[operand.text]) {
@ -935,9 +936,9 @@ namespace ts {
}
function trySubstituteExportedName(node: Identifier) {
const emitFlags = getNodeEmitFlags(node);
if ((emitFlags & NodeEmitFlags.LocalName) === 0) {
const container = resolver.getReferencedExportContainer(node, (emitFlags & NodeEmitFlags.ExportName) !== 0);
const emitFlags = getEmitFlags(node);
if ((emitFlags & EmitFlags.LocalName) === 0) {
const container = resolver.getReferencedExportContainer(node, (emitFlags & EmitFlags.ExportName) !== 0);
if (container) {
if (container.kind === SyntaxKind.SourceFile) {
return createPropertyAccess(
@ -953,7 +954,7 @@ namespace ts {
}
function trySubstituteImportedName(node: Identifier): Expression {
if ((getNodeEmitFlags(node) & NodeEmitFlags.LocalName) === 0) {
if ((getEmitFlags(node) & EmitFlags.LocalName) === 0) {
const declaration = resolver.getReferencedImportDeclaration(node);
if (declaration) {
if (isImportClause(declaration)) {
@ -1077,7 +1078,7 @@ namespace ts {
if (includeNonAmdDependencies && importAliasName) {
// Set emitFlags on the name of the classDeclaration
// This is so that when printer will not substitute the identifier
setNodeEmitFlags(importAliasName, NodeEmitFlags.NoSubstitution);
setEmitFlags(importAliasName, EmitFlags.NoSubstitution);
aliasedModuleNames.push(externalModuleName);
importAliasNames.push(createParameter(importAliasName));
}

View File

@ -10,8 +10,6 @@ namespace ts {
}
const {
getNodeEmitFlags,
setNodeEmitFlags,
startLexicalEnvironment,
endLexicalEnvironment,
hoistVariableDeclaration,
@ -50,6 +48,10 @@ namespace ts {
return transformSourceFile;
function transformSourceFile(node: SourceFile) {
if (isDeclarationFile(node)) {
return node;
}
if (isExternalModule(node) || compilerOptions.isolatedModules) {
currentSourceFile = node;
currentNode = node;
@ -116,9 +118,9 @@ namespace ts {
createParameter(contextObjectForFile)
],
/*type*/ undefined,
setNodeEmitFlags(
setEmitFlags(
createBlock(statements, /*location*/ undefined, /*multiLine*/ true),
NodeEmitFlags.EmitEmitHelpers
EmitFlags.EmitEmitHelpers
)
);
@ -135,7 +137,7 @@ namespace ts {
: [dependencies, body]
)
)
], /*nodeEmitFlags*/ ~NodeEmitFlags.EmitEmitHelpers & getNodeEmitFlags(node));
], /*nodeEmitFlags*/ ~EmitFlags.EmitEmitHelpers & getEmitFlags(node));
}
/**
@ -1053,7 +1055,7 @@ namespace ts {
}
function substituteAssignmentExpression(node: BinaryExpression): Expression {
setNodeEmitFlags(node, NodeEmitFlags.NoSubstitution);
setEmitFlags(node, EmitFlags.NoSubstitution);
const left = node.left;
switch (left.kind) {
@ -1176,7 +1178,7 @@ namespace ts {
const exportDeclaration = resolver.getReferencedExportContainer(<Identifier>operand);
if (exportDeclaration) {
const expr = createPrefix(node.operator, operand, node);
setNodeEmitFlags(expr, NodeEmitFlags.NoSubstitution);
setEmitFlags(expr, EmitFlags.NoSubstitution);
const call = createExportExpression(<Identifier>operand, expr);
if (node.kind === SyntaxKind.PrefixUnaryExpression) {
return call;
@ -1241,7 +1243,7 @@ namespace ts {
]),
m,
createBlock([
setNodeEmitFlags(
setEmitFlags(
createIf(
condition,
createStatement(
@ -1251,7 +1253,7 @@ namespace ts {
)
)
),
NodeEmitFlags.SingleLine
EmitFlags.SingleLine
)
])
),
@ -1393,10 +1395,10 @@ namespace ts {
hoistBindingElement(node, /*isExported*/ false);
}
function updateSourceFile(node: SourceFile, statements: Statement[], nodeEmitFlags: NodeEmitFlags) {
function updateSourceFile(node: SourceFile, statements: Statement[], nodeEmitFlags: EmitFlags) {
const updated = getMutableClone(node);
updated.statements = createNodeArray(statements, node.statements);
setNodeEmitFlags(updated, nodeEmitFlags);
setEmitFlags(updated, nodeEmitFlags);
return updated;
}
}

View File

@ -24,10 +24,6 @@ namespace ts {
export function transformTypeScript(context: TransformationContext) {
const {
getNodeEmitFlags,
setNodeEmitFlags,
setCommentRange,
setSourceMapRange,
startLexicalEnvironment,
endLexicalEnvironment,
hoistVariableDeclaration,
@ -85,6 +81,10 @@ namespace ts {
* @param node A SourceFile node.
*/
function transformSourceFile(node: SourceFile) {
if (isDeclarationFile(node)) {
return node;
}
return visitNode(node, visitor, isSourceFile);
}
@ -449,7 +449,7 @@ namespace ts {
node = visitEachChild(node, visitor, context);
}
setNodeEmitFlags(node, NodeEmitFlags.EmitEmitHelpers | node.emitFlags);
setEmitFlags(node, EmitFlags.EmitEmitHelpers | getEmitFlags(node));
return node;
}
@ -521,7 +521,7 @@ namespace ts {
// To better align with the old emitter, we should not emit a trailing source map
// entry if the class has static properties.
if (staticProperties.length > 0) {
setNodeEmitFlags(classDeclaration, NodeEmitFlags.NoTrailingSourceMap | getNodeEmitFlags(classDeclaration));
setEmitFlags(classDeclaration, EmitFlags.NoTrailingSourceMap | getEmitFlags(classDeclaration));
}
statements.push(classDeclaration);
@ -776,7 +776,7 @@ namespace ts {
// To preserve the behavior of the old emitter, we explicitly indent
// the body of a class with static initializers.
setNodeEmitFlags(classExpression, NodeEmitFlags.Indented | getNodeEmitFlags(classExpression));
setEmitFlags(classExpression, EmitFlags.Indented | getEmitFlags(classExpression));
expressions.push(startOnNewLine(createAssignment(temp, classExpression)));
addRange(expressions, generateInitializedPropertyExpressions(node, staticProperties, temp));
expressions.push(startOnNewLine(temp));
@ -1009,10 +1009,10 @@ namespace ts {
Debug.assert(isIdentifier(node.name));
const name = node.name as Identifier;
const propertyName = getMutableClone(name);
setNodeEmitFlags(propertyName, NodeEmitFlags.NoComments | NodeEmitFlags.NoSourceMap);
setEmitFlags(propertyName, EmitFlags.NoComments | EmitFlags.NoSourceMap);
const localName = getMutableClone(name);
setNodeEmitFlags(localName, NodeEmitFlags.NoComments);
setEmitFlags(localName, EmitFlags.NoComments);
return startOnNewLine(
createStatement(
@ -1418,7 +1418,7 @@ namespace ts {
moveRangePastDecorators(member)
);
setNodeEmitFlags(helper, NodeEmitFlags.NoComments);
setEmitFlags(helper, EmitFlags.NoComments);
return helper;
}
@ -1467,7 +1467,7 @@ namespace ts {
);
const result = createAssignment(getDeclarationName(node), expression, moveRangePastDecorators(node));
setNodeEmitFlags(result, NodeEmitFlags.NoComments);
setEmitFlags(result, EmitFlags.NoComments);
return result;
}
// Emit the call to __decorate. Given the class:
@ -1491,7 +1491,7 @@ namespace ts {
moveRangePastDecorators(node)
);
setNodeEmitFlags(result, NodeEmitFlags.NoComments);
setEmitFlags(result, EmitFlags.NoComments);
return result;
}
}
@ -1521,7 +1521,7 @@ namespace ts {
transformDecorator(decorator),
parameterOffset,
/*location*/ decorator.expression);
setNodeEmitFlags(helper, NodeEmitFlags.NoComments);
setEmitFlags(helper, EmitFlags.NoComments);
expressions.push(helper);
}
}
@ -2324,11 +2324,11 @@ namespace ts {
if (languageVersion >= ScriptTarget.ES6) {
if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.AsyncMethodWithSuperBinding) {
enableSubstitutionForAsyncMethodsWithSuper();
setNodeEmitFlags(block, NodeEmitFlags.EmitAdvancedSuperHelper);
setEmitFlags(block, EmitFlags.EmitAdvancedSuperHelper);
}
else if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.AsyncMethodWithSuper) {
enableSubstitutionForAsyncMethodsWithSuper();
setNodeEmitFlags(block, NodeEmitFlags.EmitSuperHelper);
setEmitFlags(block, EmitFlags.EmitSuperHelper);
}
}
@ -2375,7 +2375,7 @@ namespace ts {
setOriginalNode(parameter, node);
setCommentRange(parameter, node);
setSourceMapRange(parameter, moveRangePastModifiers(node));
setNodeEmitFlags(parameter.name, NodeEmitFlags.NoTrailingSourceMap);
setEmitFlags(parameter.name, EmitFlags.NoTrailingSourceMap);
return parameter;
}
@ -2534,7 +2534,7 @@ namespace ts {
// We request to be advised when the printer is about to print this node. This allows
// us to set up the correct state for later substitutions.
let emitFlags = NodeEmitFlags.AdviseOnEmitNode;
let emitFlags = EmitFlags.AdviseOnEmitNode;
// If needed, we should emit a variable declaration for the enum. If we emit
// a leading variable declaration, we should not emit leading comments for the
@ -2544,7 +2544,7 @@ namespace ts {
// We should still emit the comments if we are emitting a system module.
if (moduleKind !== ModuleKind.System || currentScope !== currentSourceFile) {
emitFlags |= NodeEmitFlags.NoLeadingComments;
emitFlags |= EmitFlags.NoLeadingComments;
}
}
@ -2584,7 +2584,7 @@ namespace ts {
);
setOriginalNode(enumStatement, node);
setNodeEmitFlags(enumStatement, emitFlags);
setEmitFlags(enumStatement, emitFlags);
statements.push(enumStatement);
if (isNamespaceExport(node)) {
@ -2736,7 +2736,7 @@ namespace ts {
// })(m1 || (m1 = {})); // trailing comment module
//
setCommentRange(statement, node);
setNodeEmitFlags(statement, NodeEmitFlags.NoTrailingComments);
setEmitFlags(statement, EmitFlags.NoTrailingComments);
statements.push(statement);
}
@ -2759,7 +2759,7 @@ namespace ts {
// We request to be advised when the printer is about to print this node. This allows
// us to set up the correct state for later substitutions.
let emitFlags = NodeEmitFlags.AdviseOnEmitNode;
let emitFlags = EmitFlags.AdviseOnEmitNode;
// If needed, we should emit a variable declaration for the module. If we emit
// a leading variable declaration, we should not emit leading comments for the
@ -2768,7 +2768,7 @@ namespace ts {
addVarForEnumOrModuleDeclaration(statements, node);
// We should still emit the comments if we are emitting a system module.
if (moduleKind !== ModuleKind.System || currentScope !== currentSourceFile) {
emitFlags |= NodeEmitFlags.NoLeadingComments;
emitFlags |= EmitFlags.NoLeadingComments;
}
}
@ -2820,7 +2820,7 @@ namespace ts {
);
setOriginalNode(moduleStatement, node);
setNodeEmitFlags(moduleStatement, emitFlags);
setEmitFlags(moduleStatement, emitFlags);
statements.push(moduleStatement);
return statements;
}
@ -2895,7 +2895,7 @@ namespace ts {
// })(hello || (hello = {}));
// We only want to emit comment on the namespace which contains block body itself, not the containing namespaces.
if (body.kind !== SyntaxKind.ModuleBlock) {
setNodeEmitFlags(block, block.emitFlags | NodeEmitFlags.NoComments);
setEmitFlags(block, getEmitFlags(block) | EmitFlags.NoComments);
}
return block;
}
@ -2936,7 +2936,7 @@ namespace ts {
}
const moduleReference = createExpressionFromEntityName(<EntityName>node.moduleReference);
setNodeEmitFlags(moduleReference, NodeEmitFlags.NoComments | NodeEmitFlags.NoNestedComments);
setEmitFlags(moduleReference, EmitFlags.NoComments | EmitFlags.NoNestedComments);
if (isNamedExternalModuleExport(node) || !isNamespaceExport(node)) {
// export var ${name} = ${moduleReference};
@ -3048,15 +3048,15 @@ namespace ts {
function getNamespaceMemberName(name: Identifier, allowComments?: boolean, allowSourceMaps?: boolean): Expression {
const qualifiedName = createPropertyAccess(currentNamespaceContainerName, getSynthesizedClone(name), /*location*/ name);
let emitFlags: NodeEmitFlags;
let emitFlags: EmitFlags;
if (!allowComments) {
emitFlags |= NodeEmitFlags.NoComments;
emitFlags |= EmitFlags.NoComments;
}
if (!allowSourceMaps) {
emitFlags |= NodeEmitFlags.NoSourceMap;
emitFlags |= EmitFlags.NoSourceMap;
}
if (emitFlags) {
setNodeEmitFlags(qualifiedName, emitFlags);
setEmitFlags(qualifiedName, emitFlags);
}
return qualifiedName;
}
@ -3093,7 +3093,7 @@ namespace ts {
* @param allowComments A value indicating whether comments may be emitted for the name.
*/
function getLocalName(node: DeclarationStatement | ClassExpression, noSourceMaps?: boolean, allowComments?: boolean) {
return getDeclarationName(node, allowComments, !noSourceMaps, NodeEmitFlags.LocalName);
return getDeclarationName(node, allowComments, !noSourceMaps, EmitFlags.LocalName);
}
/**
@ -3111,7 +3111,7 @@ namespace ts {
return getNamespaceMemberName(getDeclarationName(node), allowComments, !noSourceMaps);
}
return getDeclarationName(node, allowComments, !noSourceMaps, NodeEmitFlags.ExportName);
return getDeclarationName(node, allowComments, !noSourceMaps, EmitFlags.ExportName);
}
/**
@ -3122,20 +3122,20 @@ namespace ts {
* @param allowSourceMaps A value indicating whether source maps may be emitted for the name.
* @param emitFlags Additional NodeEmitFlags to specify for the name.
*/
function getDeclarationName(node: DeclarationStatement | ClassExpression, allowComments?: boolean, allowSourceMaps?: boolean, emitFlags?: NodeEmitFlags) {
function getDeclarationName(node: DeclarationStatement | ClassExpression, allowComments?: boolean, allowSourceMaps?: boolean, emitFlags?: EmitFlags) {
if (node.name) {
const name = getMutableClone(node.name);
emitFlags |= getNodeEmitFlags(node.name);
emitFlags |= getEmitFlags(node.name);
if (!allowSourceMaps) {
emitFlags |= NodeEmitFlags.NoSourceMap;
emitFlags |= EmitFlags.NoSourceMap;
}
if (!allowComments) {
emitFlags |= NodeEmitFlags.NoComments;
emitFlags |= EmitFlags.NoComments;
}
if (emitFlags) {
setNodeEmitFlags(name, emitFlags);
setEmitFlags(name, emitFlags);
}
return name;
@ -3342,7 +3342,7 @@ namespace ts {
function trySubstituteNamespaceExportedName(node: Identifier): Expression {
// If this is explicitly a local name, do not substitute.
if (enabledSubstitutions & applicableSubstitutions && (getNodeEmitFlags(node) & NodeEmitFlags.LocalName) === 0) {
if (enabledSubstitutions & applicableSubstitutions && (getEmitFlags(node) & EmitFlags.LocalName) === 0) {
// If we are nested within a namespace declaration, we may need to qualifiy
// an identifier that is exported from a merged namespace.
const container = resolver.getReferencedExportContainer(node, /*prefixLocals*/ false);

View File

@ -493,10 +493,7 @@ namespace ts {
/* @internal */ nextContainer?: Node; // Next container in declaration order (initialized by binding)
/* @internal */ localSymbol?: Symbol; // Local symbol declared by node (initialized by binding only for exported nodes)
/* @internal */ flowNode?: FlowNode; // Associated FlowNode (initialized by binding)
/* @internal */ transformId?: number; // Associates transient transformation properties with a specific transformation (initialized by transformation).
/* @internal */ emitFlags?: NodeEmitFlags; // Transient emit flags for a synthesized node (initialized by transformation).
/* @internal */ sourceMapRange?: TextRange; // Transient custom sourcemap range for a synthesized node (initialized by transformation).
/* @internal */ commentRange?: TextRange; // Transient custom comment range for a synthesized node (initialized by transformation).
/* @internal */ emitNode?: EmitNode; // Associated EmitNode (initialized by transforms)
}
export interface NodeArray<T extends Node> extends Array<T>, TextRange {
@ -3153,7 +3150,16 @@ namespace ts {
}
/* @internal */
export const enum NodeEmitFlags {
export interface EmitNode {
flags?: EmitFlags;
commentRange?: TextRange;
sourceMapRange?: TextRange;
tokenSourceMapRanges?: Map<TextRange>;
annotatedNodes?: Node[]; // Tracks Parse-tree nodes with EmitNodes for eventual cleanup.
}
/* @internal */
export const enum EmitFlags {
EmitEmitHelpers = 1 << 0, // Any emit helpers should be written to this node.
EmitExportStar = 1 << 1, // The export * helper should be written to this node.
EmitSuperHelper = 1 << 2, // Emit the basic _super helper for async methods.