From 5422446b0b20a620a43b901962b58c83058df644 Mon Sep 17 00:00:00 2001 From: Ivo Gabe de Wolff Date: Sat, 8 Oct 2016 12:28:32 +0200 Subject: [PATCH 1/8] Expose `emit` function --- src/compiler/emitter.ts | 188 ++++++++++++++++++++++++------------ src/compiler/transformer.ts | 4 +- 2 files changed, 128 insertions(+), 64 deletions(-) diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index b3242e211de92..1f546a539c91f 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -4,7 +4,6 @@ /// /// -/* @internal */ namespace ts { // Flags enum to track count of temp variables and a few dedicated names const enum TempFlags { @@ -16,8 +15,131 @@ namespace ts { const id = (s: SourceFile) => s; const nullTransformers: Transformer[] = [ctx => id]; + export function emit(file: SourceFile, transformers: Transformer[] = nullTransformers, newLine = "\n") { + let result: string; + + const options: CompilerOptions = {}; + const host: EmitHost = { + getCompilerOptions() { + return options; + }, + getSourceFile(fileName: string) { + if (fileName === file.fileName) return file; + }, + getSourceFileByPath(path: Path) { + if (path === file.fileName) return file; + }, + getCurrentDirectory() { + return ""; + }, + getSourceFiles() { + return [file]; + }, + isSourceFileFromExternalLibrary() { + return false; + }, + getCommonSourceDirectory() { + return ""; + }, + getCanonicalFileName(fileName: string) { + return fileName; + }, + getNewLine() { + return newLine; + }, + isEmitBlocked() { + return false; + }, + writeFile(fileName: string, data: string) { + result = data; + } + }; + + const transform = transformFiles(undefined, host, [file], transformers); + + const printFile = createPrinter(host, undefined, createDiagnosticCollection(), transform, () => false); + + printFile("output.js", "", [file], false); + + // Clean up emit nodes on parse tree + disposeEmitNodes(file); + + return { + result + }; + } + // targetSourceFile is when users only want one file in entire project to be emitted. This is used in compileOnSave feature + /* @internal */ export function emitFiles(resolver: EmitResolver, host: EmitHost, targetSourceFile: SourceFile, emitOnlyDtsFiles?: boolean): EmitResult { + const compilerOptions = host.getCompilerOptions(); + const sourceMapDataList: SourceMapData[] = compilerOptions.sourceMap || compilerOptions.inlineSourceMap ? [] : undefined; + const emittedFilesList: string[] = compilerOptions.listEmittedFiles ? [] : undefined; + const emitterDiagnostics = createDiagnosticCollection(); + const transformers: Transformer[] = emitOnlyDtsFiles ? nullTransformers : getTransformers(compilerOptions); + let emitSkipped = false; + + const sourceFiles = getSourceFilesToEmit(host, targetSourceFile); + + // Transform the source files + performance.mark("beforeTransform"); + const transform = transformFiles(resolver, host, sourceFiles, transformers); + performance.measure("transformTime", "beforeTransform"); + + const printFile = createPrinter(host, emittedFilesList, emitterDiagnostics, transform, resolver.hasGlobalName); + + // Emit each output file + performance.mark("beforePrint"); + forEachTransformedEmitFile(host, transform.transformed, emitFile, emitOnlyDtsFiles); + performance.measure("printTime", "beforePrint"); + + // Clean up emit nodes on parse tree + for (const sourceFile of sourceFiles) { + disposeEmitNodes(sourceFile); + } + + return { + emitSkipped, + diagnostics: emitterDiagnostics.getDiagnostics(), + emittedFiles: emittedFilesList, + sourceMaps: sourceMapDataList + }; + + function emitFile(jsFilePath: string, sourceMapFilePath: string, declarationFilePath: string, sourceFiles: SourceFile[], isBundledEmit: boolean) { + // Make sure not to write js file and source map file if any of them cannot be written + if (!host.isEmitBlocked(jsFilePath) && !compilerOptions.noEmit) { + if (!emitOnlyDtsFiles) { + printFile(jsFilePath, sourceMapFilePath, sourceFiles, isBundledEmit); + } + } + else { + emitSkipped = true; + } + + if (declarationFilePath) { + emitSkipped = writeDeclarationFile(declarationFilePath, getOriginalSourceFiles(sourceFiles), isBundledEmit, host, resolver, emitterDiagnostics, emitOnlyDtsFiles) || emitSkipped; + } + + if (!emitSkipped && emittedFilesList) { + if (!emitOnlyDtsFiles) { + emittedFilesList.push(jsFilePath); + } + if (sourceMapFilePath) { + emittedFilesList.push(sourceMapFilePath); + } + if (declarationFilePath) { + emittedFilesList.push(declarationFilePath); + } + } + } + } + function createPrinter( + host: EmitHost, + emittedFilesList: string[], + emitterDiagnostics: DiagnosticCollection, + { transformed, emitNodeWithSubstitution, emitNodeWithNotification }: TransformationResult, + hasGlobalName: (name: string) => boolean + ) { const delimiters = createDelimiterMap(); const brackets = createBracketsMap(); @@ -187,15 +309,12 @@ const _super = (function (geti, seti) { const cache = Object.create(null); return name => cache[name] || (cache[name] = { get value() { return geti(name); }, set value(v) { seti(name, v); } }); })(name => super[name], (name, value) => super[name] = value);`; - + const compilerOptions = host.getCompilerOptions(); const languageVersion = getEmitScriptTarget(compilerOptions); const moduleKind = getEmitModuleKind(compilerOptions); const sourceMapDataList: SourceMapData[] = compilerOptions.sourceMap || compilerOptions.inlineSourceMap ? [] : undefined; - const emittedFilesList: string[] = compilerOptions.listEmittedFiles ? [] : undefined; - const emitterDiagnostics = createDiagnosticCollection(); const newLine = host.getNewLine(); - const transformers: Transformer[] = emitOnlyDtsFiles ? nullTransformers : getTransformers(compilerOptions); const writer = createTextWriter(newLine); const { write, @@ -230,63 +349,8 @@ const _super = (function (geti, seti) { let paramEmitted: boolean; let awaiterEmitted: boolean; let isOwnFileEmit: boolean; - let emitSkipped = false; - - const sourceFiles = getSourceFilesToEmit(host, targetSourceFile); - - // Transform the source files - performance.mark("beforeTransform"); - const { - transformed, - emitNodeWithSubstitution, - emitNodeWithNotification - } = transformFiles(resolver, host, sourceFiles, transformers); - performance.measure("transformTime", "beforeTransform"); - - // Emit each output file - performance.mark("beforePrint"); - forEachTransformedEmitFile(host, transformed, emitFile, emitOnlyDtsFiles); - performance.measure("printTime", "beforePrint"); - // Clean up emit nodes on parse tree - for (const sourceFile of sourceFiles) { - disposeEmitNodes(sourceFile); - } - - return { - emitSkipped, - diagnostics: emitterDiagnostics.getDiagnostics(), - emittedFiles: emittedFilesList, - sourceMaps: sourceMapDataList - }; - - function emitFile(jsFilePath: string, sourceMapFilePath: string, declarationFilePath: string, sourceFiles: SourceFile[], isBundledEmit: boolean) { - // Make sure not to write js file and source map file if any of them cannot be written - if (!host.isEmitBlocked(jsFilePath) && !compilerOptions.noEmit) { - if (!emitOnlyDtsFiles) { - printFile(jsFilePath, sourceMapFilePath, sourceFiles, isBundledEmit); - } - } - else { - emitSkipped = true; - } - - if (declarationFilePath) { - emitSkipped = writeDeclarationFile(declarationFilePath, getOriginalSourceFiles(sourceFiles), isBundledEmit, host, resolver, emitterDiagnostics, emitOnlyDtsFiles) || emitSkipped; - } - - if (!emitSkipped && emittedFilesList) { - if (!emitOnlyDtsFiles) { - emittedFilesList.push(jsFilePath); - } - if (sourceMapFilePath) { - emittedFilesList.push(sourceMapFilePath); - } - if (declarationFilePath) { - emittedFilesList.push(declarationFilePath); - } - } - } + return printFile; function printFile(jsFilePath: string, sourceMapFilePath: string, sourceFiles: SourceFile[], isBundledEmit: boolean) { sourceMap.initialize(jsFilePath, sourceMapFilePath, sourceFiles, isBundledEmit); @@ -2620,7 +2684,7 @@ const _super = (function (geti, seti) { } function isUniqueName(name: string): boolean { - return !resolver.hasGlobalName(name) && + return !hasGlobalName(name) && !hasProperty(currentFileIdentifiers, name) && !hasProperty(generatedNameSet, name); } diff --git a/src/compiler/transformer.ts b/src/compiler/transformer.ts index 92407af2bb9fe..e90881eac9aae 100644 --- a/src/compiler/transformer.ts +++ b/src/compiler/transformer.ts @@ -8,7 +8,6 @@ /// /// -/* @internal */ namespace ts { const moduleTransformerMap = createMap({ [ModuleKind.ES6]: transformES6Module, @@ -99,9 +98,9 @@ namespace ts { onEmitNode?: (emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void) => void; } - /* @internal */ export type Transformer = (context: TransformationContext) => (node: SourceFile) => SourceFile; + /* @internal */ export function getTransformers(compilerOptions: CompilerOptions) { const jsx = compilerOptions.jsx; const languageVersion = getEmitScriptTarget(compilerOptions); @@ -133,6 +132,7 @@ namespace ts { * @param sourceFiles An array of source files * @param transforms An array of Transformers. */ + /* @internal */ export function transformFiles(resolver: EmitResolver, host: EmitHost, sourceFiles: SourceFile[], transformers: Transformer[]): TransformationResult { const lexicalEnvironmentVariableDeclarationsStack: VariableDeclaration[][] = []; const lexicalEnvironmentFunctionDeclarationsStack: FunctionDeclaration[][] = []; From 5fe10426801d6f860d8c918b5804417eb9fa73d0 Mon Sep 17 00:00:00 2001 From: Ivo Gabe de Wolff Date: Sat, 8 Oct 2016 14:06:35 +0200 Subject: [PATCH 2/8] Expose `src/compiler/factory.ts` as `ts.factory`. --- src/compiler/binder.ts | 6 +- src/compiler/checker.ts | 2 +- src/compiler/comments.ts | 6 +- src/compiler/emitter.ts | 30 +- src/compiler/factory.ts | 4 +- src/compiler/transformer.ts | 10 +- src/compiler/transformers/destructuring.ts | 68 +-- src/compiler/transformers/es6.ts | 600 ++++++++++----------- src/compiler/transformers/es7.ts | 24 +- src/compiler/transformers/generators.ts | 228 ++++---- src/compiler/transformers/jsx.ts | 30 +- src/compiler/transformers/module/es6.ts | 10 +- src/compiler/transformers/module/module.ts | 266 ++++----- src/compiler/transformers/module/system.ts | 250 ++++----- src/compiler/transformers/ts.ts | 562 +++++++++---------- src/compiler/utilities.ts | 6 +- src/compiler/visitor.ts | 180 +++---- 17 files changed, 1141 insertions(+), 1141 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 04b115b4dd9dd..718a81bc1de16 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -2595,7 +2595,7 @@ namespace ts { } // Currently, we only support generators that were originally async function bodies. - if (asteriskToken && getEmitFlags(node) & EmitFlags.AsyncFunctionBody) { + if (asteriskToken && factory.getEmitFlags(node) & EmitFlags.AsyncFunctionBody) { transformFlags |= TransformFlags.AssertGenerator; } @@ -2670,7 +2670,7 @@ namespace ts { // down-level generator. // Currently we do not support transforming any other generator fucntions // down level. - if (asteriskToken && getEmitFlags(node) & EmitFlags.AsyncFunctionBody) { + if (asteriskToken && factory.getEmitFlags(node) & EmitFlags.AsyncFunctionBody) { transformFlags |= TransformFlags.AssertGenerator; } } @@ -2701,7 +2701,7 @@ namespace ts { // down-level generator. // Currently we do not support transforming any other generator fucntions // down level. - if (asteriskToken && getEmitFlags(node) & EmitFlags.AsyncFunctionBody) { + if (asteriskToken && factory.getEmitFlags(node) & EmitFlags.AsyncFunctionBody) { transformFlags |= TransformFlags.AssertGenerator; } diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index ef428f26de913..b213960d94939 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -13438,7 +13438,7 @@ namespace ts { * its value is discarded (e.g. the left side of the comma operator). */ function isSideEffectFree(node: Node): boolean { - node = skipParentheses(node); + node = factory.skipParentheses(node); switch (node.kind) { case SyntaxKind.Identifier: case SyntaxKind.StringLiteral: diff --git a/src/compiler/comments.ts b/src/compiler/comments.ts index 116a8e849a373..5b5413b74feb3 100644 --- a/src/compiler/comments.ts +++ b/src/compiler/comments.ts @@ -41,8 +41,8 @@ namespace ts { } if (node) { - const { pos, end } = getCommentRange(node); - const emitFlags = getEmitFlags(node); + const { pos, end } = factory.getCommentRange(node); + const emitFlags = factory.getEmitFlags(node); if ((pos < 0 && end < 0) || (pos === end)) { // Both pos and end are synthesized, so just emit the node without comments. if (emitFlags & EmitFlags.NoNestedComments) { @@ -129,7 +129,7 @@ namespace ts { } const { pos, end } = detachedRange; - const emitFlags = getEmitFlags(node); + const emitFlags = factory.getEmitFlags(node); const skipLeadingComments = pos < 0 || (emitFlags & EmitFlags.NoLeadingComments) !== 0; const skipTrailingComments = disabled || end < 0 || (emitFlags & EmitFlags.NoTrailingComments) !== 0; diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 1f546a539c91f..1cebd5831763b 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -62,7 +62,7 @@ namespace ts { printFile("output.js", "", [file], false); // Clean up emit nodes on parse tree - disposeEmitNodes(file); + factory.disposeEmitNodes(file); return { result @@ -95,7 +95,7 @@ namespace ts { // Clean up emit nodes on parse tree for (const sourceFile of sourceFiles) { - disposeEmitNodes(sourceFile); + factory.disposeEmitNodes(sourceFile); } return { @@ -925,7 +925,7 @@ const _super = (function (geti, seti) { // function emitIdentifier(node: Identifier) { - if (getEmitFlags(node) & EmitFlags.UMDDefine) { + if (factory.getEmitFlags(node) & EmitFlags.UMDDefine) { writeLines(umdHelper); } else { @@ -1198,7 +1198,7 @@ const _super = (function (geti, seti) { write("{}"); } else { - const indentedFlag = getEmitFlags(node) & EmitFlags.Indented; + const indentedFlag = factory.getEmitFlags(node) & EmitFlags.Indented; if (indentedFlag) { increaseIndent(); } @@ -1216,7 +1216,7 @@ const _super = (function (geti, seti) { function emitPropertyAccessExpression(node: PropertyAccessExpression) { let indentBeforeDot = false; let indentAfterDot = false; - if (!(getEmitFlags(node) & EmitFlags.NoIndentation)) { + if (!(factory.getEmitFlags(node) & EmitFlags.NoIndentation)) { const dotRangeStart = node.expression.end; const dotRangeEnd = skipTrivia(currentText, node.expression.end) + 1; const dotToken = { kind: SyntaxKind.DotToken, pos: dotRangeStart, end: dotRangeEnd }; @@ -1245,7 +1245,7 @@ const _super = (function (geti, seti) { } else if (isPropertyAccessExpression(expression) || isElementAccessExpression(expression)) { // check if constant enum value is integer - const constantValue = getConstantValue(expression); + const constantValue = factory.getConstantValue(expression); // isFinite handles cases when constantValue is undefined return isFinite(constantValue) && Math.floor(constantValue) === constantValue @@ -1459,7 +1459,7 @@ const _super = (function (geti, seti) { } function emitBlockStatements(node: Block) { - if (getEmitFlags(node) & EmitFlags.SingleLine) { + if (factory.getEmitFlags(node) & EmitFlags.SingleLine) { emitList(node, node.statements, ListFormat.SingleLineBlockStatements); } else { @@ -1663,12 +1663,12 @@ const _super = (function (geti, seti) { const body = node.body; if (body) { if (isBlock(body)) { - const indentedFlag = getEmitFlags(node) & EmitFlags.Indented; + const indentedFlag = factory.getEmitFlags(node) & EmitFlags.Indented; if (indentedFlag) { increaseIndent(); } - if (getEmitFlags(node) & EmitFlags.ReuseTempVariableScope) { + if (factory.getEmitFlags(node) & EmitFlags.ReuseTempVariableScope) { emitSignatureHead(node); emitBlockFunctionBody(node, body); } @@ -1712,7 +1712,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 (getEmitFlags(body) & EmitFlags.SingleLine) { + if (factory.getEmitFlags(body) & EmitFlags.SingleLine) { return true; } @@ -1783,7 +1783,7 @@ const _super = (function (geti, seti) { write("class"); emitNodeWithPrefix(" ", node.name, emitIdentifierName); - const indentedFlag = getEmitFlags(node) & EmitFlags.Indented; + const indentedFlag = factory.getEmitFlags(node) & EmitFlags.Indented; if (indentedFlag) { increaseIndent(); } @@ -2116,8 +2116,8 @@ const _super = (function (geti, seti) { // "comment1" is not considered to be leading comment for node.initializer // but rather a trailing comment on the previous node. const initializer = node.initializer; - if ((getEmitFlags(initializer) & EmitFlags.NoLeadingComments) === 0) { - const commentRange = getCommentRange(initializer); + if ((factory.getEmitFlags(initializer) & EmitFlags.NoLeadingComments) === 0) { + const commentRange = factory.getCommentRange(initializer); emitTrailingCommentsOfPosition(commentRange.pos); } @@ -2189,7 +2189,7 @@ const _super = (function (geti, seti) { } function emitHelpers(node: Node) { - const emitFlags = getEmitFlags(node); + const emitFlags = factory.getEmitFlags(node); let helpersEmitted = false; if (emitFlags & EmitFlags.EmitEmitHelpers) { helpersEmitted = emitEmitHelpers(currentSourceFile); @@ -2450,7 +2450,7 @@ const _super = (function (geti, seti) { } if (shouldEmitInterveningComments) { - const commentRange = getCommentRange(child); + const commentRange = factory.getCommentRange(child); emitTrailingCommentsOfPosition(commentRange.pos); } else { diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index d873c3ef87777..5f1080b3a15fb 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -1,8 +1,7 @@ /// /// -/* @internal */ -namespace ts { +namespace ts.factory { let NodeConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node; let SourceFileConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node; @@ -2669,6 +2668,7 @@ namespace ts { * Clears any EmitNode entries from parse-tree nodes. * @param sourceFile A source file. */ + /* @internal */ 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 diff --git a/src/compiler/transformer.ts b/src/compiler/transformer.ts index e90881eac9aae..b76bf140942cb 100644 --- a/src/compiler/transformer.ts +++ b/src/compiler/transformer.ts @@ -201,7 +201,7 @@ namespace ts { */ function isSubstitutionEnabled(node: Node) { return (enabledSyntaxKindFeatures[node.kind] & SyntaxKindFeatureFlags.Substitution) !== 0 - && (getEmitFlags(node) & EmitFlags.NoSubstitution) === 0; + && (factory.getEmitFlags(node) & EmitFlags.NoSubstitution) === 0; } /** @@ -238,7 +238,7 @@ namespace ts { */ function isEmitNotificationEnabled(node: Node) { return (enabledSyntaxKindFeatures[node.kind] & SyntaxKindFeatureFlags.EmitNotifications) !== 0 - || (getEmitFlags(node) & EmitFlags.AdviseOnEmitNode) !== 0; + || (factory.getEmitFlags(node) & EmitFlags.AdviseOnEmitNode) !== 0; } /** @@ -264,7 +264,7 @@ namespace ts { */ function hoistVariableDeclaration(name: Identifier): void { Debug.assert(!lexicalEnvironmentDisabled, "Cannot modify the lexical environment during the print phase."); - const decl = createVariableDeclaration(name); + const decl = factory.createVariableDeclaration(name); if (!hoistedVariableDeclarations) { hoistedVariableDeclarations = [decl]; } @@ -318,9 +318,9 @@ namespace ts { } if (hoistedVariableDeclarations) { - const statement = createVariableStatement( + const statement = factory.createVariableStatement( /*modifiers*/ undefined, - createVariableDeclarationList(hoistedVariableDeclarations) + factory.createVariableDeclarationList(hoistedVariableDeclarations) ); if (!statements) { diff --git a/src/compiler/transformers/destructuring.ts b/src/compiler/transformers/destructuring.ts index 3bfa778cf9b33..ce49fd2d650a9 100644 --- a/src/compiler/transformers/destructuring.ts +++ b/src/compiler/transformers/destructuring.ts @@ -57,23 +57,23 @@ namespace ts { expressions.push(value); } - const expression = inlineExpressions(expressions); + const expression = factory.inlineExpressions(expressions); aggregateTransformFlags(expression); return expression; function emitAssignment(name: Identifier, value: Expression, location: TextRange) { - const expression = createAssignment(name, value, location); + const expression = factory.createAssignment(name, value, location); // NOTE: this completely disables source maps, but aligns with the behavior of // `emitAssignment` in the old emitter. - setEmitFlags(expression, EmitFlags.NoNestedSourceMaps); + factory.setEmitFlags(expression, EmitFlags.NoNestedSourceMaps); aggregateTransformFlags(expression); expressions.push(expression); } function emitTempVariableAssignment(value: Expression, location: TextRange) { - const name = createTempVariable(recordTempVariable); + const name = factory.createTempVariable(recordTempVariable); emitAssignment(name, value, location); return name; } @@ -98,18 +98,18 @@ namespace ts { return declarations; function emitAssignment(name: Identifier, value: Expression, location: TextRange) { - const declaration = createVariableDeclaration(name, /*type*/ undefined, value, location); + const declaration = factory.createVariableDeclaration(name, /*type*/ undefined, value, location); // NOTE: this completely disables source maps, but aligns with the behavior of // `emitAssignment` in the old emitter. - setEmitFlags(declaration, EmitFlags.NoNestedSourceMaps); + factory.setEmitFlags(declaration, EmitFlags.NoNestedSourceMaps); aggregateTransformFlags(declaration); declarations.push(declaration); } function emitTempVariableAssignment(value: Expression, location: TextRange) { - const name = createTempVariable(/*recordTempVariable*/ undefined); + const name = factory.createTempVariable(/*recordTempVariable*/ undefined); emitAssignment(name, value, location); return name; } @@ -138,25 +138,25 @@ namespace ts { function emitAssignment(name: Identifier, value: Expression, location: TextRange, original: Node) { if (pendingAssignments) { pendingAssignments.push(value); - value = inlineExpressions(pendingAssignments); + value = factory.inlineExpressions(pendingAssignments); pendingAssignments = undefined; } - const declaration = createVariableDeclaration(name, /*type*/ undefined, value, location); + const declaration = factory.createVariableDeclaration(name, /*type*/ undefined, value, location); declaration.original = original; // NOTE: this completely disables source maps, but aligns with the behavior of // `emitAssignment` in the old emitter. - setEmitFlags(declaration, EmitFlags.NoNestedSourceMaps); + factory.setEmitFlags(declaration, EmitFlags.NoNestedSourceMaps); declarations.push(declaration); aggregateTransformFlags(declaration); } function emitTempVariableAssignment(value: Expression, location: TextRange) { - const name = createTempVariable(recordTempVariable); + const name = factory.createTempVariable(recordTempVariable); if (recordTempVariable) { - const assignment = createAssignment(name, value, location); + const assignment = factory.createAssignment(name, value, location); if (pendingAssignments) { pendingAssignments.push(assignment); } @@ -190,7 +190,7 @@ namespace ts { flattenDestructuring(context, node, /*value*/ undefined, node, emitAssignment, emitTempVariableAssignment, visitor); - const expression = inlineExpressions(pendingAssignments); + const expression = factory.inlineExpressions(pendingAssignments); aggregateTransformFlags(expression); return expression; @@ -200,18 +200,18 @@ namespace ts { } function emitTempVariableAssignment(value: Expression, location: TextRange) { - const name = createTempVariable(recordTempVariable); + const name = factory.createTempVariable(recordTempVariable); emitPendingAssignment(name, value, location, /*original*/ undefined); return name; } function emitPendingAssignment(name: Expression, value: Expression, location: TextRange, original: Node) { - const expression = createAssignment(name, value, location); + const expression = factory.createAssignment(name, value, location); expression.original = original; // NOTE: this completely disables source maps, but aligns with the behavior of // `emitAssignment` in the old emitter. - setEmitFlags(expression, EmitFlags.NoNestedSourceMaps); + factory.setEmitFlags(expression, EmitFlags.NoNestedSourceMaps); pendingAssignments.push(expression); return expression; @@ -270,9 +270,9 @@ namespace ts { emitArrayLiteralAssignment(target, value, location); } else { - const name = getMutableClone(target); - setSourceMapRange(name, target); - setCommentRange(name, target); + const name = factory.getMutableClone(target); + factory.setSourceMapRange(name, target); + factory.setCommentRange(name, target); emitAssignment(name, value, location, /*original*/ undefined); } } @@ -311,10 +311,10 @@ namespace ts { if (e.kind !== SyntaxKind.OmittedExpression) { // Assignment for target = value.propName should highligh whole property, hence use e as source map node if (e.kind !== SyntaxKind.SpreadElementExpression) { - emitDestructuringAssignment(e, createElementAccess(value, createLiteral(i)), e); + emitDestructuringAssignment(e, factory.createElementAccess(value, factory.createLiteral(i)), e); } else if (i === numElements - 1) { - emitDestructuringAssignment((e).expression, createArraySlice(value, i), e); + emitDestructuringAssignment((e).expression, factory.createArraySlice(value, i), e); } } } @@ -329,7 +329,7 @@ namespace ts { } else if (!value) { // Use 'void 0' in absence of value and initializer - value = createVoidZero(); + value = factory.createVoidZero(); } const name = target.name; @@ -356,10 +356,10 @@ namespace ts { else { if (!element.dotDotDotToken) { // Rewrite element to a declaration that accesses array element at index i - emitBindingElement(element, createElementAccess(value, i)); + emitBindingElement(element, factory.createElementAccess(value, i)); } else if (i === numElements - 1) { - emitBindingElement(element, createArraySlice(value, i)); + emitBindingElement(element, factory.createArraySlice(value, i)); } } } @@ -371,11 +371,11 @@ namespace ts { function createDefaultValueCheck(value: Expression, defaultValue: Expression, location: TextRange): Expression { value = ensureIdentifier(value, /*reuseIdentifierExpressions*/ true, location, emitTempVariableAssignment); - return createConditional( - createStrictEquality(value, createVoidZero()), - createToken(SyntaxKind.QuestionToken), + return factory.createConditional( + factory.createStrictEquality(value, factory.createVoidZero()), + factory.createToken(SyntaxKind.QuestionToken), defaultValue, - createToken(SyntaxKind.ColonToken), + factory.createToken(SyntaxKind.ColonToken), value ); } @@ -389,24 +389,24 @@ namespace ts { */ function createDestructuringPropertyAccess(expression: Expression, propertyName: PropertyName): LeftHandSideExpression { if (isComputedPropertyName(propertyName)) { - return createElementAccess( + return factory.createElementAccess( expression, ensureIdentifier(propertyName.expression, /*reuseIdentifierExpressions*/ false, /*location*/ propertyName, emitTempVariableAssignment) ); } else if (isLiteralExpression(propertyName)) { - const clone = getSynthesizedClone(propertyName); + const clone = factory.getSynthesizedClone(propertyName); clone.text = unescapeIdentifier(clone.text); - return createElementAccess(expression, clone); + return factory.createElementAccess(expression, clone); } else { if (isGeneratedIdentifier(propertyName)) { - const clone = getSynthesizedClone(propertyName); + const clone = factory.getSynthesizedClone(propertyName); clone.text = unescapeIdentifier(clone.text); - return createPropertyAccess(expression, clone); + return factory.createPropertyAccess(expression, clone); } else { - return createPropertyAccess(expression, createIdentifier(unescapeIdentifier(propertyName.text))); + return factory.createPropertyAccess(expression, factory.createIdentifier(unescapeIdentifier(propertyName.text))); } } } diff --git a/src/compiler/transformers/es6.ts b/src/compiler/transformers/es6.ts index 7fb0594a6ccba..82eaf44369972 100644 --- a/src/compiler/transformers/es6.ts +++ b/src/compiler/transformers/es6.ts @@ -429,7 +429,7 @@ namespace ts { enclosingFunction = currentNode; if (currentNode.kind !== SyntaxKind.ArrowFunction) { enclosingNonArrowFunction = currentNode; - if (!(getEmitFlags(currentNode) & EmitFlags.AsyncFunctionBody)) { + if (!(factory.getEmitFlags(currentNode) & EmitFlags.AsyncFunctionBody)) { enclosingNonAsyncFunctionBody = currentNode; } } @@ -476,14 +476,14 @@ namespace ts { Debug.assert(convertedLoopState !== undefined); convertedLoopState.nonLocalJumps |= Jump.Return; - return createReturn( - createObjectLiteral( + return factory.createReturn( + factory.createObjectLiteral( [ - createPropertyAssignment( - createIdentifier("value"), + factory.createPropertyAssignment( + factory.createIdentifier("value"), node.expression ? visitNode(node.expression, visitor, isExpression) - : createVoidZero() + : factory.createVoidZero() ) ] ) @@ -497,7 +497,7 @@ namespace ts { convertedLoopState.containsLexicalThis = true; return node; } - return convertedLoopState.thisName || (convertedLoopState.thisName = createUniqueName("this")); + return convertedLoopState.thisName || (convertedLoopState.thisName = factory.createUniqueName("this")); } function visitIdentifier(node: Identifier): Identifier { @@ -510,7 +510,7 @@ namespace ts { if (node.text !== "arguments" && !resolver.isArgumentsLocalBinding(node)) { return node; } - return convertedLoopState.argumentsName || (convertedLoopState.argumentsName = createUniqueName("arguments")); + return convertedLoopState.argumentsName || (convertedLoopState.argumentsName = factory.createUniqueName("arguments")); } function visitBreakOrContinueStatement(node: BreakOrContinueStatement): Statement { @@ -547,7 +547,7 @@ namespace ts { setLabeledJump(convertedLoopState, /*isBreak*/ false, node.label.text, labelMarker); } } - let returnExpression: Expression = createLiteral(labelMarker); + let returnExpression: Expression = factory.createLiteral(labelMarker); if (convertedLoopState.loopOutParameters.length) { const outParams = convertedLoopState.loopOutParameters; let expr: Expression; @@ -557,12 +557,12 @@ namespace ts { expr = copyExpr; } else { - expr = createBinary(expr, SyntaxKind.CommaToken, copyExpr); + expr = factory.createBinary(expr, SyntaxKind.CommaToken, copyExpr); } } - returnExpression = createBinary(expr, SyntaxKind.CommaToken, returnExpression); + returnExpression = factory.createBinary(expr, SyntaxKind.CommaToken, returnExpression); } - return createReturn(returnExpression); + return factory.createReturn(returnExpression); } } return visitEachChild(node, visitor, context); @@ -593,10 +593,10 @@ namespace ts { ? filter(node.modifiers, isExportModifier) : undefined; - const statement = createVariableStatement( + const statement = factory.createVariableStatement( modifiers, - createVariableDeclarationList([ - createVariableDeclaration( + factory.createVariableDeclarationList([ + factory.createVariableDeclaration( getDeclarationName(node, /*allowComments*/ true), /*type*/ undefined, transformClassLikeDeclarationToExpression(node) @@ -605,13 +605,13 @@ namespace ts { /*location*/ node ); - setOriginalNode(statement, node); - startOnNewLine(statement); + factory.setOriginalNode(statement, node); + factory.startOnNewLine(statement); // Add an `export default` statement for default exports (for `--target es5 --module es6`) if (isExported && isDefault) { const statements: Statement[] = [statement]; - statements.push(createExportAssignment( + statements.push(factory.createExportAssignment( /*decorators*/ undefined, /*modifiers*/ undefined, /*isExportEquals*/ false, @@ -680,11 +680,11 @@ namespace ts { } const extendsClauseElement = getClassExtendsHeritageClauseElement(node); - const classFunction = createFunctionExpression( + const classFunction = factory.createFunctionExpression( /*asteriskToken*/ undefined, /*name*/ undefined, /*typeParameters*/ undefined, - extendsClauseElement ? [createParameter("_super")] : [], + extendsClauseElement ? [factory.createParameter("_super")] : [], /*type*/ undefined, transformClassBody(node, extendsClauseElement) ); @@ -692,22 +692,22 @@ 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 (getEmitFlags(node) & EmitFlags.Indented) { - setEmitFlags(classFunction, EmitFlags.Indented); + if (factory.getEmitFlags(node) & EmitFlags.Indented) { + factory.setEmitFlags(classFunction, EmitFlags.Indented); } // "inner" and "outer" below are added purely to preserve source map locations from // the old emitter - const inner = createPartiallyEmittedExpression(classFunction); + const inner = factory.createPartiallyEmittedExpression(classFunction); inner.end = node.end; - setEmitFlags(inner, EmitFlags.NoComments); + factory.setEmitFlags(inner, EmitFlags.NoComments); - const outer = createPartiallyEmittedExpression(inner); + const outer = factory.createPartiallyEmittedExpression(inner); outer.end = skipTrivia(currentText, node.pos); - setEmitFlags(outer, EmitFlags.NoComments); + factory.setEmitFlags(outer, EmitFlags.NoComments); - return createParen( - createCall( + return factory.createParen( + factory.createCall( outer, /*typeArguments*/ undefined, extendsClauseElement @@ -736,19 +736,19 @@ namespace ts { // The following partially-emitted expression exists purely to align our sourcemap // emit with the original emitter. - const outer = createPartiallyEmittedExpression(localName); + const outer = factory.createPartiallyEmittedExpression(localName); outer.end = closingBraceLocation.end; - setEmitFlags(outer, EmitFlags.NoComments); + factory.setEmitFlags(outer, EmitFlags.NoComments); - const statement = createReturn(outer); + const statement = factory.createReturn(outer); statement.pos = closingBraceLocation.pos; - setEmitFlags(statement, EmitFlags.NoComments | EmitFlags.NoTokenSourceMaps); + factory.setEmitFlags(statement, EmitFlags.NoComments | EmitFlags.NoTokenSourceMaps); statements.push(statement); addRange(statements, endLexicalEnvironment()); - const block = createBlock(createNodeArray(statements, /*location*/ node.members), /*location*/ undefined, /*multiLine*/ true); - setEmitFlags(block, EmitFlags.NoComments); + const block = factory.createBlock(factory.createNodeArray(statements, /*location*/ node.members), /*location*/ undefined, /*multiLine*/ true); + factory.setEmitFlags(block, EmitFlags.NoComments); return block; } @@ -762,8 +762,8 @@ namespace ts { function addExtendsHelperIfNeeded(statements: Statement[], node: ClassExpression | ClassDeclaration, extendsClauseElement: ExpressionWithTypeArguments): void { if (extendsClauseElement) { statements.push( - createStatement( - createExtendsHelper(currentSourceFile.externalHelpersModuleName, getDeclarationName(node)), + factory.createStatement( + factory.createExtendsHelper(currentSourceFile.externalHelpersModuleName, getDeclarationName(node)), /*location*/ extendsClauseElement ) ); @@ -782,7 +782,7 @@ namespace ts { const hasSynthesizedSuper = hasSynthesizedDefaultSuperCall(constructor, extendsClauseElement !== undefined); const constructorFunction = - createFunctionDeclaration( + factory.createFunctionDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, /*asteriskToken*/ undefined, @@ -795,7 +795,7 @@ namespace ts { ); if (extendsClauseElement) { - setEmitFlags(constructorFunction, EmitFlags.CapturesThis); + factory.setEmitFlags(constructorFunction, EmitFlags.CapturesThis); } statements.push(constructorFunction); } @@ -842,7 +842,7 @@ namespace ts { } else if (constructor) { // Otherwise, try to emit all potential prologue directives first. - statementOffset = addPrologueDirectives(statements, constructor.body.statements, /*ensureUseStrict*/ false, visitor); + statementOffset = factory.addPrologueDirectives(statements, constructor.body.statements, /*ensureUseStrict*/ false, visitor); } if (constructor) { @@ -870,15 +870,15 @@ namespace ts { && superCaptureStatus !== SuperCaptureResult.ReplaceWithReturn && !(constructor && isSufficientlyCoveredByReturnStatements(constructor.body))) { statements.push( - createReturn( - createIdentifier("_this") + factory.createReturn( + factory.createIdentifier("_this") ) ); } addRange(statements, endLexicalEnvironment()); - const block = createBlock( - createNodeArray( + const block = factory.createBlock( + factory.createNodeArray( statements, /*location*/ constructor ? constructor.body.statements : node.members ), @@ -887,7 +887,7 @@ namespace ts { ); if (!constructor) { - setEmitFlags(block, EmitFlags.NoComments); + factory.setEmitFlags(block, EmitFlags.NoComments); } return block; @@ -945,7 +945,7 @@ namespace ts { // but we needed to call 'super(...args)' anyway as per 14.5.14 of the ES2016 spec. // If that's the case we can just immediately return the result of a 'super()' call. if (!ctor) { - statements.push(createReturn(createDefaultSuperCallOrThis())); + statements.push(factory.createReturn(createDefaultSuperCallOrThis())); return SuperCaptureResult.ReplaceWithReturn; } @@ -984,7 +984,7 @@ namespace ts { if (firstStatement.kind === SyntaxKind.ExpressionStatement && isSuperCallExpression((firstStatement as ExpressionStatement).expression)) { const superCall = (firstStatement as ExpressionStatement).expression as CallExpression; - superCallExpression = setOriginalNode( + superCallExpression = factory.setOriginalNode( saveStateAndInvoke(superCall, visitImmediateSuperCallInBody), superCall ); @@ -993,7 +993,7 @@ namespace ts { // Return the result if we have an immediate super() call on the last statement. if (superCallExpression && statementOffset === ctorStatements.length - 1) { - statements.push(createReturn(superCallExpression)); + statements.push(factory.createReturn(superCallExpression)); return SuperCaptureResult.ReplaceWithReturn; } @@ -1009,14 +1009,14 @@ namespace ts { } function createDefaultSuperCallOrThis() { - const actualThis = createThis(); - setEmitFlags(actualThis, EmitFlags.NoSubstitution); - const superCall = createFunctionApply( - createIdentifier("_super"), + const actualThis = factory.createThis(); + factory.setEmitFlags(actualThis, EmitFlags.NoSubstitution); + const superCall = factory.createFunctionApply( + factory.createIdentifier("_super"), actualThis, - createIdentifier("arguments"), + factory.createIdentifier("arguments"), ); - return createLogicalOr(superCall, actualThis); + return factory.createLogicalOr(superCall, actualThis); } /** @@ -1032,9 +1032,9 @@ namespace ts { else if (isBindingPattern(node.name)) { // Binding patterns are converted into a generated name and are // evaluated inside the function body. - return setOriginalNode( - createParameter( - getGeneratedNameForNode(node), + return factory.setOriginalNode( + factory.createParameter( + factory.getGeneratedNameForNode(node), /*initializer*/ undefined, /*location*/ node ), @@ -1043,8 +1043,8 @@ namespace ts { } else if (node.initializer) { // Initializers are elided - return setOriginalNode( - createParameter( + return factory.setOriginalNode( + factory.createParameter( node.name, /*initializer*/ undefined, /*location*/ node @@ -1106,17 +1106,17 @@ namespace ts { * @param initializer The initializer for the parameter. */ function addDefaultValueAssignmentForBindingPattern(statements: Statement[], parameter: ParameterDeclaration, name: BindingPattern, initializer: Expression): void { - const temp = getGeneratedNameForNode(parameter); + const temp = factory.getGeneratedNameForNode(parameter); // In cases where a binding pattern is simply '[]' or '{}', // we usually don't want to emit a var declaration; however, in the presence // of an initializer, we must emit that expression to preserve side effects. if (name.elements.length > 0) { statements.push( - setEmitFlags( - createVariableStatement( + factory.setEmitFlags( + factory.createVariableStatement( /*modifiers*/ undefined, - createVariableDeclarationList( + factory.createVariableDeclarationList( flattenParameterDestructuring(context, parameter, temp, visitor) ) ), @@ -1126,9 +1126,9 @@ namespace ts { } else if (initializer) { statements.push( - setEmitFlags( - createStatement( - createAssignment( + factory.setEmitFlags( + factory.createStatement( + factory.createAssignment( temp, visitNode(initializer, visitor, isExpression) ) @@ -1149,17 +1149,17 @@ namespace ts { */ function addDefaultValueAssignmentForInitializer(statements: Statement[], parameter: ParameterDeclaration, name: Identifier, initializer: Expression): void { initializer = visitNode(initializer, visitor, isExpression); - const statement = createIf( - createStrictEquality( - getSynthesizedClone(name), - createVoidZero() + const statement = factory.createIf( + factory.createStrictEquality( + factory.getSynthesizedClone(name), + factory.createVoidZero() ), - setEmitFlags( - createBlock([ - createStatement( - createAssignment( - setEmitFlags(getMutableClone(name), EmitFlags.NoSourceMap), - setEmitFlags(initializer, EmitFlags.NoSourceMap | getEmitFlags(initializer)), + factory.setEmitFlags( + factory.createBlock([ + factory.createStatement( + factory.createAssignment( + factory.setEmitFlags(factory.getMutableClone(name), EmitFlags.NoSourceMap), + factory.setEmitFlags(initializer, EmitFlags.NoSourceMap | factory.getEmitFlags(initializer)), /*location*/ parameter ) ) @@ -1170,7 +1170,7 @@ namespace ts { /*location*/ parameter ); statement.startsOnNewLine = true; - setEmitFlags(statement, EmitFlags.NoTokenSourceMaps | EmitFlags.NoTrailingSourceMap | EmitFlags.CustomPrologue); + factory.setEmitFlags(statement, EmitFlags.NoTokenSourceMaps | EmitFlags.NoTrailingSourceMap | EmitFlags.CustomPrologue); statements.push(statement); } @@ -1202,24 +1202,24 @@ namespace ts { } // `declarationName` is the name of the local declaration for the parameter. - const declarationName = getMutableClone(parameter.name); - setEmitFlags(declarationName, EmitFlags.NoSourceMap); + const declarationName = factory.getMutableClone(parameter.name); + factory.setEmitFlags(declarationName, EmitFlags.NoSourceMap); // `expressionName` is the name of the parameter used in expressions. - const expressionName = getSynthesizedClone(parameter.name); + const expressionName = factory.getSynthesizedClone(parameter.name); const restIndex = node.parameters.length - 1; - const temp = createLoopVariable(); + const temp = factory.createLoopVariable(); // var param = []; statements.push( - setEmitFlags( - createVariableStatement( + factory.setEmitFlags( + factory.createVariableStatement( /*modifiers*/ undefined, - createVariableDeclarationList([ - createVariableDeclaration( + factory.createVariableDeclarationList([ + factory.createVariableDeclaration( declarationName, /*type*/ undefined, - createArrayLiteral([]) + factory.createArrayLiteral([]) ) ]), /*location*/ parameter @@ -1231,25 +1231,25 @@ namespace ts { // for (var _i = restIndex; _i < arguments.length; _i++) { // param[_i - restIndex] = arguments[_i]; // } - const forStatement = createFor( - createVariableDeclarationList([ - createVariableDeclaration(temp, /*type*/ undefined, createLiteral(restIndex)) + const forStatement = factory.createFor( + factory.createVariableDeclarationList([ + factory.createVariableDeclaration(temp, /*type*/ undefined, factory.createLiteral(restIndex)) ], /*location*/ parameter), - createLessThan( + factory.createLessThan( temp, - createPropertyAccess(createIdentifier("arguments"), "length"), + factory.createPropertyAccess(factory.createIdentifier("arguments"), "length"), /*location*/ parameter ), - createPostfixIncrement(temp, /*location*/ parameter), - createBlock([ - startOnNewLine( - createStatement( - createAssignment( - createElementAccess( + factory.createPostfixIncrement(temp, /*location*/ parameter), + factory.createBlock([ + factory.startOnNewLine( + factory.createStatement( + factory.createAssignment( + factory.createElementAccess( expressionName, - createSubtract(temp, createLiteral(restIndex)) + factory.createSubtract(temp, factory.createLiteral(restIndex)) ), - createElementAccess(createIdentifier("arguments"), temp) + factory.createElementAccess(factory.createIdentifier("arguments"), temp) ), /*location*/ parameter ) @@ -1257,8 +1257,8 @@ namespace ts { ]) ); - setEmitFlags(forStatement, EmitFlags.CustomPrologue); - startOnNewLine(forStatement); + factory.setEmitFlags(forStatement, EmitFlags.CustomPrologue); + factory.startOnNewLine(forStatement); statements.push(forStatement); } @@ -1270,16 +1270,16 @@ namespace ts { */ function addCaptureThisForNodeIfNeeded(statements: Statement[], node: Node): void { if (node.transformFlags & TransformFlags.ContainsCapturedLexicalThis && node.kind !== SyntaxKind.ArrowFunction) { - captureThisForNode(statements, node, createThis()); + captureThisForNode(statements, node, factory.createThis()); } } function captureThisForNode(statements: Statement[], node: Node, initializer: Expression | undefined, originalStatement?: Statement): void { enableSubstitutionsForCapturedThis(); - const captureThisStatement = createVariableStatement( + const captureThisStatement = factory.createVariableStatement( /*modifiers*/ undefined, - createVariableDeclarationList([ - createVariableDeclaration( + factory.createVariableDeclarationList([ + factory.createVariableDeclaration( "_this", /*type*/ undefined, initializer @@ -1288,8 +1288,8 @@ namespace ts { originalStatement ); - setEmitFlags(captureThisStatement, EmitFlags.NoComments | EmitFlags.CustomPrologue); - setSourceMapRange(captureThisStatement, node); + factory.setEmitFlags(captureThisStatement, EmitFlags.NoComments | EmitFlags.CustomPrologue); + factory.setSourceMapRange(captureThisStatement, node); statements.push(captureThisStatement); } @@ -1337,7 +1337,7 @@ namespace ts { * @param member The SemicolonClassElement node. */ function transformSemicolonClassElementToStatement(member: SemicolonClassElement) { - return createEmptyStatement(/*location*/ member); + return factory.createEmptyStatement(/*location*/ member); } /** @@ -1347,16 +1347,16 @@ namespace ts { * @param member The MethodDeclaration node. */ function transformClassMethodDeclarationToStatement(receiver: LeftHandSideExpression, member: MethodDeclaration) { - const commentRange = getCommentRange(member); - const sourceMapRange = getSourceMapRange(member); + const commentRange = factory.getCommentRange(member); + const sourceMapRange = factory.getSourceMapRange(member); const func = transformFunctionLikeToExpression(member, /*location*/ member, /*name*/ undefined); - setEmitFlags(func, EmitFlags.NoComments); - setSourceMapRange(func, sourceMapRange); + factory.setEmitFlags(func, EmitFlags.NoComments); + factory.setSourceMapRange(func, sourceMapRange); - const statement = createStatement( - createAssignment( - createMemberAccessForPropertyName( + const statement = factory.createStatement( + factory.createAssignment( + factory.createMemberAccessForPropertyName( receiver, visitNode(member.name, visitor, isPropertyName), /*location*/ member.name @@ -1366,13 +1366,13 @@ namespace ts { /*location*/ member ); - setOriginalNode(statement, member); - setCommentRange(statement, commentRange); + factory.setOriginalNode(statement, member); + factory.setCommentRange(statement, commentRange); // 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. - setEmitFlags(statement, EmitFlags.NoSourceMap); + factory.setEmitFlags(statement, EmitFlags.NoSourceMap); return statement; } @@ -1383,15 +1383,15 @@ namespace ts { * @param accessors The set of related get/set accessors. */ function transformAccessorsToStatement(receiver: LeftHandSideExpression, accessors: AllAccessorDeclarations): Statement { - const statement = createStatement( + const statement = factory.createStatement( transformAccessorsToExpression(receiver, accessors, /*startsOnNewLine*/ false), - /*location*/ getSourceMapRange(accessors.firstAccessor) + /*location*/ factory.getSourceMapRange(accessors.firstAccessor) ); // 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. - setEmitFlags(statement, EmitFlags.NoComments); + factory.setEmitFlags(statement, EmitFlags.NoComments); return statement; } @@ -1404,43 +1404,43 @@ namespace ts { function transformAccessorsToExpression(receiver: LeftHandSideExpression, { firstAccessor, getAccessor, setAccessor }: AllAccessorDeclarations, startsOnNewLine: boolean): Expression { // 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); - setEmitFlags(target, EmitFlags.NoComments | EmitFlags.NoTrailingSourceMap); - setSourceMapRange(target, firstAccessor.name); + const target = factory.getMutableClone(receiver); + factory.setEmitFlags(target, EmitFlags.NoComments | EmitFlags.NoTrailingSourceMap); + factory.setSourceMapRange(target, firstAccessor.name); - const propertyName = createExpressionForPropertyName(visitNode(firstAccessor.name, visitor, isPropertyName)); - setEmitFlags(propertyName, EmitFlags.NoComments | EmitFlags.NoLeadingSourceMap); - setSourceMapRange(propertyName, firstAccessor.name); + const propertyName = factory.createExpressionForPropertyName(visitNode(firstAccessor.name, visitor, isPropertyName)); + factory.setEmitFlags(propertyName, EmitFlags.NoComments | EmitFlags.NoLeadingSourceMap); + factory.setSourceMapRange(propertyName, firstAccessor.name); const properties: ObjectLiteralElementLike[] = []; if (getAccessor) { const getterFunction = transformFunctionLikeToExpression(getAccessor, /*location*/ undefined, /*name*/ undefined); - setSourceMapRange(getterFunction, getSourceMapRange(getAccessor)); - const getter = createPropertyAssignment("get", getterFunction); - setCommentRange(getter, getCommentRange(getAccessor)); + factory.setSourceMapRange(getterFunction, factory.getSourceMapRange(getAccessor)); + const getter = factory.createPropertyAssignment("get", getterFunction); + factory.setCommentRange(getter, factory.getCommentRange(getAccessor)); properties.push(getter); } if (setAccessor) { const setterFunction = transformFunctionLikeToExpression(setAccessor, /*location*/ undefined, /*name*/ undefined); - setSourceMapRange(setterFunction, getSourceMapRange(setAccessor)); - const setter = createPropertyAssignment("set", setterFunction); - setCommentRange(setter, getCommentRange(setAccessor)); + factory.setSourceMapRange(setterFunction, factory.getSourceMapRange(setAccessor)); + const setter = factory.createPropertyAssignment("set", setterFunction); + factory.setCommentRange(setter, factory.getCommentRange(setAccessor)); properties.push(setter); } properties.push( - createPropertyAssignment("enumerable", createLiteral(true)), - createPropertyAssignment("configurable", createLiteral(true)) + factory.createPropertyAssignment("enumerable", factory.createLiteral(true)), + factory.createPropertyAssignment("configurable", factory.createLiteral(true)) ); - const call = createCall( - createPropertyAccess(createIdentifier("Object"), "defineProperty"), + const call = factory.createCall( + factory.createPropertyAccess(factory.createIdentifier("Object"), "defineProperty"), /*typeArguments*/ undefined, [ target, propertyName, - createObjectLiteral(properties, /*location*/ undefined, /*multiLine*/ true) + factory.createObjectLiteral(properties, /*location*/ undefined, /*multiLine*/ true) ] ); if (startsOnNewLine) { @@ -1460,7 +1460,7 @@ namespace ts { } const func = transformFunctionLikeToExpression(node, /*location*/ node, /*name*/ undefined); - setEmitFlags(func, EmitFlags.CapturesThis); + factory.setEmitFlags(func, EmitFlags.CapturesThis); return func; } @@ -1479,8 +1479,8 @@ namespace ts { * @param node a FunctionDeclaration node. */ function visitFunctionDeclaration(node: FunctionDeclaration): FunctionDeclaration { - return setOriginalNode( - createFunctionDeclaration( + return factory.setOriginalNode( + factory.createFunctionDeclaration( /*decorators*/ undefined, node.modifiers, node.asteriskToken, @@ -1507,8 +1507,8 @@ namespace ts { enclosingNonArrowFunction = node; } - const expression = setOriginalNode( - createFunctionExpression( + const expression = factory.setOriginalNode( + factory.createFunctionExpression( node.asteriskToken, name, /*typeParameters*/ undefined, @@ -1543,7 +1543,7 @@ namespace ts { if (isBlock(body)) { // ensureUseStrict is false because no new prologue-directive should be added. // addPrologueDirectives will simply put already-existing directives at the beginning of the target statement-array - statementOffset = addPrologueDirectives(statements, body.statements, /*ensureUseStrict*/ false, visitor); + statementOffset = factory.addPrologueDirectives(statements, body.statements, /*ensureUseStrict*/ false, visitor); } addCaptureThisForNodeIfNeeded(statements, node); @@ -1584,8 +1584,8 @@ namespace ts { } const expression = visitNode(body, visitor, isExpression); - const returnStatement = createReturn(expression, /*location*/ body); - setEmitFlags(returnStatement, EmitFlags.NoTokenSourceMaps | EmitFlags.NoTrailingSourceMap | EmitFlags.NoTrailingComments); + const returnStatement = factory.createReturn(expression, /*location*/ body); + factory.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 @@ -1601,16 +1601,16 @@ namespace ts { multiLine = true; } - const block = createBlock(createNodeArray(statements, statementsLocation), node.body, multiLine); + const block = factory.createBlock(factory.createNodeArray(statements, statementsLocation), node.body, multiLine); if (!multiLine && singleLine) { - setEmitFlags(block, EmitFlags.SingleLine); + factory.setEmitFlags(block, EmitFlags.SingleLine); } if (closeBraceLocation) { - setTokenSourceMapRange(block, SyntaxKind.CloseBraceToken, closeBraceLocation); + factory.setTokenSourceMapRange(block, SyntaxKind.CloseBraceToken, closeBraceLocation); } - setOriginalNode(block, node.body); + factory.setOriginalNode(block, node.body); return block; } @@ -1623,12 +1623,12 @@ namespace ts { // If we are here it is most likely because our expression is a destructuring assignment. switch (node.expression.kind) { case SyntaxKind.ParenthesizedExpression: - return updateStatement(node, + return factory.updateStatement(node, visitParenthesizedExpression(node.expression, /*needsDestructuringValue*/ false) ); case SyntaxKind.BinaryExpression: - return updateStatement(node, + return factory.updateStatement(node, visitBinaryExpression(node.expression, /*needsDestructuringValue*/ false) ); } @@ -1648,13 +1648,13 @@ namespace ts { if (needsDestructuringValue) { switch (node.expression.kind) { case SyntaxKind.ParenthesizedExpression: - return createParen( + return factory.createParen( visitParenthesizedExpression(node.expression, /*needsDestructuringValue*/ true), /*location*/ node ); case SyntaxKind.BinaryExpression: - return createParen( + return factory.createParen( visitBinaryExpression(node.expression, /*needsDestructuringValue*/ true), /*location*/ node ); @@ -1689,13 +1689,13 @@ namespace ts { assignment = flattenVariableDestructuringToExpression(context, decl, hoistVariableDeclaration, /*nameSubstitution*/ undefined, visitor); } else { - assignment = createBinary(decl.name, SyntaxKind.EqualsToken, visitNode(decl.initializer, visitor, isExpression)); + assignment = factory.createBinary(decl.name, SyntaxKind.EqualsToken, visitNode(decl.initializer, visitor, isExpression)); } (assignments || (assignments = [])).push(assignment); } } if (assignments) { - return createStatement(reduceLeft(assignments, (acc, v) => createBinary(v, SyntaxKind.CommaToken, acc)), node); + return factory.createStatement(reduceLeft(assignments, (acc, v) => factory.createBinary(v, SyntaxKind.CommaToken, acc)), node); } else { // none of declarations has initializer - the entire variable statement can be deleted @@ -1720,9 +1720,9 @@ namespace ts { ? visitVariableDeclarationInLetDeclarationList : visitVariableDeclaration)); - const declarationList = createVariableDeclarationList(declarations, /*location*/ node); - setOriginalNode(declarationList, node); - setCommentRange(declarationList, node); + const declarationList = factory.createVariableDeclarationList(declarations, /*location*/ node); + factory.setOriginalNode(declarationList, node); + factory.setCommentRange(declarationList, node); if (node.transformFlags & TransformFlags.ContainsBindingPattern && (isBindingPattern(node.declarations[0].name) @@ -1731,7 +1731,7 @@ namespace ts { // the source map range for the declaration list. const firstDeclaration = firstOrUndefined(declarations); const lastDeclaration = lastOrUndefined(declarations); - setSourceMapRange(declarationList, createRange(firstDeclaration.pos, lastDeclaration.end)); + factory.setSourceMapRange(declarationList, createRange(firstDeclaration.pos, lastDeclaration.end)); } return declarationList; @@ -1821,8 +1821,8 @@ namespace ts { } if (!node.initializer && shouldEmitExplicitInitializerForLetDeclaration(node)) { - const clone = getMutableClone(node); - clone.initializer = createVoidZero(); + const clone = factory.getMutableClone(node); + clone.initializer = factory.createVoidZero(); return clone; } @@ -1856,7 +1856,7 @@ namespace ts { let result: VisitResult; if (isIterationStatement(node.statement, /*lookInLabeledStatements*/ false) && shouldConvertIterationStatementBody(node.statement)) { - result = visitNodes(createNodeArray([node.statement]), visitor, isStatement); + result = visitNodes(factory.createNodeArray([node.statement]), visitor, isStatement); } else { result = visitEachChild(node, visitor, context); @@ -1925,10 +1925,10 @@ namespace ts { // for (let v of arr) { } // // we don't want to emit a temporary variable for the RHS, just use it directly. - const counter = createLoopVariable(); + const counter = factory.createLoopVariable(); const rhsReference = expression.kind === SyntaxKind.Identifier - ? createUniqueName((expression).text) - : createTempVariable(/*recordTempVariable*/ undefined); + ? factory.createUniqueName((expression).text) + : factory.createTempVariable(/*recordTempVariable*/ undefined); // Initialize LHS // var v = _a[_i]; @@ -1944,21 +1944,21 @@ namespace ts { const declarations = flattenVariableDestructuring( context, firstOriginalDeclaration, - createElementAccess(rhsReference, counter), + factory.createElementAccess(rhsReference, counter), visitor ); - const declarationList = createVariableDeclarationList(declarations, /*location*/ initializer); - setOriginalNode(declarationList, initializer); + const declarationList = factory.createVariableDeclarationList(declarations, /*location*/ initializer); + factory.setOriginalNode(declarationList, initializer); // Adjust the source map range for the first declaration to align with the old // emitter. const firstDeclaration = declarations[0]; const lastDeclaration = lastOrUndefined(declarations); - setSourceMapRange(declarationList, createRange(firstDeclaration.pos, lastDeclaration.end)); + factory.setSourceMapRange(declarationList, createRange(firstDeclaration.pos, lastDeclaration.end)); statements.push( - createVariableStatement( + factory.createVariableStatement( /*modifiers*/ undefined, declarationList ) @@ -1968,13 +1968,13 @@ namespace ts { // The following call does not include the initializer, so we have // to emit it separately. statements.push( - createVariableStatement( + factory.createVariableStatement( /*modifiers*/ undefined, - createVariableDeclarationList([ - createVariableDeclaration( - firstOriginalDeclaration ? firstOriginalDeclaration.name : createTempVariable(/*recordTempVariable*/ undefined), + factory.createVariableDeclarationList([ + factory.createVariableDeclaration( + firstOriginalDeclaration ? firstOriginalDeclaration.name : factory.createTempVariable(/*recordTempVariable*/ undefined), /*type*/ undefined, - createElementAccess(rhsReference, counter) + factory.createElementAccess(rhsReference, counter) ) ], /*location*/ moveRangePos(initializer, -1)), /*location*/ moveRangeEnd(initializer, -1) @@ -1985,11 +1985,11 @@ namespace ts { else { // Initializer is an expression. Emit the expression in the body, so that it's // evaluated on every iteration. - const assignment = createAssignment(initializer, createElementAccess(rhsReference, counter)); + const assignment = factory.createAssignment(initializer, factory.createElementAccess(rhsReference, counter)); if (isDestructuringAssignment(assignment)) { // This is a destructuring pattern, so we flatten the destructuring instead. statements.push( - createStatement( + factory.createStatement( flattenDestructuringAssignment( context, assignment, @@ -2004,7 +2004,7 @@ namespace ts { // Currently there is not way to check that assignment is binary expression of destructing assignment // so we have to cast never type to binaryExpression (assignment).end = initializer.end; - statements.push(createStatement(assignment, /*location*/ moveRangeEnd(initializer, -1))); + statements.push(factory.createStatement(assignment, /*location*/ moveRangeEnd(initializer, -1))); } } @@ -2026,34 +2026,34 @@ namespace ts { } // The old emitter does not emit source maps for the expression - setEmitFlags(expression, EmitFlags.NoSourceMap | getEmitFlags(expression)); + factory.setEmitFlags(expression, EmitFlags.NoSourceMap | factory.getEmitFlags(expression)); // The old emitter does not emit source maps for the block. // We add the location to preserve comments. - const body = createBlock( - createNodeArray(statements, /*location*/ statementsLocation), + const body = factory.createBlock( + factory.createNodeArray(statements, /*location*/ statementsLocation), /*location*/ bodyLocation ); - setEmitFlags(body, EmitFlags.NoSourceMap | EmitFlags.NoTokenSourceMaps); + factory.setEmitFlags(body, EmitFlags.NoSourceMap | EmitFlags.NoTokenSourceMaps); - const forStatement = createFor( - createVariableDeclarationList([ - createVariableDeclaration(counter, /*type*/ undefined, createLiteral(0), /*location*/ moveRangePos(node.expression, -1)), - createVariableDeclaration(rhsReference, /*type*/ undefined, expression, /*location*/ node.expression) + const forStatement = factory.createFor( + factory.createVariableDeclarationList([ + factory.createVariableDeclaration(counter, /*type*/ undefined, factory.createLiteral(0), /*location*/ moveRangePos(node.expression, -1)), + factory.createVariableDeclaration(rhsReference, /*type*/ undefined, expression, /*location*/ node.expression) ], /*location*/ node.expression), - createLessThan( + factory.createLessThan( counter, - createPropertyAccess(rhsReference, "length"), + factory.createPropertyAccess(rhsReference, "length"), /*location*/ node.expression ), - createPostfixIncrement(counter, /*location*/ node.expression), + factory.createPostfixIncrement(counter, /*location*/ node.expression), body, /*location*/ node ); // Disable trailing source maps for the OpenParenToken to align source map emit with the old emitter. - setEmitFlags(forStatement, EmitFlags.NoTokenTrailingSourceMaps); + factory.setEmitFlags(forStatement, EmitFlags.NoTokenTrailingSourceMaps); return forStatement; } @@ -2083,14 +2083,14 @@ namespace ts { // For computed properties, we need to create a unique handle to the object // literal so we can modify it without risking internal assignments tainting the object. - const temp = createTempVariable(hoistVariableDeclaration); + const temp = factory.createTempVariable(hoistVariableDeclaration); // Write out the first non-computed properties, then emit the rest through indexing on the temp variable. const expressions: Expression[] = []; - const assignment = createAssignment( + const assignment = factory.createAssignment( temp, - setEmitFlags( - createObjectLiteral( + factory.setEmitFlags( + factory.createObjectLiteral( visitNodes(properties, visitor, isObjectLiteralElementLike, 0, numInitialProperties), /*location*/ undefined, node.multiLine @@ -2107,8 +2107,8 @@ namespace ts { // We need to clone the temporary identifier so that we can write it on a // new line - expressions.push(node.multiLine ? startOnNewLine(getMutableClone(temp)) : temp); - return inlineExpressions(expressions); + expressions.push(node.multiLine ? factory.startOnNewLine(factory.getMutableClone(temp)) : temp); + return factory.inlineExpressions(expressions); } function shouldConvertIterationStatementBody(node: IterationStatement): boolean { @@ -2157,7 +2157,7 @@ namespace ts { return result; } - const functionName = createUniqueName("_loop"); + const functionName = factory.createUniqueName("_loop"); let loopInitializer: VariableDeclarationList; switch (node.kind) { case SyntaxKind.ForStatement: @@ -2209,16 +2209,16 @@ namespace ts { if (loopOutParameters.length) { const statements = isBlock(loopBody) ? (loopBody).statements.slice() : [loopBody]; copyOutParameters(loopOutParameters, CopyDirection.ToOutParameter, statements); - loopBody = createBlock(statements, /*location*/ undefined, /*multiline*/ true); + loopBody = factory.createBlock(statements, /*location*/ undefined, /*multiline*/ true); } if (!isBlock(loopBody)) { - loopBody = createBlock([loopBody], /*location*/ undefined, /*multiline*/ true); + loopBody = factory.createBlock([loopBody], /*location*/ undefined, /*multiline*/ true); } const isAsyncBlockContainingAwait = enclosingNonArrowFunction - && (getEmitFlags(enclosingNonArrowFunction) & EmitFlags.AsyncFunctionBody) !== 0 + && (factory.getEmitFlags(enclosingNonArrowFunction) & EmitFlags.AsyncFunctionBody) !== 0 && (node.statement.transformFlags & TransformFlags.ContainsYield) !== 0; let loopBodyFlags: EmitFlags = 0; @@ -2231,16 +2231,16 @@ namespace ts { } const convertedLoopVariable = - createVariableStatement( + factory.createVariableStatement( /*modifiers*/ undefined, - createVariableDeclarationList( + factory.createVariableDeclarationList( [ - createVariableDeclaration( + factory.createVariableDeclaration( functionName, /*type*/ undefined, - setEmitFlags( - createFunctionExpression( - isAsyncBlockContainingAwait ? createToken(SyntaxKind.AsteriskToken) : undefined, + factory.setEmitFlags( + factory.createFunctionExpression( + isAsyncBlockContainingAwait ? factory.createToken(SyntaxKind.AsteriskToken) : undefined, /*name*/ undefined, /*typeParameters*/ undefined, loopParameters, @@ -2267,10 +2267,10 @@ namespace ts { else { // this is top level converted loop and we need to create an alias for 'arguments' object (extraVariableDeclarations || (extraVariableDeclarations = [])).push( - createVariableDeclaration( + factory.createVariableDeclaration( currentState.argumentsName, /*type*/ undefined, - createIdentifier("arguments") + factory.createIdentifier("arguments") ) ); } @@ -2288,10 +2288,10 @@ namespace ts { // if converted loops were all nested in arrow function then we'll always emit '_this' so convertedLoopState.thisName will not be set. // If it is set this means that all nested loops are not nested in arrow function and it is safe to capture 'this'. (extraVariableDeclarations || (extraVariableDeclarations = [])).push( - createVariableDeclaration( + factory.createVariableDeclaration( currentState.thisName, /*type*/ undefined, - createIdentifier("this") + factory.createIdentifier("this") ) ); } @@ -2309,7 +2309,7 @@ namespace ts { } // hoist collected variable declarations for (const identifier of currentState.hoistedLocalVariables) { - extraVariableDeclarations.push(createVariableDeclaration(identifier)); + extraVariableDeclarations.push(factory.createVariableDeclaration(identifier)); } } } @@ -2320,15 +2320,15 @@ namespace ts { extraVariableDeclarations = []; } for (const outParam of loopOutParameters) { - extraVariableDeclarations.push(createVariableDeclaration(outParam.outParamName)); + extraVariableDeclarations.push(factory.createVariableDeclaration(outParam.outParamName)); } } // create variable statement to hold all introduced variable declarations if (extraVariableDeclarations) { - statements.push(createVariableStatement( + statements.push(factory.createVariableStatement( /*modifiers*/ undefined, - createVariableDeclarationList(extraVariableDeclarations) + factory.createVariableDeclarationList(extraVariableDeclarations) )); } @@ -2338,13 +2338,13 @@ namespace ts { loop = convert(node, convertedLoopBodyStatements); } else { - loop = getMutableClone(node); + loop = factory.getMutableClone(node); // clean statement part loop.statement = undefined; // visit childnodes to transform initializer/condition/incrementor parts loop = visitEachChild(loop, visitor, context); // set loop statement - loop.statement = createBlock( + loop.statement = factory.createBlock( convertedLoopBodyStatements, /*location*/ undefined, /*multiline*/ true @@ -2358,7 +2358,7 @@ namespace ts { statements.push( currentParent.kind === SyntaxKind.LabeledStatement - ? createLabel((currentParent).label, loop) + ? factory.createLabel((currentParent).label, loop) : loop ); return statements; @@ -2367,12 +2367,12 @@ namespace ts { function copyOutParameter(outParam: LoopOutParameter, copyDirection: CopyDirection): BinaryExpression { const source = copyDirection === CopyDirection.ToOriginal ? outParam.outParamName : outParam.originalName; const target = copyDirection === CopyDirection.ToOriginal ? outParam.originalName : outParam.outParamName; - return createBinary(target, SyntaxKind.EqualsToken, source); + return factory.createBinary(target, SyntaxKind.EqualsToken, source); } function copyOutParameters(outParams: LoopOutParameter[], copyDirection: CopyDirection, statements: Statement[]): void { for (const outParam of outParams) { - statements.push(createStatement(copyOutParameter(outParam, copyDirection))); + statements.push(factory.createStatement(copyOutParameter(outParam, copyDirection))); } } @@ -2388,18 +2388,18 @@ namespace ts { !state.labeledNonLocalBreaks && !state.labeledNonLocalContinues; - const call = createCall(loopFunctionExpressionName, /*typeArguments*/ undefined, map(parameters, p => p.name)); - const callResult = isAsyncBlockContainingAwait ? createYield(createToken(SyntaxKind.AsteriskToken), call) : call; + const call = factory.createCall(loopFunctionExpressionName, /*typeArguments*/ undefined, map(parameters, p => p.name)); + const callResult = isAsyncBlockContainingAwait ? factory.createYield(factory.createToken(SyntaxKind.AsteriskToken), call) : call; if (isSimpleLoop) { - statements.push(createStatement(callResult)); + statements.push(factory.createStatement(callResult)); copyOutParameters(state.loopOutParameters, CopyDirection.ToOriginal, statements); } else { - const loopResultName = createUniqueName("state"); - const stateVariable = createVariableStatement( + const loopResultName = factory.createUniqueName("state"); + const stateVariable = factory.createVariableStatement( /*modifiers*/ undefined, - createVariableDeclarationList( - [createVariableDeclaration(loopResultName, /*type*/ undefined, callResult)] + factory.createVariableDeclarationList( + [factory.createVariableDeclaration(loopResultName, /*type*/ undefined, callResult)] ) ); statements.push(stateVariable); @@ -2409,17 +2409,17 @@ namespace ts { let returnStatement: ReturnStatement; if (outerConvertedLoopState) { outerConvertedLoopState.nonLocalJumps |= Jump.Return; - returnStatement = createReturn(loopResultName); + returnStatement = factory.createReturn(loopResultName); } else { - returnStatement = createReturn(createPropertyAccess(loopResultName, "value")); + returnStatement = factory.createReturn(factory.createPropertyAccess(loopResultName, "value")); } statements.push( - createIf( - createBinary( - createTypeOf(loopResultName), + factory.createIf( + factory.createBinary( + factory.createTypeOf(loopResultName), SyntaxKind.EqualsEqualsEqualsToken, - createLiteral("object") + factory.createLiteral("object") ), returnStatement ) @@ -2428,13 +2428,13 @@ namespace ts { if (state.nonLocalJumps & Jump.Break) { statements.push( - createIf( - createBinary( + factory.createIf( + factory.createBinary( loopResultName, SyntaxKind.EqualsEqualsEqualsToken, - createLiteral("break") + factory.createLiteral("break") ), - createBreak() + factory.createBreak() ) ); } @@ -2444,9 +2444,9 @@ namespace ts { processLabeledJumps(state.labeledNonLocalBreaks, /*isBreak*/ true, loopResultName, outerConvertedLoopState, caseClauses); processLabeledJumps(state.labeledNonLocalContinues, /*isBreak*/ false, loopResultName, outerConvertedLoopState, caseClauses); statements.push( - createSwitch( + factory.createSwitch( loopResultName, - createCaseBlock(caseClauses) + factory.createCaseBlock(caseClauses) ) ); } @@ -2480,14 +2480,14 @@ namespace ts { // then emit labeled break\continue // otherwise propagate pair 'label -> marker' to outer converted loop and emit 'return labelMarker' so outer loop can later decide what to do if (!outerLoop || (outerLoop.labels && outerLoop.labels[labelText])) { - const label = createIdentifier(labelText); - statements.push(isBreak ? createBreak(label) : createContinue(label)); + const label = factory.createIdentifier(labelText); + statements.push(isBreak ? factory.createBreak(label) : factory.createContinue(label)); } else { setLabeledJump(outerLoop, isBreak, labelText, labelMarker); - statements.push(createReturn(loopResultName)); + statements.push(factory.createReturn(loopResultName)); } - caseClauses.push(createCaseClause(createLiteral(labelMarker), statements)); + caseClauses.push(factory.createCaseClause(factory.createLiteral(labelMarker), statements)); } } @@ -2501,9 +2501,9 @@ namespace ts { } } else { - loopParameters.push(createParameter(name)); + loopParameters.push(factory.createParameter(name)); if (resolver.getNodeCheckFlags(decl) & NodeCheckFlags.NeedsLoopOutParameter) { - const outParamName = createUniqueName("out_" + name.text); + const outParamName = factory.createUniqueName("out_" + name.text); loopOutParameters.push({ originalName: name, outParamName }); } } @@ -2560,8 +2560,8 @@ namespace ts { * @param receiver The receiver for the assignment. */ function transformPropertyAssignmentToExpression(node: ObjectLiteralExpression, property: PropertyAssignment, receiver: Expression, startsOnNewLine: boolean) { - const expression = createAssignment( - createMemberAccessForPropertyName( + const expression = factory.createAssignment( + factory.createMemberAccessForPropertyName( receiver, visitNode(property.name, visitor, isPropertyName) ), @@ -2582,12 +2582,12 @@ namespace ts { * @param receiver The receiver for the assignment. */ function transformShorthandPropertyAssignmentToExpression(node: ObjectLiteralExpression, property: ShorthandPropertyAssignment, receiver: Expression, startsOnNewLine: boolean) { - const expression = createAssignment( - createMemberAccessForPropertyName( + const expression = factory.createAssignment( + factory.createMemberAccessForPropertyName( receiver, visitNode(property.name, visitor, isPropertyName) ), - getSynthesizedClone(property.name), + factory.getSynthesizedClone(property.name), /*location*/ property ); if (startsOnNewLine) { @@ -2604,8 +2604,8 @@ namespace ts { * @param receiver The receiver for the assignment. */ function transformObjectLiteralMethodDeclarationToExpression(node: ObjectLiteralExpression, method: MethodDeclaration, receiver: Expression, startsOnNewLine: boolean) { - const expression = createAssignment( - createMemberAccessForPropertyName( + const expression = factory.createAssignment( + factory.createMemberAccessForPropertyName( receiver, visitNode(method.name, visitor, isPropertyName) ), @@ -2630,8 +2630,8 @@ 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); - setEmitFlags(functionExpression, EmitFlags.NoLeadingComments | getEmitFlags(functionExpression)); - return createPropertyAssignment( + factory.setEmitFlags(functionExpression, EmitFlags.NoLeadingComments | factory.getEmitFlags(functionExpression)); + return factory.createPropertyAssignment( node.name, functionExpression, /*location*/ node @@ -2644,9 +2644,9 @@ namespace ts { * @param node A ShorthandPropertyAssignment node. */ function visitShorthandPropertyAssignment(node: ShorthandPropertyAssignment): ObjectLiteralElementLike { - return createPropertyAssignment( + return factory.createPropertyAssignment( node.name, - getSynthesizedClone(node.name), + factory.getSynthesizedClone(node.name), /*location*/ node ); } @@ -2688,9 +2688,9 @@ namespace ts { // We are here either because SuperKeyword was used somewhere in the expression, or // because we contain a SpreadElementExpression. - const { target, thisArg } = createCallBinding(node.expression, hoistVariableDeclaration); + const { target, thisArg } = factory.createCallBinding(node.expression, hoistVariableDeclaration); if (node.expression.kind === SyntaxKind.SuperKeyword) { - setEmitFlags(thisArg, EmitFlags.NoSubstitution); + factory.setEmitFlags(thisArg, EmitFlags.NoSubstitution); } let resultingCall: CallExpression | BinaryExpression; if (node.transformFlags & TransformFlags.ContainsSpreadElementExpression) { @@ -2708,7 +2708,7 @@ namespace ts { // _super.m.apply(this, a.concat([b])) // _super.prototype.m.apply(this, a.concat([b])) - resultingCall = createFunctionApply( + resultingCall = factory.createFunctionApply( visitNode(target, visitor, isExpression), visitNode(thisArg, visitor, isExpression), transformAndSpreadElements(node.arguments, /*needsUniqueCopy*/ false, /*multiLine*/ false, /*hasTrailingComma*/ false) @@ -2725,7 +2725,7 @@ namespace ts { // _super.m.call(this, a) // _super.prototype.m.call(this, a) - resultingCall = createFunctionCall( + resultingCall = factory.createFunctionCall( visitNode(target, visitor, isExpression), visitNode(thisArg, visitor, isExpression), visitNodes(node.arguments, visitor, isExpression), @@ -2734,15 +2734,15 @@ namespace ts { } if (node.expression.kind === SyntaxKind.SuperKeyword) { - const actualThis = createThis(); - setEmitFlags(actualThis, EmitFlags.NoSubstitution); + const actualThis = factory.createThis(); + factory.setEmitFlags(actualThis, EmitFlags.NoSubstitution); const initializer = - createLogicalOr( + factory.createLogicalOr( resultingCall, actualThis ); return assignToCapturedThis - ? createAssignment(createIdentifier("_this"), initializer) + ? factory.createAssignment(factory.createIdentifier("_this"), initializer) : initializer; } return resultingCall; @@ -2763,12 +2763,12 @@ namespace ts { // [output] // new ((_a = C).bind.apply(_a, [void 0].concat(a)))() - const { target, thisArg } = createCallBinding(createPropertyAccess(node.expression, "bind"), hoistVariableDeclaration); - return createNew( - createFunctionApply( + const { target, thisArg } = factory.createCallBinding(factory.createPropertyAccess(node.expression, "bind"), hoistVariableDeclaration); + return factory.createNew( + factory.createFunctionApply( visitNode(target, visitor, isExpression), thisArg, - transformAndSpreadElements(createNodeArray([createVoidZero(), ...node.arguments]), /*needsUniqueCopy*/ false, /*multiLine*/ false, /*hasTrailingComma*/ false) + transformAndSpreadElements(factory.createNodeArray([factory.createVoidZero(), ...node.arguments]), /*needsUniqueCopy*/ false, /*multiLine*/ false, /*hasTrailingComma*/ false) ), /*typeArguments*/ undefined, [] @@ -2801,12 +2801,12 @@ namespace ts { if (segments.length === 1) { const firstElement = elements[0]; return needsUniqueCopy && isSpreadElementExpression(firstElement) && firstElement.expression.kind !== SyntaxKind.ArrayLiteralExpression - ? createArraySlice(segments[0]) + ? factory.createArraySlice(segments[0]) : segments[0]; } // Rewrite using the pattern .concat(, , ...) - return createArrayConcat(segments.shift(), segments); + return factory.createArrayConcat(segments.shift(), segments); } function partitionSpreadElement(node: Expression) { @@ -2820,8 +2820,8 @@ namespace ts { } function visitSpanOfNonSpreadElements(chunk: Expression[], multiLine: boolean, hasTrailingComma: boolean): VisitResult { - return createArrayLiteral( - visitNodes(createNodeArray(chunk, /*location*/ undefined, hasTrailingComma), visitor, isExpression), + return factory.createArrayLiteral( + visitNodes(factory.createNodeArray(chunk, /*location*/ undefined, hasTrailingComma), visitor, isExpression), /*location*/ undefined, multiLine ); @@ -2842,7 +2842,7 @@ namespace ts { * @param node A template literal. */ function visitTemplateLiteral(node: LiteralExpression): LeftHandSideExpression { - return createLiteral(node.text, /*location*/ node); + return factory.createLiteral(node.text, /*location*/ node); } /** @@ -2855,7 +2855,7 @@ namespace ts { const tag = visitNode(node.tag, visitor, isExpression); // Allocate storage for the template site object - const temp = createTempVariable(hoistVariableDeclaration); + const temp = factory.createTempVariable(hoistVariableDeclaration); // Build up the template arguments and the raw and cooked strings for the template. const templateArguments: Expression[] = [temp]; @@ -2863,14 +2863,14 @@ namespace ts { const rawStrings: Expression[] = []; const template = node.template; if (isNoSubstitutionTemplateLiteral(template)) { - cookedStrings.push(createLiteral(template.text)); + cookedStrings.push(factory.createLiteral(template.text)); rawStrings.push(getRawLiteral(template)); } else { - cookedStrings.push(createLiteral(template.head.text)); + cookedStrings.push(factory.createLiteral(template.head.text)); rawStrings.push(getRawLiteral(template.head)); for (const templateSpan of template.templateSpans) { - cookedStrings.push(createLiteral(templateSpan.literal.text)); + cookedStrings.push(factory.createLiteral(templateSpan.literal.text)); rawStrings.push(getRawLiteral(templateSpan.literal)); templateArguments.push(visitNode(templateSpan.expression, visitor, isExpression)); } @@ -2879,11 +2879,11 @@ namespace ts { // NOTE: The parentheses here is entirely optional as we are now able to auto- // parenthesize when rebuilding the tree. This should be removed in a // future version. It is here for now to match our existing emit. - return createParen( - inlineExpressions([ - createAssignment(temp, createArrayLiteral(cookedStrings)), - createAssignment(createPropertyAccess(temp, "raw"), createArrayLiteral(rawStrings)), - createCall(tag, /*typeArguments*/ undefined, templateArguments) + return factory.createParen( + factory.inlineExpressions([ + factory.createAssignment(temp, factory.createArrayLiteral(cookedStrings)), + factory.createAssignment(factory.createPropertyAccess(temp, "raw"), factory.createArrayLiteral(rawStrings)), + factory.createCall(tag, /*typeArguments*/ undefined, templateArguments) ]) ); } @@ -2910,7 +2910,7 @@ namespace ts { // ES6 Spec 11.8.6.1 - Static Semantics of TV's and TRV's // and LineTerminatorSequences are normalized to for both TV and TRV. text = text.replace(/\r\n?/g, "\n"); - return createLiteral(text, /*location*/ node); + return factory.createLiteral(text, /*location*/ node); } /** @@ -2932,9 +2932,9 @@ namespace ts { // ("abc" + 1) << (2 + "") // rather than // "abc" + (1 << 2) + "" - const expression = reduceLeft(expressions, createAdd); + const expression = reduceLeft(expressions, factory.createAdd); if (nodeIsSynthesized(expression)) { - setTextRange(expression, node); + factory.setTextRange(expression, node); } return expression; @@ -2978,7 +2978,7 @@ namespace ts { return; } - expressions.push(createLiteral(node.head.text)); + expressions.push(factory.createLiteral(node.head.text)); } /** @@ -2996,7 +2996,7 @@ namespace ts { // with the head will force the result up to this point to be a string. // Emitting a '+ ""' has no semantic effect for middles and tails. if (span.literal.text.length !== 0) { - expressions.push(createLiteral(span.literal.text)); + expressions.push(factory.createLiteral(span.literal.text)); } } } @@ -3009,8 +3009,8 @@ namespace ts { && isClassElement(enclosingNonAsyncFunctionBody) && !hasModifier(enclosingNonAsyncFunctionBody, ModifierFlags.Static) && currentParent.kind !== SyntaxKind.CallExpression - ? createPropertyAccess(createIdentifier("_super"), "prototype") - : createIdentifier("_super"); + ? factory.createPropertyAccess(factory.createIdentifier("_super"), "prototype") + : factory.createIdentifier("_super"); } function visitSourceFileNode(node: SourceFile): SourceFile { @@ -3019,10 +3019,10 @@ namespace ts { startLexicalEnvironment(); addRange(statements, prologue); addCaptureThisForNodeIfNeeded(statements, node); - addRange(statements, visitNodes(createNodeArray(remaining), visitor, isStatement)); + addRange(statements, visitNodes(factory.createNodeArray(remaining), visitor, isStatement)); addRange(statements, endLexicalEnvironment()); - const clone = getMutableClone(node); - clone.statements = createNodeArray(statements, /*location*/ node.statements); + const clone = factory.getMutableClone(node); + clone.statements = factory.createNodeArray(statements, /*location*/ node.statements); return clone; } @@ -3103,7 +3103,7 @@ namespace ts { if (enabledSubstitutions & ES6SubstitutionFlags.BlockScopedBindings) { const original = getParseTreeNode(node, isIdentifier); if (original && isNameOfDeclarationWithCollidingName(original)) { - return getGeneratedNameForNode(original); + return factory.getGeneratedNameForNode(original); } } @@ -3156,7 +3156,7 @@ namespace ts { if (enabledSubstitutions & ES6SubstitutionFlags.BlockScopedBindings) { const declaration = resolver.getReferencedDeclarationWithCollidingName(node); if (declaration) { - return getGeneratedNameForNode(declaration.name); + return factory.getGeneratedNameForNode(declaration.name); } } @@ -3171,8 +3171,8 @@ namespace ts { function substituteThisKeyword(node: PrimaryExpression): PrimaryExpression { if (enabledSubstitutions & ES6SubstitutionFlags.CapturedThis && enclosingFunction - && getEmitFlags(enclosingFunction) & EmitFlags.CapturesThis) { - return createIdentifier("_this", /*location*/ node); + && factory.getEmitFlags(enclosingFunction) & EmitFlags.CapturesThis) { + return factory.createIdentifier("_this", /*location*/ node); } return node; @@ -3200,8 +3200,8 @@ namespace ts { */ function getDeclarationName(node: DeclarationStatement | ClassExpression, allowComments?: boolean, allowSourceMaps?: boolean, emitFlags?: EmitFlags) { if (node.name && !isGeneratedIdentifier(node.name)) { - const name = getMutableClone(node.name); - emitFlags |= getEmitFlags(node.name); + const name = factory.getMutableClone(node.name); + emitFlags |= factory.getEmitFlags(node.name); if (!allowSourceMaps) { emitFlags |= EmitFlags.NoSourceMap; } @@ -3209,17 +3209,17 @@ namespace ts { emitFlags |= EmitFlags.NoComments; } if (emitFlags) { - setEmitFlags(name, emitFlags); + factory.setEmitFlags(name, emitFlags); } return name; } - return getGeneratedNameForNode(node); + return factory.getGeneratedNameForNode(node); } function getClassMemberPrefix(node: ClassExpression | ClassDeclaration, member: ClassElement) { const expression = getLocalName(node); - return hasModifier(member, ModifierFlags.Static) ? expression : createPropertyAccess(expression, "prototype"); + return hasModifier(member, ModifierFlags.Static) ? expression : factory.createPropertyAccess(expression, "prototype"); } function hasSynthesizedDefaultSuperCall(constructor: ConstructorDeclaration, hasExtendsClause: boolean) { diff --git a/src/compiler/transformers/es7.ts b/src/compiler/transformers/es7.ts index 4d5e96134c40d..9a49267dead6d 100644 --- a/src/compiler/transformers/es7.ts +++ b/src/compiler/transformers/es7.ts @@ -48,17 +48,17 @@ namespace ts { let value: Expression; if (isElementAccessExpression(left)) { // Transforms `a[x] **= b` into `(_a = a)[_x = x] = Math.pow(_a[_x], b)` - const expressionTemp = createTempVariable(hoistVariableDeclaration); + const expressionTemp = factory.createTempVariable(hoistVariableDeclaration); - const argumentExpressionTemp = createTempVariable(hoistVariableDeclaration); + const argumentExpressionTemp = factory.createTempVariable(hoistVariableDeclaration); - target = createElementAccess( - createAssignment(expressionTemp, left.expression, /*location*/ left.expression), - createAssignment(argumentExpressionTemp, left.argumentExpression, /*location*/ left.argumentExpression), + target = factory.createElementAccess( + factory.createAssignment(expressionTemp, left.expression, /*location*/ left.expression), + factory.createAssignment(argumentExpressionTemp, left.argumentExpression, /*location*/ left.argumentExpression), /*location*/ left ); - value = createElementAccess( + value = factory.createElementAccess( expressionTemp, argumentExpressionTemp, /*location*/ left @@ -66,15 +66,15 @@ namespace ts { } else if (isPropertyAccessExpression(left)) { // Transforms `a.x **= b` into `(_a = a).x = Math.pow(_a.x, b)` - const expressionTemp = createTempVariable(hoistVariableDeclaration); + const expressionTemp = factory.createTempVariable(hoistVariableDeclaration); - target = createPropertyAccess( - createAssignment(expressionTemp, left.expression, /*location*/ left.expression), + target = factory.createPropertyAccess( + factory.createAssignment(expressionTemp, left.expression, /*location*/ left.expression), left.name, /*location*/ left ); - value = createPropertyAccess( + value = factory.createPropertyAccess( expressionTemp, left.name, /*location*/ left @@ -86,11 +86,11 @@ namespace ts { value = left; } - return createAssignment(target, createMathPow(value, right, /*location*/ node), /*location*/ node); + return factory.createAssignment(target, factory.createMathPow(value, right, /*location*/ node), /*location*/ node); } else if (node.operatorToken.kind === SyntaxKind.AsteriskAsteriskToken) { // Transforms `a ** b` into `Math.pow(a, b)` - return createMathPow(left, right, /*location*/ node); + return factory.createMathPow(left, right, /*location*/ node); } else { Debug.failBadSyntaxKind(node); diff --git a/src/compiler/transformers/generators.ts b/src/compiler/transformers/generators.ts index f3a47f037cadd..b247b23fac48c 100644 --- a/src/compiler/transformers/generators.ts +++ b/src/compiler/transformers/generators.ts @@ -445,9 +445,9 @@ namespace ts { */ function visitFunctionDeclaration(node: FunctionDeclaration): Statement { // Currently, we only support generators that were originally async functions. - if (node.asteriskToken && getEmitFlags(node) & EmitFlags.AsyncFunctionBody) { - node = setOriginalNode( - createFunctionDeclaration( + if (node.asteriskToken && factory.getEmitFlags(node) & EmitFlags.AsyncFunctionBody) { + node = factory.setOriginalNode( + factory.createFunctionDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, /*asteriskToken*/ undefined, @@ -493,9 +493,9 @@ namespace ts { */ function visitFunctionExpression(node: FunctionExpression): Expression { // Currently, we only support generators that were originally async functions. - if (node.asteriskToken && getEmitFlags(node) & EmitFlags.AsyncFunctionBody) { - node = setOriginalNode( - createFunctionExpression( + if (node.asteriskToken && factory.getEmitFlags(node) & EmitFlags.AsyncFunctionBody) { + node = factory.setOriginalNode( + factory.createFunctionExpression( /*asteriskToken*/ undefined, node.name, /*typeParameters*/ undefined, @@ -574,18 +574,18 @@ namespace ts { operations = undefined; operationArguments = undefined; operationLocations = undefined; - state = createTempVariable(/*recordTempVariable*/ undefined); + state = factory.createTempVariable(/*recordTempVariable*/ undefined); // Build the generator startLexicalEnvironment(); - const statementOffset = addPrologueDirectives(statements, body.statements, /*ensureUseStrict*/ false, visitor); + const statementOffset = factory.addPrologueDirectives(statements, body.statements, /*ensureUseStrict*/ false, visitor); transformAndEmitStatements(body.statements, statementOffset); const buildResult = build(); addRange(statements, endLexicalEnvironment()); - statements.push(createReturn(buildResult)); + statements.push(factory.createReturn(buildResult)); // Restore previous generator state inGeneratorFunctionBody = savedInGeneratorFunctionBody; @@ -602,7 +602,7 @@ namespace ts { operationLocations = savedOperationLocations; state = savedState; - return createBlock(statements, /*location*/ body, body.multiLine); + return factory.createBlock(statements, /*location*/ body, body.multiLine); } /** @@ -620,7 +620,7 @@ namespace ts { } else { // Do not hoist custom prologues. - if (getEmitFlags(node) & EmitFlags.CustomPrologue) { + if (factory.getEmitFlags(node) & EmitFlags.CustomPrologue) { return node; } @@ -633,8 +633,8 @@ namespace ts { return undefined; } - return createStatement( - inlineExpressions( + return factory.createStatement( + factory.inlineExpressions( map(variables, transformInitializedVariable) ) ); @@ -703,7 +703,7 @@ namespace ts { // .mark resumeLabel // _a.b = %sent%; - target = updatePropertyAccess( + target = factory.updatePropertyAccess( left, cacheExpression(visitNode((left).expression, visitor, isLeftHandSideExpression)), (left).name @@ -722,7 +722,7 @@ namespace ts { // .mark resumeLabel // _a[_b] = %sent%; - target = updateElementAccess(left, + target = factory.updateElementAccess(left, cacheExpression(visitNode((left).expression, visitor, isLeftHandSideExpression)), cacheExpression(visitNode((left).argumentExpression, visitor, isExpression)) ); @@ -735,10 +735,10 @@ namespace ts { const operator = node.operatorToken.kind; if (isCompoundAssignment(operator)) { - return createBinary( + return factory.createBinary( target, SyntaxKind.EqualsToken, - createBinary( + factory.createBinary( cacheExpression(target), getOperatorForCompoundAssignment(operator), visitNode(right, visitor, isExpression), @@ -748,7 +748,7 @@ namespace ts { ); } else { - return updateBinary(node, target, visitNode(right, visitor, isExpression)); + return factory.updateBinary(node, target, visitNode(right, visitor, isExpression)); } } @@ -773,7 +773,7 @@ namespace ts { // .yield resumeLabel // _a + %sent% + c() - const clone = getMutableClone(node); + const clone = factory.getMutableClone(node); clone.left = cacheExpression(visitNode(node.left, visitor, isExpression)); clone.right = visitNode(node.right, visitor, isExpression); return clone; @@ -853,7 +853,7 @@ namespace ts { let pendingExpressions: Expression[] = []; visit(node.left); visit(node.right); - return inlineExpressions(pendingExpressions); + return factory.inlineExpressions(pendingExpressions); function visit(node: Expression) { if (isBinaryExpression(node) && node.operatorToken.kind === SyntaxKind.CommaToken) { @@ -862,7 +862,7 @@ namespace ts { } else { if (containsYield(node) && pendingExpressions.length > 0) { - emitWorker(OpCode.Statement, [createStatement(inlineExpressions(pendingExpressions))]); + emitWorker(OpCode.Statement, [factory.createStatement(factory.inlineExpressions(pendingExpressions))]); pendingExpressions = []; } @@ -971,7 +971,7 @@ namespace ts { let hasAssignedTemp = false; if (numInitialElements > 0) { emitAssignment(temp, - createArrayLiteral( + factory.createArrayLiteral( visitNodes(elements, visitor, isExpression, 0, numInitialElements) ) ); @@ -980,19 +980,19 @@ namespace ts { const expressions = reduceLeft(elements, reduceElement, [], numInitialElements); return hasAssignedTemp - ? createArrayConcat(temp, [createArrayLiteral(expressions)]) - : createArrayLiteral(expressions); + ? factory.createArrayConcat(temp, [factory.createArrayLiteral(expressions)]) + : factory.createArrayLiteral(expressions); function reduceElement(expressions: Expression[], element: Expression) { if (containsYield(element) && expressions.length > 0) { emitAssignment( temp, hasAssignedTemp - ? createArrayConcat( + ? factory.createArrayConcat( temp, - [createArrayLiteral(expressions)] + [factory.createArrayLiteral(expressions)] ) - : createArrayLiteral(expressions) + : factory.createArrayLiteral(expressions) ); hasAssignedTemp = true; expressions = []; @@ -1028,7 +1028,7 @@ namespace ts { const temp = declareLocal(); emitAssignment(temp, - createObjectLiteral( + factory.createObjectLiteral( visitNodes(properties, visitor, isObjectLiteralElementLike, 0, numInitialProperties), /*location*/ undefined, multiLine @@ -1036,16 +1036,16 @@ namespace ts { ); const expressions = reduceLeft(properties, reduceProperty, [], numInitialProperties); - expressions.push(multiLine ? startOnNewLine(getMutableClone(temp)) : temp); - return inlineExpressions(expressions); + expressions.push(multiLine ? factory.startOnNewLine(factory.getMutableClone(temp)) : temp); + return factory.inlineExpressions(expressions); function reduceProperty(expressions: Expression[], property: ObjectLiteralElementLike) { if (containsYield(property) && expressions.length > 0) { - emitStatement(createStatement(inlineExpressions(expressions))); + emitStatement(factory.createStatement(factory.inlineExpressions(expressions))); expressions = []; } - const expression = createExpressionForObjectLiteralElementLike(node, property, temp); + const expression = factory.createExpressionForObjectLiteralElementLike(node, property, temp); const visited = visitNode(expression, visitor, isExpression); if (visited) { if (multiLine) { @@ -1074,7 +1074,7 @@ namespace ts { // .mark resumeLabel // a = _a[%sent%] - const clone = getMutableClone(node); + const clone = factory.getMutableClone(node); clone.expression = cacheExpression(visitNode(node.expression, visitor, isLeftHandSideExpression)); clone.argumentExpression = visitNode(node.argumentExpression, visitor, isExpression); return clone; @@ -1096,9 +1096,9 @@ namespace ts { // .mark resumeLabel // _b.apply(_a, _c.concat([%sent%, 2])); - const { target, thisArg } = createCallBinding(node.expression, hoistVariableDeclaration, languageVersion, /*cacheIdentifiers*/ true); - return setOriginalNode( - createFunctionApply( + const { target, thisArg } = factory.createCallBinding(node.expression, hoistVariableDeclaration, languageVersion, /*cacheIdentifiers*/ true); + return factory.setOriginalNode( + factory.createFunctionApply( cacheExpression(visitNode(target, visitor, isLeftHandSideExpression)), thisArg, visitElements(node.arguments, /*multiLine*/ false), @@ -1124,10 +1124,10 @@ namespace ts { // .mark resumeLabel // new (_b.apply(_a, _c.concat([%sent%, 2]))); - const { target, thisArg } = createCallBinding(createPropertyAccess(node.expression, "bind"), hoistVariableDeclaration); - return setOriginalNode( - createNew( - createFunctionApply( + const { target, thisArg } = factory.createCallBinding(factory.createPropertyAccess(node.expression, "bind"), hoistVariableDeclaration); + return factory.setOriginalNode( + factory.createNew( + factory.createFunctionApply( cacheExpression(visitNode(target, visitor, isExpression)), thisArg, visitElements(node.arguments, /*multiLine*/ false) @@ -1238,7 +1238,7 @@ namespace ts { } if (pendingExpressions.length) { - emitStatement(createStatement(inlineExpressions(pendingExpressions))); + emitStatement(factory.createStatement(factory.inlineExpressions(pendingExpressions))); variablesWritten += pendingExpressions.length; pendingExpressions = []; } @@ -1248,8 +1248,8 @@ namespace ts { } function transformInitializedVariable(node: VariableDeclaration) { - return createAssignment( - getSynthesizedClone(node.name), + return factory.createAssignment( + factory.getSynthesizedClone(node.name), visitNode(node.initializer, visitor, isExpression) ); } @@ -1405,7 +1405,7 @@ namespace ts { } else { emitStatement( - createStatement( + factory.createStatement( visitNode(initializer, visitor, isExpression), /*location*/ initializer ) @@ -1423,7 +1423,7 @@ namespace ts { markLabel(incrementLabel); if (node.incrementor) { emitStatement( - createStatement( + factory.createStatement( visitNode(node.incrementor, visitor, isExpression), /*location*/ node.incrementor ) @@ -1449,9 +1449,9 @@ namespace ts { } const variables = getInitializedVariables(initializer); - node = updateFor(node, + node = factory.updateFor(node, variables.length > 0 - ? inlineExpressions(map(variables, transformInitializedVariable)) + ? factory.inlineExpressions(map(variables, transformInitializedVariable)) : undefined, visitNode(node.condition, visitor, isExpression, /*optional*/ true), visitNode(node.incrementor, visitor, isExpression, /*optional*/ true), @@ -1495,18 +1495,18 @@ namespace ts { const keysArray = declareLocal(); // _a const key = declareLocal(); // _b - const keysIndex = createLoopVariable(); // _i + const keysIndex = factory.createLoopVariable(); // _i const initializer = node.initializer; hoistVariableDeclaration(keysIndex); - emitAssignment(keysArray, createArrayLiteral()); + emitAssignment(keysArray, factory.createArrayLiteral()); emitStatement( - createForIn( + factory.createForIn( key, visitNode(node.expression, visitor, isExpression), - createStatement( - createCall( - createPropertyAccess(keysArray, "push"), + factory.createStatement( + factory.createCall( + factory.createPropertyAccess(keysArray, "push"), /*typeArguments*/ undefined, [key] ) @@ -1514,14 +1514,14 @@ namespace ts { ) ); - emitAssignment(keysIndex, createLiteral(0)); + emitAssignment(keysIndex, factory.createLiteral(0)); const conditionLabel = defineLabel(); const incrementLabel = defineLabel(); const endLabel = beginLoopBlock(incrementLabel); markLabel(conditionLabel); - emitBreakWhenFalse(endLabel, createLessThan(keysIndex, createPropertyAccess(keysArray, "length"))); + emitBreakWhenFalse(endLabel, factory.createLessThan(keysIndex, factory.createPropertyAccess(keysArray, "length"))); let variable: Expression; if (isVariableDeclarationList(initializer)) { @@ -1529,18 +1529,18 @@ namespace ts { hoistVariableDeclaration(variable.name); } - variable = getSynthesizedClone(initializer.declarations[0].name); + variable = factory.getSynthesizedClone(initializer.declarations[0].name); } else { variable = visitNode(initializer, visitor, isExpression); Debug.assert(isLeftHandSideExpression(variable)); } - emitAssignment(variable, createElementAccess(keysArray, keysIndex)); + emitAssignment(variable, factory.createElementAccess(keysArray, keysIndex)); transformAndEmitEmbeddedStatement(node.statement); markLabel(incrementLabel); - emitStatement(createStatement(createPostfixIncrement(keysIndex))); + emitStatement(factory.createStatement(factory.createPostfixIncrement(keysIndex))); emitBreak(conditionLabel); endLoopBlock(); @@ -1574,7 +1574,7 @@ namespace ts { hoistVariableDeclaration(variable.name); } - node = updateForIn(node, + node = factory.updateForIn(node, initializer.declarations[0].name, visitNode(node.expression, visitor, isExpression), visitNode(node.statement, visitor, isStatement, /*optional*/ false, liftToBlock) @@ -1726,7 +1726,7 @@ namespace ts { } pendingClauses.push( - createCaseClause( + factory.createCaseClause( visitNode(caseClause.expression, visitor, isExpression), [ createInlineBreak(clauseLabels[i], /*location*/ caseClause.expression) @@ -1740,7 +1740,7 @@ namespace ts { } if (pendingClauses.length) { - emitStatement(createSwitch(expression, createCaseBlock(pendingClauses))); + emitStatement(factory.createSwitch(expression, factory.createCaseBlock(pendingClauses))); clausesWritten += pendingClauses.length; pendingClauses = []; } @@ -1914,9 +1914,9 @@ namespace ts { if (declaration) { const name = getProperty(renamedCatchVariableDeclarations, String(getOriginalNodeId(declaration))); if (name) { - const clone = getMutableClone(name); - setSourceMapRange(clone, node); - setCommentRange(clone, node); + const clone = factory.getMutableClone(name); + factory.setSourceMapRange(clone, node); + factory.setCommentRange(clone, node); return clone; } } @@ -1932,15 +1932,15 @@ namespace ts { return node; } - temp = createTempVariable(hoistVariableDeclaration); + temp = factory.createTempVariable(hoistVariableDeclaration); emitAssignment(temp, node, /*location*/ node); return temp; } function declareLocal(name?: string): Identifier { const temp = name - ? createUniqueName(name) - : createTempVariable(/*recordTempVariable*/ undefined); + ? factory.createUniqueName(name) + : factory.createTempVariable(/*recordTempVariable*/ undefined); hoistVariableDeclaration(temp); return temp; } @@ -2097,7 +2097,7 @@ namespace ts { exception.catchVariable = name; exception.catchLabel = catchLabel; - emitAssignment(name, createCall(createPropertyAccess(state, "sent"), /*typeArguments*/ undefined, [])); + emitAssignment(name, factory.createCall(factory.createPropertyAccess(state, "sent"), /*typeArguments*/ undefined, [])); emitNop(); } @@ -2368,7 +2368,7 @@ namespace ts { labelExpressions = []; } - const expression = createSynthesizedNode(SyntaxKind.NumericLiteral); + const expression = factory.createSynthesizedNode(SyntaxKind.NumericLiteral); if (labelExpressions[label] === undefined) { labelExpressions[label] = [expression]; } @@ -2386,7 +2386,7 @@ namespace ts { * Creates a numeric literal for the provided instruction. */ function createInstruction(instruction: Instruction): NumericLiteral { - const literal = createLiteral(instruction); + const literal = factory.createLiteral(instruction); literal.trailingComment = instructionNames[instruction]; return literal; } @@ -2399,8 +2399,8 @@ namespace ts { */ function createInlineBreak(label: Label, location?: TextRange): ReturnStatement { Debug.assert(label > 0, `Invalid label: ${label}`); - return createReturn( - createArrayLiteral([ + return factory.createReturn( + factory.createArrayLiteral([ createInstruction(Instruction.Break), createLabel(label) ]), @@ -2415,8 +2415,8 @@ namespace ts { * @param location An optional source map location for the statement. */ function createInlineReturn(expression?: Expression, location?: TextRange): ReturnStatement { - return createReturn( - createArrayLiteral(expression + return factory.createReturn( + factory.createArrayLiteral(expression ? [createInstruction(Instruction.Return), expression] : [createInstruction(Instruction.Return)] ), @@ -2428,7 +2428,7 @@ namespace ts { * Creates an expression that can be used to resume from a Yield operation. */ function createGeneratorResume(location?: TextRange): LeftHandSideExpression { - return createCall(createPropertyAccess(state, "sent"), /*typeArguments*/ undefined, [], location); + return factory.createCall(factory.createPropertyAccess(state, "sent"), /*typeArguments*/ undefined, [], location); } /** @@ -2584,19 +2584,19 @@ namespace ts { withBlockStack = undefined; const buildResult = buildStatements(); - return createCall( - createHelperName(currentSourceFile.externalHelpersModuleName, "__generator"), + return factory.createCall( + factory.createHelperName(currentSourceFile.externalHelpersModuleName, "__generator"), /*typeArguments*/ undefined, [ - createThis(), - setEmitFlags( - createFunctionExpression( + factory.createThis(), + factory.setEmitFlags( + factory.createFunctionExpression( /*asteriskToken*/ undefined, /*name*/ undefined, /*typeParameters*/ undefined, - [createParameter(state)], + [factory.createParameter(state)], /*type*/ undefined, - createBlock( + factory.createBlock( buildResult, /*location*/ undefined, /*multiLine*/ buildResult.length > 0 @@ -2624,8 +2624,8 @@ namespace ts { } if (clauses) { - const labelExpression = createPropertyAccess(state, "label"); - const switchStatement = createSwitch(labelExpression, createCaseBlock(clauses)); + const labelExpression = factory.createPropertyAccess(state, "label"); + const switchStatement = factory.createSwitch(labelExpression, factory.createCaseBlock(clauses)); switchStatement.startsOnNewLine = true; return [switchStatement]; } @@ -2715,7 +2715,7 @@ namespace ts { // surround the statements in generated `with` blocks to create the same environment. for (let i = withBlockStack.length - 1; i >= 0; i--) { const withBlock = withBlockStack[i]; - statements = [createWith(withBlock.expression, createBlock(statements))]; + statements = [factory.createWith(withBlock.expression, factory.createBlock(statements))]; } } @@ -2725,12 +2725,12 @@ namespace ts { // for each block in the protected region. const { startLabel, catchLabel, finallyLabel, endLabel } = currentExceptionBlock; statements.unshift( - createStatement( - createCall( - createPropertyAccess(createPropertyAccess(state, "trys"), "push"), + factory.createStatement( + factory.createCall( + factory.createPropertyAccess(factory.createPropertyAccess(state, "trys"), "push"), /*typeArguments*/ undefined, [ - createArrayLiteral([ + factory.createArrayLiteral([ createLabel(startLabel), createLabel(catchLabel), createLabel(finallyLabel), @@ -2748,10 +2748,10 @@ namespace ts { // The case clause for the last label falls through to this label, so we // add an assignment statement to reflect the change in labels. statements.push( - createStatement( - createAssignment( - createPropertyAccess(state, "label"), - createLiteral(labelNumber + 1) + factory.createStatement( + factory.createAssignment( + factory.createPropertyAccess(state, "label"), + factory.createLiteral(labelNumber + 1) ) ) ); @@ -2759,8 +2759,8 @@ namespace ts { } clauses.push( - createCaseClause( - createLiteral(labelNumber), + factory.createCaseClause( + factory.createLiteral(labelNumber), statements || [] ) ); @@ -2929,7 +2929,7 @@ namespace ts { * @param operationLocation The source map location for the operation. */ function writeAssign(left: Expression, right: Expression, operationLocation: TextRange): void { - writeStatement(createStatement(createAssignment(left, right), operationLocation)); + writeStatement(factory.createStatement(factory.createAssignment(left, right), operationLocation)); } /** @@ -2941,7 +2941,7 @@ namespace ts { function writeThrow(expression: Expression, operationLocation: TextRange): void { lastOperationWasAbrupt = true; lastOperationWasCompletion = true; - writeStatement(createThrow(expression, operationLocation)); + writeStatement(factory.createThrow(expression, operationLocation)); } /** @@ -2954,8 +2954,8 @@ namespace ts { lastOperationWasAbrupt = true; lastOperationWasCompletion = true; writeStatement( - createReturn( - createArrayLiteral(expression + factory.createReturn( + factory.createArrayLiteral(expression ? [createInstruction(Instruction.Return), expression] : [createInstruction(Instruction.Return)] ), @@ -2973,8 +2973,8 @@ namespace ts { function writeBreak(label: Label, operationLocation: TextRange): void { lastOperationWasAbrupt = true; writeStatement( - createReturn( - createArrayLiteral([ + factory.createReturn( + factory.createArrayLiteral([ createInstruction(Instruction.Break), createLabel(label) ]), @@ -2992,10 +2992,10 @@ namespace ts { */ function writeBreakWhenTrue(label: Label, condition: Expression, operationLocation: TextRange): void { writeStatement( - createIf( + factory.createIf( condition, - createReturn( - createArrayLiteral([ + factory.createReturn( + factory.createArrayLiteral([ createInstruction(Instruction.Break), createLabel(label) ]), @@ -3014,10 +3014,10 @@ namespace ts { */ function writeBreakWhenFalse(label: Label, condition: Expression, operationLocation: TextRange): void { writeStatement( - createIf( - createLogicalNot(condition), - createReturn( - createArrayLiteral([ + factory.createIf( + factory.createLogicalNot(condition), + factory.createReturn( + factory.createArrayLiteral([ createInstruction(Instruction.Break), createLabel(label) ]), @@ -3036,8 +3036,8 @@ namespace ts { function writeYield(expression: Expression, operationLocation: TextRange): void { lastOperationWasAbrupt = true; writeStatement( - createReturn( - createArrayLiteral( + factory.createReturn( + factory.createArrayLiteral( expression ? [createInstruction(Instruction.Yield), expression] : [createInstruction(Instruction.Yield)] @@ -3056,8 +3056,8 @@ namespace ts { function writeYieldStar(expression: Expression, operationLocation: TextRange): void { lastOperationWasAbrupt = true; writeStatement( - createReturn( - createArrayLiteral([ + factory.createReturn( + factory.createArrayLiteral([ createInstruction(Instruction.YieldStar), expression ]), @@ -3072,8 +3072,8 @@ namespace ts { function writeEndfinally(): void { lastOperationWasAbrupt = true; writeStatement( - createReturn( - createArrayLiteral([ + factory.createReturn( + factory.createArrayLiteral([ createInstruction(Instruction.Endfinally) ]) ) diff --git a/src/compiler/transformers/jsx.ts b/src/compiler/transformers/jsx.ts index 95a4016bb0aeb..8ef1598f8b016 100644 --- a/src/compiler/transformers/jsx.ts +++ b/src/compiler/transformers/jsx.ts @@ -89,7 +89,7 @@ namespace ts { const attrs = node.attributes; if (attrs.length === 0) { // When there are no attributes, React wants "null" - objectProperties = createNull(); + objectProperties = factory.createNull(); } else { // Map spans of JsxAttribute nodes into object literals and spans @@ -97,23 +97,23 @@ namespace ts { const segments = flatten( spanMap(attrs, isJsxSpreadAttribute, (attrs, isSpread) => isSpread ? map(attrs, transformJsxSpreadAttributeToExpression) - : createObjectLiteral(map(attrs, transformJsxAttributeToObjectLiteralElement)) + : factory.createObjectLiteral(map(attrs, transformJsxAttributeToObjectLiteralElement)) ) ); if (isJsxSpreadAttribute(attrs[0])) { // We must always emit at least one object literal before a spread // argument. - segments.unshift(createObjectLiteral()); + segments.unshift(factory.createObjectLiteral()); } // Either emit one big object literal (no spread attribs), or // a call to the __assign helper. objectProperties = singleOrUndefined(segments) - || createAssignHelper(currentSourceFile.externalHelpersModuleName, segments); + || factory.createAssignHelper(currentSourceFile.externalHelpersModuleName, segments); } - const element = createReactCreateElement( + const element = factory.createReactCreateElement( compilerOptions.reactNamespace, tagName, objectProperties, @@ -123,7 +123,7 @@ namespace ts { ); if (isChild) { - startOnNewLine(element); + factory.startOnNewLine(element); } return element; @@ -136,16 +136,16 @@ namespace ts { function transformJsxAttributeToObjectLiteralElement(node: JsxAttribute) { const name = getAttributeName(node); const expression = transformJsxAttributeInitializer(node.initializer); - return createPropertyAssignment(name, expression); + return factory.createPropertyAssignment(name, expression); } function transformJsxAttributeInitializer(node: StringLiteral | JsxExpression) { if (node === undefined) { - return createLiteral(true); + return factory.createLiteral(true); } else if (node.kind === SyntaxKind.StringLiteral) { const decoded = tryDecodeEntities((node).text); - return decoded ? createLiteral(decoded, /*location*/ node) : node; + return decoded ? factory.createLiteral(decoded, /*location*/ node) : node; } else if (node.kind === SyntaxKind.JsxExpression) { return visitJsxExpression(node); @@ -176,7 +176,7 @@ namespace ts { // We do not escape the string here as that is handled by the printer // when it emits the literal. We do, however, need to decode JSX entities. - parts.push(createLiteral(decodeEntities(part))); + parts.push(factory.createLiteral(decodeEntities(part))); } firstNonWhitespace = -1; @@ -197,7 +197,7 @@ namespace ts { // We do not escape the string here as that is handled by the printer // when it emits the literal. We do, however, need to decode JSX entities. - parts.push(createLiteral(decodeEntities(part))); + parts.push(factory.createLiteral(decodeEntities(part))); } if (parts) { @@ -211,7 +211,7 @@ namespace ts { * Aggregates two expressions by interpolating them with a whitespace literal. */ function aggregateJsxTextParts(left: Expression, right: Expression) { - return createAdd(createAdd(left, createLiteral(" ")), right); + return factory.createAdd(factory.createAdd(left, factory.createLiteral(" ")), right); } /** @@ -247,10 +247,10 @@ namespace ts { else { const name = (node).tagName; if (isIdentifier(name) && isIntrinsicJsxName(name.text)) { - return createLiteral(name.text); + return factory.createLiteral(name.text); } else { - return createExpressionFromEntityName(name); + return factory.createExpressionFromEntityName(name); } } } @@ -266,7 +266,7 @@ namespace ts { return name; } else { - return createLiteral(name.text); + return factory.createLiteral(name.text); } } diff --git a/src/compiler/transformers/module/es6.ts b/src/compiler/transformers/module/es6.ts index 09a2890727c58..c093bdf473867 100644 --- a/src/compiler/transformers/module/es6.ts +++ b/src/compiler/transformers/module/es6.ts @@ -69,7 +69,7 @@ namespace ts { return node; } return newExportClause - ? createExportDeclaration( + ? factory.createExportDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, newExportClause, @@ -82,7 +82,7 @@ namespace ts { if (node.elements === newExports) { return node; } - return newExports.length ? createNamedExports(newExports) : undefined; + return newExports.length ? factory.createNamedExports(newExports) : undefined; } function visitExportSpecifier(node: ExportSpecifier): ExportSpecifier { @@ -100,7 +100,7 @@ namespace ts { return undefined; } else if (newImportClause !== node.importClause) { - return createImportDeclaration( + return factory.createImportDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, newImportClause, @@ -117,7 +117,7 @@ namespace ts { } const newNamedBindings = visitNode(node.namedBindings, visitor, isNamedImportBindings, /*optional*/ true); return newDefaultImport !== node.name || newNamedBindings !== node.namedBindings - ? createImportClause(newDefaultImport, newNamedBindings) + ? factory.createImportClause(newDefaultImport, newNamedBindings) : node; } @@ -133,7 +133,7 @@ namespace ts { if (newNamedImportElements === (node).elements) { return node; } - return createNamedImports(newNamedImportElements); + return factory.createNamedImports(newNamedImportElements); } } diff --git a/src/compiler/transformers/module/module.ts b/src/compiler/transformers/module/module.ts index c4e9b4c31c802..fcf7da6de5b48 100644 --- a/src/compiler/transformers/module/module.ts +++ b/src/compiler/transformers/module/module.ts @@ -86,14 +86,14 @@ namespace ts { startLexicalEnvironment(); const statements: Statement[] = []; - const statementOffset = addPrologueDirectives(statements, node.statements, /*ensureUseStrict*/ !compilerOptions.noImplicitUseStrict, visitor); + const statementOffset = factory.addPrologueDirectives(statements, node.statements, /*ensureUseStrict*/ !compilerOptions.noImplicitUseStrict, visitor); addRange(statements, visitNodes(node.statements, visitor, isStatement, statementOffset)); addRange(statements, endLexicalEnvironment()); addExportEqualsIfNeeded(statements, /*emitAsReturn*/ false); const updated = updateSourceFile(node, statements); if (hasExportStarsToExportValues) { - setEmitFlags(updated, EmitFlags.EmitExportStar | getEmitFlags(node)); + factory.setEmitFlags(updated, EmitFlags.EmitExportStar | factory.getEmitFlags(node)); } return updated; @@ -105,8 +105,8 @@ namespace ts { * @param node The SourceFile node. */ function transformAMDModule(node: SourceFile) { - const define = createIdentifier("define"); - const moduleName = tryGetModuleNameFromFile(node, host, compilerOptions); + const define = factory.createIdentifier("define"); + const moduleName = factory.tryGetModuleNameFromFile(node, host, compilerOptions); return transformAsynchronousModule(node, define, moduleName, /*includeNonAmdDependencies*/ true); } @@ -116,8 +116,8 @@ namespace ts { * @param node The SourceFile node. */ function transformUMDModule(node: SourceFile) { - const define = createIdentifier("define"); - setEmitFlags(define, EmitFlags.UMDDefine); + const define = factory.createIdentifier("define"); + factory.setEmitFlags(define, EmitFlags.UMDDefine); return transformAsynchronousModule(node, define, /*moduleName*/ undefined, /*includeNonAmdDependencies*/ false); } @@ -157,8 +157,8 @@ namespace ts { // // define(moduleName?, ["module1", "module2"], function ... return updateSourceFile(node, [ - createStatement( - createCall( + factory.createStatement( + factory.createCall( define, /*typeArguments*/ undefined, [ @@ -168,9 +168,9 @@ namespace ts { // Add the dependency array argument: // // ["require", "exports", module1", "module2", ...] - createArrayLiteral([ - createLiteral("require"), - createLiteral("exports"), + factory.createArrayLiteral([ + factory.createLiteral("require"), + factory.createLiteral("exports"), ...aliasedModuleNames, ...unaliasedModuleNames ]), @@ -178,13 +178,13 @@ namespace ts { // Add the module body function argument: // // function (require, exports, module1, module2) ... - createFunctionExpression( + factory.createFunctionExpression( /*asteriskToken*/ undefined, /*name*/ undefined, /*typeParameters*/ undefined, [ - createParameter("require"), - createParameter("exports"), + factory.createParameter("require"), + factory.createParameter("exports"), ...importAliasNames ], /*type*/ undefined, @@ -205,7 +205,7 @@ namespace ts { startLexicalEnvironment(); const statements: Statement[] = []; - const statementOffset = addPrologueDirectives(statements, node.statements, /*ensureUseStrict*/ !compilerOptions.noImplicitUseStrict, visitor); + const statementOffset = factory.addPrologueDirectives(statements, node.statements, /*ensureUseStrict*/ !compilerOptions.noImplicitUseStrict, visitor); // Visit each statement of the module body. addRange(statements, visitNodes(node.statements, visitor, isStatement, statementOffset)); @@ -217,11 +217,11 @@ namespace ts { // Append the 'export =' statement if provided. addExportEqualsIfNeeded(statements, /*emitAsReturn*/ true); - const body = createBlock(statements, /*location*/ undefined, /*multiLine*/ true); + const body = factory.createBlock(statements, /*location*/ undefined, /*multiLine*/ true); if (hasExportStarsToExportValues) { // If we have any `export * from ...` declarations // we need to inform the emitter to add the __export helper. - setEmitFlags(body, EmitFlags.EmitExportStar); + factory.setEmitFlags(body, EmitFlags.EmitExportStar); } return body; @@ -230,19 +230,19 @@ namespace ts { function addExportEqualsIfNeeded(statements: Statement[], emitAsReturn: boolean) { if (exportEquals && resolver.isValueAliasDeclaration(exportEquals)) { if (emitAsReturn) { - const statement = createReturn( + const statement = factory.createReturn( exportEquals.expression, /*location*/ exportEquals ); - setEmitFlags(statement, EmitFlags.NoTokenSourceMaps | EmitFlags.NoComments); + factory.setEmitFlags(statement, EmitFlags.NoTokenSourceMaps | EmitFlags.NoComments); statements.push(statement); } else { - const statement = createStatement( - createAssignment( - createPropertyAccess( - createIdentifier("module"), + const statement = factory.createStatement( + factory.createAssignment( + factory.createPropertyAccess( + factory.createIdentifier("module"), "exports" ), exportEquals.expression @@ -250,7 +250,7 @@ namespace ts { /*location*/ exportEquals ); - setEmitFlags(statement, EmitFlags.NoComments); + factory.setEmitFlags(statement, EmitFlags.NoComments); statements.push(statement); } } @@ -310,7 +310,7 @@ namespace ts { if (!node.importClause) { // import "mod"; statements.push( - createStatement( + factory.createStatement( createRequireCall(node), /*location*/ node ) @@ -321,8 +321,8 @@ namespace ts { if (namespaceDeclaration && !isDefaultImport(node)) { // import * as n from "mod"; variables.push( - createVariableDeclaration( - getSynthesizedClone(namespaceDeclaration.name), + factory.createVariableDeclaration( + factory.getSynthesizedClone(namespaceDeclaration.name), /*type*/ undefined, createRequireCall(node) ) @@ -334,8 +334,8 @@ namespace ts { // import d, { x, y } from "mod"; // import d, * as n from "mod"; variables.push( - createVariableDeclaration( - getGeneratedNameForNode(node), + factory.createVariableDeclaration( + factory.getGeneratedNameForNode(node), /*type*/ undefined, createRequireCall(node) ) @@ -343,19 +343,19 @@ namespace ts { if (namespaceDeclaration && isDefaultImport(node)) { variables.push( - createVariableDeclaration( - getSynthesizedClone(namespaceDeclaration.name), + factory.createVariableDeclaration( + factory.getSynthesizedClone(namespaceDeclaration.name), /*type*/ undefined, - getGeneratedNameForNode(node) + factory.getGeneratedNameForNode(node) ) ); } } statements.push( - createVariableStatement( + factory.createVariableStatement( /*modifiers*/ undefined, - createConstDeclarationList(variables), + factory.createConstDeclarationList(variables), /*location*/ node ) ); @@ -364,13 +364,13 @@ namespace ts { else if (namespaceDeclaration && isDefaultImport(node)) { // import d, * as n from "mod"; statements.push( - createVariableStatement( + factory.createVariableStatement( /*modifiers*/ undefined, - createVariableDeclarationList([ - createVariableDeclaration( - getSynthesizedClone(namespaceDeclaration.name), + factory.createVariableDeclarationList([ + factory.createVariableDeclaration( + factory.getSynthesizedClone(namespaceDeclaration.name), /*type*/ undefined, - getGeneratedNameForNode(node), + factory.getGeneratedNameForNode(node), /*location*/ node ) ]) @@ -389,12 +389,12 @@ namespace ts { // Set emitFlags on the name of the importEqualsDeclaration // This is so the printer will not substitute the identifier - setEmitFlags(node.name, EmitFlags.NoSubstitution); + factory.setEmitFlags(node.name, EmitFlags.NoSubstitution); const statements: Statement[] = []; if (moduleKind !== ModuleKind.AMD) { if (hasModifier(node, ModifierFlags.Export)) { statements.push( - createStatement( + factory.createStatement( createExportAssignment( node.name, createRequireCall(node) @@ -405,11 +405,11 @@ namespace ts { } else { statements.push( - createVariableStatement( + factory.createVariableStatement( /*modifiers*/ undefined, - createVariableDeclarationList([ - createVariableDeclaration( - getSynthesizedClone(node.name), + factory.createVariableDeclarationList([ + factory.createVariableDeclaration( + factory.getSynthesizedClone(node.name), /*type*/ undefined, createRequireCall(node) ) @@ -424,7 +424,7 @@ namespace ts { else { if (hasModifier(node, ModifierFlags.Export)) { statements.push( - createStatement( + factory.createStatement( createExportAssignment(node.name, node.name), /*location*/ node ) @@ -441,16 +441,16 @@ namespace ts { return undefined; } - const generatedName = getGeneratedNameForNode(node); + const generatedName = factory.getGeneratedNameForNode(node); if (node.exportClause) { const statements: Statement[] = []; // export { x, y } from "mod"; if (moduleKind !== ModuleKind.AMD) { statements.push( - createVariableStatement( + factory.createVariableStatement( /*modifiers*/ undefined, - createVariableDeclarationList([ - createVariableDeclaration( + factory.createVariableDeclarationList([ + factory.createVariableDeclaration( generatedName, /*type*/ undefined, createRequireCall(node) @@ -462,12 +462,12 @@ namespace ts { } for (const specifier of node.exportClause.elements) { if (resolver.isValueAliasDeclaration(specifier)) { - const exportedValue = createPropertyAccess( + const exportedValue = factory.createPropertyAccess( generatedName, specifier.propertyName || specifier.name ); statements.push( - createStatement( + factory.createStatement( createExportAssignment(specifier.name, exportedValue), /*location*/ specifier ) @@ -479,9 +479,9 @@ namespace ts { } else if (resolver.moduleExportsSomeValue(node.moduleSpecifier)) { // export * from "mod"; - return createStatement( - createCall( - createIdentifier("__export"), + return factory.createStatement( + factory.createCall( + factory.createIdentifier("__export"), /*typeArguments*/ undefined, [ moduleKind !== ModuleKind.AMD @@ -510,9 +510,9 @@ namespace ts { tryAddExportDefaultCompat(statements); statements.push( - createStatement( + factory.createStatement( createExportAssignment( - createIdentifier("default"), + factory.createIdentifier("default"), expression ), location @@ -527,25 +527,25 @@ namespace ts { if (!original.symbol.exports["___esModule"]) { if (languageVersion === ScriptTarget.ES3) { statements.push( - createStatement( + factory.createStatement( createExportAssignment( - createIdentifier("__esModule"), - createLiteral(true) + factory.createIdentifier("__esModule"), + factory.createLiteral(true) ) ) ); } else { statements.push( - createStatement( - createCall( - createPropertyAccess(createIdentifier("Object"), "defineProperty"), + factory.createStatement( + factory.createCall( + factory.createPropertyAccess(factory.createIdentifier("Object"), "defineProperty"), /*typeArguments*/ undefined, [ - createIdentifier("exports"), - createLiteral("__esModule"), - createObjectLiteral([ - createPropertyAssignment("value", createLiteral(true)) + factory.createIdentifier("exports"), + factory.createLiteral("__esModule"), + factory.createObjectLiteral([ + factory.createPropertyAssignment("value", factory.createLiteral(true)) ]) ] ) @@ -582,8 +582,8 @@ namespace ts { if (!exportEquals && exportSpecifiers && hasProperty(exportSpecifiers, name.text)) { for (const specifier of exportSpecifiers[name.text]) { statements.push( - startOnNewLine( - createStatement( + factory.startOnNewLine( + factory.createStatement( createExportAssignment(specifier.name, name), /*location*/ specifier.name ) @@ -599,7 +599,7 @@ namespace ts { } else { statements.push( - createExportStatement(node.name, setEmitFlags(getSynthesizedClone(node.name), EmitFlags.LocalName), /*location*/ node) + createExportStatement(node.name, factory.setEmitFlags(factory.getSynthesizedClone(node.name), EmitFlags.LocalName), /*location*/ node) ); } } @@ -616,8 +616,8 @@ namespace ts { return node; } - return setOriginalNode( - createVariableStatement( + return factory.setOriginalNode( + factory.createVariableStatement( /*modifiers*/ undefined, node.declarationList ), @@ -632,8 +632,8 @@ namespace ts { if (hasModifier(node, ModifierFlags.Export)) { const variables = getInitializedVariables(node.declarationList); if (variables.length > 0) { - const inlineAssignments = createStatement( - inlineExpressions( + const inlineAssignments = factory.createStatement( + factory.inlineExpressions( map(variables, transformInitializedVariable) ), node @@ -690,7 +690,7 @@ namespace ts { ); } else { - return createAssignment( + return factory.createAssignment( getModuleMemberName(name), visitNode(node.initializer, visitor, isExpression) ); @@ -699,11 +699,11 @@ namespace ts { function visitFunctionDeclaration(node: FunctionDeclaration): VisitResult { const statements: Statement[] = []; - const name = node.name || getGeneratedNameForNode(node); + const name = node.name || factory.getGeneratedNameForNode(node); if (hasModifier(node, ModifierFlags.Export)) { statements.push( - setOriginalNode( - createFunctionDeclaration( + factory.setOriginalNode( + factory.createFunctionDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, node.asteriskToken, @@ -733,11 +733,11 @@ namespace ts { function visitClassDeclaration(node: ClassDeclaration): VisitResult { const statements: Statement[] = []; - const name = node.name || getGeneratedNameForNode(node); + const name = node.name || factory.getGeneratedNameForNode(node); if (hasModifier(node, ModifierFlags.Export)) { statements.push( - setOriginalNode( - createClassDeclaration( + factory.setOriginalNode( + factory.createClassDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, name, @@ -805,21 +805,21 @@ namespace ts { * Adds a trailing VariableStatement for an enum or module declaration. */ function addVarForExportedEnumOrNamespaceDeclaration(statements: Statement[], node: EnumDeclaration | ModuleDeclaration) { - const transformedStatement = createVariableStatement( + const transformedStatement = factory.createVariableStatement( /*modifiers*/ undefined, - [createVariableDeclaration( + [factory.createVariableDeclaration( getDeclarationName(node), /*type*/ undefined, - createPropertyAccess(createIdentifier("exports"), getDeclarationName(node)) + factory.createPropertyAccess(factory.createIdentifier("exports"), getDeclarationName(node)) )], /*location*/ node ); - setEmitFlags(transformedStatement, EmitFlags.NoComments); + factory.setEmitFlags(transformedStatement, EmitFlags.NoComments); statements.push(transformedStatement); } function getDeclarationName(node: DeclarationStatement) { - return node.name ? getSynthesizedClone(node.name) : getGeneratedNameForNode(node); + return node.name ? factory.getSynthesizedClone(node.name) : factory.getGeneratedNameForNode(node); } function onEmitNode(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void): void { @@ -858,10 +858,10 @@ namespace ts { // A shorthand property with an assignment initializer is probably part of a // destructuring assignment if (node.objectAssignmentInitializer) { - const initializer = createAssignment(exportedOrImportedName, node.objectAssignmentInitializer); - return createPropertyAssignment(name, initializer, /*location*/ node); + const initializer = factory.createAssignment(exportedOrImportedName, node.objectAssignmentInitializer); + return factory.createPropertyAssignment(name, initializer, /*location*/ node); } - return createPropertyAssignment(name, exportedOrImportedName, /*location*/ node); + return factory.createPropertyAssignment(name, exportedOrImportedName, /*location*/ node); } return node; } @@ -891,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)) { - setEmitFlags(node, EmitFlags.NoSubstitution); + factory.setEmitFlags(node, EmitFlags.NoSubstitution); let nestedExportAssignment: BinaryExpression; for (const specifier of bindingNameExportSpecifiersMap[left.text]) { nestedExportAssignment = nestedExportAssignment ? @@ -911,17 +911,17 @@ namespace ts { const operand = node.operand; if (isIdentifier(operand) && bindingNameExportSpecifiersForFileMap) { if (bindingNameExportSpecifiersMap && hasProperty(bindingNameExportSpecifiersMap, operand.text)) { - setEmitFlags(node, EmitFlags.NoSubstitution); + factory.setEmitFlags(node, EmitFlags.NoSubstitution); let transformedUnaryExpression: BinaryExpression; if (node.kind === SyntaxKind.PostfixUnaryExpression) { - transformedUnaryExpression = createBinary( + transformedUnaryExpression = factory.createBinary( operand, createNode(operator === SyntaxKind.PlusPlusToken ? SyntaxKind.PlusEqualsToken : SyntaxKind.MinusEqualsToken), - createLiteral(1), + factory.createLiteral(1), /*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 - setEmitFlags(transformedUnaryExpression, EmitFlags.NoSubstitution); + factory.setEmitFlags(transformedUnaryExpression, EmitFlags.NoSubstitution); } let nestedExportAssignment: BinaryExpression; for (const specifier of bindingNameExportSpecifiersMap[operand.text]) { @@ -936,14 +936,14 @@ namespace ts { } function trySubstituteExportedName(node: Identifier) { - const emitFlags = getEmitFlags(node); + const emitFlags = factory.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( - createIdentifier("exports"), - getSynthesizedClone(node), + return factory.createPropertyAccess( + factory.createIdentifier("exports"), + factory.getSynthesizedClone(node), /*location*/ node ); } @@ -954,22 +954,22 @@ namespace ts { } function trySubstituteImportedName(node: Identifier): Expression { - if ((getEmitFlags(node) & EmitFlags.LocalName) === 0) { + if ((factory.getEmitFlags(node) & EmitFlags.LocalName) === 0) { const declaration = resolver.getReferencedImportDeclaration(node); if (declaration) { if (isImportClause(declaration)) { if (languageVersion >= ScriptTarget.ES5) { - return createPropertyAccess( - getGeneratedNameForNode(declaration.parent), - createIdentifier("default"), + return factory.createPropertyAccess( + factory.getGeneratedNameForNode(declaration.parent), + factory.createIdentifier("default"), /*location*/ node ); } else { // TODO: ES3 transform to handle x.default -> x["default"] - return createElementAccess( - getGeneratedNameForNode(declaration.parent), - createLiteral("default"), + return factory.createElementAccess( + factory.getGeneratedNameForNode(declaration.parent), + factory.createLiteral("default"), /*location*/ node ); } @@ -978,16 +978,16 @@ namespace ts { const name = declaration.propertyName || declaration.name; if (name.originalKeywordKind === SyntaxKind.DefaultKeyword && languageVersion <= ScriptTarget.ES3) { // TODO: ES3 transform to handle x.default -> x["default"] - return createElementAccess( - getGeneratedNameForNode(declaration.parent.parent.parent), - createLiteral(name.text), + return factory.createElementAccess( + factory.getGeneratedNameForNode(declaration.parent.parent.parent), + factory.createLiteral(name.text), /*location*/ node ); } else { - return createPropertyAccess( - getGeneratedNameForNode(declaration.parent.parent.parent), - getSynthesizedClone(name), + return factory.createPropertyAccess( + factory.getGeneratedNameForNode(declaration.parent.parent.parent), + factory.getSynthesizedClone(name), /*location*/ node ); } @@ -998,43 +998,43 @@ namespace ts { } function getModuleMemberName(name: Identifier) { - return createPropertyAccess( - createIdentifier("exports"), + return factory.createPropertyAccess( + factory.createIdentifier("exports"), name, /*location*/ name ); } function createRequireCall(importNode: ImportDeclaration | ImportEqualsDeclaration | ExportDeclaration) { - const moduleName = getExternalModuleNameLiteral(importNode, currentSourceFile, host, resolver, compilerOptions); + const moduleName = factory.getExternalModuleNameLiteral(importNode, currentSourceFile, host, resolver, compilerOptions); const args: Expression[] = []; if (isDefined(moduleName)) { args.push(moduleName); } - return createCall(createIdentifier("require"), /*typeArguments*/ undefined, args); + return factory.createCall(factory.createIdentifier("require"), /*typeArguments*/ undefined, args); } function createExportStatement(name: Identifier, value: Expression, location?: TextRange) { - const statement = createStatement(createExportAssignment(name, value)); + const statement = factory.createStatement(createExportAssignment(name, value)); statement.startsOnNewLine = true; if (location) { - setSourceMapRange(statement, location); + factory.setSourceMapRange(statement, location); } return statement; } function createExportAssignment(name: Identifier, value: Expression) { - return createAssignment( + return factory.createAssignment( name.originalKeywordKind === SyntaxKind.DefaultKeyword && languageVersion === ScriptTarget.ES3 - ? createElementAccess( - createIdentifier("exports"), - createLiteral(name.text) + ? factory.createElementAccess( + factory.createIdentifier("exports"), + factory.createLiteral(name.text) ) - : createPropertyAccess( - createIdentifier("exports"), - getSynthesizedClone(name) + : factory.createPropertyAccess( + factory.createIdentifier("exports"), + factory.getSynthesizedClone(name) ), value ); @@ -1061,26 +1061,26 @@ namespace ts { // Fill in amd-dependency tags for (const amdDependency of node.amdDependencies) { if (amdDependency.name) { - aliasedModuleNames.push(createLiteral(amdDependency.path)); - importAliasNames.push(createParameter(amdDependency.name)); + aliasedModuleNames.push(factory.createLiteral(amdDependency.path)); + importAliasNames.push(factory.createParameter(amdDependency.name)); } else { - unaliasedModuleNames.push(createLiteral(amdDependency.path)); + unaliasedModuleNames.push(factory.createLiteral(amdDependency.path)); } } for (const importNode of externalImports) { // Find the name of the external module - const externalModuleName = getExternalModuleNameLiteral(importNode, currentSourceFile, host, resolver, compilerOptions); + const externalModuleName = factory.getExternalModuleNameLiteral(importNode, currentSourceFile, host, resolver, compilerOptions); // Find the name of the module alias, if there is one - const importAliasName = getLocalNameForExternalImport(importNode, currentSourceFile); + const importAliasName = factory.getLocalNameForExternalImport(importNode, currentSourceFile); if (includeNonAmdDependencies && importAliasName) { // Set emitFlags on the name of the classDeclaration // This is so that when printer will not substitute the identifier - setEmitFlags(importAliasName, EmitFlags.NoSubstitution); + factory.setEmitFlags(importAliasName, EmitFlags.NoSubstitution); aliasedModuleNames.push(externalModuleName); - importAliasNames.push(createParameter(importAliasName)); + importAliasNames.push(factory.createParameter(importAliasName)); } else { unaliasedModuleNames.push(externalModuleName); @@ -1091,8 +1091,8 @@ namespace ts { } function updateSourceFile(node: SourceFile, statements: Statement[]) { - const updated = getMutableClone(node); - updated.statements = createNodeArray(statements, node.statements); + const updated = factory.getMutableClone(node); + updated.statements = factory.createNodeArray(statements, node.statements); return updated; } } diff --git a/src/compiler/transformers/module/system.ts b/src/compiler/transformers/module/system.ts index 4a137c89a9336..8fe12d371f31e 100644 --- a/src/compiler/transformers/module/system.ts +++ b/src/compiler/transformers/module/system.ts @@ -95,8 +95,8 @@ namespace ts { // Make sure that the name of the 'exports' function does not conflict with // existing identifiers. - exportFunctionForFile = createUniqueName("exports"); - contextObjectForFile = createUniqueName("context"); + exportFunctionForFile = factory.createUniqueName("exports"); + contextObjectForFile = factory.createUniqueName("context"); exportFunctionForFileMap[getOriginalNodeId(node)] = exportFunctionForFile; @@ -107,19 +107,19 @@ namespace ts { // Add the body of the module. addSystemModuleBody(statements, node, dependencyGroups); - const moduleName = tryGetModuleNameFromFile(node, host, compilerOptions); - const dependencies = createArrayLiteral(map(dependencyGroups, getNameOfDependencyGroup)); - const body = createFunctionExpression( + const moduleName = factory.tryGetModuleNameFromFile(node, host, compilerOptions); + const dependencies = factory.createArrayLiteral(map(dependencyGroups, getNameOfDependencyGroup)); + const body = factory.createFunctionExpression( /*asteriskToken*/ undefined, /*name*/ undefined, /*typeParameters*/ undefined, [ - createParameter(exportFunctionForFile), - createParameter(contextObjectForFile) + factory.createParameter(exportFunctionForFile), + factory.createParameter(contextObjectForFile) ], /*type*/ undefined, - setEmitFlags( - createBlock(statements, /*location*/ undefined, /*multiLine*/ true), + factory.setEmitFlags( + factory.createBlock(statements, /*location*/ undefined, /*multiLine*/ true), EmitFlags.EmitEmitHelpers ) ); @@ -128,16 +128,16 @@ namespace ts { // Clear the emit-helpers flag for later passes since we'll have already used it in the module body // So the helper will be emit at the correct position instead of at the top of the source-file return updateSourceFile(node, [ - createStatement( - createCall( - createPropertyAccess(createIdentifier("System"), "register"), + factory.createStatement( + factory.createCall( + factory.createPropertyAccess(factory.createIdentifier("System"), "register"), /*typeArguments*/ undefined, moduleName ? [moduleName, dependencies, body] : [dependencies, body] ) ) - ], /*nodeEmitFlags*/ ~EmitFlags.EmitEmitHelpers & getEmitFlags(node)); + ], /*nodeEmitFlags*/ ~EmitFlags.EmitEmitHelpers & factory.getEmitFlags(node)); } /** @@ -196,19 +196,19 @@ namespace ts { startLexicalEnvironment(); // Add any prologue directives. - const statementOffset = addPrologueDirectives(statements, node.statements, /*ensureUseStrict*/ !compilerOptions.noImplicitUseStrict, visitSourceElement); + const statementOffset = factory.addPrologueDirectives(statements, node.statements, /*ensureUseStrict*/ !compilerOptions.noImplicitUseStrict, visitSourceElement); // var __moduleName = context_1 && context_1.id; statements.push( - createVariableStatement( + factory.createVariableStatement( /*modifiers*/ undefined, - createVariableDeclarationList([ - createVariableDeclaration( + factory.createVariableDeclarationList([ + factory.createVariableDeclaration( "__moduleName", /*type*/ undefined, - createLogicalAnd( + factory.createLogicalAnd( contextObjectForFile, - createPropertyAccess(contextObjectForFile, "id") + factory.createPropertyAccess(contextObjectForFile, "id") ) ) ]) @@ -236,20 +236,20 @@ namespace ts { const exportStarFunction = addExportStarIfNeeded(statements); statements.push( - createReturn( - setMultiLine( - createObjectLiteral([ - createPropertyAssignment("setters", + factory.createReturn( + factory.setMultiLine( + factory.createObjectLiteral([ + factory.createPropertyAssignment("setters", generateSetters(exportStarFunction, dependencyGroups) ), - createPropertyAssignment("execute", - createFunctionExpression( + factory.createPropertyAssignment("execute", + factory.createFunctionExpression( /*asteriskToken*/ undefined, /*name*/ undefined, /*typeParameters*/ undefined, /*parameters*/ [], /*type*/ undefined, - createBlock( + factory.createBlock( executeStatements, /*location*/ undefined, /*multiLine*/ true @@ -295,9 +295,9 @@ namespace ts { for (const exportedLocalName of exportedLocalNames) { // write name of exported declaration, i.e 'export var x...' exportedNames.push( - createPropertyAssignment( - createLiteral(exportedLocalName.text), - createLiteral(true) + factory.createPropertyAssignment( + factory.createLiteral(exportedLocalName.text), + factory.createLiteral(true) ) ); } @@ -317,23 +317,23 @@ namespace ts { for (const element of exportDecl.exportClause.elements) { // write name of indirectly exported entry, i.e. 'export {x} from ...' exportedNames.push( - createPropertyAssignment( - createLiteral((element.name || element.propertyName).text), - createLiteral(true) + factory.createPropertyAssignment( + factory.createLiteral((element.name || element.propertyName).text), + factory.createLiteral(true) ) ); } } - const exportedNamesStorageRef = createUniqueName("exportedNames"); + const exportedNamesStorageRef = factory.createUniqueName("exportedNames"); statements.push( - createVariableStatement( + factory.createVariableStatement( /*modifiers*/ undefined, - createVariableDeclarationList([ - createVariableDeclaration( + factory.createVariableDeclarationList([ + factory.createVariableDeclaration( exportedNamesStorageRef, /*type*/ undefined, - createObjectLiteral(exportedNames, /*location*/ undefined, /*multiline*/ true) + factory.createObjectLiteral(exportedNames, /*location*/ undefined, /*multiline*/ true) ) ]) ) @@ -350,11 +350,11 @@ namespace ts { const setters: Expression[] = []; for (const group of dependencyGroups) { // derive a unique name for parameter from the first named entry in the group - const localName = forEach(group.externalImports, i => getLocalNameForExternalImport(i, currentSourceFile)); - const parameterName = localName ? getGeneratedNameForNode(localName) : createUniqueName(""); + const localName = forEach(group.externalImports, i => factory.getLocalNameForExternalImport(i, currentSourceFile)); + const parameterName = localName ? factory.getGeneratedNameForNode(localName) : factory.createUniqueName(""); const statements: Statement[] = []; for (const entry of group.externalImports) { - const importVariableName = getLocalNameForExternalImport(entry, currentSourceFile); + const importVariableName = factory.getLocalNameForExternalImport(entry, currentSourceFile); switch (entry.kind) { case SyntaxKind.ImportDeclaration: if (!(entry).importClause) { @@ -368,8 +368,8 @@ namespace ts { Debug.assert(importVariableName !== undefined); // save import into the local statements.push( - createStatement( - createAssignment(importVariableName, parameterName) + factory.createStatement( + factory.createAssignment(importVariableName, parameterName) ) ); break; @@ -388,22 +388,22 @@ namespace ts { const properties: PropertyAssignment[] = []; for (const e of (entry).exportClause.elements) { properties.push( - createPropertyAssignment( - createLiteral(e.name.text), - createElementAccess( + factory.createPropertyAssignment( + factory.createLiteral(e.name.text), + factory.createElementAccess( parameterName, - createLiteral((e.propertyName || e.name).text) + factory.createLiteral((e.propertyName || e.name).text) ) ) ); } statements.push( - createStatement( - createCall( + factory.createStatement( + factory.createCall( exportFunctionForFile, /*typeArguments*/ undefined, - [createObjectLiteral(properties, /*location*/ undefined, /*multiline*/ true)] + [factory.createObjectLiteral(properties, /*location*/ undefined, /*multiline*/ true)] ) ) ); @@ -415,8 +415,8 @@ namespace ts { // // exportStar(foo_1_1); statements.push( - createStatement( - createCall( + factory.createStatement( + factory.createCall( exportStarFunction, /*typeArguments*/ undefined, [parameterName] @@ -429,18 +429,18 @@ namespace ts { } setters.push( - createFunctionExpression( + factory.createFunctionExpression( /*asteriskToken*/ undefined, /*name*/ undefined, /*typeParameters*/ undefined, - [createParameter(parameterName)], + [factory.createParameter(parameterName)], /*type*/ undefined, - createBlock(statements, /*location*/ undefined, /*multiLine*/ true) + factory.createBlock(statements, /*location*/ undefined, /*multiLine*/ true) ) ); } - return createArrayLiteral(setters, /*location*/ undefined, /*multiLine*/ true); + return factory.createArrayLiteral(setters, /*location*/ undefined, /*multiLine*/ true); } function visitSourceElement(node: Node): VisitResult { @@ -547,7 +547,7 @@ namespace ts { function visitImportDeclaration(node: ImportDeclaration): Node { if (node.importClause && contains(externalImports, node)) { - hoistVariableDeclaration(getLocalNameForExternalImport(node, currentSourceFile)); + hoistVariableDeclaration(factory.getLocalNameForExternalImport(node, currentSourceFile)); } return undefined; @@ -555,7 +555,7 @@ namespace ts { function visitImportEqualsDeclaration(node: ImportEqualsDeclaration): Node { if (contains(externalImports, node)) { - hoistVariableDeclaration(getLocalNameForExternalImport(node, currentSourceFile)); + hoistVariableDeclaration(factory.getLocalNameForExternalImport(node, currentSourceFile)); } // NOTE(rbuckton): Do we support export import = require('') in System? @@ -588,7 +588,7 @@ namespace ts { if (!node.isExportEquals) { if (nodeIsSynthesized(node) || resolver.isValueAliasDeclaration(node)) { return createExportStatement( - createLiteral("default"), + factory.createLiteral("default"), node.expression ); } @@ -621,7 +621,7 @@ namespace ts { } if (expressions.length) { - return createStatement(inlineExpressions(expressions), node); + return factory.createStatement(factory.inlineExpressions(expressions), node); } return undefined; @@ -645,7 +645,7 @@ namespace ts { const name = node.name; if (isIdentifier(name)) { // If the variable has an IdentifierName, write out an assignment expression in its place. - return createAssignment(name, node.initializer); + return factory.createAssignment(name, node.initializer); } else { // If the variable has a BindingPattern, flatten the variable into multiple assignment expressions. @@ -661,8 +661,8 @@ namespace ts { function visitFunctionDeclaration(node: FunctionDeclaration): Node { if (hasModifier(node, ModifierFlags.Export)) { // If the function is exported, ensure it has a name and rewrite the function without any export flags. - const name = node.name || getGeneratedNameForNode(node); - const newNode = createFunctionDeclaration( + const name = node.name || factory.getGeneratedNameForNode(node); + const newNode = factory.createFunctionDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, node.asteriskToken, @@ -680,7 +680,7 @@ namespace ts { recordExportName(name); } - setOriginalNode(newNode, node); + factory.setOriginalNode(newNode, node); node = newNode; } @@ -721,10 +721,10 @@ namespace ts { // Rewrite the class declaration into an assignment of a class expression. statements.push( - createStatement( - createAssignment( + factory.createStatement( + factory.createAssignment( name, - createClassExpression( + factory.createClassExpression( /*modifiers*/ undefined, node.name, /*typeParameters*/ undefined, @@ -769,10 +769,10 @@ namespace ts { } }; - return createFor( + return factory.createFor( expressions.length - ? inlineExpressions(expressions) - : createSynthesizedNode(SyntaxKind.OmittedExpression), + ? factory.inlineExpressions(expressions) + : factory.createSynthesizedNode(SyntaxKind.OmittedExpression), node.condition, node.incrementor, visitNode(node.statement, visitNestedNode, isStatement), @@ -807,7 +807,7 @@ namespace ts { function visitForInStatement(node: ForInStatement): ForInStatement { const initializer = node.initializer; if (shouldHoistLoopInitializer(initializer)) { - const updated = getMutableClone(node); + const updated = factory.getMutableClone(node); updated.initializer = transformForBinding(initializer); updated.statement = visitNode(node.statement, visitNestedNode, isStatement, /*optional*/ false, liftToBlock); return updated; @@ -825,7 +825,7 @@ namespace ts { function visitForOfStatement(node: ForOfStatement): ForOfStatement { const initializer = node.initializer; if (shouldHoistLoopInitializer(initializer)) { - const updated = getMutableClone(node); + const updated = factory.getMutableClone(node); updated.initializer = transformForBinding(initializer); updated.statement = visitNode(node.statement, visitNestedNode, isStatement, /*optional*/ false, liftToBlock); return updated; @@ -843,7 +843,7 @@ namespace ts { function visitDoStatement(node: DoStatement) { const statement = visitNode(node.statement, visitNestedNode, isStatement, /*optional*/ false, liftToBlock); if (statement !== node.statement) { - const updated = getMutableClone(node); + const updated = factory.getMutableClone(node); updated.statement = statement; return updated; } @@ -858,7 +858,7 @@ namespace ts { function visitWhileStatement(node: WhileStatement) { const statement = visitNode(node.statement, visitNestedNode, isStatement, /*optional*/ false, liftToBlock); if (statement !== node.statement) { - const updated = getMutableClone(node); + const updated = factory.getMutableClone(node); updated.statement = statement; return updated; } @@ -873,7 +873,7 @@ namespace ts { function visitLabeledStatement(node: LabeledStatement) { const statement = visitNode(node.statement, visitNestedNode, isStatement, /*optional*/ false, liftToBlock); if (statement !== node.statement) { - const updated = getMutableClone(node); + const updated = factory.getMutableClone(node); updated.statement = statement; return updated; } @@ -888,7 +888,7 @@ namespace ts { function visitWithStatement(node: WithStatement) { const statement = visitNode(node.statement, visitNestedNode, isStatement, /*optional*/ false, liftToBlock); if (statement !== node.statement) { - const updated = getMutableClone(node); + const updated = factory.getMutableClone(node); updated.statement = statement; return updated; } @@ -903,7 +903,7 @@ namespace ts { function visitSwitchStatement(node: SwitchStatement) { const caseBlock = visitNode(node.caseBlock, visitNestedNode, isCaseBlock); if (caseBlock !== node.caseBlock) { - const updated = getMutableClone(node); + const updated = factory.getMutableClone(node); updated.caseBlock = caseBlock; return updated; } @@ -918,7 +918,7 @@ namespace ts { function visitCaseBlock(node: CaseBlock) { const clauses = visitNodes(node.clauses, visitNestedNode, isCaseOrDefaultClause); if (clauses !== node.clauses) { - const updated = getMutableClone(node); + const updated = factory.getMutableClone(node); updated.clauses = clauses; return updated; } @@ -933,7 +933,7 @@ namespace ts { function visitCaseClause(node: CaseClause) { const statements = visitNodes(node.statements, visitNestedNode, isStatement); if (statements !== node.statements) { - const updated = getMutableClone(node); + const updated = factory.getMutableClone(node); updated.statements = statements; return updated; } @@ -966,7 +966,7 @@ namespace ts { function visitCatchClause(node: CatchClause) { const block = visitNode(node.block, visitNestedNode, isBlock); if (block !== node.block) { - const updated = getMutableClone(node); + const updated = factory.getMutableClone(node); updated.block = block; return updated; } @@ -1055,7 +1055,7 @@ namespace ts { } function substituteAssignmentExpression(node: BinaryExpression): Expression { - setEmitFlags(node, EmitFlags.NoSubstitution); + factory.setEmitFlags(node, EmitFlags.NoSubstitution); const left = node.left; switch (left.kind) { @@ -1177,8 +1177,8 @@ namespace ts { if (substitute) { const exportDeclaration = resolver.getReferencedExportContainer(operand); if (exportDeclaration) { - const expr = createPrefix(node.operator, operand, node); - setEmitFlags(expr, EmitFlags.NoSubstitution); + const expr = factory.createPrefix(node.operator, operand, node); + factory.setEmitFlags(expr, EmitFlags.NoSubstitution); const call = createExportExpression(operand, expr); if (node.kind === SyntaxKind.PrefixUnaryExpression) { return call; @@ -1188,8 +1188,8 @@ namespace ts { // however for postfix unary expressions result value should be the value before modification. // emit 'x++' as '(export('x', ++x) - 1)' and 'x--' as '(export('x', --x) + 1)' return operator === SyntaxKind.PlusPlusToken - ? createSubtract(call, createLiteral(1)) - : createAdd(call, createLiteral(1)); + ? factory.createSubtract(call, factory.createLiteral(1)) + : factory.createAdd(call, factory.createLiteral(1)); } } } @@ -1201,55 +1201,55 @@ namespace ts { * @param node The declaration statement. */ function getDeclarationName(node: DeclarationStatement) { - return node.name ? getSynthesizedClone(node.name) : getGeneratedNameForNode(node); + return node.name ? factory.getSynthesizedClone(node.name) : factory.getGeneratedNameForNode(node); } function addExportStarFunction(statements: Statement[], localNames: Identifier) { - const exportStarFunction = createUniqueName("exportStar"); - const m = createIdentifier("m"); - const n = createIdentifier("n"); - const exports = createIdentifier("exports"); - let condition: Expression = createStrictInequality(n, createLiteral("default")); + const exportStarFunction = factory.createUniqueName("exportStar"); + const m = factory.createIdentifier("m"); + const n = factory.createIdentifier("n"); + const exports = factory.createIdentifier("exports"); + let condition: Expression = factory.createStrictInequality(n, factory.createLiteral("default")); if (localNames) { - condition = createLogicalAnd( + condition = factory.createLogicalAnd( condition, - createLogicalNot(createHasOwnProperty(localNames, n)) + factory.createLogicalNot(factory.createHasOwnProperty(localNames, n)) ); } statements.push( - createFunctionDeclaration( + factory.createFunctionDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, /*asteriskToken*/ undefined, exportStarFunction, /*typeParameters*/ undefined, - [createParameter(m)], + [factory.createParameter(m)], /*type*/ undefined, - createBlock([ - createVariableStatement( + factory.createBlock([ + factory.createVariableStatement( /*modifiers*/ undefined, - createVariableDeclarationList([ - createVariableDeclaration( + factory.createVariableDeclarationList([ + factory.createVariableDeclaration( exports, /*type*/ undefined, - createObjectLiteral([]) + factory.createObjectLiteral([]) ) ]) ), - createForIn( - createVariableDeclarationList([ - createVariableDeclaration(n, /*type*/ undefined) + factory.createForIn( + factory.createVariableDeclarationList([ + factory.createVariableDeclaration(n, /*type*/ undefined) ]), m, - createBlock([ - setEmitFlags( - createIf( + factory.createBlock([ + factory.setEmitFlags( + factory.createIf( condition, - createStatement( - createAssignment( - createElementAccess(exports, n), - createElementAccess(m, n) + factory.createStatement( + factory.createAssignment( + factory.createElementAccess(exports, n), + factory.createElementAccess(m, n) ) ) ), @@ -1257,8 +1257,8 @@ namespace ts { ) ]) ), - createStatement( - createCall( + factory.createStatement( + factory.createCall( exportFunctionForFile, /*typeArguments*/ undefined, [exports] @@ -1279,8 +1279,8 @@ namespace ts { * @param value The exported value. */ function createExportExpression(name: Identifier | StringLiteral, value: Expression) { - const exportName = isIdentifier(name) ? createLiteral(name.text) : name; - return createCall(exportFunctionForFile, /*typeArguments*/ undefined, [exportName, value]); + const exportName = isIdentifier(name) ? factory.createLiteral(name.text) : name; + return factory.createCall(exportFunctionForFile, /*typeArguments*/ undefined, [exportName, value]); } /** @@ -1289,7 +1289,7 @@ namespace ts { * @param value The exported value. */ function createExportStatement(name: Identifier | StringLiteral, value: Expression) { - return createStatement(createExportExpression(name, value)); + return factory.createStatement(createExportExpression(name, value)); } /** @@ -1298,7 +1298,7 @@ namespace ts { */ function createDeclarationExport(node: DeclarationStatement) { const declarationName = getDeclarationName(node); - const exportName = hasModifier(node, ModifierFlags.Default) ? createLiteral("default") : declarationName; + const exportName = hasModifier(node, ModifierFlags.Default) ? factory.createLiteral("default") : declarationName; return createExportStatement(exportName, declarationName); } @@ -1306,11 +1306,11 @@ namespace ts { let importAlias: Identifier; let name: Identifier; if (isImportClause(importDeclaration)) { - importAlias = getGeneratedNameForNode(importDeclaration.parent); - name = createIdentifier("default"); + importAlias = factory.getGeneratedNameForNode(importDeclaration.parent); + name = factory.createIdentifier("default"); } else if (isImportSpecifier(importDeclaration)) { - importAlias = getGeneratedNameForNode(importDeclaration.parent.parent.parent); + importAlias = factory.getGeneratedNameForNode(importDeclaration.parent.parent.parent); name = importDeclaration.propertyName || importDeclaration.name; } else { @@ -1318,10 +1318,10 @@ namespace ts { } if (name.originalKeywordKind && languageVersion === ScriptTarget.ES3) { - return createElementAccess(importAlias, createLiteral(name.text)); + return factory.createElementAccess(importAlias, factory.createLiteral(name.text)); } else { - return createPropertyAccess(importAlias, getSynthesizedClone(name)); + return factory.createPropertyAccess(importAlias, factory.getSynthesizedClone(name)); } } @@ -1330,7 +1330,7 @@ namespace ts { const dependencyGroups: DependencyGroup[] = []; for (let i = 0; i < externalImports.length; i++) { const externalImport = externalImports[i]; - const externalModuleName = getExternalModuleNameLiteral(externalImport, currentSourceFile, host, resolver, compilerOptions); + const externalModuleName = factory.getExternalModuleNameLiteral(externalImport, currentSourceFile, host, resolver, compilerOptions); const text = externalModuleName.text; if (hasProperty(groupIndices, text)) { // deduplicate/group entries in dependency list by the dependency name @@ -1377,7 +1377,7 @@ namespace ts { const name = node.name; if (isIdentifier(name)) { - hoistVariableDeclaration(getSynthesizedClone(name)); + hoistVariableDeclaration(factory.getSynthesizedClone(name)); if (isExported) { recordExportName(name); } @@ -1396,9 +1396,9 @@ namespace ts { } function updateSourceFile(node: SourceFile, statements: Statement[], nodeEmitFlags: EmitFlags) { - const updated = getMutableClone(node); - updated.statements = createNodeArray(statements, node.statements); - setEmitFlags(updated, nodeEmitFlags); + const updated = factory.getMutableClone(node); + updated.statements = factory.createNodeArray(statements, node.statements); + factory.setEmitFlags(updated, nodeEmitFlags); return updated; } } diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index 2419ffa4c3b73..06bef7b455dbc 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -231,7 +231,7 @@ namespace ts { if (hasModifier(node, ModifierFlags.Ambient) && isStatement(node)) { // TypeScript ambient declarations are elided, but some comments may be preserved. // See the implementation of `getLeadingComments` in comments.ts for more details. - return createNotEmittedStatement(node); + return factory.createNotEmittedStatement(node); } switch (node.kind) { @@ -292,7 +292,7 @@ namespace ts { case SyntaxKind.InterfaceDeclaration: // TypeScript interfaces are elided, but some comments may be preserved. // See the implementation of `getLeadingComments` in comments.ts for more details. - return createNotEmittedStatement(node); + return factory.createNotEmittedStatement(node); case SyntaxKind.ClassDeclaration: // This is a class declaration with TypeScript syntax extensions. @@ -444,13 +444,13 @@ namespace ts { && (isExternalModule(node) || compilerOptions.isolatedModules)) { startLexicalEnvironment(); const statements: Statement[] = []; - const statementOffset = addPrologueDirectives(statements, node.statements, /*ensureUseStrict*/ false, visitor); - const externalHelpersModuleName = createUniqueName(externalHelpersModuleNameText); - const externalHelpersModuleImport = createImportDeclaration( + const statementOffset = factory.addPrologueDirectives(statements, node.statements, /*ensureUseStrict*/ false, visitor); + const externalHelpersModuleName = factory.createUniqueName(externalHelpersModuleNameText); + const externalHelpersModuleImport = factory.createImportDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, - createImportClause(/*name*/ undefined, createNamespaceImport(externalHelpersModuleName)), - createLiteral(externalHelpersModuleNameText) + factory.createImportClause(/*name*/ undefined, factory.createNamespaceImport(externalHelpersModuleName)), + factory.createLiteral(externalHelpersModuleNameText) ); externalHelpersModuleImport.parent = node; externalHelpersModuleImport.flags &= ~NodeFlags.Synthesized; @@ -461,14 +461,14 @@ namespace ts { addRange(statements, endLexicalEnvironment()); currentSourceFileExternalHelpersModuleName = undefined; - node = updateSourceFileNode(node, createNodeArray(statements, node.statements)); + node = factory.updateSourceFileNode(node, factory.createNodeArray(statements, node.statements)); node.externalHelpersModuleName = externalHelpersModuleName; } else { node = visitEachChild(node, visitor, context); } - setEmitFlags(node, EmitFlags.EmitEmitHelpers | getEmitFlags(node)); + factory.setEmitFlags(node, EmitFlags.EmitEmitHelpers | factory.getEmitFlags(node)); return node; } @@ -518,7 +518,7 @@ namespace ts { // let name = node.name; if (!name && staticProperties.length > 0) { - name = getGeneratedNameForNode(node); + name = factory.getGeneratedNameForNode(node); } const statements: Statement[] = []; @@ -526,7 +526,7 @@ namespace ts { // ${modifiers} class ${name} ${heritageClauses} { // ${members} // } - const classDeclaration = createClassDeclaration( + const classDeclaration = factory.createClassDeclaration( /*decorators*/ undefined, visitNodes(node.modifiers, visitor, isModifier), name, @@ -535,12 +535,12 @@ namespace ts { transformClassMembers(node, hasExtendsClause), /*location*/ node ); - setOriginalNode(classDeclaration, node); + factory.setOriginalNode(classDeclaration, node); // 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) { - setEmitFlags(classDeclaration, EmitFlags.NoTrailingSourceMap | getEmitFlags(classDeclaration)); + factory.setEmitFlags(classDeclaration, EmitFlags.NoTrailingSourceMap | factory.getEmitFlags(classDeclaration)); } statements.push(classDeclaration); @@ -571,7 +571,7 @@ namespace ts { } else if (isDecoratedClass) { if (isDefaultExternalModuleExport(node)) { - statements.push(createExportAssignment( + statements.push(factory.createExportAssignment( /*decorators*/ undefined, /*modifiers*/ undefined, /*isExportEquals*/ false, @@ -685,8 +685,8 @@ namespace ts { // ... = class ${name} ${heritageClauses} { // ${members} // } - const classExpression: Expression = setOriginalNode( - createClassExpression( + const classExpression: Expression = factory.setOriginalNode( + factory.createClassExpression( /*modifiers*/ undefined, name, /*typeParameters*/ undefined, @@ -698,14 +698,14 @@ namespace ts { ); if (!name) { - name = getGeneratedNameForNode(node); + name = factory.getGeneratedNameForNode(node); } // Record an alias to avoid class double-binding. let classAlias: Identifier; if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.ClassWithConstructorReference) { enableSubstitutionForClassAliases(); - classAlias = createUniqueName(node.name && !isGeneratedIdentifier(node.name) ? node.name.text : "default"); + classAlias = factory.createUniqueName(node.name && !isGeneratedIdentifier(node.name) ? node.name.text : "default"); classAliases[getOriginalNodeId(node)] = classAlias; } @@ -713,10 +713,10 @@ namespace ts { // let ${name} = ${classExpression} where name is either declaredName if the class doesn't contain self-reference // or decoratedClassAlias if the class contain self-reference. - const transformedClassExpression = createVariableStatement( + const transformedClassExpression = factory.createVariableStatement( /*modifiers*/ undefined, - createLetDeclarationList([ - createVariableDeclaration( + factory.createLetDeclarationList([ + factory.createVariableDeclaration( classAlias || declaredName, /*type*/ undefined, classExpression @@ -724,9 +724,9 @@ namespace ts { ]), /*location*/ location ); - setCommentRange(transformedClassExpression, node); + factory.setCommentRange(transformedClassExpression, node); statements.push( - setOriginalNode( + factory.setOriginalNode( /*node*/ transformedClassExpression, /*original*/ node ) @@ -738,11 +738,11 @@ namespace ts { // let ${declaredName} = ${decoratedClassAlias} statements.push( - setOriginalNode( - createVariableStatement( + factory.setOriginalNode( + factory.createVariableStatement( /*modifiers*/ undefined, - createLetDeclarationList([ - createVariableDeclaration( + factory.createLetDeclarationList([ + factory.createVariableDeclaration( declaredName, /*type*/ undefined, classAlias @@ -772,8 +772,8 @@ namespace ts { const heritageClauses = visitNodes(node.heritageClauses, visitor, isHeritageClause); const members = transformClassMembers(node, heritageClauses !== undefined); - const classExpression = setOriginalNode( - createClassExpression( + const classExpression = factory.setOriginalNode( + factory.createClassExpression( /*modifiers*/ undefined, node.name, /*typeParameters*/ undefined, @@ -786,20 +786,20 @@ namespace ts { if (staticProperties.length > 0) { const expressions: Expression[] = []; - const temp = createTempVariable(hoistVariableDeclaration); + const temp = factory.createTempVariable(hoistVariableDeclaration); if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.ClassWithConstructorReference) { // record an alias as the class name is not in scope for statics. enableSubstitutionForClassAliases(); - classAliases[getOriginalNodeId(node)] = getSynthesizedClone(temp); + classAliases[getOriginalNodeId(node)] = factory.getSynthesizedClone(temp); } // To preserve the behavior of the old emitter, we explicitly indent // the body of a class with static initializers. - setEmitFlags(classExpression, EmitFlags.Indented | getEmitFlags(classExpression)); - expressions.push(startOnNewLine(createAssignment(temp, classExpression))); + factory.setEmitFlags(classExpression, EmitFlags.Indented | factory.getEmitFlags(classExpression)); + expressions.push(factory.startOnNewLine(factory.createAssignment(temp, classExpression))); addRange(expressions, generateInitializedPropertyExpressions(node, staticProperties, temp)); - expressions.push(startOnNewLine(temp)); - return inlineExpressions(expressions); + expressions.push(factory.startOnNewLine(temp)); + return factory.inlineExpressions(expressions); } return classExpression; @@ -819,7 +819,7 @@ namespace ts { } addRange(members, visitNodes(node.members, classElementVisitor, isClassElement)); - return createNodeArray(members, /*location*/ node.members); + return factory.createNodeArray(members, /*location*/ node.members); } /** @@ -848,9 +848,9 @@ namespace ts { // constructor(${parameters}) { // ${body} // } - return startOnNewLine( - setOriginalNode( - createConstructor( + return factory.startOnNewLine( + factory.setOriginalNode( + factory.createConstructor( /*decorators*/ undefined, /*modifiers*/ undefined, parameters, @@ -930,11 +930,11 @@ namespace ts { // super(...arguments); // statements.push( - createStatement( - createCall( - createSuper(), + factory.createStatement( + factory.createCall( + factory.createSuper(), /*typeArguments*/ undefined, - [createSpread(createIdentifier("arguments"))] + [factory.createSpread(factory.createIdentifier("arguments"))] ) ) ); @@ -951,7 +951,7 @@ namespace ts { // } // const properties = getInitializedProperties(node, /*isStatic*/ false); - addInitializedPropertyStatements(statements, node, properties, createThis()); + addInitializedPropertyStatements(statements, node, properties, factory.createThis()); if (constructor) { // The class already had a constructor, so we should add the existing statements, skipping the initial super call. @@ -960,9 +960,9 @@ namespace ts { // End the lexical environment. addRange(statements, endLexicalEnvironment()); - return setMultiLine( - createBlock( - createNodeArray( + return factory.setMultiLine( + factory.createBlock( + factory.createNodeArray( statements, /*location*/ constructor ? constructor.body.statements : node.members ), @@ -982,7 +982,7 @@ namespace ts { if (ctor.body) { const statements = ctor.body.statements; // add prologue directives to the list (if any) - const index = addPrologueDirectives(result, statements, /*ensureUseStrict*/ false, visitor); + const index = factory.addPrologueDirectives(result, statements, /*ensureUseStrict*/ false, visitor); if (index === statements.length) { // list contains nothing but prologue directives (or empty) - exit return index; @@ -1027,17 +1027,17 @@ namespace ts { function transformParameterWithPropertyAssignment(node: ParameterDeclaration) { Debug.assert(isIdentifier(node.name)); const name = node.name as Identifier; - const propertyName = getMutableClone(name); - setEmitFlags(propertyName, EmitFlags.NoComments | EmitFlags.NoSourceMap); + const propertyName = factory.getMutableClone(name); + factory.setEmitFlags(propertyName, EmitFlags.NoComments | EmitFlags.NoSourceMap); - const localName = getMutableClone(name); - setEmitFlags(localName, EmitFlags.NoComments); + const localName = factory.getMutableClone(name); + factory.setEmitFlags(localName, EmitFlags.NoComments); - return startOnNewLine( - createStatement( - createAssignment( - createPropertyAccess( - createThis(), + return factory.startOnNewLine( + factory.createStatement( + factory.createAssignment( + factory.createPropertyAccess( + factory.createThis(), propertyName, /*location*/ node.name ), @@ -1097,9 +1097,9 @@ namespace ts { */ function addInitializedPropertyStatements(statements: Statement[], node: ClassExpression | ClassDeclaration, properties: PropertyDeclaration[], receiver: LeftHandSideExpression) { for (const property of properties) { - const statement = createStatement(transformInitializedProperty(node, property, receiver)); - setSourceMapRange(statement, moveRangePastModifiers(property)); - setCommentRange(statement, property); + const statement = factory.createStatement(transformInitializedProperty(node, property, receiver)); + factory.setSourceMapRange(statement, moveRangePastModifiers(property)); + factory.setCommentRange(statement, property); statements.push(statement); } } @@ -1116,8 +1116,8 @@ namespace ts { for (const property of properties) { const expression = transformInitializedProperty(node, property, receiver); expression.startsOnNewLine = true; - setSourceMapRange(expression, moveRangePastModifiers(property)); - setCommentRange(expression, property); + factory.setSourceMapRange(expression, moveRangePastModifiers(property)); + factory.setCommentRange(expression, property); expressions.push(expression); } @@ -1134,9 +1134,9 @@ namespace ts { function transformInitializedProperty(node: ClassExpression | ClassDeclaration, property: PropertyDeclaration, receiver: LeftHandSideExpression) { const propertyName = visitPropertyNameOfClassElement(property); const initializer = visitNode(property.initializer, visitor, isExpression); - const memberAccess = createMemberAccessForPropertyName(receiver, propertyName, /*location*/ propertyName); + const memberAccess = factory.createMemberAccessForPropertyName(receiver, propertyName, /*location*/ propertyName); - return createAssignment(memberAccess, initializer); + return factory.createAssignment(memberAccess, initializer); } /** @@ -1421,14 +1421,14 @@ namespace ts { ? member.kind === SyntaxKind.PropertyDeclaration // We emit `void 0` here to indicate to `__decorate` that it can invoke `Object.defineProperty` directly, but that it // should not invoke `Object.getOwnPropertyDescriptor`. - ? createVoidZero() + ? factory.createVoidZero() // We emit `null` here to indicate to `__decorate` that it can invoke `Object.getOwnPropertyDescriptor` directly. // We have this extra argument here so that we can inject an explicit property descriptor at a later date. - : createNull() + : factory.createNull() : undefined; - const helper = createDecorateHelper( + const helper = factory.createDecorateHelper( currentSourceFileExternalHelpersModuleName, decoratorExpressions, prefix, @@ -1437,7 +1437,7 @@ namespace ts { moveRangePastDecorators(member) ); - setEmitFlags(helper, EmitFlags.NoComments); + factory.setEmitFlags(helper, EmitFlags.NoComments); return helper; } @@ -1449,7 +1449,7 @@ namespace ts { function addConstructorDecorationStatement(statements: Statement[], node: ClassDeclaration, decoratedClassAlias: Identifier) { const expression = generateConstructorDecorationExpression(node, decoratedClassAlias); if (expression) { - statements.push(setOriginalNode(createStatement(expression), node)); + statements.push(factory.setOriginalNode(factory.createStatement(expression), node)); } } @@ -1476,17 +1476,17 @@ namespace ts { // C = C_1 = __decorate([dec], C); // if (decoratedClassAlias) { - const expression = createAssignment( + const expression = factory.createAssignment( decoratedClassAlias, - createDecorateHelper( + factory.createDecorateHelper( currentSourceFileExternalHelpersModuleName, decoratorExpressions, getDeclarationName(node) ) ); - const result = createAssignment(getDeclarationName(node), expression, moveRangePastDecorators(node)); - setEmitFlags(result, EmitFlags.NoComments); + const result = factory.createAssignment(getDeclarationName(node), expression, moveRangePastDecorators(node)); + factory.setEmitFlags(result, EmitFlags.NoComments); return result; } // Emit the call to __decorate. Given the class: @@ -1500,9 +1500,9 @@ namespace ts { // C = __decorate([dec], C); // else { - const result = createAssignment( + const result = factory.createAssignment( getDeclarationName(node), - createDecorateHelper( + factory.createDecorateHelper( currentSourceFileExternalHelpersModuleName, decoratorExpressions, getDeclarationName(node) @@ -1510,7 +1510,7 @@ namespace ts { moveRangePastDecorators(node) ); - setEmitFlags(result, EmitFlags.NoComments); + factory.setEmitFlags(result, EmitFlags.NoComments); return result; } } @@ -1535,12 +1535,12 @@ namespace ts { if (decorators) { expressions = []; for (const decorator of decorators) { - const helper = createParamHelper( + const helper = factory.createParamHelper( currentSourceFileExternalHelpersModuleName, transformDecorator(decorator), parameterOffset, /*location*/ decorator.expression); - setEmitFlags(helper, EmitFlags.NoComments); + factory.setEmitFlags(helper, EmitFlags.NoComments); expressions.push(helper); } } @@ -1566,13 +1566,13 @@ namespace ts { function addOldTypeMetadata(node: Declaration, decoratorExpressions: Expression[]) { if (compilerOptions.emitDecoratorMetadata) { if (shouldAddTypeMetadata(node)) { - decoratorExpressions.push(createMetadataHelper(currentSourceFileExternalHelpersModuleName, "design:type", serializeTypeOfNode(node))); + decoratorExpressions.push(factory.createMetadataHelper(currentSourceFileExternalHelpersModuleName, "design:type", serializeTypeOfNode(node))); } if (shouldAddParamTypesMetadata(node)) { - decoratorExpressions.push(createMetadataHelper(currentSourceFileExternalHelpersModuleName, "design:paramtypes", serializeParameterTypesOfNode(node))); + decoratorExpressions.push(factory.createMetadataHelper(currentSourceFileExternalHelpersModuleName, "design:paramtypes", serializeParameterTypesOfNode(node))); } if (shouldAddReturnTypeMetadata(node)) { - decoratorExpressions.push(createMetadataHelper(currentSourceFileExternalHelpersModuleName, "design:returntype", serializeReturnTypeOfNode(node))); + decoratorExpressions.push(factory.createMetadataHelper(currentSourceFileExternalHelpersModuleName, "design:returntype", serializeReturnTypeOfNode(node))); } } } @@ -1581,16 +1581,16 @@ namespace ts { if (compilerOptions.emitDecoratorMetadata) { let properties: ObjectLiteralElementLike[]; if (shouldAddTypeMetadata(node)) { - (properties || (properties = [])).push(createPropertyAssignment("type", createArrowFunction(/*modifiers*/ undefined, /*typeParameters*/ undefined, [], /*type*/ undefined, /*equalsGreaterThanToken*/ undefined, serializeTypeOfNode(node)))); + (properties || (properties = [])).push(factory.createPropertyAssignment("type", factory.createArrowFunction(/*modifiers*/ undefined, /*typeParameters*/ undefined, [], /*type*/ undefined, /*equalsGreaterThanToken*/ undefined, serializeTypeOfNode(node)))); } if (shouldAddParamTypesMetadata(node)) { - (properties || (properties = [])).push(createPropertyAssignment("paramTypes", createArrowFunction(/*modifiers*/ undefined, /*typeParameters*/ undefined, [], /*type*/ undefined, /*equalsGreaterThanToken*/ undefined, serializeParameterTypesOfNode(node)))); + (properties || (properties = [])).push(factory.createPropertyAssignment("paramTypes", factory.createArrowFunction(/*modifiers*/ undefined, /*typeParameters*/ undefined, [], /*type*/ undefined, /*equalsGreaterThanToken*/ undefined, serializeParameterTypesOfNode(node)))); } if (shouldAddReturnTypeMetadata(node)) { - (properties || (properties = [])).push(createPropertyAssignment("returnType", createArrowFunction(/*modifiers*/ undefined, /*typeParameters*/ undefined, [], /*type*/ undefined, /*equalsGreaterThanToken*/ undefined, serializeReturnTypeOfNode(node)))); + (properties || (properties = [])).push(factory.createPropertyAssignment("returnType", factory.createArrowFunction(/*modifiers*/ undefined, /*typeParameters*/ undefined, [], /*type*/ undefined, /*equalsGreaterThanToken*/ undefined, serializeReturnTypeOfNode(node)))); } if (properties) { - decoratorExpressions.push(createMetadataHelper(currentSourceFileExternalHelpersModuleName, "design:typeinfo", createObjectLiteral(properties, /*location*/ undefined, /*multiLine*/ true))); + decoratorExpressions.push(factory.createMetadataHelper(currentSourceFileExternalHelpersModuleName, "design:typeinfo", factory.createObjectLiteral(properties, /*location*/ undefined, /*multiLine*/ true))); } } } @@ -1653,9 +1653,9 @@ namespace ts { case SyntaxKind.ClassDeclaration: case SyntaxKind.ClassExpression: case SyntaxKind.MethodDeclaration: - return createIdentifier("Function"); + return factory.createIdentifier("Function"); default: - return createVoidZero(); + return factory.createVoidZero(); } } @@ -1708,7 +1708,7 @@ namespace ts { } } - return createArrayLiteral(expressions); + return factory.createArrayLiteral(expressions); } /** @@ -1721,10 +1721,10 @@ namespace ts { return serializeTypeNode(node.type); } else if (isAsyncFunctionLike(node)) { - return createIdentifier("Promise"); + return factory.createIdentifier("Promise"); } - return createVoidZero(); + return factory.createVoidZero(); } /** @@ -1747,42 +1747,42 @@ namespace ts { */ function serializeTypeNode(node: TypeNode): Expression { if (node === undefined) { - return createIdentifier("Object"); + return factory.createIdentifier("Object"); } switch (node.kind) { case SyntaxKind.VoidKeyword: - return createVoidZero(); + return factory.createVoidZero(); case SyntaxKind.ParenthesizedType: return serializeTypeNode((node).type); case SyntaxKind.FunctionType: case SyntaxKind.ConstructorType: - return createIdentifier("Function"); + return factory.createIdentifier("Function"); case SyntaxKind.ArrayType: case SyntaxKind.TupleType: - return createIdentifier("Array"); + return factory.createIdentifier("Array"); case SyntaxKind.TypePredicate: case SyntaxKind.BooleanKeyword: - return createIdentifier("Boolean"); + return factory.createIdentifier("Boolean"); case SyntaxKind.StringKeyword: - return createIdentifier("String"); + return factory.createIdentifier("String"); case SyntaxKind.LiteralType: switch ((node).literal.kind) { case SyntaxKind.StringLiteral: - return createIdentifier("String"); + return factory.createIdentifier("String"); case SyntaxKind.NumericLiteral: - return createIdentifier("Number"); + return factory.createIdentifier("Number"); case SyntaxKind.TrueKeyword: case SyntaxKind.FalseKeyword: - return createIdentifier("Boolean"); + return factory.createIdentifier("Boolean"); default: Debug.failBadSyntaxKind((node).literal); @@ -1791,12 +1791,12 @@ namespace ts { break; case SyntaxKind.NumberKeyword: - return createIdentifier("Number"); + return factory.createIdentifier("Number"); case SyntaxKind.SymbolKeyword: return languageVersion < ScriptTarget.ES6 ? getGlobalSymbolNameWithFallback() - : createIdentifier("Symbol"); + : factory.createIdentifier("Symbol"); case SyntaxKind.TypeReference: return serializeTypeReferenceNode(node); @@ -1845,7 +1845,7 @@ namespace ts { break; } - return createIdentifier("Object"); + return factory.createIdentifier("Object"); } /** @@ -1858,52 +1858,52 @@ namespace ts { switch (resolver.getTypeReferenceSerializationKind(node.typeName, currentScope)) { case TypeReferenceSerializationKind.Unknown: const serialized = serializeEntityNameAsExpression(node.typeName, /*useFallback*/ true); - const temp = createTempVariable(hoistVariableDeclaration); - return createLogicalOr( - createLogicalAnd( - createStrictEquality( - createTypeOf( - createAssignment(temp, serialized) + const temp = factory.createTempVariable(hoistVariableDeclaration); + return factory.createLogicalOr( + factory.createLogicalAnd( + factory.createStrictEquality( + factory.createTypeOf( + factory.createAssignment(temp, serialized) ), - createLiteral("function") + factory.createLiteral("function") ), temp ), - createIdentifier("Object") + factory.createIdentifier("Object") ); case TypeReferenceSerializationKind.TypeWithConstructSignatureAndValue: return serializeEntityNameAsExpression(node.typeName, /*useFallback*/ false); case TypeReferenceSerializationKind.VoidNullableOrNeverType: - return createVoidZero(); + return factory.createVoidZero(); case TypeReferenceSerializationKind.BooleanType: - return createIdentifier("Boolean"); + return factory.createIdentifier("Boolean"); case TypeReferenceSerializationKind.NumberLikeType: - return createIdentifier("Number"); + return factory.createIdentifier("Number"); case TypeReferenceSerializationKind.StringLikeType: - return createIdentifier("String"); + return factory.createIdentifier("String"); case TypeReferenceSerializationKind.ArrayLikeType: - return createIdentifier("Array"); + return factory.createIdentifier("Array"); case TypeReferenceSerializationKind.ESSymbolType: return languageVersion < ScriptTarget.ES6 ? getGlobalSymbolNameWithFallback() - : createIdentifier("Symbol"); + : factory.createIdentifier("Symbol"); case TypeReferenceSerializationKind.TypeWithCallSignature: - return createIdentifier("Function"); + return factory.createIdentifier("Function"); case TypeReferenceSerializationKind.Promise: - return createIdentifier("Promise"); + return factory.createIdentifier("Promise"); case TypeReferenceSerializationKind.ObjectType: default: - return createIdentifier("Object"); + return factory.createIdentifier("Object"); } } @@ -1919,15 +1919,15 @@ namespace ts { case SyntaxKind.Identifier: // Create a clone of the name with a new parent, and treat it as if it were // a source tree node for the purposes of the checker. - const name = getMutableClone(node); + const name = factory.getMutableClone(node); name.flags &= ~NodeFlags.Synthesized; name.original = undefined; name.parent = currentScope; if (useFallback) { - return createLogicalAnd( - createStrictInequality( - createTypeOf(name), - createLiteral("undefined") + return factory.createLogicalAnd( + factory.createStrictInequality( + factory.createTypeOf(name), + factory.createLiteral("undefined") ), name ); @@ -1953,9 +1953,9 @@ namespace ts { left = serializeEntityNameAsExpression(node.left, useFallback); } else if (useFallback) { - const temp = createTempVariable(hoistVariableDeclaration); - left = createLogicalAnd( - createAssignment( + const temp = factory.createTempVariable(hoistVariableDeclaration); + left = factory.createLogicalAnd( + factory.createAssignment( temp, serializeEntityNameAsExpression(node.left, /*useFallback*/ true) ), @@ -1966,7 +1966,7 @@ namespace ts { left = serializeEntityNameAsExpression(node.left, /*useFallback*/ false); } - return createPropertyAccess(left, node.right); + return factory.createPropertyAccess(left, node.right); } /** @@ -1974,15 +1974,15 @@ namespace ts { * available. */ function getGlobalSymbolNameWithFallback(): Expression { - return createConditional( - createStrictEquality( - createTypeOf(createIdentifier("Symbol")), - createLiteral("function") + return factory.createConditional( + factory.createStrictEquality( + factory.createTypeOf(factory.createIdentifier("Symbol")), + factory.createLiteral("function") ), - createToken(SyntaxKind.QuestionToken), - createIdentifier("Symbol"), - createToken(SyntaxKind.ColonToken), - createIdentifier("Object") + factory.createToken(SyntaxKind.QuestionToken), + factory.createIdentifier("Symbol"), + factory.createToken(SyntaxKind.ColonToken), + factory.createIdentifier("Object") ); } @@ -1996,14 +1996,14 @@ namespace ts { const name = member.name; if (isComputedPropertyName(name)) { return generateNameForComputedPropertyName - ? getGeneratedNameForNode(name) + ? factory.getGeneratedNameForNode(name) : (name).expression; } else if (isIdentifier(name)) { - return createLiteral(name.text); + return factory.createLiteral(name.text); } else { - return getSynthesizedClone(name); + return factory.getSynthesizedClone(name); } } @@ -2019,13 +2019,13 @@ namespace ts { if (isComputedPropertyName(name)) { let expression = visitNode(name.expression, visitor, isExpression); if (member.decorators) { - const generatedName = getGeneratedNameForNode(name); + const generatedName = factory.getGeneratedNameForNode(name); hoistVariableDeclaration(generatedName); - expression = createAssignment(generatedName, expression); + expression = factory.createAssignment(generatedName, expression); } - return setOriginalNode( - createComputedPropertyName(expression, /*location*/ name), + return factory.setOriginalNode( + factory.createComputedPropertyName(expression, /*location*/ name), name ); } @@ -2046,7 +2046,7 @@ namespace ts { function visitHeritageClause(node: HeritageClause): HeritageClause { if (node.token === SyntaxKind.ExtendsKeyword) { const types = visitNodes(node.types, visitor, isExpressionWithTypeArguments, 0, 1); - return createHeritageClause( + return factory.createHeritageClause( SyntaxKind.ExtendsKeyword, types, node @@ -2066,7 +2066,7 @@ namespace ts { */ function visitExpressionWithTypeArguments(node: ExpressionWithTypeArguments): ExpressionWithTypeArguments { const expression = visitNode(node.expression, visitor, isLeftHandSideExpression); - return createExpressionWithTypeArguments( + return factory.createExpressionWithTypeArguments( /*typeArguments*/ undefined, expression, node @@ -2098,7 +2098,7 @@ namespace ts { return undefined; } - const method = createMethod( + const method = factory.createMethod( /*decorators*/ undefined, visitNodes(node.modifiers, visitor, isModifier), node.asteriskToken, @@ -2112,9 +2112,9 @@ namespace ts { // While we emit the source map for the node after skipping decorators and modifiers, // we need to emit the comments for the original range. - setCommentRange(method, node); - setSourceMapRange(method, moveRangePastDecorators(node)); - setOriginalNode(method, node); + factory.setCommentRange(method, node); + factory.setSourceMapRange(method, moveRangePastDecorators(node)); + factory.setOriginalNode(method, node); return method; } @@ -2143,21 +2143,21 @@ namespace ts { return undefined; } - const accessor = createGetAccessor( + const accessor = factory.createGetAccessor( /*decorators*/ undefined, visitNodes(node.modifiers, visitor, isModifier), visitPropertyNameOfClassElement(node), visitNodes(node.parameters, visitor, isParameter), /*type*/ undefined, - node.body ? visitEachChild(node.body, visitor, context) : createBlock([]), + node.body ? visitEachChild(node.body, visitor, context) : factory.createBlock([]), /*location*/ node ); // While we emit the source map for the node after skipping decorators and modifiers, // we need to emit the comments for the original range. - setCommentRange(accessor, node); - setSourceMapRange(accessor, moveRangePastDecorators(node)); - setOriginalNode(accessor, node); + factory.setCommentRange(accessor, node); + factory.setSourceMapRange(accessor, moveRangePastDecorators(node)); + factory.setOriginalNode(accessor, node); return accessor; } @@ -2176,20 +2176,20 @@ namespace ts { return undefined; } - const accessor = createSetAccessor( + const accessor = factory.createSetAccessor( /*decorators*/ undefined, visitNodes(node.modifiers, visitor, isModifier), visitPropertyNameOfClassElement(node), visitNodes(node.parameters, visitor, isParameter), - node.body ? visitEachChild(node.body, visitor, context) : createBlock([]), + node.body ? visitEachChild(node.body, visitor, context) : factory.createBlock([]), /*location*/ node ); // While we emit the source map for the node after skipping decorators and modifiers, // we need to emit the comments for the original range. - setCommentRange(accessor, node); - setSourceMapRange(accessor, moveRangePastDecorators(node)); - setOriginalNode(accessor, node); + factory.setCommentRange(accessor, node); + factory.setSourceMapRange(accessor, moveRangePastDecorators(node)); + factory.setOriginalNode(accessor, node); return accessor; } @@ -2206,10 +2206,10 @@ namespace ts { */ function visitFunctionDeclaration(node: FunctionDeclaration): VisitResult { if (!shouldEmitFunctionLikeDeclaration(node)) { - return createNotEmittedStatement(node); + return factory.createNotEmittedStatement(node); } - const func = createFunctionDeclaration( + const func = factory.createFunctionDeclaration( /*decorators*/ undefined, visitNodes(node.modifiers, visitor, isModifier), node.asteriskToken, @@ -2220,7 +2220,7 @@ namespace ts { transformFunctionBody(node), /*location*/ node ); - setOriginalNode(func, node); + factory.setOriginalNode(func, node); if (isNamespaceExport(node)) { const statements: Statement[] = [func]; @@ -2241,10 +2241,10 @@ namespace ts { */ function visitFunctionExpression(node: FunctionExpression): Expression { if (nodeIsMissing(node.body)) { - return createOmittedExpression(); + return factory.createOmittedExpression(); } - const func = createFunctionExpression( + const func = factory.createFunctionExpression( node.asteriskToken, node.name, /*typeParameters*/ undefined, @@ -2254,7 +2254,7 @@ namespace ts { /*location*/ node ); - setOriginalNode(func, node); + factory.setOriginalNode(func, node); return func; } @@ -2265,7 +2265,7 @@ namespace ts { * - The node is marked async */ function visitArrowFunction(node: ArrowFunction) { - const func = createArrowFunction( + const func = factory.createArrowFunction( /*modifiers*/ undefined, /*typeParameters*/ undefined, visitNodes(node.parameters, visitor, isParameter), @@ -2275,7 +2275,7 @@ namespace ts { /*location*/ node ); - setOriginalNode(func, node); + factory.setOriginalNode(func, node); return func; } @@ -2294,7 +2294,7 @@ namespace ts { startLexicalEnvironment(); const statements = visitNodes(body.statements, visitor, isStatement, start); - const visited = updateBlock(body, statements); + const visited = factory.updateBlock(body, statements); const declarations = endLexicalEnvironment(); currentScope = savedCurrentScope; return mergeFunctionBodyLexicalEnvironment(visited, declarations); @@ -2318,8 +2318,8 @@ namespace ts { const declarations = endLexicalEnvironment(); const merged = mergeFunctionBodyLexicalEnvironment(visited, declarations); if (forceBlockFunctionBody && !isBlock(merged)) { - return createBlock([ - createReturn(merged) + return factory.createBlock([ + factory.createReturn(merged) ]); } else { @@ -2355,10 +2355,10 @@ namespace ts { if (!isArrowFunction) { const statements: Statement[] = []; - const statementOffset = addPrologueDirectives(statements, (node.body).statements, /*ensureUseStrict*/ false, visitor); + const statementOffset = factory.addPrologueDirectives(statements, (node.body).statements, /*ensureUseStrict*/ false, visitor); statements.push( - createReturn( - createAwaiterHelper( + factory.createReturn( + factory.createAwaiterHelper( currentSourceFileExternalHelpersModuleName, hasLexicalArguments, promiseConstructor, @@ -2367,25 +2367,25 @@ namespace ts { ) ); - const block = createBlock(statements, /*location*/ node.body, /*multiLine*/ true); + const block = factory.createBlock(statements, /*location*/ node.body, /*multiLine*/ true); // Minor optimization, emit `_super` helper to capture `super` access in an arrow. // This step isn't needed if we eventually transform this to ES5. if (languageVersion >= ScriptTarget.ES6) { if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.AsyncMethodWithSuperBinding) { enableSubstitutionForAsyncMethodsWithSuper(); - setEmitFlags(block, EmitFlags.EmitAdvancedSuperHelper); + factory.setEmitFlags(block, EmitFlags.EmitAdvancedSuperHelper); } else if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.AsyncMethodWithSuper) { enableSubstitutionForAsyncMethodsWithSuper(); - setEmitFlags(block, EmitFlags.EmitSuperHelper); + factory.setEmitFlags(block, EmitFlags.EmitSuperHelper); } } return block; } else { - return createAwaiterHelper( + return factory.createAwaiterHelper( currentSourceFileExternalHelpersModuleName, hasLexicalArguments, promiseConstructor, @@ -2409,7 +2409,7 @@ namespace ts { return undefined; } - const parameter = createParameterDeclaration( + const parameter = factory.createParameterDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, node.dotDotDotToken, @@ -2422,10 +2422,10 @@ namespace ts { // While we emit the source map for the node after skipping decorators and modifiers, // we need to emit the comments for the original range. - setOriginalNode(parameter, node); - setCommentRange(parameter, node); - setSourceMapRange(parameter, moveRangePastModifiers(node)); - setEmitFlags(parameter.name, EmitFlags.NoTrailingSourceMap); + factory.setOriginalNode(parameter, node); + factory.setCommentRange(parameter, node); + factory.setSourceMapRange(parameter, moveRangePastModifiers(node)); + factory.setEmitFlags(parameter.name, EmitFlags.NoTrailingSourceMap); return parameter; } @@ -2444,8 +2444,8 @@ namespace ts { return undefined; } - return createStatement( - inlineExpressions( + return factory.createStatement( + factory.inlineExpressions( map(variables, transformInitializedVariable) ), /*location*/ node @@ -2468,7 +2468,7 @@ namespace ts { ); } else { - return createAssignment( + return factory.createAssignment( getNamespaceMemberNameWithSourceMapsAndWithoutComments(name), visitNode(node.initializer, visitor, isExpression), /*location*/ node @@ -2484,8 +2484,8 @@ namespace ts { * @param node The await expression node. */ function visitAwaitExpression(node: AwaitExpression): Expression { - return setOriginalNode( - createYield( + return factory.setOriginalNode( + factory.createYield( /*asteriskToken*/ undefined, visitNode(node.expression, visitor, isExpression), /*location*/ node @@ -2501,7 +2501,7 @@ namespace ts { * @param node The parenthesized expression node. */ function visitParenthesizedExpression(node: ParenthesizedExpression): Expression { - const innerExpression = skipOuterExpressions(node.expression, ~OuterExpressionKinds.Assertions); + const innerExpression = factory.skipOuterExpressions(node.expression, ~factory.OuterExpressionKinds.Assertions); if (isAssertionExpression(innerExpression)) { // Make sure we consider all nested cast expressions, e.g.: // (-A).x; @@ -2520,7 +2520,7 @@ namespace ts { // // To preserve comments, we return a "PartiallyEmittedExpression" here which will // preserve the position information of the original expression. - return createPartiallyEmittedExpression(expression, node); + return factory.createPartiallyEmittedExpression(expression, node); } return visitEachChild(node, visitor, context); @@ -2528,12 +2528,12 @@ namespace ts { function visitAssertionExpression(node: AssertionExpression): Expression { const expression = visitNode(node.expression, visitor, isExpression); - return createPartiallyEmittedExpression(expression, node); + return factory.createPartiallyEmittedExpression(expression, node); } function visitNonNullExpression(node: NonNullExpression): Expression { const expression = visitNode(node.expression, visitor, isLeftHandSideExpression); - return createPartiallyEmittedExpression(expression, node); + return factory.createPartiallyEmittedExpression(expression, node); } /** @@ -2558,15 +2558,15 @@ namespace ts { * Adds a trailing VariableStatement for an enum or module declaration. */ function addVarForEnumExportedFromNamespace(statements: Statement[], node: EnumDeclaration | ModuleDeclaration) { - const statement = createVariableStatement( + const statement = factory.createVariableStatement( /*modifiers*/ undefined, - [createVariableDeclaration( + [factory.createVariableDeclaration( getDeclarationName(node), /*type*/ undefined, getExportName(node) )] ); - setSourceMapRange(statement, node); + factory.setSourceMapRange(statement, node); statements.push(statement); } @@ -2614,30 +2614,30 @@ namespace ts { // x[x["y"] = 0] = "y"; // ... // })(x || (x = {})); - const enumStatement = createStatement( - createCall( - createFunctionExpression( + const enumStatement = factory.createStatement( + factory.createCall( + factory.createFunctionExpression( /*asteriskToken*/ undefined, /*name*/ undefined, /*typeParameters*/ undefined, - [createParameter(parameterName)], + [factory.createParameter(parameterName)], /*type*/ undefined, transformEnumBody(node, containerName) ), /*typeArguments*/ undefined, - [createLogicalOr( + [factory.createLogicalOr( exportName, - createAssignment( + factory.createAssignment( exportName, - createObjectLiteral() + factory.createObjectLiteral() ) )] ), /*location*/ node ); - setOriginalNode(enumStatement, node); - setEmitFlags(enumStatement, emitFlags); + factory.setOriginalNode(enumStatement, node); + factory.setEmitFlags(enumStatement, emitFlags); statements.push(enumStatement); if (isNamespaceExport(node)) { @@ -2662,8 +2662,8 @@ namespace ts { addRange(statements, endLexicalEnvironment()); currentNamespaceContainerName = savedCurrentNamespaceLocalName; - return createBlock( - createNodeArray(statements, /*location*/ node.members), + return factory.createBlock( + factory.createNodeArray(statements, /*location*/ node.members), /*location*/ undefined, /*multiLine*/ true ); @@ -2679,12 +2679,12 @@ namespace ts { // we pass false as 'generateNameForComputedPropertyName' for a backward compatibility purposes // old emitter always generate 'expression' part of the name as-is. const name = getExpressionForPropertyName(member, /*generateNameForComputedPropertyName*/ false); - return createStatement( - createAssignment( - createElementAccess( + return factory.createStatement( + factory.createAssignment( + factory.createElementAccess( currentNamespaceContainerName, - createAssignment( - createElementAccess( + factory.createAssignment( + factory.createElementAccess( currentNamespaceContainerName, name ), @@ -2706,7 +2706,7 @@ namespace ts { function transformEnumMemberDeclarationValue(member: EnumMember): Expression { const value = resolver.getConstantValue(member); if (value !== undefined) { - return createLiteral(value); + return factory.createLiteral(value); } else { enableSubstitutionForNonQualifiedEnumMembers(); @@ -2714,7 +2714,7 @@ namespace ts { return visitNode(member.initializer, visitor, isExpression); } else { - return createVoidZero(); + return factory.createVoidZero(); } } } @@ -2777,25 +2777,25 @@ namespace ts { */ function addVarForEnumOrModuleDeclaration(statements: Statement[], node: ModuleDeclaration | EnumDeclaration) { // Emit a variable statement for the module. - const statement = createVariableStatement( + const statement = factory.createVariableStatement( isES6ExportedDeclaration(node) ? visitNodes(node.modifiers, visitor, isModifier) : undefined, [ - createVariableDeclaration( + factory.createVariableDeclaration( getDeclarationName(node, /*allowComments*/ false, /*allowSourceMaps*/ true) ) ] ); - setOriginalNode(statement, /*original*/ node); + factory.setOriginalNode(statement, /*original*/ node); // Adjust the source map emit to match the old emitter. if (node.kind === SyntaxKind.EnumDeclaration) { - setSourceMapRange(statement.declarationList, node); + factory.setSourceMapRange(statement.declarationList, node); } else { - setSourceMapRange(statement, node); + factory.setSourceMapRange(statement, node); } // Trailing comments for module declaration should be emitted after the function closure @@ -2816,8 +2816,8 @@ namespace ts { // } // })(m1 || (m1 = {})); // trailing comment module // - setCommentRange(statement, node); - setEmitFlags(statement, EmitFlags.NoTrailingComments); + factory.setCommentRange(statement, node); + factory.setEmitFlags(statement, EmitFlags.NoTrailingComments); statements.push(statement); } @@ -2830,7 +2830,7 @@ namespace ts { */ function visitModuleDeclaration(node: ModuleDeclaration): VisitResult { if (!shouldEmitModuleDeclaration(node)) { - return createNotEmittedStatement(node); + return factory.createNotEmittedStatement(node); } Debug.assert(isIdentifier(node.name), "TypeScript module should have an Identifier name."); @@ -2866,11 +2866,11 @@ namespace ts { // x || (x = {}) // exports.x || (exports.x = {}) let moduleArg = - createLogicalOr( + factory.createLogicalOr( exportName, - createAssignment( + factory.createAssignment( exportName, - createObjectLiteral() + factory.createObjectLiteral() ) ); @@ -2879,19 +2879,19 @@ namespace ts { const localName = getLocalName(node); // x = (exports.x || (exports.x = {})) - moduleArg = createAssignment(localName, moduleArg); + moduleArg = factory.createAssignment(localName, moduleArg); } // (function (x_1) { // x_1.y = ...; // })(x || (x = {})); - const moduleStatement = createStatement( - createCall( - createFunctionExpression( + const moduleStatement = factory.createStatement( + factory.createCall( + factory.createFunctionExpression( /*asteriskToken*/ undefined, /*name*/ undefined, /*typeParameters*/ undefined, - [createParameter(parameterName)], + [factory.createParameter(parameterName)], /*type*/ undefined, transformModuleBody(node, containerName) ), @@ -2901,8 +2901,8 @@ namespace ts { /*location*/ node ); - setOriginalNode(moduleStatement, node); - setEmitFlags(moduleStatement, emitFlags); + factory.setOriginalNode(moduleStatement, node); + factory.setEmitFlags(moduleStatement, emitFlags); statements.push(moduleStatement); return statements; } @@ -2951,8 +2951,8 @@ namespace ts { currentNamespace = savedCurrentNamespace; currentScopeFirstDeclarationsOfName = savedCurrentScopeFirstDeclarationsOfName; - const block = createBlock( - createNodeArray( + const block = factory.createBlock( + factory.createNodeArray( statements, /*location*/ statementsLocation ), @@ -2981,7 +2981,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) { - setEmitFlags(block, getEmitFlags(block) | EmitFlags.NoComments); + factory.setEmitFlags(block, factory.getEmitFlags(block) | EmitFlags.NoComments); } return block; } @@ -3021,17 +3021,17 @@ namespace ts { return undefined; } - const moduleReference = createExpressionFromEntityName(node.moduleReference); - setEmitFlags(moduleReference, EmitFlags.NoComments | EmitFlags.NoNestedComments); + const moduleReference = factory.createExpressionFromEntityName(node.moduleReference); + factory.setEmitFlags(moduleReference, EmitFlags.NoComments | EmitFlags.NoNestedComments); if (isNamedExternalModuleExport(node) || !isNamespaceExport(node)) { // export var ${name} = ${moduleReference}; // var ${name} = ${moduleReference}; - return setOriginalNode( - createVariableStatement( + return factory.setOriginalNode( + factory.createVariableStatement( visitNodes(node.modifiers, visitor, isModifier), - createVariableDeclarationList([ - createVariableDeclaration( + factory.createVariableDeclarationList([ + factory.createVariableDeclaration( node.name, /*type*/ undefined, moduleReference @@ -3044,7 +3044,7 @@ namespace ts { } else { // exports.${name} = ${moduleReference}; - return setOriginalNode( + return factory.setOriginalNode( createNamespaceExport( node.name, moduleReference, @@ -3097,24 +3097,24 @@ namespace ts { * Creates a statement for the provided expression. This is used in calls to `map`. */ function expressionToStatement(expression: Expression) { - return createStatement(expression, /*location*/ undefined); + return factory.createStatement(expression, /*location*/ undefined); } function addExportMemberAssignment(statements: Statement[], node: DeclarationStatement) { - const expression = createAssignment( + const expression = factory.createAssignment( getExportName(node), getLocalName(node, /*noSourceMaps*/ true) ); - setSourceMapRange(expression, createRange(node.name.pos, node.end)); + factory.setSourceMapRange(expression, createRange(node.name.pos, node.end)); - const statement = createStatement(expression); - setSourceMapRange(statement, createRange(-1, node.end)); + const statement = factory.createStatement(expression); + factory.setSourceMapRange(statement, createRange(-1, node.end)); statements.push(statement); } function createNamespaceExport(exportName: Identifier, exportValue: Expression, location?: TextRange) { - return createStatement( - createAssignment( + return factory.createStatement( + factory.createAssignment( getNamespaceMemberName(exportName, /*allowComments*/ false, /*allowSourceMaps*/ true), exportValue ), @@ -3123,17 +3123,17 @@ namespace ts { } function createExternalModuleExport(exportName: Identifier) { - return createExportDeclaration( + return factory.createExportDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, - createNamedExports([ - createExportSpecifier(exportName) + factory.createNamedExports([ + factory.createExportSpecifier(exportName) ]) ); } function getNamespaceMemberName(name: Identifier, allowComments?: boolean, allowSourceMaps?: boolean): Expression { - const qualifiedName = createPropertyAccess(currentNamespaceContainerName, getSynthesizedClone(name), /*location*/ name); + const qualifiedName = factory.createPropertyAccess(currentNamespaceContainerName, factory.getSynthesizedClone(name), /*location*/ name); let emitFlags: EmitFlags; if (!allowComments) { emitFlags |= EmitFlags.NoComments; @@ -3142,7 +3142,7 @@ namespace ts { emitFlags |= EmitFlags.NoSourceMap; } if (emitFlags) { - setEmitFlags(qualifiedName, emitFlags); + factory.setEmitFlags(qualifiedName, emitFlags); } return qualifiedName; } @@ -3155,8 +3155,8 @@ namespace ts { * Gets the declaration name used inside of a namespace or enum. */ function getNamespaceParameterName(node: ModuleDeclaration | EnumDeclaration) { - const name = getGeneratedNameForNode(node); - setSourceMapRange(name, node.name); + const name = factory.getGeneratedNameForNode(node); + factory.setSourceMapRange(name, node.name); return name; } @@ -3165,7 +3165,7 @@ namespace ts { * of its declaration. */ function getNamespaceContainerName(node: ModuleDeclaration | EnumDeclaration) { - return getGeneratedNameForNode(node); + return factory.getGeneratedNameForNode(node); } /** @@ -3210,8 +3210,8 @@ namespace ts { */ function getDeclarationName(node: DeclarationStatement | ClassExpression, allowComments?: boolean, allowSourceMaps?: boolean, emitFlags?: EmitFlags) { if (node.name) { - const name = getMutableClone(node.name); - emitFlags |= getEmitFlags(node.name); + const name = factory.getMutableClone(node.name); + emitFlags |= factory.getEmitFlags(node.name); if (!allowSourceMaps) { emitFlags |= EmitFlags.NoSourceMap; } @@ -3221,18 +3221,18 @@ namespace ts { } if (emitFlags) { - setEmitFlags(name, emitFlags); + factory.setEmitFlags(name, emitFlags); } return name; } else { - return getGeneratedNameForNode(node); + return factory.getGeneratedNameForNode(node); } } function getClassPrototype(node: ClassExpression | ClassDeclaration) { - return createPropertyAccess(getDeclarationName(node), "prototype"); + return factory.createPropertyAccess(getDeclarationName(node), "prototype"); } function getClassMemberPrefix(node: ClassExpression | ClassDeclaration, member: ClassElement) { @@ -3367,10 +3367,10 @@ namespace ts { // A shorthand property with an assignment initializer is probably part of a // destructuring assignment if (node.objectAssignmentInitializer) { - const initializer = createAssignment(exportedName, node.objectAssignmentInitializer); - return createPropertyAssignment(name, initializer, /*location*/ node); + const initializer = factory.createAssignment(exportedName, node.objectAssignmentInitializer); + return factory.createPropertyAssignment(name, initializer, /*location*/ node); } - return createPropertyAssignment(name, exportedName, /*location*/ node); + return factory.createPropertyAssignment(name, exportedName, /*location*/ node); } } return node; @@ -3412,9 +3412,9 @@ namespace ts { if (declaration) { const classAlias = classAliases[declaration.id]; if (classAlias) { - const clone = getSynthesizedClone(classAlias); - setSourceMapRange(clone, node); - setCommentRange(clone, node); + const clone = factory.getSynthesizedClone(classAlias); + factory.setSourceMapRange(clone, node); + factory.setCommentRange(clone, node); return clone; } } @@ -3426,7 +3426,7 @@ namespace ts { function trySubstituteNamespaceExportedName(node: Identifier): Expression { // If this is explicitly a local name, do not substitute. - if (enabledSubstitutions & applicableSubstitutions && (getEmitFlags(node) & EmitFlags.LocalName) === 0) { + if (enabledSubstitutions & applicableSubstitutions && (factory.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); @@ -3435,7 +3435,7 @@ namespace ts { (applicableSubstitutions & TypeScriptSubstitutionFlags.NamespaceExports && container.kind === SyntaxKind.ModuleDeclaration) || (applicableSubstitutions & TypeScriptSubstitutionFlags.NonQualifiedEnumMembers && container.kind === SyntaxKind.EnumDeclaration); if (substitute) { - return createPropertyAccess(getGeneratedNameForNode(container), node, /*location*/ node); + return factory.createPropertyAccess(factory.getGeneratedNameForNode(container), node, /*location*/ node); } } } @@ -3451,11 +3451,11 @@ namespace ts { const argumentExpression = isPropertyAccessExpression(expression) ? substitutePropertyAccessExpression(expression) : substituteElementAccessExpression(expression); - return createCall( - createPropertyAccess(argumentExpression, "call"), + return factory.createCall( + factory.createPropertyAccess(argumentExpression, "call"), /*typeArguments*/ undefined, [ - createThis(), + factory.createThis(), ...node.arguments ] ); @@ -3469,7 +3469,7 @@ namespace ts { const flags = getSuperContainerAsyncMethodFlags(); if (flags) { return createSuperAccessInAsyncMethod( - createLiteral(node.name.text), + factory.createLiteral(node.name.text), flags, node ); @@ -3497,9 +3497,9 @@ namespace ts { function substituteConstantValue(node: PropertyAccessExpression | ElementAccessExpression): LeftHandSideExpression { const constantValue = tryGetConstEnumValue(node); if (constantValue !== undefined) { - const substitute = createLiteral(constantValue); - setSourceMapRange(substitute, node); - setCommentRange(substitute, node); + const substitute = factory.createLiteral(constantValue); + factory.setSourceMapRange(substitute, node); + factory.setCommentRange(substitute, node); if (!compilerOptions.removeComments) { const propertyName = isPropertyAccessExpression(node) ? declarationNameToString(node.name) @@ -3507,7 +3507,7 @@ namespace ts { substitute.trailingComment = ` ${propertyName} `; } - setConstantValue(node, constantValue); + factory.setConstantValue(node, constantValue); return substitute; } @@ -3526,9 +3526,9 @@ namespace ts { function createSuperAccessInAsyncMethod(argumentExpression: Expression, flags: NodeCheckFlags, location: TextRange): LeftHandSideExpression { if (flags & NodeCheckFlags.AsyncMethodWithSuperBinding) { - return createPropertyAccess( - createCall( - createIdentifier("_super"), + return factory.createPropertyAccess( + factory.createCall( + factory.createIdentifier("_super"), /*typeArguments*/ undefined, [argumentExpression] ), @@ -3537,8 +3537,8 @@ namespace ts { ); } else { - return createCall( - createIdentifier("_super"), + return factory.createCall( + factory.createIdentifier("_super"), /*typeArguments*/ undefined, [argumentExpression], location diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 62813e9447c87..4f96f4cfc5b61 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -3839,7 +3839,7 @@ namespace ts { } export function isLeftHandSideExpression(node: Node): node is LeftHandSideExpression { - return isLeftHandSideExpressionKind(skipPartiallyEmittedExpressions(node).kind); + return isLeftHandSideExpressionKind(factory.skipPartiallyEmittedExpressions(node).kind); } function isUnaryExpressionKind(kind: SyntaxKind): boolean { @@ -3854,7 +3854,7 @@ namespace ts { } export function isUnaryExpression(node: Node): node is UnaryExpression { - return isUnaryExpressionKind(skipPartiallyEmittedExpressions(node).kind); + return isUnaryExpressionKind(factory.skipPartiallyEmittedExpressions(node).kind); } function isExpressionKind(kind: SyntaxKind) { @@ -3869,7 +3869,7 @@ namespace ts { } export function isExpression(node: Node): node is Expression { - return isExpressionKind(skipPartiallyEmittedExpressions(node).kind); + return isExpressionKind(factory.skipPartiallyEmittedExpressions(node).kind); } export function isAssertionExpression(node: Node): node is AssertionExpression { diff --git a/src/compiler/visitor.ts b/src/compiler/visitor.ts index e147eda8535a6..004dce0bd9ff1 100644 --- a/src/compiler/visitor.ts +++ b/src/compiler/visitor.ts @@ -91,7 +91,7 @@ namespace ts { ], [SyntaxKind.EnumMember]: [ { name: "name", test: isPropertyName }, - { name: "initializer", test: isExpression, optional: true, parenthesize: parenthesizeExpressionForList } + { name: "initializer", test: isExpression, optional: true, parenthesize: factory.parenthesizeExpressionForList } ] }); @@ -614,7 +614,7 @@ namespace ts { // If we are not visiting all of the original nodes, we must always create a new array. // Since this is a fragment of a node array, we do not copy over the previous location // and will only copy over `hasTrailingComma` if we are including the last element. - updated = createNodeArray([], /*location*/ undefined, + updated = factory.createNodeArray([], /*location*/ undefined, /*hasTrailingComma*/ nodes.hasTrailingComma && start + count === length); } @@ -625,7 +625,7 @@ namespace ts { if (updated !== undefined || visited === undefined || visited !== node) { if (updated === undefined) { // Ensure we have a copy of `nodes`, up to the current index. - updated = createNodeArray(nodes.slice(0, i), /*location*/ nodes, nodes.hasTrailingComma); + updated = factory.createNodeArray(nodes.slice(0, i), /*location*/ nodes, nodes.hasTrailingComma); } if (visited) { if (isArray(visited)) { @@ -687,12 +687,12 @@ namespace ts { // Names case SyntaxKind.ComputedPropertyName: - return updateComputedPropertyName(node, + return factory.updateComputedPropertyName(node, visitNode((node).expression, visitor, isExpression)); // Signature elements case SyntaxKind.Parameter: - return updateParameterDeclaration(node, + return factory.updateParameterDeclaration(node, visitNodes((node).decorators, visitor, isDecorator), visitNodes((node).modifiers, visitor, isModifier), visitNode((node).name, visitor, isBindingName), @@ -701,7 +701,7 @@ namespace ts { // Type member case SyntaxKind.PropertyDeclaration: - return updateProperty(node, + return factory.updateProperty(node, visitNodes((node).decorators, visitor, isDecorator), visitNodes((node).modifiers, visitor, isModifier), visitNode((node).name, visitor, isPropertyName), @@ -709,7 +709,7 @@ namespace ts { visitNode((node).initializer, visitor, isExpression, /*optional*/ true)); case SyntaxKind.MethodDeclaration: - return updateMethod(node, + return factory.updateMethod(node, visitNodes((node).decorators, visitor, isDecorator), visitNodes((node).modifiers, visitor, isModifier), visitNode((node).name, visitor, isPropertyName), @@ -721,7 +721,7 @@ namespace ts { context.endLexicalEnvironment())); case SyntaxKind.Constructor: - return updateConstructor(node, + return factory.updateConstructor(node, visitNodes((node).decorators, visitor, isDecorator), visitNodes((node).modifiers, visitor, isModifier), (context.startLexicalEnvironment(), visitNodes((node).parameters, visitor, isParameter)), @@ -730,7 +730,7 @@ namespace ts { context.endLexicalEnvironment())); case SyntaxKind.GetAccessor: - return updateGetAccessor(node, + return factory.updateGetAccessor(node, visitNodes((node).decorators, visitor, isDecorator), visitNodes((node).modifiers, visitor, isModifier), visitNode((node).name, visitor, isPropertyName), @@ -741,7 +741,7 @@ namespace ts { context.endLexicalEnvironment())); case SyntaxKind.SetAccessor: - return updateSetAccessor(node, + return factory.updateSetAccessor(node, visitNodes((node).decorators, visitor, isDecorator), visitNodes((node).modifiers, visitor, isModifier), visitNode((node).name, visitor, isPropertyName), @@ -752,61 +752,61 @@ namespace ts { // Binding patterns case SyntaxKind.ObjectBindingPattern: - return updateObjectBindingPattern(node, + return factory.updateObjectBindingPattern(node, visitNodes((node).elements, visitor, isBindingElement)); case SyntaxKind.ArrayBindingPattern: - return updateArrayBindingPattern(node, + return factory.updateArrayBindingPattern(node, visitNodes((node).elements, visitor, isArrayBindingElement)); case SyntaxKind.BindingElement: - return updateBindingElement(node, + return factory.updateBindingElement(node, visitNode((node).propertyName, visitor, isPropertyName, /*optional*/ true), visitNode((node).name, visitor, isBindingName), visitNode((node).initializer, visitor, isExpression, /*optional*/ true)); // Expression case SyntaxKind.ArrayLiteralExpression: - return updateArrayLiteral(node, + return factory.updateArrayLiteral(node, visitNodes((node).elements, visitor, isExpression)); case SyntaxKind.ObjectLiteralExpression: - return updateObjectLiteral(node, + return factory.updateObjectLiteral(node, visitNodes((node).properties, visitor, isObjectLiteralElementLike)); case SyntaxKind.PropertyAccessExpression: - return updatePropertyAccess(node, + return factory.updatePropertyAccess(node, visitNode((node).expression, visitor, isExpression), visitNode((node).name, visitor, isIdentifier)); case SyntaxKind.ElementAccessExpression: - return updateElementAccess(node, + return factory.updateElementAccess(node, visitNode((node).expression, visitor, isExpression), visitNode((node).argumentExpression, visitor, isExpression)); case SyntaxKind.CallExpression: - return updateCall(node, + return factory.updateCall(node, visitNode((node).expression, visitor, isExpression), visitNodes((node).typeArguments, visitor, isTypeNode), visitNodes((node).arguments, visitor, isExpression)); case SyntaxKind.NewExpression: - return updateNew(node, + return factory.updateNew(node, visitNode((node).expression, visitor, isExpression), visitNodes((node).typeArguments, visitor, isTypeNode), visitNodes((node).arguments, visitor, isExpression)); case SyntaxKind.TaggedTemplateExpression: - return updateTaggedTemplate(node, + return factory.updateTaggedTemplate(node, visitNode((node).tag, visitor, isExpression), visitNode((node).template, visitor, isTemplate)); case SyntaxKind.ParenthesizedExpression: - return updateParen(node, + return factory.updateParen(node, visitNode((node).expression, visitor, isExpression)); case SyntaxKind.FunctionExpression: - return updateFunctionExpression(node, + return factory.updateFunctionExpression(node, visitNode((node).name, visitor, isPropertyName), visitNodes((node).typeParameters, visitor, isTypeParameter), (context.startLexicalEnvironment(), visitNodes((node).parameters, visitor, isParameter)), @@ -816,7 +816,7 @@ namespace ts { context.endLexicalEnvironment())); case SyntaxKind.ArrowFunction: - return updateArrowFunction(node, + return factory.updateArrowFunction(node, visitNodes((node).modifiers, visitor, isModifier), visitNodes((node).typeParameters, visitor, isTypeParameter), (context.startLexicalEnvironment(), visitNodes((node).parameters, visitor, isParameter)), @@ -826,55 +826,55 @@ namespace ts { context.endLexicalEnvironment())); case SyntaxKind.DeleteExpression: - return updateDelete(node, + return factory.updateDelete(node, visitNode((node).expression, visitor, isExpression)); case SyntaxKind.TypeOfExpression: - return updateTypeOf(node, + return factory.updateTypeOf(node, visitNode((node).expression, visitor, isExpression)); case SyntaxKind.VoidExpression: - return updateVoid(node, + return factory.updateVoid(node, visitNode((node).expression, visitor, isExpression)); case SyntaxKind.AwaitExpression: - return updateAwait(node, + return factory.updateAwait(node, visitNode((node).expression, visitor, isExpression)); case SyntaxKind.BinaryExpression: - return updateBinary(node, + return factory.updateBinary(node, visitNode((node).left, visitor, isExpression), visitNode((node).right, visitor, isExpression)); case SyntaxKind.PrefixUnaryExpression: - return updatePrefix(node, + return factory.updatePrefix(node, visitNode((node).operand, visitor, isExpression)); case SyntaxKind.PostfixUnaryExpression: - return updatePostfix(node, + return factory.updatePostfix(node, visitNode((node).operand, visitor, isExpression)); case SyntaxKind.ConditionalExpression: - return updateConditional(node, + return factory.updateConditional(node, visitNode((node).condition, visitor, isExpression), visitNode((node).whenTrue, visitor, isExpression), visitNode((node).whenFalse, visitor, isExpression)); case SyntaxKind.TemplateExpression: - return updateTemplateExpression(node, + return factory.updateTemplateExpression(node, visitNode((node).head, visitor, isTemplateLiteralFragment), visitNodes((node).templateSpans, visitor, isTemplateSpan)); case SyntaxKind.YieldExpression: - return updateYield(node, + return factory.updateYield(node, visitNode((node).expression, visitor, isExpression)); case SyntaxKind.SpreadElementExpression: - return updateSpread(node, + return factory.updateSpread(node, visitNode((node).expression, visitor, isExpression)); case SyntaxKind.ClassExpression: - return updateClassExpression(node, + return factory.updateClassExpression(node, visitNodes((node).modifiers, visitor, isModifier), visitNode((node).name, visitor, isIdentifier, /*optional*/ true), visitNodes((node).typeParameters, visitor, isTypeParameter), @@ -882,114 +882,114 @@ namespace ts { visitNodes((node).members, visitor, isClassElement)); case SyntaxKind.ExpressionWithTypeArguments: - return updateExpressionWithTypeArguments(node, + return factory.updateExpressionWithTypeArguments(node, visitNodes((node).typeArguments, visitor, isTypeNode), visitNode((node).expression, visitor, isExpression)); // Misc case SyntaxKind.TemplateSpan: - return updateTemplateSpan(node, + return factory.updateTemplateSpan(node, visitNode((node).expression, visitor, isExpression), visitNode((node).literal, visitor, isTemplateLiteralFragment)); // Element case SyntaxKind.Block: - return updateBlock(node, + return factory.updateBlock(node, visitNodes((node).statements, visitor, isStatement)); case SyntaxKind.VariableStatement: - return updateVariableStatement(node, + return factory.updateVariableStatement(node, visitNodes((node).modifiers, visitor, isModifier), visitNode((node).declarationList, visitor, isVariableDeclarationList)); case SyntaxKind.ExpressionStatement: - return updateStatement(node, + return factory.updateStatement(node, visitNode((node).expression, visitor, isExpression)); case SyntaxKind.IfStatement: - return updateIf(node, + return factory.updateIf(node, visitNode((node).expression, visitor, isExpression), visitNode((node).thenStatement, visitor, isStatement, /*optional*/ false, liftToBlock), visitNode((node).elseStatement, visitor, isStatement, /*optional*/ true, liftToBlock)); case SyntaxKind.DoStatement: - return updateDo(node, + return factory.updateDo(node, visitNode((node).statement, visitor, isStatement, /*optional*/ false, liftToBlock), visitNode((node).expression, visitor, isExpression)); case SyntaxKind.WhileStatement: - return updateWhile(node, + return factory.updateWhile(node, visitNode((node).expression, visitor, isExpression), visitNode((node).statement, visitor, isStatement, /*optional*/ false, liftToBlock)); case SyntaxKind.ForStatement: - return updateFor(node, + return factory.updateFor(node, visitNode((node).initializer, visitor, isForInitializer), visitNode((node).condition, visitor, isExpression), visitNode((node).incrementor, visitor, isExpression), visitNode((node).statement, visitor, isStatement, /*optional*/ false, liftToBlock)); case SyntaxKind.ForInStatement: - return updateForIn(node, + return factory.updateForIn(node, visitNode((node).initializer, visitor, isForInitializer), visitNode((node).expression, visitor, isExpression), visitNode((node).statement, visitor, isStatement, /*optional*/ false, liftToBlock)); case SyntaxKind.ForOfStatement: - return updateForOf(node, + return factory.updateForOf(node, visitNode((node).initializer, visitor, isForInitializer), visitNode((node).expression, visitor, isExpression), visitNode((node).statement, visitor, isStatement, /*optional*/ false, liftToBlock)); case SyntaxKind.ContinueStatement: - return updateContinue(node, + return factory.updateContinue(node, visitNode((node).label, visitor, isIdentifier, /*optional*/ true)); case SyntaxKind.BreakStatement: - return updateBreak(node, + return factory.updateBreak(node, visitNode((node).label, visitor, isIdentifier, /*optional*/ true)); case SyntaxKind.ReturnStatement: - return updateReturn(node, + return factory.updateReturn(node, visitNode((node).expression, visitor, isExpression, /*optional*/ true)); case SyntaxKind.WithStatement: - return updateWith(node, + return factory.updateWith(node, visitNode((node).expression, visitor, isExpression), visitNode((node).statement, visitor, isStatement, /*optional*/ false, liftToBlock)); case SyntaxKind.SwitchStatement: - return updateSwitch(node, + return factory.updateSwitch(node, visitNode((node).expression, visitor, isExpression), visitNode((node).caseBlock, visitor, isCaseBlock)); case SyntaxKind.LabeledStatement: - return updateLabel(node, + return factory.updateLabel(node, visitNode((node).label, visitor, isIdentifier), visitNode((node).statement, visitor, isStatement, /*optional*/ false, liftToBlock)); case SyntaxKind.ThrowStatement: - return updateThrow(node, + return factory.updateThrow(node, visitNode((node).expression, visitor, isExpression)); case SyntaxKind.TryStatement: - return updateTry(node, + return factory.updateTry(node, visitNode((node).tryBlock, visitor, isBlock), visitNode((node).catchClause, visitor, isCatchClause, /*optional*/ true), visitNode((node).finallyBlock, visitor, isBlock, /*optional*/ true)); case SyntaxKind.VariableDeclaration: - return updateVariableDeclaration(node, + return factory.updateVariableDeclaration(node, visitNode((node).name, visitor, isBindingName), visitNode((node).type, visitor, isTypeNode, /*optional*/ true), visitNode((node).initializer, visitor, isExpression, /*optional*/ true)); case SyntaxKind.VariableDeclarationList: - return updateVariableDeclarationList(node, + return factory.updateVariableDeclarationList(node, visitNodes((node).declarations, visitor, isVariableDeclaration)); case SyntaxKind.FunctionDeclaration: - return updateFunctionDeclaration(node, + return factory.updateFunctionDeclaration(node, visitNodes((node).decorators, visitor, isDecorator), visitNodes((node).modifiers, visitor, isModifier), visitNode((node).name, visitor, isPropertyName), @@ -1001,7 +1001,7 @@ namespace ts { context.endLexicalEnvironment())); case SyntaxKind.ClassDeclaration: - return updateClassDeclaration(node, + return factory.updateClassDeclaration(node, visitNodes((node).decorators, visitor, isDecorator), visitNodes((node).modifiers, visitor, isModifier), visitNode((node).name, visitor, isIdentifier, /*optional*/ true), @@ -1010,125 +1010,125 @@ namespace ts { visitNodes((node).members, visitor, isClassElement)); case SyntaxKind.CaseBlock: - return updateCaseBlock(node, + return factory.updateCaseBlock(node, visitNodes((node).clauses, visitor, isCaseOrDefaultClause)); case SyntaxKind.ImportDeclaration: - return updateImportDeclaration(node, + return factory.updateImportDeclaration(node, visitNodes((node).decorators, visitor, isDecorator), visitNodes((node).modifiers, visitor, isModifier), visitNode((node).importClause, visitor, isImportClause, /*optional*/ true), visitNode((node).moduleSpecifier, visitor, isExpression)); case SyntaxKind.ImportClause: - return updateImportClause(node, + return factory.updateImportClause(node, visitNode((node).name, visitor, isIdentifier, /*optional*/ true), visitNode((node).namedBindings, visitor, isNamedImportBindings, /*optional*/ true)); case SyntaxKind.NamespaceImport: - return updateNamespaceImport(node, + return factory.updateNamespaceImport(node, visitNode((node).name, visitor, isIdentifier)); case SyntaxKind.NamedImports: - return updateNamedImports(node, + return factory.updateNamedImports(node, visitNodes((node).elements, visitor, isImportSpecifier)); case SyntaxKind.ImportSpecifier: - return updateImportSpecifier(node, + return factory.updateImportSpecifier(node, visitNode((node).propertyName, visitor, isIdentifier, /*optional*/ true), visitNode((node).name, visitor, isIdentifier)); case SyntaxKind.ExportAssignment: - return updateExportAssignment(node, + return factory.updateExportAssignment(node, visitNodes((node).decorators, visitor, isDecorator), visitNodes((node).modifiers, visitor, isModifier), visitNode((node).expression, visitor, isExpression)); case SyntaxKind.ExportDeclaration: - return updateExportDeclaration(node, + return factory.updateExportDeclaration(node, visitNodes((node).decorators, visitor, isDecorator), visitNodes((node).modifiers, visitor, isModifier), visitNode((node).exportClause, visitor, isNamedExports, /*optional*/ true), visitNode((node).moduleSpecifier, visitor, isExpression, /*optional*/ true)); case SyntaxKind.NamedExports: - return updateNamedExports(node, + return factory.updateNamedExports(node, visitNodes((node).elements, visitor, isExportSpecifier)); case SyntaxKind.ExportSpecifier: - return updateExportSpecifier(node, + return factory.updateExportSpecifier(node, visitNode((node).propertyName, visitor, isIdentifier, /*optional*/ true), visitNode((node).name, visitor, isIdentifier)); // JSX case SyntaxKind.JsxElement: - return updateJsxElement(node, + return factory.updateJsxElement(node, visitNode((node).openingElement, visitor, isJsxOpeningElement), visitNodes((node).children, visitor, isJsxChild), visitNode((node).closingElement, visitor, isJsxClosingElement)); case SyntaxKind.JsxSelfClosingElement: - return updateJsxSelfClosingElement(node, + return factory.updateJsxSelfClosingElement(node, visitNode((node).tagName, visitor, isJsxTagNameExpression), visitNodes((node).attributes, visitor, isJsxAttributeLike)); case SyntaxKind.JsxOpeningElement: - return updateJsxOpeningElement(node, + return factory.updateJsxOpeningElement(node, visitNode((node).tagName, visitor, isJsxTagNameExpression), visitNodes((node).attributes, visitor, isJsxAttributeLike)); case SyntaxKind.JsxClosingElement: - return updateJsxClosingElement(node, + return factory.updateJsxClosingElement(node, visitNode((node).tagName, visitor, isJsxTagNameExpression)); case SyntaxKind.JsxAttribute: - return updateJsxAttribute(node, + return factory.updateJsxAttribute(node, visitNode((node).name, visitor, isIdentifier), visitNode((node).initializer, visitor, isStringLiteralOrJsxExpression)); case SyntaxKind.JsxSpreadAttribute: - return updateJsxSpreadAttribute(node, + return factory.updateJsxSpreadAttribute(node, visitNode((node).expression, visitor, isExpression)); case SyntaxKind.JsxExpression: - return updateJsxExpression(node, + return factory.updateJsxExpression(node, visitNode((node).expression, visitor, isExpression)); // Clauses case SyntaxKind.CaseClause: - return updateCaseClause(node, + return factory.updateCaseClause(node, visitNode((node).expression, visitor, isExpression), visitNodes((node).statements, visitor, isStatement)); case SyntaxKind.DefaultClause: - return updateDefaultClause(node, + return factory.updateDefaultClause(node, visitNodes((node).statements, visitor, isStatement)); case SyntaxKind.HeritageClause: - return updateHeritageClause(node, + return factory.updateHeritageClause(node, visitNodes((node).types, visitor, isExpressionWithTypeArguments)); case SyntaxKind.CatchClause: - return updateCatchClause(node, + return factory.updateCatchClause(node, visitNode((node).variableDeclaration, visitor, isVariableDeclaration), visitNode((node).block, visitor, isBlock)); // Property assignments case SyntaxKind.PropertyAssignment: - return updatePropertyAssignment(node, + return factory.updatePropertyAssignment(node, visitNode((node).name, visitor, isPropertyName), visitNode((node).initializer, visitor, isExpression)); case SyntaxKind.ShorthandPropertyAssignment: - return updateShorthandPropertyAssignment(node, + return factory.updateShorthandPropertyAssignment(node, visitNode((node).name, visitor, isIdentifier), visitNode((node).objectAssignmentInitializer, visitor, isExpression)); // Top-level nodes case SyntaxKind.SourceFile: context.startLexicalEnvironment(); - return updateSourceFileNode(node, - createNodeArray( + return factory.updateSourceFileNode(node, + factory.createNodeArray( concatenate( visitNodes((node).statements, visitor, isStatement), context.endLexicalEnvironment()), @@ -1136,7 +1136,7 @@ namespace ts { // Transformation nodes case SyntaxKind.PartiallyEmittedExpression: - return updatePartiallyEmittedExpression(node, + return factory.updatePartiallyEmittedExpression(node, visitNode((node).expression, visitor, isExpression)); default: @@ -1151,7 +1151,7 @@ namespace ts { : visitNode(value, visitor, edge.test, edge.optional, edge.lift, edge.parenthesize, node); if (updated !== undefined || visited !== value) { if (updated === undefined) { - updated = getMutableClone(node); + updated = factory.getMutableClone(node); } if (visited !== value) { updated[edge.name] = visited; @@ -1160,7 +1160,7 @@ namespace ts { } } } - return updated ? updateNode(updated, node) : node; + return updated ? factory.updateNode(updated, node) : node; } // return node; @@ -1185,11 +1185,11 @@ namespace ts { export function mergeFunctionBodyLexicalEnvironment(body: ConciseBody, declarations: Statement[]): ConciseBody { if (body && declarations !== undefined && declarations.length > 0) { if (isBlock(body)) { - return updateBlock(body, createNodeArray(concatenate(body.statements, declarations), body.statements)); + return factory.updateBlock(body, factory.createNodeArray(concatenate(body.statements, declarations), body.statements)); } else { - return createBlock( - createNodeArray([createReturn(body, /*location*/ body), ...declarations], body), + return factory.createBlock( + factory.createNodeArray([factory.createReturn(body, /*location*/ body), ...declarations], body), /*location*/ body, /*multiLine*/ true); } @@ -1204,7 +1204,7 @@ namespace ts { */ export function liftToBlock(nodes: Node[]): Statement { Debug.assert(every(nodes, isStatement), "Cannot lift nodes to a Block."); - return singleOrUndefined(nodes) || createBlock(>nodes); + return singleOrUndefined(nodes) || factory.createBlock(>nodes); } /** From 9101a1473e733cb9856ab711dd1157c71b66f755 Mon Sep 17 00:00:00 2001 From: Ivo Gabe de Wolff Date: Sat, 8 Oct 2016 20:01:24 +0200 Subject: [PATCH 3/8] Move @internal annotations --- src/compiler/factory.ts | 7 +++++++ src/compiler/transformer.ts | 2 ++ src/compiler/types.ts | 2 -- src/compiler/visitor.ts | 12 +++++++++++- 4 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index 5f1080b3a15fb..68856e8cc0118 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -1466,6 +1466,7 @@ namespace ts.factory { * * @param original The original statement. */ + /* @internal */ export function createNotEmittedStatement(original: Node) { const node = createNode(SyntaxKind.NotEmittedStatement, /*location*/ original); node.original = original; @@ -1480,6 +1481,7 @@ namespace ts.factory { * @param original The original outer expression. * @param location The location for the expression. Defaults to the positions from "original" if provided. */ + /* @internal */ export function createPartiallyEmittedExpression(expression: Expression, original?: Node, location?: TextRange) { const node = createNode(SyntaxKind.PartiallyEmittedExpression, /*location*/ location || original); node.expression = expression; @@ -1487,6 +1489,7 @@ namespace ts.factory { return node; } + /* @internal */ export function updatePartiallyEmittedExpression(node: PartiallyEmittedExpression, expression: Expression) { if (node.expression !== expression) { return updateNode(createPartiallyEmittedExpression(expression, node.original, node), node); @@ -2717,6 +2720,7 @@ namespace ts.factory { * * @param node The node. */ + /* @internal */ export function getEmitFlags(node: Node) { const emitNode = node.emitNode; return emitNode && emitNode.flags; @@ -2728,6 +2732,7 @@ namespace ts.factory { * @param node The node. * @param emitFlags The NodeEmitFlags for the node. */ + /* @internal */ export function setEmitFlags(node: T, emitFlags: EmitFlags) { getOrCreateEmitNode(node).flags = emitFlags; return node; @@ -2864,6 +2869,7 @@ namespace ts.factory { * 3- The containing SourceFile has an entry in renamedDependencies for the import as requested by some module loaders (e.g. System). * Otherwise, a new StringLiteral node representing the module name will be returned. */ + /* @internal */ export function getExternalModuleNameLiteral(importNode: ImportDeclaration | ExportDeclaration | ImportEqualsDeclaration, sourceFile: SourceFile, host: EmitHost, resolver: EmitResolver, compilerOptions: CompilerOptions) { const moduleName = getExternalModuleName(importNode); if (moduleName.kind === SyntaxKind.StringLiteral) { @@ -2893,6 +2899,7 @@ namespace ts.factory { * 2. --out or --outFile is used, making the name relative to the rootDir * Otherwise, a new StringLiteral node representing the module name will be returned. */ + /* @internal */ export function tryGetModuleNameFromFile(file: SourceFile, host: EmitHost, options: CompilerOptions): StringLiteral { if (!file) { return undefined; diff --git a/src/compiler/transformer.ts b/src/compiler/transformer.ts index b76bf140942cb..d1ad2636fea26 100644 --- a/src/compiler/transformer.ts +++ b/src/compiler/transformer.ts @@ -50,7 +50,9 @@ namespace ts { export interface TransformationContext extends LexicalEnvironment { getCompilerOptions(): CompilerOptions; + /* @internal */ getEmitResolver(): EmitResolver; + /* @internal */ getEmitHost(): EmitHost; /** diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 4a4a25fd62755..6a73acfd34a79 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3214,7 +3214,6 @@ namespace ts { CustomPrologue = 1 << 23, // Treat the statement as if it were a prologue directive (NOTE: Prologue directives are *not* transformed). } - /* @internal */ export const enum EmitContext { SourceFile, // Emitting a SourceFile Expression, // Emitting an Expression @@ -3223,7 +3222,6 @@ namespace ts { } /** Additional context provided to `visitEachChild` */ - /* @internal */ export interface LexicalEnvironment { /** Starts a new lexical environment. */ startLexicalEnvironment(): void; diff --git a/src/compiler/visitor.ts b/src/compiler/visitor.ts index 004dce0bd9ff1..a3d9e2b3856fd 100644 --- a/src/compiler/visitor.ts +++ b/src/compiler/visitor.ts @@ -2,7 +2,6 @@ /// /// -/* @internal */ namespace ts { export type VisitResult = T | T[]; @@ -108,6 +107,7 @@ namespace ts { * @param f The callback function * @param initial The initial value to supply to the reduction. */ + /* @internal */ export function reduceEachChild(node: Node, f: (memo: T, node: Node) => T, initial: T): T { if (node === undefined) { return initial; @@ -591,8 +591,11 @@ namespace ts { * @param start An optional value indicating the starting offset at which to start visiting. * @param count An optional value indicating the maximum number of nodes to visit. */ + /* @internal */ export function visitNodes(nodes: NodeArray, visitor: (node: Node) => VisitResult, test: (node: Node) => boolean, start?: number, count?: number): NodeArray; + /* @internal */ export function visitNodes(nodes: NodeArray, visitor: (node: Node) => VisitResult, test: (node: Node) => boolean, start: number, count: number, parenthesize: (node: Node, parentNode: Node) => Node, parentNode: Node): NodeArray; + /* @internal */ export function visitNodes(nodes: NodeArray, visitor: (node: Node) => VisitResult, test: (node: Node) => boolean, start?: number, count?: number, parenthesize?: (node: Node, parentNode: Node) => Node, parentNode?: Node): NodeArray { if (nodes === undefined) { return undefined; @@ -660,6 +663,7 @@ namespace ts { * @param visitor The callback used to visit each child. * @param context A lexical environment context for the visitor. */ + /* @internal */ export function visitEachChild(node: T, visitor: (node: Node) => VisitResult, context: LexicalEnvironment): T; export function visitEachChild(node: Node, visitor: (node: Node) => VisitResult, context: LexicalEnvironment): Node { if (node === undefined) { @@ -1172,6 +1176,7 @@ namespace ts { * @param node The ConciseBody of an arrow function. * @param declarations The lexical declarations to merge. */ + /* @internal */ export function mergeFunctionBodyLexicalEnvironment(body: FunctionBody, declarations: Statement[]): FunctionBody; /** @@ -1180,8 +1185,10 @@ namespace ts { * @param node The ConciseBody of an arrow function. * @param declarations The lexical declarations to merge. */ + /* @internal */ export function mergeFunctionBodyLexicalEnvironment(body: ConciseBody, declarations: Statement[]): ConciseBody; + /* @internal */ export function mergeFunctionBodyLexicalEnvironment(body: ConciseBody, declarations: Statement[]): ConciseBody { if (body && declarations !== undefined && declarations.length > 0) { if (isBlock(body)) { @@ -1202,6 +1209,7 @@ namespace ts { * * @param nodes The NodeArray. */ + /* @internal */ export function liftToBlock(nodes: Node[]): Statement { Debug.assert(every(nodes, isStatement), "Cannot lift nodes to a Block."); return singleOrUndefined(nodes) || factory.createBlock(>nodes); @@ -1220,6 +1228,7 @@ namespace ts { /** * Aggregates the TransformFlags for a Node and its subtree. */ + /* @internal */ export function aggregateTransformFlags(node: T): T { aggregateTransformFlagsForNode(node); return node; @@ -1327,6 +1336,7 @@ namespace ts { } } + /* @internal */ export namespace Debug { export const failNotOptional = shouldAssert(AssertionLevel.Normal) ? (message?: string) => assert(false, message || "Node not optional.") From 2b3792673928d0fe13910eb701b34531f2df0b18 Mon Sep 17 00:00:00 2001 From: Ivo Gabe de Wolff Date: Sat, 8 Oct 2016 20:46:27 +0200 Subject: [PATCH 4/8] Expose visitEachChild instead of visitNode --- src/compiler/visitor.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/visitor.ts b/src/compiler/visitor.ts index a3d9e2b3856fd..d00046937343f 100644 --- a/src/compiler/visitor.ts +++ b/src/compiler/visitor.ts @@ -546,6 +546,7 @@ namespace ts { * @param optional An optional value indicating whether the Node is itself optional. * @param lift An optional callback to execute to lift a NodeArrayNode into a valid Node. */ + /* @internal */ export function visitNode(node: T, visitor: (node: Node) => VisitResult, test: (node: Node) => boolean, optional?: boolean, lift?: (node: NodeArray) => T): T; export function visitNode(node: T, visitor: (node: Node) => VisitResult, test: (node: Node) => boolean, optional: boolean, lift: (node: NodeArray) => T, parenthesize: (node: Node, parentNode: Node) => Node, parentNode: Node): T; export function visitNode(node: Node, visitor: (node: Node) => VisitResult, test: (node: Node) => boolean, optional?: boolean, lift?: (node: Node[]) => Node, parenthesize?: (node: Node, parentNode: Node) => Node, parentNode?: Node): Node { @@ -663,7 +664,6 @@ namespace ts { * @param visitor The callback used to visit each child. * @param context A lexical environment context for the visitor. */ - /* @internal */ export function visitEachChild(node: T, visitor: (node: Node) => VisitResult, context: LexicalEnvironment): T; export function visitEachChild(node: Node, visitor: (node: Node) => VisitResult, context: LexicalEnvironment): Node { if (node === undefined) { From dde2dc7e616c517104af8e38511c8c6551ce163e Mon Sep 17 00:00:00 2001 From: Ivo Gabe de Wolff Date: Sat, 8 Oct 2016 20:47:40 +0200 Subject: [PATCH 5/8] Make last argument of visitEachChild optional --- src/compiler/visitor.ts | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/compiler/visitor.ts b/src/compiler/visitor.ts index d00046937343f..8942fa562c5f7 100644 --- a/src/compiler/visitor.ts +++ b/src/compiler/visitor.ts @@ -657,6 +657,13 @@ namespace ts { return updated || nodes; } + const emptyLexicalEnvironment: LexicalEnvironment = { + startLexicalEnvironment() {}, + endLexicalEnvironment() { + return []; + } + }; + /** * Visits each child of a Node using the supplied visitor, possibly returning a new Node of the same kind in its place. * @@ -664,8 +671,8 @@ namespace ts { * @param visitor The callback used to visit each child. * @param context A lexical environment context for the visitor. */ - export function visitEachChild(node: T, visitor: (node: Node) => VisitResult, context: LexicalEnvironment): T; - export function visitEachChild(node: Node, visitor: (node: Node) => VisitResult, context: LexicalEnvironment): Node { + export function visitEachChild(node: T, visitor: (node: Node) => VisitResult, context?: LexicalEnvironment): T; + export function visitEachChild(node: Node, visitor: (node: Node) => VisitResult, context: LexicalEnvironment = emptyLexicalEnvironment): Node { if (node === undefined) { return undefined; } From fd441faa6afaea7c9f004545a97527925e13c348 Mon Sep 17 00:00:00 2001 From: Ivo Gabe de Wolff Date: Wed, 12 Oct 2016 17:05:14 +0200 Subject: [PATCH 6/8] Fix source map generation --- src/compiler/emitter.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index fa98fbb0c34a3..f55187e5eee6d 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -86,7 +86,7 @@ namespace ts { const transform = transformFiles(resolver, host, sourceFiles, transformers); performance.measure("transformTime", "beforeTransform"); - const printFile = createPrinter(host, emittedFilesList, emitterDiagnostics, transform, resolver.hasGlobalName); + const printFile = createPrinter(host, emittedFilesList, emitterDiagnostics, transform, resolver.hasGlobalName, sourceMapDataList); // Emit each output file performance.mark("beforePrint"); @@ -138,7 +138,8 @@ namespace ts { emittedFilesList: string[], emitterDiagnostics: DiagnosticCollection, { transformed, emitNodeWithSubstitution, emitNodeWithNotification }: TransformationResult, - hasGlobalName: (name: string) => boolean + hasGlobalName: (name: string) => boolean, + sourceMapDataList?: SourceMapData[] ) { const delimiters = createDelimiterMap(); const brackets = createBracketsMap(); @@ -313,7 +314,6 @@ const _super = (function (geti, seti) { const compilerOptions = host.getCompilerOptions(); const languageVersion = getEmitScriptTarget(compilerOptions); const moduleKind = getEmitModuleKind(compilerOptions); - const sourceMapDataList: SourceMapData[] = compilerOptions.sourceMap || compilerOptions.inlineSourceMap ? [] : undefined; const newLine = host.getNewLine(); const writer = createTextWriter(newLine); const { From 4b10786cea518ec5c44be5ae36fa14ab284a4eb3 Mon Sep 17 00:00:00 2001 From: Ivo Gabe de Wolff Date: Wed, 12 Oct 2016 17:06:31 +0200 Subject: [PATCH 7/8] Nested namespace for ts.factory Before this change, this would be rewritten to `namespace "typescript".factory {` by the build process, resulting in an invalid definition file. --- src/compiler/factory.ts | 4846 ++++++++++++++++++++------------------- 1 file changed, 2424 insertions(+), 2422 deletions(-) diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index a55e7a5c022c3..cf905f75f1f00 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -1,2920 +1,2922 @@ /// /// -namespace ts.factory { - let NodeConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node; - let SourceFileConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node; +namespace ts { + export namespace factory { + let NodeConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node; + let SourceFileConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node; - function createNode(kind: SyntaxKind, location?: TextRange, flags?: NodeFlags): Node { - const ConstructorForKind = kind === SyntaxKind.SourceFile - ? (SourceFileConstructor || (SourceFileConstructor = objectAllocator.getSourceFileConstructor())) - : (NodeConstructor || (NodeConstructor = objectAllocator.getNodeConstructor())); + function createNode(kind: SyntaxKind, location?: TextRange, flags?: NodeFlags): Node { + const ConstructorForKind = kind === SyntaxKind.SourceFile + ? (SourceFileConstructor || (SourceFileConstructor = objectAllocator.getSourceFileConstructor())) + : (NodeConstructor || (NodeConstructor = objectAllocator.getNodeConstructor())); - const node = location - ? new ConstructorForKind(kind, location.pos, location.end) - : new ConstructorForKind(kind, /*pos*/ -1, /*end*/ -1); + const node = location + ? new ConstructorForKind(kind, location.pos, location.end) + : new ConstructorForKind(kind, /*pos*/ -1, /*end*/ -1); - node.flags = flags | NodeFlags.Synthesized; + node.flags = flags | NodeFlags.Synthesized; - return node; - } + return node; + } - export function updateNode(updated: T, original: T): T { - if (updated !== original) { - setOriginalNode(updated, original); - if (original.startsOnNewLine) { - updated.startsOnNewLine = true; + export function updateNode(updated: T, original: T): T { + if (updated !== original) { + setOriginalNode(updated, original); + if (original.startsOnNewLine) { + updated.startsOnNewLine = true; + } + aggregateTransformFlags(updated); } - aggregateTransformFlags(updated); + return updated; } - return updated; - } - export function createNodeArray(elements?: T[], location?: TextRange, hasTrailingComma?: boolean): NodeArray { - if (elements) { - if (isNodeArray(elements)) { - return elements; + export function createNodeArray(elements?: T[], location?: TextRange, hasTrailingComma?: boolean): NodeArray { + if (elements) { + if (isNodeArray(elements)) { + return elements; + } + } + else { + elements = []; } - } - else { - elements = []; - } - const array = >elements; - if (location) { - array.pos = location.pos; - array.end = location.end; - } - else { - array.pos = -1; - array.end = -1; - } + const array = >elements; + if (location) { + array.pos = location.pos; + array.end = location.end; + } + else { + array.pos = -1; + array.end = -1; + } + + if (hasTrailingComma) { + array.hasTrailingComma = true; + } - if (hasTrailingComma) { - array.hasTrailingComma = true; + return array; } - return array; - } + export function createSynthesizedNode(kind: SyntaxKind, startsOnNewLine?: boolean): Node { + const node = createNode(kind, /*location*/ undefined); + node.startsOnNewLine = startsOnNewLine; + return node; + } - export function createSynthesizedNode(kind: SyntaxKind, startsOnNewLine?: boolean): Node { - const node = createNode(kind, /*location*/ undefined); - node.startsOnNewLine = startsOnNewLine; - return node; - } + export function createSynthesizedNodeArray(elements?: T[]): NodeArray { + return createNodeArray(elements, /*location*/ undefined); + } - export function createSynthesizedNodeArray(elements?: T[]): NodeArray { - return createNodeArray(elements, /*location*/ undefined); - } + /** + * Creates a shallow, memberwise clone of a node with no source map location. + */ + export function getSynthesizedClone(node: T): T { + // We don't use "clone" from core.ts here, as we need to preserve the prototype chain of + // 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 = createNode(node.kind, /*location*/ undefined, node.flags); + setOriginalNode(clone, node); - /** - * Creates a shallow, memberwise clone of a node with no source map location. - */ - export function getSynthesizedClone(node: T): T { - // We don't use "clone" from core.ts here, as we need to preserve the prototype chain of - // 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 = createNode(node.kind, /*location*/ undefined, node.flags); - setOriginalNode(clone, node); + for (const key in node) { + if (clone.hasOwnProperty(key) || !node.hasOwnProperty(key)) { + continue; + } - for (const key in node) { - if (clone.hasOwnProperty(key) || !node.hasOwnProperty(key)) { - continue; + (clone)[key] = (node)[key]; } - (clone)[key] = (node)[key]; + return clone; } - return clone; - } - - /** - * Creates a shallow, memberwise clone of a node for mutation. - */ - export function getMutableClone(node: T): T { - const clone = getSynthesizedClone(node); - clone.pos = node.pos; - clone.end = node.end; - clone.parent = node.parent; - return clone; - } - - // Literals - - export function createLiteral(textSource: StringLiteral | Identifier, location?: TextRange): StringLiteral; - export function createLiteral(value: string, location?: TextRange): StringLiteral; - export function createLiteral(value: number, location?: TextRange): NumericLiteral; - export function createLiteral(value: boolean, location?: TextRange): BooleanLiteral; - export function createLiteral(value: string | number | boolean, location?: TextRange): PrimaryExpression; - export function createLiteral(value: string | number | boolean | StringLiteral | Identifier, location?: TextRange): PrimaryExpression { - if (typeof value === "number") { - const node = createNode(SyntaxKind.NumericLiteral, location, /*flags*/ undefined); - node.text = value.toString(); - return node; - } - else if (typeof value === "boolean") { - return createNode(value ? SyntaxKind.TrueKeyword : SyntaxKind.FalseKeyword, location, /*flags*/ undefined); - } - else if (typeof value === "string") { - const node = createNode(SyntaxKind.StringLiteral, location, /*flags*/ undefined); - node.text = value; - return node; - } - else if (value) { - const node = createNode(SyntaxKind.StringLiteral, location, /*flags*/ undefined); - node.textSourceNode = value; - node.text = value.text; - return node; + /** + * Creates a shallow, memberwise clone of a node for mutation. + */ + export function getMutableClone(node: T): T { + const clone = getSynthesizedClone(node); + clone.pos = node.pos; + clone.end = node.end; + clone.parent = node.parent; + return clone; } - } - - // Identifiers - let nextAutoGenerateId = 0; + // Literals - export function createIdentifier(text: string, location?: TextRange): Identifier { - const node = createNode(SyntaxKind.Identifier, location); - node.text = escapeIdentifier(text); - node.originalKeywordKind = stringToToken(text); - node.autoGenerateKind = GeneratedIdentifierKind.None; - node.autoGenerateId = 0; - return node; - } + export function createLiteral(textSource: StringLiteral | Identifier, location?: TextRange): StringLiteral; + export function createLiteral(value: string, location?: TextRange): StringLiteral; + export function createLiteral(value: number, location?: TextRange): NumericLiteral; + export function createLiteral(value: boolean, location?: TextRange): BooleanLiteral; + export function createLiteral(value: string | number | boolean, location?: TextRange): PrimaryExpression; + export function createLiteral(value: string | number | boolean | StringLiteral | Identifier, location?: TextRange): PrimaryExpression { + if (typeof value === "number") { + const node = createNode(SyntaxKind.NumericLiteral, location, /*flags*/ undefined); + node.text = value.toString(); + return node; + } + else if (typeof value === "boolean") { + return createNode(value ? SyntaxKind.TrueKeyword : SyntaxKind.FalseKeyword, location, /*flags*/ undefined); + } + else if (typeof value === "string") { + const node = createNode(SyntaxKind.StringLiteral, location, /*flags*/ undefined); + node.text = value; + return node; + } + else if (value) { + const node = createNode(SyntaxKind.StringLiteral, location, /*flags*/ undefined); + node.textSourceNode = value; + node.text = value.text; + return node; + } + } - export function createTempVariable(recordTempVariable: ((node: Identifier) => void) | undefined, location?: TextRange): Identifier { - const name = createNode(SyntaxKind.Identifier, location); - name.text = ""; - name.originalKeywordKind = SyntaxKind.Unknown; - name.autoGenerateKind = GeneratedIdentifierKind.Auto; - name.autoGenerateId = nextAutoGenerateId; - nextAutoGenerateId++; - if (recordTempVariable) { - recordTempVariable(name); - } - return name; - } + // Identifiers - export function createLoopVariable(location?: TextRange): Identifier { - const name = createNode(SyntaxKind.Identifier, location); - name.text = ""; - name.originalKeywordKind = SyntaxKind.Unknown; - name.autoGenerateKind = GeneratedIdentifierKind.Loop; - name.autoGenerateId = nextAutoGenerateId; - nextAutoGenerateId++; - return name; - } + let nextAutoGenerateId = 0; - export function createUniqueName(text: string, location?: TextRange): Identifier { - const name = createNode(SyntaxKind.Identifier, location); - name.text = text; - name.originalKeywordKind = SyntaxKind.Unknown; - name.autoGenerateKind = GeneratedIdentifierKind.Unique; - name.autoGenerateId = nextAutoGenerateId; - nextAutoGenerateId++; - return name; - } + export function createIdentifier(text: string, location?: TextRange): Identifier { + const node = createNode(SyntaxKind.Identifier, location); + node.text = escapeIdentifier(text); + node.originalKeywordKind = stringToToken(text); + node.autoGenerateKind = GeneratedIdentifierKind.None; + node.autoGenerateId = 0; + return node; + } - export function getGeneratedNameForNode(node: Node, location?: TextRange): Identifier { - const name = createNode(SyntaxKind.Identifier, location); - name.original = node; - name.text = ""; - name.originalKeywordKind = SyntaxKind.Unknown; - name.autoGenerateKind = GeneratedIdentifierKind.Node; - name.autoGenerateId = nextAutoGenerateId; - nextAutoGenerateId++; - return name; - } + export function createTempVariable(recordTempVariable: ((node: Identifier) => void) | undefined, location?: TextRange): Identifier { + const name = createNode(SyntaxKind.Identifier, location); + name.text = ""; + name.originalKeywordKind = SyntaxKind.Unknown; + name.autoGenerateKind = GeneratedIdentifierKind.Auto; + name.autoGenerateId = nextAutoGenerateId; + nextAutoGenerateId++; + if (recordTempVariable) { + recordTempVariable(name); + } + return name; + } - // Punctuation + export function createLoopVariable(location?: TextRange): Identifier { + const name = createNode(SyntaxKind.Identifier, location); + name.text = ""; + name.originalKeywordKind = SyntaxKind.Unknown; + name.autoGenerateKind = GeneratedIdentifierKind.Loop; + name.autoGenerateId = nextAutoGenerateId; + nextAutoGenerateId++; + return name; + } - export function createToken(token: TKind) { - return >createNode(token); - } + export function createUniqueName(text: string, location?: TextRange): Identifier { + const name = createNode(SyntaxKind.Identifier, location); + name.text = text; + name.originalKeywordKind = SyntaxKind.Unknown; + name.autoGenerateKind = GeneratedIdentifierKind.Unique; + name.autoGenerateId = nextAutoGenerateId; + nextAutoGenerateId++; + return name; + } - // Reserved words + export function getGeneratedNameForNode(node: Node, location?: TextRange): Identifier { + const name = createNode(SyntaxKind.Identifier, location); + name.original = node; + name.text = ""; + name.originalKeywordKind = SyntaxKind.Unknown; + name.autoGenerateKind = GeneratedIdentifierKind.Node; + name.autoGenerateId = nextAutoGenerateId; + nextAutoGenerateId++; + return name; + } - export function createSuper() { - const node = createNode(SyntaxKind.SuperKeyword); - return node; - } + // Punctuation - export function createThis(location?: TextRange) { - const node = createNode(SyntaxKind.ThisKeyword, location); - return node; - } + export function createToken(token: TKind) { + return >createNode(token); + } - export function createNull() { - const node = createNode(SyntaxKind.NullKeyword); - return node; - } + // Reserved words - // Names + export function createSuper() { + const node = createNode(SyntaxKind.SuperKeyword); + return node; + } - export function createComputedPropertyName(expression: Expression, location?: TextRange) { - const node = createNode(SyntaxKind.ComputedPropertyName, location); - node.expression = expression; - return node; - } + export function createThis(location?: TextRange) { + const node = createNode(SyntaxKind.ThisKeyword, location); + return node; + } - export function updateComputedPropertyName(node: ComputedPropertyName, expression: Expression) { - if (node.expression !== expression) { - return updateNode(createComputedPropertyName(expression, node), node); + export function createNull() { + const node = createNode(SyntaxKind.NullKeyword); + return node; } - return node; - } - // Signature elements - - export function createParameter(name: string | Identifier | BindingPattern, initializer?: Expression, location?: TextRange) { - return createParameterDeclaration( - /*decorators*/ undefined, - /*modifiers*/ undefined, - /*dotDotDotToken*/ undefined, - name, - /*questionToken*/ undefined, - /*type*/ undefined, - initializer, - location - ); - } + // Names - export function createParameterDeclaration(decorators: Decorator[], modifiers: Modifier[], dotDotDotToken: DotDotDotToken, name: string | Identifier | BindingPattern, questionToken: QuestionToken, type: TypeNode, initializer: Expression, location?: TextRange, flags?: NodeFlags) { - const node = createNode(SyntaxKind.Parameter, location, flags); - node.decorators = decorators ? createNodeArray(decorators) : undefined; - node.modifiers = modifiers ? createNodeArray(modifiers) : undefined; - node.dotDotDotToken = dotDotDotToken; - node.name = typeof name === "string" ? createIdentifier(name) : name; - node.questionToken = questionToken; - node.type = type; - node.initializer = initializer ? parenthesizeExpressionForList(initializer) : undefined; - return node; - } + export function createComputedPropertyName(expression: Expression, location?: TextRange) { + const node = createNode(SyntaxKind.ComputedPropertyName, location); + node.expression = expression; + return node; + } - export function updateParameterDeclaration(node: ParameterDeclaration, decorators: Decorator[], modifiers: Modifier[], name: BindingName, type: TypeNode, initializer: Expression) { - if (node.decorators !== decorators || node.modifiers !== modifiers || node.name !== name || node.type !== type || node.initializer !== initializer) { - return updateNode(createParameterDeclaration(decorators, modifiers, node.dotDotDotToken, name, node.questionToken, type, initializer, /*location*/ node, /*flags*/ node.flags), node); + export function updateComputedPropertyName(node: ComputedPropertyName, expression: Expression) { + if (node.expression !== expression) { + return updateNode(createComputedPropertyName(expression, node), node); + } + return node; } - return node; - } + // Signature elements - // Type members - - export function createProperty(decorators: Decorator[], modifiers: Modifier[], name: string | PropertyName, questionToken: QuestionToken, type: TypeNode, initializer: Expression, location?: TextRange) { - const node = createNode(SyntaxKind.PropertyDeclaration, location); - node.decorators = decorators ? createNodeArray(decorators) : undefined; - node.modifiers = modifiers ? createNodeArray(modifiers) : undefined; - node.name = typeof name === "string" ? createIdentifier(name) : name; - node.questionToken = questionToken; - node.type = type; - node.initializer = initializer; - return node; - } + export function createParameter(name: string | Identifier | BindingPattern, initializer?: Expression, location?: TextRange) { + return createParameterDeclaration( + /*decorators*/ undefined, + /*modifiers*/ undefined, + /*dotDotDotToken*/ undefined, + name, + /*questionToken*/ undefined, + /*type*/ undefined, + initializer, + location + ); + } - export function updateProperty(node: PropertyDeclaration, decorators: Decorator[], modifiers: Modifier[], name: PropertyName, type: TypeNode, initializer: Expression) { - if (node.decorators !== decorators || node.modifiers !== modifiers || node.name !== name || node.type !== type || node.initializer !== initializer) { - return updateNode(createProperty(decorators, modifiers, name, node.questionToken, type, initializer, node), node); + export function createParameterDeclaration(decorators: Decorator[], modifiers: Modifier[], dotDotDotToken: DotDotDotToken, name: string | Identifier | BindingPattern, questionToken: QuestionToken, type: TypeNode, initializer: Expression, location?: TextRange, flags?: NodeFlags) { + const node = createNode(SyntaxKind.Parameter, location, flags); + node.decorators = decorators ? createNodeArray(decorators) : undefined; + node.modifiers = modifiers ? createNodeArray(modifiers) : undefined; + node.dotDotDotToken = dotDotDotToken; + node.name = typeof name === "string" ? createIdentifier(name) : name; + node.questionToken = questionToken; + node.type = type; + node.initializer = initializer ? parenthesizeExpressionForList(initializer) : undefined; + return node; } - return node; - } - export function createMethod(decorators: Decorator[], modifiers: Modifier[], asteriskToken: AsteriskToken, name: string | PropertyName, typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, body: Block, location?: TextRange, flags?: NodeFlags) { - const node = createNode(SyntaxKind.MethodDeclaration, location, flags); - node.decorators = decorators ? createNodeArray(decorators) : undefined; - node.modifiers = modifiers ? createNodeArray(modifiers) : undefined; - node.asteriskToken = asteriskToken; - node.name = typeof name === "string" ? createIdentifier(name) : name; - node.typeParameters = typeParameters ? createNodeArray(typeParameters) : undefined; - node.parameters = createNodeArray(parameters); - node.type = type; - node.body = body; - return node; - } + export function updateParameterDeclaration(node: ParameterDeclaration, decorators: Decorator[], modifiers: Modifier[], name: BindingName, type: TypeNode, initializer: Expression) { + if (node.decorators !== decorators || node.modifiers !== modifiers || node.name !== name || node.type !== type || node.initializer !== initializer) { + return updateNode(createParameterDeclaration(decorators, modifiers, node.dotDotDotToken, name, node.questionToken, type, initializer, /*location*/ node, /*flags*/ node.flags), node); + } - export function updateMethod(node: MethodDeclaration, decorators: Decorator[], modifiers: Modifier[], name: PropertyName, typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, body: Block) { - if (node.decorators !== decorators || node.modifiers !== modifiers || node.name !== name || node.typeParameters !== typeParameters || node.parameters !== parameters || node.type !== type || node.body !== body) { - return updateNode(createMethod(decorators, modifiers, node.asteriskToken, name, typeParameters, parameters, type, body, /*location*/ node, node.flags), node); + return node; } - return node; - } - export function createConstructor(decorators: Decorator[], modifiers: Modifier[], parameters: ParameterDeclaration[], body: Block, location?: TextRange, flags?: NodeFlags) { - const node = createNode(SyntaxKind.Constructor, location, flags); - node.decorators = decorators ? createNodeArray(decorators) : undefined; - node.modifiers = modifiers ? createNodeArray(modifiers) : undefined; - node.typeParameters = undefined; - node.parameters = createNodeArray(parameters); - node.type = undefined; - node.body = body; - return node; - } + // Type members - export function updateConstructor(node: ConstructorDeclaration, decorators: Decorator[], modifiers: Modifier[], parameters: ParameterDeclaration[], body: Block) { - if (node.decorators !== decorators || node.modifiers !== modifiers || node.parameters !== parameters || node.body !== body) { - return updateNode(createConstructor(decorators, modifiers, parameters, body, /*location*/ node, node.flags), node); + export function createProperty(decorators: Decorator[], modifiers: Modifier[], name: string | PropertyName, questionToken: QuestionToken, type: TypeNode, initializer: Expression, location?: TextRange) { + const node = createNode(SyntaxKind.PropertyDeclaration, location); + node.decorators = decorators ? createNodeArray(decorators) : undefined; + node.modifiers = modifiers ? createNodeArray(modifiers) : undefined; + node.name = typeof name === "string" ? createIdentifier(name) : name; + node.questionToken = questionToken; + node.type = type; + node.initializer = initializer; + return node; } - return node; - } - export function createGetAccessor(decorators: Decorator[], modifiers: Modifier[], name: string | PropertyName, parameters: ParameterDeclaration[], type: TypeNode, body: Block, location?: TextRange, flags?: NodeFlags) { - const node = createNode(SyntaxKind.GetAccessor, location, flags); - node.decorators = decorators ? createNodeArray(decorators) : undefined; - node.modifiers = modifiers ? createNodeArray(modifiers) : undefined; - node.name = typeof name === "string" ? createIdentifier(name) : name; - node.typeParameters = undefined; - node.parameters = createNodeArray(parameters); - node.type = type; - node.body = body; - return node; - } + export function updateProperty(node: PropertyDeclaration, decorators: Decorator[], modifiers: Modifier[], name: PropertyName, type: TypeNode, initializer: Expression) { + if (node.decorators !== decorators || node.modifiers !== modifiers || node.name !== name || node.type !== type || node.initializer !== initializer) { + return updateNode(createProperty(decorators, modifiers, name, node.questionToken, type, initializer, node), node); + } + return node; + } - export function updateGetAccessor(node: GetAccessorDeclaration, decorators: Decorator[], modifiers: Modifier[], name: PropertyName, parameters: ParameterDeclaration[], type: TypeNode, body: Block) { - if (node.decorators !== decorators || node.modifiers !== modifiers || node.name !== name || node.parameters !== parameters || node.type !== type || node.body !== body) { - return updateNode(createGetAccessor(decorators, modifiers, name, parameters, type, body, /*location*/ node, node.flags), node); + export function createMethod(decorators: Decorator[], modifiers: Modifier[], asteriskToken: AsteriskToken, name: string | PropertyName, typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, body: Block, location?: TextRange, flags?: NodeFlags) { + const node = createNode(SyntaxKind.MethodDeclaration, location, flags); + node.decorators = decorators ? createNodeArray(decorators) : undefined; + node.modifiers = modifiers ? createNodeArray(modifiers) : undefined; + node.asteriskToken = asteriskToken; + node.name = typeof name === "string" ? createIdentifier(name) : name; + node.typeParameters = typeParameters ? createNodeArray(typeParameters) : undefined; + node.parameters = createNodeArray(parameters); + node.type = type; + node.body = body; + return node; } - return node; - } - export function createSetAccessor(decorators: Decorator[], modifiers: Modifier[], name: string | PropertyName, parameters: ParameterDeclaration[], body: Block, location?: TextRange, flags?: NodeFlags) { - const node = createNode(SyntaxKind.SetAccessor, location, flags); - node.decorators = decorators ? createNodeArray(decorators) : undefined; - node.modifiers = modifiers ? createNodeArray(modifiers) : undefined; - node.name = typeof name === "string" ? createIdentifier(name) : name; - node.typeParameters = undefined; - node.parameters = createNodeArray(parameters); - node.body = body; - return node; - } + export function updateMethod(node: MethodDeclaration, decorators: Decorator[], modifiers: Modifier[], name: PropertyName, typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, body: Block) { + if (node.decorators !== decorators || node.modifiers !== modifiers || node.name !== name || node.typeParameters !== typeParameters || node.parameters !== parameters || node.type !== type || node.body !== body) { + return updateNode(createMethod(decorators, modifiers, node.asteriskToken, name, typeParameters, parameters, type, body, /*location*/ node, node.flags), node); + } + return node; + } - export function updateSetAccessor(node: SetAccessorDeclaration, decorators: Decorator[], modifiers: Modifier[], name: PropertyName, parameters: ParameterDeclaration[], body: Block) { - if (node.decorators !== decorators || node.modifiers !== modifiers || node.name !== name || node.parameters !== parameters || node.body !== body) { - return updateNode(createSetAccessor(decorators, modifiers, name, parameters, body, /*location*/ node, node.flags), node); + export function createConstructor(decorators: Decorator[], modifiers: Modifier[], parameters: ParameterDeclaration[], body: Block, location?: TextRange, flags?: NodeFlags) { + const node = createNode(SyntaxKind.Constructor, location, flags); + node.decorators = decorators ? createNodeArray(decorators) : undefined; + node.modifiers = modifiers ? createNodeArray(modifiers) : undefined; + node.typeParameters = undefined; + node.parameters = createNodeArray(parameters); + node.type = undefined; + node.body = body; + return node; } - return node; - } - // Binding Patterns + export function updateConstructor(node: ConstructorDeclaration, decorators: Decorator[], modifiers: Modifier[], parameters: ParameterDeclaration[], body: Block) { + if (node.decorators !== decorators || node.modifiers !== modifiers || node.parameters !== parameters || node.body !== body) { + return updateNode(createConstructor(decorators, modifiers, parameters, body, /*location*/ node, node.flags), node); + } + return node; + } - export function createObjectBindingPattern(elements: BindingElement[], location?: TextRange) { - const node = createNode(SyntaxKind.ObjectBindingPattern, location); - node.elements = createNodeArray(elements); - return node; - } + export function createGetAccessor(decorators: Decorator[], modifiers: Modifier[], name: string | PropertyName, parameters: ParameterDeclaration[], type: TypeNode, body: Block, location?: TextRange, flags?: NodeFlags) { + const node = createNode(SyntaxKind.GetAccessor, location, flags); + node.decorators = decorators ? createNodeArray(decorators) : undefined; + node.modifiers = modifiers ? createNodeArray(modifiers) : undefined; + node.name = typeof name === "string" ? createIdentifier(name) : name; + node.typeParameters = undefined; + node.parameters = createNodeArray(parameters); + node.type = type; + node.body = body; + return node; + } - export function updateObjectBindingPattern(node: ObjectBindingPattern, elements: BindingElement[]) { - if (node.elements !== elements) { - return updateNode(createObjectBindingPattern(elements, node), node); + export function updateGetAccessor(node: GetAccessorDeclaration, decorators: Decorator[], modifiers: Modifier[], name: PropertyName, parameters: ParameterDeclaration[], type: TypeNode, body: Block) { + if (node.decorators !== decorators || node.modifiers !== modifiers || node.name !== name || node.parameters !== parameters || node.type !== type || node.body !== body) { + return updateNode(createGetAccessor(decorators, modifiers, name, parameters, type, body, /*location*/ node, node.flags), node); + } + return node; } - return node; - } - export function createArrayBindingPattern(elements: ArrayBindingElement[], location?: TextRange) { - const node = createNode(SyntaxKind.ArrayBindingPattern, location); - node.elements = createNodeArray(elements); - return node; - } + export function createSetAccessor(decorators: Decorator[], modifiers: Modifier[], name: string | PropertyName, parameters: ParameterDeclaration[], body: Block, location?: TextRange, flags?: NodeFlags) { + const node = createNode(SyntaxKind.SetAccessor, location, flags); + node.decorators = decorators ? createNodeArray(decorators) : undefined; + node.modifiers = modifiers ? createNodeArray(modifiers) : undefined; + node.name = typeof name === "string" ? createIdentifier(name) : name; + node.typeParameters = undefined; + node.parameters = createNodeArray(parameters); + node.body = body; + return node; + } - export function updateArrayBindingPattern(node: ArrayBindingPattern, elements: ArrayBindingElement[]) { - if (node.elements !== elements) { - return updateNode(createArrayBindingPattern(elements, node), node); + export function updateSetAccessor(node: SetAccessorDeclaration, decorators: Decorator[], modifiers: Modifier[], name: PropertyName, parameters: ParameterDeclaration[], body: Block) { + if (node.decorators !== decorators || node.modifiers !== modifiers || node.name !== name || node.parameters !== parameters || node.body !== body) { + return updateNode(createSetAccessor(decorators, modifiers, name, parameters, body, /*location*/ node, node.flags), node); + } + return node; } - return node; - } - export function createBindingElement(propertyName: string | PropertyName, dotDotDotToken: DotDotDotToken, name: string | BindingName, initializer?: Expression, location?: TextRange) { - const node = createNode(SyntaxKind.BindingElement, location); - node.propertyName = typeof propertyName === "string" ? createIdentifier(propertyName) : propertyName; - node.dotDotDotToken = dotDotDotToken; - node.name = typeof name === "string" ? createIdentifier(name) : name; - node.initializer = initializer; - return node; - } + // Binding Patterns - export function updateBindingElement(node: BindingElement, propertyName: PropertyName, name: BindingName, initializer: Expression) { - if (node.propertyName !== propertyName || node.name !== name || node.initializer !== initializer) { - return updateNode(createBindingElement(propertyName, node.dotDotDotToken, name, initializer, node), node); + export function createObjectBindingPattern(elements: BindingElement[], location?: TextRange) { + const node = createNode(SyntaxKind.ObjectBindingPattern, location); + node.elements = createNodeArray(elements); + return node; } - return node; - } - - // Expression - export function createArrayLiteral(elements?: Expression[], location?: TextRange, multiLine?: boolean) { - const node = createNode(SyntaxKind.ArrayLiteralExpression, location); - node.elements = parenthesizeListElements(createNodeArray(elements)); - if (multiLine) { - node.multiLine = true; + export function updateObjectBindingPattern(node: ObjectBindingPattern, elements: BindingElement[]) { + if (node.elements !== elements) { + return updateNode(createObjectBindingPattern(elements, node), node); + } + return node; } - return node; - } + export function createArrayBindingPattern(elements: ArrayBindingElement[], location?: TextRange) { + const node = createNode(SyntaxKind.ArrayBindingPattern, location); + node.elements = createNodeArray(elements); + return node; + } - export function updateArrayLiteral(node: ArrayLiteralExpression, elements: Expression[]) { - if (node.elements !== elements) { - return updateNode(createArrayLiteral(elements, node, node.multiLine), node); + export function updateArrayBindingPattern(node: ArrayBindingPattern, elements: ArrayBindingElement[]) { + if (node.elements !== elements) { + return updateNode(createArrayBindingPattern(elements, node), node); + } + return node; } - return node; - } - export function createObjectLiteral(properties?: ObjectLiteralElementLike[], location?: TextRange, multiLine?: boolean) { - const node = createNode(SyntaxKind.ObjectLiteralExpression, location); - node.properties = createNodeArray(properties); - if (multiLine) { - node.multiLine = true; + export function createBindingElement(propertyName: string | PropertyName, dotDotDotToken: DotDotDotToken, name: string | BindingName, initializer?: Expression, location?: TextRange) { + const node = createNode(SyntaxKind.BindingElement, location); + node.propertyName = typeof propertyName === "string" ? createIdentifier(propertyName) : propertyName; + node.dotDotDotToken = dotDotDotToken; + node.name = typeof name === "string" ? createIdentifier(name) : name; + node.initializer = initializer; + return node; } - return node; - } - export function updateObjectLiteral(node: ObjectLiteralExpression, properties: ObjectLiteralElementLike[]) { - if (node.properties !== properties) { - return updateNode(createObjectLiteral(properties, node, node.multiLine), node); + export function updateBindingElement(node: BindingElement, propertyName: PropertyName, name: BindingName, initializer: Expression) { + if (node.propertyName !== propertyName || node.name !== name || node.initializer !== initializer) { + return updateNode(createBindingElement(propertyName, node.dotDotDotToken, name, initializer, node), node); + } + return node; } - return node; - } - export function createPropertyAccess(expression: Expression, name: string | Identifier, location?: TextRange, flags?: NodeFlags) { - const node = createNode(SyntaxKind.PropertyAccessExpression, location, flags); - node.expression = parenthesizeForAccess(expression); - (node.emitNode || (node.emitNode = {})).flags |= EmitFlags.NoIndentation; - node.name = typeof name === "string" ? createIdentifier(name) : name; - return node; - } + // Expression - export function updatePropertyAccess(node: PropertyAccessExpression, expression: Expression, name: Identifier) { - 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.emitNode || (propertyAccess.emitNode = {})).flags = getEmitFlags(node); - return updateNode(propertyAccess, node); + export function createArrayLiteral(elements?: Expression[], location?: TextRange, multiLine?: boolean) { + const node = createNode(SyntaxKind.ArrayLiteralExpression, location); + node.elements = parenthesizeListElements(createNodeArray(elements)); + if (multiLine) { + node.multiLine = true; + } + + return node; } - return node; - } - export function createElementAccess(expression: Expression, index: number | Expression, location?: TextRange) { - const node = createNode(SyntaxKind.ElementAccessExpression, location); - node.expression = parenthesizeForAccess(expression); - node.argumentExpression = typeof index === "number" ? createLiteral(index) : index; - return node; - } + export function updateArrayLiteral(node: ArrayLiteralExpression, elements: Expression[]) { + if (node.elements !== elements) { + return updateNode(createArrayLiteral(elements, node, node.multiLine), node); + } + return node; + } - export function updateElementAccess(node: ElementAccessExpression, expression: Expression, argumentExpression: Expression) { - if (node.expression !== expression || node.argumentExpression !== argumentExpression) { - return updateNode(createElementAccess(expression, argumentExpression, node), node); + export function createObjectLiteral(properties?: ObjectLiteralElementLike[], location?: TextRange, multiLine?: boolean) { + const node = createNode(SyntaxKind.ObjectLiteralExpression, location); + node.properties = createNodeArray(properties); + if (multiLine) { + node.multiLine = true; + } + return node; } - return node; - } - export function createCall(expression: Expression, typeArguments: TypeNode[], argumentsArray: Expression[], location?: TextRange, flags?: NodeFlags) { - const node = createNode(SyntaxKind.CallExpression, location, flags); - node.expression = parenthesizeForAccess(expression); - if (typeArguments) { - node.typeArguments = createNodeArray(typeArguments); + export function updateObjectLiteral(node: ObjectLiteralExpression, properties: ObjectLiteralElementLike[]) { + if (node.properties !== properties) { + return updateNode(createObjectLiteral(properties, node, node.multiLine), node); + } + return node; } - node.arguments = parenthesizeListElements(createNodeArray(argumentsArray)); - return node; - } + export function createPropertyAccess(expression: Expression, name: string | Identifier, location?: TextRange, flags?: NodeFlags) { + const node = createNode(SyntaxKind.PropertyAccessExpression, location, flags); + node.expression = parenthesizeForAccess(expression); + (node.emitNode || (node.emitNode = {})).flags |= EmitFlags.NoIndentation; + node.name = typeof name === "string" ? createIdentifier(name) : name; + return node; + } - export function updateCall(node: CallExpression, expression: Expression, typeArguments: TypeNode[], argumentsArray: Expression[]) { - if (expression !== node.expression || typeArguments !== node.typeArguments || argumentsArray !== node.arguments) { - return updateNode(createCall(expression, typeArguments, argumentsArray, /*location*/ node, node.flags), node); + export function updatePropertyAccess(node: PropertyAccessExpression, expression: Expression, name: Identifier) { + 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.emitNode || (propertyAccess.emitNode = {})).flags = getEmitFlags(node); + return updateNode(propertyAccess, node); + } + return node; } - return node; - } - export function createNew(expression: Expression, typeArguments: TypeNode[], argumentsArray: Expression[], location?: TextRange, flags?: NodeFlags) { - const node = createNode(SyntaxKind.NewExpression, location, flags); - node.expression = parenthesizeForNew(expression); - node.typeArguments = typeArguments ? createNodeArray(typeArguments) : undefined; - node.arguments = argumentsArray ? parenthesizeListElements(createNodeArray(argumentsArray)) : undefined; - return node; - } + export function createElementAccess(expression: Expression, index: number | Expression, location?: TextRange) { + const node = createNode(SyntaxKind.ElementAccessExpression, location); + node.expression = parenthesizeForAccess(expression); + node.argumentExpression = typeof index === "number" ? createLiteral(index) : index; + return node; + } - export function updateNew(node: NewExpression, expression: Expression, typeArguments: TypeNode[], argumentsArray: Expression[]) { - if (node.expression !== expression || node.typeArguments !== typeArguments || node.arguments !== argumentsArray) { - return updateNode(createNew(expression, typeArguments, argumentsArray, /*location*/ node, node.flags), node); + export function updateElementAccess(node: ElementAccessExpression, expression: Expression, argumentExpression: Expression) { + if (node.expression !== expression || node.argumentExpression !== argumentExpression) { + return updateNode(createElementAccess(expression, argumentExpression, node), node); + } + return node; } - return node; - } - export function createTaggedTemplate(tag: Expression, template: TemplateLiteral, location?: TextRange) { - const node = createNode(SyntaxKind.TaggedTemplateExpression, location); - node.tag = parenthesizeForAccess(tag); - node.template = template; - return node; - } + export function createCall(expression: Expression, typeArguments: TypeNode[], argumentsArray: Expression[], location?: TextRange, flags?: NodeFlags) { + const node = createNode(SyntaxKind.CallExpression, location, flags); + node.expression = parenthesizeForAccess(expression); + if (typeArguments) { + node.typeArguments = createNodeArray(typeArguments); + } - export function updateTaggedTemplate(node: TaggedTemplateExpression, tag: Expression, template: TemplateLiteral) { - if (node.tag !== tag || node.template !== template) { - return updateNode(createTaggedTemplate(tag, template, node), node); + node.arguments = parenthesizeListElements(createNodeArray(argumentsArray)); + return node; } - return node; - } - export function createParen(expression: Expression, location?: TextRange) { - const node = createNode(SyntaxKind.ParenthesizedExpression, location); - node.expression = expression; - return node; - } + export function updateCall(node: CallExpression, expression: Expression, typeArguments: TypeNode[], argumentsArray: Expression[]) { + if (expression !== node.expression || typeArguments !== node.typeArguments || argumentsArray !== node.arguments) { + return updateNode(createCall(expression, typeArguments, argumentsArray, /*location*/ node, node.flags), node); + } + return node; + } - export function updateParen(node: ParenthesizedExpression, expression: Expression) { - if (node.expression !== expression) { - return updateNode(createParen(expression, node), node); + export function createNew(expression: Expression, typeArguments: TypeNode[], argumentsArray: Expression[], location?: TextRange, flags?: NodeFlags) { + const node = createNode(SyntaxKind.NewExpression, location, flags); + node.expression = parenthesizeForNew(expression); + node.typeArguments = typeArguments ? createNodeArray(typeArguments) : undefined; + node.arguments = argumentsArray ? parenthesizeListElements(createNodeArray(argumentsArray)) : undefined; + return node; } - return node; - } - export function createFunctionExpression(asteriskToken: AsteriskToken, name: string | Identifier, typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, body: Block, location?: TextRange, flags?: NodeFlags) { - const node = createNode(SyntaxKind.FunctionExpression, location, flags); - node.modifiers = undefined; - node.asteriskToken = asteriskToken; - node.name = typeof name === "string" ? createIdentifier(name) : name; - node.typeParameters = typeParameters ? createNodeArray(typeParameters) : undefined; - node.parameters = createNodeArray(parameters); - node.type = type; - node.body = body; - return node; - } + export function updateNew(node: NewExpression, expression: Expression, typeArguments: TypeNode[], argumentsArray: Expression[]) { + if (node.expression !== expression || node.typeArguments !== typeArguments || node.arguments !== argumentsArray) { + return updateNode(createNew(expression, typeArguments, argumentsArray, /*location*/ node, node.flags), node); + } + return node; + } - export function updateFunctionExpression(node: FunctionExpression, name: Identifier, typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, body: Block) { - if (node.name !== name || node.typeParameters !== typeParameters || node.parameters !== parameters || node.type !== type || node.body !== body) { - return updateNode(createFunctionExpression(node.asteriskToken, name, typeParameters, parameters, type, body, /*location*/ node, node.flags), node); + export function createTaggedTemplate(tag: Expression, template: TemplateLiteral, location?: TextRange) { + const node = createNode(SyntaxKind.TaggedTemplateExpression, location); + node.tag = parenthesizeForAccess(tag); + node.template = template; + return node; } - return node; - } - export function createArrowFunction(modifiers: Modifier[], typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, equalsGreaterThanToken: EqualsGreaterThanToken, body: ConciseBody, location?: TextRange, flags?: NodeFlags) { - const node = createNode(SyntaxKind.ArrowFunction, location, flags); - node.modifiers = modifiers ? createNodeArray(modifiers) : undefined; - node.typeParameters = typeParameters ? createNodeArray(typeParameters) : undefined; - node.parameters = createNodeArray(parameters); - node.type = type; - node.equalsGreaterThanToken = equalsGreaterThanToken || createToken(SyntaxKind.EqualsGreaterThanToken); - node.body = parenthesizeConciseBody(body); - return node; - } + export function updateTaggedTemplate(node: TaggedTemplateExpression, tag: Expression, template: TemplateLiteral) { + if (node.tag !== tag || node.template !== template) { + return updateNode(createTaggedTemplate(tag, template, node), node); + } + return node; + } - export function updateArrowFunction(node: ArrowFunction, modifiers: Modifier[], typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, body: ConciseBody) { - if (node.modifiers !== modifiers || node.typeParameters !== typeParameters || node.parameters !== parameters || node.type !== type || node.body !== body) { - return updateNode(createArrowFunction(modifiers, typeParameters, parameters, type, node.equalsGreaterThanToken, body, /*location*/ node, node.flags), node); + export function createParen(expression: Expression, location?: TextRange) { + const node = createNode(SyntaxKind.ParenthesizedExpression, location); + node.expression = expression; + return node; } - return node; - } - export function createDelete(expression: Expression, location?: TextRange) { - const node = createNode(SyntaxKind.DeleteExpression, location); - node.expression = parenthesizePrefixOperand(expression); - return node; - } + export function updateParen(node: ParenthesizedExpression, expression: Expression) { + if (node.expression !== expression) { + return updateNode(createParen(expression, node), node); + } + return node; + } - export function updateDelete(node: DeleteExpression, expression: Expression) { - if (node.expression !== expression) { - return updateNode(createDelete(expression, node), expression); + export function createFunctionExpression(asteriskToken: AsteriskToken, name: string | Identifier, typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, body: Block, location?: TextRange, flags?: NodeFlags) { + const node = createNode(SyntaxKind.FunctionExpression, location, flags); + node.modifiers = undefined; + node.asteriskToken = asteriskToken; + node.name = typeof name === "string" ? createIdentifier(name) : name; + node.typeParameters = typeParameters ? createNodeArray(typeParameters) : undefined; + node.parameters = createNodeArray(parameters); + node.type = type; + node.body = body; + return node; } - return node; - } - export function createTypeOf(expression: Expression, location?: TextRange) { - const node = createNode(SyntaxKind.TypeOfExpression, location); - node.expression = parenthesizePrefixOperand(expression); - return node; - } + export function updateFunctionExpression(node: FunctionExpression, name: Identifier, typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, body: Block) { + if (node.name !== name || node.typeParameters !== typeParameters || node.parameters !== parameters || node.type !== type || node.body !== body) { + return updateNode(createFunctionExpression(node.asteriskToken, name, typeParameters, parameters, type, body, /*location*/ node, node.flags), node); + } + return node; + } - export function updateTypeOf(node: TypeOfExpression, expression: Expression) { - if (node.expression !== expression) { - return updateNode(createTypeOf(expression, node), expression); + export function createArrowFunction(modifiers: Modifier[], typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, equalsGreaterThanToken: EqualsGreaterThanToken, body: ConciseBody, location?: TextRange, flags?: NodeFlags) { + const node = createNode(SyntaxKind.ArrowFunction, location, flags); + node.modifiers = modifiers ? createNodeArray(modifiers) : undefined; + node.typeParameters = typeParameters ? createNodeArray(typeParameters) : undefined; + node.parameters = createNodeArray(parameters); + node.type = type; + node.equalsGreaterThanToken = equalsGreaterThanToken || createToken(SyntaxKind.EqualsGreaterThanToken); + node.body = parenthesizeConciseBody(body); + return node; } - return node; - } - export function createVoid(expression: Expression, location?: TextRange) { - const node = createNode(SyntaxKind.VoidExpression, location); - node.expression = parenthesizePrefixOperand(expression); - return node; - } + export function updateArrowFunction(node: ArrowFunction, modifiers: Modifier[], typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, body: ConciseBody) { + if (node.modifiers !== modifiers || node.typeParameters !== typeParameters || node.parameters !== parameters || node.type !== type || node.body !== body) { + return updateNode(createArrowFunction(modifiers, typeParameters, parameters, type, node.equalsGreaterThanToken, body, /*location*/ node, node.flags), node); + } + return node; + } - export function updateVoid(node: VoidExpression, expression: Expression) { - if (node.expression !== expression) { - return updateNode(createVoid(expression, node), node); + export function createDelete(expression: Expression, location?: TextRange) { + const node = createNode(SyntaxKind.DeleteExpression, location); + node.expression = parenthesizePrefixOperand(expression); + return node; } - return node; - } - export function createAwait(expression: Expression, location?: TextRange) { - const node = createNode(SyntaxKind.AwaitExpression, location); - node.expression = parenthesizePrefixOperand(expression); - return node; - } + export function updateDelete(node: DeleteExpression, expression: Expression) { + if (node.expression !== expression) { + return updateNode(createDelete(expression, node), expression); + } + return node; + } - export function updateAwait(node: AwaitExpression, expression: Expression) { - if (node.expression !== expression) { - return updateNode(createAwait(expression, node), node); + export function createTypeOf(expression: Expression, location?: TextRange) { + const node = createNode(SyntaxKind.TypeOfExpression, location); + node.expression = parenthesizePrefixOperand(expression); + return node; } - return node; - } - export function createPrefix(operator: PrefixUnaryOperator, operand: Expression, location?: TextRange) { - const node = createNode(SyntaxKind.PrefixUnaryExpression, location); - node.operator = operator; - node.operand = parenthesizePrefixOperand(operand); - return node; - } + export function updateTypeOf(node: TypeOfExpression, expression: Expression) { + if (node.expression !== expression) { + return updateNode(createTypeOf(expression, node), expression); + } + return node; + } - export function updatePrefix(node: PrefixUnaryExpression, operand: Expression) { - if (node.operand !== operand) { - return updateNode(createPrefix(node.operator, operand, node), node); + export function createVoid(expression: Expression, location?: TextRange) { + const node = createNode(SyntaxKind.VoidExpression, location); + node.expression = parenthesizePrefixOperand(expression); + return node; } - return node; - } - export function createPostfix(operand: Expression, operator: PostfixUnaryOperator, location?: TextRange) { - const node = createNode(SyntaxKind.PostfixUnaryExpression, location); - node.operand = parenthesizePostfixOperand(operand); - node.operator = operator; - return node; - } + export function updateVoid(node: VoidExpression, expression: Expression) { + if (node.expression !== expression) { + return updateNode(createVoid(expression, node), node); + } + return node; + } - export function updatePostfix(node: PostfixUnaryExpression, operand: Expression) { - if (node.operand !== operand) { - return updateNode(createPostfix(operand, node.operator, node), node); + export function createAwait(expression: Expression, location?: TextRange) { + const node = createNode(SyntaxKind.AwaitExpression, location); + node.expression = parenthesizePrefixOperand(expression); + return node; } - return node; - } - export function createBinary(left: Expression, operator: BinaryOperator | BinaryOperatorToken, right: Expression, location?: TextRange) { - const operatorToken = typeof operator === "number" ? createToken(operator) : operator; - const operatorKind = operatorToken.kind; - const node = createNode(SyntaxKind.BinaryExpression, location); - node.left = parenthesizeBinaryOperand(operatorKind, left, /*isLeftSideOfBinary*/ true, /*leftOperand*/ undefined); - node.operatorToken = operatorToken; - node.right = parenthesizeBinaryOperand(operatorKind, right, /*isLeftSideOfBinary*/ false, node.left); - return node; - } + export function updateAwait(node: AwaitExpression, expression: Expression) { + if (node.expression !== expression) { + return updateNode(createAwait(expression, node), node); + } + return node; + } - export function updateBinary(node: BinaryExpression, left: Expression, right: Expression) { - if (node.left !== left || node.right !== right) { - return updateNode(createBinary(left, node.operatorToken, right, /*location*/ node), node); + export function createPrefix(operator: PrefixUnaryOperator, operand: Expression, location?: TextRange) { + const node = createNode(SyntaxKind.PrefixUnaryExpression, location); + node.operator = operator; + node.operand = parenthesizePrefixOperand(operand); + return node; } - return node; - } - export function createConditional(condition: Expression, questionToken: QuestionToken, whenTrue: Expression, colonToken: ColonToken, whenFalse: Expression, location?: TextRange) { - const node = createNode(SyntaxKind.ConditionalExpression, location); - node.condition = condition; - node.questionToken = questionToken; - node.whenTrue = whenTrue; - node.colonToken = colonToken; - node.whenFalse = whenFalse; - return node; - } + export function updatePrefix(node: PrefixUnaryExpression, operand: Expression) { + if (node.operand !== operand) { + return updateNode(createPrefix(node.operator, operand, node), node); + } + return node; + } - export function updateConditional(node: ConditionalExpression, condition: Expression, whenTrue: Expression, whenFalse: Expression) { - if (node.condition !== condition || node.whenTrue !== whenTrue || node.whenFalse !== whenFalse) { - return updateNode(createConditional(condition, node.questionToken, whenTrue, node.colonToken, whenFalse, node), node); + export function createPostfix(operand: Expression, operator: PostfixUnaryOperator, location?: TextRange) { + const node = createNode(SyntaxKind.PostfixUnaryExpression, location); + node.operand = parenthesizePostfixOperand(operand); + node.operator = operator; + return node; } - return node; - } - export function createTemplateExpression(head: TemplateHead, templateSpans: TemplateSpan[], location?: TextRange) { - const node = createNode(SyntaxKind.TemplateExpression, location); - node.head = head; - node.templateSpans = createNodeArray(templateSpans); - return node; - } + export function updatePostfix(node: PostfixUnaryExpression, operand: Expression) { + if (node.operand !== operand) { + return updateNode(createPostfix(operand, node.operator, node), node); + } + return node; + } - export function updateTemplateExpression(node: TemplateExpression, head: TemplateHead, templateSpans: TemplateSpan[]) { - if (node.head !== head || node.templateSpans !== templateSpans) { - return updateNode(createTemplateExpression(head, templateSpans, node), node); + export function createBinary(left: Expression, operator: BinaryOperator | BinaryOperatorToken, right: Expression, location?: TextRange) { + const operatorToken = typeof operator === "number" ? createToken(operator) : operator; + const operatorKind = operatorToken.kind; + const node = createNode(SyntaxKind.BinaryExpression, location); + node.left = parenthesizeBinaryOperand(operatorKind, left, /*isLeftSideOfBinary*/ true, /*leftOperand*/ undefined); + node.operatorToken = operatorToken; + node.right = parenthesizeBinaryOperand(operatorKind, right, /*isLeftSideOfBinary*/ false, node.left); + return node; } - return node; - } - export function createYield(asteriskToken: AsteriskToken, expression: Expression, location?: TextRange) { - const node = createNode(SyntaxKind.YieldExpression, location); - node.asteriskToken = asteriskToken; - node.expression = expression; - return node; - } + export function updateBinary(node: BinaryExpression, left: Expression, right: Expression) { + if (node.left !== left || node.right !== right) { + return updateNode(createBinary(left, node.operatorToken, right, /*location*/ node), node); + } + return node; + } - export function updateYield(node: YieldExpression, expression: Expression) { - if (node.expression !== expression) { - return updateNode(createYield(node.asteriskToken, expression, node), node); + export function createConditional(condition: Expression, questionToken: QuestionToken, whenTrue: Expression, colonToken: ColonToken, whenFalse: Expression, location?: TextRange) { + const node = createNode(SyntaxKind.ConditionalExpression, location); + node.condition = condition; + node.questionToken = questionToken; + node.whenTrue = whenTrue; + node.colonToken = colonToken; + node.whenFalse = whenFalse; + return node; } - return node; - } - export function createSpread(expression: Expression, location?: TextRange) { - const node = createNode(SyntaxKind.SpreadElementExpression, location); - node.expression = parenthesizeExpressionForList(expression); - return node; - } + export function updateConditional(node: ConditionalExpression, condition: Expression, whenTrue: Expression, whenFalse: Expression) { + if (node.condition !== condition || node.whenTrue !== whenTrue || node.whenFalse !== whenFalse) { + return updateNode(createConditional(condition, node.questionToken, whenTrue, node.colonToken, whenFalse, node), node); + } + return node; + } - export function updateSpread(node: SpreadElementExpression, expression: Expression) { - if (node.expression !== expression) { - return updateNode(createSpread(expression, node), node); + export function createTemplateExpression(head: TemplateHead, templateSpans: TemplateSpan[], location?: TextRange) { + const node = createNode(SyntaxKind.TemplateExpression, location); + node.head = head; + node.templateSpans = createNodeArray(templateSpans); + return node; } - return node; - } - export function createClassExpression(modifiers: Modifier[], name: Identifier, typeParameters: TypeParameterDeclaration[], heritageClauses: HeritageClause[], members: ClassElement[], location?: TextRange) { - const node = createNode(SyntaxKind.ClassExpression, location); - node.decorators = undefined; - node.modifiers = modifiers ? createNodeArray(modifiers) : undefined; - node.name = name; - node.typeParameters = typeParameters ? createNodeArray(typeParameters) : undefined; - node.heritageClauses = createNodeArray(heritageClauses); - node.members = createNodeArray(members); - return node; - } + export function updateTemplateExpression(node: TemplateExpression, head: TemplateHead, templateSpans: TemplateSpan[]) { + if (node.head !== head || node.templateSpans !== templateSpans) { + return updateNode(createTemplateExpression(head, templateSpans, node), node); + } + return node; + } - export function updateClassExpression(node: ClassExpression, modifiers: Modifier[], name: Identifier, typeParameters: TypeParameterDeclaration[], heritageClauses: HeritageClause[], members: ClassElement[]) { - if (node.modifiers !== modifiers || node.name !== name || node.typeParameters !== typeParameters || node.heritageClauses !== heritageClauses || node.members !== members) { - return updateNode(createClassExpression(modifiers, name, typeParameters, heritageClauses, members, node), node); + export function createYield(asteriskToken: AsteriskToken, expression: Expression, location?: TextRange) { + const node = createNode(SyntaxKind.YieldExpression, location); + node.asteriskToken = asteriskToken; + node.expression = expression; + return node; } - return node; - } - export function createOmittedExpression(location?: TextRange) { - const node = createNode(SyntaxKind.OmittedExpression, location); - return node; - } - - export function createExpressionWithTypeArguments(typeArguments: TypeNode[], expression: Expression, location?: TextRange) { - const node = createNode(SyntaxKind.ExpressionWithTypeArguments, location); - node.typeArguments = typeArguments ? createNodeArray(typeArguments) : undefined; - node.expression = parenthesizeForAccess(expression); - return node; - } - - export function updateExpressionWithTypeArguments(node: ExpressionWithTypeArguments, typeArguments: TypeNode[], expression: Expression) { - if (node.typeArguments !== typeArguments || node.expression !== expression) { - return updateNode(createExpressionWithTypeArguments(typeArguments, expression, node), node); + export function updateYield(node: YieldExpression, expression: Expression) { + if (node.expression !== expression) { + return updateNode(createYield(node.asteriskToken, expression, node), node); + } + return node; } - return node; - } + export function createSpread(expression: Expression, location?: TextRange) { + const node = createNode(SyntaxKind.SpreadElementExpression, location); + node.expression = parenthesizeExpressionForList(expression); + return node; + } - // Misc + export function updateSpread(node: SpreadElementExpression, expression: Expression) { + if (node.expression !== expression) { + return updateNode(createSpread(expression, node), node); + } + return node; + } - export function createTemplateSpan(expression: Expression, literal: TemplateMiddle | TemplateTail, location?: TextRange) { - const node = createNode(SyntaxKind.TemplateSpan, location); - node.expression = expression; - node.literal = literal; - return node; - } + export function createClassExpression(modifiers: Modifier[], name: Identifier, typeParameters: TypeParameterDeclaration[], heritageClauses: HeritageClause[], members: ClassElement[], location?: TextRange) { + const node = createNode(SyntaxKind.ClassExpression, location); + node.decorators = undefined; + node.modifiers = modifiers ? createNodeArray(modifiers) : undefined; + node.name = name; + node.typeParameters = typeParameters ? createNodeArray(typeParameters) : undefined; + node.heritageClauses = createNodeArray(heritageClauses); + node.members = createNodeArray(members); + return node; + } - export function updateTemplateSpan(node: TemplateSpan, expression: Expression, literal: TemplateMiddle | TemplateTail) { - if (node.expression !== expression || node.literal !== literal) { - return updateNode(createTemplateSpan(expression, literal, node), node); + export function updateClassExpression(node: ClassExpression, modifiers: Modifier[], name: Identifier, typeParameters: TypeParameterDeclaration[], heritageClauses: HeritageClause[], members: ClassElement[]) { + if (node.modifiers !== modifiers || node.name !== name || node.typeParameters !== typeParameters || node.heritageClauses !== heritageClauses || node.members !== members) { + return updateNode(createClassExpression(modifiers, name, typeParameters, heritageClauses, members, node), node); + } + return node; } - return node; - } - // Element + export function createOmittedExpression(location?: TextRange) { + const node = createNode(SyntaxKind.OmittedExpression, location); + return node; + } - export function createBlock(statements: Statement[], location?: TextRange, multiLine?: boolean, flags?: NodeFlags): Block { - const block = createNode(SyntaxKind.Block, location, flags); - block.statements = createNodeArray(statements); - if (multiLine) { - block.multiLine = true; + export function createExpressionWithTypeArguments(typeArguments: TypeNode[], expression: Expression, location?: TextRange) { + const node = createNode(SyntaxKind.ExpressionWithTypeArguments, location); + node.typeArguments = typeArguments ? createNodeArray(typeArguments) : undefined; + node.expression = parenthesizeForAccess(expression); + return node; } - return block; - } - export function updateBlock(node: Block, statements: Statement[]) { - if (statements !== node.statements) { - return updateNode(createBlock(statements, /*location*/ node, node.multiLine, node.flags), node); + export function updateExpressionWithTypeArguments(node: ExpressionWithTypeArguments, typeArguments: TypeNode[], expression: Expression) { + if (node.typeArguments !== typeArguments || node.expression !== expression) { + return updateNode(createExpressionWithTypeArguments(typeArguments, expression, node), node); + } + return node; } - return node; - } - export function createVariableStatement(modifiers: Modifier[], declarationList: VariableDeclarationList | VariableDeclaration[], location?: TextRange, flags?: NodeFlags): VariableStatement { - const node = createNode(SyntaxKind.VariableStatement, location, flags); - node.decorators = undefined; - node.modifiers = modifiers ? createNodeArray(modifiers) : undefined; - node.declarationList = isArray(declarationList) ? createVariableDeclarationList(declarationList) : declarationList; - return node; - } + // Misc - export function updateVariableStatement(node: VariableStatement, modifiers: Modifier[], declarationList: VariableDeclarationList): VariableStatement { - if (node.modifiers !== modifiers || node.declarationList !== declarationList) { - return updateNode(createVariableStatement(modifiers, declarationList, /*location*/ node, node.flags), node); + export function createTemplateSpan(expression: Expression, literal: TemplateMiddle | TemplateTail, location?: TextRange) { + const node = createNode(SyntaxKind.TemplateSpan, location); + node.expression = expression; + node.literal = literal; + return node; } - return node; - } - - export function createVariableDeclarationList(declarations: VariableDeclaration[], location?: TextRange, flags?: NodeFlags): VariableDeclarationList { - const node = createNode(SyntaxKind.VariableDeclarationList, location, flags); - node.declarations = createNodeArray(declarations); - return node; - } - export function updateVariableDeclarationList(node: VariableDeclarationList, declarations: VariableDeclaration[]) { - if (node.declarations !== declarations) { - return updateNode(createVariableDeclarationList(declarations, /*location*/ node, node.flags), node); + export function updateTemplateSpan(node: TemplateSpan, expression: Expression, literal: TemplateMiddle | TemplateTail) { + if (node.expression !== expression || node.literal !== literal) { + return updateNode(createTemplateSpan(expression, literal, node), node); + } + return node; } - return node; - } - export function createVariableDeclaration(name: string | BindingPattern | Identifier, type?: TypeNode, initializer?: Expression, location?: TextRange, flags?: NodeFlags): VariableDeclaration { - const node = createNode(SyntaxKind.VariableDeclaration, location, flags); - node.name = typeof name === "string" ? createIdentifier(name) : name; - node.type = type; - node.initializer = initializer !== undefined ? parenthesizeExpressionForList(initializer) : undefined; - return node; - } + // Element - export function updateVariableDeclaration(node: VariableDeclaration, name: BindingName, type: TypeNode, initializer: Expression) { - if (node.name !== name || node.type !== type || node.initializer !== initializer) { - return updateNode(createVariableDeclaration(name, type, initializer, /*location*/ node, node.flags), node); + export function createBlock(statements: Statement[], location?: TextRange, multiLine?: boolean, flags?: NodeFlags): Block { + const block = createNode(SyntaxKind.Block, location, flags); + block.statements = createNodeArray(statements); + if (multiLine) { + block.multiLine = true; + } + return block; } - return node; - } - export function createEmptyStatement(location: TextRange) { - return createNode(SyntaxKind.EmptyStatement, location); - } + export function updateBlock(node: Block, statements: Statement[]) { + if (statements !== node.statements) { + return updateNode(createBlock(statements, /*location*/ node, node.multiLine, node.flags), node); + } - export function createStatement(expression: Expression, location?: TextRange, flags?: NodeFlags): ExpressionStatement { - const node = createNode(SyntaxKind.ExpressionStatement, location, flags); - node.expression = parenthesizeExpressionForExpressionStatement(expression); - return node; - } + return node; + } - export function updateStatement(node: ExpressionStatement, expression: Expression) { - if (node.expression !== expression) { - return updateNode(createStatement(expression, /*location*/ node, node.flags), node); + export function createVariableStatement(modifiers: Modifier[], declarationList: VariableDeclarationList | VariableDeclaration[], location?: TextRange, flags?: NodeFlags): VariableStatement { + const node = createNode(SyntaxKind.VariableStatement, location, flags); + node.decorators = undefined; + node.modifiers = modifiers ? createNodeArray(modifiers) : undefined; + node.declarationList = isArray(declarationList) ? createVariableDeclarationList(declarationList) : declarationList; + return node; } - return node; - } + export function updateVariableStatement(node: VariableStatement, modifiers: Modifier[], declarationList: VariableDeclarationList): VariableStatement { + if (node.modifiers !== modifiers || node.declarationList !== declarationList) { + return updateNode(createVariableStatement(modifiers, declarationList, /*location*/ node, node.flags), node); + } + return node; + } - export function createIf(expression: Expression, thenStatement: Statement, elseStatement?: Statement, location?: TextRange) { - const node = createNode(SyntaxKind.IfStatement, location); - node.expression = expression; - node.thenStatement = thenStatement; - node.elseStatement = elseStatement; - return node; - } + export function createVariableDeclarationList(declarations: VariableDeclaration[], location?: TextRange, flags?: NodeFlags): VariableDeclarationList { + const node = createNode(SyntaxKind.VariableDeclarationList, location, flags); + node.declarations = createNodeArray(declarations); + return node; + } - export function updateIf(node: IfStatement, expression: Expression, thenStatement: Statement, elseStatement: Statement) { - if (node.expression !== expression || node.thenStatement !== thenStatement || node.elseStatement !== elseStatement) { - return updateNode(createIf(expression, thenStatement, elseStatement, /*location*/ node), node); + export function updateVariableDeclarationList(node: VariableDeclarationList, declarations: VariableDeclaration[]) { + if (node.declarations !== declarations) { + return updateNode(createVariableDeclarationList(declarations, /*location*/ node, node.flags), node); + } + return node; } - return node; - } - export function createDo(statement: Statement, expression: Expression, location?: TextRange) { - const node = createNode(SyntaxKind.DoStatement, location); - node.statement = statement; - node.expression = expression; - return node; - } + export function createVariableDeclaration(name: string | BindingPattern | Identifier, type?: TypeNode, initializer?: Expression, location?: TextRange, flags?: NodeFlags): VariableDeclaration { + const node = createNode(SyntaxKind.VariableDeclaration, location, flags); + node.name = typeof name === "string" ? createIdentifier(name) : name; + node.type = type; + node.initializer = initializer !== undefined ? parenthesizeExpressionForList(initializer) : undefined; + return node; + } - export function updateDo(node: DoStatement, statement: Statement, expression: Expression) { - if (node.statement !== statement || node.expression !== expression) { - return updateNode(createDo(statement, expression, node), node); + export function updateVariableDeclaration(node: VariableDeclaration, name: BindingName, type: TypeNode, initializer: Expression) { + if (node.name !== name || node.type !== type || node.initializer !== initializer) { + return updateNode(createVariableDeclaration(name, type, initializer, /*location*/ node, node.flags), node); + } + return node; } - return node; - } - export function createWhile(expression: Expression, statement: Statement, location?: TextRange) { - const node = createNode(SyntaxKind.WhileStatement, location); - node.expression = expression; - node.statement = statement; - return node; - } + export function createEmptyStatement(location: TextRange) { + return createNode(SyntaxKind.EmptyStatement, location); + } - export function updateWhile(node: WhileStatement, expression: Expression, statement: Statement) { - if (node.expression !== expression || node.statement !== statement) { - return updateNode(createWhile(expression, statement, node), node); + export function createStatement(expression: Expression, location?: TextRange, flags?: NodeFlags): ExpressionStatement { + const node = createNode(SyntaxKind.ExpressionStatement, location, flags); + node.expression = parenthesizeExpressionForExpressionStatement(expression); + return node; } - return node; - } - export function createFor(initializer: ForInitializer, condition: Expression, incrementor: Expression, statement: Statement, location?: TextRange) { - const node = createNode(SyntaxKind.ForStatement, location, /*flags*/ undefined); - node.initializer = initializer; - node.condition = condition; - node.incrementor = incrementor; - node.statement = statement; - return node; - } + export function updateStatement(node: ExpressionStatement, expression: Expression) { + if (node.expression !== expression) { + return updateNode(createStatement(expression, /*location*/ node, node.flags), node); + } - export function updateFor(node: ForStatement, initializer: ForInitializer, condition: Expression, incrementor: Expression, statement: Statement) { - if (node.initializer !== initializer || node.condition !== condition || node.incrementor !== incrementor || node.statement !== statement) { - return updateNode(createFor(initializer, condition, incrementor, statement, node), node); + return node; } - return node; - } - - export function createForIn(initializer: ForInitializer, expression: Expression, statement: Statement, location?: TextRange) { - const node = createNode(SyntaxKind.ForInStatement, location); - node.initializer = initializer; - node.expression = expression; - node.statement = statement; - return node; - } - export function updateForIn(node: ForInStatement, initializer: ForInitializer, expression: Expression, statement: Statement) { - if (node.initializer !== initializer || node.expression !== expression || node.statement !== statement) { - return updateNode(createForIn(initializer, expression, statement, node), node); + export function createIf(expression: Expression, thenStatement: Statement, elseStatement?: Statement, location?: TextRange) { + const node = createNode(SyntaxKind.IfStatement, location); + node.expression = expression; + node.thenStatement = thenStatement; + node.elseStatement = elseStatement; + return node; } - return node; - } - export function createForOf(initializer: ForInitializer, expression: Expression, statement: Statement, location?: TextRange) { - const node = createNode(SyntaxKind.ForOfStatement, location); - node.initializer = initializer; - node.expression = expression; - node.statement = statement; - return node; - } + export function updateIf(node: IfStatement, expression: Expression, thenStatement: Statement, elseStatement: Statement) { + if (node.expression !== expression || node.thenStatement !== thenStatement || node.elseStatement !== elseStatement) { + return updateNode(createIf(expression, thenStatement, elseStatement, /*location*/ node), node); + } + return node; + } - export function updateForOf(node: ForOfStatement, initializer: ForInitializer, expression: Expression, statement: Statement) { - if (node.initializer !== initializer || node.expression !== expression || node.statement !== statement) { - return updateNode(createForOf(initializer, expression, statement, node), node); + export function createDo(statement: Statement, expression: Expression, location?: TextRange) { + const node = createNode(SyntaxKind.DoStatement, location); + node.statement = statement; + node.expression = expression; + return node; } - return node; - } - export function createContinue(label?: Identifier, location?: TextRange): ContinueStatement { - const node = createNode(SyntaxKind.ContinueStatement, location); - if (label) { - node.label = label; + export function updateDo(node: DoStatement, statement: Statement, expression: Expression) { + if (node.statement !== statement || node.expression !== expression) { + return updateNode(createDo(statement, expression, node), node); + } + return node; } - return node; - } - export function updateContinue(node: ContinueStatement, label: Identifier) { - if (node.label !== label) { - return updateNode(createContinue(label, node), node); + export function createWhile(expression: Expression, statement: Statement, location?: TextRange) { + const node = createNode(SyntaxKind.WhileStatement, location); + node.expression = expression; + node.statement = statement; + return node; } - return node; - } - export function createBreak(label?: Identifier, location?: TextRange): BreakStatement { - const node = createNode(SyntaxKind.BreakStatement, location); - if (label) { - node.label = label; + export function updateWhile(node: WhileStatement, expression: Expression, statement: Statement) { + if (node.expression !== expression || node.statement !== statement) { + return updateNode(createWhile(expression, statement, node), node); + } + return node; } - return node; - } - export function updateBreak(node: BreakStatement, label: Identifier) { - if (node.label !== label) { - return updateNode(createBreak(label, node), node); + export function createFor(initializer: ForInitializer, condition: Expression, incrementor: Expression, statement: Statement, location?: TextRange) { + const node = createNode(SyntaxKind.ForStatement, location, /*flags*/ undefined); + node.initializer = initializer; + node.condition = condition; + node.incrementor = incrementor; + node.statement = statement; + return node; } - return node; - } - export function createReturn(expression?: Expression, location?: TextRange): ReturnStatement { - const node = createNode(SyntaxKind.ReturnStatement, location); - node.expression = expression; - return node; - } + export function updateFor(node: ForStatement, initializer: ForInitializer, condition: Expression, incrementor: Expression, statement: Statement) { + if (node.initializer !== initializer || node.condition !== condition || node.incrementor !== incrementor || node.statement !== statement) { + return updateNode(createFor(initializer, condition, incrementor, statement, node), node); + } + return node; + } - export function updateReturn(node: ReturnStatement, expression: Expression) { - if (node.expression !== expression) { - return updateNode(createReturn(expression, /*location*/ node), node); + export function createForIn(initializer: ForInitializer, expression: Expression, statement: Statement, location?: TextRange) { + const node = createNode(SyntaxKind.ForInStatement, location); + node.initializer = initializer; + node.expression = expression; + node.statement = statement; + return node; } - return node; - } - export function createWith(expression: Expression, statement: Statement, location?: TextRange) { - const node = createNode(SyntaxKind.WithStatement, location); - node.expression = expression; - node.statement = statement; - return node; - } + export function updateForIn(node: ForInStatement, initializer: ForInitializer, expression: Expression, statement: Statement) { + if (node.initializer !== initializer || node.expression !== expression || node.statement !== statement) { + return updateNode(createForIn(initializer, expression, statement, node), node); + } + return node; + } - export function updateWith(node: WithStatement, expression: Expression, statement: Statement) { - if (node.expression !== expression || node.statement !== statement) { - return updateNode(createWith(expression, statement, node), node); + export function createForOf(initializer: ForInitializer, expression: Expression, statement: Statement, location?: TextRange) { + const node = createNode(SyntaxKind.ForOfStatement, location); + node.initializer = initializer; + node.expression = expression; + node.statement = statement; + return node; } - return node; - } - export function createSwitch(expression: Expression, caseBlock: CaseBlock, location?: TextRange): SwitchStatement { - const node = createNode(SyntaxKind.SwitchStatement, location); - node.expression = parenthesizeExpressionForList(expression); - node.caseBlock = caseBlock; - return node; - } + export function updateForOf(node: ForOfStatement, initializer: ForInitializer, expression: Expression, statement: Statement) { + if (node.initializer !== initializer || node.expression !== expression || node.statement !== statement) { + return updateNode(createForOf(initializer, expression, statement, node), node); + } + return node; + } - export function updateSwitch(node: SwitchStatement, expression: Expression, caseBlock: CaseBlock) { - if (node.expression !== expression || node.caseBlock !== caseBlock) { - return updateNode(createSwitch(expression, caseBlock, node), node); + export function createContinue(label?: Identifier, location?: TextRange): ContinueStatement { + const node = createNode(SyntaxKind.ContinueStatement, location); + if (label) { + node.label = label; + } + return node; } - return node; - } - export function createLabel(label: string | Identifier, statement: Statement, location?: TextRange) { - const node = createNode(SyntaxKind.LabeledStatement, location); - node.label = typeof label === "string" ? createIdentifier(label) : label; - node.statement = statement; - return node; - } + export function updateContinue(node: ContinueStatement, label: Identifier) { + if (node.label !== label) { + return updateNode(createContinue(label, node), node); + } + return node; + } - export function updateLabel(node: LabeledStatement, label: Identifier, statement: Statement) { - if (node.label !== label || node.statement !== statement) { - return updateNode(createLabel(label, statement, node), node); + export function createBreak(label?: Identifier, location?: TextRange): BreakStatement { + const node = createNode(SyntaxKind.BreakStatement, location); + if (label) { + node.label = label; + } + return node; } - return node; - } - export function createThrow(expression: Expression, location?: TextRange) { - const node = createNode(SyntaxKind.ThrowStatement, location); - node.expression = expression; - return node; - } + export function updateBreak(node: BreakStatement, label: Identifier) { + if (node.label !== label) { + return updateNode(createBreak(label, node), node); + } + return node; + } - export function updateThrow(node: ThrowStatement, expression: Expression) { - if (node.expression !== expression) { - return updateNode(createThrow(expression, node), node); + export function createReturn(expression?: Expression, location?: TextRange): ReturnStatement { + const node = createNode(SyntaxKind.ReturnStatement, location); + node.expression = expression; + return node; } - return node; - } - export function createTry(tryBlock: Block, catchClause: CatchClause, finallyBlock: Block, location?: TextRange) { - const node = createNode(SyntaxKind.TryStatement, location); - node.tryBlock = tryBlock; - node.catchClause = catchClause; - node.finallyBlock = finallyBlock; - return node; - } + export function updateReturn(node: ReturnStatement, expression: Expression) { + if (node.expression !== expression) { + return updateNode(createReturn(expression, /*location*/ node), node); + } + return node; + } - export function updateTry(node: TryStatement, tryBlock: Block, catchClause: CatchClause, finallyBlock: Block) { - if (node.tryBlock !== tryBlock || node.catchClause !== catchClause || node.finallyBlock !== finallyBlock) { - return updateNode(createTry(tryBlock, catchClause, finallyBlock, node), node); + export function createWith(expression: Expression, statement: Statement, location?: TextRange) { + const node = createNode(SyntaxKind.WithStatement, location); + node.expression = expression; + node.statement = statement; + return node; } - return node; - } - export function createCaseBlock(clauses: CaseOrDefaultClause[], location?: TextRange): CaseBlock { - const node = createNode(SyntaxKind.CaseBlock, location); - node.clauses = createNodeArray(clauses); - return node; - } + export function updateWith(node: WithStatement, expression: Expression, statement: Statement) { + if (node.expression !== expression || node.statement !== statement) { + return updateNode(createWith(expression, statement, node), node); + } + return node; + } - export function updateCaseBlock(node: CaseBlock, clauses: CaseOrDefaultClause[]) { - if (node.clauses !== clauses) { - return updateNode(createCaseBlock(clauses, node), node); + export function createSwitch(expression: Expression, caseBlock: CaseBlock, location?: TextRange): SwitchStatement { + const node = createNode(SyntaxKind.SwitchStatement, location); + node.expression = parenthesizeExpressionForList(expression); + node.caseBlock = caseBlock; + return node; } - return node; - } - export function createFunctionDeclaration(decorators: Decorator[], modifiers: Modifier[], asteriskToken: AsteriskToken, name: string | Identifier, typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, body: Block, location?: TextRange, flags?: NodeFlags) { - const node = createNode(SyntaxKind.FunctionDeclaration, location, flags); - node.decorators = decorators ? createNodeArray(decorators) : undefined; - node.modifiers = modifiers ? createNodeArray(modifiers) : undefined; - node.asteriskToken = asteriskToken; - node.name = typeof name === "string" ? createIdentifier(name) : name; - node.typeParameters = typeParameters ? createNodeArray(typeParameters) : undefined; - node.parameters = createNodeArray(parameters); - node.type = type; - node.body = body; - return node; - } + export function updateSwitch(node: SwitchStatement, expression: Expression, caseBlock: CaseBlock) { + if (node.expression !== expression || node.caseBlock !== caseBlock) { + return updateNode(createSwitch(expression, caseBlock, node), node); + } + return node; + } - export function updateFunctionDeclaration(node: FunctionDeclaration, decorators: Decorator[], modifiers: Modifier[], name: Identifier, typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, body: Block) { - if (node.decorators !== decorators || node.modifiers !== modifiers || node.name !== name || node.typeParameters !== typeParameters || node.parameters !== parameters || node.type !== type || node.body !== body) { - return updateNode(createFunctionDeclaration(decorators, modifiers, node.asteriskToken, name, typeParameters, parameters, type, body, /*location*/ node, node.flags), node); + export function createLabel(label: string | Identifier, statement: Statement, location?: TextRange) { + const node = createNode(SyntaxKind.LabeledStatement, location); + node.label = typeof label === "string" ? createIdentifier(label) : label; + node.statement = statement; + return node; } - return node; - } - export function createClassDeclaration(decorators: Decorator[], modifiers: Modifier[], name: Identifier, typeParameters: TypeParameterDeclaration[], heritageClauses: HeritageClause[], members: ClassElement[], location?: TextRange) { - const node = createNode(SyntaxKind.ClassDeclaration, location); - node.decorators = decorators ? createNodeArray(decorators) : undefined; - node.modifiers = modifiers ? createNodeArray(modifiers) : undefined; - node.name = name; - node.typeParameters = typeParameters ? createNodeArray(typeParameters) : undefined; - node.heritageClauses = createNodeArray(heritageClauses); - node.members = createNodeArray(members); - return node; - } + export function updateLabel(node: LabeledStatement, label: Identifier, statement: Statement) { + if (node.label !== label || node.statement !== statement) { + return updateNode(createLabel(label, statement, node), node); + } + return node; + } - export function updateClassDeclaration(node: ClassDeclaration, decorators: Decorator[], modifiers: Modifier[], name: Identifier, typeParameters: TypeParameterDeclaration[], heritageClauses: HeritageClause[], members: ClassElement[]) { - if (node.decorators !== decorators || node.modifiers !== modifiers || node.name !== name || node.typeParameters !== typeParameters || node.heritageClauses !== heritageClauses || node.members !== members) { - return updateNode(createClassDeclaration(decorators, modifiers, name, typeParameters, heritageClauses, members, node), node); + export function createThrow(expression: Expression, location?: TextRange) { + const node = createNode(SyntaxKind.ThrowStatement, location); + node.expression = expression; + return node; } - return node; - } - export function createImportDeclaration(decorators: Decorator[], modifiers: Modifier[], importClause: ImportClause, moduleSpecifier?: Expression, location?: TextRange): ImportDeclaration { - const node = createNode(SyntaxKind.ImportDeclaration, location); - node.decorators = decorators ? createNodeArray(decorators) : undefined; - node.modifiers = modifiers ? createNodeArray(modifiers) : undefined; - node.importClause = importClause; - node.moduleSpecifier = moduleSpecifier; - return node; - } + export function updateThrow(node: ThrowStatement, expression: Expression) { + if (node.expression !== expression) { + return updateNode(createThrow(expression, node), node); + } + return node; + } - export function updateImportDeclaration(node: ImportDeclaration, decorators: Decorator[], modifiers: Modifier[], importClause: ImportClause, moduleSpecifier: Expression) { - if (node.decorators !== decorators || node.modifiers !== modifiers || node.importClause !== importClause || node.moduleSpecifier !== moduleSpecifier) { - return updateNode(createImportDeclaration(decorators, modifiers, importClause, moduleSpecifier, node), node); + export function createTry(tryBlock: Block, catchClause: CatchClause, finallyBlock: Block, location?: TextRange) { + const node = createNode(SyntaxKind.TryStatement, location); + node.tryBlock = tryBlock; + node.catchClause = catchClause; + node.finallyBlock = finallyBlock; + return node; } - return node; - } - export function createImportClause(name: Identifier, namedBindings: NamedImportBindings, location?: TextRange): ImportClause { - const node = createNode(SyntaxKind.ImportClause, location); - node.name = name; - node.namedBindings = namedBindings; - return node; - } + export function updateTry(node: TryStatement, tryBlock: Block, catchClause: CatchClause, finallyBlock: Block) { + if (node.tryBlock !== tryBlock || node.catchClause !== catchClause || node.finallyBlock !== finallyBlock) { + return updateNode(createTry(tryBlock, catchClause, finallyBlock, node), node); + } + return node; + } - export function updateImportClause(node: ImportClause, name: Identifier, namedBindings: NamedImportBindings) { - if (node.name !== name || node.namedBindings !== namedBindings) { - return updateNode(createImportClause(name, namedBindings, node), node); + export function createCaseBlock(clauses: CaseOrDefaultClause[], location?: TextRange): CaseBlock { + const node = createNode(SyntaxKind.CaseBlock, location); + node.clauses = createNodeArray(clauses); + return node; } - return node; - } - export function createNamespaceImport(name: Identifier, location?: TextRange): NamespaceImport { - const node = createNode(SyntaxKind.NamespaceImport, location); - node.name = name; - return node; - } + export function updateCaseBlock(node: CaseBlock, clauses: CaseOrDefaultClause[]) { + if (node.clauses !== clauses) { + return updateNode(createCaseBlock(clauses, node), node); + } + return node; + } - export function updateNamespaceImport(node: NamespaceImport, name: Identifier) { - if (node.name !== name) { - return updateNode(createNamespaceImport(name, node), node); + export function createFunctionDeclaration(decorators: Decorator[], modifiers: Modifier[], asteriskToken: AsteriskToken, name: string | Identifier, typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, body: Block, location?: TextRange, flags?: NodeFlags) { + const node = createNode(SyntaxKind.FunctionDeclaration, location, flags); + node.decorators = decorators ? createNodeArray(decorators) : undefined; + node.modifiers = modifiers ? createNodeArray(modifiers) : undefined; + node.asteriskToken = asteriskToken; + node.name = typeof name === "string" ? createIdentifier(name) : name; + node.typeParameters = typeParameters ? createNodeArray(typeParameters) : undefined; + node.parameters = createNodeArray(parameters); + node.type = type; + node.body = body; + return node; } - return node; - } - export function createNamedImports(elements: ImportSpecifier[], location?: TextRange): NamedImports { - const node = createNode(SyntaxKind.NamedImports, location); - node.elements = createNodeArray(elements); - return node; - } + export function updateFunctionDeclaration(node: FunctionDeclaration, decorators: Decorator[], modifiers: Modifier[], name: Identifier, typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, body: Block) { + if (node.decorators !== decorators || node.modifiers !== modifiers || node.name !== name || node.typeParameters !== typeParameters || node.parameters !== parameters || node.type !== type || node.body !== body) { + return updateNode(createFunctionDeclaration(decorators, modifiers, node.asteriskToken, name, typeParameters, parameters, type, body, /*location*/ node, node.flags), node); + } + return node; + } - export function updateNamedImports(node: NamedImports, elements: ImportSpecifier[]) { - if (node.elements !== elements) { - return updateNode(createNamedImports(elements, node), node); + export function createClassDeclaration(decorators: Decorator[], modifiers: Modifier[], name: Identifier, typeParameters: TypeParameterDeclaration[], heritageClauses: HeritageClause[], members: ClassElement[], location?: TextRange) { + const node = createNode(SyntaxKind.ClassDeclaration, location); + node.decorators = decorators ? createNodeArray(decorators) : undefined; + node.modifiers = modifiers ? createNodeArray(modifiers) : undefined; + node.name = name; + node.typeParameters = typeParameters ? createNodeArray(typeParameters) : undefined; + node.heritageClauses = createNodeArray(heritageClauses); + node.members = createNodeArray(members); + return node; } - return node; - } - export function createImportSpecifier(propertyName: Identifier, name: Identifier, location?: TextRange) { - const node = createNode(SyntaxKind.ImportSpecifier, location); - node.propertyName = propertyName; - node.name = name; - return node; - } + export function updateClassDeclaration(node: ClassDeclaration, decorators: Decorator[], modifiers: Modifier[], name: Identifier, typeParameters: TypeParameterDeclaration[], heritageClauses: HeritageClause[], members: ClassElement[]) { + if (node.decorators !== decorators || node.modifiers !== modifiers || node.name !== name || node.typeParameters !== typeParameters || node.heritageClauses !== heritageClauses || node.members !== members) { + return updateNode(createClassDeclaration(decorators, modifiers, name, typeParameters, heritageClauses, members, node), node); + } + return node; + } - export function updateImportSpecifier(node: ImportSpecifier, propertyName: Identifier, name: Identifier) { - if (node.propertyName !== propertyName || node.name !== name) { - return updateNode(createImportSpecifier(propertyName, name, node), node); + export function createImportDeclaration(decorators: Decorator[], modifiers: Modifier[], importClause: ImportClause, moduleSpecifier?: Expression, location?: TextRange): ImportDeclaration { + const node = createNode(SyntaxKind.ImportDeclaration, location); + node.decorators = decorators ? createNodeArray(decorators) : undefined; + node.modifiers = modifiers ? createNodeArray(modifiers) : undefined; + node.importClause = importClause; + node.moduleSpecifier = moduleSpecifier; + return node; } - return node; - } - export function createExportAssignment(decorators: Decorator[], modifiers: Modifier[], isExportEquals: boolean, expression: Expression, location?: TextRange) { - const node = createNode(SyntaxKind.ExportAssignment, location); - node.decorators = decorators ? createNodeArray(decorators) : undefined; - node.modifiers = modifiers ? createNodeArray(modifiers) : undefined; - node.isExportEquals = isExportEquals; - node.expression = expression; - return node; - } + export function updateImportDeclaration(node: ImportDeclaration, decorators: Decorator[], modifiers: Modifier[], importClause: ImportClause, moduleSpecifier: Expression) { + if (node.decorators !== decorators || node.modifiers !== modifiers || node.importClause !== importClause || node.moduleSpecifier !== moduleSpecifier) { + return updateNode(createImportDeclaration(decorators, modifiers, importClause, moduleSpecifier, node), node); + } + return node; + } - export function updateExportAssignment(node: ExportAssignment, decorators: Decorator[], modifiers: Modifier[], expression: Expression) { - if (node.decorators !== decorators || node.modifiers !== modifiers || node.expression !== expression) { - return updateNode(createExportAssignment(decorators, modifiers, node.isExportEquals, expression, node), node); + export function createImportClause(name: Identifier, namedBindings: NamedImportBindings, location?: TextRange): ImportClause { + const node = createNode(SyntaxKind.ImportClause, location); + node.name = name; + node.namedBindings = namedBindings; + return node; } - return node; - } - export function createExportDeclaration(decorators: Decorator[], modifiers: Modifier[], exportClause: NamedExports, moduleSpecifier?: Expression, location?: TextRange) { - const node = createNode(SyntaxKind.ExportDeclaration, location); - node.decorators = decorators ? createNodeArray(decorators) : undefined; - node.modifiers = modifiers ? createNodeArray(modifiers) : undefined; - node.exportClause = exportClause; - node.moduleSpecifier = moduleSpecifier; - return node; - } + export function updateImportClause(node: ImportClause, name: Identifier, namedBindings: NamedImportBindings) { + if (node.name !== name || node.namedBindings !== namedBindings) { + return updateNode(createImportClause(name, namedBindings, node), node); + } + return node; + } - export function updateExportDeclaration(node: ExportDeclaration, decorators: Decorator[], modifiers: Modifier[], exportClause: NamedExports, moduleSpecifier: Expression) { - if (node.decorators !== decorators || node.modifiers !== modifiers || node.exportClause !== exportClause || node.moduleSpecifier !== moduleSpecifier) { - return updateNode(createExportDeclaration(decorators, modifiers, exportClause, moduleSpecifier, node), node); + export function createNamespaceImport(name: Identifier, location?: TextRange): NamespaceImport { + const node = createNode(SyntaxKind.NamespaceImport, location); + node.name = name; + return node; } - return node; - } - export function createNamedExports(elements: ExportSpecifier[], location?: TextRange) { - const node = createNode(SyntaxKind.NamedExports, location); - node.elements = createNodeArray(elements); - return node; - } + export function updateNamespaceImport(node: NamespaceImport, name: Identifier) { + if (node.name !== name) { + return updateNode(createNamespaceImport(name, node), node); + } + return node; + } - export function updateNamedExports(node: NamedExports, elements: ExportSpecifier[]) { - if (node.elements !== elements) { - return updateNode(createNamedExports(elements, node), node); + export function createNamedImports(elements: ImportSpecifier[], location?: TextRange): NamedImports { + const node = createNode(SyntaxKind.NamedImports, location); + node.elements = createNodeArray(elements); + return node; } - return node; - } - export function createExportSpecifier(name: string | Identifier, propertyName?: string | Identifier, location?: TextRange) { - const node = createNode(SyntaxKind.ExportSpecifier, location); - node.name = typeof name === "string" ? createIdentifier(name) : name; - node.propertyName = typeof propertyName === "string" ? createIdentifier(propertyName) : propertyName; - return node; - } + export function updateNamedImports(node: NamedImports, elements: ImportSpecifier[]) { + if (node.elements !== elements) { + return updateNode(createNamedImports(elements, node), node); + } + return node; + } - export function updateExportSpecifier(node: ExportSpecifier, name: Identifier, propertyName: Identifier) { - if (node.name !== name || node.propertyName !== propertyName) { - return updateNode(createExportSpecifier(name, propertyName, node), node); + export function createImportSpecifier(propertyName: Identifier, name: Identifier, location?: TextRange) { + const node = createNode(SyntaxKind.ImportSpecifier, location); + node.propertyName = propertyName; + node.name = name; + return node; } - return node; - } - // JSX + export function updateImportSpecifier(node: ImportSpecifier, propertyName: Identifier, name: Identifier) { + if (node.propertyName !== propertyName || node.name !== name) { + return updateNode(createImportSpecifier(propertyName, name, node), node); + } + return node; + } - export function createJsxElement(openingElement: JsxOpeningElement, children: JsxChild[], closingElement: JsxClosingElement, location?: TextRange) { - const node = createNode(SyntaxKind.JsxElement, location); - node.openingElement = openingElement; - node.children = createNodeArray(children); - node.closingElement = closingElement; - return node; - } + export function createExportAssignment(decorators: Decorator[], modifiers: Modifier[], isExportEquals: boolean, expression: Expression, location?: TextRange) { + const node = createNode(SyntaxKind.ExportAssignment, location); + node.decorators = decorators ? createNodeArray(decorators) : undefined; + node.modifiers = modifiers ? createNodeArray(modifiers) : undefined; + node.isExportEquals = isExportEquals; + node.expression = expression; + return node; + } - export function updateJsxElement(node: JsxElement, openingElement: JsxOpeningElement, children: JsxChild[], closingElement: JsxClosingElement) { - if (node.openingElement !== openingElement || node.children !== children || node.closingElement !== closingElement) { - return updateNode(createJsxElement(openingElement, children, closingElement, node), node); + export function updateExportAssignment(node: ExportAssignment, decorators: Decorator[], modifiers: Modifier[], expression: Expression) { + if (node.decorators !== decorators || node.modifiers !== modifiers || node.expression !== expression) { + return updateNode(createExportAssignment(decorators, modifiers, node.isExportEquals, expression, node), node); + } + return node; } - return node; - } - export function createJsxSelfClosingElement(tagName: JsxTagNameExpression, attributes: JsxAttributeLike[], location?: TextRange) { - const node = createNode(SyntaxKind.JsxSelfClosingElement, location); - node.tagName = tagName; - node.attributes = createNodeArray(attributes); - return node; - } + export function createExportDeclaration(decorators: Decorator[], modifiers: Modifier[], exportClause: NamedExports, moduleSpecifier?: Expression, location?: TextRange) { + const node = createNode(SyntaxKind.ExportDeclaration, location); + node.decorators = decorators ? createNodeArray(decorators) : undefined; + node.modifiers = modifiers ? createNodeArray(modifiers) : undefined; + node.exportClause = exportClause; + node.moduleSpecifier = moduleSpecifier; + return node; + } - export function updateJsxSelfClosingElement(node: JsxSelfClosingElement, tagName: JsxTagNameExpression, attributes: JsxAttributeLike[]) { - if (node.tagName !== tagName || node.attributes !== attributes) { - return updateNode(createJsxSelfClosingElement(tagName, attributes, node), node); + export function updateExportDeclaration(node: ExportDeclaration, decorators: Decorator[], modifiers: Modifier[], exportClause: NamedExports, moduleSpecifier: Expression) { + if (node.decorators !== decorators || node.modifiers !== modifiers || node.exportClause !== exportClause || node.moduleSpecifier !== moduleSpecifier) { + return updateNode(createExportDeclaration(decorators, modifiers, exportClause, moduleSpecifier, node), node); + } + return node; } - return node; - } - export function createJsxOpeningElement(tagName: JsxTagNameExpression, attributes: JsxAttributeLike[], location?: TextRange) { - const node = createNode(SyntaxKind.JsxOpeningElement, location); - node.tagName = tagName; - node.attributes = createNodeArray(attributes); - return node; - } + export function createNamedExports(elements: ExportSpecifier[], location?: TextRange) { + const node = createNode(SyntaxKind.NamedExports, location); + node.elements = createNodeArray(elements); + return node; + } - export function updateJsxOpeningElement(node: JsxOpeningElement, tagName: JsxTagNameExpression, attributes: JsxAttributeLike[]) { - if (node.tagName !== tagName || node.attributes !== attributes) { - return updateNode(createJsxOpeningElement(tagName, attributes, node), node); + export function updateNamedExports(node: NamedExports, elements: ExportSpecifier[]) { + if (node.elements !== elements) { + return updateNode(createNamedExports(elements, node), node); + } + return node; } - return node; - } - export function createJsxClosingElement(tagName: JsxTagNameExpression, location?: TextRange) { - const node = createNode(SyntaxKind.JsxClosingElement, location); - node.tagName = tagName; - return node; - } + export function createExportSpecifier(name: string | Identifier, propertyName?: string | Identifier, location?: TextRange) { + const node = createNode(SyntaxKind.ExportSpecifier, location); + node.name = typeof name === "string" ? createIdentifier(name) : name; + node.propertyName = typeof propertyName === "string" ? createIdentifier(propertyName) : propertyName; + return node; + } - export function updateJsxClosingElement(node: JsxClosingElement, tagName: JsxTagNameExpression) { - if (node.tagName !== tagName) { - return updateNode(createJsxClosingElement(tagName, node), node); + export function updateExportSpecifier(node: ExportSpecifier, name: Identifier, propertyName: Identifier) { + if (node.name !== name || node.propertyName !== propertyName) { + return updateNode(createExportSpecifier(name, propertyName, node), node); + } + return node; } - return node; - } - export function createJsxAttribute(name: Identifier, initializer: StringLiteral | JsxExpression, location?: TextRange) { - const node = createNode(SyntaxKind.JsxAttribute, location); - node.name = name; - node.initializer = initializer; - return node; - } + // JSX - export function updateJsxAttribute(node: JsxAttribute, name: Identifier, initializer: StringLiteral | JsxExpression) { - if (node.name !== name || node.initializer !== initializer) { - return updateNode(createJsxAttribute(name, initializer, node), node); + export function createJsxElement(openingElement: JsxOpeningElement, children: JsxChild[], closingElement: JsxClosingElement, location?: TextRange) { + const node = createNode(SyntaxKind.JsxElement, location); + node.openingElement = openingElement; + node.children = createNodeArray(children); + node.closingElement = closingElement; + return node; } - return node; - } - - export function createJsxSpreadAttribute(expression: Expression, location?: TextRange) { - const node = createNode(SyntaxKind.JsxSpreadAttribute, location); - node.expression = expression; - return node; - } - export function updateJsxSpreadAttribute(node: JsxSpreadAttribute, expression: Expression) { - if (node.expression !== expression) { - return updateNode(createJsxSpreadAttribute(expression, node), node); + export function updateJsxElement(node: JsxElement, openingElement: JsxOpeningElement, children: JsxChild[], closingElement: JsxClosingElement) { + if (node.openingElement !== openingElement || node.children !== children || node.closingElement !== closingElement) { + return updateNode(createJsxElement(openingElement, children, closingElement, node), node); + } + return node; } - return node; - } - export function createJsxExpression(expression: Expression, location?: TextRange) { - const node = createNode(SyntaxKind.JsxExpression, location); - node.expression = expression; - return node; - } + export function createJsxSelfClosingElement(tagName: JsxTagNameExpression, attributes: JsxAttributeLike[], location?: TextRange) { + const node = createNode(SyntaxKind.JsxSelfClosingElement, location); + node.tagName = tagName; + node.attributes = createNodeArray(attributes); + return node; + } - export function updateJsxExpression(node: JsxExpression, expression: Expression) { - if (node.expression !== expression) { - return updateNode(createJsxExpression(expression, node), node); + export function updateJsxSelfClosingElement(node: JsxSelfClosingElement, tagName: JsxTagNameExpression, attributes: JsxAttributeLike[]) { + if (node.tagName !== tagName || node.attributes !== attributes) { + return updateNode(createJsxSelfClosingElement(tagName, attributes, node), node); + } + return node; } - return node; - } - // Clauses + export function createJsxOpeningElement(tagName: JsxTagNameExpression, attributes: JsxAttributeLike[], location?: TextRange) { + const node = createNode(SyntaxKind.JsxOpeningElement, location); + node.tagName = tagName; + node.attributes = createNodeArray(attributes); + return node; + } - export function createHeritageClause(token: SyntaxKind, types: ExpressionWithTypeArguments[], location?: TextRange) { - const node = createNode(SyntaxKind.HeritageClause, location); - node.token = token; - node.types = createNodeArray(types); - return node; - } + export function updateJsxOpeningElement(node: JsxOpeningElement, tagName: JsxTagNameExpression, attributes: JsxAttributeLike[]) { + if (node.tagName !== tagName || node.attributes !== attributes) { + return updateNode(createJsxOpeningElement(tagName, attributes, node), node); + } + return node; + } - export function updateHeritageClause(node: HeritageClause, types: ExpressionWithTypeArguments[]) { - if (node.types !== types) { - return updateNode(createHeritageClause(node.token, types, node), node); + export function createJsxClosingElement(tagName: JsxTagNameExpression, location?: TextRange) { + const node = createNode(SyntaxKind.JsxClosingElement, location); + node.tagName = tagName; + return node; } - return node; - } - export function createCaseClause(expression: Expression, statements: Statement[], location?: TextRange) { - const node = createNode(SyntaxKind.CaseClause, location); - node.expression = parenthesizeExpressionForList(expression); - node.statements = createNodeArray(statements); - return node; - } + export function updateJsxClosingElement(node: JsxClosingElement, tagName: JsxTagNameExpression) { + if (node.tagName !== tagName) { + return updateNode(createJsxClosingElement(tagName, node), node); + } + return node; + } - export function updateCaseClause(node: CaseClause, expression: Expression, statements: Statement[]) { - if (node.expression !== expression || node.statements !== statements) { - return updateNode(createCaseClause(expression, statements, node), node); + export function createJsxAttribute(name: Identifier, initializer: StringLiteral | JsxExpression, location?: TextRange) { + const node = createNode(SyntaxKind.JsxAttribute, location); + node.name = name; + node.initializer = initializer; + return node; } - return node; - } - export function createDefaultClause(statements: Statement[], location?: TextRange) { - const node = createNode(SyntaxKind.DefaultClause, location); - node.statements = createNodeArray(statements); - return node; - } + export function updateJsxAttribute(node: JsxAttribute, name: Identifier, initializer: StringLiteral | JsxExpression) { + if (node.name !== name || node.initializer !== initializer) { + return updateNode(createJsxAttribute(name, initializer, node), node); + } + return node; + } - export function updateDefaultClause(node: DefaultClause, statements: Statement[]) { - if (node.statements !== statements) { - return updateNode(createDefaultClause(statements, node), node); + export function createJsxSpreadAttribute(expression: Expression, location?: TextRange) { + const node = createNode(SyntaxKind.JsxSpreadAttribute, location); + node.expression = expression; + return node; } - return node; - } - export function createCatchClause(variableDeclaration: string | VariableDeclaration, block: Block, location?: TextRange) { - const node = createNode(SyntaxKind.CatchClause, location); - node.variableDeclaration = typeof variableDeclaration === "string" ? createVariableDeclaration(variableDeclaration) : variableDeclaration; - node.block = block; - return node; - } + export function updateJsxSpreadAttribute(node: JsxSpreadAttribute, expression: Expression) { + if (node.expression !== expression) { + return updateNode(createJsxSpreadAttribute(expression, node), node); + } + return node; + } - export function updateCatchClause(node: CatchClause, variableDeclaration: VariableDeclaration, block: Block) { - if (node.variableDeclaration !== variableDeclaration || node.block !== block) { - return updateNode(createCatchClause(variableDeclaration, block, node), node); + export function createJsxExpression(expression: Expression, location?: TextRange) { + const node = createNode(SyntaxKind.JsxExpression, location); + node.expression = expression; + return node; } - return node; - } - // Property assignments + export function updateJsxExpression(node: JsxExpression, expression: Expression) { + if (node.expression !== expression) { + return updateNode(createJsxExpression(expression, node), node); + } + return node; + } - export function createPropertyAssignment(name: string | PropertyName, initializer: Expression, location?: TextRange) { - const node = createNode(SyntaxKind.PropertyAssignment, location); - node.name = typeof name === "string" ? createIdentifier(name) : name; - node.questionToken = undefined; - node.initializer = initializer !== undefined ? parenthesizeExpressionForList(initializer) : undefined; - return node; - } + // Clauses - export function updatePropertyAssignment(node: PropertyAssignment, name: PropertyName, initializer: Expression) { - if (node.name !== name || node.initializer !== initializer) { - return updateNode(createPropertyAssignment(name, initializer, node), node); + export function createHeritageClause(token: SyntaxKind, types: ExpressionWithTypeArguments[], location?: TextRange) { + const node = createNode(SyntaxKind.HeritageClause, location); + node.token = token; + node.types = createNodeArray(types); + return node; } - return node; - } - export function createShorthandPropertyAssignment(name: string | Identifier, objectAssignmentInitializer: Expression, location?: TextRange) { - const node = createNode(SyntaxKind.ShorthandPropertyAssignment, location); - node.name = typeof name === "string" ? createIdentifier(name) : name; - node.objectAssignmentInitializer = objectAssignmentInitializer !== undefined ? parenthesizeExpressionForList(objectAssignmentInitializer) : undefined; - return node; - } + export function updateHeritageClause(node: HeritageClause, types: ExpressionWithTypeArguments[]) { + if (node.types !== types) { + return updateNode(createHeritageClause(node.token, types, node), node); + } + return node; + } - export function updateShorthandPropertyAssignment(node: ShorthandPropertyAssignment, name: Identifier, objectAssignmentInitializer: Expression) { - if (node.name !== name || node.objectAssignmentInitializer !== objectAssignmentInitializer) { - return updateNode(createShorthandPropertyAssignment(name, objectAssignmentInitializer, node), node); + export function createCaseClause(expression: Expression, statements: Statement[], location?: TextRange) { + const node = createNode(SyntaxKind.CaseClause, location); + node.expression = parenthesizeExpressionForList(expression); + node.statements = createNodeArray(statements); + return node; } - return node; - } - // Top-level nodes - - export function updateSourceFileNode(node: SourceFile, statements: Statement[]) { - if (node.statements !== statements) { - const updated = createNode(SyntaxKind.SourceFile, /*location*/ node, node.flags); - updated.statements = createNodeArray(statements); - updated.endOfFileToken = node.endOfFileToken; - updated.fileName = node.fileName; - updated.path = node.path; - updated.text = node.text; - if (node.amdDependencies !== undefined) updated.amdDependencies = node.amdDependencies; - if (node.moduleName !== undefined) updated.moduleName = node.moduleName; - if (node.referencedFiles !== undefined) updated.referencedFiles = node.referencedFiles; - if (node.typeReferenceDirectives !== undefined) updated.typeReferenceDirectives = node.typeReferenceDirectives; - if (node.languageVariant !== undefined) updated.languageVariant = node.languageVariant; - if (node.isDeclarationFile !== undefined) updated.isDeclarationFile = node.isDeclarationFile; - if (node.renamedDependencies !== undefined) updated.renamedDependencies = node.renamedDependencies; - if (node.hasNoDefaultLib !== undefined) updated.hasNoDefaultLib = node.hasNoDefaultLib; - if (node.languageVersion !== undefined) updated.languageVersion = node.languageVersion; - if (node.scriptKind !== undefined) updated.scriptKind = node.scriptKind; - if (node.externalModuleIndicator !== undefined) updated.externalModuleIndicator = node.externalModuleIndicator; - if (node.commonJsModuleIndicator !== undefined) updated.commonJsModuleIndicator = node.commonJsModuleIndicator; - if (node.identifiers !== undefined) updated.identifiers = node.identifiers; - if (node.nodeCount !== undefined) updated.nodeCount = node.nodeCount; - if (node.identifierCount !== undefined) updated.identifierCount = node.identifierCount; - if (node.symbolCount !== undefined) updated.symbolCount = node.symbolCount; - if (node.parseDiagnostics !== undefined) updated.parseDiagnostics = node.parseDiagnostics; - if (node.bindDiagnostics !== undefined) updated.bindDiagnostics = node.bindDiagnostics; - if (node.lineMap !== undefined) updated.lineMap = node.lineMap; - if (node.classifiableNames !== undefined) updated.classifiableNames = node.classifiableNames; - if (node.resolvedModules !== undefined) updated.resolvedModules = node.resolvedModules; - if (node.resolvedTypeReferenceDirectiveNames !== undefined) updated.resolvedTypeReferenceDirectiveNames = node.resolvedTypeReferenceDirectiveNames; - if (node.imports !== undefined) updated.imports = node.imports; - if (node.moduleAugmentations !== undefined) updated.moduleAugmentations = node.moduleAugmentations; - if (node.externalHelpersModuleName !== undefined) updated.externalHelpersModuleName = node.externalHelpersModuleName; - return updateNode(updated, node); - } - - return node; - } + export function updateCaseClause(node: CaseClause, expression: Expression, statements: Statement[]) { + if (node.expression !== expression || node.statements !== statements) { + return updateNode(createCaseClause(expression, statements, node), node); + } + return node; + } - // Transformation nodes - - /** - * Creates a synthetic statement to act as a placeholder for a not-emitted statement in - * order to preserve comments. - * - * @param original The original statement. - */ - /* @internal */ - export function createNotEmittedStatement(original: Node) { - const node = createNode(SyntaxKind.NotEmittedStatement, /*location*/ original); - node.original = original; - return node; - } + export function createDefaultClause(statements: Statement[], location?: TextRange) { + const node = createNode(SyntaxKind.DefaultClause, location); + node.statements = createNodeArray(statements); + return node; + } - /** - * Creates a synthetic expression to act as a placeholder for a not-emitted expression in - * order to preserve comments or sourcemap positions. - * - * @param expression The inner expression to emit. - * @param original The original outer expression. - * @param location The location for the expression. Defaults to the positions from "original" if provided. - */ - /* @internal */ - export function createPartiallyEmittedExpression(expression: Expression, original?: Node, location?: TextRange) { - const node = createNode(SyntaxKind.PartiallyEmittedExpression, /*location*/ location || original); - node.expression = expression; - node.original = original; - return node; - } + export function updateDefaultClause(node: DefaultClause, statements: Statement[]) { + if (node.statements !== statements) { + return updateNode(createDefaultClause(statements, node), node); + } + return node; + } - /* @internal */ - export function updatePartiallyEmittedExpression(node: PartiallyEmittedExpression, expression: Expression) { - if (node.expression !== expression) { - return updateNode(createPartiallyEmittedExpression(expression, node.original, node), node); + export function createCatchClause(variableDeclaration: string | VariableDeclaration, block: Block, location?: TextRange) { + const node = createNode(SyntaxKind.CatchClause, location); + node.variableDeclaration = typeof variableDeclaration === "string" ? createVariableDeclaration(variableDeclaration) : variableDeclaration; + node.block = block; + return node; } - return node; - } - // Compound nodes + export function updateCatchClause(node: CatchClause, variableDeclaration: VariableDeclaration, block: Block) { + if (node.variableDeclaration !== variableDeclaration || node.block !== block) { + return updateNode(createCatchClause(variableDeclaration, block, node), node); + } + return node; + } - export function createComma(left: Expression, right: Expression) { - return createBinary(left, SyntaxKind.CommaToken, right); - } + // Property assignments - export function createLessThan(left: Expression, right: Expression, location?: TextRange) { - return createBinary(left, SyntaxKind.LessThanToken, right, location); - } + export function createPropertyAssignment(name: string | PropertyName, initializer: Expression, location?: TextRange) { + const node = createNode(SyntaxKind.PropertyAssignment, location); + node.name = typeof name === "string" ? createIdentifier(name) : name; + node.questionToken = undefined; + node.initializer = initializer !== undefined ? parenthesizeExpressionForList(initializer) : undefined; + return node; + } - export function createAssignment(left: Expression, right: Expression, location?: TextRange) { - return createBinary(left, SyntaxKind.EqualsToken, right, location); - } + export function updatePropertyAssignment(node: PropertyAssignment, name: PropertyName, initializer: Expression) { + if (node.name !== name || node.initializer !== initializer) { + return updateNode(createPropertyAssignment(name, initializer, node), node); + } + return node; + } - export function createStrictEquality(left: Expression, right: Expression) { - return createBinary(left, SyntaxKind.EqualsEqualsEqualsToken, right); - } + export function createShorthandPropertyAssignment(name: string | Identifier, objectAssignmentInitializer: Expression, location?: TextRange) { + const node = createNode(SyntaxKind.ShorthandPropertyAssignment, location); + node.name = typeof name === "string" ? createIdentifier(name) : name; + node.objectAssignmentInitializer = objectAssignmentInitializer !== undefined ? parenthesizeExpressionForList(objectAssignmentInitializer) : undefined; + return node; + } - export function createStrictInequality(left: Expression, right: Expression) { - return createBinary(left, SyntaxKind.ExclamationEqualsEqualsToken, right); - } + export function updateShorthandPropertyAssignment(node: ShorthandPropertyAssignment, name: Identifier, objectAssignmentInitializer: Expression) { + if (node.name !== name || node.objectAssignmentInitializer !== objectAssignmentInitializer) { + return updateNode(createShorthandPropertyAssignment(name, objectAssignmentInitializer, node), node); + } + return node; + } - export function createAdd(left: Expression, right: Expression) { - return createBinary(left, SyntaxKind.PlusToken, right); - } + // Top-level nodes + + export function updateSourceFileNode(node: SourceFile, statements: Statement[]) { + if (node.statements !== statements) { + const updated = createNode(SyntaxKind.SourceFile, /*location*/ node, node.flags); + updated.statements = createNodeArray(statements); + updated.endOfFileToken = node.endOfFileToken; + updated.fileName = node.fileName; + updated.path = node.path; + updated.text = node.text; + if (node.amdDependencies !== undefined) updated.amdDependencies = node.amdDependencies; + if (node.moduleName !== undefined) updated.moduleName = node.moduleName; + if (node.referencedFiles !== undefined) updated.referencedFiles = node.referencedFiles; + if (node.typeReferenceDirectives !== undefined) updated.typeReferenceDirectives = node.typeReferenceDirectives; + if (node.languageVariant !== undefined) updated.languageVariant = node.languageVariant; + if (node.isDeclarationFile !== undefined) updated.isDeclarationFile = node.isDeclarationFile; + if (node.renamedDependencies !== undefined) updated.renamedDependencies = node.renamedDependencies; + if (node.hasNoDefaultLib !== undefined) updated.hasNoDefaultLib = node.hasNoDefaultLib; + if (node.languageVersion !== undefined) updated.languageVersion = node.languageVersion; + if (node.scriptKind !== undefined) updated.scriptKind = node.scriptKind; + if (node.externalModuleIndicator !== undefined) updated.externalModuleIndicator = node.externalModuleIndicator; + if (node.commonJsModuleIndicator !== undefined) updated.commonJsModuleIndicator = node.commonJsModuleIndicator; + if (node.identifiers !== undefined) updated.identifiers = node.identifiers; + if (node.nodeCount !== undefined) updated.nodeCount = node.nodeCount; + if (node.identifierCount !== undefined) updated.identifierCount = node.identifierCount; + if (node.symbolCount !== undefined) updated.symbolCount = node.symbolCount; + if (node.parseDiagnostics !== undefined) updated.parseDiagnostics = node.parseDiagnostics; + if (node.bindDiagnostics !== undefined) updated.bindDiagnostics = node.bindDiagnostics; + if (node.lineMap !== undefined) updated.lineMap = node.lineMap; + if (node.classifiableNames !== undefined) updated.classifiableNames = node.classifiableNames; + if (node.resolvedModules !== undefined) updated.resolvedModules = node.resolvedModules; + if (node.resolvedTypeReferenceDirectiveNames !== undefined) updated.resolvedTypeReferenceDirectiveNames = node.resolvedTypeReferenceDirectiveNames; + if (node.imports !== undefined) updated.imports = node.imports; + if (node.moduleAugmentations !== undefined) updated.moduleAugmentations = node.moduleAugmentations; + if (node.externalHelpersModuleName !== undefined) updated.externalHelpersModuleName = node.externalHelpersModuleName; + return updateNode(updated, node); + } - export function createSubtract(left: Expression, right: Expression) { - return createBinary(left, SyntaxKind.MinusToken, right); - } + return node; + } - export function createPostfixIncrement(operand: Expression, location?: TextRange) { - return createPostfix(operand, SyntaxKind.PlusPlusToken, location); - } + // Transformation nodes - export function createLogicalAnd(left: Expression, right: Expression) { - return createBinary(left, SyntaxKind.AmpersandAmpersandToken, right); - } + /** + * Creates a synthetic statement to act as a placeholder for a not-emitted statement in + * order to preserve comments. + * + * @param original The original statement. + */ + /* @internal */ + export function createNotEmittedStatement(original: Node) { + const node = createNode(SyntaxKind.NotEmittedStatement, /*location*/ original); + node.original = original; + return node; + } - export function createLogicalOr(left: Expression, right: Expression) { - return createBinary(left, SyntaxKind.BarBarToken, right); - } + /** + * Creates a synthetic expression to act as a placeholder for a not-emitted expression in + * order to preserve comments or sourcemap positions. + * + * @param expression The inner expression to emit. + * @param original The original outer expression. + * @param location The location for the expression. Defaults to the positions from "original" if provided. + */ + /* @internal */ + export function createPartiallyEmittedExpression(expression: Expression, original?: Node, location?: TextRange) { + const node = createNode(SyntaxKind.PartiallyEmittedExpression, /*location*/ location || original); + node.expression = expression; + node.original = original; + return node; + } - export function createLogicalNot(operand: Expression) { - return createPrefix(SyntaxKind.ExclamationToken, operand); - } + /* @internal */ + export function updatePartiallyEmittedExpression(node: PartiallyEmittedExpression, expression: Expression) { + if (node.expression !== expression) { + return updateNode(createPartiallyEmittedExpression(expression, node.original, node), node); + } + return node; + } - export function createVoidZero() { - return createVoid(createLiteral(0)); - } + // Compound nodes - export function createMemberAccessForPropertyName(target: Expression, memberName: PropertyName, location?: TextRange): MemberExpression { - if (isComputedPropertyName(memberName)) { - return createElementAccess(target, memberName.expression, location); + export function createComma(left: Expression, right: Expression) { + return createBinary(left, SyntaxKind.CommaToken, right); } - else { - const expression = isIdentifier(memberName) ? createPropertyAccess(target, memberName, location) : createElementAccess(target, memberName, location); - (expression.emitNode || (expression.emitNode = {})).flags |= EmitFlags.NoNestedSourceMaps; - return expression; + + export function createLessThan(left: Expression, right: Expression, location?: TextRange) { + return createBinary(left, SyntaxKind.LessThanToken, right, location); } - } - export function createRestParameter(name: string | Identifier) { - return createParameterDeclaration( - /*decorators*/ undefined, - /*modifiers*/ undefined, - createToken(SyntaxKind.DotDotDotToken), - name, - /*questionToken*/ undefined, - /*type*/ undefined, - /*initializer*/ undefined - ); - } + export function createAssignment(left: Expression, right: Expression, location?: TextRange) { + return createBinary(left, SyntaxKind.EqualsToken, right, location); + } - export function createFunctionCall(func: Expression, thisArg: Expression, argumentsList: Expression[], location?: TextRange) { - return createCall( - createPropertyAccess(func, "call"), - /*typeArguments*/ undefined, - [ - thisArg, - ...argumentsList - ], - location - ); - } + export function createStrictEquality(left: Expression, right: Expression) { + return createBinary(left, SyntaxKind.EqualsEqualsEqualsToken, right); + } - export function createFunctionApply(func: Expression, thisArg: Expression, argumentsExpression: Expression, location?: TextRange) { - return createCall( - createPropertyAccess(func, "apply"), - /*typeArguments*/ undefined, - [ - thisArg, - argumentsExpression - ], - location - ); - } + export function createStrictInequality(left: Expression, right: Expression) { + return createBinary(left, SyntaxKind.ExclamationEqualsEqualsToken, right); + } - export function createArraySlice(array: Expression, start?: number | Expression) { - const argumentsList: Expression[] = []; - if (start !== undefined) { - argumentsList.push(typeof start === "number" ? createLiteral(start) : start); + export function createAdd(left: Expression, right: Expression) { + return createBinary(left, SyntaxKind.PlusToken, right); } - return createCall(createPropertyAccess(array, "slice"), /*typeArguments*/ undefined, argumentsList); - } + export function createSubtract(left: Expression, right: Expression) { + return createBinary(left, SyntaxKind.MinusToken, right); + } - export function createArrayConcat(array: Expression, values: Expression[]) { - return createCall( - createPropertyAccess(array, "concat"), - /*typeArguments*/ undefined, - values - ); - } + export function createPostfixIncrement(operand: Expression, location?: TextRange) { + return createPostfix(operand, SyntaxKind.PlusPlusToken, location); + } - export function createMathPow(left: Expression, right: Expression, location?: TextRange) { - return createCall( - createPropertyAccess(createIdentifier("Math"), "pow"), - /*typeArguments*/ undefined, - [left, right], - location - ); - } + export function createLogicalAnd(left: Expression, right: Expression) { + return createBinary(left, SyntaxKind.AmpersandAmpersandToken, right); + } - function createReactNamespace(reactNamespace: string, parent: JsxOpeningLikeElement) { - // 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; - return react; - } + export function createLogicalOr(left: Expression, right: Expression) { + return createBinary(left, SyntaxKind.BarBarToken, right); + } - export function createReactCreateElement(reactNamespace: string, tagName: Expression, props: Expression, children: Expression[], parentElement: JsxOpeningLikeElement, location: TextRange): LeftHandSideExpression { - const argumentsList = [tagName]; - if (props) { - argumentsList.push(props); + export function createLogicalNot(operand: Expression) { + return createPrefix(SyntaxKind.ExclamationToken, operand); } - if (children && children.length > 0) { - if (!props) { - argumentsList.push(createNull()); - } + export function createVoidZero() { + return createVoid(createLiteral(0)); + } - if (children.length > 1) { - for (const child of children) { - child.startsOnNewLine = true; - argumentsList.push(child); - } + export function createMemberAccessForPropertyName(target: Expression, memberName: PropertyName, location?: TextRange): MemberExpression { + if (isComputedPropertyName(memberName)) { + return createElementAccess(target, memberName.expression, location); } else { - argumentsList.push(children[0]); + const expression = isIdentifier(memberName) ? createPropertyAccess(target, memberName, location) : createElementAccess(target, memberName, location); + (expression.emitNode || (expression.emitNode = {})).flags |= EmitFlags.NoNestedSourceMaps; + return expression; } } - return createCall( - createPropertyAccess( - createReactNamespace(reactNamespace, parentElement), - "createElement" - ), - /*typeArguments*/ undefined, - argumentsList, - location - ); - } + export function createRestParameter(name: string | Identifier) { + return createParameterDeclaration( + /*decorators*/ undefined, + /*modifiers*/ undefined, + createToken(SyntaxKind.DotDotDotToken), + name, + /*questionToken*/ undefined, + /*type*/ undefined, + /*initializer*/ undefined + ); + } - export function createLetDeclarationList(declarations: VariableDeclaration[], location?: TextRange) { - return createVariableDeclarationList(declarations, location, NodeFlags.Let); - } + export function createFunctionCall(func: Expression, thisArg: Expression, argumentsList: Expression[], location?: TextRange) { + return createCall( + createPropertyAccess(func, "call"), + /*typeArguments*/ undefined, + [ + thisArg, + ...argumentsList + ], + location + ); + } - export function createConstDeclarationList(declarations: VariableDeclaration[], location?: TextRange) { - return createVariableDeclarationList(declarations, location, NodeFlags.Const); - } + export function createFunctionApply(func: Expression, thisArg: Expression, argumentsExpression: Expression, location?: TextRange) { + return createCall( + createPropertyAccess(func, "apply"), + /*typeArguments*/ undefined, + [ + thisArg, + argumentsExpression + ], + location + ); + } - // Helpers + export function createArraySlice(array: Expression, start?: number | Expression) { + const argumentsList: Expression[] = []; + if (start !== undefined) { + argumentsList.push(typeof start === "number" ? createLiteral(start) : start); + } - export function createHelperName(externalHelpersModuleName: Identifier | undefined, name: string) { - return externalHelpersModuleName - ? createPropertyAccess(externalHelpersModuleName, name) - : createIdentifier(name); - } + return createCall(createPropertyAccess(array, "slice"), /*typeArguments*/ undefined, argumentsList); + } - export function createExtendsHelper(externalHelpersModuleName: Identifier | undefined, name: Identifier) { - return createCall( - createHelperName(externalHelpersModuleName, "__extends"), - /*typeArguments*/ undefined, - [ - name, - createIdentifier("_super") - ] - ); - } + export function createArrayConcat(array: Expression, values: Expression[]) { + return createCall( + createPropertyAccess(array, "concat"), + /*typeArguments*/ undefined, + values + ); + } - export function createAssignHelper(externalHelpersModuleName: Identifier | undefined, attributesSegments: Expression[]) { - return createCall( - createHelperName(externalHelpersModuleName, "__assign"), - /*typeArguments*/ undefined, - attributesSegments - ); - } + export function createMathPow(left: Expression, right: Expression, location?: TextRange) { + return createCall( + createPropertyAccess(createIdentifier("Math"), "pow"), + /*typeArguments*/ undefined, + [left, right], + location + ); + } - export function createParamHelper(externalHelpersModuleName: Identifier | undefined, expression: Expression, parameterOffset: number, location?: TextRange) { - return createCall( - createHelperName(externalHelpersModuleName, "__param"), - /*typeArguments*/ undefined, - [ - createLiteral(parameterOffset), - expression - ], - location - ); - } + function createReactNamespace(reactNamespace: string, parent: JsxOpeningLikeElement) { + // 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; + return react; + } - export function createMetadataHelper(externalHelpersModuleName: Identifier | undefined, metadataKey: string, metadataValue: Expression) { - return createCall( - createHelperName(externalHelpersModuleName, "__metadata"), - /*typeArguments*/ undefined, - [ - createLiteral(metadataKey), - metadataValue - ] - ); - } + export function createReactCreateElement(reactNamespace: string, tagName: Expression, props: Expression, children: Expression[], parentElement: JsxOpeningLikeElement, location: TextRange): LeftHandSideExpression { + const argumentsList = [tagName]; + if (props) { + argumentsList.push(props); + } + + if (children && children.length > 0) { + if (!props) { + argumentsList.push(createNull()); + } + + if (children.length > 1) { + for (const child of children) { + child.startsOnNewLine = true; + argumentsList.push(child); + } + } + else { + argumentsList.push(children[0]); + } + } + + return createCall( + createPropertyAccess( + createReactNamespace(reactNamespace, parentElement), + "createElement" + ), + /*typeArguments*/ undefined, + argumentsList, + location + ); + } + + export function createLetDeclarationList(declarations: VariableDeclaration[], location?: TextRange) { + return createVariableDeclarationList(declarations, location, NodeFlags.Let); + } + + export function createConstDeclarationList(declarations: VariableDeclaration[], location?: TextRange) { + return createVariableDeclarationList(declarations, location, NodeFlags.Const); + } + + // Helpers + + export function createHelperName(externalHelpersModuleName: Identifier | undefined, name: string) { + return externalHelpersModuleName + ? createPropertyAccess(externalHelpersModuleName, name) + : createIdentifier(name); + } + + export function createExtendsHelper(externalHelpersModuleName: Identifier | undefined, name: Identifier) { + return createCall( + createHelperName(externalHelpersModuleName, "__extends"), + /*typeArguments*/ undefined, + [ + name, + createIdentifier("_super") + ] + ); + } + + export function createAssignHelper(externalHelpersModuleName: Identifier | undefined, attributesSegments: Expression[]) { + return createCall( + createHelperName(externalHelpersModuleName, "__assign"), + /*typeArguments*/ undefined, + attributesSegments + ); + } - export function createDecorateHelper(externalHelpersModuleName: Identifier | undefined, decoratorExpressions: Expression[], target: Expression, memberName?: Expression, descriptor?: Expression, location?: TextRange) { - const argumentsArray: Expression[] = []; - argumentsArray.push(createArrayLiteral(decoratorExpressions, /*location*/ undefined, /*multiLine*/ true)); - argumentsArray.push(target); - if (memberName) { - argumentsArray.push(memberName); - if (descriptor) { - argumentsArray.push(descriptor); + export function createParamHelper(externalHelpersModuleName: Identifier | undefined, expression: Expression, parameterOffset: number, location?: TextRange) { + return createCall( + createHelperName(externalHelpersModuleName, "__param"), + /*typeArguments*/ undefined, + [ + createLiteral(parameterOffset), + expression + ], + location + ); + } + + export function createMetadataHelper(externalHelpersModuleName: Identifier | undefined, metadataKey: string, metadataValue: Expression) { + return createCall( + createHelperName(externalHelpersModuleName, "__metadata"), + /*typeArguments*/ undefined, + [ + createLiteral(metadataKey), + metadataValue + ] + ); + } + + export function createDecorateHelper(externalHelpersModuleName: Identifier | undefined, decoratorExpressions: Expression[], target: Expression, memberName?: Expression, descriptor?: Expression, location?: TextRange) { + const argumentsArray: Expression[] = []; + argumentsArray.push(createArrayLiteral(decoratorExpressions, /*location*/ undefined, /*multiLine*/ true)); + argumentsArray.push(target); + if (memberName) { + argumentsArray.push(memberName); + if (descriptor) { + argumentsArray.push(descriptor); + } } + + return createCall(createHelperName(externalHelpersModuleName, "__decorate"), /*typeArguments*/ undefined, argumentsArray, location); } - return createCall(createHelperName(externalHelpersModuleName, "__decorate"), /*typeArguments*/ undefined, argumentsArray, location); - } + export function createAwaiterHelper(externalHelpersModuleName: Identifier | undefined, hasLexicalArguments: boolean, promiseConstructor: EntityName | Expression, body: Block) { + const generatorFunc = createFunctionExpression( + createToken(SyntaxKind.AsteriskToken), + /*name*/ undefined, + /*typeParameters*/ undefined, + /*parameters*/ [], + /*type*/ undefined, + body + ); - export function createAwaiterHelper(externalHelpersModuleName: Identifier | undefined, hasLexicalArguments: boolean, promiseConstructor: EntityName | Expression, body: Block) { - const generatorFunc = createFunctionExpression( - createToken(SyntaxKind.AsteriskToken), - /*name*/ undefined, - /*typeParameters*/ undefined, - /*parameters*/ [], - /*type*/ undefined, - body - ); - - // Mark this node as originally an async function - (generatorFunc.emitNode || (generatorFunc.emitNode = {})).flags |= EmitFlags.AsyncFunctionBody; - - return createCall( - createHelperName(externalHelpersModuleName, "__awaiter"), - /*typeArguments*/ undefined, - [ - createThis(), - hasLexicalArguments ? createIdentifier("arguments") : createVoidZero(), - promiseConstructor ? createExpressionFromEntityName(promiseConstructor) : createVoidZero(), - generatorFunc - ] - ); - } + // Mark this node as originally an async function + (generatorFunc.emitNode || (generatorFunc.emitNode = {})).flags |= EmitFlags.AsyncFunctionBody; - export function createHasOwnProperty(target: LeftHandSideExpression, propertyName: Expression) { - return createCall( - createPropertyAccess(target, "hasOwnProperty"), - /*typeArguments*/ undefined, - [propertyName] - ); - } + return createCall( + createHelperName(externalHelpersModuleName, "__awaiter"), + /*typeArguments*/ undefined, + [ + createThis(), + hasLexicalArguments ? createIdentifier("arguments") : createVoidZero(), + promiseConstructor ? createExpressionFromEntityName(promiseConstructor) : createVoidZero(), + generatorFunc + ] + ); + } - function createObjectCreate(prototype: Expression) { - return createCall( - createPropertyAccess(createIdentifier("Object"), "create"), - /*typeArguments*/ undefined, - [prototype] - ); - } + export function createHasOwnProperty(target: LeftHandSideExpression, propertyName: Expression) { + return createCall( + createPropertyAccess(target, "hasOwnProperty"), + /*typeArguments*/ undefined, + [propertyName] + ); + } - function createGeti(target: LeftHandSideExpression) { - // name => super[name] - return createArrowFunction( - /*modifiers*/ undefined, - /*typeParameters*/ undefined, - [createParameter("name")], - /*type*/ undefined, - /*equalsGreaterThanToken*/ undefined, - createElementAccess( - target, - createIdentifier("name") - ) - ); - } + function createObjectCreate(prototype: Expression) { + return createCall( + createPropertyAccess(createIdentifier("Object"), "create"), + /*typeArguments*/ undefined, + [prototype] + ); + } - function createSeti(target: LeftHandSideExpression) { - // (name, value) => super[name] = value - return createArrowFunction( - /*modifiers*/ undefined, - /*typeParameters*/ undefined, - [ - createParameter("name"), - createParameter("value") - ], - /*type*/ undefined, - /*equalsGreaterThanToken*/ undefined, - createAssignment( + function createGeti(target: LeftHandSideExpression) { + // name => super[name] + return createArrowFunction( + /*modifiers*/ undefined, + /*typeParameters*/ undefined, + [createParameter("name")], + /*type*/ undefined, + /*equalsGreaterThanToken*/ undefined, createElementAccess( target, createIdentifier("name") - ), - createIdentifier("value") - ) - ); - } - - export function createAdvancedAsyncSuperHelper() { - // const _super = (function (geti, seti) { - // const cache = Object.create(null); - // return name => cache[name] || (cache[name] = { get value() { return geti(name); }, set value(v) { seti(name, v); } }); - // })(name => super[name], (name, value) => super[name] = value); - - // const cache = Object.create(null); - const createCache = createVariableStatement( - /*modifiers*/ undefined, - createConstDeclarationList([ - createVariableDeclaration( - "cache", - /*type*/ undefined, - createObjectCreate(createNull()) - ) - ]) - ); - - // get value() { return geti(name); } - const getter = createGetAccessor( - /*decorators*/ undefined, - /*modifiers*/ undefined, - "value", - /*parameters*/ [], - /*type*/ undefined, - createBlock([ - createReturn( - createCall( - createIdentifier("geti"), - /*typeArguments*/ undefined, - [createIdentifier("name")] - ) - ) - ]) - ); - - // set value(v) { seti(name, v); } - const setter = createSetAccessor( - /*decorators*/ undefined, - /*modifiers*/ undefined, - "value", - [createParameter("v")], - createBlock([ - createStatement( - createCall( - createIdentifier("seti"), - /*typeArguments*/ undefined, - [ - createIdentifier("name"), - createIdentifier("v") - ] - ) ) - ]) - ); + ); + } - // return name => cache[name] || ... - const getOrCreateAccessorsForName = createReturn( - createArrowFunction( + function createSeti(target: LeftHandSideExpression) { + // (name, value) => super[name] = value + return createArrowFunction( /*modifiers*/ undefined, /*typeParameters*/ undefined, - [createParameter("name")], + [ + createParameter("name"), + createParameter("value") + ], /*type*/ undefined, /*equalsGreaterThanToken*/ undefined, - createLogicalOr( + createAssignment( createElementAccess( - createIdentifier("cache"), + target, createIdentifier("name") ), - createParen( - createAssignment( - createElementAccess( - createIdentifier("cache"), - createIdentifier("name") - ), - createObjectLiteral([ - getter, - setter - ]) + createIdentifier("value") + ) + ); + } + + export function createAdvancedAsyncSuperHelper() { + // const _super = (function (geti, seti) { + // const cache = Object.create(null); + // return name => cache[name] || (cache[name] = { get value() { return geti(name); }, set value(v) { seti(name, v); } }); + // })(name => super[name], (name, value) => super[name] = value); + + // const cache = Object.create(null); + const createCache = createVariableStatement( + /*modifiers*/ undefined, + createConstDeclarationList([ + createVariableDeclaration( + "cache", + /*type*/ undefined, + createObjectCreate(createNull()) + ) + ]) + ); + + // get value() { return geti(name); } + const getter = createGetAccessor( + /*decorators*/ undefined, + /*modifiers*/ undefined, + "value", + /*parameters*/ [], + /*type*/ undefined, + createBlock([ + createReturn( + createCall( + createIdentifier("geti"), + /*typeArguments*/ undefined, + [createIdentifier("name")] ) ) - ) - ) - ); - - // const _super = (function (geti, seti) { - // const cache = Object.create(null); - // return name => cache[name] || (cache[name] = { get value() { return geti(name); }, set value(v) { seti(name, v); } }); - // })(name => super[name], (name, value) => super[name] = value); - return createVariableStatement( - /*modifiers*/ undefined, - createConstDeclarationList([ - createVariableDeclaration( - "_super", + ]) + ); + + // set value(v) { seti(name, v); } + const setter = createSetAccessor( + /*decorators*/ undefined, + /*modifiers*/ undefined, + "value", + [createParameter("v")], + createBlock([ + createStatement( + createCall( + createIdentifier("seti"), + /*typeArguments*/ undefined, + [ + createIdentifier("name"), + createIdentifier("v") + ] + ) + ) + ]) + ); + + // return name => cache[name] || ... + const getOrCreateAccessorsForName = createReturn( + createArrowFunction( + /*modifiers*/ undefined, + /*typeParameters*/ undefined, + [createParameter("name")], /*type*/ undefined, - createCall( + /*equalsGreaterThanToken*/ undefined, + createLogicalOr( + createElementAccess( + createIdentifier("cache"), + createIdentifier("name") + ), createParen( - createFunctionExpression( - /*asteriskToken*/ undefined, - /*name*/ undefined, - /*typeParameters*/ undefined, - [ - createParameter("geti"), - createParameter("seti") - ], - /*type*/ undefined, - createBlock([ - createCache, - getOrCreateAccessorsForName + createAssignment( + createElementAccess( + createIdentifier("cache"), + createIdentifier("name") + ), + createObjectLiteral([ + getter, + setter ]) ) - ), - /*typeArguments*/ undefined, - [ - createGeti(createSuper()), - createSeti(createSuper()) - ] + ) ) ) - ]) - ); - } + ); - export function createSimpleAsyncSuperHelper() { - return createVariableStatement( - /*modifiers*/ undefined, - createConstDeclarationList([ - createVariableDeclaration( - "_super", - /*type*/ undefined, - createGeti(createSuper()) - ) - ]) - ); - } + // const _super = (function (geti, seti) { + // const cache = Object.create(null); + // return name => cache[name] || (cache[name] = { get value() { return geti(name); }, set value(v) { seti(name, v); } }); + // })(name => super[name], (name, value) => super[name] = value); + return createVariableStatement( + /*modifiers*/ undefined, + createConstDeclarationList([ + createVariableDeclaration( + "_super", + /*type*/ undefined, + createCall( + createParen( + createFunctionExpression( + /*asteriskToken*/ undefined, + /*name*/ undefined, + /*typeParameters*/ undefined, + [ + createParameter("geti"), + createParameter("seti") + ], + /*type*/ undefined, + createBlock([ + createCache, + getOrCreateAccessorsForName + ]) + ) + ), + /*typeArguments*/ undefined, + [ + createGeti(createSuper()), + createSeti(createSuper()) + ] + ) + ) + ]) + ); + } - export interface CallBinding { - target: LeftHandSideExpression; - thisArg: Expression; - } + export function createSimpleAsyncSuperHelper() { + return createVariableStatement( + /*modifiers*/ undefined, + createConstDeclarationList([ + createVariableDeclaration( + "_super", + /*type*/ undefined, + createGeti(createSuper()) + ) + ]) + ); + } - function shouldBeCapturedInTempVariable(node: Expression, cacheIdentifiers: boolean): boolean { - const target = skipParentheses(node); - switch (target.kind) { - case SyntaxKind.Identifier: - return cacheIdentifiers; - case SyntaxKind.ThisKeyword: - case SyntaxKind.NumericLiteral: - case SyntaxKind.StringLiteral: - return false; - case SyntaxKind.ArrayLiteralExpression: - const elements = (target).elements; - if (elements.length === 0) { - return false; - } - return true; - case SyntaxKind.ObjectLiteralExpression: - return (target).properties.length > 0; - default: - return true; + export interface CallBinding { + target: LeftHandSideExpression; + thisArg: Expression; } - } - export function createCallBinding(expression: Expression, recordTempVariable: (temp: Identifier) => void, languageVersion?: ScriptTarget, cacheIdentifiers?: boolean): CallBinding { - const callee = skipOuterExpressions(expression, OuterExpressionKinds.All); - let thisArg: Expression; - let target: LeftHandSideExpression; - if (isSuperProperty(callee)) { - thisArg = createThis(); - target = callee; - } - else if (callee.kind === SyntaxKind.SuperKeyword) { - thisArg = createThis(); - target = languageVersion < ScriptTarget.ES6 ? createIdentifier("_super", /*location*/ callee) : callee; - } - else { - switch (callee.kind) { - case SyntaxKind.PropertyAccessExpression: { - if (shouldBeCapturedInTempVariable((callee).expression, cacheIdentifiers)) { - // for `a.b()` target is `(_a = a).b` and thisArg is `_a` - thisArg = createTempVariable(recordTempVariable); - target = createPropertyAccess( - createAssignment( - thisArg, - (callee).expression, - /*location*/ (callee).expression - ), - (callee).name, - /*location*/ callee - ); - } - else { - thisArg = (callee).expression; - target = callee; + function shouldBeCapturedInTempVariable(node: Expression, cacheIdentifiers: boolean): boolean { + const target = skipParentheses(node); + switch (target.kind) { + case SyntaxKind.Identifier: + return cacheIdentifiers; + case SyntaxKind.ThisKeyword: + case SyntaxKind.NumericLiteral: + case SyntaxKind.StringLiteral: + return false; + case SyntaxKind.ArrayLiteralExpression: + const elements = (target).elements; + if (elements.length === 0) { + return false; } - break; - } + return true; + case SyntaxKind.ObjectLiteralExpression: + return (target).properties.length > 0; + default: + return true; + } + } - case SyntaxKind.ElementAccessExpression: { - if (shouldBeCapturedInTempVariable((callee).expression, cacheIdentifiers)) { - // for `a[b]()` target is `(_a = a)[b]` and thisArg is `_a` - thisArg = createTempVariable(recordTempVariable); - target = createElementAccess( - createAssignment( - thisArg, - (callee).expression, - /*location*/ (callee).expression - ), - (callee).argumentExpression, - /*location*/ callee - ); - } - else { - thisArg = (callee).expression; - target = callee; + export function createCallBinding(expression: Expression, recordTempVariable: (temp: Identifier) => void, languageVersion?: ScriptTarget, cacheIdentifiers?: boolean): CallBinding { + const callee = skipOuterExpressions(expression, OuterExpressionKinds.All); + let thisArg: Expression; + let target: LeftHandSideExpression; + if (isSuperProperty(callee)) { + thisArg = createThis(); + target = callee; + } + else if (callee.kind === SyntaxKind.SuperKeyword) { + thisArg = createThis(); + target = languageVersion < ScriptTarget.ES6 ? createIdentifier("_super", /*location*/ callee) : callee; + } + else { + switch (callee.kind) { + case SyntaxKind.PropertyAccessExpression: { + if (shouldBeCapturedInTempVariable((callee).expression, cacheIdentifiers)) { + // for `a.b()` target is `(_a = a).b` and thisArg is `_a` + thisArg = createTempVariable(recordTempVariable); + target = createPropertyAccess( + createAssignment( + thisArg, + (callee).expression, + /*location*/ (callee).expression + ), + (callee).name, + /*location*/ callee + ); + } + else { + thisArg = (callee).expression; + target = callee; + } + break; } - break; - } + case SyntaxKind.ElementAccessExpression: { + if (shouldBeCapturedInTempVariable((callee).expression, cacheIdentifiers)) { + // for `a[b]()` target is `(_a = a)[b]` and thisArg is `_a` + thisArg = createTempVariable(recordTempVariable); + target = createElementAccess( + createAssignment( + thisArg, + (callee).expression, + /*location*/ (callee).expression + ), + (callee).argumentExpression, + /*location*/ callee + ); + } + else { + thisArg = (callee).expression; + target = callee; + } + + break; + } - default: { - // for `a()` target is `a` and thisArg is `void 0` - thisArg = createVoidZero(); - target = parenthesizeForAccess(expression); - break; + default: { + // for `a()` target is `a` and thisArg is `void 0` + thisArg = createVoidZero(); + target = parenthesizeForAccess(expression); + break; + } } } - } - - return { target, thisArg }; - } - - export function inlineExpressions(expressions: Expression[]) { - return reduceLeft(expressions, createComma); - } - export function createExpressionFromEntityName(node: EntityName | Expression): Expression { - if (isQualifiedName(node)) { - const left = createExpressionFromEntityName(node.left); - const right = getMutableClone(node.right); - return createPropertyAccess(left, right, /*location*/ node); - } - else { - return getMutableClone(node); + return { target, thisArg }; } - } - export function createExpressionForPropertyName(memberName: PropertyName): Expression { - if (isIdentifier(memberName)) { - return createLiteral(memberName, /*location*/ undefined); - } - else if (isComputedPropertyName(memberName)) { - return getMutableClone(memberName.expression); + export function inlineExpressions(expressions: Expression[]) { + return reduceLeft(expressions, createComma); } - else { - return getMutableClone(memberName); + + export function createExpressionFromEntityName(node: EntityName | Expression): Expression { + if (isQualifiedName(node)) { + const left = createExpressionFromEntityName(node.left); + const right = getMutableClone(node.right); + return createPropertyAccess(left, right, /*location*/ node); + } + else { + return getMutableClone(node); + } } - } - export function createExpressionForObjectLiteralElementLike(node: ObjectLiteralExpression, property: ObjectLiteralElementLike, receiver: Expression): Expression { - switch (property.kind) { - case SyntaxKind.GetAccessor: - case SyntaxKind.SetAccessor: - return createExpressionForAccessorDeclaration(node.properties, property, receiver, node.multiLine); - case SyntaxKind.PropertyAssignment: - return createExpressionForPropertyAssignment(property, receiver); - case SyntaxKind.ShorthandPropertyAssignment: - return createExpressionForShorthandPropertyAssignment(property, receiver); - case SyntaxKind.MethodDeclaration: - return createExpressionForMethodDeclaration(property, receiver); + export function createExpressionForPropertyName(memberName: PropertyName): Expression { + if (isIdentifier(memberName)) { + return createLiteral(memberName, /*location*/ undefined); + } + else if (isComputedPropertyName(memberName)) { + return getMutableClone(memberName.expression); + } + else { + return getMutableClone(memberName); + } } - } - function createExpressionForAccessorDeclaration(properties: NodeArray, property: AccessorDeclaration, receiver: Expression, multiLine: boolean) { - const { firstAccessor, getAccessor, setAccessor } = getAllAccessorDeclarations(properties, property); - if (property === firstAccessor) { - const properties: ObjectLiteralElementLike[] = []; - if (getAccessor) { - const getterFunction = createFunctionExpression( - /*asteriskToken*/ undefined, - /*name*/ undefined, - /*typeParameters*/ undefined, - getAccessor.parameters, - /*type*/ undefined, - getAccessor.body, - /*location*/ getAccessor - ); - setOriginalNode(getterFunction, getAccessor); - const getter = createPropertyAssignment("get", getterFunction); - properties.push(getter); + export function createExpressionForObjectLiteralElementLike(node: ObjectLiteralExpression, property: ObjectLiteralElementLike, receiver: Expression): Expression { + switch (property.kind) { + case SyntaxKind.GetAccessor: + case SyntaxKind.SetAccessor: + return createExpressionForAccessorDeclaration(node.properties, property, receiver, node.multiLine); + case SyntaxKind.PropertyAssignment: + return createExpressionForPropertyAssignment(property, receiver); + case SyntaxKind.ShorthandPropertyAssignment: + return createExpressionForShorthandPropertyAssignment(property, receiver); + case SyntaxKind.MethodDeclaration: + return createExpressionForMethodDeclaration(property, receiver); } + } - if (setAccessor) { - const setterFunction = createFunctionExpression( - /*asteriskToken*/ undefined, - /*name*/ undefined, - /*typeParameters*/ undefined, - setAccessor.parameters, - /*type*/ undefined, - setAccessor.body, - /*location*/ setAccessor + function createExpressionForAccessorDeclaration(properties: NodeArray, property: AccessorDeclaration, receiver: Expression, multiLine: boolean) { + const { firstAccessor, getAccessor, setAccessor } = getAllAccessorDeclarations(properties, property); + if (property === firstAccessor) { + const properties: ObjectLiteralElementLike[] = []; + if (getAccessor) { + const getterFunction = createFunctionExpression( + /*asteriskToken*/ undefined, + /*name*/ undefined, + /*typeParameters*/ undefined, + getAccessor.parameters, + /*type*/ undefined, + getAccessor.body, + /*location*/ getAccessor + ); + setOriginalNode(getterFunction, getAccessor); + const getter = createPropertyAssignment("get", getterFunction); + properties.push(getter); + } + + if (setAccessor) { + const setterFunction = createFunctionExpression( + /*asteriskToken*/ undefined, + /*name*/ undefined, + /*typeParameters*/ undefined, + setAccessor.parameters, + /*type*/ undefined, + setAccessor.body, + /*location*/ setAccessor + ); + setOriginalNode(setterFunction, setAccessor); + const setter = createPropertyAssignment("set", setterFunction); + properties.push(setter); + } + + properties.push(createPropertyAssignment("enumerable", createLiteral(true))); + properties.push(createPropertyAssignment("configurable", createLiteral(true))); + + const expression = createCall( + createPropertyAccess(createIdentifier("Object"), "defineProperty"), + /*typeArguments*/ undefined, + [ + receiver, + createExpressionForPropertyName(property.name), + createObjectLiteral(properties, /*location*/ undefined, multiLine) + ], + /*location*/ firstAccessor ); - setOriginalNode(setterFunction, setAccessor); - const setter = createPropertyAssignment("set", setterFunction); - properties.push(setter); + + return aggregateTransformFlags(expression); } - properties.push(createPropertyAssignment("enumerable", createLiteral(true))); - properties.push(createPropertyAssignment("configurable", createLiteral(true))); + return undefined; + } - const expression = createCall( - createPropertyAccess(createIdentifier("Object"), "defineProperty"), - /*typeArguments*/ undefined, - [ - receiver, - createExpressionForPropertyName(property.name), - createObjectLiteral(properties, /*location*/ undefined, multiLine) - ], - /*location*/ firstAccessor + function createExpressionForPropertyAssignment(property: PropertyAssignment, receiver: Expression) { + return aggregateTransformFlags( + setOriginalNode( + createAssignment( + createMemberAccessForPropertyName(receiver, property.name, /*location*/ property.name), + property.initializer, + /*location*/ property + ), + /*original*/ property + ) ); - - return aggregateTransformFlags(expression); } - return undefined; - } - - function createExpressionForPropertyAssignment(property: PropertyAssignment, receiver: Expression) { - return aggregateTransformFlags( - setOriginalNode( - createAssignment( - createMemberAccessForPropertyName(receiver, property.name, /*location*/ property.name), - property.initializer, - /*location*/ property - ), - /*original*/ property - ) - ); - } - - function createExpressionForShorthandPropertyAssignment(property: ShorthandPropertyAssignment, receiver: Expression) { - return aggregateTransformFlags( - setOriginalNode( - createAssignment( - createMemberAccessForPropertyName(receiver, property.name, /*location*/ property.name), - getSynthesizedClone(property.name), - /*location*/ property - ), - /*original*/ property - ) - ); - } + function createExpressionForShorthandPropertyAssignment(property: ShorthandPropertyAssignment, receiver: Expression) { + return aggregateTransformFlags( + setOriginalNode( + createAssignment( + createMemberAccessForPropertyName(receiver, property.name, /*location*/ property.name), + getSynthesizedClone(property.name), + /*location*/ property + ), + /*original*/ property + ) + ); + } - function createExpressionForMethodDeclaration(method: MethodDeclaration, receiver: Expression) { - return aggregateTransformFlags( - setOriginalNode( - createAssignment( - createMemberAccessForPropertyName(receiver, method.name, /*location*/ method.name), - setOriginalNode( - createFunctionExpression( - method.asteriskToken, - /*name*/ undefined, - /*typeParameters*/ undefined, - method.parameters, - /*type*/ undefined, - method.body, - /*location*/ method + function createExpressionForMethodDeclaration(method: MethodDeclaration, receiver: Expression) { + return aggregateTransformFlags( + setOriginalNode( + createAssignment( + createMemberAccessForPropertyName(receiver, method.name, /*location*/ method.name), + setOriginalNode( + createFunctionExpression( + method.asteriskToken, + /*name*/ undefined, + /*typeParameters*/ undefined, + method.parameters, + /*type*/ undefined, + method.body, + /*location*/ method + ), + /*original*/ method ), - /*original*/ method + /*location*/ method ), - /*location*/ method - ), - /*original*/ method - ) - ); - } - - // Utilities - - function isUseStrictPrologue(node: ExpressionStatement): boolean { - return (node.expression as StringLiteral).text === "use strict"; - } + /*original*/ method + ) + ); + } - /** - * Add any necessary prologue-directives into target statement-array. - * The function needs to be called during each transformation step. - * This function needs to be called whenever we transform the statement - * list of a source file, namespace, or function-like body. - * - * @param target: result statements array - * @param source: origin statements array - * @param ensureUseStrict: boolean determining whether the function need to add prologue-directives - * @param visitor: Optional callback used to visit any custom prologue directives. - */ - export function addPrologueDirectives(target: Statement[], source: Statement[], ensureUseStrict?: boolean, visitor?: (node: Node) => VisitResult): number { - Debug.assert(target.length === 0, "PrologueDirectives should be at the first statement in the target statements array"); - let foundUseStrict = false; - let statementOffset = 0; - const numStatements = source.length; - while (statementOffset < numStatements) { - const statement = source[statementOffset]; - if (isPrologueDirective(statement)) { - if (isUseStrictPrologue(statement as ExpressionStatement)) { - foundUseStrict = true; - } - target.push(statement); - } - else { - if (ensureUseStrict && !foundUseStrict) { - target.push(startOnNewLine(createStatement(createLiteral("use strict")))); - foundUseStrict = true; - } - if (getEmitFlags(statement) & EmitFlags.CustomPrologue) { - target.push(visitor ? visitNode(statement, visitor, isStatement) : statement); + // Utilities + + function isUseStrictPrologue(node: ExpressionStatement): boolean { + return (node.expression as StringLiteral).text === "use strict"; + } + + /** + * Add any necessary prologue-directives into target statement-array. + * The function needs to be called during each transformation step. + * This function needs to be called whenever we transform the statement + * list of a source file, namespace, or function-like body. + * + * @param target: result statements array + * @param source: origin statements array + * @param ensureUseStrict: boolean determining whether the function need to add prologue-directives + * @param visitor: Optional callback used to visit any custom prologue directives. + */ + export function addPrologueDirectives(target: Statement[], source: Statement[], ensureUseStrict?: boolean, visitor?: (node: Node) => VisitResult): number { + Debug.assert(target.length === 0, "PrologueDirectives should be at the first statement in the target statements array"); + let foundUseStrict = false; + let statementOffset = 0; + const numStatements = source.length; + while (statementOffset < numStatements) { + const statement = source[statementOffset]; + if (isPrologueDirective(statement)) { + if (isUseStrictPrologue(statement as ExpressionStatement)) { + foundUseStrict = true; + } + target.push(statement); } else { - break; + if (ensureUseStrict && !foundUseStrict) { + target.push(startOnNewLine(createStatement(createLiteral("use strict")))); + foundUseStrict = true; + } + if (getEmitFlags(statement) & EmitFlags.CustomPrologue) { + target.push(visitor ? visitNode(statement, visitor, isStatement) : statement); + } + else { + break; + } } + statementOffset++; + } + return statementOffset; + } + + /** + * Wraps the operand to a BinaryExpression in parentheses if they are needed to preserve the intended + * order of operations. + * + * @param binaryOperator The operator for the BinaryExpression. + * @param operand The operand for the BinaryExpression. + * @param isLeftSideOfBinary A value indicating whether the operand is the left side of the + * BinaryExpression. + */ + export function parenthesizeBinaryOperand(binaryOperator: SyntaxKind, operand: Expression, isLeftSideOfBinary: boolean, leftOperand?: Expression) { + const skipped = skipPartiallyEmittedExpressions(operand); + + // If the resulting expression is already parenthesized, we do not need to do any further processing. + if (skipped.kind === SyntaxKind.ParenthesizedExpression) { + return operand; } - statementOffset++; - } - return statementOffset; - } - /** - * Wraps the operand to a BinaryExpression in parentheses if they are needed to preserve the intended - * order of operations. - * - * @param binaryOperator The operator for the BinaryExpression. - * @param operand The operand for the BinaryExpression. - * @param isLeftSideOfBinary A value indicating whether the operand is the left side of the - * BinaryExpression. - */ - export function parenthesizeBinaryOperand(binaryOperator: SyntaxKind, operand: Expression, isLeftSideOfBinary: boolean, leftOperand?: Expression) { - const skipped = skipPartiallyEmittedExpressions(operand); - - // If the resulting expression is already parenthesized, we do not need to do any further processing. - if (skipped.kind === SyntaxKind.ParenthesizedExpression) { - return operand; - } - - return binaryOperandNeedsParentheses(binaryOperator, operand, isLeftSideOfBinary, leftOperand) - ? createParen(operand) - : operand; - } + return binaryOperandNeedsParentheses(binaryOperator, operand, isLeftSideOfBinary, leftOperand) + ? createParen(operand) + : operand; + } + + /** + * Determines whether the operand to a BinaryExpression needs to be parenthesized. + * + * @param binaryOperator The operator for the BinaryExpression. + * @param operand The operand for the BinaryExpression. + * @param isLeftSideOfBinary A value indicating whether the operand is the left side of the + * BinaryExpression. + */ + function binaryOperandNeedsParentheses(binaryOperator: SyntaxKind, operand: Expression, isLeftSideOfBinary: boolean, leftOperand: Expression) { + // If the operand has lower precedence, then it needs to be parenthesized to preserve the + // intent of the expression. For example, if the operand is `a + b` and the operator is + // `*`, then we need to parenthesize the operand to preserve the intended order of + // operations: `(a + b) * x`. + // + // If the operand has higher precedence, then it does not need to be parenthesized. For + // example, if the operand is `a * b` and the operator is `+`, then we do not need to + // parenthesize to preserve the intended order of operations: `a * b + x`. + // + // If the operand has the same precedence, then we need to check the associativity of + // the operator based on whether this is the left or right operand of the expression. + // + // For example, if `a / d` is on the right of operator `*`, we need to parenthesize + // to preserve the intended order of operations: `x * (a / d)` + // + // If `a ** d` is on the left of operator `**`, we need to parenthesize to preserve + // the intended order of operations: `(a ** b) ** c` + const binaryOperatorPrecedence = getOperatorPrecedence(SyntaxKind.BinaryExpression, binaryOperator); + const binaryOperatorAssociativity = getOperatorAssociativity(SyntaxKind.BinaryExpression, binaryOperator); + const emittedOperand = skipPartiallyEmittedExpressions(operand); + const operandPrecedence = getExpressionPrecedence(emittedOperand); + switch (compareValues(operandPrecedence, binaryOperatorPrecedence)) { + case Comparison.LessThan: + // If the operand is the right side of a right-associative binary operation + // and is a yield expression, then we do not need parentheses. + if (!isLeftSideOfBinary + && binaryOperatorAssociativity === Associativity.Right + && operand.kind === SyntaxKind.YieldExpression) { + return false; + } - /** - * Determines whether the operand to a BinaryExpression needs to be parenthesized. - * - * @param binaryOperator The operator for the BinaryExpression. - * @param operand The operand for the BinaryExpression. - * @param isLeftSideOfBinary A value indicating whether the operand is the left side of the - * BinaryExpression. - */ - function binaryOperandNeedsParentheses(binaryOperator: SyntaxKind, operand: Expression, isLeftSideOfBinary: boolean, leftOperand: Expression) { - // If the operand has lower precedence, then it needs to be parenthesized to preserve the - // intent of the expression. For example, if the operand is `a + b` and the operator is - // `*`, then we need to parenthesize the operand to preserve the intended order of - // operations: `(a + b) * x`. - // - // If the operand has higher precedence, then it does not need to be parenthesized. For - // example, if the operand is `a * b` and the operator is `+`, then we do not need to - // parenthesize to preserve the intended order of operations: `a * b + x`. - // - // If the operand has the same precedence, then we need to check the associativity of - // the operator based on whether this is the left or right operand of the expression. - // - // For example, if `a / d` is on the right of operator `*`, we need to parenthesize - // to preserve the intended order of operations: `x * (a / d)` - // - // If `a ** d` is on the left of operator `**`, we need to parenthesize to preserve - // the intended order of operations: `(a ** b) ** c` - const binaryOperatorPrecedence = getOperatorPrecedence(SyntaxKind.BinaryExpression, binaryOperator); - const binaryOperatorAssociativity = getOperatorAssociativity(SyntaxKind.BinaryExpression, binaryOperator); - const emittedOperand = skipPartiallyEmittedExpressions(operand); - const operandPrecedence = getExpressionPrecedence(emittedOperand); - switch (compareValues(operandPrecedence, binaryOperatorPrecedence)) { - case Comparison.LessThan: - // If the operand is the right side of a right-associative binary operation - // and is a yield expression, then we do not need parentheses. - if (!isLeftSideOfBinary - && binaryOperatorAssociativity === Associativity.Right - && operand.kind === SyntaxKind.YieldExpression) { - return false; - } + return true; - return true; - - case Comparison.GreaterThan: - return false; - - case Comparison.EqualTo: - if (isLeftSideOfBinary) { - // No need to parenthesize the left operand when the binary operator is - // left associative: - // (a*b)/x -> a*b/x - // (a**b)/x -> a**b/x - // - // Parentheses are needed for the left operand when the binary operator is - // right associative: - // (a/b)**x -> (a/b)**x - // (a**b)**x -> (a**b)**x - return binaryOperatorAssociativity === Associativity.Right; - } - else { - if (isBinaryExpression(emittedOperand) - && emittedOperand.operatorToken.kind === binaryOperator) { - // No need to parenthesize the right operand when the binary operator and - // operand are the same and one of the following: - // x*(a*b) => x*a*b - // x|(a|b) => x|a|b - // x&(a&b) => x&a&b - // x^(a^b) => x^a^b - if (operatorHasAssociativeProperty(binaryOperator)) { - return false; - } + case Comparison.GreaterThan: + return false; - // No need to parenthesize the right operand when the binary operator - // is plus (+) if both the left and right operands consist solely of either - // literals of the same kind or binary plus (+) expressions for literals of - // the same kind (recursively). - // "a"+(1+2) => "a"+(1+2) - // "a"+("b"+"c") => "a"+"b"+"c" - if (binaryOperator === SyntaxKind.PlusToken) { - const leftKind = leftOperand ? getLiteralKindOfBinaryPlusOperand(leftOperand) : SyntaxKind.Unknown; - if (isLiteralKind(leftKind) && leftKind === getLiteralKindOfBinaryPlusOperand(emittedOperand)) { + case Comparison.EqualTo: + if (isLeftSideOfBinary) { + // No need to parenthesize the left operand when the binary operator is + // left associative: + // (a*b)/x -> a*b/x + // (a**b)/x -> a**b/x + // + // Parentheses are needed for the left operand when the binary operator is + // right associative: + // (a/b)**x -> (a/b)**x + // (a**b)**x -> (a**b)**x + return binaryOperatorAssociativity === Associativity.Right; + } + else { + if (isBinaryExpression(emittedOperand) + && emittedOperand.operatorToken.kind === binaryOperator) { + // No need to parenthesize the right operand when the binary operator and + // operand are the same and one of the following: + // x*(a*b) => x*a*b + // x|(a|b) => x|a|b + // x&(a&b) => x&a&b + // x^(a^b) => x^a^b + if (operatorHasAssociativeProperty(binaryOperator)) { return false; } + + // No need to parenthesize the right operand when the binary operator + // is plus (+) if both the left and right operands consist solely of either + // literals of the same kind or binary plus (+) expressions for literals of + // the same kind (recursively). + // "a"+(1+2) => "a"+(1+2) + // "a"+("b"+"c") => "a"+"b"+"c" + if (binaryOperator === SyntaxKind.PlusToken) { + const leftKind = leftOperand ? getLiteralKindOfBinaryPlusOperand(leftOperand) : SyntaxKind.Unknown; + if (isLiteralKind(leftKind) && leftKind === getLiteralKindOfBinaryPlusOperand(emittedOperand)) { + return false; + } + } } - } - // No need to parenthesize the right operand when the operand is right - // associative: - // x/(a**b) -> x/a**b - // x**(a**b) -> x**a**b - // - // Parentheses are needed for the right operand when the operand is left - // associative: - // x/(a*b) -> x/(a*b) - // x**(a/b) -> x**(a/b) - const operandAssociativity = getExpressionAssociativity(emittedOperand); - return operandAssociativity === Associativity.Left; - } + // No need to parenthesize the right operand when the operand is right + // associative: + // x/(a**b) -> x/a**b + // x**(a**b) -> x**a**b + // + // Parentheses are needed for the right operand when the operand is left + // associative: + // x/(a*b) -> x/(a*b) + // x**(a/b) -> x**(a/b) + const operandAssociativity = getExpressionAssociativity(emittedOperand); + return operandAssociativity === Associativity.Left; + } + } } - } - /** - * Determines whether a binary operator is mathematically associative. - * - * @param binaryOperator The binary operator. - */ - function operatorHasAssociativeProperty(binaryOperator: SyntaxKind) { - // The following operators are associative in JavaScript: - // (a*b)*c -> a*(b*c) -> a*b*c - // (a|b)|c -> a|(b|c) -> a|b|c - // (a&b)&c -> a&(b&c) -> a&b&c - // (a^b)^c -> a^(b^c) -> a^b^c - // - // While addition is associative in mathematics, JavaScript's `+` is not - // guaranteed to be associative as it is overloaded with string concatenation. - return binaryOperator === SyntaxKind.AsteriskToken - || binaryOperator === SyntaxKind.BarToken - || binaryOperator === SyntaxKind.AmpersandToken - || binaryOperator === SyntaxKind.CaretToken; - } + /** + * Determines whether a binary operator is mathematically associative. + * + * @param binaryOperator The binary operator. + */ + function operatorHasAssociativeProperty(binaryOperator: SyntaxKind) { + // The following operators are associative in JavaScript: + // (a*b)*c -> a*(b*c) -> a*b*c + // (a|b)|c -> a|(b|c) -> a|b|c + // (a&b)&c -> a&(b&c) -> a&b&c + // (a^b)^c -> a^(b^c) -> a^b^c + // + // While addition is associative in mathematics, JavaScript's `+` is not + // guaranteed to be associative as it is overloaded with string concatenation. + return binaryOperator === SyntaxKind.AsteriskToken + || binaryOperator === SyntaxKind.BarToken + || binaryOperator === SyntaxKind.AmpersandToken + || binaryOperator === SyntaxKind.CaretToken; + } + + interface BinaryPlusExpression extends BinaryExpression { + cachedLiteralKind: SyntaxKind; + } + + /** + * This function determines whether an expression consists of a homogeneous set of + * literal expressions or binary plus expressions that all share the same literal kind. + * It is used to determine whether the right-hand operand of a binary plus expression can be + * emitted without parentheses. + */ + function getLiteralKindOfBinaryPlusOperand(node: Expression): SyntaxKind { + node = skipPartiallyEmittedExpressions(node); + + if (isLiteralKind(node.kind)) { + return node.kind; + } - interface BinaryPlusExpression extends BinaryExpression { - cachedLiteralKind: SyntaxKind; - } + if (node.kind === SyntaxKind.BinaryExpression && (node).operatorToken.kind === SyntaxKind.PlusToken) { + if ((node).cachedLiteralKind !== undefined) { + return (node).cachedLiteralKind; + } - /** - * This function determines whether an expression consists of a homogeneous set of - * literal expressions or binary plus expressions that all share the same literal kind. - * It is used to determine whether the right-hand operand of a binary plus expression can be - * emitted without parentheses. - */ - function getLiteralKindOfBinaryPlusOperand(node: Expression): SyntaxKind { - node = skipPartiallyEmittedExpressions(node); + const leftKind = getLiteralKindOfBinaryPlusOperand((node).left); + const literalKind = isLiteralKind(leftKind) + && leftKind === getLiteralKindOfBinaryPlusOperand((node).right) + ? leftKind + : SyntaxKind.Unknown; - if (isLiteralKind(node.kind)) { - return node.kind; + (node).cachedLiteralKind = literalKind; + return literalKind; + } + + return SyntaxKind.Unknown; } - if (node.kind === SyntaxKind.BinaryExpression && (node).operatorToken.kind === SyntaxKind.PlusToken) { - if ((node).cachedLiteralKind !== undefined) { - return (node).cachedLiteralKind; + /** + * Wraps an expression in parentheses if it is needed in order to use the expression + * as the expression of a NewExpression node. + * + * @param expression The Expression node. + */ + export function parenthesizeForNew(expression: Expression): LeftHandSideExpression { + const emittedExpression = skipPartiallyEmittedExpressions(expression); + switch (emittedExpression.kind) { + case SyntaxKind.CallExpression: + return createParen(expression); + + case SyntaxKind.NewExpression: + return (emittedExpression).arguments + ? expression + : createParen(expression); } - const leftKind = getLiteralKindOfBinaryPlusOperand((node).left); - const literalKind = isLiteralKind(leftKind) - && leftKind === getLiteralKindOfBinaryPlusOperand((node).right) - ? leftKind - : SyntaxKind.Unknown; + return parenthesizeForAccess(expression); + } + + /** + * Wraps an expression in parentheses if it is needed in order to use the expression for + * property or element access. + * + * @param expr The expression node. + */ + export function parenthesizeForAccess(expression: Expression): LeftHandSideExpression { + // isLeftHandSideExpression is almost the correct criterion for when it is not necessary + // to parenthesize the expression before a dot. The known exceptions are: + // + // NewExpression: + // new C.x -> not the same as (new C).x + // NumericLiteral + // 1.x -> not the same as (1).x + // + const emittedExpression = skipPartiallyEmittedExpressions(expression); + if (isLeftHandSideExpression(emittedExpression) + && (emittedExpression.kind !== SyntaxKind.NewExpression || (emittedExpression).arguments) + && emittedExpression.kind !== SyntaxKind.NumericLiteral) { + return expression; + } - (node).cachedLiteralKind = literalKind; - return literalKind; + return createParen(expression, /*location*/ expression); } - return SyntaxKind.Unknown; - } - - /** - * Wraps an expression in parentheses if it is needed in order to use the expression - * as the expression of a NewExpression node. - * - * @param expression The Expression node. - */ - export function parenthesizeForNew(expression: Expression): LeftHandSideExpression { - const emittedExpression = skipPartiallyEmittedExpressions(expression); - switch (emittedExpression.kind) { - case SyntaxKind.CallExpression: - return createParen(expression); - - case SyntaxKind.NewExpression: - return (emittedExpression).arguments - ? expression - : createParen(expression); - } - - return parenthesizeForAccess(expression); - } - - /** - * Wraps an expression in parentheses if it is needed in order to use the expression for - * property or element access. - * - * @param expr The expression node. - */ - export function parenthesizeForAccess(expression: Expression): LeftHandSideExpression { - // isLeftHandSideExpression is almost the correct criterion for when it is not necessary - // to parenthesize the expression before a dot. The known exceptions are: - // - // NewExpression: - // new C.x -> not the same as (new C).x - // NumericLiteral - // 1.x -> not the same as (1).x - // - const emittedExpression = skipPartiallyEmittedExpressions(expression); - if (isLeftHandSideExpression(emittedExpression) - && (emittedExpression.kind !== SyntaxKind.NewExpression || (emittedExpression).arguments) - && emittedExpression.kind !== SyntaxKind.NumericLiteral) { - return expression; - } - - return createParen(expression, /*location*/ expression); - } + export function parenthesizePostfixOperand(operand: Expression) { + return isLeftHandSideExpression(operand) + ? operand + : createParen(operand, /*location*/ operand); + } - export function parenthesizePostfixOperand(operand: Expression) { - return isLeftHandSideExpression(operand) - ? operand - : createParen(operand, /*location*/ operand); - } + export function parenthesizePrefixOperand(operand: Expression) { + return isUnaryExpression(operand) + ? operand + : createParen(operand, /*location*/ operand); + } - export function parenthesizePrefixOperand(operand: Expression) { - return isUnaryExpression(operand) - ? operand - : createParen(operand, /*location*/ operand); - } + function parenthesizeListElements(elements: NodeArray) { + let result: Expression[]; + for (let i = 0; i < elements.length; i++) { + const element = parenthesizeExpressionForList(elements[i]); + if (result !== undefined || element !== elements[i]) { + if (result === undefined) { + result = elements.slice(0, i); + } - function parenthesizeListElements(elements: NodeArray) { - let result: Expression[]; - for (let i = 0; i < elements.length; i++) { - const element = parenthesizeExpressionForList(elements[i]); - if (result !== undefined || element !== elements[i]) { - if (result === undefined) { - result = elements.slice(0, i); + result.push(element); } + } - result.push(element); + if (result !== undefined) { + return createNodeArray(result, elements, elements.hasTrailingComma); } - } - if (result !== undefined) { - return createNodeArray(result, elements, elements.hasTrailingComma); + return elements; } - return elements; - } - - export function parenthesizeExpressionForList(expression: Expression) { - const emittedExpression = skipPartiallyEmittedExpressions(expression); - const expressionPrecedence = getExpressionPrecedence(emittedExpression); - const commaPrecedence = getOperatorPrecedence(SyntaxKind.BinaryExpression, SyntaxKind.CommaToken); - return expressionPrecedence > commaPrecedence - ? expression - : createParen(expression, /*location*/ expression); - } + export function parenthesizeExpressionForList(expression: Expression) { + const emittedExpression = skipPartiallyEmittedExpressions(expression); + const expressionPrecedence = getExpressionPrecedence(emittedExpression); + const commaPrecedence = getOperatorPrecedence(SyntaxKind.BinaryExpression, SyntaxKind.CommaToken); + return expressionPrecedence > commaPrecedence + ? expression + : createParen(expression, /*location*/ expression); + } - export function parenthesizeExpressionForExpressionStatement(expression: Expression) { - const emittedExpression = skipPartiallyEmittedExpressions(expression); - if (isCallExpression(emittedExpression)) { - const callee = emittedExpression.expression; - const kind = skipPartiallyEmittedExpressions(callee).kind; - if (kind === SyntaxKind.FunctionExpression || kind === SyntaxKind.ArrowFunction) { - const mutableCall = getMutableClone(emittedExpression); - mutableCall.expression = createParen(callee, /*location*/ callee); - return recreatePartiallyEmittedExpressions(expression, mutableCall); + export function parenthesizeExpressionForExpressionStatement(expression: Expression) { + const emittedExpression = skipPartiallyEmittedExpressions(expression); + if (isCallExpression(emittedExpression)) { + const callee = emittedExpression.expression; + const kind = skipPartiallyEmittedExpressions(callee).kind; + if (kind === SyntaxKind.FunctionExpression || kind === SyntaxKind.ArrowFunction) { + const mutableCall = getMutableClone(emittedExpression); + mutableCall.expression = createParen(callee, /*location*/ callee); + return recreatePartiallyEmittedExpressions(expression, mutableCall); + } } - } - else { - const leftmostExpressionKind = getLeftmostExpression(emittedExpression).kind; - if (leftmostExpressionKind === SyntaxKind.ObjectLiteralExpression || leftmostExpressionKind === SyntaxKind.FunctionExpression) { - return createParen(expression, /*location*/ expression); + else { + const leftmostExpressionKind = getLeftmostExpression(emittedExpression).kind; + if (leftmostExpressionKind === SyntaxKind.ObjectLiteralExpression || leftmostExpressionKind === SyntaxKind.FunctionExpression) { + return createParen(expression, /*location*/ expression); + } } + + return expression; } - return expression; - } + /** + * Clones a series of not-emitted expressions with a new inner expression. + * + * @param originalOuterExpression The original outer expression. + * @param newInnerExpression The new inner expression. + */ + function recreatePartiallyEmittedExpressions(originalOuterExpression: Expression, newInnerExpression: Expression) { + if (isPartiallyEmittedExpression(originalOuterExpression)) { + const clone = getMutableClone(originalOuterExpression); + clone.expression = recreatePartiallyEmittedExpressions(clone.expression, newInnerExpression); + return clone; + } - /** - * Clones a series of not-emitted expressions with a new inner expression. - * - * @param originalOuterExpression The original outer expression. - * @param newInnerExpression The new inner expression. - */ - function recreatePartiallyEmittedExpressions(originalOuterExpression: Expression, newInnerExpression: Expression) { - if (isPartiallyEmittedExpression(originalOuterExpression)) { - const clone = getMutableClone(originalOuterExpression); - clone.expression = recreatePartiallyEmittedExpressions(clone.expression, newInnerExpression); - return clone; + return newInnerExpression; } - return newInnerExpression; - } + function getLeftmostExpression(node: Expression): Expression { + while (true) { + switch (node.kind) { + case SyntaxKind.PostfixUnaryExpression: + node = (node).operand; + continue; - function getLeftmostExpression(node: Expression): Expression { - while (true) { - switch (node.kind) { - case SyntaxKind.PostfixUnaryExpression: - node = (node).operand; - continue; + case SyntaxKind.BinaryExpression: + node = (node).left; + continue; - case SyntaxKind.BinaryExpression: - node = (node).left; - continue; + case SyntaxKind.ConditionalExpression: + node = (node).condition; + continue; - case SyntaxKind.ConditionalExpression: - node = (node).condition; - continue; + case SyntaxKind.CallExpression: + case SyntaxKind.ElementAccessExpression: + case SyntaxKind.PropertyAccessExpression: + node = (node).expression; + continue; - case SyntaxKind.CallExpression: - case SyntaxKind.ElementAccessExpression: - case SyntaxKind.PropertyAccessExpression: - node = (node).expression; - continue; + case SyntaxKind.PartiallyEmittedExpression: + node = (node).expression; + continue; + } - case SyntaxKind.PartiallyEmittedExpression: - node = (node).expression; - continue; + return node; } - - return node; } - } - export function parenthesizeConciseBody(body: ConciseBody): ConciseBody { - const emittedBody = skipPartiallyEmittedExpressions(body); - if (emittedBody.kind === SyntaxKind.ObjectLiteralExpression) { - return createParen(body, /*location*/ body); + export function parenthesizeConciseBody(body: ConciseBody): ConciseBody { + const emittedBody = skipPartiallyEmittedExpressions(body); + if (emittedBody.kind === SyntaxKind.ObjectLiteralExpression) { + return createParen(body, /*location*/ body); + } + + return body; } - return body; - } + export const enum OuterExpressionKinds { + Parentheses = 1 << 0, + Assertions = 1 << 1, + PartiallyEmittedExpressions = 1 << 2, - export const enum OuterExpressionKinds { - Parentheses = 1 << 0, - Assertions = 1 << 1, - PartiallyEmittedExpressions = 1 << 2, + All = Parentheses | Assertions | PartiallyEmittedExpressions + } - All = Parentheses | Assertions | PartiallyEmittedExpressions - } + export function skipOuterExpressions(node: Expression, kinds?: OuterExpressionKinds): Expression; + export function skipOuterExpressions(node: Node, kinds?: OuterExpressionKinds): Node; + export function skipOuterExpressions(node: Node, kinds = OuterExpressionKinds.All) { + let previousNode: Node; + do { + previousNode = node; + if (kinds & OuterExpressionKinds.Parentheses) { + node = skipParentheses(node); + } - export function skipOuterExpressions(node: Expression, kinds?: OuterExpressionKinds): Expression; - export function skipOuterExpressions(node: Node, kinds?: OuterExpressionKinds): Node; - export function skipOuterExpressions(node: Node, kinds = OuterExpressionKinds.All) { - let previousNode: Node; - do { - previousNode = node; - if (kinds & OuterExpressionKinds.Parentheses) { - node = skipParentheses(node); - } + if (kinds & OuterExpressionKinds.Assertions) { + node = skipAssertions(node); + } - if (kinds & OuterExpressionKinds.Assertions) { - node = skipAssertions(node); + if (kinds & OuterExpressionKinds.PartiallyEmittedExpressions) { + node = skipPartiallyEmittedExpressions(node); + } } + while (previousNode !== node); - if (kinds & OuterExpressionKinds.PartiallyEmittedExpressions) { - node = skipPartiallyEmittedExpressions(node); - } + return node; } - while (previousNode !== node); - return node; - } + export function skipParentheses(node: Expression): Expression; + export function skipParentheses(node: Node): Node; + export function skipParentheses(node: Node): Node { + while (node.kind === SyntaxKind.ParenthesizedExpression) { + node = (node).expression; + } - export function skipParentheses(node: Expression): Expression; - export function skipParentheses(node: Node): Node; - export function skipParentheses(node: Node): Node { - while (node.kind === SyntaxKind.ParenthesizedExpression) { - node = (node).expression; + return node; } - return node; - } + export function skipAssertions(node: Expression): Expression; + export function skipAssertions(node: Node): Node; + export function skipAssertions(node: Node): Node { + while (isAssertionExpression(node)) { + node = (node).expression; + } - export function skipAssertions(node: Expression): Expression; - export function skipAssertions(node: Node): Node; - export function skipAssertions(node: Node): Node { - while (isAssertionExpression(node)) { - node = (node).expression; + return node; } - return node; - } + export function skipPartiallyEmittedExpressions(node: Expression): Expression; + export function skipPartiallyEmittedExpressions(node: Node): Node; + export function skipPartiallyEmittedExpressions(node: Node) { + while (node.kind === SyntaxKind.PartiallyEmittedExpression) { + node = (node).expression; + } - export function skipPartiallyEmittedExpressions(node: Expression): Expression; - export function skipPartiallyEmittedExpressions(node: Node): Node; - export function skipPartiallyEmittedExpressions(node: Node) { - while (node.kind === SyntaxKind.PartiallyEmittedExpression) { - node = (node).expression; + return node; } - return node; - } - - export function startOnNewLine(node: T): T { - node.startsOnNewLine = true; - return node; - } - - export function setOriginalNode(node: T, original: Node): T { - node.original = original; - if (original) { - const emitNode = original.emitNode; - if (emitNode) node.emitNode = mergeEmitNode(emitNode, node.emitNode); + export function startOnNewLine(node: T): T { + node.startsOnNewLine = true; + return node; } - 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, destRanges: Map) { - if (!destRanges) destRanges = createMap(); - copyProperties(sourceRanges, destRanges); - return destRanges; - } - /** - * Clears any EmitNode entries from parse-tree nodes. - * @param sourceFile A source file. - */ - /* @internal */ - 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; + export function setOriginalNode(node: T, original: Node): T { + node.original = original; + if (original) { + const emitNode = original.emitNode; + if (emitNode) node.emitNode = mergeEmitNode(emitNode, node.emitNode); } + return node; } - } - /** - * 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] }; + 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, destRanges: Map) { + if (!destRanges) destRanges = createMap(); + copyProperties(sourceRanges, destRanges); + return destRanges; + } + + /** + * Clears any EmitNode entries from parse-tree nodes. + * @param sourceFile A source file. + */ + /* @internal */ + 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; } - - 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. - */ - /* @internal */ - 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. - */ - /* @internal */ - export function setEmitFlags(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(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(node: T, token: SyntaxKind, range: TextRange) { - const emitNode = getOrCreateEmitNode(node); - const tokenSourceMapRanges = emitNode.tokenSourceMapRanges || (emitNode.tokenSourceMapRanges = createMap()); - tokenSourceMapRanges[token] = range; - return node; - } - - /** - * Sets a custom text range to use when emitting comments. - */ - export function setCommentRange(node: T, range: TextRange) { - getOrCreateEmitNode(node).commentRange = range; - return node; - } + /** + * 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] }; + } - /** - * 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; - } + const sourceFile = getSourceFileOfNode(node); + getOrCreateEmitNode(sourceFile).annotatedNodes.push(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; - } + node.emitNode = {}; + } - /** - * 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]; - } + return node.emitNode; + } + + /** + * Gets flags that control emit behavior of a node. + * + * @param node The node. + */ + /* @internal */ + 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. + */ + /* @internal */ + export function setEmitFlags(node: T, emitFlags: EmitFlags) { + getOrCreateEmitNode(node).flags = emitFlags; + return node; + } - /** - * Gets the constant value to emit for an expression. - */ - export function getConstantValue(node: PropertyAccessExpression | ElementAccessExpression) { - const emitNode = node.emitNode; - return emitNode && emitNode.constantValue; - } + /** + * Sets a custom text range to use when emitting source maps. + * + * @param node The node. + * @param range The text range. + */ + export function setSourceMapRange(node: T, range: TextRange) { + getOrCreateEmitNode(node).sourceMapRange = range; + return node; + } - /** - * Sets the constant value to emit for an expression. - */ - export function setConstantValue(node: PropertyAccessExpression | ElementAccessExpression, value: number) { - const emitNode = getOrCreateEmitNode(node); - emitNode.constantValue = value; - 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(node: T, token: SyntaxKind, range: TextRange) { + const emitNode = getOrCreateEmitNode(node); + const tokenSourceMapRanges = emitNode.tokenSourceMapRanges || (emitNode.tokenSourceMapRanges = createMap()); + tokenSourceMapRanges[token] = range; + return node; + } - export function setTextRange(node: T, location: TextRange): T { - if (location) { - node.pos = location.pos; - node.end = location.end; + /** + * Sets a custom text range to use when emitting comments. + */ + export function setCommentRange(node: T, range: TextRange) { + getOrCreateEmitNode(node).commentRange = range; + return node; } - return node; - } - export function setNodeFlags(node: T, flags: NodeFlags): T { - node.flags = flags; - 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]; + } + + /** + * Gets the constant value to emit for an expression. + */ + export function getConstantValue(node: PropertyAccessExpression | ElementAccessExpression) { + const emitNode = node.emitNode; + return emitNode && emitNode.constantValue; + } + + /** + * Sets the constant value to emit for an expression. + */ + export function setConstantValue(node: PropertyAccessExpression | ElementAccessExpression, value: number) { + const emitNode = getOrCreateEmitNode(node); + emitNode.constantValue = value; + return node; + } - export function setMultiLine(node: T, multiLine: boolean): T { - node.multiLine = multiLine; - return node; - } + export function setTextRange(node: T, location: TextRange): T { + if (location) { + node.pos = location.pos; + node.end = location.end; + } + return node; + } - export function setHasTrailingComma(nodes: NodeArray, hasTrailingComma: boolean): NodeArray { - nodes.hasTrailingComma = hasTrailingComma; - return nodes; - } + export function setNodeFlags(node: T, flags: NodeFlags): T { + node.flags = flags; + return node; + } - /** - * Get the name of that target module from an import or export declaration - */ - export function getLocalNameForExternalImport(node: ImportDeclaration | ExportDeclaration | ImportEqualsDeclaration, sourceFile: SourceFile): Identifier { - const namespaceDeclaration = getNamespaceDeclarationNode(node); - if (namespaceDeclaration && !isDefaultImport(node)) { - const name = namespaceDeclaration.name; - return isGeneratedIdentifier(name) ? name : createIdentifier(getSourceTextOfNodeFromSourceFile(sourceFile, namespaceDeclaration.name)); + export function setMultiLine(node: T, multiLine: boolean): T { + node.multiLine = multiLine; + return node; } - if (node.kind === SyntaxKind.ImportDeclaration && (node).importClause) { - return getGeneratedNameForNode(node); + + export function setHasTrailingComma(nodes: NodeArray, hasTrailingComma: boolean): NodeArray { + nodes.hasTrailingComma = hasTrailingComma; + return nodes; } - if (node.kind === SyntaxKind.ExportDeclaration && (node).moduleSpecifier) { - return getGeneratedNameForNode(node); + + /** + * Get the name of that target module from an import or export declaration + */ + export function getLocalNameForExternalImport(node: ImportDeclaration | ExportDeclaration | ImportEqualsDeclaration, sourceFile: SourceFile): Identifier { + const namespaceDeclaration = getNamespaceDeclarationNode(node); + if (namespaceDeclaration && !isDefaultImport(node)) { + const name = namespaceDeclaration.name; + return isGeneratedIdentifier(name) ? name : createIdentifier(getSourceTextOfNodeFromSourceFile(sourceFile, namespaceDeclaration.name)); + } + if (node.kind === SyntaxKind.ImportDeclaration && (node).importClause) { + return getGeneratedNameForNode(node); + } + if (node.kind === SyntaxKind.ExportDeclaration && (node).moduleSpecifier) { + return getGeneratedNameForNode(node); + } + return undefined; } - return undefined; - } - /** - * Get the name of a target module from an import/export declaration as should be written in the emitted output. - * The emitted output name can be different from the input if: - * 1. The module has a /// - * 2. --out or --outFile is used, making the name relative to the rootDir - * 3- The containing SourceFile has an entry in renamedDependencies for the import as requested by some module loaders (e.g. System). - * Otherwise, a new StringLiteral node representing the module name will be returned. - */ - /* @internal */ - export function getExternalModuleNameLiteral(importNode: ImportDeclaration | ExportDeclaration | ImportEqualsDeclaration, sourceFile: SourceFile, host: EmitHost, resolver: EmitResolver, compilerOptions: CompilerOptions) { - const moduleName = getExternalModuleName(importNode); - if (moduleName.kind === SyntaxKind.StringLiteral) { - return tryGetModuleNameFromDeclaration(importNode, host, resolver, compilerOptions) - || tryRenameExternalModule(moduleName, sourceFile) - || getSynthesizedClone(moduleName); - } - - return undefined; - } + /** + * Get the name of a target module from an import/export declaration as should be written in the emitted output. + * The emitted output name can be different from the input if: + * 1. The module has a /// + * 2. --out or --outFile is used, making the name relative to the rootDir + * 3- The containing SourceFile has an entry in renamedDependencies for the import as requested by some module loaders (e.g. System). + * Otherwise, a new StringLiteral node representing the module name will be returned. + */ + /* @internal */ + export function getExternalModuleNameLiteral(importNode: ImportDeclaration | ExportDeclaration | ImportEqualsDeclaration, sourceFile: SourceFile, host: EmitHost, resolver: EmitResolver, compilerOptions: CompilerOptions) { + const moduleName = getExternalModuleName(importNode); + if (moduleName.kind === SyntaxKind.StringLiteral) { + return tryGetModuleNameFromDeclaration(importNode, host, resolver, compilerOptions) + || tryRenameExternalModule(moduleName, sourceFile) + || getSynthesizedClone(moduleName); + } - /** - * Some bundlers (SystemJS builder) sometimes want to rename dependencies. - * Here we check if alternative name was provided for a given moduleName and return it if possible. - */ - function tryRenameExternalModule(moduleName: LiteralExpression, sourceFile: SourceFile) { - if (sourceFile.renamedDependencies && hasProperty(sourceFile.renamedDependencies, moduleName.text)) { - return createLiteral(sourceFile.renamedDependencies[moduleName.text]); + return undefined; } - return undefined; - } - /** - * Get the name of a module as should be written in the emitted output. - * The emitted output name can be different from the input if: - * 1. The module has a /// - * 2. --out or --outFile is used, making the name relative to the rootDir - * Otherwise, a new StringLiteral node representing the module name will be returned. - */ - /* @internal */ - export function tryGetModuleNameFromFile(file: SourceFile, host: EmitHost, options: CompilerOptions): StringLiteral { - if (!file) { + /** + * Some bundlers (SystemJS builder) sometimes want to rename dependencies. + * Here we check if alternative name was provided for a given moduleName and return it if possible. + */ + function tryRenameExternalModule(moduleName: LiteralExpression, sourceFile: SourceFile) { + if (sourceFile.renamedDependencies && hasProperty(sourceFile.renamedDependencies, moduleName.text)) { + return createLiteral(sourceFile.renamedDependencies[moduleName.text]); + } return undefined; } - if (file.moduleName) { - return createLiteral(file.moduleName); - } - if (!isDeclarationFile(file) && (options.out || options.outFile)) { - return createLiteral(getExternalModuleNameFromPath(host, file.fileName)); + + /** + * Get the name of a module as should be written in the emitted output. + * The emitted output name can be different from the input if: + * 1. The module has a /// + * 2. --out or --outFile is used, making the name relative to the rootDir + * Otherwise, a new StringLiteral node representing the module name will be returned. + */ + /* @internal */ + export function tryGetModuleNameFromFile(file: SourceFile, host: EmitHost, options: CompilerOptions): StringLiteral { + if (!file) { + return undefined; + } + if (file.moduleName) { + return createLiteral(file.moduleName); + } + if (!isDeclarationFile(file) && (options.out || options.outFile)) { + return createLiteral(getExternalModuleNameFromPath(host, file.fileName)); + } + return undefined; } - return undefined; - } - function tryGetModuleNameFromDeclaration(declaration: ImportEqualsDeclaration | ImportDeclaration | ExportDeclaration, host: EmitHost, resolver: EmitResolver, compilerOptions: CompilerOptions) { - return tryGetModuleNameFromFile(resolver.getExternalModuleFileFromDeclaration(declaration), host, compilerOptions); + function tryGetModuleNameFromDeclaration(declaration: ImportEqualsDeclaration | ImportDeclaration | ExportDeclaration, host: EmitHost, resolver: EmitResolver, compilerOptions: CompilerOptions) { + return tryGetModuleNameFromFile(resolver.getExternalModuleFileFromDeclaration(declaration), host, compilerOptions); + } } } \ No newline at end of file From 6c122bcf16c329a21da04d7b5256f20ecc0bbd1d Mon Sep 17 00:00:00 2001 From: Ivo Gabe de Wolff Date: Wed, 12 Oct 2016 17:57:43 +0200 Subject: [PATCH 8/8] Fix linting errors --- src/compiler/emitter.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index f55187e5eee6d..46668d50b62c0 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -59,7 +59,7 @@ namespace ts { const printFile = createPrinter(host, undefined, createDiagnosticCollection(), transform, () => false); - printFile("output.js", "", [file], false); + printFile("output.js", "", [file], /*isBundledEmit*/ false); // Clean up emit nodes on parse tree factory.disposeEmitNodes(file); @@ -137,7 +137,7 @@ namespace ts { host: EmitHost, emittedFilesList: string[], emitterDiagnostics: DiagnosticCollection, - { transformed, emitNodeWithSubstitution, emitNodeWithNotification }: TransformationResult, + { emitNodeWithSubstitution, emitNodeWithNotification }: TransformationResult, hasGlobalName: (name: string) => boolean, sourceMapDataList?: SourceMapData[] ) { @@ -310,7 +310,7 @@ const _super = (function (geti, seti) { const cache = Object.create(null); return name => cache[name] || (cache[name] = { get value() { return geti(name); }, set value(v) { seti(name, v); } }); })(name => super[name], (name, value) => super[name] = value);`; - + const compilerOptions = host.getCompilerOptions(); const languageVersion = getEmitScriptTarget(compilerOptions); const moduleKind = getEmitModuleKind(compilerOptions);