@tslite/printer 0.5.7 → 1.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +55 -0
- package/NOTICE +15 -0
- package/dist/_namespaces/ts.d.ts +4 -0
- package/dist/_namespaces/ts.js +6 -0
- package/dist/emitter.d.ts +2 -0
- package/dist/emitter.js +2751 -0
- package/dist/index.d.ts +1 -64
- package/dist/index.js +4 -1
- package/dist/types.d.ts +197 -0
- package/dist/types.js +65 -0
- package/dist/utilities.d.ts +24 -0
- package/dist/utilities.js +427 -0
- package/package.json +17 -38
- package/dist/index.cjs +0 -1
- package/dist/index.d.cts +0 -64
package/dist/emitter.js
ADDED
|
@@ -0,0 +1,2751 @@
|
|
|
1
|
+
// Modificado de microsoft/TypeScript v3.9.10, src/compiler/emitter.ts: o namespace virou módulo ES, com os imports explícitos.
|
|
2
|
+
import * as ts from "./_namespaces/ts.js";
|
|
3
|
+
import { CharacterCodes, Debug, EmitFlags, EmitHint, GeneratedIdentifierFlags, NodeFlags, ScriptTarget, SymbolFlags, SyntaxKind, cast, computeLineStarts, createMap, createNode, createTextWriter, emitDetachedComments, emitNewLineBeforeLeadingCommentOfPosition, escapeJsxAttributeString, escapeLeadingUnderscores, escapeNonAsciiString, escapeString, findIndex, forEach, forEachLeadingCommentRange, forEachTrailingCommentRange, getCommentRange, getEmitFlags, getExternalModuleName, getLineStarts, getLinesBetweenPositionAndNextNonWhitespaceCharacter, getLinesBetweenPositionAndPrecedingNonWhitespaceCharacter, getLinesBetweenRangeEndAndRangeStart, getLiteralText, getNewLineCharacter, getNodeId, getOriginalNode, getParseTreeNode, getShebang, getSourceFileOfNode, getSourceTextOfNodeFromSourceFile, getStartsOnNewLine, getSyntheticLeadingComments, getSyntheticTrailingComments, getTrailingSemicolonDeferringWriter, idText, isArrowFunction, isBinaryExpression, isBindingPattern, isBlock, isEmptyStatement, isExpression, isFunctionLike, isGeneratedIdentifier, isIdentifier, isJsonSourceFile, isJsxClosingElement, isJsxOpeningElement, isKeyword, isLet, isLiteralExpression, isNodeDescendantOf, isNumericLiteral, isPrologueDirective, isSourceFile, isStringLiteral, isTemplateLiteralKind, isToken, isTypeParameterDeclaration, isVarConst, last, lastOrUndefined, makeIdentifierFromModuleName, noEmitNotification, nodeIsSynthesized, positionIsSynthesized, positionsAreOnSameLine, rangeEndIsOnSameLineAsRangeStart, rangeEndPositionsAreOnSameLine, rangeIsOnSingleLine, rangeStartPositionsAreOnSameLine, singleOrUndefined, skipPartiallyEmittedExpressions, skipTrivia, some, stringContains, tokenToString, writeCommentRange, } from "./_namespaces/ts.js";
|
|
4
|
+
const syntheticParent = { pos: -1, end: -1 };
|
|
5
|
+
const brackets = createBracketsMap();
|
|
6
|
+
var PipelinePhase;
|
|
7
|
+
(function (PipelinePhase) {
|
|
8
|
+
PipelinePhase[PipelinePhase["Notification"] = 0] = "Notification";
|
|
9
|
+
PipelinePhase[PipelinePhase["Comments"] = 1] = "Comments";
|
|
10
|
+
PipelinePhase[PipelinePhase["Emit"] = 2] = "Emit";
|
|
11
|
+
})(PipelinePhase || (PipelinePhase = {}));
|
|
12
|
+
export function createPrinter(printerOptions = {}, handlers = {}) {
|
|
13
|
+
const { hasGlobalName, onEmitNode = noEmitNotification, isEmitNotificationEnabled, onBeforeEmitNodeArray, onAfterEmitNodeArray, onBeforeEmitToken, onAfterEmitToken } = handlers;
|
|
14
|
+
const newLine = getNewLineCharacter(printerOptions);
|
|
15
|
+
let currentSourceFile;
|
|
16
|
+
let nodeIdToGeneratedName; // Map of generated names for specific nodes.
|
|
17
|
+
let autoGeneratedIdToGeneratedName; // Map of generated names for temp and loop variables.
|
|
18
|
+
let generatedNames; // Set of names generated by the NameGenerator.
|
|
19
|
+
let tempFlagsStack; // Stack of enclosing name generation scopes.
|
|
20
|
+
let tempFlags; // TempFlags for the current name generation scope.
|
|
21
|
+
let reservedNamesStack; // Stack of TempFlags reserved in enclosing name generation scopes.
|
|
22
|
+
let reservedNames; // TempFlags to reserve in nested name generation scopes.
|
|
23
|
+
let preserveSourceNewlines = printerOptions.preserveSourceNewlines; // Can be overridden inside nodes with the `IgnoreSourceNewlines` emit flag.
|
|
24
|
+
let writer;
|
|
25
|
+
let ownWriter; // Reusable `EmitTextWriter` for basic printing.
|
|
26
|
+
let write = writeBase;
|
|
27
|
+
// Comments
|
|
28
|
+
let containerPos = -1;
|
|
29
|
+
let containerEnd = -1;
|
|
30
|
+
let declarationListContainerEnd = -1;
|
|
31
|
+
let currentLineMap;
|
|
32
|
+
let detachedCommentsInfo;
|
|
33
|
+
let hasWrittenComment = false;
|
|
34
|
+
let commentsDisabled = !!printerOptions.removeComments;
|
|
35
|
+
let lastNode;
|
|
36
|
+
reset();
|
|
37
|
+
return {
|
|
38
|
+
// public API
|
|
39
|
+
printNode,
|
|
40
|
+
printList,
|
|
41
|
+
printFile,
|
|
42
|
+
// internal API
|
|
43
|
+
writeNode,
|
|
44
|
+
writeList,
|
|
45
|
+
writeFile,
|
|
46
|
+
};
|
|
47
|
+
function printNode(hint, node, sourceFile) {
|
|
48
|
+
switch (hint) {
|
|
49
|
+
case EmitHint.SourceFile:
|
|
50
|
+
Debug.assert(isSourceFile(node), "Expected a SourceFile node.");
|
|
51
|
+
break;
|
|
52
|
+
case EmitHint.IdentifierName:
|
|
53
|
+
Debug.assert(isIdentifier(node), "Expected an Identifier node.");
|
|
54
|
+
break;
|
|
55
|
+
case EmitHint.Expression:
|
|
56
|
+
Debug.assert(isExpression(node), "Expected an Expression node.");
|
|
57
|
+
break;
|
|
58
|
+
}
|
|
59
|
+
switch (node.kind) {
|
|
60
|
+
case SyntaxKind.SourceFile: return printFile(node);
|
|
61
|
+
}
|
|
62
|
+
writeNode(hint, node, sourceFile, beginPrint());
|
|
63
|
+
return endPrint();
|
|
64
|
+
}
|
|
65
|
+
function printList(format, nodes, sourceFile) {
|
|
66
|
+
writeList(format, nodes, sourceFile, beginPrint());
|
|
67
|
+
return endPrint();
|
|
68
|
+
}
|
|
69
|
+
function printFile(sourceFile) {
|
|
70
|
+
writeFile(sourceFile, beginPrint());
|
|
71
|
+
return endPrint();
|
|
72
|
+
}
|
|
73
|
+
function writeNode(hint, node, sourceFile, output) {
|
|
74
|
+
const previousWriter = writer;
|
|
75
|
+
setWriter(output);
|
|
76
|
+
print(hint, node, sourceFile);
|
|
77
|
+
reset();
|
|
78
|
+
writer = previousWriter;
|
|
79
|
+
}
|
|
80
|
+
function writeList(format, nodes, sourceFile, output) {
|
|
81
|
+
const previousWriter = writer;
|
|
82
|
+
setWriter(output);
|
|
83
|
+
if (sourceFile) {
|
|
84
|
+
setSourceFile(sourceFile);
|
|
85
|
+
}
|
|
86
|
+
emitList(syntheticParent, nodes, format);
|
|
87
|
+
reset();
|
|
88
|
+
writer = previousWriter;
|
|
89
|
+
}
|
|
90
|
+
function writeFile(sourceFile, output) {
|
|
91
|
+
const previousWriter = writer;
|
|
92
|
+
setWriter(output);
|
|
93
|
+
emitShebangIfNeeded(sourceFile);
|
|
94
|
+
emitPrologueDirectivesIfNeeded(sourceFile);
|
|
95
|
+
print(EmitHint.SourceFile, sourceFile, sourceFile);
|
|
96
|
+
reset();
|
|
97
|
+
writer = previousWriter;
|
|
98
|
+
}
|
|
99
|
+
function beginPrint() {
|
|
100
|
+
return ownWriter || (ownWriter = createTextWriter(newLine));
|
|
101
|
+
}
|
|
102
|
+
function endPrint() {
|
|
103
|
+
const text = ownWriter.getText();
|
|
104
|
+
ownWriter.clear();
|
|
105
|
+
return text;
|
|
106
|
+
}
|
|
107
|
+
function print(hint, node, sourceFile) {
|
|
108
|
+
if (sourceFile) {
|
|
109
|
+
setSourceFile(sourceFile);
|
|
110
|
+
}
|
|
111
|
+
pipelineEmit(hint, node);
|
|
112
|
+
}
|
|
113
|
+
function setSourceFile(sourceFile) {
|
|
114
|
+
currentSourceFile = sourceFile;
|
|
115
|
+
currentLineMap = undefined;
|
|
116
|
+
detachedCommentsInfo = undefined;
|
|
117
|
+
}
|
|
118
|
+
function setWriter(_writer) {
|
|
119
|
+
if (_writer && printerOptions.omitTrailingSemicolon) {
|
|
120
|
+
_writer = getTrailingSemicolonDeferringWriter(_writer);
|
|
121
|
+
}
|
|
122
|
+
writer = _writer;
|
|
123
|
+
}
|
|
124
|
+
function reset() {
|
|
125
|
+
nodeIdToGeneratedName = [];
|
|
126
|
+
autoGeneratedIdToGeneratedName = [];
|
|
127
|
+
generatedNames = createMap();
|
|
128
|
+
tempFlagsStack = [];
|
|
129
|
+
tempFlags = 0 /* TempFlags.Auto */;
|
|
130
|
+
reservedNamesStack = [];
|
|
131
|
+
currentSourceFile = undefined;
|
|
132
|
+
currentLineMap = undefined;
|
|
133
|
+
detachedCommentsInfo = undefined;
|
|
134
|
+
lastNode = undefined;
|
|
135
|
+
setWriter(/*output*/ undefined);
|
|
136
|
+
}
|
|
137
|
+
function getCurrentLineMap() {
|
|
138
|
+
return currentLineMap || (currentLineMap = getLineStarts(currentSourceFile));
|
|
139
|
+
}
|
|
140
|
+
function emit(node) {
|
|
141
|
+
if (node === undefined)
|
|
142
|
+
return;
|
|
143
|
+
return pipelineEmit(EmitHint.Unspecified, node);
|
|
144
|
+
}
|
|
145
|
+
function emitExpression(node) {
|
|
146
|
+
if (node === undefined)
|
|
147
|
+
return;
|
|
148
|
+
return pipelineEmit(EmitHint.Expression, node);
|
|
149
|
+
}
|
|
150
|
+
function emitJsxAttributeValue(node) {
|
|
151
|
+
return pipelineEmit(isStringLiteral(node) ? EmitHint.JsxAttributeValue : EmitHint.Unspecified, node);
|
|
152
|
+
}
|
|
153
|
+
function pipelineEmit(emitHint, node) {
|
|
154
|
+
const savedLastNode = lastNode;
|
|
155
|
+
const savedPreserveSourceNewlines = preserveSourceNewlines;
|
|
156
|
+
lastNode = node;
|
|
157
|
+
if (preserveSourceNewlines && !!(getEmitFlags(node) & EmitFlags.IgnoreSourceNewlines)) {
|
|
158
|
+
preserveSourceNewlines = false;
|
|
159
|
+
}
|
|
160
|
+
const pipelinePhase = getPipelinePhase(0 /* PipelinePhase.Notification */, emitHint, node);
|
|
161
|
+
pipelinePhase(emitHint, node);
|
|
162
|
+
Debug.assert(lastNode === node);
|
|
163
|
+
lastNode = savedLastNode;
|
|
164
|
+
preserveSourceNewlines = savedPreserveSourceNewlines;
|
|
165
|
+
return node;
|
|
166
|
+
}
|
|
167
|
+
function getPipelinePhase(phase, _emitHint, node) {
|
|
168
|
+
switch (phase) {
|
|
169
|
+
case 0 /* PipelinePhase.Notification */:
|
|
170
|
+
if (onEmitNode !== noEmitNotification && (!isEmitNotificationEnabled || isEmitNotificationEnabled(node))) {
|
|
171
|
+
return pipelineEmitWithNotification;
|
|
172
|
+
}
|
|
173
|
+
// falls through
|
|
174
|
+
case 1 /* PipelinePhase.Comments */:
|
|
175
|
+
if (!commentsDisabled && node.kind !== SyntaxKind.SourceFile) {
|
|
176
|
+
return pipelineEmitWithComments;
|
|
177
|
+
}
|
|
178
|
+
// falls through
|
|
179
|
+
case 2 /* PipelinePhase.Emit */:
|
|
180
|
+
return pipelineEmitWithHint;
|
|
181
|
+
default:
|
|
182
|
+
return Debug.assertNever(phase);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
function getNextPipelinePhase(currentPhase, emitHint, node) {
|
|
186
|
+
return getPipelinePhase(currentPhase + 1, emitHint, node);
|
|
187
|
+
}
|
|
188
|
+
function pipelineEmitWithNotification(hint, node) {
|
|
189
|
+
Debug.assert(lastNode === node);
|
|
190
|
+
const pipelinePhase = getNextPipelinePhase(0 /* PipelinePhase.Notification */, hint, node);
|
|
191
|
+
onEmitNode(hint, node, pipelinePhase);
|
|
192
|
+
Debug.assert(lastNode === node);
|
|
193
|
+
}
|
|
194
|
+
function pipelineEmitWithHint(hint, node) {
|
|
195
|
+
Debug.assert(lastNode === node);
|
|
196
|
+
if (hint === EmitHint.SourceFile)
|
|
197
|
+
return emitSourceFile(cast(node, isSourceFile));
|
|
198
|
+
if (hint === EmitHint.IdentifierName)
|
|
199
|
+
return emitIdentifier(cast(node, isIdentifier));
|
|
200
|
+
if (hint === EmitHint.JsxAttributeValue)
|
|
201
|
+
return emitLiteral(cast(node, isStringLiteral), /*jsxAttributeEscape*/ true);
|
|
202
|
+
if (hint === EmitHint.MappedTypeParameter)
|
|
203
|
+
return emitMappedTypeParameter(cast(node, isTypeParameterDeclaration));
|
|
204
|
+
if (hint === EmitHint.EmbeddedStatement) {
|
|
205
|
+
Debug.assertNode(node, isEmptyStatement);
|
|
206
|
+
return emitEmptyStatement(/*isEmbeddedStatement*/ true);
|
|
207
|
+
}
|
|
208
|
+
if (hint === EmitHint.Unspecified) {
|
|
209
|
+
if (isKeyword(node.kind))
|
|
210
|
+
return writeTokenNode(node, writeKeyword);
|
|
211
|
+
switch (node.kind) {
|
|
212
|
+
// Pseudo-literals
|
|
213
|
+
case SyntaxKind.TemplateHead:
|
|
214
|
+
case SyntaxKind.TemplateMiddle:
|
|
215
|
+
case SyntaxKind.TemplateTail:
|
|
216
|
+
return emitLiteral(node, /*jsxAttributeEscape*/ false);
|
|
217
|
+
// Identifiers
|
|
218
|
+
case SyntaxKind.Identifier:
|
|
219
|
+
return emitIdentifier(node);
|
|
220
|
+
// Parse tree nodes
|
|
221
|
+
// Names
|
|
222
|
+
case SyntaxKind.QualifiedName:
|
|
223
|
+
return emitQualifiedName(node);
|
|
224
|
+
case SyntaxKind.ComputedPropertyName:
|
|
225
|
+
return emitComputedPropertyName(node);
|
|
226
|
+
// Signature elements
|
|
227
|
+
case SyntaxKind.TypeParameter:
|
|
228
|
+
return emitTypeParameter(node);
|
|
229
|
+
case SyntaxKind.Parameter:
|
|
230
|
+
return emitParameter(node);
|
|
231
|
+
// Type members
|
|
232
|
+
case SyntaxKind.PropertySignature:
|
|
233
|
+
return emitPropertySignature(node);
|
|
234
|
+
case SyntaxKind.MethodSignature:
|
|
235
|
+
return emitMethodSignature(node);
|
|
236
|
+
case SyntaxKind.CallSignature:
|
|
237
|
+
return emitCallSignature(node);
|
|
238
|
+
case SyntaxKind.IndexSignature:
|
|
239
|
+
return emitIndexSignature(node);
|
|
240
|
+
// Types
|
|
241
|
+
case SyntaxKind.TypePredicate:
|
|
242
|
+
return emitTypePredicate(node);
|
|
243
|
+
case SyntaxKind.TypeReference:
|
|
244
|
+
return emitTypeReference(node);
|
|
245
|
+
case SyntaxKind.FunctionType:
|
|
246
|
+
return emitFunctionType(node);
|
|
247
|
+
case SyntaxKind.TypeQuery:
|
|
248
|
+
return emitTypeQuery(node);
|
|
249
|
+
case SyntaxKind.TypeLiteral:
|
|
250
|
+
return emitTypeLiteral(node);
|
|
251
|
+
case SyntaxKind.ArrayType:
|
|
252
|
+
return emitArrayType(node);
|
|
253
|
+
case SyntaxKind.TupleType:
|
|
254
|
+
return emitTupleType(node);
|
|
255
|
+
case SyntaxKind.OptionalType:
|
|
256
|
+
return emitOptionalType(node);
|
|
257
|
+
case SyntaxKind.UnionType:
|
|
258
|
+
return emitUnionType(node);
|
|
259
|
+
case SyntaxKind.IntersectionType:
|
|
260
|
+
return emitIntersectionType(node);
|
|
261
|
+
case SyntaxKind.ConditionalType:
|
|
262
|
+
return emitConditionalType(node);
|
|
263
|
+
case SyntaxKind.InferType:
|
|
264
|
+
return emitInferType(node);
|
|
265
|
+
case SyntaxKind.ParenthesizedType:
|
|
266
|
+
return emitParenthesizedType(node);
|
|
267
|
+
case SyntaxKind.TypeOperator:
|
|
268
|
+
return emitTypeOperator(node);
|
|
269
|
+
case SyntaxKind.IndexedAccessType:
|
|
270
|
+
return emitIndexedAccessType(node);
|
|
271
|
+
case SyntaxKind.MappedType:
|
|
272
|
+
return emitMappedType(node);
|
|
273
|
+
case SyntaxKind.LiteralType:
|
|
274
|
+
return emitLiteralType(node);
|
|
275
|
+
case SyntaxKind.ImportType:
|
|
276
|
+
return emitImportTypeNode(node);
|
|
277
|
+
case SyntaxKind.RestType:
|
|
278
|
+
return emitRestOrJSDocVariadicType(node);
|
|
279
|
+
// Binding patterns
|
|
280
|
+
case SyntaxKind.ObjectBindingPattern:
|
|
281
|
+
return emitObjectBindingPattern(node);
|
|
282
|
+
case SyntaxKind.ArrayBindingPattern:
|
|
283
|
+
return emitArrayBindingPattern(node);
|
|
284
|
+
case SyntaxKind.BindingElement:
|
|
285
|
+
return emitBindingElement(node);
|
|
286
|
+
// Misc
|
|
287
|
+
case SyntaxKind.TemplateSpan:
|
|
288
|
+
return emitTemplateSpan(node);
|
|
289
|
+
// Statements
|
|
290
|
+
case SyntaxKind.Block:
|
|
291
|
+
return emitBlock(node);
|
|
292
|
+
case SyntaxKind.VariableStatement:
|
|
293
|
+
return emitVariableStatement(node);
|
|
294
|
+
case SyntaxKind.EmptyStatement:
|
|
295
|
+
return emitEmptyStatement(/*isEmbeddedStatement*/ false);
|
|
296
|
+
case SyntaxKind.ExpressionStatement:
|
|
297
|
+
return emitExpressionStatement(node);
|
|
298
|
+
case SyntaxKind.IfStatement:
|
|
299
|
+
return emitIfStatement(node);
|
|
300
|
+
case SyntaxKind.DoStatement:
|
|
301
|
+
return emitDoStatement(node);
|
|
302
|
+
case SyntaxKind.WhileStatement:
|
|
303
|
+
return emitWhileStatement(node);
|
|
304
|
+
case SyntaxKind.ForStatement:
|
|
305
|
+
return emitForStatement(node);
|
|
306
|
+
case SyntaxKind.ForInStatement:
|
|
307
|
+
return emitForInStatement(node);
|
|
308
|
+
case SyntaxKind.ForOfStatement:
|
|
309
|
+
return emitForOfStatement(node);
|
|
310
|
+
case SyntaxKind.ContinueStatement:
|
|
311
|
+
return emitContinueStatement(node);
|
|
312
|
+
case SyntaxKind.BreakStatement:
|
|
313
|
+
return emitBreakStatement(node);
|
|
314
|
+
case SyntaxKind.ReturnStatement:
|
|
315
|
+
return emitReturnStatement(node);
|
|
316
|
+
case SyntaxKind.SwitchStatement:
|
|
317
|
+
return emitSwitchStatement(node);
|
|
318
|
+
case SyntaxKind.ThrowStatement:
|
|
319
|
+
return emitThrowStatement(node);
|
|
320
|
+
case SyntaxKind.TryStatement:
|
|
321
|
+
return emitTryStatement(node);
|
|
322
|
+
// Declarations
|
|
323
|
+
case SyntaxKind.VariableDeclaration:
|
|
324
|
+
return emitVariableDeclaration(node);
|
|
325
|
+
case SyntaxKind.VariableDeclarationList:
|
|
326
|
+
return emitVariableDeclarationList(node);
|
|
327
|
+
case SyntaxKind.TypeAliasDeclaration:
|
|
328
|
+
return emitTypeAliasDeclaration(node);
|
|
329
|
+
case SyntaxKind.ModuleDeclaration:
|
|
330
|
+
return emitModuleDeclaration(node);
|
|
331
|
+
case SyntaxKind.ModuleBlock:
|
|
332
|
+
return emitModuleBlock(node);
|
|
333
|
+
case SyntaxKind.CaseBlock:
|
|
334
|
+
return emitCaseBlock(node);
|
|
335
|
+
case SyntaxKind.ImportDeclaration:
|
|
336
|
+
return emitImportDeclaration(node);
|
|
337
|
+
case SyntaxKind.ImportClause:
|
|
338
|
+
return emitImportClause(node);
|
|
339
|
+
case SyntaxKind.NamespaceImport:
|
|
340
|
+
return emitNamespaceImport(node);
|
|
341
|
+
case SyntaxKind.NamespaceExport:
|
|
342
|
+
return emitNamespaceExport(node);
|
|
343
|
+
case SyntaxKind.NamedImports:
|
|
344
|
+
return emitNamedImports(node);
|
|
345
|
+
case SyntaxKind.ImportSpecifier:
|
|
346
|
+
return emitImportSpecifier(node);
|
|
347
|
+
case SyntaxKind.ExportAssignment:
|
|
348
|
+
return emitExportAssignment(node);
|
|
349
|
+
case SyntaxKind.ExportDeclaration:
|
|
350
|
+
return emitExportDeclaration(node);
|
|
351
|
+
case SyntaxKind.NamedExports:
|
|
352
|
+
return emitNamedExports(node);
|
|
353
|
+
case SyntaxKind.ExportSpecifier:
|
|
354
|
+
return emitExportSpecifier(node);
|
|
355
|
+
case SyntaxKind.MissingDeclaration:
|
|
356
|
+
return;
|
|
357
|
+
// JSX (non-expression)
|
|
358
|
+
case SyntaxKind.JsxText:
|
|
359
|
+
return emitJsxText(node);
|
|
360
|
+
case SyntaxKind.JsxOpeningElement:
|
|
361
|
+
case SyntaxKind.JsxOpeningFragment:
|
|
362
|
+
return emitJsxOpeningElementOrFragment(node);
|
|
363
|
+
case SyntaxKind.JsxClosingElement:
|
|
364
|
+
case SyntaxKind.JsxClosingFragment:
|
|
365
|
+
return emitJsxClosingElementOrFragment(node);
|
|
366
|
+
case SyntaxKind.JsxAttribute:
|
|
367
|
+
return emitJsxAttribute(node);
|
|
368
|
+
case SyntaxKind.JsxAttributes:
|
|
369
|
+
return emitJsxAttributes(node);
|
|
370
|
+
case SyntaxKind.JsxSpreadAttribute:
|
|
371
|
+
return emitJsxSpreadAttribute(node);
|
|
372
|
+
case SyntaxKind.JsxExpression:
|
|
373
|
+
return emitJsxExpression(node);
|
|
374
|
+
// Clauses
|
|
375
|
+
case SyntaxKind.CaseClause:
|
|
376
|
+
return emitCaseClause(node);
|
|
377
|
+
case SyntaxKind.DefaultClause:
|
|
378
|
+
return emitDefaultClause(node);
|
|
379
|
+
case SyntaxKind.CatchClause:
|
|
380
|
+
return emitCatchClause(node);
|
|
381
|
+
// Property assignments
|
|
382
|
+
case SyntaxKind.PropertyAssignment:
|
|
383
|
+
return emitPropertyAssignment(node);
|
|
384
|
+
case SyntaxKind.ShorthandPropertyAssignment:
|
|
385
|
+
return emitShorthandPropertyAssignment(node);
|
|
386
|
+
case SyntaxKind.SpreadAssignment:
|
|
387
|
+
return emitSpreadAssignment(node);
|
|
388
|
+
// Transformation nodes (ignored)
|
|
389
|
+
}
|
|
390
|
+
if (isExpression(node)) {
|
|
391
|
+
hint = EmitHint.Expression;
|
|
392
|
+
}
|
|
393
|
+
else if (isToken(node)) {
|
|
394
|
+
return writeTokenNode(node, writePunctuation);
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
if (hint === EmitHint.Expression) {
|
|
398
|
+
switch (node.kind) {
|
|
399
|
+
// Literals
|
|
400
|
+
case SyntaxKind.NumericLiteral:
|
|
401
|
+
case SyntaxKind.BigIntLiteral:
|
|
402
|
+
return emitNumericOrBigIntLiteral(node);
|
|
403
|
+
case SyntaxKind.StringLiteral:
|
|
404
|
+
case SyntaxKind.NoSubstitutionTemplateLiteral:
|
|
405
|
+
return emitLiteral(node, /*jsxAttributeEscape*/ false);
|
|
406
|
+
// Identifiers
|
|
407
|
+
case SyntaxKind.Identifier:
|
|
408
|
+
return emitIdentifier(node);
|
|
409
|
+
// Reserved words
|
|
410
|
+
case SyntaxKind.FalseKeyword:
|
|
411
|
+
case SyntaxKind.NullKeyword:
|
|
412
|
+
case SyntaxKind.TrueKeyword:
|
|
413
|
+
case SyntaxKind.ImportKeyword:
|
|
414
|
+
writeTokenNode(node, writeKeyword);
|
|
415
|
+
return;
|
|
416
|
+
// Expressions
|
|
417
|
+
case SyntaxKind.ArrayLiteralExpression:
|
|
418
|
+
return emitArrayLiteralExpression(node);
|
|
419
|
+
case SyntaxKind.ObjectLiteralExpression:
|
|
420
|
+
return emitObjectLiteralExpression(node);
|
|
421
|
+
case SyntaxKind.PropertyAccessExpression:
|
|
422
|
+
return emitPropertyAccessExpression(node);
|
|
423
|
+
case SyntaxKind.ElementAccessExpression:
|
|
424
|
+
return emitElementAccessExpression(node);
|
|
425
|
+
case SyntaxKind.CallExpression:
|
|
426
|
+
return emitCallExpression(node);
|
|
427
|
+
case SyntaxKind.ParenthesizedExpression:
|
|
428
|
+
return emitParenthesizedExpression(node);
|
|
429
|
+
case SyntaxKind.ArrowFunction:
|
|
430
|
+
return emitArrowFunction(node);
|
|
431
|
+
case SyntaxKind.DeleteExpression:
|
|
432
|
+
return emitDeleteExpression(node);
|
|
433
|
+
case SyntaxKind.TypeOfExpression:
|
|
434
|
+
return emitTypeOfExpression(node);
|
|
435
|
+
case SyntaxKind.AwaitExpression:
|
|
436
|
+
return emitAwaitExpression(node);
|
|
437
|
+
case SyntaxKind.PrefixUnaryExpression:
|
|
438
|
+
return emitPrefixUnaryExpression(node);
|
|
439
|
+
case SyntaxKind.PostfixUnaryExpression:
|
|
440
|
+
return emitPostfixUnaryExpression(node);
|
|
441
|
+
case SyntaxKind.BinaryExpression:
|
|
442
|
+
return emitBinaryExpression(node);
|
|
443
|
+
case SyntaxKind.ConditionalExpression:
|
|
444
|
+
return emitConditionalExpression(node);
|
|
445
|
+
case SyntaxKind.TemplateExpression:
|
|
446
|
+
return emitTemplateExpression(node);
|
|
447
|
+
case SyntaxKind.SpreadElement:
|
|
448
|
+
return emitSpreadExpression(node);
|
|
449
|
+
case SyntaxKind.OmittedExpression:
|
|
450
|
+
return;
|
|
451
|
+
case SyntaxKind.AsExpression:
|
|
452
|
+
return emitAsExpression(node);
|
|
453
|
+
case SyntaxKind.MetaProperty:
|
|
454
|
+
return emitMetaProperty(node);
|
|
455
|
+
// JSX
|
|
456
|
+
case SyntaxKind.JsxElement:
|
|
457
|
+
return emitJsxElement(node);
|
|
458
|
+
case SyntaxKind.JsxSelfClosingElement:
|
|
459
|
+
return emitJsxSelfClosingElement(node);
|
|
460
|
+
case SyntaxKind.JsxFragment:
|
|
461
|
+
return emitJsxFragment(node);
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
function emitMappedTypeParameter(node) {
|
|
466
|
+
emit(node.name);
|
|
467
|
+
writeSpace();
|
|
468
|
+
writeKeyword("in");
|
|
469
|
+
writeSpace();
|
|
470
|
+
emit(node.constraint);
|
|
471
|
+
}
|
|
472
|
+
//
|
|
473
|
+
// Literals/Pseudo-literals
|
|
474
|
+
//
|
|
475
|
+
// SyntaxKind.NumericLiteral
|
|
476
|
+
// SyntaxKind.BigIntLiteral
|
|
477
|
+
function emitNumericOrBigIntLiteral(node) {
|
|
478
|
+
emitLiteral(node, /*jsxAttributeEscape*/ false);
|
|
479
|
+
}
|
|
480
|
+
// SyntaxKind.StringLiteral
|
|
481
|
+
// SyntaxKind.NoSubstitutionTemplateLiteral
|
|
482
|
+
// SyntaxKind.TemplateHead
|
|
483
|
+
// SyntaxKind.TemplateMiddle
|
|
484
|
+
// SyntaxKind.TemplateTail
|
|
485
|
+
function emitLiteral(node, jsxAttributeEscape) {
|
|
486
|
+
const text = getLiteralTextOfNode(node, printerOptions.neverAsciiEscape, jsxAttributeEscape);
|
|
487
|
+
if ((printerOptions.sourceMap || printerOptions.inlineSourceMap)
|
|
488
|
+
&& (node.kind === SyntaxKind.StringLiteral || isTemplateLiteralKind(node.kind))) {
|
|
489
|
+
writeLiteral(text);
|
|
490
|
+
}
|
|
491
|
+
else {
|
|
492
|
+
// Quick info expects all literals to be called with writeStringLiteral, as there's no specific type for numberLiterals
|
|
493
|
+
writeStringLiteral(text);
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
//
|
|
497
|
+
// Identifiers
|
|
498
|
+
//
|
|
499
|
+
function emitIdentifier(node) {
|
|
500
|
+
const writeText = node.symbol ? writeSymbol : write;
|
|
501
|
+
writeText(getTextOfNode(node, /*includeTrivia*/ false), node.symbol);
|
|
502
|
+
emitList(node, node.typeArguments, 53776 /* ListFormat.TypeParameters */); // Call emitList directly since it could be an array of TypeParameterDeclarations _or_ type arguments
|
|
503
|
+
}
|
|
504
|
+
//
|
|
505
|
+
// Names
|
|
506
|
+
//
|
|
507
|
+
function emitQualifiedName(node) {
|
|
508
|
+
emitEntityName(node.left);
|
|
509
|
+
writePunctuation(".");
|
|
510
|
+
emit(node.right);
|
|
511
|
+
}
|
|
512
|
+
function emitEntityName(node) {
|
|
513
|
+
if (node.kind === SyntaxKind.Identifier) {
|
|
514
|
+
emitExpression(node);
|
|
515
|
+
}
|
|
516
|
+
else {
|
|
517
|
+
emit(node);
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
function emitComputedPropertyName(node) {
|
|
521
|
+
writePunctuation("[");
|
|
522
|
+
emitExpression(node.expression);
|
|
523
|
+
writePunctuation("]");
|
|
524
|
+
}
|
|
525
|
+
//
|
|
526
|
+
// Signature elements
|
|
527
|
+
//
|
|
528
|
+
function emitTypeParameter(node) {
|
|
529
|
+
emit(node.name);
|
|
530
|
+
if (node.constraint) {
|
|
531
|
+
writeSpace();
|
|
532
|
+
writeKeyword("extends");
|
|
533
|
+
writeSpace();
|
|
534
|
+
emit(node.constraint);
|
|
535
|
+
}
|
|
536
|
+
if (node.default) {
|
|
537
|
+
writeSpace();
|
|
538
|
+
writeOperator("=");
|
|
539
|
+
writeSpace();
|
|
540
|
+
emit(node.default);
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
function emitParameter(node) {
|
|
544
|
+
emitModifiers(node, node.modifiers);
|
|
545
|
+
emit(node.dotDotDotToken);
|
|
546
|
+
emitNodeWithWriter(node.name, writeParameter);
|
|
547
|
+
emit(node.questionToken);
|
|
548
|
+
emitTypeAnnotation(node.type);
|
|
549
|
+
// The comment position has to fallback to any present node within the parameterdeclaration because as it turns out, the parser can make parameter declarations with _just_ an initializer.
|
|
550
|
+
emitInitializer(node.initializer, node.type ? node.type.end : node.questionToken ? node.questionToken.end : node.name ? node.name.end : node.modifiers ? node.modifiers.end : node.pos, node);
|
|
551
|
+
}
|
|
552
|
+
//
|
|
553
|
+
// Type members
|
|
554
|
+
//
|
|
555
|
+
function emitPropertySignature(node) {
|
|
556
|
+
emitModifiers(node, node.modifiers);
|
|
557
|
+
emitNodeWithWriter(node.name, writeProperty);
|
|
558
|
+
emit(node.questionToken);
|
|
559
|
+
emitTypeAnnotation(node.type);
|
|
560
|
+
writeTrailingSemicolon();
|
|
561
|
+
}
|
|
562
|
+
function emitMethodSignature(node) {
|
|
563
|
+
pushNameGenerationScope(node);
|
|
564
|
+
emitModifiers(node, node.modifiers);
|
|
565
|
+
emit(node.name);
|
|
566
|
+
emit(node.questionToken);
|
|
567
|
+
emitTypeParameters(node, node.typeParameters);
|
|
568
|
+
emitParameters(node, node.parameters);
|
|
569
|
+
emitTypeAnnotation(node.type);
|
|
570
|
+
writeTrailingSemicolon();
|
|
571
|
+
popNameGenerationScope(node);
|
|
572
|
+
}
|
|
573
|
+
function emitCallSignature(node) {
|
|
574
|
+
pushNameGenerationScope(node);
|
|
575
|
+
emitModifiers(node, node.modifiers);
|
|
576
|
+
emitTypeParameters(node, node.typeParameters);
|
|
577
|
+
emitParameters(node, node.parameters);
|
|
578
|
+
emitTypeAnnotation(node.type);
|
|
579
|
+
writeTrailingSemicolon();
|
|
580
|
+
popNameGenerationScope(node);
|
|
581
|
+
}
|
|
582
|
+
function emitIndexSignature(node) {
|
|
583
|
+
emitModifiers(node, node.modifiers);
|
|
584
|
+
emitParametersForIndexSignature(node, node.parameters);
|
|
585
|
+
emitTypeAnnotation(node.type);
|
|
586
|
+
writeTrailingSemicolon();
|
|
587
|
+
}
|
|
588
|
+
//
|
|
589
|
+
// Types
|
|
590
|
+
//
|
|
591
|
+
function emitTypePredicate(node) {
|
|
592
|
+
if (node.assertsModifier) {
|
|
593
|
+
emit(node.assertsModifier);
|
|
594
|
+
writeSpace();
|
|
595
|
+
}
|
|
596
|
+
emit(node.parameterName);
|
|
597
|
+
if (node.type) {
|
|
598
|
+
writeSpace();
|
|
599
|
+
writeKeyword("is");
|
|
600
|
+
writeSpace();
|
|
601
|
+
emit(node.type);
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
function emitTypeReference(node) {
|
|
605
|
+
emit(node.typeName);
|
|
606
|
+
emitTypeArguments(node, node.typeArguments);
|
|
607
|
+
}
|
|
608
|
+
function emitFunctionType(node) {
|
|
609
|
+
pushNameGenerationScope(node);
|
|
610
|
+
emitTypeParameters(node, node.typeParameters);
|
|
611
|
+
emitParametersForArrow(node, node.parameters);
|
|
612
|
+
writeSpace();
|
|
613
|
+
writePunctuation("=>");
|
|
614
|
+
writeSpace();
|
|
615
|
+
emit(node.type);
|
|
616
|
+
popNameGenerationScope(node);
|
|
617
|
+
}
|
|
618
|
+
function emitTypeQuery(node) {
|
|
619
|
+
writeKeyword("typeof");
|
|
620
|
+
writeSpace();
|
|
621
|
+
emit(node.exprName);
|
|
622
|
+
}
|
|
623
|
+
function emitTypeLiteral(node) {
|
|
624
|
+
writePunctuation("{");
|
|
625
|
+
const flags = getEmitFlags(node) & EmitFlags.SingleLine ? 768 /* ListFormat.SingleLineTypeLiteralMembers */ : 32897 /* ListFormat.MultiLineTypeLiteralMembers */;
|
|
626
|
+
emitList(node, node.members, flags | 524288 /* ListFormat.NoSpaceIfEmpty */);
|
|
627
|
+
writePunctuation("}");
|
|
628
|
+
}
|
|
629
|
+
function emitArrayType(node) {
|
|
630
|
+
emit(node.elementType);
|
|
631
|
+
writePunctuation("[");
|
|
632
|
+
writePunctuation("]");
|
|
633
|
+
}
|
|
634
|
+
function emitRestOrJSDocVariadicType(node) {
|
|
635
|
+
writePunctuation("...");
|
|
636
|
+
emit(node.type);
|
|
637
|
+
}
|
|
638
|
+
function emitTupleType(node) {
|
|
639
|
+
writePunctuation("[");
|
|
640
|
+
emitList(node, node.elementTypes, 528 /* ListFormat.TupleTypeElements */);
|
|
641
|
+
writePunctuation("]");
|
|
642
|
+
}
|
|
643
|
+
function emitOptionalType(node) {
|
|
644
|
+
emit(node.type);
|
|
645
|
+
writePunctuation("?");
|
|
646
|
+
}
|
|
647
|
+
function emitUnionType(node) {
|
|
648
|
+
emitList(node, node.types, 516 /* ListFormat.UnionTypeConstituents */);
|
|
649
|
+
}
|
|
650
|
+
function emitIntersectionType(node) {
|
|
651
|
+
emitList(node, node.types, 520 /* ListFormat.IntersectionTypeConstituents */);
|
|
652
|
+
}
|
|
653
|
+
function emitConditionalType(node) {
|
|
654
|
+
emit(node.checkType);
|
|
655
|
+
writeSpace();
|
|
656
|
+
writeKeyword("extends");
|
|
657
|
+
writeSpace();
|
|
658
|
+
emit(node.extendsType);
|
|
659
|
+
writeSpace();
|
|
660
|
+
writePunctuation("?");
|
|
661
|
+
writeSpace();
|
|
662
|
+
emit(node.trueType);
|
|
663
|
+
writeSpace();
|
|
664
|
+
writePunctuation(":");
|
|
665
|
+
writeSpace();
|
|
666
|
+
emit(node.falseType);
|
|
667
|
+
}
|
|
668
|
+
function emitInferType(node) {
|
|
669
|
+
writeKeyword("infer");
|
|
670
|
+
writeSpace();
|
|
671
|
+
emit(node.typeParameter);
|
|
672
|
+
}
|
|
673
|
+
function emitParenthesizedType(node) {
|
|
674
|
+
writePunctuation("(");
|
|
675
|
+
emit(node.type);
|
|
676
|
+
writePunctuation(")");
|
|
677
|
+
}
|
|
678
|
+
function emitTypeOperator(node) {
|
|
679
|
+
writeTokenText(node.operator, writeKeyword);
|
|
680
|
+
writeSpace();
|
|
681
|
+
emit(node.type);
|
|
682
|
+
}
|
|
683
|
+
function emitIndexedAccessType(node) {
|
|
684
|
+
emit(node.objectType);
|
|
685
|
+
writePunctuation("[");
|
|
686
|
+
emit(node.indexType);
|
|
687
|
+
writePunctuation("]");
|
|
688
|
+
}
|
|
689
|
+
function emitMappedType(node) {
|
|
690
|
+
const emitFlags = getEmitFlags(node);
|
|
691
|
+
writePunctuation("{");
|
|
692
|
+
if (emitFlags & EmitFlags.SingleLine) {
|
|
693
|
+
writeSpace();
|
|
694
|
+
}
|
|
695
|
+
else {
|
|
696
|
+
writeLine();
|
|
697
|
+
increaseIndent();
|
|
698
|
+
}
|
|
699
|
+
if (node.readonlyToken) {
|
|
700
|
+
emit(node.readonlyToken);
|
|
701
|
+
if (node.readonlyToken.kind !== SyntaxKind.ReadonlyKeyword) {
|
|
702
|
+
writeKeyword("readonly");
|
|
703
|
+
}
|
|
704
|
+
writeSpace();
|
|
705
|
+
}
|
|
706
|
+
writePunctuation("[");
|
|
707
|
+
pipelineEmit(EmitHint.MappedTypeParameter, node.typeParameter);
|
|
708
|
+
writePunctuation("]");
|
|
709
|
+
if (node.questionToken) {
|
|
710
|
+
emit(node.questionToken);
|
|
711
|
+
if (node.questionToken.kind !== SyntaxKind.QuestionToken) {
|
|
712
|
+
writePunctuation("?");
|
|
713
|
+
}
|
|
714
|
+
}
|
|
715
|
+
writePunctuation(":");
|
|
716
|
+
writeSpace();
|
|
717
|
+
emit(node.type);
|
|
718
|
+
writeTrailingSemicolon();
|
|
719
|
+
if (emitFlags & EmitFlags.SingleLine) {
|
|
720
|
+
writeSpace();
|
|
721
|
+
}
|
|
722
|
+
else {
|
|
723
|
+
writeLine();
|
|
724
|
+
decreaseIndent();
|
|
725
|
+
}
|
|
726
|
+
writePunctuation("}");
|
|
727
|
+
}
|
|
728
|
+
function emitLiteralType(node) {
|
|
729
|
+
emitExpression(node.literal);
|
|
730
|
+
}
|
|
731
|
+
function emitImportTypeNode(node) {
|
|
732
|
+
if (node.isTypeOf) {
|
|
733
|
+
writeKeyword("typeof");
|
|
734
|
+
writeSpace();
|
|
735
|
+
}
|
|
736
|
+
writeKeyword("import");
|
|
737
|
+
writePunctuation("(");
|
|
738
|
+
emit(node.argument);
|
|
739
|
+
writePunctuation(")");
|
|
740
|
+
if (node.qualifier) {
|
|
741
|
+
writePunctuation(".");
|
|
742
|
+
emit(node.qualifier);
|
|
743
|
+
}
|
|
744
|
+
emitTypeArguments(node, node.typeArguments);
|
|
745
|
+
}
|
|
746
|
+
//
|
|
747
|
+
// Binding patterns
|
|
748
|
+
//
|
|
749
|
+
function emitObjectBindingPattern(node) {
|
|
750
|
+
writePunctuation("{");
|
|
751
|
+
emitList(node, node.elements, 525136 /* ListFormat.ObjectBindingPatternElements */);
|
|
752
|
+
writePunctuation("}");
|
|
753
|
+
}
|
|
754
|
+
function emitArrayBindingPattern(node) {
|
|
755
|
+
writePunctuation("[");
|
|
756
|
+
emitList(node, node.elements, 524880 /* ListFormat.ArrayBindingPatternElements */);
|
|
757
|
+
writePunctuation("]");
|
|
758
|
+
}
|
|
759
|
+
function emitBindingElement(node) {
|
|
760
|
+
emit(node.dotDotDotToken);
|
|
761
|
+
if (node.propertyName) {
|
|
762
|
+
emit(node.propertyName);
|
|
763
|
+
writePunctuation(":");
|
|
764
|
+
writeSpace();
|
|
765
|
+
}
|
|
766
|
+
emit(node.name);
|
|
767
|
+
emitInitializer(node.initializer, node.name.end, node);
|
|
768
|
+
}
|
|
769
|
+
//
|
|
770
|
+
// Expressions
|
|
771
|
+
//
|
|
772
|
+
function emitArrayLiteralExpression(node) {
|
|
773
|
+
const elements = node.elements;
|
|
774
|
+
const preferNewLine = node.multiLine ? 65536 /* ListFormat.PreferNewLine */ : 0 /* ListFormat.None */;
|
|
775
|
+
emitExpressionList(node, elements, 8914 /* ListFormat.ArrayLiteralExpressionElements */ | preferNewLine);
|
|
776
|
+
}
|
|
777
|
+
function emitObjectLiteralExpression(node) {
|
|
778
|
+
forEach(node.properties, generateMemberNames);
|
|
779
|
+
const indentedFlag = getEmitFlags(node) & EmitFlags.Indented;
|
|
780
|
+
if (indentedFlag) {
|
|
781
|
+
increaseIndent();
|
|
782
|
+
}
|
|
783
|
+
const preferNewLine = node.multiLine ? 65536 /* ListFormat.PreferNewLine */ : 0 /* ListFormat.None */;
|
|
784
|
+
const allowTrailingComma = currentSourceFile.languageVersion >= ScriptTarget.ES5 && !isJsonSourceFile(currentSourceFile) ? 64 /* ListFormat.AllowTrailingComma */ : 0 /* ListFormat.None */;
|
|
785
|
+
emitList(node, node.properties, 526226 /* ListFormat.ObjectLiteralExpressionProperties */ | allowTrailingComma | preferNewLine);
|
|
786
|
+
if (indentedFlag) {
|
|
787
|
+
decreaseIndent();
|
|
788
|
+
}
|
|
789
|
+
}
|
|
790
|
+
function emitPropertyAccessExpression(node) {
|
|
791
|
+
const expression = cast(emitExpression(node.expression), isExpression);
|
|
792
|
+
const token = node.questionDotToken || createNode(SyntaxKind.DotToken, node.expression.end, node.name.pos);
|
|
793
|
+
const linesBeforeDot = getLinesBetweenNodes(node, node.expression, token);
|
|
794
|
+
const linesAfterDot = getLinesBetweenNodes(node, token, node.name);
|
|
795
|
+
writeLinesAndIndent(linesBeforeDot, /*writeSpaceIfNotIndenting*/ false);
|
|
796
|
+
const shouldEmitDotDot = token.kind !== SyntaxKind.QuestionDotToken &&
|
|
797
|
+
mayNeedDotDotForPropertyAccess(expression) &&
|
|
798
|
+
!writer.hasTrailingComment() &&
|
|
799
|
+
!writer.hasTrailingWhitespace();
|
|
800
|
+
if (shouldEmitDotDot) {
|
|
801
|
+
writePunctuation(".");
|
|
802
|
+
}
|
|
803
|
+
if (node.questionDotToken) {
|
|
804
|
+
emit(token);
|
|
805
|
+
}
|
|
806
|
+
else {
|
|
807
|
+
emitTokenWithComment(token.kind, node.expression.end, writePunctuation, node);
|
|
808
|
+
}
|
|
809
|
+
writeLinesAndIndent(linesAfterDot, /*writeSpaceIfNotIndenting*/ false);
|
|
810
|
+
emit(node.name);
|
|
811
|
+
decreaseIndentIf(linesBeforeDot, linesAfterDot);
|
|
812
|
+
}
|
|
813
|
+
// `1..toString` é um acesso válido: o literal inteiro, impresso como foi escrito e sem ponto, precisa de um segundo
|
|
814
|
+
// ponto antes do acesso.
|
|
815
|
+
function mayNeedDotDotForPropertyAccess(expression) {
|
|
816
|
+
expression = skipPartiallyEmittedExpressions(expression);
|
|
817
|
+
if (isNumericLiteral(expression)) {
|
|
818
|
+
const text = getLiteralTextOfNode(expression, /*neverAsciiEscape*/ true, /*jsxAttributeEscape*/ false);
|
|
819
|
+
return !expression.numericLiteralFlags && !stringContains(text, tokenToString(SyntaxKind.DotToken));
|
|
820
|
+
}
|
|
821
|
+
}
|
|
822
|
+
function emitElementAccessExpression(node) {
|
|
823
|
+
emitExpression(node.expression);
|
|
824
|
+
emit(node.questionDotToken);
|
|
825
|
+
emitTokenWithComment(SyntaxKind.OpenBracketToken, node.expression.end, writePunctuation, node);
|
|
826
|
+
emitExpression(node.argumentExpression);
|
|
827
|
+
emitTokenWithComment(SyntaxKind.CloseBracketToken, node.argumentExpression.end, writePunctuation, node);
|
|
828
|
+
}
|
|
829
|
+
function emitCallExpression(node) {
|
|
830
|
+
emitExpression(node.expression);
|
|
831
|
+
emit(node.questionDotToken);
|
|
832
|
+
emitTypeArguments(node, node.typeArguments);
|
|
833
|
+
emitExpressionList(node, node.arguments, 2576 /* ListFormat.CallExpressionArguments */);
|
|
834
|
+
}
|
|
835
|
+
function emitParenthesizedExpression(node) {
|
|
836
|
+
const openParenPos = emitTokenWithComment(SyntaxKind.OpenParenToken, node.pos, writePunctuation, node);
|
|
837
|
+
const indented = writeLineSeparatorsAndIndentBefore(node.expression, node);
|
|
838
|
+
emitExpression(node.expression);
|
|
839
|
+
writeLineSeparatorsAfter(node.expression, node);
|
|
840
|
+
decreaseIndentIf(indented);
|
|
841
|
+
emitTokenWithComment(SyntaxKind.CloseParenToken, node.expression ? node.expression.end : openParenPos, writePunctuation, node);
|
|
842
|
+
}
|
|
843
|
+
function emitArrowFunction(node) {
|
|
844
|
+
emitModifiers(node, node.modifiers);
|
|
845
|
+
emitSignatureAndBody(node, emitArrowFunctionHead);
|
|
846
|
+
}
|
|
847
|
+
function emitArrowFunctionHead(node) {
|
|
848
|
+
emitTypeParameters(node, node.typeParameters);
|
|
849
|
+
emitParametersForArrow(node, node.parameters);
|
|
850
|
+
emitTypeAnnotation(node.type);
|
|
851
|
+
writeSpace();
|
|
852
|
+
emit(node.equalsGreaterThanToken);
|
|
853
|
+
}
|
|
854
|
+
function emitDeleteExpression(node) {
|
|
855
|
+
emitTokenWithComment(SyntaxKind.DeleteKeyword, node.pos, writeKeyword, node);
|
|
856
|
+
writeSpace();
|
|
857
|
+
emitExpression(node.expression);
|
|
858
|
+
}
|
|
859
|
+
function emitTypeOfExpression(node) {
|
|
860
|
+
emitTokenWithComment(SyntaxKind.TypeOfKeyword, node.pos, writeKeyword, node);
|
|
861
|
+
writeSpace();
|
|
862
|
+
emitExpression(node.expression);
|
|
863
|
+
}
|
|
864
|
+
function emitAwaitExpression(node) {
|
|
865
|
+
emitTokenWithComment(SyntaxKind.AwaitKeyword, node.pos, writeKeyword, node);
|
|
866
|
+
writeSpace();
|
|
867
|
+
emitExpression(node.expression);
|
|
868
|
+
}
|
|
869
|
+
function emitPrefixUnaryExpression(node) {
|
|
870
|
+
writeTokenText(node.operator, writeOperator);
|
|
871
|
+
if (shouldEmitWhitespaceBeforeOperand(node)) {
|
|
872
|
+
writeSpace();
|
|
873
|
+
}
|
|
874
|
+
emitExpression(node.operand);
|
|
875
|
+
}
|
|
876
|
+
function shouldEmitWhitespaceBeforeOperand(node) {
|
|
877
|
+
// In some cases, we need to emit a space between the operator and the operand. One obvious case
|
|
878
|
+
// is when the operator is an identifier, like delete or typeof. We also need to do this for plus
|
|
879
|
+
// and minus expressions in certain cases. Specifically, consider the following two cases (parens
|
|
880
|
+
// are just for clarity of exposition, and not part of the source code):
|
|
881
|
+
//
|
|
882
|
+
// (+(+1))
|
|
883
|
+
// (+(++1))
|
|
884
|
+
//
|
|
885
|
+
// We need to emit a space in both cases. In the first case, the absence of a space will make
|
|
886
|
+
// the resulting expression a prefix increment operation. And in the second, it will make the resulting
|
|
887
|
+
// expression a prefix increment whose operand is a plus expression - (++(+x))
|
|
888
|
+
// The same is true of minus of course.
|
|
889
|
+
const operand = node.operand;
|
|
890
|
+
return operand.kind === SyntaxKind.PrefixUnaryExpression
|
|
891
|
+
&& ((node.operator === SyntaxKind.PlusToken && (operand.operator === SyntaxKind.PlusToken || operand.operator === SyntaxKind.PlusPlusToken))
|
|
892
|
+
|| (node.operator === SyntaxKind.MinusToken && (operand.operator === SyntaxKind.MinusToken || operand.operator === SyntaxKind.MinusMinusToken)));
|
|
893
|
+
}
|
|
894
|
+
function emitPostfixUnaryExpression(node) {
|
|
895
|
+
emitExpression(node.operand);
|
|
896
|
+
writeTokenText(node.operator, writeOperator);
|
|
897
|
+
}
|
|
898
|
+
let EmitBinaryExpressionState;
|
|
899
|
+
(function (EmitBinaryExpressionState) {
|
|
900
|
+
EmitBinaryExpressionState[EmitBinaryExpressionState["EmitLeft"] = 0] = "EmitLeft";
|
|
901
|
+
EmitBinaryExpressionState[EmitBinaryExpressionState["EmitRight"] = 1] = "EmitRight";
|
|
902
|
+
EmitBinaryExpressionState[EmitBinaryExpressionState["FinishEmit"] = 2] = "FinishEmit";
|
|
903
|
+
})(EmitBinaryExpressionState || (EmitBinaryExpressionState = {}));
|
|
904
|
+
/**
|
|
905
|
+
* emitBinaryExpression includes an embedded work stack to attempt to handle as many nested binary expressions
|
|
906
|
+
* as possible without creating any additional stack frames. This can only be done when the emit pipeline does
|
|
907
|
+
* not require notification/substitution/comment/sourcemap decorations.
|
|
908
|
+
*/
|
|
909
|
+
function emitBinaryExpression(node) {
|
|
910
|
+
const nodeStack = [node];
|
|
911
|
+
const stateStack = [0 /* EmitBinaryExpressionState.EmitLeft */];
|
|
912
|
+
let stackIndex = 0;
|
|
913
|
+
while (stackIndex >= 0) {
|
|
914
|
+
node = nodeStack[stackIndex];
|
|
915
|
+
switch (stateStack[stackIndex]) {
|
|
916
|
+
case 0 /* EmitBinaryExpressionState.EmitLeft */: {
|
|
917
|
+
maybePipelineEmitExpression(node.left);
|
|
918
|
+
break;
|
|
919
|
+
}
|
|
920
|
+
case 1 /* EmitBinaryExpressionState.EmitRight */: {
|
|
921
|
+
const isCommaOperator = node.operatorToken.kind !== SyntaxKind.CommaToken;
|
|
922
|
+
const linesBeforeOperator = getLinesBetweenNodes(node, node.left, node.operatorToken);
|
|
923
|
+
const linesAfterOperator = getLinesBetweenNodes(node, node.operatorToken, node.right);
|
|
924
|
+
writeLinesAndIndent(linesBeforeOperator, isCommaOperator);
|
|
925
|
+
emitLeadingCommentsOfPosition(node.operatorToken.pos);
|
|
926
|
+
writeTokenNode(node.operatorToken, node.operatorToken.kind === SyntaxKind.InKeyword ? writeKeyword : writeOperator);
|
|
927
|
+
emitTrailingCommentsOfPosition(node.operatorToken.end, /*prefixSpace*/ true); // Binary operators should have a space before the comment starts
|
|
928
|
+
writeLinesAndIndent(linesAfterOperator, /*writeSpaceIfNotIndenting*/ true);
|
|
929
|
+
maybePipelineEmitExpression(node.right);
|
|
930
|
+
break;
|
|
931
|
+
}
|
|
932
|
+
case 2 /* EmitBinaryExpressionState.FinishEmit */: {
|
|
933
|
+
const linesBeforeOperator = getLinesBetweenNodes(node, node.left, node.operatorToken);
|
|
934
|
+
const linesAfterOperator = getLinesBetweenNodes(node, node.operatorToken, node.right);
|
|
935
|
+
decreaseIndentIf(linesBeforeOperator, linesAfterOperator);
|
|
936
|
+
stackIndex--;
|
|
937
|
+
break;
|
|
938
|
+
}
|
|
939
|
+
default: return Debug.fail(`Invalid state ${stateStack[stackIndex]} for emitBinaryExpressionWorker`);
|
|
940
|
+
}
|
|
941
|
+
}
|
|
942
|
+
function maybePipelineEmitExpression(next) {
|
|
943
|
+
// Advance the state of this unit of work,
|
|
944
|
+
stateStack[stackIndex]++;
|
|
945
|
+
// Then actually do the work of emitting the node `next` returned by the prior state
|
|
946
|
+
// The following section should be identical to `pipelineEmit` save it assumes EmitHint.Expression and offloads
|
|
947
|
+
// binary expression handling, where possible, to the contained work queue
|
|
948
|
+
// #region trampolinePipelineEmit
|
|
949
|
+
const savedLastNode = lastNode;
|
|
950
|
+
lastNode = next;
|
|
951
|
+
const pipelinePhase = getPipelinePhase(0 /* PipelinePhase.Notification */, EmitHint.Expression, next);
|
|
952
|
+
if (pipelinePhase === pipelineEmitWithHint && isBinaryExpression(next)) {
|
|
953
|
+
// If the target pipeline phase is emit directly, and the next node's also a binary expression,
|
|
954
|
+
// skip all the intermediate indirection and push the expression directly onto the work stack
|
|
955
|
+
stackIndex++;
|
|
956
|
+
stateStack[stackIndex] = 0 /* EmitBinaryExpressionState.EmitLeft */;
|
|
957
|
+
nodeStack[stackIndex] = next;
|
|
958
|
+
}
|
|
959
|
+
else {
|
|
960
|
+
pipelinePhase(EmitHint.Expression, next);
|
|
961
|
+
}
|
|
962
|
+
Debug.assert(lastNode === next);
|
|
963
|
+
lastNode = savedLastNode;
|
|
964
|
+
// #endregion trampolinePipelineEmit
|
|
965
|
+
}
|
|
966
|
+
}
|
|
967
|
+
function emitConditionalExpression(node) {
|
|
968
|
+
const linesBeforeQuestion = getLinesBetweenNodes(node, node.condition, node.questionToken);
|
|
969
|
+
const linesAfterQuestion = getLinesBetweenNodes(node, node.questionToken, node.whenTrue);
|
|
970
|
+
const linesBeforeColon = getLinesBetweenNodes(node, node.whenTrue, node.colonToken);
|
|
971
|
+
const linesAfterColon = getLinesBetweenNodes(node, node.colonToken, node.whenFalse);
|
|
972
|
+
emitExpression(node.condition);
|
|
973
|
+
writeLinesAndIndent(linesBeforeQuestion, /*writeSpaceIfNotIndenting*/ true);
|
|
974
|
+
emit(node.questionToken);
|
|
975
|
+
writeLinesAndIndent(linesAfterQuestion, /*writeSpaceIfNotIndenting*/ true);
|
|
976
|
+
emitExpression(node.whenTrue);
|
|
977
|
+
decreaseIndentIf(linesBeforeQuestion, linesAfterQuestion);
|
|
978
|
+
writeLinesAndIndent(linesBeforeColon, /*writeSpaceIfNotIndenting*/ true);
|
|
979
|
+
emit(node.colonToken);
|
|
980
|
+
writeLinesAndIndent(linesAfterColon, /*writeSpaceIfNotIndenting*/ true);
|
|
981
|
+
emitExpression(node.whenFalse);
|
|
982
|
+
decreaseIndentIf(linesBeforeColon, linesAfterColon);
|
|
983
|
+
}
|
|
984
|
+
function emitTemplateExpression(node) {
|
|
985
|
+
emit(node.head);
|
|
986
|
+
emitList(node, node.templateSpans, 262144 /* ListFormat.TemplateExpressionSpans */);
|
|
987
|
+
}
|
|
988
|
+
function emitSpreadExpression(node) {
|
|
989
|
+
emitTokenWithComment(SyntaxKind.DotDotDotToken, node.pos, writePunctuation, node);
|
|
990
|
+
emitExpression(node.expression);
|
|
991
|
+
}
|
|
992
|
+
function emitAsExpression(node) {
|
|
993
|
+
emitExpression(node.expression);
|
|
994
|
+
if (node.type) {
|
|
995
|
+
writeSpace();
|
|
996
|
+
writeKeyword("as");
|
|
997
|
+
writeSpace();
|
|
998
|
+
emit(node.type);
|
|
999
|
+
}
|
|
1000
|
+
}
|
|
1001
|
+
function emitMetaProperty(node) {
|
|
1002
|
+
writeToken(node.keywordToken, node.pos, writePunctuation);
|
|
1003
|
+
writePunctuation(".");
|
|
1004
|
+
emit(node.name);
|
|
1005
|
+
}
|
|
1006
|
+
//
|
|
1007
|
+
// Misc
|
|
1008
|
+
//
|
|
1009
|
+
function emitTemplateSpan(node) {
|
|
1010
|
+
emitExpression(node.expression);
|
|
1011
|
+
emit(node.literal);
|
|
1012
|
+
}
|
|
1013
|
+
//
|
|
1014
|
+
// Statements
|
|
1015
|
+
//
|
|
1016
|
+
function emitBlock(node) {
|
|
1017
|
+
emitBlockStatements(node, /*forceSingleLine*/ !node.multiLine && isEmptyBlock(node));
|
|
1018
|
+
}
|
|
1019
|
+
function emitBlockStatements(node, forceSingleLine) {
|
|
1020
|
+
emitTokenWithComment(SyntaxKind.OpenBraceToken, node.pos, writePunctuation, /*contextNode*/ node);
|
|
1021
|
+
const format = forceSingleLine || getEmitFlags(node) & EmitFlags.SingleLine ? 768 /* ListFormat.SingleLineBlockStatements */ : 129 /* ListFormat.MultiLineBlockStatements */;
|
|
1022
|
+
emitList(node, node.statements, format);
|
|
1023
|
+
emitTokenWithComment(SyntaxKind.CloseBraceToken, node.statements.end, writePunctuation, /*contextNode*/ node, /*indentLeading*/ !!(format & 1 /* ListFormat.MultiLine */));
|
|
1024
|
+
}
|
|
1025
|
+
function emitVariableStatement(node) {
|
|
1026
|
+
emitModifiers(node, node.modifiers);
|
|
1027
|
+
emit(node.declarationList);
|
|
1028
|
+
writeTrailingSemicolon();
|
|
1029
|
+
}
|
|
1030
|
+
function emitEmptyStatement(isEmbeddedStatement) {
|
|
1031
|
+
// While most trailing semicolons are possibly insignificant, an embedded "empty"
|
|
1032
|
+
// statement is significant and cannot be elided by a trailing-semicolon-omitting writer.
|
|
1033
|
+
if (isEmbeddedStatement) {
|
|
1034
|
+
writePunctuation(";");
|
|
1035
|
+
}
|
|
1036
|
+
else {
|
|
1037
|
+
writeTrailingSemicolon();
|
|
1038
|
+
}
|
|
1039
|
+
}
|
|
1040
|
+
function emitExpressionStatement(node) {
|
|
1041
|
+
emitExpression(node.expression);
|
|
1042
|
+
// Emit semicolon in non json files
|
|
1043
|
+
// or if json file that created synthesized expression(eg.define expression statement when --out and amd code generation)
|
|
1044
|
+
if (!isJsonSourceFile(currentSourceFile) || nodeIsSynthesized(node.expression)) {
|
|
1045
|
+
writeTrailingSemicolon();
|
|
1046
|
+
}
|
|
1047
|
+
}
|
|
1048
|
+
function emitIfStatement(node) {
|
|
1049
|
+
const openParenPos = emitTokenWithComment(SyntaxKind.IfKeyword, node.pos, writeKeyword, node);
|
|
1050
|
+
writeSpace();
|
|
1051
|
+
emitTokenWithComment(SyntaxKind.OpenParenToken, openParenPos, writePunctuation, node);
|
|
1052
|
+
emitExpression(node.expression);
|
|
1053
|
+
emitTokenWithComment(SyntaxKind.CloseParenToken, node.expression.end, writePunctuation, node);
|
|
1054
|
+
emitEmbeddedStatement(node, node.thenStatement);
|
|
1055
|
+
if (node.elseStatement) {
|
|
1056
|
+
writeLineOrSpace(node);
|
|
1057
|
+
emitTokenWithComment(SyntaxKind.ElseKeyword, node.thenStatement.end, writeKeyword, node);
|
|
1058
|
+
if (node.elseStatement.kind === SyntaxKind.IfStatement) {
|
|
1059
|
+
writeSpace();
|
|
1060
|
+
emit(node.elseStatement);
|
|
1061
|
+
}
|
|
1062
|
+
else {
|
|
1063
|
+
emitEmbeddedStatement(node, node.elseStatement);
|
|
1064
|
+
}
|
|
1065
|
+
}
|
|
1066
|
+
}
|
|
1067
|
+
function emitWhileClause(node, startPos) {
|
|
1068
|
+
const openParenPos = emitTokenWithComment(SyntaxKind.WhileKeyword, startPos, writeKeyword, node);
|
|
1069
|
+
writeSpace();
|
|
1070
|
+
emitTokenWithComment(SyntaxKind.OpenParenToken, openParenPos, writePunctuation, node);
|
|
1071
|
+
emitExpression(node.expression);
|
|
1072
|
+
emitTokenWithComment(SyntaxKind.CloseParenToken, node.expression.end, writePunctuation, node);
|
|
1073
|
+
}
|
|
1074
|
+
function emitDoStatement(node) {
|
|
1075
|
+
emitTokenWithComment(SyntaxKind.DoKeyword, node.pos, writeKeyword, node);
|
|
1076
|
+
emitEmbeddedStatement(node, node.statement);
|
|
1077
|
+
if (isBlock(node.statement)) {
|
|
1078
|
+
writeSpace();
|
|
1079
|
+
}
|
|
1080
|
+
else {
|
|
1081
|
+
writeLineOrSpace(node);
|
|
1082
|
+
}
|
|
1083
|
+
emitWhileClause(node, node.statement.end);
|
|
1084
|
+
writeTrailingSemicolon();
|
|
1085
|
+
}
|
|
1086
|
+
function emitWhileStatement(node) {
|
|
1087
|
+
emitWhileClause(node, node.pos);
|
|
1088
|
+
emitEmbeddedStatement(node, node.statement);
|
|
1089
|
+
}
|
|
1090
|
+
function emitForStatement(node) {
|
|
1091
|
+
const openParenPos = emitTokenWithComment(SyntaxKind.ForKeyword, node.pos, writeKeyword, node);
|
|
1092
|
+
writeSpace();
|
|
1093
|
+
let pos = emitTokenWithComment(SyntaxKind.OpenParenToken, openParenPos, writePunctuation, /*contextNode*/ node);
|
|
1094
|
+
emitForBinding(node.initializer);
|
|
1095
|
+
pos = emitTokenWithComment(SyntaxKind.SemicolonToken, node.initializer ? node.initializer.end : pos, writePunctuation, node);
|
|
1096
|
+
emitExpressionWithLeadingSpace(node.condition);
|
|
1097
|
+
pos = emitTokenWithComment(SyntaxKind.SemicolonToken, node.condition ? node.condition.end : pos, writePunctuation, node);
|
|
1098
|
+
emitExpressionWithLeadingSpace(node.incrementor);
|
|
1099
|
+
emitTokenWithComment(SyntaxKind.CloseParenToken, node.incrementor ? node.incrementor.end : pos, writePunctuation, node);
|
|
1100
|
+
emitEmbeddedStatement(node, node.statement);
|
|
1101
|
+
}
|
|
1102
|
+
function emitForInStatement(node) {
|
|
1103
|
+
const openParenPos = emitTokenWithComment(SyntaxKind.ForKeyword, node.pos, writeKeyword, node);
|
|
1104
|
+
writeSpace();
|
|
1105
|
+
emitTokenWithComment(SyntaxKind.OpenParenToken, openParenPos, writePunctuation, node);
|
|
1106
|
+
emitForBinding(node.initializer);
|
|
1107
|
+
writeSpace();
|
|
1108
|
+
emitTokenWithComment(SyntaxKind.InKeyword, node.initializer.end, writeKeyword, node);
|
|
1109
|
+
writeSpace();
|
|
1110
|
+
emitExpression(node.expression);
|
|
1111
|
+
emitTokenWithComment(SyntaxKind.CloseParenToken, node.expression.end, writePunctuation, node);
|
|
1112
|
+
emitEmbeddedStatement(node, node.statement);
|
|
1113
|
+
}
|
|
1114
|
+
function emitForOfStatement(node) {
|
|
1115
|
+
const openParenPos = emitTokenWithComment(SyntaxKind.ForKeyword, node.pos, writeKeyword, node);
|
|
1116
|
+
writeSpace();
|
|
1117
|
+
emitWithTrailingSpace(node.awaitModifier);
|
|
1118
|
+
emitTokenWithComment(SyntaxKind.OpenParenToken, openParenPos, writePunctuation, node);
|
|
1119
|
+
emitForBinding(node.initializer);
|
|
1120
|
+
writeSpace();
|
|
1121
|
+
emitTokenWithComment(SyntaxKind.OfKeyword, node.initializer.end, writeKeyword, node);
|
|
1122
|
+
writeSpace();
|
|
1123
|
+
emitExpression(node.expression);
|
|
1124
|
+
emitTokenWithComment(SyntaxKind.CloseParenToken, node.expression.end, writePunctuation, node);
|
|
1125
|
+
emitEmbeddedStatement(node, node.statement);
|
|
1126
|
+
}
|
|
1127
|
+
function emitForBinding(node) {
|
|
1128
|
+
if (node !== undefined) {
|
|
1129
|
+
if (node.kind === SyntaxKind.VariableDeclarationList) {
|
|
1130
|
+
emit(node);
|
|
1131
|
+
}
|
|
1132
|
+
else {
|
|
1133
|
+
emitExpression(node);
|
|
1134
|
+
}
|
|
1135
|
+
}
|
|
1136
|
+
}
|
|
1137
|
+
function emitContinueStatement(node) {
|
|
1138
|
+
emitTokenWithComment(SyntaxKind.ContinueKeyword, node.pos, writeKeyword, node);
|
|
1139
|
+
writeTrailingSemicolon();
|
|
1140
|
+
}
|
|
1141
|
+
function emitBreakStatement(node) {
|
|
1142
|
+
emitTokenWithComment(SyntaxKind.BreakKeyword, node.pos, writeKeyword, node);
|
|
1143
|
+
writeTrailingSemicolon();
|
|
1144
|
+
}
|
|
1145
|
+
function emitTokenWithComment(token, pos, writer, contextNode, indentLeading) {
|
|
1146
|
+
const node = getParseTreeNode(contextNode);
|
|
1147
|
+
const isSimilarNode = node && node.kind === contextNode.kind;
|
|
1148
|
+
const startPos = pos;
|
|
1149
|
+
if (isSimilarNode && currentSourceFile) {
|
|
1150
|
+
pos = skipTrivia(currentSourceFile.text, pos);
|
|
1151
|
+
}
|
|
1152
|
+
if (emitLeadingCommentsOfPosition && isSimilarNode && contextNode.pos !== startPos) {
|
|
1153
|
+
const needsIndent = indentLeading && currentSourceFile && !positionsAreOnSameLine(startPos, pos, currentSourceFile);
|
|
1154
|
+
if (needsIndent) {
|
|
1155
|
+
increaseIndent();
|
|
1156
|
+
}
|
|
1157
|
+
emitLeadingCommentsOfPosition(startPos);
|
|
1158
|
+
if (needsIndent) {
|
|
1159
|
+
decreaseIndent();
|
|
1160
|
+
}
|
|
1161
|
+
}
|
|
1162
|
+
pos = writeTokenText(token, writer, pos);
|
|
1163
|
+
if (emitTrailingCommentsOfPosition && isSimilarNode && contextNode.end !== pos) {
|
|
1164
|
+
emitTrailingCommentsOfPosition(pos, /*prefixSpace*/ true);
|
|
1165
|
+
}
|
|
1166
|
+
return pos;
|
|
1167
|
+
}
|
|
1168
|
+
function emitReturnStatement(node) {
|
|
1169
|
+
emitTokenWithComment(SyntaxKind.ReturnKeyword, node.pos, writeKeyword, /*contextNode*/ node);
|
|
1170
|
+
emitExpressionWithLeadingSpace(node.expression);
|
|
1171
|
+
writeTrailingSemicolon();
|
|
1172
|
+
}
|
|
1173
|
+
function emitSwitchStatement(node) {
|
|
1174
|
+
const openParenPos = emitTokenWithComment(SyntaxKind.SwitchKeyword, node.pos, writeKeyword, node);
|
|
1175
|
+
writeSpace();
|
|
1176
|
+
emitTokenWithComment(SyntaxKind.OpenParenToken, openParenPos, writePunctuation, node);
|
|
1177
|
+
emitExpression(node.expression);
|
|
1178
|
+
emitTokenWithComment(SyntaxKind.CloseParenToken, node.expression.end, writePunctuation, node);
|
|
1179
|
+
writeSpace();
|
|
1180
|
+
emit(node.caseBlock);
|
|
1181
|
+
}
|
|
1182
|
+
function emitThrowStatement(node) {
|
|
1183
|
+
emitTokenWithComment(SyntaxKind.ThrowKeyword, node.pos, writeKeyword, node);
|
|
1184
|
+
emitExpressionWithLeadingSpace(node.expression);
|
|
1185
|
+
writeTrailingSemicolon();
|
|
1186
|
+
}
|
|
1187
|
+
function emitTryStatement(node) {
|
|
1188
|
+
emitTokenWithComment(SyntaxKind.TryKeyword, node.pos, writeKeyword, node);
|
|
1189
|
+
writeSpace();
|
|
1190
|
+
emit(node.tryBlock);
|
|
1191
|
+
if (node.catchClause) {
|
|
1192
|
+
writeLineOrSpace(node);
|
|
1193
|
+
emit(node.catchClause);
|
|
1194
|
+
}
|
|
1195
|
+
if (node.finallyBlock) {
|
|
1196
|
+
writeLineOrSpace(node);
|
|
1197
|
+
emitTokenWithComment(SyntaxKind.FinallyKeyword, (node.catchClause || node.tryBlock).end, writeKeyword, node);
|
|
1198
|
+
writeSpace();
|
|
1199
|
+
emit(node.finallyBlock);
|
|
1200
|
+
}
|
|
1201
|
+
}
|
|
1202
|
+
//
|
|
1203
|
+
// Declarations
|
|
1204
|
+
//
|
|
1205
|
+
function emitVariableDeclaration(node) {
|
|
1206
|
+
emit(node.name);
|
|
1207
|
+
emit(node.exclamationToken);
|
|
1208
|
+
emitTypeAnnotation(node.type);
|
|
1209
|
+
emitInitializer(node.initializer, node.type ? node.type.end : node.name.end, node);
|
|
1210
|
+
}
|
|
1211
|
+
function emitVariableDeclarationList(node) {
|
|
1212
|
+
writeKeyword(isLet(node) ? "let" : isVarConst(node) ? "const" : "var");
|
|
1213
|
+
writeSpace();
|
|
1214
|
+
emitList(node, node.declarations, 528 /* ListFormat.VariableDeclarationList */);
|
|
1215
|
+
}
|
|
1216
|
+
function emitBlockCallback(_hint, body) {
|
|
1217
|
+
emitBlockFunctionBody(body);
|
|
1218
|
+
}
|
|
1219
|
+
function emitSignatureAndBody(node, emitSignatureHead) {
|
|
1220
|
+
const body = node.body;
|
|
1221
|
+
if (body) {
|
|
1222
|
+
if (isBlock(body)) {
|
|
1223
|
+
const indentedFlag = getEmitFlags(node) & EmitFlags.Indented;
|
|
1224
|
+
if (indentedFlag) {
|
|
1225
|
+
increaseIndent();
|
|
1226
|
+
}
|
|
1227
|
+
pushNameGenerationScope(node);
|
|
1228
|
+
forEach(node.parameters, generateNames);
|
|
1229
|
+
generateNames(node.body);
|
|
1230
|
+
emitSignatureHead(node);
|
|
1231
|
+
if (onEmitNode) {
|
|
1232
|
+
onEmitNode(EmitHint.Unspecified, body, emitBlockCallback);
|
|
1233
|
+
}
|
|
1234
|
+
else {
|
|
1235
|
+
emitBlockFunctionBody(body);
|
|
1236
|
+
}
|
|
1237
|
+
popNameGenerationScope(node);
|
|
1238
|
+
if (indentedFlag) {
|
|
1239
|
+
decreaseIndent();
|
|
1240
|
+
}
|
|
1241
|
+
}
|
|
1242
|
+
else {
|
|
1243
|
+
emitSignatureHead(node);
|
|
1244
|
+
writeSpace();
|
|
1245
|
+
emitExpression(body);
|
|
1246
|
+
}
|
|
1247
|
+
}
|
|
1248
|
+
else {
|
|
1249
|
+
emitSignatureHead(node);
|
|
1250
|
+
writeTrailingSemicolon();
|
|
1251
|
+
}
|
|
1252
|
+
}
|
|
1253
|
+
function shouldEmitBlockFunctionBodyOnSingleLine(body) {
|
|
1254
|
+
// We must emit a function body as a single-line body in the following case:
|
|
1255
|
+
// * The body has NodeEmitFlags.SingleLine specified.
|
|
1256
|
+
// We must emit a function body as a multi-line body in the following cases:
|
|
1257
|
+
// * The body is explicitly marked as multi-line.
|
|
1258
|
+
// * A non-synthesized body's start and end position are on different lines.
|
|
1259
|
+
// * Any statement in the body starts on a new line.
|
|
1260
|
+
if (getEmitFlags(body) & EmitFlags.SingleLine) {
|
|
1261
|
+
return true;
|
|
1262
|
+
}
|
|
1263
|
+
if (body.multiLine) {
|
|
1264
|
+
return false;
|
|
1265
|
+
}
|
|
1266
|
+
if (!nodeIsSynthesized(body) && !rangeIsOnSingleLine(body, currentSourceFile)) {
|
|
1267
|
+
return false;
|
|
1268
|
+
}
|
|
1269
|
+
if (getLeadingLineTerminatorCount(body, body.statements, 2 /* ListFormat.PreserveLines */)
|
|
1270
|
+
|| getClosingLineTerminatorCount(body, body.statements, 2 /* ListFormat.PreserveLines */)) {
|
|
1271
|
+
return false;
|
|
1272
|
+
}
|
|
1273
|
+
let previousStatement;
|
|
1274
|
+
for (const statement of body.statements) {
|
|
1275
|
+
if (getSeparatingLineTerminatorCount(previousStatement, statement, 2 /* ListFormat.PreserveLines */) > 0) {
|
|
1276
|
+
return false;
|
|
1277
|
+
}
|
|
1278
|
+
previousStatement = statement;
|
|
1279
|
+
}
|
|
1280
|
+
return true;
|
|
1281
|
+
}
|
|
1282
|
+
function emitBlockFunctionBody(body) {
|
|
1283
|
+
writeSpace();
|
|
1284
|
+
writePunctuation("{");
|
|
1285
|
+
increaseIndent();
|
|
1286
|
+
const emitBlockFunctionBody = shouldEmitBlockFunctionBodyOnSingleLine(body)
|
|
1287
|
+
? emitBlockFunctionBodyOnSingleLine
|
|
1288
|
+
: emitBlockFunctionBodyWorker;
|
|
1289
|
+
if (emitBodyWithDetachedComments) {
|
|
1290
|
+
emitBodyWithDetachedComments(body, body.statements, emitBlockFunctionBody);
|
|
1291
|
+
}
|
|
1292
|
+
else {
|
|
1293
|
+
emitBlockFunctionBody(body);
|
|
1294
|
+
}
|
|
1295
|
+
decreaseIndent();
|
|
1296
|
+
writeToken(SyntaxKind.CloseBraceToken, body.statements.end, writePunctuation);
|
|
1297
|
+
}
|
|
1298
|
+
function emitBlockFunctionBodyOnSingleLine(body) {
|
|
1299
|
+
emitBlockFunctionBodyWorker(body, /*emitBlockFunctionBodyOnSingleLine*/ true);
|
|
1300
|
+
}
|
|
1301
|
+
function emitBlockFunctionBodyWorker(body, emitBlockFunctionBodyOnSingleLine) {
|
|
1302
|
+
// Emit all the prologue directives (like "use strict").
|
|
1303
|
+
const statementOffset = emitPrologueDirectives(body.statements);
|
|
1304
|
+
const pos = writer.getTextPos();
|
|
1305
|
+
if (statementOffset === 0 && pos === writer.getTextPos() && emitBlockFunctionBodyOnSingleLine) {
|
|
1306
|
+
decreaseIndent();
|
|
1307
|
+
emitList(body, body.statements, 768 /* ListFormat.SingleLineFunctionBodyStatements */);
|
|
1308
|
+
increaseIndent();
|
|
1309
|
+
}
|
|
1310
|
+
else {
|
|
1311
|
+
emitList(body, body.statements, 1 /* ListFormat.MultiLineFunctionBodyStatements */, statementOffset);
|
|
1312
|
+
}
|
|
1313
|
+
}
|
|
1314
|
+
function emitTypeAliasDeclaration(node) {
|
|
1315
|
+
emitModifiers(node, node.modifiers);
|
|
1316
|
+
writeKeyword("type");
|
|
1317
|
+
writeSpace();
|
|
1318
|
+
emit(node.name);
|
|
1319
|
+
emitTypeParameters(node, node.typeParameters);
|
|
1320
|
+
writeSpace();
|
|
1321
|
+
writePunctuation("=");
|
|
1322
|
+
writeSpace();
|
|
1323
|
+
emit(node.type);
|
|
1324
|
+
writeTrailingSemicolon();
|
|
1325
|
+
}
|
|
1326
|
+
function emitModuleDeclaration(node) {
|
|
1327
|
+
emitModifiers(node, node.modifiers);
|
|
1328
|
+
if (~node.flags & NodeFlags.GlobalAugmentation) {
|
|
1329
|
+
writeKeyword(node.flags & NodeFlags.Namespace ? "namespace" : "module");
|
|
1330
|
+
writeSpace();
|
|
1331
|
+
}
|
|
1332
|
+
emit(node.name);
|
|
1333
|
+
let body = node.body;
|
|
1334
|
+
if (!body)
|
|
1335
|
+
return writeTrailingSemicolon();
|
|
1336
|
+
while (body.kind === SyntaxKind.ModuleDeclaration) {
|
|
1337
|
+
writePunctuation(".");
|
|
1338
|
+
emit(body.name);
|
|
1339
|
+
body = body.body;
|
|
1340
|
+
}
|
|
1341
|
+
writeSpace();
|
|
1342
|
+
emit(body);
|
|
1343
|
+
}
|
|
1344
|
+
function emitModuleBlock(node) {
|
|
1345
|
+
pushNameGenerationScope(node);
|
|
1346
|
+
forEach(node.statements, generateNames);
|
|
1347
|
+
emitBlockStatements(node, /*forceSingleLine*/ isEmptyBlock(node));
|
|
1348
|
+
popNameGenerationScope(node);
|
|
1349
|
+
}
|
|
1350
|
+
function emitCaseBlock(node) {
|
|
1351
|
+
emitTokenWithComment(SyntaxKind.OpenBraceToken, node.pos, writePunctuation, node);
|
|
1352
|
+
emitList(node, node.clauses, 129 /* ListFormat.CaseBlockClauses */);
|
|
1353
|
+
emitTokenWithComment(SyntaxKind.CloseBraceToken, node.clauses.end, writePunctuation, node, /*indentLeading*/ true);
|
|
1354
|
+
}
|
|
1355
|
+
function emitImportDeclaration(node) {
|
|
1356
|
+
emitModifiers(node, node.modifiers);
|
|
1357
|
+
emitTokenWithComment(SyntaxKind.ImportKeyword, node.modifiers ? node.modifiers.end : node.pos, writeKeyword, node);
|
|
1358
|
+
writeSpace();
|
|
1359
|
+
if (node.importClause) {
|
|
1360
|
+
emit(node.importClause);
|
|
1361
|
+
writeSpace();
|
|
1362
|
+
emitTokenWithComment(SyntaxKind.FromKeyword, node.importClause.end, writeKeyword, node);
|
|
1363
|
+
writeSpace();
|
|
1364
|
+
}
|
|
1365
|
+
emitExpression(node.moduleSpecifier);
|
|
1366
|
+
writeTrailingSemicolon();
|
|
1367
|
+
}
|
|
1368
|
+
function emitImportClause(node) {
|
|
1369
|
+
if (node.isTypeOnly) {
|
|
1370
|
+
emitTokenWithComment(SyntaxKind.TypeKeyword, node.pos, writeKeyword, node);
|
|
1371
|
+
writeSpace();
|
|
1372
|
+
}
|
|
1373
|
+
emit(node.name);
|
|
1374
|
+
if (node.name && node.namedBindings) {
|
|
1375
|
+
emitTokenWithComment(SyntaxKind.CommaToken, node.name.end, writePunctuation, node);
|
|
1376
|
+
writeSpace();
|
|
1377
|
+
}
|
|
1378
|
+
emit(node.namedBindings);
|
|
1379
|
+
}
|
|
1380
|
+
function emitNamespaceImport(node) {
|
|
1381
|
+
const asPos = emitTokenWithComment(SyntaxKind.AsteriskToken, node.pos, writePunctuation, node);
|
|
1382
|
+
writeSpace();
|
|
1383
|
+
emitTokenWithComment(SyntaxKind.AsKeyword, asPos, writeKeyword, node);
|
|
1384
|
+
writeSpace();
|
|
1385
|
+
emit(node.name);
|
|
1386
|
+
}
|
|
1387
|
+
function emitNamedImports(node) {
|
|
1388
|
+
emitNamedImportsOrExports(node);
|
|
1389
|
+
}
|
|
1390
|
+
function emitImportSpecifier(node) {
|
|
1391
|
+
emitImportOrExportSpecifier(node);
|
|
1392
|
+
}
|
|
1393
|
+
function emitExportAssignment(node) {
|
|
1394
|
+
const nextPos = emitTokenWithComment(SyntaxKind.ExportKeyword, node.pos, writeKeyword, node);
|
|
1395
|
+
writeSpace();
|
|
1396
|
+
emitTokenWithComment(SyntaxKind.DefaultKeyword, nextPos, writeKeyword, node);
|
|
1397
|
+
writeSpace();
|
|
1398
|
+
emitExpression(node.expression);
|
|
1399
|
+
writeTrailingSemicolon();
|
|
1400
|
+
}
|
|
1401
|
+
function emitExportDeclaration(node) {
|
|
1402
|
+
let nextPos = emitTokenWithComment(SyntaxKind.ExportKeyword, node.pos, writeKeyword, node);
|
|
1403
|
+
writeSpace();
|
|
1404
|
+
if (node.isTypeOnly) {
|
|
1405
|
+
nextPos = emitTokenWithComment(SyntaxKind.TypeKeyword, nextPos, writeKeyword, node);
|
|
1406
|
+
writeSpace();
|
|
1407
|
+
}
|
|
1408
|
+
if (node.exportClause) {
|
|
1409
|
+
emit(node.exportClause);
|
|
1410
|
+
}
|
|
1411
|
+
else {
|
|
1412
|
+
nextPos = emitTokenWithComment(SyntaxKind.AsteriskToken, nextPos, writePunctuation, node);
|
|
1413
|
+
}
|
|
1414
|
+
if (node.moduleSpecifier) {
|
|
1415
|
+
writeSpace();
|
|
1416
|
+
const fromPos = node.exportClause ? node.exportClause.end : nextPos;
|
|
1417
|
+
emitTokenWithComment(SyntaxKind.FromKeyword, fromPos, writeKeyword, node);
|
|
1418
|
+
writeSpace();
|
|
1419
|
+
emitExpression(node.moduleSpecifier);
|
|
1420
|
+
}
|
|
1421
|
+
writeTrailingSemicolon();
|
|
1422
|
+
}
|
|
1423
|
+
function emitNamespaceExport(node) {
|
|
1424
|
+
const asPos = emitTokenWithComment(SyntaxKind.AsteriskToken, node.pos, writePunctuation, node);
|
|
1425
|
+
writeSpace();
|
|
1426
|
+
emitTokenWithComment(SyntaxKind.AsKeyword, asPos, writeKeyword, node);
|
|
1427
|
+
writeSpace();
|
|
1428
|
+
emit(node.name);
|
|
1429
|
+
}
|
|
1430
|
+
function emitNamedExports(node) {
|
|
1431
|
+
emitNamedImportsOrExports(node);
|
|
1432
|
+
}
|
|
1433
|
+
function emitExportSpecifier(node) {
|
|
1434
|
+
emitImportOrExportSpecifier(node);
|
|
1435
|
+
}
|
|
1436
|
+
function emitNamedImportsOrExports(node) {
|
|
1437
|
+
writePunctuation("{");
|
|
1438
|
+
emitList(node, node.elements, 525136 /* ListFormat.NamedImportsOrExportsElements */);
|
|
1439
|
+
writePunctuation("}");
|
|
1440
|
+
}
|
|
1441
|
+
function emitImportOrExportSpecifier(node) {
|
|
1442
|
+
if (node.propertyName) {
|
|
1443
|
+
emit(node.propertyName);
|
|
1444
|
+
writeSpace();
|
|
1445
|
+
emitTokenWithComment(SyntaxKind.AsKeyword, node.propertyName.end, writeKeyword, node);
|
|
1446
|
+
writeSpace();
|
|
1447
|
+
}
|
|
1448
|
+
emit(node.name);
|
|
1449
|
+
}
|
|
1450
|
+
//
|
|
1451
|
+
// JSX
|
|
1452
|
+
//
|
|
1453
|
+
function emitJsxElement(node) {
|
|
1454
|
+
emit(node.openingElement);
|
|
1455
|
+
emitList(node, node.children, 262144 /* ListFormat.JsxElementOrFragmentChildren */);
|
|
1456
|
+
emit(node.closingElement);
|
|
1457
|
+
}
|
|
1458
|
+
function emitJsxSelfClosingElement(node) {
|
|
1459
|
+
writePunctuation("<");
|
|
1460
|
+
emitJsxTagName(node.tagName);
|
|
1461
|
+
emitTypeArguments(node, node.typeArguments);
|
|
1462
|
+
writeSpace();
|
|
1463
|
+
emit(node.attributes);
|
|
1464
|
+
writePunctuation("/>");
|
|
1465
|
+
}
|
|
1466
|
+
function emitJsxFragment(node) {
|
|
1467
|
+
emit(node.openingFragment);
|
|
1468
|
+
emitList(node, node.children, 262144 /* ListFormat.JsxElementOrFragmentChildren */);
|
|
1469
|
+
emit(node.closingFragment);
|
|
1470
|
+
}
|
|
1471
|
+
function emitJsxOpeningElementOrFragment(node) {
|
|
1472
|
+
writePunctuation("<");
|
|
1473
|
+
if (isJsxOpeningElement(node)) {
|
|
1474
|
+
const indented = writeLineSeparatorsAndIndentBefore(node.tagName, node);
|
|
1475
|
+
emitJsxTagName(node.tagName);
|
|
1476
|
+
emitTypeArguments(node, node.typeArguments);
|
|
1477
|
+
if (node.attributes.properties && node.attributes.properties.length > 0) {
|
|
1478
|
+
writeSpace();
|
|
1479
|
+
}
|
|
1480
|
+
emit(node.attributes);
|
|
1481
|
+
writeLineSeparatorsAfter(node.attributes, node);
|
|
1482
|
+
decreaseIndentIf(indented);
|
|
1483
|
+
}
|
|
1484
|
+
writePunctuation(">");
|
|
1485
|
+
}
|
|
1486
|
+
function emitJsxText(node) {
|
|
1487
|
+
writer.writeLiteral(node.text);
|
|
1488
|
+
}
|
|
1489
|
+
function emitJsxClosingElementOrFragment(node) {
|
|
1490
|
+
writePunctuation("</");
|
|
1491
|
+
if (isJsxClosingElement(node)) {
|
|
1492
|
+
emitJsxTagName(node.tagName);
|
|
1493
|
+
}
|
|
1494
|
+
writePunctuation(">");
|
|
1495
|
+
}
|
|
1496
|
+
function emitJsxAttributes(node) {
|
|
1497
|
+
emitList(node, node.properties, 262656 /* ListFormat.JsxElementAttributes */);
|
|
1498
|
+
}
|
|
1499
|
+
function emitJsxAttribute(node) {
|
|
1500
|
+
emit(node.name);
|
|
1501
|
+
emitNodeWithPrefix("=", writePunctuation, node.initializer, emitJsxAttributeValue);
|
|
1502
|
+
}
|
|
1503
|
+
function emitJsxSpreadAttribute(node) {
|
|
1504
|
+
writePunctuation("{...");
|
|
1505
|
+
emitExpression(node.expression);
|
|
1506
|
+
writePunctuation("}");
|
|
1507
|
+
}
|
|
1508
|
+
function emitJsxExpression(node) {
|
|
1509
|
+
if (node.expression) {
|
|
1510
|
+
writePunctuation("{");
|
|
1511
|
+
emit(node.dotDotDotToken);
|
|
1512
|
+
emitExpression(node.expression);
|
|
1513
|
+
writePunctuation("}");
|
|
1514
|
+
}
|
|
1515
|
+
}
|
|
1516
|
+
function emitJsxTagName(node) {
|
|
1517
|
+
if (node.kind === SyntaxKind.Identifier) {
|
|
1518
|
+
emitExpression(node);
|
|
1519
|
+
}
|
|
1520
|
+
else {
|
|
1521
|
+
emit(node);
|
|
1522
|
+
}
|
|
1523
|
+
}
|
|
1524
|
+
//
|
|
1525
|
+
// Clauses
|
|
1526
|
+
//
|
|
1527
|
+
function emitCaseClause(node) {
|
|
1528
|
+
emitTokenWithComment(SyntaxKind.CaseKeyword, node.pos, writeKeyword, node);
|
|
1529
|
+
writeSpace();
|
|
1530
|
+
emitExpression(node.expression);
|
|
1531
|
+
emitCaseOrDefaultClauseRest(node, node.statements, node.expression.end);
|
|
1532
|
+
}
|
|
1533
|
+
function emitDefaultClause(node) {
|
|
1534
|
+
const pos = emitTokenWithComment(SyntaxKind.DefaultKeyword, node.pos, writeKeyword, node);
|
|
1535
|
+
emitCaseOrDefaultClauseRest(node, node.statements, pos);
|
|
1536
|
+
}
|
|
1537
|
+
function emitCaseOrDefaultClauseRest(parentNode, statements, colonPos) {
|
|
1538
|
+
const emitAsSingleStatement = statements.length === 1 &&
|
|
1539
|
+
(
|
|
1540
|
+
// treat synthesized nodes as located on the same line for emit purposes
|
|
1541
|
+
nodeIsSynthesized(parentNode) ||
|
|
1542
|
+
nodeIsSynthesized(statements[0]) ||
|
|
1543
|
+
rangeStartPositionsAreOnSameLine(parentNode, statements[0], currentSourceFile));
|
|
1544
|
+
let format = 163969 /* ListFormat.CaseOrDefaultClauseStatements */;
|
|
1545
|
+
if (emitAsSingleStatement) {
|
|
1546
|
+
writeToken(SyntaxKind.ColonToken, colonPos, writePunctuation);
|
|
1547
|
+
writeSpace();
|
|
1548
|
+
format &= ~(1 /* ListFormat.MultiLine */ | 128 /* ListFormat.Indented */);
|
|
1549
|
+
}
|
|
1550
|
+
else {
|
|
1551
|
+
emitTokenWithComment(SyntaxKind.ColonToken, colonPos, writePunctuation, parentNode);
|
|
1552
|
+
}
|
|
1553
|
+
emitList(parentNode, statements, format);
|
|
1554
|
+
}
|
|
1555
|
+
function emitCatchClause(node) {
|
|
1556
|
+
const openParenPos = emitTokenWithComment(SyntaxKind.CatchKeyword, node.pos, writeKeyword, node);
|
|
1557
|
+
writeSpace();
|
|
1558
|
+
if (node.variableDeclaration) {
|
|
1559
|
+
emitTokenWithComment(SyntaxKind.OpenParenToken, openParenPos, writePunctuation, node);
|
|
1560
|
+
emit(node.variableDeclaration);
|
|
1561
|
+
emitTokenWithComment(SyntaxKind.CloseParenToken, node.variableDeclaration.end, writePunctuation, node);
|
|
1562
|
+
writeSpace();
|
|
1563
|
+
}
|
|
1564
|
+
emit(node.block);
|
|
1565
|
+
}
|
|
1566
|
+
//
|
|
1567
|
+
// Property assignments
|
|
1568
|
+
//
|
|
1569
|
+
function emitPropertyAssignment(node) {
|
|
1570
|
+
emit(node.name);
|
|
1571
|
+
writePunctuation(":");
|
|
1572
|
+
writeSpace();
|
|
1573
|
+
// This is to ensure that we emit comment in the following case:
|
|
1574
|
+
// For example:
|
|
1575
|
+
// obj = {
|
|
1576
|
+
// id: /*comment1*/ ()=>void
|
|
1577
|
+
// }
|
|
1578
|
+
// "comment1" is not considered to be leading comment for node.initializer
|
|
1579
|
+
// but rather a trailing comment on the previous node.
|
|
1580
|
+
const initializer = node.initializer;
|
|
1581
|
+
if (emitTrailingCommentsOfPosition && (getEmitFlags(initializer) & EmitFlags.NoLeadingComments) === 0) {
|
|
1582
|
+
const commentRange = getCommentRange(initializer);
|
|
1583
|
+
emitTrailingCommentsOfPosition(commentRange.pos);
|
|
1584
|
+
}
|
|
1585
|
+
emitExpression(initializer);
|
|
1586
|
+
}
|
|
1587
|
+
function emitShorthandPropertyAssignment(node) {
|
|
1588
|
+
emit(node.name);
|
|
1589
|
+
if (node.objectAssignmentInitializer) {
|
|
1590
|
+
writeSpace();
|
|
1591
|
+
writePunctuation("=");
|
|
1592
|
+
writeSpace();
|
|
1593
|
+
emitExpression(node.objectAssignmentInitializer);
|
|
1594
|
+
}
|
|
1595
|
+
}
|
|
1596
|
+
function emitSpreadAssignment(node) {
|
|
1597
|
+
if (node.expression) {
|
|
1598
|
+
emitTokenWithComment(SyntaxKind.DotDotDotToken, node.pos, writePunctuation, node);
|
|
1599
|
+
emitExpression(node.expression);
|
|
1600
|
+
}
|
|
1601
|
+
}
|
|
1602
|
+
//
|
|
1603
|
+
// Top-level nodes
|
|
1604
|
+
//
|
|
1605
|
+
function emitSourceFile(node) {
|
|
1606
|
+
writeLine();
|
|
1607
|
+
const statements = node.statements;
|
|
1608
|
+
if (emitBodyWithDetachedComments) {
|
|
1609
|
+
// Emit detached comment if there are no prologue directives or if the first node is synthesized.
|
|
1610
|
+
// The synthesized node will have no leading comment so some comments may be missed.
|
|
1611
|
+
const shouldEmitDetachedComment = statements.length === 0 ||
|
|
1612
|
+
!isPrologueDirective(statements[0]) ||
|
|
1613
|
+
nodeIsSynthesized(statements[0]);
|
|
1614
|
+
if (shouldEmitDetachedComment) {
|
|
1615
|
+
emitBodyWithDetachedComments(node, statements, emitSourceFileWorker);
|
|
1616
|
+
return;
|
|
1617
|
+
}
|
|
1618
|
+
}
|
|
1619
|
+
emitSourceFileWorker(node);
|
|
1620
|
+
}
|
|
1621
|
+
function emitSourceFileWorker(node) {
|
|
1622
|
+
const statements = node.statements;
|
|
1623
|
+
pushNameGenerationScope(node);
|
|
1624
|
+
forEach(node.statements, generateNames);
|
|
1625
|
+
const index = findIndex(statements, statement => !isPrologueDirective(statement));
|
|
1626
|
+
emitList(node, statements, 1 /* ListFormat.MultiLine */, index === -1 ? statements.length : index);
|
|
1627
|
+
popNameGenerationScope(node);
|
|
1628
|
+
}
|
|
1629
|
+
/**
|
|
1630
|
+
* Emits any prologue directives at the start of a Statement list, returning the
|
|
1631
|
+
* number of prologue directives written to the output.
|
|
1632
|
+
*/
|
|
1633
|
+
function emitPrologueDirectives(statements, sourceFile) {
|
|
1634
|
+
let needsToSetSourceFile = !!sourceFile;
|
|
1635
|
+
for (let i = 0; i < statements.length; i++) {
|
|
1636
|
+
const statement = statements[i];
|
|
1637
|
+
if (isPrologueDirective(statement)) {
|
|
1638
|
+
if (needsToSetSourceFile) {
|
|
1639
|
+
needsToSetSourceFile = false;
|
|
1640
|
+
setSourceFile(sourceFile);
|
|
1641
|
+
}
|
|
1642
|
+
writeLine();
|
|
1643
|
+
emit(statement);
|
|
1644
|
+
}
|
|
1645
|
+
else {
|
|
1646
|
+
// return index of the first non prologue directive
|
|
1647
|
+
return i;
|
|
1648
|
+
}
|
|
1649
|
+
}
|
|
1650
|
+
return statements.length;
|
|
1651
|
+
}
|
|
1652
|
+
function emitPrologueDirectivesIfNeeded(sourceFile) {
|
|
1653
|
+
emitPrologueDirectives(sourceFile.statements, sourceFile);
|
|
1654
|
+
}
|
|
1655
|
+
function emitShebangIfNeeded(sourceFile) {
|
|
1656
|
+
const shebang = getShebang(sourceFile.text);
|
|
1657
|
+
if (shebang) {
|
|
1658
|
+
writeComment(shebang);
|
|
1659
|
+
writeLine();
|
|
1660
|
+
return true;
|
|
1661
|
+
}
|
|
1662
|
+
}
|
|
1663
|
+
//
|
|
1664
|
+
// Helpers
|
|
1665
|
+
//
|
|
1666
|
+
function emitNodeWithWriter(node, writer) {
|
|
1667
|
+
if (!node)
|
|
1668
|
+
return;
|
|
1669
|
+
const savedWrite = write;
|
|
1670
|
+
write = writer;
|
|
1671
|
+
emit(node);
|
|
1672
|
+
write = savedWrite;
|
|
1673
|
+
}
|
|
1674
|
+
function emitModifiers(node, modifiers) {
|
|
1675
|
+
if (modifiers && modifiers.length) {
|
|
1676
|
+
emitList(node, modifiers, 262656 /* ListFormat.Modifiers */);
|
|
1677
|
+
writeSpace();
|
|
1678
|
+
}
|
|
1679
|
+
}
|
|
1680
|
+
function emitTypeAnnotation(node) {
|
|
1681
|
+
if (node) {
|
|
1682
|
+
writePunctuation(":");
|
|
1683
|
+
writeSpace();
|
|
1684
|
+
emit(node);
|
|
1685
|
+
}
|
|
1686
|
+
}
|
|
1687
|
+
function emitInitializer(node, equalCommentStartPos, container) {
|
|
1688
|
+
if (node) {
|
|
1689
|
+
writeSpace();
|
|
1690
|
+
emitTokenWithComment(SyntaxKind.EqualsToken, equalCommentStartPos, writeOperator, container);
|
|
1691
|
+
writeSpace();
|
|
1692
|
+
emitExpression(node);
|
|
1693
|
+
}
|
|
1694
|
+
}
|
|
1695
|
+
function emitNodeWithPrefix(prefix, prefixWriter, node, emit) {
|
|
1696
|
+
if (node) {
|
|
1697
|
+
prefixWriter(prefix);
|
|
1698
|
+
emit(node);
|
|
1699
|
+
}
|
|
1700
|
+
}
|
|
1701
|
+
function emitExpressionWithLeadingSpace(node) {
|
|
1702
|
+
if (node) {
|
|
1703
|
+
writeSpace();
|
|
1704
|
+
emitExpression(node);
|
|
1705
|
+
}
|
|
1706
|
+
}
|
|
1707
|
+
function emitWithTrailingSpace(node) {
|
|
1708
|
+
if (node) {
|
|
1709
|
+
emit(node);
|
|
1710
|
+
writeSpace();
|
|
1711
|
+
}
|
|
1712
|
+
}
|
|
1713
|
+
function emitEmbeddedStatement(parent, node) {
|
|
1714
|
+
if (isBlock(node) || getEmitFlags(parent) & EmitFlags.SingleLine) {
|
|
1715
|
+
writeSpace();
|
|
1716
|
+
emit(node);
|
|
1717
|
+
}
|
|
1718
|
+
else {
|
|
1719
|
+
writeLine();
|
|
1720
|
+
increaseIndent();
|
|
1721
|
+
if (isEmptyStatement(node)) {
|
|
1722
|
+
pipelineEmit(EmitHint.EmbeddedStatement, node);
|
|
1723
|
+
}
|
|
1724
|
+
else {
|
|
1725
|
+
emit(node);
|
|
1726
|
+
}
|
|
1727
|
+
decreaseIndent();
|
|
1728
|
+
}
|
|
1729
|
+
}
|
|
1730
|
+
function emitTypeArguments(parentNode, typeArguments) {
|
|
1731
|
+
emitList(parentNode, typeArguments, 53776 /* ListFormat.TypeArguments */);
|
|
1732
|
+
}
|
|
1733
|
+
function emitTypeParameters(parentNode, typeParameters) {
|
|
1734
|
+
if (isFunctionLike(parentNode) && parentNode.typeArguments) { // Quick info uses type arguments in place of type parameters on instantiated signatures
|
|
1735
|
+
return emitTypeArguments(parentNode, parentNode.typeArguments);
|
|
1736
|
+
}
|
|
1737
|
+
emitList(parentNode, typeParameters, 53776 /* ListFormat.TypeParameters */);
|
|
1738
|
+
}
|
|
1739
|
+
function emitParameters(parentNode, parameters) {
|
|
1740
|
+
emitList(parentNode, parameters, 2576 /* ListFormat.Parameters */);
|
|
1741
|
+
}
|
|
1742
|
+
function canEmitSimpleArrowHead(parentNode, parameters) {
|
|
1743
|
+
const parameter = singleOrUndefined(parameters);
|
|
1744
|
+
return parameter
|
|
1745
|
+
&& parameter.pos === parentNode.pos // may not have parsed tokens between parent and parameter
|
|
1746
|
+
&& isArrowFunction(parentNode) // only arrow functions may have simple arrow head
|
|
1747
|
+
&& !parentNode.type // arrow function may not have return type annotation
|
|
1748
|
+
&& !some(parentNode.modifiers) // parent may not have modifiers
|
|
1749
|
+
&& !some(parentNode.typeParameters) // parent may not have type parameters
|
|
1750
|
+
&& !some(parameter.modifiers) // parameter may not have modifiers
|
|
1751
|
+
&& !parameter.dotDotDotToken // parameter may not be rest
|
|
1752
|
+
&& !parameter.questionToken // parameter may not be optional
|
|
1753
|
+
&& !parameter.type // parameter may not have a type annotation
|
|
1754
|
+
&& !parameter.initializer // parameter may not have an initializer
|
|
1755
|
+
&& isIdentifier(parameter.name); // parameter name must be identifier
|
|
1756
|
+
}
|
|
1757
|
+
function emitParametersForArrow(parentNode, parameters) {
|
|
1758
|
+
if (canEmitSimpleArrowHead(parentNode, parameters)) {
|
|
1759
|
+
emitList(parentNode, parameters, 2576 /* ListFormat.Parameters */ & ~2048 /* ListFormat.Parenthesis */);
|
|
1760
|
+
}
|
|
1761
|
+
else {
|
|
1762
|
+
emitParameters(parentNode, parameters);
|
|
1763
|
+
}
|
|
1764
|
+
}
|
|
1765
|
+
function emitParametersForIndexSignature(parentNode, parameters) {
|
|
1766
|
+
emitList(parentNode, parameters, 8848 /* ListFormat.IndexSignatureParameters */);
|
|
1767
|
+
}
|
|
1768
|
+
function emitList(parentNode, children, format, start, count) {
|
|
1769
|
+
emitNodeList(emit, parentNode, children, format, start, count);
|
|
1770
|
+
}
|
|
1771
|
+
function emitExpressionList(parentNode, children, format, start, count) {
|
|
1772
|
+
emitNodeList(emitExpression, parentNode, children, format, start, count);
|
|
1773
|
+
}
|
|
1774
|
+
function writeDelimiter(format) {
|
|
1775
|
+
switch (format & 28 /* ListFormat.DelimitersMask */) {
|
|
1776
|
+
case 0 /* ListFormat.None */:
|
|
1777
|
+
break;
|
|
1778
|
+
case 16 /* ListFormat.CommaDelimited */:
|
|
1779
|
+
writePunctuation(",");
|
|
1780
|
+
break;
|
|
1781
|
+
case 4 /* ListFormat.BarDelimited */:
|
|
1782
|
+
writeSpace();
|
|
1783
|
+
writePunctuation("|");
|
|
1784
|
+
break;
|
|
1785
|
+
case 8 /* ListFormat.AmpersandDelimited */:
|
|
1786
|
+
writeSpace();
|
|
1787
|
+
writePunctuation("&");
|
|
1788
|
+
break;
|
|
1789
|
+
}
|
|
1790
|
+
}
|
|
1791
|
+
function emitNodeList(emit, parentNode, children, format, start = 0, count = children ? children.length - start : 0) {
|
|
1792
|
+
const isUndefined = children === undefined;
|
|
1793
|
+
if (isUndefined && format & 16384 /* ListFormat.OptionalIfUndefined */) {
|
|
1794
|
+
return;
|
|
1795
|
+
}
|
|
1796
|
+
const isEmpty = children === undefined || start >= children.length || count === 0;
|
|
1797
|
+
if (isEmpty && format & 32768 /* ListFormat.OptionalIfEmpty */) {
|
|
1798
|
+
if (onBeforeEmitNodeArray) {
|
|
1799
|
+
onBeforeEmitNodeArray(children);
|
|
1800
|
+
}
|
|
1801
|
+
if (onAfterEmitNodeArray) {
|
|
1802
|
+
onAfterEmitNodeArray(children);
|
|
1803
|
+
}
|
|
1804
|
+
return;
|
|
1805
|
+
}
|
|
1806
|
+
if (format & 15360 /* ListFormat.BracketsMask */) {
|
|
1807
|
+
writePunctuation(getOpeningBracket(format));
|
|
1808
|
+
if (isEmpty && !isUndefined) {
|
|
1809
|
+
emitTrailingCommentsOfPosition(children.pos, /*prefixSpace*/ true); // Emit comments within empty bracketed lists
|
|
1810
|
+
}
|
|
1811
|
+
}
|
|
1812
|
+
if (onBeforeEmitNodeArray) {
|
|
1813
|
+
onBeforeEmitNodeArray(children);
|
|
1814
|
+
}
|
|
1815
|
+
if (isEmpty) {
|
|
1816
|
+
// Write a line terminator if the parent node was multi-line
|
|
1817
|
+
if (format & 1 /* ListFormat.MultiLine */ && !(preserveSourceNewlines && rangeIsOnSingleLine(parentNode, currentSourceFile))) {
|
|
1818
|
+
writeLine();
|
|
1819
|
+
}
|
|
1820
|
+
else if (format & 256 /* ListFormat.SpaceBetweenBraces */ && !(format & 524288 /* ListFormat.NoSpaceIfEmpty */)) {
|
|
1821
|
+
writeSpace();
|
|
1822
|
+
}
|
|
1823
|
+
}
|
|
1824
|
+
else {
|
|
1825
|
+
// Write the opening line terminator or leading whitespace.
|
|
1826
|
+
const mayEmitInterveningComments = (format & 262144 /* ListFormat.NoInterveningComments */) === 0;
|
|
1827
|
+
let shouldEmitInterveningComments = mayEmitInterveningComments;
|
|
1828
|
+
const leadingLineTerminatorCount = getLeadingLineTerminatorCount(parentNode, children, format);
|
|
1829
|
+
if (leadingLineTerminatorCount) {
|
|
1830
|
+
writeLine(leadingLineTerminatorCount);
|
|
1831
|
+
shouldEmitInterveningComments = false;
|
|
1832
|
+
}
|
|
1833
|
+
else if (format & 256 /* ListFormat.SpaceBetweenBraces */) {
|
|
1834
|
+
writeSpace();
|
|
1835
|
+
}
|
|
1836
|
+
// Increase the indent, if requested.
|
|
1837
|
+
if (format & 128 /* ListFormat.Indented */) {
|
|
1838
|
+
increaseIndent();
|
|
1839
|
+
}
|
|
1840
|
+
// Emit each child.
|
|
1841
|
+
let previousSibling;
|
|
1842
|
+
let shouldDecreaseIndentAfterEmit = false;
|
|
1843
|
+
for (let i = 0; i < count; i++) {
|
|
1844
|
+
const child = children[start + i];
|
|
1845
|
+
// Write the delimiter if this is not the first node.
|
|
1846
|
+
if (previousSibling) {
|
|
1847
|
+
// i.e
|
|
1848
|
+
// function commentedParameters(
|
|
1849
|
+
// /* Parameter a */
|
|
1850
|
+
// a
|
|
1851
|
+
// /* End of parameter a */ -> this comment isn't considered to be trailing comment of parameter "a" due to newline
|
|
1852
|
+
// ,
|
|
1853
|
+
if (format & 28 /* ListFormat.DelimitersMask */ && previousSibling.end !== parentNode.end) {
|
|
1854
|
+
emitLeadingCommentsOfPosition(previousSibling.end);
|
|
1855
|
+
}
|
|
1856
|
+
writeDelimiter(format);
|
|
1857
|
+
// Write either a line terminator or whitespace to separate the elements.
|
|
1858
|
+
const separatingLineTerminatorCount = getSeparatingLineTerminatorCount(previousSibling, child, format);
|
|
1859
|
+
if (separatingLineTerminatorCount > 0) {
|
|
1860
|
+
// If a synthesized node in a single-line list starts on a new
|
|
1861
|
+
// line, we should increase the indent.
|
|
1862
|
+
if ((format & (3 /* ListFormat.LinesMask */ | 128 /* ListFormat.Indented */)) === 0 /* ListFormat.SingleLine */) {
|
|
1863
|
+
increaseIndent();
|
|
1864
|
+
shouldDecreaseIndentAfterEmit = true;
|
|
1865
|
+
}
|
|
1866
|
+
writeLine(separatingLineTerminatorCount);
|
|
1867
|
+
shouldEmitInterveningComments = false;
|
|
1868
|
+
}
|
|
1869
|
+
else if (previousSibling && format & 512 /* ListFormat.SpaceBetweenSiblings */) {
|
|
1870
|
+
writeSpace();
|
|
1871
|
+
}
|
|
1872
|
+
}
|
|
1873
|
+
// Emit this child.
|
|
1874
|
+
if (shouldEmitInterveningComments) {
|
|
1875
|
+
if (emitTrailingCommentsOfPosition) {
|
|
1876
|
+
const commentRange = getCommentRange(child);
|
|
1877
|
+
emitTrailingCommentsOfPosition(commentRange.pos);
|
|
1878
|
+
}
|
|
1879
|
+
}
|
|
1880
|
+
else {
|
|
1881
|
+
shouldEmitInterveningComments = mayEmitInterveningComments;
|
|
1882
|
+
}
|
|
1883
|
+
emit(child);
|
|
1884
|
+
if (shouldDecreaseIndentAfterEmit) {
|
|
1885
|
+
decreaseIndent();
|
|
1886
|
+
shouldDecreaseIndentAfterEmit = false;
|
|
1887
|
+
}
|
|
1888
|
+
previousSibling = child;
|
|
1889
|
+
}
|
|
1890
|
+
// Write a trailing comma, if requested.
|
|
1891
|
+
const hasTrailingComma = (format & 64 /* ListFormat.AllowTrailingComma */) && children.hasTrailingComma;
|
|
1892
|
+
if (format & 16 /* ListFormat.CommaDelimited */ && hasTrailingComma) {
|
|
1893
|
+
writePunctuation(",");
|
|
1894
|
+
}
|
|
1895
|
+
// Emit any trailing comment of the last element in the list
|
|
1896
|
+
// i.e
|
|
1897
|
+
// var array = [...
|
|
1898
|
+
// 2
|
|
1899
|
+
// /* end of element 2 */
|
|
1900
|
+
// ];
|
|
1901
|
+
if (previousSibling && format & 28 /* ListFormat.DelimitersMask */ && previousSibling.end !== parentNode.end && !(getEmitFlags(previousSibling) & EmitFlags.NoTrailingComments)) {
|
|
1902
|
+
emitLeadingCommentsOfPosition(previousSibling.end);
|
|
1903
|
+
}
|
|
1904
|
+
// Decrease the indent, if requested.
|
|
1905
|
+
if (format & 128 /* ListFormat.Indented */) {
|
|
1906
|
+
decreaseIndent();
|
|
1907
|
+
}
|
|
1908
|
+
// Write the closing line terminator or closing whitespace.
|
|
1909
|
+
const closingLineTerminatorCount = getClosingLineTerminatorCount(parentNode, children, format);
|
|
1910
|
+
if (closingLineTerminatorCount) {
|
|
1911
|
+
writeLine(closingLineTerminatorCount);
|
|
1912
|
+
}
|
|
1913
|
+
else if (format & (2097152 /* ListFormat.SpaceAfterList */ | 256 /* ListFormat.SpaceBetweenBraces */)) {
|
|
1914
|
+
writeSpace();
|
|
1915
|
+
}
|
|
1916
|
+
}
|
|
1917
|
+
if (onAfterEmitNodeArray) {
|
|
1918
|
+
onAfterEmitNodeArray(children);
|
|
1919
|
+
}
|
|
1920
|
+
if (format & 15360 /* ListFormat.BracketsMask */) {
|
|
1921
|
+
if (isEmpty && !isUndefined) {
|
|
1922
|
+
emitLeadingCommentsOfPosition(children.end); // Emit leading comments within empty lists
|
|
1923
|
+
}
|
|
1924
|
+
writePunctuation(getClosingBracket(format));
|
|
1925
|
+
}
|
|
1926
|
+
}
|
|
1927
|
+
// Writers
|
|
1928
|
+
function writeLiteral(s) {
|
|
1929
|
+
writer.writeLiteral(s);
|
|
1930
|
+
}
|
|
1931
|
+
function writeStringLiteral(s) {
|
|
1932
|
+
writer.writeStringLiteral(s);
|
|
1933
|
+
}
|
|
1934
|
+
function writeBase(s) {
|
|
1935
|
+
writer.write(s);
|
|
1936
|
+
}
|
|
1937
|
+
function writeSymbol(s, sym) {
|
|
1938
|
+
writer.writeSymbol(s, sym);
|
|
1939
|
+
}
|
|
1940
|
+
function writePunctuation(s) {
|
|
1941
|
+
writer.writePunctuation(s);
|
|
1942
|
+
}
|
|
1943
|
+
function writeTrailingSemicolon() {
|
|
1944
|
+
writer.writeTrailingSemicolon(";");
|
|
1945
|
+
}
|
|
1946
|
+
function writeKeyword(s) {
|
|
1947
|
+
writer.writeKeyword(s);
|
|
1948
|
+
}
|
|
1949
|
+
function writeOperator(s) {
|
|
1950
|
+
writer.writeOperator(s);
|
|
1951
|
+
}
|
|
1952
|
+
function writeParameter(s) {
|
|
1953
|
+
writer.writeParameter(s);
|
|
1954
|
+
}
|
|
1955
|
+
function writeComment(s) {
|
|
1956
|
+
writer.writeComment(s);
|
|
1957
|
+
}
|
|
1958
|
+
function writeSpace() {
|
|
1959
|
+
writer.writeSpace(" ");
|
|
1960
|
+
}
|
|
1961
|
+
function writeProperty(s) {
|
|
1962
|
+
writer.writeProperty(s);
|
|
1963
|
+
}
|
|
1964
|
+
function writeLine(count = 1) {
|
|
1965
|
+
for (let i = 0; i < count; i++) {
|
|
1966
|
+
writer.writeLine(i > 0);
|
|
1967
|
+
}
|
|
1968
|
+
}
|
|
1969
|
+
function increaseIndent() {
|
|
1970
|
+
writer.increaseIndent();
|
|
1971
|
+
}
|
|
1972
|
+
function decreaseIndent() {
|
|
1973
|
+
writer.decreaseIndent();
|
|
1974
|
+
}
|
|
1975
|
+
function writeToken(token, pos, writer) {
|
|
1976
|
+
return writeTokenText(token, writer, pos);
|
|
1977
|
+
}
|
|
1978
|
+
function writeTokenNode(node, writer) {
|
|
1979
|
+
if (onBeforeEmitToken) {
|
|
1980
|
+
onBeforeEmitToken(node);
|
|
1981
|
+
}
|
|
1982
|
+
writer(tokenToString(node.kind));
|
|
1983
|
+
if (onAfterEmitToken) {
|
|
1984
|
+
onAfterEmitToken(node);
|
|
1985
|
+
}
|
|
1986
|
+
}
|
|
1987
|
+
function writeTokenText(token, writer, pos) {
|
|
1988
|
+
const tokenString = tokenToString(token);
|
|
1989
|
+
writer(tokenString);
|
|
1990
|
+
return pos < 0 ? pos : pos + tokenString.length;
|
|
1991
|
+
}
|
|
1992
|
+
function writeLineOrSpace(node) {
|
|
1993
|
+
if (getEmitFlags(node) & EmitFlags.SingleLine) {
|
|
1994
|
+
writeSpace();
|
|
1995
|
+
}
|
|
1996
|
+
else {
|
|
1997
|
+
writeLine();
|
|
1998
|
+
}
|
|
1999
|
+
}
|
|
2000
|
+
function writeLinesAndIndent(lineCount, writeSpaceIfNotIndenting) {
|
|
2001
|
+
if (lineCount) {
|
|
2002
|
+
increaseIndent();
|
|
2003
|
+
writeLine(lineCount);
|
|
2004
|
+
}
|
|
2005
|
+
else if (writeSpaceIfNotIndenting) {
|
|
2006
|
+
writeSpace();
|
|
2007
|
+
}
|
|
2008
|
+
}
|
|
2009
|
+
// Helper function to decrease the indent if we previously indented. Allows multiple
|
|
2010
|
+
// previous indent values to be considered at a time. This also allows caller to just
|
|
2011
|
+
// call this once, passing in all their appropriate indent values, instead of needing
|
|
2012
|
+
// to call this helper function multiple times.
|
|
2013
|
+
function decreaseIndentIf(value1, value2) {
|
|
2014
|
+
if (value1) {
|
|
2015
|
+
decreaseIndent();
|
|
2016
|
+
}
|
|
2017
|
+
if (value2) {
|
|
2018
|
+
decreaseIndent();
|
|
2019
|
+
}
|
|
2020
|
+
}
|
|
2021
|
+
function getLeadingLineTerminatorCount(parentNode, children, format) {
|
|
2022
|
+
if (format & 2 /* ListFormat.PreserveLines */ || preserveSourceNewlines) {
|
|
2023
|
+
if (format & 65536 /* ListFormat.PreferNewLine */) {
|
|
2024
|
+
return 1;
|
|
2025
|
+
}
|
|
2026
|
+
const firstChild = children[0];
|
|
2027
|
+
if (firstChild === undefined) {
|
|
2028
|
+
return rangeIsOnSingleLine(parentNode, currentSourceFile) ? 0 : 1;
|
|
2029
|
+
}
|
|
2030
|
+
if (firstChild.kind === SyntaxKind.JsxText) {
|
|
2031
|
+
// JsxText will be written with its leading whitespace, so don't add more manually.
|
|
2032
|
+
return 0;
|
|
2033
|
+
}
|
|
2034
|
+
if (!positionIsSynthesized(parentNode.pos) && !nodeIsSynthesized(firstChild) && (!firstChild.parent || firstChild.parent === parentNode)) {
|
|
2035
|
+
if (preserveSourceNewlines) {
|
|
2036
|
+
return getEffectiveLines(includeComments => getLinesBetweenPositionAndPrecedingNonWhitespaceCharacter(firstChild.pos, parentNode.pos, currentSourceFile, includeComments));
|
|
2037
|
+
}
|
|
2038
|
+
return rangeStartPositionsAreOnSameLine(parentNode, firstChild, currentSourceFile) ? 0 : 1;
|
|
2039
|
+
}
|
|
2040
|
+
if (synthesizedNodeStartsOnNewLine(firstChild, format)) {
|
|
2041
|
+
return 1;
|
|
2042
|
+
}
|
|
2043
|
+
}
|
|
2044
|
+
return format & 1 /* ListFormat.MultiLine */ ? 1 : 0;
|
|
2045
|
+
}
|
|
2046
|
+
function getSeparatingLineTerminatorCount(previousNode, nextNode, format) {
|
|
2047
|
+
if (format & 2 /* ListFormat.PreserveLines */ || preserveSourceNewlines) {
|
|
2048
|
+
if (previousNode === undefined || nextNode === undefined) {
|
|
2049
|
+
return 0;
|
|
2050
|
+
}
|
|
2051
|
+
if (nextNode.kind === SyntaxKind.JsxText) {
|
|
2052
|
+
// JsxText will be written with its leading whitespace, so don't add more manually.
|
|
2053
|
+
return 0;
|
|
2054
|
+
}
|
|
2055
|
+
else if (!nodeIsSynthesized(previousNode) && !nodeIsSynthesized(nextNode) && previousNode.parent === nextNode.parent) {
|
|
2056
|
+
if (preserveSourceNewlines) {
|
|
2057
|
+
return getEffectiveLines(includeComments => getLinesBetweenRangeEndAndRangeStart(previousNode, nextNode, currentSourceFile, includeComments));
|
|
2058
|
+
}
|
|
2059
|
+
return rangeEndIsOnSameLineAsRangeStart(previousNode, nextNode, currentSourceFile) ? 0 : 1;
|
|
2060
|
+
}
|
|
2061
|
+
else if (synthesizedNodeStartsOnNewLine(previousNode, format) || synthesizedNodeStartsOnNewLine(nextNode, format)) {
|
|
2062
|
+
return 1;
|
|
2063
|
+
}
|
|
2064
|
+
}
|
|
2065
|
+
else if (getStartsOnNewLine(nextNode)) {
|
|
2066
|
+
return 1;
|
|
2067
|
+
}
|
|
2068
|
+
return format & 1 /* ListFormat.MultiLine */ ? 1 : 0;
|
|
2069
|
+
}
|
|
2070
|
+
function getClosingLineTerminatorCount(parentNode, children, format) {
|
|
2071
|
+
if (format & 2 /* ListFormat.PreserveLines */ || preserveSourceNewlines) {
|
|
2072
|
+
if (format & 65536 /* ListFormat.PreferNewLine */) {
|
|
2073
|
+
return 1;
|
|
2074
|
+
}
|
|
2075
|
+
const lastChild = lastOrUndefined(children);
|
|
2076
|
+
if (lastChild === undefined) {
|
|
2077
|
+
return rangeIsOnSingleLine(parentNode, currentSourceFile) ? 0 : 1;
|
|
2078
|
+
}
|
|
2079
|
+
if (!positionIsSynthesized(parentNode.pos) && !nodeIsSynthesized(lastChild) && (!lastChild.parent || lastChild.parent === parentNode)) {
|
|
2080
|
+
if (preserveSourceNewlines) {
|
|
2081
|
+
return getEffectiveLines(includeComments => getLinesBetweenPositionAndNextNonWhitespaceCharacter(lastChild.end, parentNode.end, currentSourceFile, includeComments));
|
|
2082
|
+
}
|
|
2083
|
+
return rangeEndPositionsAreOnSameLine(parentNode, lastChild, currentSourceFile) ? 0 : 1;
|
|
2084
|
+
}
|
|
2085
|
+
if (synthesizedNodeStartsOnNewLine(lastChild, format)) {
|
|
2086
|
+
return 1;
|
|
2087
|
+
}
|
|
2088
|
+
}
|
|
2089
|
+
if (format & 1 /* ListFormat.MultiLine */ && !(format & 131072 /* ListFormat.NoTrailingNewLine */)) {
|
|
2090
|
+
return 1;
|
|
2091
|
+
}
|
|
2092
|
+
return 0;
|
|
2093
|
+
}
|
|
2094
|
+
function getEffectiveLines(getLineDifference) {
|
|
2095
|
+
// If 'preserveSourceNewlines' is disabled, we should never call this function
|
|
2096
|
+
// because it could be more expensive than alternative approximations.
|
|
2097
|
+
Debug.assert(!!preserveSourceNewlines);
|
|
2098
|
+
// We start by measuring the line difference from a position to its adjacent comments,
|
|
2099
|
+
// so that this is counted as a one-line difference, not two:
|
|
2100
|
+
//
|
|
2101
|
+
// node1;
|
|
2102
|
+
// // NODE2 COMMENT
|
|
2103
|
+
// node2;
|
|
2104
|
+
const lines = getLineDifference(/*includeComments*/ true);
|
|
2105
|
+
if (lines === 0) {
|
|
2106
|
+
// However, if the line difference considering comments was 0, we might have this:
|
|
2107
|
+
//
|
|
2108
|
+
// node1; // NODE2 COMMENT
|
|
2109
|
+
// node2;
|
|
2110
|
+
//
|
|
2111
|
+
// in which case we should be ignoring node2's comment, so this too is counted as
|
|
2112
|
+
// a one-line difference, not zero.
|
|
2113
|
+
return getLineDifference(/*includeComments*/ false);
|
|
2114
|
+
}
|
|
2115
|
+
return lines;
|
|
2116
|
+
}
|
|
2117
|
+
function writeLineSeparatorsAndIndentBefore(node, parent) {
|
|
2118
|
+
const leadingNewlines = preserveSourceNewlines && getLeadingLineTerminatorCount(parent, [node], 0 /* ListFormat.None */);
|
|
2119
|
+
if (leadingNewlines) {
|
|
2120
|
+
writeLinesAndIndent(leadingNewlines, /*writeLinesIfNotIndenting*/ false);
|
|
2121
|
+
}
|
|
2122
|
+
return !!leadingNewlines;
|
|
2123
|
+
}
|
|
2124
|
+
function writeLineSeparatorsAfter(node, parent) {
|
|
2125
|
+
const trailingNewlines = preserveSourceNewlines && getClosingLineTerminatorCount(parent, [node], 0 /* ListFormat.None */);
|
|
2126
|
+
if (trailingNewlines) {
|
|
2127
|
+
writeLine(trailingNewlines);
|
|
2128
|
+
}
|
|
2129
|
+
}
|
|
2130
|
+
function synthesizedNodeStartsOnNewLine(node, format) {
|
|
2131
|
+
if (nodeIsSynthesized(node)) {
|
|
2132
|
+
const startsOnNewLine = getStartsOnNewLine(node);
|
|
2133
|
+
if (startsOnNewLine === undefined) {
|
|
2134
|
+
return (format & 65536 /* ListFormat.PreferNewLine */) !== 0;
|
|
2135
|
+
}
|
|
2136
|
+
return startsOnNewLine;
|
|
2137
|
+
}
|
|
2138
|
+
return (format & 65536 /* ListFormat.PreferNewLine */) !== 0;
|
|
2139
|
+
}
|
|
2140
|
+
function getLinesBetweenNodes(parent, node1, node2) {
|
|
2141
|
+
if (getEmitFlags(parent) & EmitFlags.NoIndentation) {
|
|
2142
|
+
return 0;
|
|
2143
|
+
}
|
|
2144
|
+
parent = skipSynthesizedParentheses(parent);
|
|
2145
|
+
node1 = skipSynthesizedParentheses(node1);
|
|
2146
|
+
node2 = skipSynthesizedParentheses(node2);
|
|
2147
|
+
// Always use a newline for synthesized code if the synthesizer desires it.
|
|
2148
|
+
if (getStartsOnNewLine(node2)) {
|
|
2149
|
+
return 1;
|
|
2150
|
+
}
|
|
2151
|
+
if (!nodeIsSynthesized(parent) && !nodeIsSynthesized(node1) && !nodeIsSynthesized(node2)) {
|
|
2152
|
+
if (preserveSourceNewlines) {
|
|
2153
|
+
return getEffectiveLines(includeComments => getLinesBetweenRangeEndAndRangeStart(node1, node2, currentSourceFile, includeComments));
|
|
2154
|
+
}
|
|
2155
|
+
return rangeEndIsOnSameLineAsRangeStart(node1, node2, currentSourceFile) ? 0 : 1;
|
|
2156
|
+
}
|
|
2157
|
+
return 0;
|
|
2158
|
+
}
|
|
2159
|
+
function isEmptyBlock(block) {
|
|
2160
|
+
return block.statements.length === 0
|
|
2161
|
+
&& rangeEndIsOnSameLineAsRangeStart(block, block, currentSourceFile);
|
|
2162
|
+
}
|
|
2163
|
+
function skipSynthesizedParentheses(node) {
|
|
2164
|
+
while (node.kind === SyntaxKind.ParenthesizedExpression && nodeIsSynthesized(node)) {
|
|
2165
|
+
node = node.expression;
|
|
2166
|
+
}
|
|
2167
|
+
return node;
|
|
2168
|
+
}
|
|
2169
|
+
function getTextOfNode(node, includeTrivia) {
|
|
2170
|
+
if (isGeneratedIdentifier(node)) {
|
|
2171
|
+
return generateName(node);
|
|
2172
|
+
}
|
|
2173
|
+
else if (isIdentifier(node) && (nodeIsSynthesized(node) || !node.parent || !currentSourceFile || (node.parent && currentSourceFile && getSourceFileOfNode(node) !== getOriginalNode(currentSourceFile)))) {
|
|
2174
|
+
return idText(node);
|
|
2175
|
+
}
|
|
2176
|
+
else if (node.kind === SyntaxKind.StringLiteral && node.textSourceNode) {
|
|
2177
|
+
return getTextOfNode(node.textSourceNode, includeTrivia);
|
|
2178
|
+
}
|
|
2179
|
+
else if (isLiteralExpression(node) && (nodeIsSynthesized(node) || !node.parent)) {
|
|
2180
|
+
return node.text;
|
|
2181
|
+
}
|
|
2182
|
+
return getSourceTextOfNodeFromSourceFile(currentSourceFile, node, includeTrivia);
|
|
2183
|
+
}
|
|
2184
|
+
function getLiteralTextOfNode(node, neverAsciiEscape, jsxAttributeEscape) {
|
|
2185
|
+
if (node.kind === SyntaxKind.StringLiteral && node.textSourceNode) {
|
|
2186
|
+
const textSourceNode = node.textSourceNode;
|
|
2187
|
+
if (isIdentifier(textSourceNode)) {
|
|
2188
|
+
return jsxAttributeEscape ? `"${escapeJsxAttributeString(getTextOfNode(textSourceNode))}"` :
|
|
2189
|
+
neverAsciiEscape || (getEmitFlags(node) & EmitFlags.NoAsciiEscaping) ? `"${escapeString(getTextOfNode(textSourceNode))}"` :
|
|
2190
|
+
`"${escapeNonAsciiString(getTextOfNode(textSourceNode))}"`;
|
|
2191
|
+
}
|
|
2192
|
+
else {
|
|
2193
|
+
return getLiteralTextOfNode(textSourceNode, neverAsciiEscape, jsxAttributeEscape);
|
|
2194
|
+
}
|
|
2195
|
+
}
|
|
2196
|
+
return getLiteralText(node, currentSourceFile, neverAsciiEscape, jsxAttributeEscape);
|
|
2197
|
+
}
|
|
2198
|
+
/**
|
|
2199
|
+
* Push a new name generation scope.
|
|
2200
|
+
*/
|
|
2201
|
+
function pushNameGenerationScope(node) {
|
|
2202
|
+
if (node && getEmitFlags(node) & EmitFlags.ReuseTempVariableScope) {
|
|
2203
|
+
return;
|
|
2204
|
+
}
|
|
2205
|
+
tempFlagsStack.push(tempFlags);
|
|
2206
|
+
tempFlags = 0;
|
|
2207
|
+
reservedNamesStack.push(reservedNames);
|
|
2208
|
+
}
|
|
2209
|
+
/**
|
|
2210
|
+
* Pop the current name generation scope.
|
|
2211
|
+
*/
|
|
2212
|
+
function popNameGenerationScope(node) {
|
|
2213
|
+
if (node && getEmitFlags(node) & EmitFlags.ReuseTempVariableScope) {
|
|
2214
|
+
return;
|
|
2215
|
+
}
|
|
2216
|
+
tempFlags = tempFlagsStack.pop();
|
|
2217
|
+
reservedNames = reservedNamesStack.pop();
|
|
2218
|
+
}
|
|
2219
|
+
function reserveNameInNestedScopes(name) {
|
|
2220
|
+
if (!reservedNames || reservedNames === lastOrUndefined(reservedNamesStack)) {
|
|
2221
|
+
reservedNames = createMap();
|
|
2222
|
+
}
|
|
2223
|
+
reservedNames.set(name, true);
|
|
2224
|
+
}
|
|
2225
|
+
function generateNames(node) {
|
|
2226
|
+
if (!node)
|
|
2227
|
+
return;
|
|
2228
|
+
switch (node.kind) {
|
|
2229
|
+
case SyntaxKind.Block:
|
|
2230
|
+
forEach(node.statements, generateNames);
|
|
2231
|
+
break;
|
|
2232
|
+
case SyntaxKind.DoStatement:
|
|
2233
|
+
case SyntaxKind.WhileStatement:
|
|
2234
|
+
generateNames(node.statement);
|
|
2235
|
+
break;
|
|
2236
|
+
case SyntaxKind.IfStatement:
|
|
2237
|
+
generateNames(node.thenStatement);
|
|
2238
|
+
generateNames(node.elseStatement);
|
|
2239
|
+
break;
|
|
2240
|
+
case SyntaxKind.ForStatement:
|
|
2241
|
+
case SyntaxKind.ForOfStatement:
|
|
2242
|
+
case SyntaxKind.ForInStatement:
|
|
2243
|
+
generateNames(node.initializer);
|
|
2244
|
+
generateNames(node.statement);
|
|
2245
|
+
break;
|
|
2246
|
+
case SyntaxKind.SwitchStatement:
|
|
2247
|
+
generateNames(node.caseBlock);
|
|
2248
|
+
break;
|
|
2249
|
+
case SyntaxKind.CaseBlock:
|
|
2250
|
+
forEach(node.clauses, generateNames);
|
|
2251
|
+
break;
|
|
2252
|
+
case SyntaxKind.CaseClause:
|
|
2253
|
+
case SyntaxKind.DefaultClause:
|
|
2254
|
+
forEach(node.statements, generateNames);
|
|
2255
|
+
break;
|
|
2256
|
+
case SyntaxKind.TryStatement:
|
|
2257
|
+
generateNames(node.tryBlock);
|
|
2258
|
+
generateNames(node.catchClause);
|
|
2259
|
+
generateNames(node.finallyBlock);
|
|
2260
|
+
break;
|
|
2261
|
+
case SyntaxKind.CatchClause:
|
|
2262
|
+
generateNames(node.variableDeclaration);
|
|
2263
|
+
generateNames(node.block);
|
|
2264
|
+
break;
|
|
2265
|
+
case SyntaxKind.VariableStatement:
|
|
2266
|
+
generateNames(node.declarationList);
|
|
2267
|
+
break;
|
|
2268
|
+
case SyntaxKind.VariableDeclarationList:
|
|
2269
|
+
forEach(node.declarations, generateNames);
|
|
2270
|
+
break;
|
|
2271
|
+
case SyntaxKind.VariableDeclaration:
|
|
2272
|
+
case SyntaxKind.Parameter:
|
|
2273
|
+
case SyntaxKind.BindingElement:
|
|
2274
|
+
generateNameIfNeeded(node.name);
|
|
2275
|
+
break;
|
|
2276
|
+
case SyntaxKind.ObjectBindingPattern:
|
|
2277
|
+
case SyntaxKind.ArrayBindingPattern:
|
|
2278
|
+
forEach(node.elements, generateNames);
|
|
2279
|
+
break;
|
|
2280
|
+
case SyntaxKind.ImportDeclaration:
|
|
2281
|
+
generateNames(node.importClause);
|
|
2282
|
+
break;
|
|
2283
|
+
case SyntaxKind.ImportClause:
|
|
2284
|
+
generateNameIfNeeded(node.name);
|
|
2285
|
+
generateNames(node.namedBindings);
|
|
2286
|
+
break;
|
|
2287
|
+
case SyntaxKind.NamespaceImport:
|
|
2288
|
+
generateNameIfNeeded(node.name);
|
|
2289
|
+
break;
|
|
2290
|
+
case SyntaxKind.NamespaceExport:
|
|
2291
|
+
generateNameIfNeeded(node.name);
|
|
2292
|
+
break;
|
|
2293
|
+
case SyntaxKind.NamedImports:
|
|
2294
|
+
forEach(node.elements, generateNames);
|
|
2295
|
+
break;
|
|
2296
|
+
case SyntaxKind.ImportSpecifier:
|
|
2297
|
+
generateNameIfNeeded(node.propertyName || node.name);
|
|
2298
|
+
break;
|
|
2299
|
+
}
|
|
2300
|
+
}
|
|
2301
|
+
function generateMemberNames(node) {
|
|
2302
|
+
if (!node)
|
|
2303
|
+
return;
|
|
2304
|
+
switch (node.kind) {
|
|
2305
|
+
case SyntaxKind.PropertyAssignment:
|
|
2306
|
+
case SyntaxKind.ShorthandPropertyAssignment:
|
|
2307
|
+
generateNameIfNeeded(node.name);
|
|
2308
|
+
break;
|
|
2309
|
+
}
|
|
2310
|
+
}
|
|
2311
|
+
function generateNameIfNeeded(name) {
|
|
2312
|
+
if (name) {
|
|
2313
|
+
if (isGeneratedIdentifier(name)) {
|
|
2314
|
+
generateName(name);
|
|
2315
|
+
}
|
|
2316
|
+
else if (isBindingPattern(name)) {
|
|
2317
|
+
generateNames(name);
|
|
2318
|
+
}
|
|
2319
|
+
}
|
|
2320
|
+
}
|
|
2321
|
+
/**
|
|
2322
|
+
* Generate the text for a generated identifier.
|
|
2323
|
+
*/
|
|
2324
|
+
function generateName(name) {
|
|
2325
|
+
if ((name.autoGenerateFlags & GeneratedIdentifierFlags.KindMask) === GeneratedIdentifierFlags.Node) {
|
|
2326
|
+
// Node names generate unique names based on their original node
|
|
2327
|
+
// and are cached based on that node's id.
|
|
2328
|
+
return generateNameCached(getNodeForGeneratedName(name), name.autoGenerateFlags);
|
|
2329
|
+
}
|
|
2330
|
+
else {
|
|
2331
|
+
// Auto, Loop, and Unique names are cached based on their unique
|
|
2332
|
+
// autoGenerateId.
|
|
2333
|
+
const autoGenerateId = name.autoGenerateId;
|
|
2334
|
+
return autoGeneratedIdToGeneratedName[autoGenerateId] || (autoGeneratedIdToGeneratedName[autoGenerateId] = makeName(name));
|
|
2335
|
+
}
|
|
2336
|
+
}
|
|
2337
|
+
function generateNameCached(node, flags) {
|
|
2338
|
+
const nodeId = getNodeId(node);
|
|
2339
|
+
return nodeIdToGeneratedName[nodeId] || (nodeIdToGeneratedName[nodeId] = generateNameForNode(node, flags));
|
|
2340
|
+
}
|
|
2341
|
+
/**
|
|
2342
|
+
* Returns a value indicating whether a name is unique globally, within the current file,
|
|
2343
|
+
* or within the NameGenerator.
|
|
2344
|
+
*/
|
|
2345
|
+
function isUniqueName(name) {
|
|
2346
|
+
return isFileLevelUniqueName(name)
|
|
2347
|
+
&& !generatedNames.has(name)
|
|
2348
|
+
&& !(reservedNames && reservedNames.has(name));
|
|
2349
|
+
}
|
|
2350
|
+
/**
|
|
2351
|
+
* Returns a value indicating whether a name is unique globally or within the current file.
|
|
2352
|
+
*/
|
|
2353
|
+
function isFileLevelUniqueName(name) {
|
|
2354
|
+
return currentSourceFile ? ts.isFileLevelUniqueName(currentSourceFile, name, hasGlobalName) : true;
|
|
2355
|
+
}
|
|
2356
|
+
/**
|
|
2357
|
+
* Returns a value indicating whether a name is unique within a container.
|
|
2358
|
+
*/
|
|
2359
|
+
function isUniqueLocalName(name, container) {
|
|
2360
|
+
for (let node = container; isNodeDescendantOf(node, container); node = node.nextContainer) {
|
|
2361
|
+
if (node.locals) {
|
|
2362
|
+
const local = node.locals.get(escapeLeadingUnderscores(name));
|
|
2363
|
+
// We conservatively include alias symbols to cover cases where they're emitted as locals
|
|
2364
|
+
if (local && local.flags & (SymbolFlags.Value | SymbolFlags.ExportValue | SymbolFlags.Alias)) {
|
|
2365
|
+
return false;
|
|
2366
|
+
}
|
|
2367
|
+
}
|
|
2368
|
+
}
|
|
2369
|
+
return true;
|
|
2370
|
+
}
|
|
2371
|
+
/**
|
|
2372
|
+
* Return the next available name in the pattern _a ... _z, _0, _1, ...
|
|
2373
|
+
* TempFlags._i or TempFlags._n may be used to express a preference for that dedicated name.
|
|
2374
|
+
* Note that names generated by makeTempVariableName and makeUniqueName will never conflict.
|
|
2375
|
+
*/
|
|
2376
|
+
function makeTempVariableName(flags, reservedInNestedScopes) {
|
|
2377
|
+
if (flags && !(tempFlags & flags)) {
|
|
2378
|
+
const name = flags === 268435456 /* TempFlags._i */ ? "_i" : "_n";
|
|
2379
|
+
if (isUniqueName(name)) {
|
|
2380
|
+
tempFlags |= flags;
|
|
2381
|
+
if (reservedInNestedScopes) {
|
|
2382
|
+
reserveNameInNestedScopes(name);
|
|
2383
|
+
}
|
|
2384
|
+
return name;
|
|
2385
|
+
}
|
|
2386
|
+
}
|
|
2387
|
+
while (true) {
|
|
2388
|
+
const count = tempFlags & 268435455 /* TempFlags.CountMask */;
|
|
2389
|
+
tempFlags++;
|
|
2390
|
+
// Skip over 'i' and 'n'
|
|
2391
|
+
if (count !== 8 && count !== 13) {
|
|
2392
|
+
const name = count < 26
|
|
2393
|
+
? "_" + String.fromCharCode(CharacterCodes.a + count)
|
|
2394
|
+
: "_" + (count - 26);
|
|
2395
|
+
if (isUniqueName(name)) {
|
|
2396
|
+
if (reservedInNestedScopes) {
|
|
2397
|
+
reserveNameInNestedScopes(name);
|
|
2398
|
+
}
|
|
2399
|
+
return name;
|
|
2400
|
+
}
|
|
2401
|
+
}
|
|
2402
|
+
}
|
|
2403
|
+
}
|
|
2404
|
+
/**
|
|
2405
|
+
* Generate a name that is unique within the current file and doesn't conflict with any names
|
|
2406
|
+
* in global scope. The name is formed by adding an '_n' suffix to the specified base name,
|
|
2407
|
+
* where n is a positive integer. Note that names generated by makeTempVariableName and
|
|
2408
|
+
* makeUniqueName are guaranteed to never conflict.
|
|
2409
|
+
* If `optimistic` is set, the first instance will use 'baseName' verbatim instead of 'baseName_1'
|
|
2410
|
+
*/
|
|
2411
|
+
function makeUniqueName(baseName, checkFn = isUniqueName, optimistic, scoped) {
|
|
2412
|
+
if (optimistic) {
|
|
2413
|
+
if (checkFn(baseName)) {
|
|
2414
|
+
if (scoped) {
|
|
2415
|
+
reserveNameInNestedScopes(baseName);
|
|
2416
|
+
}
|
|
2417
|
+
else {
|
|
2418
|
+
generatedNames.set(baseName, true);
|
|
2419
|
+
}
|
|
2420
|
+
return baseName;
|
|
2421
|
+
}
|
|
2422
|
+
}
|
|
2423
|
+
// Find the first unique 'name_n', where n is a positive number
|
|
2424
|
+
if (baseName.charCodeAt(baseName.length - 1) !== CharacterCodes._) {
|
|
2425
|
+
baseName += "_";
|
|
2426
|
+
}
|
|
2427
|
+
let i = 1;
|
|
2428
|
+
while (true) {
|
|
2429
|
+
const generatedName = baseName + i;
|
|
2430
|
+
if (checkFn(generatedName)) {
|
|
2431
|
+
if (scoped) {
|
|
2432
|
+
reserveNameInNestedScopes(generatedName);
|
|
2433
|
+
}
|
|
2434
|
+
else {
|
|
2435
|
+
generatedNames.set(generatedName, true);
|
|
2436
|
+
}
|
|
2437
|
+
return generatedName;
|
|
2438
|
+
}
|
|
2439
|
+
i++;
|
|
2440
|
+
}
|
|
2441
|
+
}
|
|
2442
|
+
/** O nome único de uma `ModuleDeclaration`: o próprio nome, se é único, ou uma variação dele. */
|
|
2443
|
+
function generateNameForModuleOrEnum(node) {
|
|
2444
|
+
const name = getTextOfNode(node.name);
|
|
2445
|
+
return isUniqueLocalName(name, node) ? name : makeUniqueName(name);
|
|
2446
|
+
}
|
|
2447
|
+
/**
|
|
2448
|
+
* Generates a unique name for an ImportDeclaration or ExportDeclaration.
|
|
2449
|
+
*/
|
|
2450
|
+
function generateNameForImportOrExportDeclaration(node) {
|
|
2451
|
+
const expr = getExternalModuleName(node);
|
|
2452
|
+
const baseName = isStringLiteral(expr) ?
|
|
2453
|
+
makeIdentifierFromModuleName(expr.text) : "module";
|
|
2454
|
+
return makeUniqueName(baseName);
|
|
2455
|
+
}
|
|
2456
|
+
/**
|
|
2457
|
+
* Generates a unique name for a default export.
|
|
2458
|
+
*/
|
|
2459
|
+
function generateNameForExportDefault() {
|
|
2460
|
+
return makeUniqueName("default");
|
|
2461
|
+
}
|
|
2462
|
+
/**
|
|
2463
|
+
* Generates a unique name from a node.
|
|
2464
|
+
*/
|
|
2465
|
+
function generateNameForNode(node, flags) {
|
|
2466
|
+
switch (node.kind) {
|
|
2467
|
+
case SyntaxKind.Identifier:
|
|
2468
|
+
return makeUniqueName(getTextOfNode(node), isUniqueName, !!(flags & GeneratedIdentifierFlags.Optimistic), !!(flags & GeneratedIdentifierFlags.ReservedInNestedScopes));
|
|
2469
|
+
case SyntaxKind.ModuleDeclaration:
|
|
2470
|
+
return generateNameForModuleOrEnum(node);
|
|
2471
|
+
case SyntaxKind.ImportDeclaration:
|
|
2472
|
+
case SyntaxKind.ExportDeclaration:
|
|
2473
|
+
return generateNameForImportOrExportDeclaration(node);
|
|
2474
|
+
case SyntaxKind.ExportAssignment:
|
|
2475
|
+
return generateNameForExportDefault();
|
|
2476
|
+
case SyntaxKind.ComputedPropertyName:
|
|
2477
|
+
return makeTempVariableName(0 /* TempFlags.Auto */, /*reserveInNestedScopes*/ true);
|
|
2478
|
+
default:
|
|
2479
|
+
return makeTempVariableName(0 /* TempFlags.Auto */);
|
|
2480
|
+
}
|
|
2481
|
+
}
|
|
2482
|
+
/**
|
|
2483
|
+
* Generates a unique identifier for a node.
|
|
2484
|
+
*/
|
|
2485
|
+
function makeName(name) {
|
|
2486
|
+
switch (name.autoGenerateFlags & GeneratedIdentifierFlags.KindMask) {
|
|
2487
|
+
case GeneratedIdentifierFlags.Auto:
|
|
2488
|
+
return makeTempVariableName(0 /* TempFlags.Auto */, !!(name.autoGenerateFlags & GeneratedIdentifierFlags.ReservedInNestedScopes));
|
|
2489
|
+
case GeneratedIdentifierFlags.Loop:
|
|
2490
|
+
return makeTempVariableName(268435456 /* TempFlags._i */, !!(name.autoGenerateFlags & GeneratedIdentifierFlags.ReservedInNestedScopes));
|
|
2491
|
+
case GeneratedIdentifierFlags.Unique:
|
|
2492
|
+
return makeUniqueName(idText(name), (name.autoGenerateFlags & GeneratedIdentifierFlags.FileLevel) ? isFileLevelUniqueName : isUniqueName, !!(name.autoGenerateFlags & GeneratedIdentifierFlags.Optimistic), !!(name.autoGenerateFlags & GeneratedIdentifierFlags.ReservedInNestedScopes));
|
|
2493
|
+
}
|
|
2494
|
+
return Debug.fail("Unsupported GeneratedIdentifierKind.");
|
|
2495
|
+
}
|
|
2496
|
+
/**
|
|
2497
|
+
* Gets the node from which a name should be generated.
|
|
2498
|
+
*/
|
|
2499
|
+
function getNodeForGeneratedName(name) {
|
|
2500
|
+
const autoGenerateId = name.autoGenerateId;
|
|
2501
|
+
let node = name;
|
|
2502
|
+
let original = node.original;
|
|
2503
|
+
while (original) {
|
|
2504
|
+
node = original;
|
|
2505
|
+
// if "node" is a different generated name (having a different
|
|
2506
|
+
// "autoGenerateId"), use it and stop traversing.
|
|
2507
|
+
if (isIdentifier(node)
|
|
2508
|
+
&& !!(node.autoGenerateFlags & GeneratedIdentifierFlags.Node)
|
|
2509
|
+
&& node.autoGenerateId !== autoGenerateId) {
|
|
2510
|
+
break;
|
|
2511
|
+
}
|
|
2512
|
+
original = node.original;
|
|
2513
|
+
}
|
|
2514
|
+
// otherwise, return the original node for the source;
|
|
2515
|
+
return node;
|
|
2516
|
+
}
|
|
2517
|
+
// Comments
|
|
2518
|
+
function pipelineEmitWithComments(hint, node) {
|
|
2519
|
+
Debug.assert(lastNode === node);
|
|
2520
|
+
hasWrittenComment = false;
|
|
2521
|
+
const emitFlags = getEmitFlags(node);
|
|
2522
|
+
const { pos, end } = getCommentRange(node);
|
|
2523
|
+
const isEmittedNode = node.kind !== SyntaxKind.NotEmittedStatement;
|
|
2524
|
+
// We have to explicitly check that the node is JsxText because if the compilerOptions.jsx is "preserve" we will not do any transformation.
|
|
2525
|
+
// It is expensive to walk entire tree just to set one kind of node to have no comments.
|
|
2526
|
+
const skipLeadingComments = pos < 0 || (emitFlags & EmitFlags.NoLeadingComments) !== 0 || node.kind === SyntaxKind.JsxText;
|
|
2527
|
+
const skipTrailingComments = end < 0 || (emitFlags & EmitFlags.NoTrailingComments) !== 0 || node.kind === SyntaxKind.JsxText;
|
|
2528
|
+
// Save current container state on the stack.
|
|
2529
|
+
const savedContainerPos = containerPos;
|
|
2530
|
+
const savedContainerEnd = containerEnd;
|
|
2531
|
+
const savedDeclarationListContainerEnd = declarationListContainerEnd;
|
|
2532
|
+
if ((pos > 0 || end > 0) && pos !== end) {
|
|
2533
|
+
// Emit leading comments if the position is not synthesized and the node
|
|
2534
|
+
// has not opted out from emitting leading comments.
|
|
2535
|
+
if (!skipLeadingComments) {
|
|
2536
|
+
emitLeadingComments(pos, isEmittedNode);
|
|
2537
|
+
}
|
|
2538
|
+
if (!skipLeadingComments || (pos >= 0 && (emitFlags & EmitFlags.NoLeadingComments) !== 0)) {
|
|
2539
|
+
// Advance the container position if comments get emitted or if they've been disabled explicitly using NoLeadingComments.
|
|
2540
|
+
containerPos = pos;
|
|
2541
|
+
}
|
|
2542
|
+
if (!skipTrailingComments || (end >= 0 && (emitFlags & EmitFlags.NoTrailingComments) !== 0)) {
|
|
2543
|
+
// As above.
|
|
2544
|
+
containerEnd = end;
|
|
2545
|
+
// To avoid invalid comment emit in a down-level binding pattern, we
|
|
2546
|
+
// keep track of the last declaration list container's end
|
|
2547
|
+
if (node.kind === SyntaxKind.VariableDeclarationList) {
|
|
2548
|
+
declarationListContainerEnd = end;
|
|
2549
|
+
}
|
|
2550
|
+
}
|
|
2551
|
+
}
|
|
2552
|
+
forEach(getSyntheticLeadingComments(node), emitLeadingSynthesizedComment);
|
|
2553
|
+
const pipelinePhase = getNextPipelinePhase(1 /* PipelinePhase.Comments */, hint, node);
|
|
2554
|
+
if (emitFlags & EmitFlags.NoNestedComments) {
|
|
2555
|
+
commentsDisabled = true;
|
|
2556
|
+
pipelinePhase(hint, node);
|
|
2557
|
+
commentsDisabled = false;
|
|
2558
|
+
}
|
|
2559
|
+
else {
|
|
2560
|
+
pipelinePhase(hint, node);
|
|
2561
|
+
}
|
|
2562
|
+
forEach(getSyntheticTrailingComments(node), emitTrailingSynthesizedComment);
|
|
2563
|
+
if ((pos > 0 || end > 0) && pos !== end) {
|
|
2564
|
+
// Restore previous container state.
|
|
2565
|
+
containerPos = savedContainerPos;
|
|
2566
|
+
containerEnd = savedContainerEnd;
|
|
2567
|
+
declarationListContainerEnd = savedDeclarationListContainerEnd;
|
|
2568
|
+
// Emit trailing comments if the position is not synthesized and the node
|
|
2569
|
+
// has not opted out from emitting leading comments and is an emitted node.
|
|
2570
|
+
if (!skipTrailingComments && isEmittedNode) {
|
|
2571
|
+
emitTrailingComments(end);
|
|
2572
|
+
}
|
|
2573
|
+
}
|
|
2574
|
+
Debug.assert(lastNode === node);
|
|
2575
|
+
}
|
|
2576
|
+
function emitLeadingSynthesizedComment(comment) {
|
|
2577
|
+
if (comment.kind === SyntaxKind.SingleLineCommentTrivia) {
|
|
2578
|
+
writer.writeLine();
|
|
2579
|
+
}
|
|
2580
|
+
writeSynthesizedComment(comment);
|
|
2581
|
+
if (comment.hasTrailingNewLine || comment.kind === SyntaxKind.SingleLineCommentTrivia) {
|
|
2582
|
+
writer.writeLine();
|
|
2583
|
+
}
|
|
2584
|
+
else {
|
|
2585
|
+
writer.writeSpace(" ");
|
|
2586
|
+
}
|
|
2587
|
+
}
|
|
2588
|
+
function emitTrailingSynthesizedComment(comment) {
|
|
2589
|
+
if (!writer.isAtStartOfLine()) {
|
|
2590
|
+
writer.writeSpace(" ");
|
|
2591
|
+
}
|
|
2592
|
+
writeSynthesizedComment(comment);
|
|
2593
|
+
if (comment.hasTrailingNewLine) {
|
|
2594
|
+
writer.writeLine();
|
|
2595
|
+
}
|
|
2596
|
+
}
|
|
2597
|
+
function writeSynthesizedComment(comment) {
|
|
2598
|
+
const text = formatSynthesizedComment(comment);
|
|
2599
|
+
const lineMap = comment.kind === SyntaxKind.MultiLineCommentTrivia ? computeLineStarts(text) : undefined;
|
|
2600
|
+
writeCommentRange(text, lineMap, writer, 0, text.length, newLine);
|
|
2601
|
+
}
|
|
2602
|
+
function formatSynthesizedComment(comment) {
|
|
2603
|
+
return comment.kind === SyntaxKind.MultiLineCommentTrivia
|
|
2604
|
+
? `/*${comment.text}*/`
|
|
2605
|
+
: `//${comment.text}`;
|
|
2606
|
+
}
|
|
2607
|
+
function emitBodyWithDetachedComments(node, detachedRange, emitCallback) {
|
|
2608
|
+
const { pos, end } = detachedRange;
|
|
2609
|
+
const emitFlags = getEmitFlags(node);
|
|
2610
|
+
const skipLeadingComments = pos < 0 || (emitFlags & EmitFlags.NoLeadingComments) !== 0;
|
|
2611
|
+
const skipTrailingComments = commentsDisabled || end < 0 || (emitFlags & EmitFlags.NoTrailingComments) !== 0;
|
|
2612
|
+
if (!skipLeadingComments) {
|
|
2613
|
+
emitDetachedCommentsAndUpdateCommentsInfo(detachedRange);
|
|
2614
|
+
}
|
|
2615
|
+
if (emitFlags & EmitFlags.NoNestedComments && !commentsDisabled) {
|
|
2616
|
+
commentsDisabled = true;
|
|
2617
|
+
emitCallback(node);
|
|
2618
|
+
commentsDisabled = false;
|
|
2619
|
+
}
|
|
2620
|
+
else {
|
|
2621
|
+
emitCallback(node);
|
|
2622
|
+
}
|
|
2623
|
+
if (!skipTrailingComments) {
|
|
2624
|
+
emitLeadingComments(detachedRange.end, /*isEmittedNode*/ true);
|
|
2625
|
+
if (hasWrittenComment && !writer.isAtStartOfLine()) {
|
|
2626
|
+
writer.writeLine();
|
|
2627
|
+
}
|
|
2628
|
+
}
|
|
2629
|
+
}
|
|
2630
|
+
function emitLeadingComments(pos, isEmittedNode) {
|
|
2631
|
+
hasWrittenComment = false;
|
|
2632
|
+
if (isEmittedNode) {
|
|
2633
|
+
forEachLeadingCommentToEmit(pos, emitLeadingComment);
|
|
2634
|
+
}
|
|
2635
|
+
}
|
|
2636
|
+
function emitLeadingComment(commentPos, commentEnd, kind, hasTrailingNewLine, rangePos) {
|
|
2637
|
+
if (!hasWrittenComment) {
|
|
2638
|
+
emitNewLineBeforeLeadingCommentOfPosition(getCurrentLineMap(), writer, rangePos, commentPos);
|
|
2639
|
+
hasWrittenComment = true;
|
|
2640
|
+
}
|
|
2641
|
+
// Leading comments are emitted at /*leading comment1 */space/*leading comment*/space
|
|
2642
|
+
writeCommentRange(currentSourceFile.text, getCurrentLineMap(), writer, commentPos, commentEnd, newLine);
|
|
2643
|
+
if (hasTrailingNewLine) {
|
|
2644
|
+
writer.writeLine();
|
|
2645
|
+
}
|
|
2646
|
+
else if (kind === SyntaxKind.MultiLineCommentTrivia) {
|
|
2647
|
+
writer.writeSpace(" ");
|
|
2648
|
+
}
|
|
2649
|
+
}
|
|
2650
|
+
function emitLeadingCommentsOfPosition(pos) {
|
|
2651
|
+
if (commentsDisabled || pos === -1) {
|
|
2652
|
+
return;
|
|
2653
|
+
}
|
|
2654
|
+
emitLeadingComments(pos, /*isEmittedNode*/ true);
|
|
2655
|
+
}
|
|
2656
|
+
function emitTrailingComments(pos) {
|
|
2657
|
+
forEachTrailingCommentToEmit(pos, emitTrailingComment);
|
|
2658
|
+
}
|
|
2659
|
+
function emitTrailingComment(commentPos, commentEnd, _kind, hasTrailingNewLine) {
|
|
2660
|
+
// trailing comments are emitted at space/*trailing comment1 */space/*trailing comment2*/
|
|
2661
|
+
if (!writer.isAtStartOfLine()) {
|
|
2662
|
+
writer.writeSpace(" ");
|
|
2663
|
+
}
|
|
2664
|
+
writeCommentRange(currentSourceFile.text, getCurrentLineMap(), writer, commentPos, commentEnd, newLine);
|
|
2665
|
+
if (hasTrailingNewLine) {
|
|
2666
|
+
writer.writeLine();
|
|
2667
|
+
}
|
|
2668
|
+
}
|
|
2669
|
+
function emitTrailingCommentsOfPosition(pos, prefixSpace) {
|
|
2670
|
+
if (commentsDisabled) {
|
|
2671
|
+
return;
|
|
2672
|
+
}
|
|
2673
|
+
forEachTrailingCommentToEmit(pos, prefixSpace ? emitTrailingComment : emitTrailingCommentOfPosition);
|
|
2674
|
+
}
|
|
2675
|
+
function emitTrailingCommentOfPosition(commentPos, commentEnd, _kind, hasTrailingNewLine) {
|
|
2676
|
+
// trailing comments of a position are emitted at /*trailing comment1 */space/*trailing comment*/space
|
|
2677
|
+
writeCommentRange(currentSourceFile.text, getCurrentLineMap(), writer, commentPos, commentEnd, newLine);
|
|
2678
|
+
if (hasTrailingNewLine) {
|
|
2679
|
+
writer.writeLine();
|
|
2680
|
+
}
|
|
2681
|
+
else {
|
|
2682
|
+
writer.writeSpace(" ");
|
|
2683
|
+
}
|
|
2684
|
+
}
|
|
2685
|
+
function forEachLeadingCommentToEmit(pos, cb) {
|
|
2686
|
+
// Emit the leading comments only if the container's pos doesn't match because the container should take care of emitting these comments
|
|
2687
|
+
if (currentSourceFile && (containerPos === -1 || pos !== containerPos)) {
|
|
2688
|
+
if (hasDetachedComments(pos)) {
|
|
2689
|
+
forEachLeadingCommentWithoutDetachedComments(cb);
|
|
2690
|
+
}
|
|
2691
|
+
else {
|
|
2692
|
+
forEachLeadingCommentRange(currentSourceFile.text, pos, cb, /*state*/ pos);
|
|
2693
|
+
}
|
|
2694
|
+
}
|
|
2695
|
+
}
|
|
2696
|
+
function forEachTrailingCommentToEmit(end, cb) {
|
|
2697
|
+
// Emit the trailing comments only if the container's end doesn't match because the container should take care of emitting these comments
|
|
2698
|
+
if (currentSourceFile && (containerEnd === -1 || (end !== containerEnd && end !== declarationListContainerEnd))) {
|
|
2699
|
+
forEachTrailingCommentRange(currentSourceFile.text, end, cb);
|
|
2700
|
+
}
|
|
2701
|
+
}
|
|
2702
|
+
function hasDetachedComments(pos) {
|
|
2703
|
+
return detachedCommentsInfo !== undefined && last(detachedCommentsInfo).nodePos === pos;
|
|
2704
|
+
}
|
|
2705
|
+
function forEachLeadingCommentWithoutDetachedComments(cb) {
|
|
2706
|
+
// get the leading comments from detachedPos
|
|
2707
|
+
const pos = last(detachedCommentsInfo).detachedCommentEndPos;
|
|
2708
|
+
if (detachedCommentsInfo.length - 1) {
|
|
2709
|
+
detachedCommentsInfo.pop();
|
|
2710
|
+
}
|
|
2711
|
+
else {
|
|
2712
|
+
detachedCommentsInfo = undefined;
|
|
2713
|
+
}
|
|
2714
|
+
forEachLeadingCommentRange(currentSourceFile.text, pos, cb, /*state*/ pos);
|
|
2715
|
+
}
|
|
2716
|
+
function emitDetachedCommentsAndUpdateCommentsInfo(range) {
|
|
2717
|
+
const currentDetachedCommentInfo = emitDetachedComments(currentSourceFile.text, getCurrentLineMap(), writer, emitComment, range, newLine, commentsDisabled);
|
|
2718
|
+
if (currentDetachedCommentInfo) {
|
|
2719
|
+
if (detachedCommentsInfo) {
|
|
2720
|
+
detachedCommentsInfo.push(currentDetachedCommentInfo);
|
|
2721
|
+
}
|
|
2722
|
+
else {
|
|
2723
|
+
detachedCommentsInfo = [currentDetachedCommentInfo];
|
|
2724
|
+
}
|
|
2725
|
+
}
|
|
2726
|
+
}
|
|
2727
|
+
function emitComment(text, lineMap, writer, commentPos, commentEnd, newLine) {
|
|
2728
|
+
writeCommentRange(text, lineMap, writer, commentPos, commentEnd, newLine);
|
|
2729
|
+
}
|
|
2730
|
+
}
|
|
2731
|
+
function createBracketsMap() {
|
|
2732
|
+
const brackets = [];
|
|
2733
|
+
brackets[1024 /* ListFormat.Braces */] = ["{", "}"];
|
|
2734
|
+
brackets[2048 /* ListFormat.Parenthesis */] = ["(", ")"];
|
|
2735
|
+
brackets[4096 /* ListFormat.AngleBrackets */] = ["<", ">"];
|
|
2736
|
+
brackets[8192 /* ListFormat.SquareBrackets */] = ["[", "]"];
|
|
2737
|
+
return brackets;
|
|
2738
|
+
}
|
|
2739
|
+
function getOpeningBracket(format) {
|
|
2740
|
+
return brackets[format & 15360 /* ListFormat.BracketsMask */][0];
|
|
2741
|
+
}
|
|
2742
|
+
function getClosingBracket(format) {
|
|
2743
|
+
return brackets[format & 15360 /* ListFormat.BracketsMask */][1];
|
|
2744
|
+
}
|
|
2745
|
+
// Flags enum to track count of temp variables and a few dedicated names
|
|
2746
|
+
var TempFlags;
|
|
2747
|
+
(function (TempFlags) {
|
|
2748
|
+
TempFlags[TempFlags["Auto"] = 0] = "Auto";
|
|
2749
|
+
TempFlags[TempFlags["CountMask"] = 268435455] = "CountMask";
|
|
2750
|
+
TempFlags[TempFlags["_i"] = 268435456] = "_i";
|
|
2751
|
+
})(TempFlags || (TempFlags = {}));
|