@tslite/parser 1.10.0 → 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 +14 -0
- package/dist/_namespaces/ts.d.ts +18 -0
- package/dist/_namespaces/ts.js +21 -0
- package/dist/_namespaces/ts.performance.d.ts +1 -0
- package/dist/_namespaces/ts.performance.js +2 -0
- package/dist/core.d.ts +450 -0
- package/dist/core.js +1394 -0
- package/dist/corePublic.d.ts +62 -0
- package/dist/corePublic.js +31 -0
- package/dist/debug.d.ts +74 -0
- package/dist/debug.js +326 -0
- package/dist/diagnosticInformationMap.generated.d.ts +1435 -0
- package/dist/diagnosticInformationMap.generated.js +1441 -0
- package/dist/factory.d.ts +78 -0
- package/dist/factory.js +622 -0
- package/dist/factoryPublic.d.ts +314 -0
- package/dist/factoryPublic.js +1796 -0
- package/dist/index.d.ts +1 -249
- package/dist/index.js +4 -6
- package/dist/parser.d.ts +59 -0
- package/dist/parser.js +5075 -0
- package/dist/path.d.ts +312 -0
- package/dist/path.js +475 -0
- package/dist/perfLogger.d.ts +4 -0
- package/dist/perfLogger.js +38 -0
- package/dist/performance.d.ts +20 -0
- package/dist/performance.js +49 -0
- package/dist/performanceTimestamp.d.ts +2 -0
- package/dist/performanceTimestamp.js +2 -0
- package/dist/scanner.d.ts +80 -0
- package/dist/scanner.js +1984 -0
- package/dist/shims/mapShim.d.ts +23 -0
- package/dist/shims/mapShim.js +156 -0
- package/dist/types.d.ts +2626 -0
- package/dist/types.js +1074 -0
- package/dist/utilities.d.ts +473 -0
- package/dist/utilities.js +2632 -0
- package/dist/utilitiesPublic.d.ts +274 -0
- package/dist/utilitiesPublic.js +1049 -0
- package/dist/visitor.d.ts +15 -0
- package/dist/visitor.js +64 -0
- package/dist/visitorPublic.d.ts +82 -0
- package/dist/visitorPublic.js +352 -0
- package/package.json +14 -42
- package/dist/index.cjs +0 -6
- package/dist/index.d.cts +0 -249
|
@@ -0,0 +1,2632 @@
|
|
|
1
|
+
// Modificado de microsoft/TypeScript v3.9.10, src/compiler/utilities.ts: o namespace virou módulo ES, com os imports explícitos.
|
|
2
|
+
import { Debug, Diagnostics, Map, arrayToMap, assertType, binarySearch, compareStringsCaseSensitive, compareValues, computeLineOfPosition, contains, createMap, createMapFromTemplate, createScanner, createTextSpan, createTextSpanFromBounds, equateValues, escapeLeadingUnderscores, every, fileExtensionIs, find, firstOrUndefined, forEach, forEachChild, getBaseFileName, getCombinedModifierFlags, getCombinedNodeFlags, getLeadingCommentRanges, getLineAndCharacterOfPosition, getLineStarts, getLinesBetweenPositions, getNameOfDeclaration, idText, isBigIntLiteral, isBinaryExpression, isAnyDirectorySeparator, isBindingPattern, isCallExpression, isComputedPropertyName, isDeclaration, isElementAccessExpression, isExportAssignment, isExportDeclaration, isExternalModule, isFunctionLike, isFunctionLikeDeclaration, isIdentifier, isImportTypeNode, isJsxText, isLeftHandSideExpression, isLineBreak, isLiteralTypeNode, isMetaProperty, isModuleDeclaration, isNumericLiteral, isObjectLiteralExpression, isPrefixUnaryExpression, isPropertyAccessExpression, isQualifiedName, isSourceFile, isString, isStringLiteral, isStringLiteralLike, isTypeLiteralNode, isTypeReferenceNode, isVariableDeclaration, isVariableStatement, isWhiteSpaceLike, lastOrUndefined, length, returnTrue, skipOuterExpressions, skipTrivia, some, startsWith, stringContains, stringToToken, tryCast, tryRemovePrefix, unescapeLeadingUnderscores, } from "./_namespaces/ts.js";
|
|
3
|
+
export const defaultMaximumTruncationLength = 160;
|
|
4
|
+
export const noTruncationMaximumTruncationLength = 1_000_000;
|
|
5
|
+
export function getDeclarationOfKind(symbol, kind) {
|
|
6
|
+
const declarations = symbol.declarations;
|
|
7
|
+
if (declarations) {
|
|
8
|
+
for (const declaration of declarations) {
|
|
9
|
+
if (declaration.kind === kind) {
|
|
10
|
+
return declaration;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
return undefined;
|
|
15
|
+
}
|
|
16
|
+
/** Create a new escaped identifier map. */
|
|
17
|
+
export function createUnderscoreEscapedMap() {
|
|
18
|
+
return new Map();
|
|
19
|
+
}
|
|
20
|
+
export function hasEntries(map) {
|
|
21
|
+
return !!map && !!map.size;
|
|
22
|
+
}
|
|
23
|
+
export function createSymbolTable(symbols) {
|
|
24
|
+
const result = createMap();
|
|
25
|
+
if (symbols) {
|
|
26
|
+
for (const symbol of symbols) {
|
|
27
|
+
result.set(symbol.escapedName, symbol);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return result;
|
|
31
|
+
}
|
|
32
|
+
export function findAncestor(node, callback) {
|
|
33
|
+
while (node) {
|
|
34
|
+
const result = callback(node);
|
|
35
|
+
if (result === "quit") {
|
|
36
|
+
return undefined;
|
|
37
|
+
}
|
|
38
|
+
else if (result) {
|
|
39
|
+
return node;
|
|
40
|
+
}
|
|
41
|
+
node = node.parent;
|
|
42
|
+
}
|
|
43
|
+
return undefined;
|
|
44
|
+
}
|
|
45
|
+
export function forEachEntry(map, callback) {
|
|
46
|
+
const iterator = map.entries();
|
|
47
|
+
for (let iterResult = iterator.next(); !iterResult.done; iterResult = iterator.next()) {
|
|
48
|
+
const [key, value] = iterResult.value;
|
|
49
|
+
const result = callback(value, key);
|
|
50
|
+
if (result) {
|
|
51
|
+
return result;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return undefined;
|
|
55
|
+
}
|
|
56
|
+
export function forEachKey(map, callback) {
|
|
57
|
+
const iterator = map.keys();
|
|
58
|
+
for (let iterResult = iterator.next(); !iterResult.done; iterResult = iterator.next()) {
|
|
59
|
+
const result = callback(iterResult.value);
|
|
60
|
+
if (result) {
|
|
61
|
+
return result;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return undefined;
|
|
65
|
+
}
|
|
66
|
+
export function copyEntries(source, target) {
|
|
67
|
+
source.forEach((value, key) => {
|
|
68
|
+
target.set(key, value);
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
export function arrayToSet(array, makeKey) {
|
|
72
|
+
return arrayToMap(array, makeKey || (s => s), returnTrue);
|
|
73
|
+
}
|
|
74
|
+
export function cloneMap(map) {
|
|
75
|
+
const clone = createMap();
|
|
76
|
+
copyEntries(map, clone);
|
|
77
|
+
return clone;
|
|
78
|
+
}
|
|
79
|
+
export function getFullWidth(node) {
|
|
80
|
+
return node.end - node.pos;
|
|
81
|
+
}
|
|
82
|
+
export function getResolvedModule(sourceFile, moduleNameText) {
|
|
83
|
+
return sourceFile && sourceFile.resolvedModules && sourceFile.resolvedModules.get(moduleNameText);
|
|
84
|
+
}
|
|
85
|
+
export function setResolvedModule(sourceFile, moduleNameText, resolvedModule) {
|
|
86
|
+
if (!sourceFile.resolvedModules) {
|
|
87
|
+
sourceFile.resolvedModules = createMap();
|
|
88
|
+
}
|
|
89
|
+
sourceFile.resolvedModules.set(moduleNameText, resolvedModule);
|
|
90
|
+
}
|
|
91
|
+
// Returns true if this node contains a parse error anywhere underneath it.
|
|
92
|
+
export function containsParseError(node) {
|
|
93
|
+
aggregateChildData(node);
|
|
94
|
+
return (node.flags & 262144 /* NodeFlags.ThisNodeOrAnySubNodesHasError */) !== 0;
|
|
95
|
+
}
|
|
96
|
+
function aggregateChildData(node) {
|
|
97
|
+
if (!(node.flags & 524288 /* NodeFlags.HasAggregatedChildData */)) {
|
|
98
|
+
// A node is considered to contain a parse error if:
|
|
99
|
+
// a) the parser explicitly marked that it had an error
|
|
100
|
+
// b) any of it's children reported that it had an error.
|
|
101
|
+
const thisNodeOrAnySubNodesHasError = ((node.flags & 65536 /* NodeFlags.ThisNodeHasError */) !== 0) ||
|
|
102
|
+
forEachChild(node, containsParseError);
|
|
103
|
+
// If so, mark ourselves accordingly.
|
|
104
|
+
if (thisNodeOrAnySubNodesHasError) {
|
|
105
|
+
node.flags |= 262144 /* NodeFlags.ThisNodeOrAnySubNodesHasError */;
|
|
106
|
+
}
|
|
107
|
+
// Also mark that we've propagated the child information to this node. This way we can
|
|
108
|
+
// always consult the bit directly on this node without needing to check its children
|
|
109
|
+
// again.
|
|
110
|
+
node.flags |= 524288 /* NodeFlags.HasAggregatedChildData */;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
let nextNodeId = 1;
|
|
114
|
+
/** O id do nó, dado na primeira vez que alguém pede: indexa as tabelas laterais do binder e do checker. */
|
|
115
|
+
export function getNodeId(node) {
|
|
116
|
+
if (!node.id) {
|
|
117
|
+
node.id = nextNodeId;
|
|
118
|
+
nextNodeId++;
|
|
119
|
+
}
|
|
120
|
+
return node.id;
|
|
121
|
+
}
|
|
122
|
+
export function getSourceFileOfNode(node) {
|
|
123
|
+
while (node && node.kind !== 290 /* SyntaxKind.SourceFile */) {
|
|
124
|
+
node = node.parent;
|
|
125
|
+
}
|
|
126
|
+
return node;
|
|
127
|
+
}
|
|
128
|
+
export function getStartPositionOfLine(line, sourceFile) {
|
|
129
|
+
Debug.assert(line >= 0);
|
|
130
|
+
return getLineStarts(sourceFile)[line];
|
|
131
|
+
}
|
|
132
|
+
export function getEndLinePosition(line, sourceFile) {
|
|
133
|
+
Debug.assert(line >= 0);
|
|
134
|
+
const lineStarts = getLineStarts(sourceFile);
|
|
135
|
+
const lineIndex = line;
|
|
136
|
+
const sourceText = sourceFile.text;
|
|
137
|
+
if (lineIndex + 1 === lineStarts.length) {
|
|
138
|
+
// last line - return EOF
|
|
139
|
+
return sourceText.length - 1;
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
// current line start
|
|
143
|
+
const start = lineStarts[lineIndex];
|
|
144
|
+
// take the start position of the next line - 1 = it should be some line break
|
|
145
|
+
let pos = lineStarts[lineIndex + 1] - 1;
|
|
146
|
+
Debug.assert(isLineBreak(sourceText.charCodeAt(pos)));
|
|
147
|
+
// walk backwards skipping line breaks, stop the the beginning of current line.
|
|
148
|
+
// i.e:
|
|
149
|
+
// <some text>
|
|
150
|
+
// $ <- end of line for this position should match the start position
|
|
151
|
+
while (start <= pos && isLineBreak(sourceText.charCodeAt(pos))) {
|
|
152
|
+
pos--;
|
|
153
|
+
}
|
|
154
|
+
return pos;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
// Returns true if this node is missing from the actual source code. A 'missing' node is different
|
|
158
|
+
// from 'undefined/defined'. When a node is undefined (which can happen for optional nodes
|
|
159
|
+
// in the tree), it is definitely missing. However, a node may be defined, but still be
|
|
160
|
+
// missing. This happens whenever the parser knows it needs to parse something, but can't
|
|
161
|
+
// get anything in the source code that it expects at that location. For example:
|
|
162
|
+
//
|
|
163
|
+
// let a: ;
|
|
164
|
+
//
|
|
165
|
+
// Here, the Type in the Type-Annotation is not-optional (as there is a colon in the source
|
|
166
|
+
// code). So the parser will attempt to parse out a type, and will create an actual node.
|
|
167
|
+
// However, this node will be 'missing' in the sense that no actual source-code/tokens are
|
|
168
|
+
// contained within it.
|
|
169
|
+
export function nodeIsMissing(node) {
|
|
170
|
+
if (node === undefined) {
|
|
171
|
+
return true;
|
|
172
|
+
}
|
|
173
|
+
return node.pos === node.end && node.pos >= 0 && node.kind !== 1 /* SyntaxKind.EndOfFileToken */;
|
|
174
|
+
}
|
|
175
|
+
export function nodeIsPresent(node) {
|
|
176
|
+
return !nodeIsMissing(node);
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Determine if the given comment is a triple-slash
|
|
180
|
+
*
|
|
181
|
+
* @return true if the comment is a triple-slash comment else false
|
|
182
|
+
*/
|
|
183
|
+
export function isRecognizedTripleSlashComment(text, commentPos, commentEnd) {
|
|
184
|
+
// Verify this is /// comment, but do the regexp match only when we first can find /// in the comment text
|
|
185
|
+
// so that we don't end up computing comment string and doing match for all // comments
|
|
186
|
+
if (text.charCodeAt(commentPos + 1) === 47 /* CharacterCodes.slash */ &&
|
|
187
|
+
commentPos + 2 < commentEnd &&
|
|
188
|
+
text.charCodeAt(commentPos + 2) === 47 /* CharacterCodes.slash */) {
|
|
189
|
+
const textSubStr = text.substring(commentPos, commentEnd);
|
|
190
|
+
// Na tag, também a referência por texto (`path`) e o `amd-dependency` (CK-03), e a dos pacotes de tipos
|
|
191
|
+
// (`types`, CK-46); fica a diretiva da lib.
|
|
192
|
+
return textSubStr.match(defaultLibReferenceRegEx) ?
|
|
193
|
+
true : false;
|
|
194
|
+
}
|
|
195
|
+
return false;
|
|
196
|
+
}
|
|
197
|
+
export function isPinnedComment(text, start) {
|
|
198
|
+
return text.charCodeAt(start + 1) === 42 /* CharacterCodes.asterisk */ &&
|
|
199
|
+
text.charCodeAt(start + 2) === 33 /* CharacterCodes.exclamation */;
|
|
200
|
+
}
|
|
201
|
+
export function getTokenPosOfNode(node, sourceFile) {
|
|
202
|
+
// With nodes that have no width (i.e. 'Missing' nodes), we actually *don't*
|
|
203
|
+
// want to skip trivia because this will launch us forward to the next token.
|
|
204
|
+
if (nodeIsMissing(node)) {
|
|
205
|
+
return node.pos;
|
|
206
|
+
}
|
|
207
|
+
// Uma syntax list começa no primeiro token do primeiro filho.
|
|
208
|
+
if (node.kind === 324 /* SyntaxKind.SyntaxList */ && node._children.length > 0) {
|
|
209
|
+
return getTokenPosOfNode(node._children[0], sourceFile);
|
|
210
|
+
}
|
|
211
|
+
return skipTrivia((sourceFile || getSourceFileOfNode(node)).text, node.pos);
|
|
212
|
+
}
|
|
213
|
+
export function getSourceTextOfNodeFromSourceFile(sourceFile, node, includeTrivia = false) {
|
|
214
|
+
return getTextOfNodeFromSourceText(sourceFile.text, node, includeTrivia);
|
|
215
|
+
}
|
|
216
|
+
export function getTextOfNodeFromSourceText(sourceText, node, includeTrivia = false) {
|
|
217
|
+
if (nodeIsMissing(node)) {
|
|
218
|
+
return "";
|
|
219
|
+
}
|
|
220
|
+
return sourceText.substring(includeTrivia ? node.pos : skipTrivia(sourceText, node.pos), node.end);
|
|
221
|
+
}
|
|
222
|
+
export function getTextOfNode(node, includeTrivia = false) {
|
|
223
|
+
return getSourceTextOfNodeFromSourceFile(getSourceFileOfNode(node), node, includeTrivia);
|
|
224
|
+
}
|
|
225
|
+
function getPos(range) {
|
|
226
|
+
return range.pos;
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Note: it is expected that the `nodeArray` and the `node` are within the same file.
|
|
230
|
+
* For example, searching for a `SourceFile` in a `SourceFile[]` wouldn't work.
|
|
231
|
+
*/
|
|
232
|
+
export function indexOfNode(nodeArray, node) {
|
|
233
|
+
return binarySearch(nodeArray, node, getPos, compareValues);
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Gets flags that control emit behavior of a node.
|
|
237
|
+
*/
|
|
238
|
+
export function getEmitFlags(node) {
|
|
239
|
+
const emitNode = node.emitNode;
|
|
240
|
+
return emitNode && emitNode.flags || 0;
|
|
241
|
+
}
|
|
242
|
+
export function getLiteralText(node, sourceFile, neverAsciiEscape, jsxAttributeEscape) {
|
|
243
|
+
// If we don't need to downlevel and we can reach the original source text using
|
|
244
|
+
// the node's parent reference, then simply get the text as it was originally written.
|
|
245
|
+
if (!nodeIsSynthesized(node) && node.parent && !((isNumericLiteral(node) && node.numericLiteralFlags & 512 /* TokenFlags.ContainsSeparator */) ||
|
|
246
|
+
isBigIntLiteral(node))) {
|
|
247
|
+
return getSourceTextOfNodeFromSourceFile(sourceFile, node);
|
|
248
|
+
}
|
|
249
|
+
// If we can't reach the original source text, use the canonical form if it's a number,
|
|
250
|
+
// or a (possibly escaped) quoted form of the original text if it's string-like.
|
|
251
|
+
switch (node.kind) {
|
|
252
|
+
case 10 /* SyntaxKind.StringLiteral */: {
|
|
253
|
+
const escapeText = jsxAttributeEscape ? escapeJsxAttributeString :
|
|
254
|
+
neverAsciiEscape || (getEmitFlags(node) & 16777216 /* EmitFlags.NoAsciiEscaping */) ? escapeString :
|
|
255
|
+
escapeNonAsciiString;
|
|
256
|
+
if (node.singleQuote) {
|
|
257
|
+
return "'" + escapeText(node.text, 39 /* CharacterCodes.singleQuote */) + "'";
|
|
258
|
+
}
|
|
259
|
+
else {
|
|
260
|
+
return '"' + escapeText(node.text, 34 /* CharacterCodes.doubleQuote */) + '"';
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
case 14 /* SyntaxKind.NoSubstitutionTemplateLiteral */:
|
|
264
|
+
case 15 /* SyntaxKind.TemplateHead */:
|
|
265
|
+
case 16 /* SyntaxKind.TemplateMiddle */:
|
|
266
|
+
case 17 /* SyntaxKind.TemplateTail */: {
|
|
267
|
+
// If a NoSubstitutionTemplateLiteral appears to have a substitution in it, the original text
|
|
268
|
+
// had to include a backslash: `not \${a} substitution`.
|
|
269
|
+
const escapeText = neverAsciiEscape || (getEmitFlags(node) & 16777216 /* EmitFlags.NoAsciiEscaping */) ? escapeString :
|
|
270
|
+
escapeNonAsciiString;
|
|
271
|
+
const rawText = node.rawText ?? escapeTemplateSubstitution(escapeText(node.text, 96 /* CharacterCodes.backtick */));
|
|
272
|
+
switch (node.kind) {
|
|
273
|
+
case 14 /* SyntaxKind.NoSubstitutionTemplateLiteral */:
|
|
274
|
+
return "`" + rawText + "`";
|
|
275
|
+
case 15 /* SyntaxKind.TemplateHead */:
|
|
276
|
+
return "`" + rawText + "${";
|
|
277
|
+
case 16 /* SyntaxKind.TemplateMiddle */:
|
|
278
|
+
return "}" + rawText + "${";
|
|
279
|
+
case 17 /* SyntaxKind.TemplateTail */:
|
|
280
|
+
return "}" + rawText + "`";
|
|
281
|
+
}
|
|
282
|
+
break;
|
|
283
|
+
}
|
|
284
|
+
case 8 /* SyntaxKind.NumericLiteral */:
|
|
285
|
+
case 9 /* SyntaxKind.BigIntLiteral */:
|
|
286
|
+
return node.text;
|
|
287
|
+
}
|
|
288
|
+
return Debug.fail(`Literal kind '${node.kind}' not accounted for.`);
|
|
289
|
+
}
|
|
290
|
+
// Make an identifier from an external module name by extracting the string after the last "/" and replacing
|
|
291
|
+
// all non-alphanumeric characters with underscores
|
|
292
|
+
export function makeIdentifierFromModuleName(moduleName) {
|
|
293
|
+
return getBaseFileName(moduleName).replace(/^(\d)/, "_$1").replace(/\W/g, "_");
|
|
294
|
+
}
|
|
295
|
+
export function isBlockOrCatchScoped(declaration) {
|
|
296
|
+
return (getCombinedNodeFlags(declaration) & 3 /* NodeFlags.BlockScoped */) !== 0 ||
|
|
297
|
+
isCatchClauseVariableDeclarationOrBindingElement(declaration);
|
|
298
|
+
}
|
|
299
|
+
export function isCatchClauseVariableDeclarationOrBindingElement(declaration) {
|
|
300
|
+
const node = getRootDeclaration(declaration);
|
|
301
|
+
return node.kind === 242 /* SyntaxKind.VariableDeclaration */ && node.parent.kind === 280 /* SyntaxKind.CatchClause */;
|
|
302
|
+
}
|
|
303
|
+
/** O módulo ambiente é só o `declare global`: o de nome em string (`declare module "x"`) saiu (CK-02, princípio 4). */
|
|
304
|
+
export function isAmbientModule(node) {
|
|
305
|
+
return isModuleDeclaration(node) && isGlobalScopeAugmentation(node);
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* An effective module (namespace) declaration is either
|
|
309
|
+
* 1. An actual declaration: namespace X { ... }
|
|
310
|
+
* 2. A Javascript declaration, which is:
|
|
311
|
+
* An identifier in a nested property access expression: Y in `X.Y.Z = { ... }`
|
|
312
|
+
*/
|
|
313
|
+
export function isEffectiveModuleDeclaration(node) {
|
|
314
|
+
return isModuleDeclaration(node) || isIdentifier(node);
|
|
315
|
+
}
|
|
316
|
+
export function isGlobalScopeAugmentation(module) {
|
|
317
|
+
return !!(module.flags & 1024 /* NodeFlags.GlobalAugmentation */);
|
|
318
|
+
}
|
|
319
|
+
export function isExternalModuleAugmentation(node) {
|
|
320
|
+
return isAmbientModule(node) && isModuleAugmentationExternal(node);
|
|
321
|
+
}
|
|
322
|
+
export function isModuleAugmentationExternal(node) {
|
|
323
|
+
// external module augmentation is a ambient module declaration that is either:
|
|
324
|
+
// - defined in the top level scope and source file is an external module
|
|
325
|
+
// - defined inside ambient module declaration located in the top level scope and source file not an external module
|
|
326
|
+
switch (node.parent.kind) {
|
|
327
|
+
case 290 /* SyntaxKind.SourceFile */:
|
|
328
|
+
return isExternalModule(node.parent);
|
|
329
|
+
case 250 /* SyntaxKind.ModuleBlock */:
|
|
330
|
+
return isAmbientModule(node.parent.parent) && isSourceFile(node.parent.parent.parent) && !isExternalModule(node.parent.parent.parent);
|
|
331
|
+
}
|
|
332
|
+
return false;
|
|
333
|
+
}
|
|
334
|
+
export function getNonAugmentationDeclaration(symbol) {
|
|
335
|
+
return find(symbol.declarations, d => !isExternalModuleAugmentation(d) && !(isModuleDeclaration(d) && isGlobalScopeAugmentation(d)));
|
|
336
|
+
}
|
|
337
|
+
export function isBlockScope(node, parentNode) {
|
|
338
|
+
switch (node.kind) {
|
|
339
|
+
case 290 /* SyntaxKind.SourceFile */:
|
|
340
|
+
case 251 /* SyntaxKind.CaseBlock */:
|
|
341
|
+
case 280 /* SyntaxKind.CatchClause */:
|
|
342
|
+
case 249 /* SyntaxKind.ModuleDeclaration */:
|
|
343
|
+
case 230 /* SyntaxKind.ForStatement */:
|
|
344
|
+
case 231 /* SyntaxKind.ForInStatement */:
|
|
345
|
+
case 232 /* SyntaxKind.ForOfStatement */:
|
|
346
|
+
case 202 /* SyntaxKind.ArrowFunction */:
|
|
347
|
+
return true;
|
|
348
|
+
case 223 /* SyntaxKind.Block */:
|
|
349
|
+
// function block is not considered block-scope container
|
|
350
|
+
// see comment in binder.ts: bind(...), case for SyntaxKind.Block
|
|
351
|
+
return !isFunctionLike(parentNode);
|
|
352
|
+
}
|
|
353
|
+
return false;
|
|
354
|
+
}
|
|
355
|
+
/** Na tag, também o callback, o typedef e a assinatura do JSDoc, que têm parâmetros de tipo sem filhos (CK-03). */
|
|
356
|
+
export function isDeclarationWithTypeParameters(node) {
|
|
357
|
+
return isDeclarationWithTypeParameterChildren(node);
|
|
358
|
+
}
|
|
359
|
+
export function isDeclarationWithTypeParameterChildren(node) {
|
|
360
|
+
Debug.type(node);
|
|
361
|
+
switch (node.kind) {
|
|
362
|
+
case 165 /* SyntaxKind.CallSignature */:
|
|
363
|
+
case 160 /* SyntaxKind.MethodSignature */:
|
|
364
|
+
case 167 /* SyntaxKind.IndexSignature */:
|
|
365
|
+
case 170 /* SyntaxKind.FunctionType */:
|
|
366
|
+
case 247 /* SyntaxKind.TypeAliasDeclaration */:
|
|
367
|
+
case 202 /* SyntaxKind.ArrowFunction */:
|
|
368
|
+
return true;
|
|
369
|
+
default:
|
|
370
|
+
assertType(node);
|
|
371
|
+
return false;
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
export function isAnyImportSyntax(node) {
|
|
375
|
+
switch (node.kind) {
|
|
376
|
+
case 254 /* SyntaxKind.ImportDeclaration */:
|
|
377
|
+
return true;
|
|
378
|
+
default:
|
|
379
|
+
return false;
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
export function isLateVisibilityPaintedStatement(node) {
|
|
383
|
+
switch (node.kind) {
|
|
384
|
+
case 254 /* SyntaxKind.ImportDeclaration */:
|
|
385
|
+
case 225 /* SyntaxKind.VariableStatement */:
|
|
386
|
+
case 249 /* SyntaxKind.ModuleDeclaration */:
|
|
387
|
+
case 247 /* SyntaxKind.TypeAliasDeclaration */:
|
|
388
|
+
return true;
|
|
389
|
+
default:
|
|
390
|
+
return false;
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
export function isAnyImportOrReExport(node) {
|
|
394
|
+
return isAnyImportSyntax(node) || isExportDeclaration(node);
|
|
395
|
+
}
|
|
396
|
+
// Gets the nearest enclosing block scope container that has the provided node
|
|
397
|
+
// as a descendant, that is not the provided node.
|
|
398
|
+
export function getEnclosingBlockScopeContainer(node) {
|
|
399
|
+
return findAncestor(node.parent, current => isBlockScope(current, current.parent));
|
|
400
|
+
}
|
|
401
|
+
// Return display name of an identifier
|
|
402
|
+
// Computed property names will just be emitted as "[<expr>]", where <expr> is the source
|
|
403
|
+
// text of the expression in the computed property.
|
|
404
|
+
export function declarationNameToString(name) {
|
|
405
|
+
return !name || getFullWidth(name) === 0 ? "(Missing)" : getTextOfNode(name);
|
|
406
|
+
}
|
|
407
|
+
export function isComputedNonLiteralName(name) {
|
|
408
|
+
return name.kind === 154 /* SyntaxKind.ComputedPropertyName */ && !isStringOrNumericLiteralLike(name.expression);
|
|
409
|
+
}
|
|
410
|
+
export function createDiagnosticForNode(node, message, arg0, arg1, arg2, arg3) {
|
|
411
|
+
const sourceFile = getSourceFileOfNode(node);
|
|
412
|
+
return createDiagnosticForNodeInSourceFile(sourceFile, node, message, arg0, arg1, arg2, arg3);
|
|
413
|
+
}
|
|
414
|
+
export function createDiagnosticForNodeArray(sourceFile, nodes, message, arg0, arg1, arg2, arg3) {
|
|
415
|
+
const start = skipTrivia(sourceFile.text, nodes.pos);
|
|
416
|
+
return createFileDiagnostic(sourceFile, start, nodes.end - start, message, arg0, arg1, arg2, arg3);
|
|
417
|
+
}
|
|
418
|
+
export function createDiagnosticForNodeInSourceFile(sourceFile, node, message, arg0, arg1, arg2, arg3) {
|
|
419
|
+
const span = getErrorSpanForNode(sourceFile, node);
|
|
420
|
+
return createFileDiagnostic(sourceFile, span.start, span.length, message, arg0, arg1, arg2, arg3);
|
|
421
|
+
}
|
|
422
|
+
export function createDiagnosticForNodeFromMessageChain(node, messageChain, relatedInformation) {
|
|
423
|
+
const sourceFile = getSourceFileOfNode(node);
|
|
424
|
+
const span = getErrorSpanForNode(sourceFile, node);
|
|
425
|
+
return {
|
|
426
|
+
file: sourceFile,
|
|
427
|
+
start: span.start,
|
|
428
|
+
length: span.length,
|
|
429
|
+
code: messageChain.code,
|
|
430
|
+
category: messageChain.category,
|
|
431
|
+
messageText: messageChain.next ? messageChain : messageChain.messageText,
|
|
432
|
+
relatedInformation
|
|
433
|
+
};
|
|
434
|
+
}
|
|
435
|
+
export function createDiagnosticForRange(sourceFile, range, message) {
|
|
436
|
+
return {
|
|
437
|
+
file: sourceFile,
|
|
438
|
+
start: range.pos,
|
|
439
|
+
length: range.end - range.pos,
|
|
440
|
+
code: message.code,
|
|
441
|
+
category: message.category,
|
|
442
|
+
messageText: message.message,
|
|
443
|
+
};
|
|
444
|
+
}
|
|
445
|
+
export function getSpanOfTokenAtPosition(sourceFile, pos) {
|
|
446
|
+
const scanner = createScanner(sourceFile.languageVersion, /*skipTrivia*/ true, sourceFile.languageVariant, sourceFile.text, /*onError:*/ undefined, pos);
|
|
447
|
+
scanner.scan();
|
|
448
|
+
const start = scanner.getTokenPos();
|
|
449
|
+
return createTextSpanFromBounds(start, scanner.getTextPos());
|
|
450
|
+
}
|
|
451
|
+
function getErrorSpanForArrowFunction(sourceFile, node) {
|
|
452
|
+
const pos = skipTrivia(sourceFile.text, node.pos);
|
|
453
|
+
if (node.body && node.body.kind === 223 /* SyntaxKind.Block */) {
|
|
454
|
+
const { line: startLine } = getLineAndCharacterOfPosition(sourceFile, node.body.pos);
|
|
455
|
+
const { line: endLine } = getLineAndCharacterOfPosition(sourceFile, node.body.end);
|
|
456
|
+
if (startLine < endLine) {
|
|
457
|
+
// The arrow function spans multiple lines,
|
|
458
|
+
// make the error span be the first line, inclusive.
|
|
459
|
+
return createTextSpan(pos, getEndLinePosition(startLine, sourceFile) - pos + 1);
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
return createTextSpanFromBounds(pos, node.end);
|
|
463
|
+
}
|
|
464
|
+
export function getErrorSpanForNode(sourceFile, node) {
|
|
465
|
+
let errorNode = node;
|
|
466
|
+
switch (node.kind) {
|
|
467
|
+
case 290 /* SyntaxKind.SourceFile */:
|
|
468
|
+
const pos = skipTrivia(sourceFile.text, 0, /*stopAfterLineBreak*/ false);
|
|
469
|
+
if (pos === sourceFile.text.length) {
|
|
470
|
+
// file is empty - return span for the beginning of the file
|
|
471
|
+
return createTextSpan(0, 0);
|
|
472
|
+
}
|
|
473
|
+
return getSpanOfTokenAtPosition(sourceFile, pos);
|
|
474
|
+
// This list is a work in progress. Add missing node kinds to improve their error
|
|
475
|
+
// spans.
|
|
476
|
+
case 242 /* SyntaxKind.VariableDeclaration */:
|
|
477
|
+
case 191 /* SyntaxKind.BindingElement */:
|
|
478
|
+
case 249 /* SyntaxKind.ModuleDeclaration */:
|
|
479
|
+
case 247 /* SyntaxKind.TypeAliasDeclaration */:
|
|
480
|
+
case 158 /* SyntaxKind.PropertySignature */:
|
|
481
|
+
errorNode = node.name;
|
|
482
|
+
break;
|
|
483
|
+
case 202 /* SyntaxKind.ArrowFunction */:
|
|
484
|
+
return getErrorSpanForArrowFunction(sourceFile, node);
|
|
485
|
+
case 277 /* SyntaxKind.CaseClause */:
|
|
486
|
+
case 278 /* SyntaxKind.DefaultClause */:
|
|
487
|
+
const start = skipTrivia(sourceFile.text, node.pos);
|
|
488
|
+
const end = node.statements.length > 0 ? node.statements[0].pos : node.end;
|
|
489
|
+
return createTextSpanFromBounds(start, end);
|
|
490
|
+
}
|
|
491
|
+
if (errorNode === undefined) {
|
|
492
|
+
// If we don't have a better node, then just set the error on the first token of
|
|
493
|
+
// construct.
|
|
494
|
+
return getSpanOfTokenAtPosition(sourceFile, node.pos);
|
|
495
|
+
}
|
|
496
|
+
const isMissing = nodeIsMissing(errorNode);
|
|
497
|
+
const pos = isMissing || isJsxText(node)
|
|
498
|
+
? errorNode.pos
|
|
499
|
+
: skipTrivia(sourceFile.text, errorNode.pos);
|
|
500
|
+
// These asserts should all be satisfied for a properly constructed `errorNode`.
|
|
501
|
+
if (isMissing) {
|
|
502
|
+
Debug.assert(pos === errorNode.pos, "This failure could trigger https://github.com/Microsoft/TypeScript/issues/20809");
|
|
503
|
+
Debug.assert(pos === errorNode.end, "This failure could trigger https://github.com/Microsoft/TypeScript/issues/20809");
|
|
504
|
+
}
|
|
505
|
+
else {
|
|
506
|
+
Debug.assert(pos >= errorNode.pos, "This failure could trigger https://github.com/Microsoft/TypeScript/issues/20809");
|
|
507
|
+
Debug.assert(pos <= errorNode.end, "This failure could trigger https://github.com/Microsoft/TypeScript/issues/20809");
|
|
508
|
+
}
|
|
509
|
+
return createTextSpanFromBounds(pos, errorNode.end);
|
|
510
|
+
}
|
|
511
|
+
export function isExternalOrCommonJsModule(file) {
|
|
512
|
+
return (file.externalModuleIndicator || file.commonJsModuleIndicator) !== undefined;
|
|
513
|
+
}
|
|
514
|
+
export function isJsonSourceFile(file) {
|
|
515
|
+
return file.scriptKind === 6 /* ScriptKind.JSON */;
|
|
516
|
+
}
|
|
517
|
+
export function isDeclarationReadonly(declaration) {
|
|
518
|
+
return !!(getCombinedModifierFlags(declaration) & 64 /* ModifierFlags.Readonly */);
|
|
519
|
+
}
|
|
520
|
+
export function isVarConst(node) {
|
|
521
|
+
return !!(getCombinedNodeFlags(node) & 2 /* NodeFlags.Const */);
|
|
522
|
+
}
|
|
523
|
+
export function isLet(node) {
|
|
524
|
+
return !!(getCombinedNodeFlags(node) & 1 /* NodeFlags.Let */);
|
|
525
|
+
}
|
|
526
|
+
export function isImportCall(n) {
|
|
527
|
+
return n.kind === 196 /* SyntaxKind.CallExpression */ && n.expression.kind === 96 /* SyntaxKind.ImportKeyword */;
|
|
528
|
+
}
|
|
529
|
+
export function isImportMeta(n) {
|
|
530
|
+
return isMetaProperty(n)
|
|
531
|
+
&& n.keywordToken === 96 /* SyntaxKind.ImportKeyword */
|
|
532
|
+
&& n.name.escapedText === "meta";
|
|
533
|
+
}
|
|
534
|
+
export function isLiteralImportTypeNode(n) {
|
|
535
|
+
return isImportTypeNode(n) && isLiteralTypeNode(n.argument) && isStringLiteral(n.argument.literal);
|
|
536
|
+
}
|
|
537
|
+
export function isPrologueDirective(node) {
|
|
538
|
+
return node.kind === 226 /* SyntaxKind.ExpressionStatement */
|
|
539
|
+
&& node.expression.kind === 10 /* SyntaxKind.StringLiteral */;
|
|
540
|
+
}
|
|
541
|
+
export function isCustomPrologue(node) {
|
|
542
|
+
return !!(getEmitFlags(node) & 1048576 /* EmitFlags.CustomPrologue */);
|
|
543
|
+
}
|
|
544
|
+
function isHoistedVariable(node) {
|
|
545
|
+
return isIdentifier(node.name)
|
|
546
|
+
&& !node.initializer;
|
|
547
|
+
}
|
|
548
|
+
export function isHoistedVariableStatement(node) {
|
|
549
|
+
return isCustomPrologue(node)
|
|
550
|
+
&& isVariableStatement(node)
|
|
551
|
+
&& every(node.declarationList.declarations, isHoistedVariable);
|
|
552
|
+
}
|
|
553
|
+
export function getLeadingCommentRangesOfNode(node, sourceFileOfNode) {
|
|
554
|
+
return node.kind !== 11 /* SyntaxKind.JsxText */ ? getLeadingCommentRanges(sourceFileOfNode.text, node.pos) : undefined;
|
|
555
|
+
}
|
|
556
|
+
const defaultLibReferenceRegEx = /^(\/\/\/\s*<reference\s+no-default-lib\s*=\s*)('|")(.+?)\2\s*\/>/;
|
|
557
|
+
export function isPartOfTypeNode(node) {
|
|
558
|
+
if (168 /* SyntaxKind.FirstTypeNode */ <= node.kind && node.kind <= 188 /* SyntaxKind.LastTypeNode */) {
|
|
559
|
+
return true;
|
|
560
|
+
}
|
|
561
|
+
switch (node.kind) {
|
|
562
|
+
case 125 /* SyntaxKind.AnyKeyword */:
|
|
563
|
+
case 148 /* SyntaxKind.UnknownKeyword */:
|
|
564
|
+
case 140 /* SyntaxKind.NumberKeyword */:
|
|
565
|
+
case 151 /* SyntaxKind.BigIntKeyword */:
|
|
566
|
+
case 143 /* SyntaxKind.StringKeyword */:
|
|
567
|
+
case 128 /* SyntaxKind.BooleanKeyword */:
|
|
568
|
+
case 141 /* SyntaxKind.ObjectKeyword */:
|
|
569
|
+
case 146 /* SyntaxKind.UndefinedKeyword */:
|
|
570
|
+
case 137 /* SyntaxKind.NeverKeyword */:
|
|
571
|
+
case 110 /* SyntaxKind.VoidKeyword */:
|
|
572
|
+
return true;
|
|
573
|
+
case 155 /* SyntaxKind.TypeParameter */:
|
|
574
|
+
return node.parent.kind === 186 /* SyntaxKind.MappedType */ || node.parent.kind === 181 /* SyntaxKind.InferType */;
|
|
575
|
+
// Identifiers and qualified names may be type nodes, depending on their context. Climb
|
|
576
|
+
// above them to find the lowest container
|
|
577
|
+
case 75 /* SyntaxKind.Identifier */:
|
|
578
|
+
// If the identifier is the RHS of a qualified name, then it's a type iff its parent is.
|
|
579
|
+
if (node.parent.kind === 153 /* SyntaxKind.QualifiedName */ && node.parent.right === node) {
|
|
580
|
+
node = node.parent;
|
|
581
|
+
}
|
|
582
|
+
else if (node.parent.kind === 194 /* SyntaxKind.PropertyAccessExpression */ && node.parent.name === node) {
|
|
583
|
+
node = node.parent;
|
|
584
|
+
}
|
|
585
|
+
// At this point, node is either a qualified name or an identifier
|
|
586
|
+
Debug.assert(node.kind === 75 /* SyntaxKind.Identifier */ || node.kind === 153 /* SyntaxKind.QualifiedName */ || node.kind === 194 /* SyntaxKind.PropertyAccessExpression */, "'node' was expected to be a qualified name, identifier or property access in 'isPartOfTypeNode'.");
|
|
587
|
+
// falls through
|
|
588
|
+
case 153 /* SyntaxKind.QualifiedName */:
|
|
589
|
+
case 194 /* SyntaxKind.PropertyAccessExpression */: {
|
|
590
|
+
const { parent } = node;
|
|
591
|
+
if (parent.kind === 172 /* SyntaxKind.TypeQuery */) {
|
|
592
|
+
return false;
|
|
593
|
+
}
|
|
594
|
+
if (parent.kind === 188 /* SyntaxKind.ImportType */) {
|
|
595
|
+
return !parent.isTypeOf;
|
|
596
|
+
}
|
|
597
|
+
// Do not recursively call isPartOfTypeNode on the parent. In the example:
|
|
598
|
+
//
|
|
599
|
+
// let a: A.B.C;
|
|
600
|
+
//
|
|
601
|
+
// Calling isPartOfTypeNode would consider the qualified name A.B a type node.
|
|
602
|
+
// Only C and A.B.C are type nodes.
|
|
603
|
+
if (168 /* SyntaxKind.FirstTypeNode */ <= parent.kind && parent.kind <= 188 /* SyntaxKind.LastTypeNode */) {
|
|
604
|
+
return true;
|
|
605
|
+
}
|
|
606
|
+
switch (parent.kind) {
|
|
607
|
+
case 155 /* SyntaxKind.TypeParameter */:
|
|
608
|
+
return node === parent.constraint;
|
|
609
|
+
case 158 /* SyntaxKind.PropertySignature */:
|
|
610
|
+
case 156 /* SyntaxKind.Parameter */:
|
|
611
|
+
case 242 /* SyntaxKind.VariableDeclaration */:
|
|
612
|
+
return node === parent.type;
|
|
613
|
+
case 202 /* SyntaxKind.ArrowFunction */:
|
|
614
|
+
return node === parent.type;
|
|
615
|
+
case 165 /* SyntaxKind.CallSignature */:
|
|
616
|
+
case 167 /* SyntaxKind.IndexSignature */:
|
|
617
|
+
return node === parent.type;
|
|
618
|
+
case 196 /* SyntaxKind.CallExpression */:
|
|
619
|
+
return contains(parent.typeArguments, node);
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
return false;
|
|
624
|
+
}
|
|
625
|
+
// Warning: This has the same semantics as the forEach family of functions,
|
|
626
|
+
// in that traversal terminates in the event that 'visitor' supplies a truthy value.
|
|
627
|
+
export function forEachReturnStatement(body, visitor) {
|
|
628
|
+
return traverse(body);
|
|
629
|
+
function traverse(node) {
|
|
630
|
+
switch (node.kind) {
|
|
631
|
+
case 235 /* SyntaxKind.ReturnStatement */:
|
|
632
|
+
return visitor(node);
|
|
633
|
+
case 251 /* SyntaxKind.CaseBlock */:
|
|
634
|
+
case 223 /* SyntaxKind.Block */:
|
|
635
|
+
case 227 /* SyntaxKind.IfStatement */:
|
|
636
|
+
case 228 /* SyntaxKind.DoStatement */:
|
|
637
|
+
case 229 /* SyntaxKind.WhileStatement */:
|
|
638
|
+
case 230 /* SyntaxKind.ForStatement */:
|
|
639
|
+
case 231 /* SyntaxKind.ForInStatement */:
|
|
640
|
+
case 232 /* SyntaxKind.ForOfStatement */:
|
|
641
|
+
case 237 /* SyntaxKind.SwitchStatement */:
|
|
642
|
+
case 277 /* SyntaxKind.CaseClause */:
|
|
643
|
+
case 278 /* SyntaxKind.DefaultClause */:
|
|
644
|
+
case 240 /* SyntaxKind.TryStatement */:
|
|
645
|
+
case 280 /* SyntaxKind.CatchClause */:
|
|
646
|
+
return forEachChild(node, traverse);
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
export function getMembersOfDeclaration(node) {
|
|
651
|
+
switch (node.kind) {
|
|
652
|
+
case 173 /* SyntaxKind.TypeLiteral */:
|
|
653
|
+
return node.members;
|
|
654
|
+
case 193 /* SyntaxKind.ObjectLiteralExpression */:
|
|
655
|
+
return node.properties;
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
export function isVariableLike(node) {
|
|
659
|
+
if (node) {
|
|
660
|
+
switch (node.kind) {
|
|
661
|
+
case 191 /* SyntaxKind.BindingElement */:
|
|
662
|
+
case 156 /* SyntaxKind.Parameter */:
|
|
663
|
+
case 281 /* SyntaxKind.PropertyAssignment */:
|
|
664
|
+
case 158 /* SyntaxKind.PropertySignature */:
|
|
665
|
+
case 282 /* SyntaxKind.ShorthandPropertyAssignment */:
|
|
666
|
+
case 242 /* SyntaxKind.VariableDeclaration */:
|
|
667
|
+
return true;
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
return false;
|
|
671
|
+
}
|
|
672
|
+
export function isFunctionBlock(node) {
|
|
673
|
+
return node && node.kind === 223 /* SyntaxKind.Block */ && isFunctionLike(node.parent);
|
|
674
|
+
}
|
|
675
|
+
export function getContainingFunction(node) {
|
|
676
|
+
return findAncestor(node.parent, isFunctionLike);
|
|
677
|
+
}
|
|
678
|
+
export function getContainingFunctionDeclaration(node) {
|
|
679
|
+
return findAncestor(node.parent, isFunctionLikeDeclaration);
|
|
680
|
+
}
|
|
681
|
+
export function getThisContainer(node, includeArrowFunctions) {
|
|
682
|
+
Debug.assert(node.kind !== 290 /* SyntaxKind.SourceFile */);
|
|
683
|
+
while (true) {
|
|
684
|
+
node = node.parent;
|
|
685
|
+
if (!node) {
|
|
686
|
+
return Debug.fail(); // If we never pass in a SourceFile, this should be unreachable, since we'll stop when we reach that.
|
|
687
|
+
}
|
|
688
|
+
switch (node.kind) {
|
|
689
|
+
case 154 /* SyntaxKind.ComputedPropertyName */:
|
|
690
|
+
// O pai de um nome computado é a propriedade que ele nomeia, e não é o contêiner.
|
|
691
|
+
node = node.parent;
|
|
692
|
+
break;
|
|
693
|
+
case 202 /* SyntaxKind.ArrowFunction */:
|
|
694
|
+
if (!includeArrowFunctions) {
|
|
695
|
+
continue;
|
|
696
|
+
}
|
|
697
|
+
// falls through
|
|
698
|
+
case 249 /* SyntaxKind.ModuleDeclaration */:
|
|
699
|
+
case 158 /* SyntaxKind.PropertySignature */:
|
|
700
|
+
case 165 /* SyntaxKind.CallSignature */:
|
|
701
|
+
case 167 /* SyntaxKind.IndexSignature */:
|
|
702
|
+
case 290 /* SyntaxKind.SourceFile */:
|
|
703
|
+
return node;
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
}
|
|
707
|
+
export function getImmediatelyInvokedFunctionExpression(func) {
|
|
708
|
+
if (func.kind === 202 /* SyntaxKind.ArrowFunction */) {
|
|
709
|
+
let prev = func;
|
|
710
|
+
let parent = func.parent;
|
|
711
|
+
while (parent.kind === 200 /* SyntaxKind.ParenthesizedExpression */) {
|
|
712
|
+
prev = parent;
|
|
713
|
+
parent = parent.parent;
|
|
714
|
+
}
|
|
715
|
+
if (parent.kind === 196 /* SyntaxKind.CallExpression */ && parent.expression === prev) {
|
|
716
|
+
return parent;
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
/** O nome de uma referência de tipo. Na tag, também o de um `extends` ou de um `implements` (CK-02). */
|
|
721
|
+
export function getEntityNameFromTypeNode(node) {
|
|
722
|
+
switch (node.kind) {
|
|
723
|
+
case 169 /* SyntaxKind.TypeReference */:
|
|
724
|
+
return node.typeName;
|
|
725
|
+
case 75 /* SyntaxKind.Identifier */:
|
|
726
|
+
case 153 /* SyntaxKind.QualifiedName */:
|
|
727
|
+
return node;
|
|
728
|
+
}
|
|
729
|
+
return undefined;
|
|
730
|
+
}
|
|
731
|
+
/** A expressão chamada: a de uma chamada, ou a tag de um elemento JSX. Na tag, também a de um template marcado (CK-02). */
|
|
732
|
+
export function getInvokedExpression(node) {
|
|
733
|
+
switch (node.kind) {
|
|
734
|
+
case 268 /* SyntaxKind.JsxOpeningElement */:
|
|
735
|
+
case 267 /* SyntaxKind.JsxSelfClosingElement */:
|
|
736
|
+
return node.tagName;
|
|
737
|
+
default:
|
|
738
|
+
return node.expression;
|
|
739
|
+
}
|
|
740
|
+
}
|
|
741
|
+
export function isJSXTagName(node) {
|
|
742
|
+
const { parent } = node;
|
|
743
|
+
if (parent.kind === 268 /* SyntaxKind.JsxOpeningElement */ ||
|
|
744
|
+
parent.kind === 267 /* SyntaxKind.JsxSelfClosingElement */ ||
|
|
745
|
+
parent.kind === 269 /* SyntaxKind.JsxClosingElement */) {
|
|
746
|
+
return parent.tagName === node;
|
|
747
|
+
}
|
|
748
|
+
return false;
|
|
749
|
+
}
|
|
750
|
+
export function isExpressionNode(node) {
|
|
751
|
+
switch (node.kind) {
|
|
752
|
+
case 100 /* SyntaxKind.NullKeyword */:
|
|
753
|
+
case 106 /* SyntaxKind.TrueKeyword */:
|
|
754
|
+
case 91 /* SyntaxKind.FalseKeyword */:
|
|
755
|
+
case 192 /* SyntaxKind.ArrayLiteralExpression */:
|
|
756
|
+
case 193 /* SyntaxKind.ObjectLiteralExpression */:
|
|
757
|
+
case 194 /* SyntaxKind.PropertyAccessExpression */:
|
|
758
|
+
case 195 /* SyntaxKind.ElementAccessExpression */:
|
|
759
|
+
case 196 /* SyntaxKind.CallExpression */:
|
|
760
|
+
case 217 /* SyntaxKind.AsExpression */:
|
|
761
|
+
case 200 /* SyntaxKind.ParenthesizedExpression */:
|
|
762
|
+
case 202 /* SyntaxKind.ArrowFunction */:
|
|
763
|
+
case 203 /* SyntaxKind.DeleteExpression */:
|
|
764
|
+
case 204 /* SyntaxKind.TypeOfExpression */:
|
|
765
|
+
case 207 /* SyntaxKind.PrefixUnaryExpression */:
|
|
766
|
+
case 208 /* SyntaxKind.PostfixUnaryExpression */:
|
|
767
|
+
case 209 /* SyntaxKind.BinaryExpression */:
|
|
768
|
+
case 210 /* SyntaxKind.ConditionalExpression */:
|
|
769
|
+
case 213 /* SyntaxKind.SpreadElement */:
|
|
770
|
+
case 211 /* SyntaxKind.TemplateExpression */:
|
|
771
|
+
case 215 /* SyntaxKind.OmittedExpression */:
|
|
772
|
+
case 266 /* SyntaxKind.JsxElement */:
|
|
773
|
+
case 267 /* SyntaxKind.JsxSelfClosingElement */:
|
|
774
|
+
case 270 /* SyntaxKind.JsxFragment */:
|
|
775
|
+
case 206 /* SyntaxKind.AwaitExpression */:
|
|
776
|
+
case 219 /* SyntaxKind.MetaProperty */:
|
|
777
|
+
return true;
|
|
778
|
+
case 153 /* SyntaxKind.QualifiedName */:
|
|
779
|
+
while (node.parent.kind === 153 /* SyntaxKind.QualifiedName */) {
|
|
780
|
+
node = node.parent;
|
|
781
|
+
}
|
|
782
|
+
return node.parent.kind === 172 /* SyntaxKind.TypeQuery */ || isJSXTagName(node);
|
|
783
|
+
case 75 /* SyntaxKind.Identifier */:
|
|
784
|
+
if (node.parent.kind === 172 /* SyntaxKind.TypeQuery */ || isJSXTagName(node)) {
|
|
785
|
+
return true;
|
|
786
|
+
}
|
|
787
|
+
// falls through
|
|
788
|
+
case 8 /* SyntaxKind.NumericLiteral */:
|
|
789
|
+
case 9 /* SyntaxKind.BigIntLiteral */:
|
|
790
|
+
case 10 /* SyntaxKind.StringLiteral */:
|
|
791
|
+
case 14 /* SyntaxKind.NoSubstitutionTemplateLiteral */:
|
|
792
|
+
return isInExpressionContext(node);
|
|
793
|
+
default:
|
|
794
|
+
return false;
|
|
795
|
+
}
|
|
796
|
+
}
|
|
797
|
+
export function isInExpressionContext(node) {
|
|
798
|
+
const { parent } = node;
|
|
799
|
+
switch (parent.kind) {
|
|
800
|
+
case 242 /* SyntaxKind.VariableDeclaration */:
|
|
801
|
+
case 156 /* SyntaxKind.Parameter */:
|
|
802
|
+
case 158 /* SyntaxKind.PropertySignature */:
|
|
803
|
+
case 281 /* SyntaxKind.PropertyAssignment */:
|
|
804
|
+
case 191 /* SyntaxKind.BindingElement */:
|
|
805
|
+
return parent.initializer === node;
|
|
806
|
+
case 226 /* SyntaxKind.ExpressionStatement */:
|
|
807
|
+
case 227 /* SyntaxKind.IfStatement */:
|
|
808
|
+
case 228 /* SyntaxKind.DoStatement */:
|
|
809
|
+
case 229 /* SyntaxKind.WhileStatement */:
|
|
810
|
+
case 235 /* SyntaxKind.ReturnStatement */:
|
|
811
|
+
case 237 /* SyntaxKind.SwitchStatement */:
|
|
812
|
+
case 277 /* SyntaxKind.CaseClause */:
|
|
813
|
+
case 239 /* SyntaxKind.ThrowStatement */:
|
|
814
|
+
return parent.expression === node;
|
|
815
|
+
case 230 /* SyntaxKind.ForStatement */:
|
|
816
|
+
const forStatement = parent;
|
|
817
|
+
return (forStatement.initializer === node && forStatement.initializer.kind !== 243 /* SyntaxKind.VariableDeclarationList */) ||
|
|
818
|
+
forStatement.condition === node ||
|
|
819
|
+
forStatement.incrementor === node;
|
|
820
|
+
case 231 /* SyntaxKind.ForInStatement */:
|
|
821
|
+
case 232 /* SyntaxKind.ForOfStatement */:
|
|
822
|
+
const forInStatement = parent;
|
|
823
|
+
return (forInStatement.initializer === node && forInStatement.initializer.kind !== 243 /* SyntaxKind.VariableDeclarationList */) ||
|
|
824
|
+
forInStatement.expression === node;
|
|
825
|
+
case 217 /* SyntaxKind.AsExpression */:
|
|
826
|
+
return node === parent.expression;
|
|
827
|
+
case 221 /* SyntaxKind.TemplateSpan */:
|
|
828
|
+
return node === parent.expression;
|
|
829
|
+
case 154 /* SyntaxKind.ComputedPropertyName */:
|
|
830
|
+
return node === parent.expression;
|
|
831
|
+
case 276 /* SyntaxKind.JsxExpression */:
|
|
832
|
+
case 275 /* SyntaxKind.JsxSpreadAttribute */:
|
|
833
|
+
case 283 /* SyntaxKind.SpreadAssignment */:
|
|
834
|
+
return true;
|
|
835
|
+
case 282 /* SyntaxKind.ShorthandPropertyAssignment */:
|
|
836
|
+
return parent.objectAssignmentInitializer === node;
|
|
837
|
+
default:
|
|
838
|
+
return isExpressionNode(parent);
|
|
839
|
+
}
|
|
840
|
+
}
|
|
841
|
+
export function isPartOfTypeQuery(node) {
|
|
842
|
+
while (node.kind === 153 /* SyntaxKind.QualifiedName */ || node.kind === 75 /* SyntaxKind.Identifier */) {
|
|
843
|
+
node = node.parent;
|
|
844
|
+
}
|
|
845
|
+
return node.kind === 172 /* SyntaxKind.TypeQuery */;
|
|
846
|
+
}
|
|
847
|
+
export function isSourceFileJS(file) {
|
|
848
|
+
return isInJSFile(file);
|
|
849
|
+
}
|
|
850
|
+
export function isInJSFile(node) {
|
|
851
|
+
return !!node && !!(node.flags & 131072 /* NodeFlags.JavaScriptFile */);
|
|
852
|
+
}
|
|
853
|
+
export function isRequireCall(callExpression, requireStringLiteralLikeArgument) {
|
|
854
|
+
if (callExpression.kind !== 196 /* SyntaxKind.CallExpression */) {
|
|
855
|
+
return false;
|
|
856
|
+
}
|
|
857
|
+
const { expression, arguments: args } = callExpression;
|
|
858
|
+
if (expression.kind !== 75 /* SyntaxKind.Identifier */ || expression.escapedText !== "require") {
|
|
859
|
+
return false;
|
|
860
|
+
}
|
|
861
|
+
if (args.length !== 1) {
|
|
862
|
+
return false;
|
|
863
|
+
}
|
|
864
|
+
const arg = args[0];
|
|
865
|
+
return !requireStringLiteralLikeArgument || isStringLiteralLike(arg);
|
|
866
|
+
}
|
|
867
|
+
export function isSingleOrDoubleQuote(charCode) {
|
|
868
|
+
return charCode === 39 /* CharacterCodes.singleQuote */ || charCode === 34 /* CharacterCodes.doubleQuote */;
|
|
869
|
+
}
|
|
870
|
+
export function isStringDoubleQuoted(str, sourceFile) {
|
|
871
|
+
return getSourceTextOfNodeFromSourceFile(sourceFile, str).charCodeAt(0) === 34 /* CharacterCodes.doubleQuote */;
|
|
872
|
+
}
|
|
873
|
+
export function isAssignmentDeclaration(decl) {
|
|
874
|
+
return isBinaryExpression(decl) || isAccessExpression(decl) || isIdentifier(decl) || isCallExpression(decl);
|
|
875
|
+
}
|
|
876
|
+
export function getEffectiveInitializer(node) {
|
|
877
|
+
return node.initializer;
|
|
878
|
+
}
|
|
879
|
+
/**
|
|
880
|
+
* Os inicializadores de expando reconhecidos: a arrow chamada na hora (`(() => {})()`), a arrow, o object literal vazio
|
|
881
|
+
* e, quando inicializa um protótipo, o object literal com membros.
|
|
882
|
+
*
|
|
883
|
+
* Devolve o inicializador, ou `undefined` se ele não for um desses.
|
|
884
|
+
*/
|
|
885
|
+
export function getExpandoInitializer(initializer, isPrototypeAssignment) {
|
|
886
|
+
if (isCallExpression(initializer)) {
|
|
887
|
+
const e = skipParentheses(initializer.expression);
|
|
888
|
+
return e.kind === 202 /* SyntaxKind.ArrowFunction */ ? initializer : undefined;
|
|
889
|
+
}
|
|
890
|
+
if (initializer.kind === 202 /* SyntaxKind.ArrowFunction */) {
|
|
891
|
+
return initializer;
|
|
892
|
+
}
|
|
893
|
+
if (isObjectLiteralExpression(initializer) && (initializer.properties.length === 0 || isPrototypeAssignment)) {
|
|
894
|
+
return initializer;
|
|
895
|
+
}
|
|
896
|
+
}
|
|
897
|
+
export function isDefaultedExpandoInitializer(node) {
|
|
898
|
+
const name = isVariableDeclaration(node.parent) ? node.parent.name :
|
|
899
|
+
isBinaryExpression(node.parent) && node.parent.operatorToken.kind === 62 /* SyntaxKind.EqualsToken */ ? node.parent.left :
|
|
900
|
+
undefined;
|
|
901
|
+
return name && getExpandoInitializer(node.right, isPrototypeAccess(name)) && isEntityNameExpression(name) && isSameEntityName(name, node.left);
|
|
902
|
+
}
|
|
903
|
+
/**
|
|
904
|
+
* Is the 'declared' name the same as the one in the initializer?
|
|
905
|
+
* @return true for identical entity names, as well as ones where the initializer is prefixed with
|
|
906
|
+
* 'window', 'self' or 'global'. For example:
|
|
907
|
+
*
|
|
908
|
+
* var my = my || {}
|
|
909
|
+
* var min = window.min || {}
|
|
910
|
+
* my.app = self.my.app || class { }
|
|
911
|
+
*/
|
|
912
|
+
function isSameEntityName(name, initializer) {
|
|
913
|
+
if (isPropertyNameLiteral(name) && isPropertyNameLiteral(initializer)) {
|
|
914
|
+
return getTextOfIdentifierOrLiteral(name) === getTextOfIdentifierOrLiteral(name);
|
|
915
|
+
}
|
|
916
|
+
if (isIdentifier(name) && isLiteralLikeAccess(initializer) &&
|
|
917
|
+
isIdentifier(initializer.expression) &&
|
|
918
|
+
(initializer.expression.escapedText === "window" ||
|
|
919
|
+
initializer.expression.escapedText === "self" ||
|
|
920
|
+
initializer.expression.escapedText === "global")) {
|
|
921
|
+
return isSameEntityName(name, getNameOrArgument(initializer));
|
|
922
|
+
}
|
|
923
|
+
if (isLiteralLikeAccess(name) && isLiteralLikeAccess(initializer)) {
|
|
924
|
+
return getElementOrPropertyAccessName(name) === getElementOrPropertyAccessName(initializer)
|
|
925
|
+
&& isSameEntityName(name.expression, initializer.expression);
|
|
926
|
+
}
|
|
927
|
+
return false;
|
|
928
|
+
}
|
|
929
|
+
export function isExportsIdentifier(node) {
|
|
930
|
+
return isIdentifier(node) && node.escapedText === "exports";
|
|
931
|
+
}
|
|
932
|
+
export function isModuleIdentifier(node) {
|
|
933
|
+
return isIdentifier(node) && node.escapedText === "module";
|
|
934
|
+
}
|
|
935
|
+
export function isModuleExportsAccessExpression(node) {
|
|
936
|
+
return (isPropertyAccessExpression(node) || isLiteralLikeElementAccess(node))
|
|
937
|
+
&& isModuleIdentifier(node.expression)
|
|
938
|
+
&& getElementOrPropertyAccessName(node) === "exports";
|
|
939
|
+
}
|
|
940
|
+
/// Given a BinaryExpression, returns SpecialPropertyAssignmentKind for the various kinds of property
|
|
941
|
+
/// assignments we treat as special in the binder
|
|
942
|
+
export function getAssignmentDeclarationKind(expr) {
|
|
943
|
+
const special = getAssignmentDeclarationKindWorker(expr);
|
|
944
|
+
return special === 4 /* AssignmentDeclarationKind.Property */ ? special : 0 /* AssignmentDeclarationKind.None */;
|
|
945
|
+
}
|
|
946
|
+
export function isBindableObjectDefinePropertyCall(expr) {
|
|
947
|
+
return length(expr.arguments) === 3 &&
|
|
948
|
+
isPropertyAccessExpression(expr.expression) &&
|
|
949
|
+
isIdentifier(expr.expression.expression) &&
|
|
950
|
+
idText(expr.expression.expression) === "Object" &&
|
|
951
|
+
idText(expr.expression.name) === "defineProperty" &&
|
|
952
|
+
isStringOrNumericLiteralLike(expr.arguments[1]) &&
|
|
953
|
+
isBindableStaticNameExpression(expr.arguments[0]);
|
|
954
|
+
}
|
|
955
|
+
/** x.y OR x[0] */
|
|
956
|
+
export function isLiteralLikeAccess(node) {
|
|
957
|
+
return isPropertyAccessExpression(node) || isLiteralLikeElementAccess(node);
|
|
958
|
+
}
|
|
959
|
+
/** x[0] OR x['a'] OR x[Symbol.y] */
|
|
960
|
+
export function isLiteralLikeElementAccess(node) {
|
|
961
|
+
return isElementAccessExpression(node) && (isStringOrNumericLiteralLike(node.argumentExpression) ||
|
|
962
|
+
isWellKnownSymbolSyntactically(node.argumentExpression));
|
|
963
|
+
}
|
|
964
|
+
/** Any series of property and element accesses. */
|
|
965
|
+
export function isBindableStaticAccessExpression(node) {
|
|
966
|
+
return isPropertyAccessExpression(node) && isIdentifier(node.name) && isBindableStaticNameExpression(node.expression)
|
|
967
|
+
|| isBindableStaticElementAccessExpression(node);
|
|
968
|
+
}
|
|
969
|
+
/** Any series of property and element accesses, ending in a literal element access */
|
|
970
|
+
export function isBindableStaticElementAccessExpression(node) {
|
|
971
|
+
return isLiteralLikeElementAccess(node)
|
|
972
|
+
&& (isEntityNameExpression(node.expression) ||
|
|
973
|
+
isBindableStaticAccessExpression(node.expression));
|
|
974
|
+
}
|
|
975
|
+
export function isBindableStaticNameExpression(node) {
|
|
976
|
+
return isEntityNameExpression(node) || isBindableStaticAccessExpression(node);
|
|
977
|
+
}
|
|
978
|
+
export function getNameOrArgument(expr) {
|
|
979
|
+
if (isPropertyAccessExpression(expr)) {
|
|
980
|
+
return expr.name;
|
|
981
|
+
}
|
|
982
|
+
return expr.argumentExpression;
|
|
983
|
+
}
|
|
984
|
+
function getAssignmentDeclarationKindWorker(expr) {
|
|
985
|
+
if (isCallExpression(expr)) {
|
|
986
|
+
if (!isBindableObjectDefinePropertyCall(expr)) {
|
|
987
|
+
return 0 /* AssignmentDeclarationKind.None */;
|
|
988
|
+
}
|
|
989
|
+
const entityName = expr.arguments[0];
|
|
990
|
+
if (isExportsIdentifier(entityName) || isModuleExportsAccessExpression(entityName)) {
|
|
991
|
+
return 7 /* AssignmentDeclarationKind.ObjectDefinePropertyExports */;
|
|
992
|
+
}
|
|
993
|
+
if (isBindableStaticAccessExpression(entityName) && getElementOrPropertyAccessName(entityName) === "prototype") {
|
|
994
|
+
return 8 /* AssignmentDeclarationKind.ObjectDefinePrototypeProperty */;
|
|
995
|
+
}
|
|
996
|
+
return 6 /* AssignmentDeclarationKind.ObjectDefinePropertyValue */;
|
|
997
|
+
}
|
|
998
|
+
if (expr.operatorToken.kind !== 62 /* SyntaxKind.EqualsToken */ || !isAccessExpression(expr.left)) {
|
|
999
|
+
return 0 /* AssignmentDeclarationKind.None */;
|
|
1000
|
+
}
|
|
1001
|
+
if (isBindableStaticNameExpression(expr.left.expression) && getElementOrPropertyAccessName(expr.left) === "prototype" && isObjectLiteralExpression(getInitializerOfBinaryExpression(expr))) {
|
|
1002
|
+
// F.prototype = { ... }
|
|
1003
|
+
return 5 /* AssignmentDeclarationKind.Prototype */;
|
|
1004
|
+
}
|
|
1005
|
+
return getAssignmentDeclarationPropertyAccessKind(expr.left);
|
|
1006
|
+
}
|
|
1007
|
+
/**
|
|
1008
|
+
* Does not handle signed numeric names like `a[+0]` - handling those would require handling prefix unary expressions
|
|
1009
|
+
* throughout late binding handling as well, which is awkward (but ultimately probably doable if there is demand)
|
|
1010
|
+
*/
|
|
1011
|
+
export function getElementOrPropertyAccessArgumentExpressionOrName(node) {
|
|
1012
|
+
if (isPropertyAccessExpression(node)) {
|
|
1013
|
+
return node.name;
|
|
1014
|
+
}
|
|
1015
|
+
const arg = skipParentheses(node.argumentExpression);
|
|
1016
|
+
if (isNumericLiteral(arg) || isStringLiteralLike(arg)) {
|
|
1017
|
+
return arg;
|
|
1018
|
+
}
|
|
1019
|
+
return node;
|
|
1020
|
+
}
|
|
1021
|
+
export function getElementOrPropertyAccessName(node) {
|
|
1022
|
+
const name = getElementOrPropertyAccessArgumentExpressionOrName(node);
|
|
1023
|
+
if (name) {
|
|
1024
|
+
if (isIdentifier(name)) {
|
|
1025
|
+
return name.escapedText;
|
|
1026
|
+
}
|
|
1027
|
+
if (isStringLiteralLike(name) || isNumericLiteral(name)) {
|
|
1028
|
+
return escapeLeadingUnderscores(name.text);
|
|
1029
|
+
}
|
|
1030
|
+
}
|
|
1031
|
+
if (isElementAccessExpression(node) && isWellKnownSymbolSyntactically(node.argumentExpression)) {
|
|
1032
|
+
return getPropertyNameForKnownSymbolName(idText(node.argumentExpression.name));
|
|
1033
|
+
}
|
|
1034
|
+
return undefined;
|
|
1035
|
+
}
|
|
1036
|
+
export function getAssignmentDeclarationPropertyAccessKind(lhs) {
|
|
1037
|
+
if (isModuleExportsAccessExpression(lhs)) {
|
|
1038
|
+
// module.exports = expr
|
|
1039
|
+
return 2 /* AssignmentDeclarationKind.ModuleExports */;
|
|
1040
|
+
}
|
|
1041
|
+
else if (isBindableStaticNameExpression(lhs.expression)) {
|
|
1042
|
+
if (isPrototypeAccess(lhs.expression)) {
|
|
1043
|
+
// F.G....prototype.x = expr
|
|
1044
|
+
return 3 /* AssignmentDeclarationKind.PrototypeProperty */;
|
|
1045
|
+
}
|
|
1046
|
+
let nextToLast = lhs;
|
|
1047
|
+
while (!isIdentifier(nextToLast.expression)) {
|
|
1048
|
+
nextToLast = nextToLast.expression;
|
|
1049
|
+
}
|
|
1050
|
+
const id = nextToLast.expression;
|
|
1051
|
+
if ((id.escapedText === "exports" ||
|
|
1052
|
+
id.escapedText === "module" && getElementOrPropertyAccessName(nextToLast) === "exports") &&
|
|
1053
|
+
// ExportsProperty does not support binding with computed names
|
|
1054
|
+
isBindableStaticAccessExpression(lhs)) {
|
|
1055
|
+
// exports.name = expr OR module.exports.name = expr OR exports["name"] = expr ...
|
|
1056
|
+
return 1 /* AssignmentDeclarationKind.ExportsProperty */;
|
|
1057
|
+
}
|
|
1058
|
+
if (isBindableStaticNameExpression(lhs) || (isElementAccessExpression(lhs) && isDynamicName(lhs))) {
|
|
1059
|
+
// F.G...x = expr
|
|
1060
|
+
return 4 /* AssignmentDeclarationKind.Property */;
|
|
1061
|
+
}
|
|
1062
|
+
}
|
|
1063
|
+
return 0 /* AssignmentDeclarationKind.None */;
|
|
1064
|
+
}
|
|
1065
|
+
export function getInitializerOfBinaryExpression(expr) {
|
|
1066
|
+
while (isBinaryExpression(expr.right)) {
|
|
1067
|
+
expr = expr.right;
|
|
1068
|
+
}
|
|
1069
|
+
return expr.right;
|
|
1070
|
+
}
|
|
1071
|
+
export function setValueDeclaration(symbol, node) {
|
|
1072
|
+
const { valueDeclaration } = symbol;
|
|
1073
|
+
if (!valueDeclaration ||
|
|
1074
|
+
!(node.flags & 8388608 /* NodeFlags.Ambient */ && !(valueDeclaration.flags & 8388608 /* NodeFlags.Ambient */)) &&
|
|
1075
|
+
(isAssignmentDeclaration(valueDeclaration) && !isAssignmentDeclaration(node)) ||
|
|
1076
|
+
(valueDeclaration.kind !== node.kind && isEffectiveModuleDeclaration(valueDeclaration))) {
|
|
1077
|
+
// other kinds of value declarations take precedence over modules and assignment declarations
|
|
1078
|
+
symbol.valueDeclaration = node;
|
|
1079
|
+
}
|
|
1080
|
+
}
|
|
1081
|
+
export function importFromModuleSpecifier(node) {
|
|
1082
|
+
return tryGetImportFromModuleSpecifier(node) || Debug.failBadSyntaxKind(node.parent);
|
|
1083
|
+
}
|
|
1084
|
+
export function tryGetImportFromModuleSpecifier(node) {
|
|
1085
|
+
switch (node.parent.kind) {
|
|
1086
|
+
case 254 /* SyntaxKind.ImportDeclaration */:
|
|
1087
|
+
case 260 /* SyntaxKind.ExportDeclaration */:
|
|
1088
|
+
return node.parent;
|
|
1089
|
+
// Na tag, também o `require` do `import =` (CK-03).
|
|
1090
|
+
case 196 /* SyntaxKind.CallExpression */:
|
|
1091
|
+
return isImportCall(node.parent) || isRequireCall(node.parent, /*checkArg*/ false) ? node.parent : undefined;
|
|
1092
|
+
case 187 /* SyntaxKind.LiteralType */:
|
|
1093
|
+
Debug.assert(isStringLiteral(node));
|
|
1094
|
+
return tryCast(node.parent.parent, isImportTypeNode);
|
|
1095
|
+
default:
|
|
1096
|
+
return undefined;
|
|
1097
|
+
}
|
|
1098
|
+
}
|
|
1099
|
+
export function getExternalModuleName(node) {
|
|
1100
|
+
switch (node.kind) {
|
|
1101
|
+
case 254 /* SyntaxKind.ImportDeclaration */:
|
|
1102
|
+
case 260 /* SyntaxKind.ExportDeclaration */:
|
|
1103
|
+
return node.moduleSpecifier;
|
|
1104
|
+
case 188 /* SyntaxKind.ImportType */:
|
|
1105
|
+
return isLiteralImportTypeNode(node) ? node.argument.literal : undefined;
|
|
1106
|
+
default:
|
|
1107
|
+
return Debug.assertNever(node);
|
|
1108
|
+
}
|
|
1109
|
+
}
|
|
1110
|
+
/** Na tag, também o `import =` (CK-03), que nunca é import default. */
|
|
1111
|
+
export function isDefaultImport(node) {
|
|
1112
|
+
return node.kind === 254 /* SyntaxKind.ImportDeclaration */ && !!node.importClause && !!node.importClause.name;
|
|
1113
|
+
}
|
|
1114
|
+
export function hasQuestionToken(node) {
|
|
1115
|
+
if (node) {
|
|
1116
|
+
switch (node.kind) {
|
|
1117
|
+
case 156 /* SyntaxKind.Parameter */:
|
|
1118
|
+
case 282 /* SyntaxKind.ShorthandPropertyAssignment */:
|
|
1119
|
+
case 281 /* SyntaxKind.PropertyAssignment */:
|
|
1120
|
+
case 158 /* SyntaxKind.PropertySignature */:
|
|
1121
|
+
return node.questionToken !== undefined;
|
|
1122
|
+
}
|
|
1123
|
+
}
|
|
1124
|
+
return false;
|
|
1125
|
+
}
|
|
1126
|
+
/** Na tag, também o inicializador de uma propriedade de classe (CK-02). */
|
|
1127
|
+
export function getSingleInitializerOfVariableStatementOrPropertyDeclaration(node) {
|
|
1128
|
+
switch (node.kind) {
|
|
1129
|
+
case 225 /* SyntaxKind.VariableStatement */:
|
|
1130
|
+
const v = getSingleVariableOfVariableStatement(node);
|
|
1131
|
+
return v && v.initializer;
|
|
1132
|
+
case 281 /* SyntaxKind.PropertyAssignment */:
|
|
1133
|
+
return node.initializer;
|
|
1134
|
+
}
|
|
1135
|
+
}
|
|
1136
|
+
function getSingleVariableOfVariableStatement(node) {
|
|
1137
|
+
return isVariableStatement(node) ? firstOrUndefined(node.declarationList.declarations) : undefined;
|
|
1138
|
+
}
|
|
1139
|
+
export function hasRestParameter(s) {
|
|
1140
|
+
const last = lastOrUndefined(s.parameters);
|
|
1141
|
+
return !!last && isRestParameter(last);
|
|
1142
|
+
}
|
|
1143
|
+
export function isRestParameter(node) {
|
|
1144
|
+
return node.dotDotDotToken !== undefined;
|
|
1145
|
+
}
|
|
1146
|
+
export var AssignmentKind;
|
|
1147
|
+
(function (AssignmentKind) {
|
|
1148
|
+
AssignmentKind[AssignmentKind["None"] = 0] = "None";
|
|
1149
|
+
AssignmentKind[AssignmentKind["Definite"] = 1] = "Definite";
|
|
1150
|
+
AssignmentKind[AssignmentKind["Compound"] = 2] = "Compound";
|
|
1151
|
+
})(AssignmentKind || (AssignmentKind = {}));
|
|
1152
|
+
export function getAssignmentTargetKind(node) {
|
|
1153
|
+
let parent = node.parent;
|
|
1154
|
+
while (true) {
|
|
1155
|
+
switch (parent.kind) {
|
|
1156
|
+
case 209 /* SyntaxKind.BinaryExpression */:
|
|
1157
|
+
const binaryOperator = parent.operatorToken.kind;
|
|
1158
|
+
return isAssignmentOperator(binaryOperator) && parent.left === node ?
|
|
1159
|
+
binaryOperator === 62 /* SyntaxKind.EqualsToken */ ? 1 /* AssignmentKind.Definite */ : 2 /* AssignmentKind.Compound */ :
|
|
1160
|
+
0 /* AssignmentKind.None */;
|
|
1161
|
+
case 207 /* SyntaxKind.PrefixUnaryExpression */:
|
|
1162
|
+
case 208 /* SyntaxKind.PostfixUnaryExpression */:
|
|
1163
|
+
const unaryOperator = parent.operator;
|
|
1164
|
+
return unaryOperator === 45 /* SyntaxKind.PlusPlusToken */ || unaryOperator === 46 /* SyntaxKind.MinusMinusToken */ ? 2 /* AssignmentKind.Compound */ : 0 /* AssignmentKind.None */;
|
|
1165
|
+
case 231 /* SyntaxKind.ForInStatement */:
|
|
1166
|
+
case 232 /* SyntaxKind.ForOfStatement */:
|
|
1167
|
+
return parent.initializer === node ? 1 /* AssignmentKind.Definite */ : 0 /* AssignmentKind.None */;
|
|
1168
|
+
case 200 /* SyntaxKind.ParenthesizedExpression */:
|
|
1169
|
+
case 192 /* SyntaxKind.ArrayLiteralExpression */:
|
|
1170
|
+
case 213 /* SyntaxKind.SpreadElement */:
|
|
1171
|
+
node = parent;
|
|
1172
|
+
break;
|
|
1173
|
+
case 282 /* SyntaxKind.ShorthandPropertyAssignment */:
|
|
1174
|
+
if (parent.name !== node) {
|
|
1175
|
+
return 0 /* AssignmentKind.None */;
|
|
1176
|
+
}
|
|
1177
|
+
node = parent.parent;
|
|
1178
|
+
break;
|
|
1179
|
+
case 281 /* SyntaxKind.PropertyAssignment */:
|
|
1180
|
+
if (parent.name === node) {
|
|
1181
|
+
return 0 /* AssignmentKind.None */;
|
|
1182
|
+
}
|
|
1183
|
+
node = parent.parent;
|
|
1184
|
+
break;
|
|
1185
|
+
default:
|
|
1186
|
+
return 0 /* AssignmentKind.None */;
|
|
1187
|
+
}
|
|
1188
|
+
parent = node.parent;
|
|
1189
|
+
}
|
|
1190
|
+
}
|
|
1191
|
+
// A node is an assignment target if it is on the left hand side of an '=' token, if it is parented by a property
|
|
1192
|
+
// assignment in an object literal that is an assignment target, or if it is parented by an array literal that is
|
|
1193
|
+
// an assignment target. Examples include 'a = xxx', '{ p: a } = xxx', '[{ a }] = xxx'.
|
|
1194
|
+
// (Note that `p` is not a target in the above examples, only `a`.)
|
|
1195
|
+
export function isAssignmentTarget(node) {
|
|
1196
|
+
return getAssignmentTargetKind(node) !== 0 /* AssignmentKind.None */;
|
|
1197
|
+
}
|
|
1198
|
+
function walkUp(node, kind) {
|
|
1199
|
+
while (node && node.kind === kind) {
|
|
1200
|
+
node = node.parent;
|
|
1201
|
+
}
|
|
1202
|
+
return node;
|
|
1203
|
+
}
|
|
1204
|
+
export function walkUpParenthesizedExpressions(node) {
|
|
1205
|
+
return walkUp(node, 200 /* SyntaxKind.ParenthesizedExpression */);
|
|
1206
|
+
}
|
|
1207
|
+
export function skipParentheses(node) {
|
|
1208
|
+
return skipOuterExpressions(node, 1 /* OuterExpressionKinds.Parentheses */);
|
|
1209
|
+
}
|
|
1210
|
+
function skipParenthesesUp(node) {
|
|
1211
|
+
while (node.kind === 200 /* SyntaxKind.ParenthesizedExpression */) {
|
|
1212
|
+
node = node.parent;
|
|
1213
|
+
}
|
|
1214
|
+
return node;
|
|
1215
|
+
}
|
|
1216
|
+
// a node is delete target iff. it is PropertyAccessExpression/ElementAccessExpression with parentheses skipped
|
|
1217
|
+
export function isDeleteTarget(node) {
|
|
1218
|
+
if (node.kind !== 194 /* SyntaxKind.PropertyAccessExpression */ && node.kind !== 195 /* SyntaxKind.ElementAccessExpression */) {
|
|
1219
|
+
return false;
|
|
1220
|
+
}
|
|
1221
|
+
node = walkUpParenthesizedExpressions(node.parent);
|
|
1222
|
+
return node && node.kind === 203 /* SyntaxKind.DeleteExpression */;
|
|
1223
|
+
}
|
|
1224
|
+
export function isNodeDescendantOf(node, ancestor) {
|
|
1225
|
+
while (node) {
|
|
1226
|
+
if (node === ancestor)
|
|
1227
|
+
return true;
|
|
1228
|
+
node = node.parent;
|
|
1229
|
+
}
|
|
1230
|
+
return false;
|
|
1231
|
+
}
|
|
1232
|
+
// True if `name` is the name of a declaration node
|
|
1233
|
+
export function isDeclarationName(name) {
|
|
1234
|
+
return !isSourceFile(name) && !isBindingPattern(name) && isDeclaration(name.parent) && name.parent.name === name;
|
|
1235
|
+
}
|
|
1236
|
+
/**
|
|
1237
|
+
* A declaração de que o nome é o nome. Na tag, também o parâmetro do JSDoc num nome qualificado (CK-03) e o nome
|
|
1238
|
+
* `#private` (CK-02).
|
|
1239
|
+
*/
|
|
1240
|
+
export function getDeclarationFromName(name) {
|
|
1241
|
+
const parent = name.parent;
|
|
1242
|
+
switch (name.kind) {
|
|
1243
|
+
case 10 /* SyntaxKind.StringLiteral */:
|
|
1244
|
+
case 14 /* SyntaxKind.NoSubstitutionTemplateLiteral */:
|
|
1245
|
+
case 8 /* SyntaxKind.NumericLiteral */:
|
|
1246
|
+
if (isComputedPropertyName(parent))
|
|
1247
|
+
return parent.parent;
|
|
1248
|
+
// falls through
|
|
1249
|
+
case 75 /* SyntaxKind.Identifier */:
|
|
1250
|
+
if (isDeclaration(parent)) {
|
|
1251
|
+
return parent.name === name ? parent : undefined;
|
|
1252
|
+
}
|
|
1253
|
+
else if (isQualifiedName(parent)) {
|
|
1254
|
+
return undefined;
|
|
1255
|
+
}
|
|
1256
|
+
else {
|
|
1257
|
+
const binExp = parent.parent;
|
|
1258
|
+
return isBinaryExpression(binExp) &&
|
|
1259
|
+
getAssignmentDeclarationKind(binExp) !== 0 /* AssignmentDeclarationKind.None */ &&
|
|
1260
|
+
(binExp.left.symbol || binExp.symbol) &&
|
|
1261
|
+
getNameOfDeclaration(binExp) === name
|
|
1262
|
+
? binExp
|
|
1263
|
+
: undefined;
|
|
1264
|
+
}
|
|
1265
|
+
default:
|
|
1266
|
+
return undefined;
|
|
1267
|
+
}
|
|
1268
|
+
}
|
|
1269
|
+
export function isLiteralComputedPropertyDeclarationName(node) {
|
|
1270
|
+
return isStringOrNumericLiteralLike(node) &&
|
|
1271
|
+
node.parent.kind === 154 /* SyntaxKind.ComputedPropertyName */ &&
|
|
1272
|
+
isDeclaration(node.parent.parent);
|
|
1273
|
+
}
|
|
1274
|
+
// Return true if the given identifier is classified as an IdentifierName
|
|
1275
|
+
export function isIdentifierName(node) {
|
|
1276
|
+
let parent = node.parent;
|
|
1277
|
+
switch (parent.kind) {
|
|
1278
|
+
case 158 /* SyntaxKind.PropertySignature */:
|
|
1279
|
+
case 281 /* SyntaxKind.PropertyAssignment */:
|
|
1280
|
+
case 194 /* SyntaxKind.PropertyAccessExpression */:
|
|
1281
|
+
// Name in member declaration or property name in property access
|
|
1282
|
+
return parent.name === node;
|
|
1283
|
+
case 153 /* SyntaxKind.QualifiedName */:
|
|
1284
|
+
// Name on right hand side of dot in a type query or type reference
|
|
1285
|
+
if (parent.right === node) {
|
|
1286
|
+
while (parent.kind === 153 /* SyntaxKind.QualifiedName */) {
|
|
1287
|
+
parent = parent.parent;
|
|
1288
|
+
}
|
|
1289
|
+
return parent.kind === 172 /* SyntaxKind.TypeQuery */ || parent.kind === 169 /* SyntaxKind.TypeReference */;
|
|
1290
|
+
}
|
|
1291
|
+
return false;
|
|
1292
|
+
case 191 /* SyntaxKind.BindingElement */:
|
|
1293
|
+
case 258 /* SyntaxKind.ImportSpecifier */:
|
|
1294
|
+
// Property name in binding element or import specifier
|
|
1295
|
+
return parent.propertyName === node;
|
|
1296
|
+
case 263 /* SyntaxKind.ExportSpecifier */:
|
|
1297
|
+
case 273 /* SyntaxKind.JsxAttribute */:
|
|
1298
|
+
// Any name in an export specifier or JSX Attribute
|
|
1299
|
+
return true;
|
|
1300
|
+
}
|
|
1301
|
+
return false;
|
|
1302
|
+
}
|
|
1303
|
+
/**
|
|
1304
|
+
* A declaração que cria um símbolo alias: `import x from`, `import * as x from`, `import { a as x } from`,
|
|
1305
|
+
* `export { a as x }`, `export * as x from`, `export default` de um nome, e o shorthand e a propriedade de objeto cujo
|
|
1306
|
+
* valor é um nome.
|
|
1307
|
+
*/
|
|
1308
|
+
export function isAliasSymbolDeclaration(node) {
|
|
1309
|
+
return node.kind === 255 /* SyntaxKind.ImportClause */ && !!node.name ||
|
|
1310
|
+
node.kind === 256 /* SyntaxKind.NamespaceImport */ ||
|
|
1311
|
+
node.kind === 262 /* SyntaxKind.NamespaceExport */ ||
|
|
1312
|
+
node.kind === 258 /* SyntaxKind.ImportSpecifier */ ||
|
|
1313
|
+
node.kind === 263 /* SyntaxKind.ExportSpecifier */ ||
|
|
1314
|
+
node.kind === 259 /* SyntaxKind.ExportAssignment */ && exportAssignmentIsAlias(node) ||
|
|
1315
|
+
isBinaryExpression(node) && getAssignmentDeclarationKind(node) === 2 /* AssignmentDeclarationKind.ModuleExports */ && exportAssignmentIsAlias(node) ||
|
|
1316
|
+
isPropertyAccessExpression(node) && isBinaryExpression(node.parent) && node.parent.left === node && node.parent.operatorToken.kind === 62 /* SyntaxKind.EqualsToken */ && isAliasableExpression(node.parent.right) ||
|
|
1317
|
+
node.kind === 282 /* SyntaxKind.ShorthandPropertyAssignment */ ||
|
|
1318
|
+
node.kind === 281 /* SyntaxKind.PropertyAssignment */ && isAliasableExpression(node.initializer);
|
|
1319
|
+
}
|
|
1320
|
+
export function getAliasDeclarationFromName(node) {
|
|
1321
|
+
switch (node.parent.kind) {
|
|
1322
|
+
case 255 /* SyntaxKind.ImportClause */:
|
|
1323
|
+
case 258 /* SyntaxKind.ImportSpecifier */:
|
|
1324
|
+
case 256 /* SyntaxKind.NamespaceImport */:
|
|
1325
|
+
case 263 /* SyntaxKind.ExportSpecifier */:
|
|
1326
|
+
case 259 /* SyntaxKind.ExportAssignment */:
|
|
1327
|
+
return node.parent;
|
|
1328
|
+
case 153 /* SyntaxKind.QualifiedName */:
|
|
1329
|
+
do {
|
|
1330
|
+
node = node.parent;
|
|
1331
|
+
} while (node.parent.kind === 153 /* SyntaxKind.QualifiedName */);
|
|
1332
|
+
return getAliasDeclarationFromName(node);
|
|
1333
|
+
}
|
|
1334
|
+
}
|
|
1335
|
+
export function isAliasableExpression(e) {
|
|
1336
|
+
return isEntityNameExpression(e);
|
|
1337
|
+
}
|
|
1338
|
+
export function exportAssignmentIsAlias(node) {
|
|
1339
|
+
const e = getExportAssignmentExpression(node);
|
|
1340
|
+
return isAliasableExpression(e);
|
|
1341
|
+
}
|
|
1342
|
+
export function getExportAssignmentExpression(node) {
|
|
1343
|
+
return isExportAssignment(node) ? node.expression : node.right;
|
|
1344
|
+
}
|
|
1345
|
+
export function getAncestor(node, kind) {
|
|
1346
|
+
while (node) {
|
|
1347
|
+
if (node.kind === kind) {
|
|
1348
|
+
return node;
|
|
1349
|
+
}
|
|
1350
|
+
node = node.parent;
|
|
1351
|
+
}
|
|
1352
|
+
return undefined;
|
|
1353
|
+
}
|
|
1354
|
+
export function isKeyword(token) {
|
|
1355
|
+
return 77 /* SyntaxKind.FirstKeyword */ <= token && token <= 152 /* SyntaxKind.LastKeyword */;
|
|
1356
|
+
}
|
|
1357
|
+
export function isContextualKeyword(token) {
|
|
1358
|
+
return 122 /* SyntaxKind.FirstContextualKeyword */ <= token && token <= 152 /* SyntaxKind.LastContextualKeyword */;
|
|
1359
|
+
}
|
|
1360
|
+
export function isNonContextualKeyword(token) {
|
|
1361
|
+
return isKeyword(token) && !isContextualKeyword(token);
|
|
1362
|
+
}
|
|
1363
|
+
export function isStringANonContextualKeyword(name) {
|
|
1364
|
+
const token = stringToToken(name);
|
|
1365
|
+
return token !== undefined && isNonContextualKeyword(token);
|
|
1366
|
+
}
|
|
1367
|
+
export function isIdentifierANonContextualKeyword({ originalKeywordKind }) {
|
|
1368
|
+
return !!originalKeywordKind && !isContextualKeyword(originalKeywordKind);
|
|
1369
|
+
}
|
|
1370
|
+
export function isTrivia(token) {
|
|
1371
|
+
return 2 /* SyntaxKind.FirstTriviaToken */ <= token && token <= 7 /* SyntaxKind.LastTriviaToken */;
|
|
1372
|
+
}
|
|
1373
|
+
export var FunctionFlags;
|
|
1374
|
+
(function (FunctionFlags) {
|
|
1375
|
+
FunctionFlags[FunctionFlags["Normal"] = 0] = "Normal";
|
|
1376
|
+
FunctionFlags[FunctionFlags["Async"] = 2] = "Async";
|
|
1377
|
+
FunctionFlags[FunctionFlags["Invalid"] = 4] = "Invalid";
|
|
1378
|
+
})(FunctionFlags || (FunctionFlags = {}));
|
|
1379
|
+
export function getFunctionFlags(node) {
|
|
1380
|
+
if (!node) {
|
|
1381
|
+
return 4 /* FunctionFlags.Invalid */;
|
|
1382
|
+
}
|
|
1383
|
+
let flags = 0 /* FunctionFlags.Normal */;
|
|
1384
|
+
switch (node.kind) {
|
|
1385
|
+
case 202 /* SyntaxKind.ArrowFunction */:
|
|
1386
|
+
if (hasModifier(node, 256 /* ModifierFlags.Async */)) {
|
|
1387
|
+
flags |= 2 /* FunctionFlags.Async */;
|
|
1388
|
+
}
|
|
1389
|
+
break;
|
|
1390
|
+
}
|
|
1391
|
+
if (!node.body) {
|
|
1392
|
+
flags |= 4 /* FunctionFlags.Invalid */;
|
|
1393
|
+
}
|
|
1394
|
+
return flags;
|
|
1395
|
+
}
|
|
1396
|
+
export function isAsyncFunction(node) {
|
|
1397
|
+
switch (node.kind) {
|
|
1398
|
+
case 202 /* SyntaxKind.ArrowFunction */:
|
|
1399
|
+
return node.body !== undefined
|
|
1400
|
+
&& hasModifier(node, 256 /* ModifierFlags.Async */);
|
|
1401
|
+
}
|
|
1402
|
+
return false;
|
|
1403
|
+
}
|
|
1404
|
+
export function isStringOrNumericLiteralLike(node) {
|
|
1405
|
+
return isStringLiteralLike(node) || isNumericLiteral(node);
|
|
1406
|
+
}
|
|
1407
|
+
export function isSignedNumericLiteral(node) {
|
|
1408
|
+
return isPrefixUnaryExpression(node) && (node.operator === 39 /* SyntaxKind.PlusToken */ || node.operator === 40 /* SyntaxKind.MinusToken */) && isNumericLiteral(node.operand);
|
|
1409
|
+
}
|
|
1410
|
+
/**
|
|
1411
|
+
* A declaration has a dynamic name if all of the following are true:
|
|
1412
|
+
* 1. The declaration has a computed property name.
|
|
1413
|
+
* 2. The computed name is *not* expressed as a StringLiteral.
|
|
1414
|
+
* 3. The computed name is *not* expressed as a NumericLiteral.
|
|
1415
|
+
* 4. The computed name is *not* expressed as a PlusToken or MinusToken
|
|
1416
|
+
* immediately followed by a NumericLiteral.
|
|
1417
|
+
* 5. The computed name is *not* expressed as `Symbol.<name>`, where `<name>`
|
|
1418
|
+
* is a property of the Symbol constructor that denotes a built-in
|
|
1419
|
+
* Symbol.
|
|
1420
|
+
*/
|
|
1421
|
+
export function hasDynamicName(declaration) {
|
|
1422
|
+
const name = getNameOfDeclaration(declaration);
|
|
1423
|
+
return !!name && isDynamicName(name);
|
|
1424
|
+
}
|
|
1425
|
+
export function isDynamicName(name) {
|
|
1426
|
+
if (!(name.kind === 154 /* SyntaxKind.ComputedPropertyName */ || name.kind === 195 /* SyntaxKind.ElementAccessExpression */)) {
|
|
1427
|
+
return false;
|
|
1428
|
+
}
|
|
1429
|
+
const expr = isElementAccessExpression(name) ? skipParentheses(name.argumentExpression) : name.expression;
|
|
1430
|
+
return !isStringOrNumericLiteralLike(expr) &&
|
|
1431
|
+
!isSignedNumericLiteral(expr) &&
|
|
1432
|
+
!isWellKnownSymbolSyntactically(expr);
|
|
1433
|
+
}
|
|
1434
|
+
/**
|
|
1435
|
+
* Checks if the expression is of the form:
|
|
1436
|
+
* Symbol.name
|
|
1437
|
+
* where Symbol is literally the word "Symbol", and name is any identifierName
|
|
1438
|
+
*/
|
|
1439
|
+
export function isWellKnownSymbolSyntactically(node) {
|
|
1440
|
+
return isPropertyAccessExpression(node) && isESSymbolIdentifier(node.expression);
|
|
1441
|
+
}
|
|
1442
|
+
export function getPropertyNameForPropertyNameNode(name) {
|
|
1443
|
+
switch (name.kind) {
|
|
1444
|
+
case 75 /* SyntaxKind.Identifier */:
|
|
1445
|
+
return name.escapedText;
|
|
1446
|
+
case 10 /* SyntaxKind.StringLiteral */:
|
|
1447
|
+
case 8 /* SyntaxKind.NumericLiteral */:
|
|
1448
|
+
return escapeLeadingUnderscores(name.text);
|
|
1449
|
+
case 154 /* SyntaxKind.ComputedPropertyName */:
|
|
1450
|
+
const nameExpression = name.expression;
|
|
1451
|
+
if (isWellKnownSymbolSyntactically(nameExpression)) {
|
|
1452
|
+
return getPropertyNameForKnownSymbolName(idText(nameExpression.name));
|
|
1453
|
+
}
|
|
1454
|
+
else if (isStringOrNumericLiteralLike(nameExpression)) {
|
|
1455
|
+
return escapeLeadingUnderscores(nameExpression.text);
|
|
1456
|
+
}
|
|
1457
|
+
return undefined;
|
|
1458
|
+
default:
|
|
1459
|
+
return Debug.assertNever(name);
|
|
1460
|
+
}
|
|
1461
|
+
}
|
|
1462
|
+
export function isPropertyNameLiteral(node) {
|
|
1463
|
+
switch (node.kind) {
|
|
1464
|
+
case 75 /* SyntaxKind.Identifier */:
|
|
1465
|
+
case 10 /* SyntaxKind.StringLiteral */:
|
|
1466
|
+
case 14 /* SyntaxKind.NoSubstitutionTemplateLiteral */:
|
|
1467
|
+
case 8 /* SyntaxKind.NumericLiteral */:
|
|
1468
|
+
return true;
|
|
1469
|
+
default:
|
|
1470
|
+
return false;
|
|
1471
|
+
}
|
|
1472
|
+
}
|
|
1473
|
+
export function getTextOfIdentifierOrLiteral(node) {
|
|
1474
|
+
return isIdentifier(node) ? idText(node) : node.text;
|
|
1475
|
+
}
|
|
1476
|
+
export function getEscapedTextOfIdentifierOrLiteral(node) {
|
|
1477
|
+
return isIdentifier(node) ? node.escapedText : escapeLeadingUnderscores(node.text);
|
|
1478
|
+
}
|
|
1479
|
+
export function getPropertyNameForKnownSymbolName(symbolName) {
|
|
1480
|
+
return "__@" + symbolName;
|
|
1481
|
+
}
|
|
1482
|
+
export function isKnownSymbol(symbol) {
|
|
1483
|
+
return startsWith(symbol.escapedName, "__@");
|
|
1484
|
+
}
|
|
1485
|
+
/**
|
|
1486
|
+
* Includes the word "Symbol" with unicode escapes
|
|
1487
|
+
*/
|
|
1488
|
+
export function isESSymbolIdentifier(node) {
|
|
1489
|
+
return node.kind === 75 /* SyntaxKind.Identifier */ && node.escapedText === "Symbol";
|
|
1490
|
+
}
|
|
1491
|
+
export function isParameterDeclaration(node) {
|
|
1492
|
+
const root = getRootDeclaration(node);
|
|
1493
|
+
return root.kind === 156 /* SyntaxKind.Parameter */;
|
|
1494
|
+
}
|
|
1495
|
+
export function getRootDeclaration(node) {
|
|
1496
|
+
while (node.kind === 191 /* SyntaxKind.BindingElement */) {
|
|
1497
|
+
node = node.parent.parent;
|
|
1498
|
+
}
|
|
1499
|
+
return node;
|
|
1500
|
+
}
|
|
1501
|
+
export function nodeIsSynthesized(range) {
|
|
1502
|
+
return positionIsSynthesized(range.pos)
|
|
1503
|
+
|| positionIsSynthesized(range.end);
|
|
1504
|
+
}
|
|
1505
|
+
export var Associativity;
|
|
1506
|
+
(function (Associativity) {
|
|
1507
|
+
Associativity[Associativity["Left"] = 0] = "Left";
|
|
1508
|
+
Associativity[Associativity["Right"] = 1] = "Right";
|
|
1509
|
+
})(Associativity || (Associativity = {}));
|
|
1510
|
+
export function getExpressionAssociativity(expression) {
|
|
1511
|
+
const operator = getOperator(expression);
|
|
1512
|
+
return getOperatorAssociativity(expression.kind, operator);
|
|
1513
|
+
}
|
|
1514
|
+
export function getOperatorAssociativity(kind, operator) {
|
|
1515
|
+
switch (kind) {
|
|
1516
|
+
case 207 /* SyntaxKind.PrefixUnaryExpression */:
|
|
1517
|
+
case 204 /* SyntaxKind.TypeOfExpression */:
|
|
1518
|
+
case 203 /* SyntaxKind.DeleteExpression */:
|
|
1519
|
+
case 206 /* SyntaxKind.AwaitExpression */:
|
|
1520
|
+
case 210 /* SyntaxKind.ConditionalExpression */:
|
|
1521
|
+
return 1 /* Associativity.Right */;
|
|
1522
|
+
case 209 /* SyntaxKind.BinaryExpression */:
|
|
1523
|
+
switch (operator) {
|
|
1524
|
+
case 42 /* SyntaxKind.AsteriskAsteriskToken */:
|
|
1525
|
+
case 62 /* SyntaxKind.EqualsToken */:
|
|
1526
|
+
case 63 /* SyntaxKind.PlusEqualsToken */:
|
|
1527
|
+
case 64 /* SyntaxKind.MinusEqualsToken */:
|
|
1528
|
+
case 66 /* SyntaxKind.AsteriskAsteriskEqualsToken */:
|
|
1529
|
+
case 65 /* SyntaxKind.AsteriskEqualsToken */:
|
|
1530
|
+
case 67 /* SyntaxKind.SlashEqualsToken */:
|
|
1531
|
+
case 68 /* SyntaxKind.PercentEqualsToken */:
|
|
1532
|
+
case 69 /* SyntaxKind.LessThanLessThanEqualsToken */:
|
|
1533
|
+
case 70 /* SyntaxKind.GreaterThanGreaterThanEqualsToken */:
|
|
1534
|
+
case 71 /* SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken */:
|
|
1535
|
+
case 72 /* SyntaxKind.AmpersandEqualsToken */:
|
|
1536
|
+
case 74 /* SyntaxKind.CaretEqualsToken */:
|
|
1537
|
+
case 73 /* SyntaxKind.BarEqualsToken */:
|
|
1538
|
+
return 1 /* Associativity.Right */;
|
|
1539
|
+
}
|
|
1540
|
+
}
|
|
1541
|
+
return 0 /* Associativity.Left */;
|
|
1542
|
+
}
|
|
1543
|
+
export function getExpressionPrecedence(expression) {
|
|
1544
|
+
const operator = getOperator(expression);
|
|
1545
|
+
return getOperatorPrecedence(expression.kind, operator);
|
|
1546
|
+
}
|
|
1547
|
+
export function getOperator(expression) {
|
|
1548
|
+
if (expression.kind === 209 /* SyntaxKind.BinaryExpression */) {
|
|
1549
|
+
return expression.operatorToken.kind;
|
|
1550
|
+
}
|
|
1551
|
+
else if (expression.kind === 207 /* SyntaxKind.PrefixUnaryExpression */ || expression.kind === 208 /* SyntaxKind.PostfixUnaryExpression */) {
|
|
1552
|
+
return expression.operator;
|
|
1553
|
+
}
|
|
1554
|
+
else {
|
|
1555
|
+
return expression.kind;
|
|
1556
|
+
}
|
|
1557
|
+
}
|
|
1558
|
+
export function getOperatorPrecedence(nodeKind, operatorKind) {
|
|
1559
|
+
switch (nodeKind) {
|
|
1560
|
+
case 327 /* SyntaxKind.CommaListExpression */:
|
|
1561
|
+
return 0;
|
|
1562
|
+
case 213 /* SyntaxKind.SpreadElement */:
|
|
1563
|
+
return 1;
|
|
1564
|
+
case 210 /* SyntaxKind.ConditionalExpression */:
|
|
1565
|
+
return 4;
|
|
1566
|
+
case 209 /* SyntaxKind.BinaryExpression */:
|
|
1567
|
+
switch (operatorKind) {
|
|
1568
|
+
case 27 /* SyntaxKind.CommaToken */:
|
|
1569
|
+
return 0;
|
|
1570
|
+
case 62 /* SyntaxKind.EqualsToken */:
|
|
1571
|
+
case 63 /* SyntaxKind.PlusEqualsToken */:
|
|
1572
|
+
case 64 /* SyntaxKind.MinusEqualsToken */:
|
|
1573
|
+
case 66 /* SyntaxKind.AsteriskAsteriskEqualsToken */:
|
|
1574
|
+
case 65 /* SyntaxKind.AsteriskEqualsToken */:
|
|
1575
|
+
case 67 /* SyntaxKind.SlashEqualsToken */:
|
|
1576
|
+
case 68 /* SyntaxKind.PercentEqualsToken */:
|
|
1577
|
+
case 69 /* SyntaxKind.LessThanLessThanEqualsToken */:
|
|
1578
|
+
case 70 /* SyntaxKind.GreaterThanGreaterThanEqualsToken */:
|
|
1579
|
+
case 71 /* SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken */:
|
|
1580
|
+
case 72 /* SyntaxKind.AmpersandEqualsToken */:
|
|
1581
|
+
case 74 /* SyntaxKind.CaretEqualsToken */:
|
|
1582
|
+
case 73 /* SyntaxKind.BarEqualsToken */:
|
|
1583
|
+
return 3;
|
|
1584
|
+
default:
|
|
1585
|
+
return getBinaryOperatorPrecedence(operatorKind);
|
|
1586
|
+
}
|
|
1587
|
+
case 207 /* SyntaxKind.PrefixUnaryExpression */:
|
|
1588
|
+
case 204 /* SyntaxKind.TypeOfExpression */:
|
|
1589
|
+
case 203 /* SyntaxKind.DeleteExpression */:
|
|
1590
|
+
case 206 /* SyntaxKind.AwaitExpression */:
|
|
1591
|
+
return 16;
|
|
1592
|
+
case 208 /* SyntaxKind.PostfixUnaryExpression */:
|
|
1593
|
+
return 17;
|
|
1594
|
+
case 196 /* SyntaxKind.CallExpression */:
|
|
1595
|
+
return 18;
|
|
1596
|
+
case 194 /* SyntaxKind.PropertyAccessExpression */:
|
|
1597
|
+
case 195 /* SyntaxKind.ElementAccessExpression */:
|
|
1598
|
+
return 19;
|
|
1599
|
+
case 75 /* SyntaxKind.Identifier */:
|
|
1600
|
+
case 100 /* SyntaxKind.NullKeyword */:
|
|
1601
|
+
case 106 /* SyntaxKind.TrueKeyword */:
|
|
1602
|
+
case 91 /* SyntaxKind.FalseKeyword */:
|
|
1603
|
+
case 8 /* SyntaxKind.NumericLiteral */:
|
|
1604
|
+
case 9 /* SyntaxKind.BigIntLiteral */:
|
|
1605
|
+
case 10 /* SyntaxKind.StringLiteral */:
|
|
1606
|
+
case 192 /* SyntaxKind.ArrayLiteralExpression */:
|
|
1607
|
+
case 193 /* SyntaxKind.ObjectLiteralExpression */:
|
|
1608
|
+
case 202 /* SyntaxKind.ArrowFunction */:
|
|
1609
|
+
case 266 /* SyntaxKind.JsxElement */:
|
|
1610
|
+
case 267 /* SyntaxKind.JsxSelfClosingElement */:
|
|
1611
|
+
case 270 /* SyntaxKind.JsxFragment */:
|
|
1612
|
+
case 14 /* SyntaxKind.NoSubstitutionTemplateLiteral */:
|
|
1613
|
+
case 211 /* SyntaxKind.TemplateExpression */:
|
|
1614
|
+
case 200 /* SyntaxKind.ParenthesizedExpression */:
|
|
1615
|
+
case 215 /* SyntaxKind.OmittedExpression */:
|
|
1616
|
+
return 20;
|
|
1617
|
+
default:
|
|
1618
|
+
return -1;
|
|
1619
|
+
}
|
|
1620
|
+
}
|
|
1621
|
+
export function getBinaryOperatorPrecedence(kind) {
|
|
1622
|
+
switch (kind) {
|
|
1623
|
+
// O `??` tem a precedência do `||`, e não a do condicional.
|
|
1624
|
+
case 60 /* SyntaxKind.QuestionQuestionToken */:
|
|
1625
|
+
case 56 /* SyntaxKind.BarBarToken */:
|
|
1626
|
+
return 5;
|
|
1627
|
+
case 55 /* SyntaxKind.AmpersandAmpersandToken */:
|
|
1628
|
+
return 6;
|
|
1629
|
+
case 51 /* SyntaxKind.BarToken */:
|
|
1630
|
+
return 7;
|
|
1631
|
+
case 52 /* SyntaxKind.CaretToken */:
|
|
1632
|
+
return 8;
|
|
1633
|
+
case 50 /* SyntaxKind.AmpersandToken */:
|
|
1634
|
+
return 9;
|
|
1635
|
+
// A igualdade da Linguagem é o `==` e o `!=`, com o significado do `===` e do `!==` da tag (CK-70); o `===` e o
|
|
1636
|
+
// `!==` não são operador, e o parser não os lê.
|
|
1637
|
+
case 34 /* SyntaxKind.EqualsEqualsToken */:
|
|
1638
|
+
case 35 /* SyntaxKind.ExclamationEqualsToken */:
|
|
1639
|
+
return 10;
|
|
1640
|
+
case 29 /* SyntaxKind.LessThanToken */:
|
|
1641
|
+
case 31 /* SyntaxKind.GreaterThanToken */:
|
|
1642
|
+
case 32 /* SyntaxKind.LessThanEqualsToken */:
|
|
1643
|
+
case 33 /* SyntaxKind.GreaterThanEqualsToken */:
|
|
1644
|
+
case 97 /* SyntaxKind.InKeyword */:
|
|
1645
|
+
case 123 /* SyntaxKind.AsKeyword */:
|
|
1646
|
+
return 11;
|
|
1647
|
+
case 47 /* SyntaxKind.LessThanLessThanToken */:
|
|
1648
|
+
case 48 /* SyntaxKind.GreaterThanGreaterThanToken */:
|
|
1649
|
+
case 49 /* SyntaxKind.GreaterThanGreaterThanGreaterThanToken */:
|
|
1650
|
+
return 12;
|
|
1651
|
+
case 39 /* SyntaxKind.PlusToken */:
|
|
1652
|
+
case 40 /* SyntaxKind.MinusToken */:
|
|
1653
|
+
return 13;
|
|
1654
|
+
case 41 /* SyntaxKind.AsteriskToken */:
|
|
1655
|
+
case 43 /* SyntaxKind.SlashToken */:
|
|
1656
|
+
case 44 /* SyntaxKind.PercentToken */:
|
|
1657
|
+
return 14;
|
|
1658
|
+
case 42 /* SyntaxKind.AsteriskAsteriskToken */:
|
|
1659
|
+
return 15;
|
|
1660
|
+
}
|
|
1661
|
+
// -1 is lower than all other precedences. Returning it will cause binary expression
|
|
1662
|
+
// parsing to stop.
|
|
1663
|
+
return -1;
|
|
1664
|
+
}
|
|
1665
|
+
const templateSubstitutionRegExp = /\$\{/g;
|
|
1666
|
+
function escapeTemplateSubstitution(str) {
|
|
1667
|
+
return str.replace(templateSubstitutionRegExp, "\\${");
|
|
1668
|
+
}
|
|
1669
|
+
// This consists of the first 19 unprintable ASCII characters, canonical escapes, lineSeparator,
|
|
1670
|
+
// paragraphSeparator, and nextLine. The latter three are just desirable to suppress new lines in
|
|
1671
|
+
// the language service. These characters should be escaped when printing, and if any characters are added,
|
|
1672
|
+
// the map below must be updated. Note that this regexp *does not* include the 'delete' character.
|
|
1673
|
+
// There is no reason for this other than that JSON.stringify does not handle it either.
|
|
1674
|
+
const doubleQuoteEscapedCharsRegExp = /[\\\"\u0000-\u001f\t\v\f\b\r\n\u2028\u2029\u0085]/g;
|
|
1675
|
+
const singleQuoteEscapedCharsRegExp = /[\\\'\u0000-\u001f\t\v\f\b\r\n\u2028\u2029\u0085]/g;
|
|
1676
|
+
// O template guarda o LF simples, e escapa os outros caracteres de controle; o CRLF e o CR, relidos, virariam LF.
|
|
1677
|
+
const backtickQuoteEscapedCharsRegExp = /\r\n|[\\`\u0000-\u0009\u000b-\u001f\u2028\u2029\u0085]/g;
|
|
1678
|
+
const escapedCharsMap = createMapFromTemplate({
|
|
1679
|
+
"\t": "\\t",
|
|
1680
|
+
"\v": "\\v",
|
|
1681
|
+
"\f": "\\f",
|
|
1682
|
+
"\b": "\\b",
|
|
1683
|
+
"\r": "\\r",
|
|
1684
|
+
"\n": "\\n",
|
|
1685
|
+
"\\": "\\\\",
|
|
1686
|
+
"\"": "\\\"",
|
|
1687
|
+
"\'": "\\\'",
|
|
1688
|
+
"\`": "\\\`",
|
|
1689
|
+
"\u2028": "\\u2028", // lineSeparator
|
|
1690
|
+
"\u2029": "\\u2029", // paragraphSeparator
|
|
1691
|
+
"\u0085": "\\u0085", // nextLine
|
|
1692
|
+
"\r\n": "\\r\\n", // o CRLF num template
|
|
1693
|
+
});
|
|
1694
|
+
function encodeUtf16EscapeSequence(charCode) {
|
|
1695
|
+
const hexCharCode = charCode.toString(16).toUpperCase();
|
|
1696
|
+
const paddedHexCode = ("0000" + hexCharCode).slice(-4);
|
|
1697
|
+
return "\\u" + paddedHexCode;
|
|
1698
|
+
}
|
|
1699
|
+
function getReplacement(c, offset, input) {
|
|
1700
|
+
if (c.charCodeAt(0) === 0 /* CharacterCodes.nullCharacter */) {
|
|
1701
|
+
const lookAhead = input.charCodeAt(offset + c.length);
|
|
1702
|
+
if (lookAhead >= 48 /* CharacterCodes._0 */ && lookAhead <= 57 /* CharacterCodes._9 */) {
|
|
1703
|
+
// If the null character is followed by digits, print as a hex escape to prevent the result from parsing as an octal (which is forbidden in strict mode)
|
|
1704
|
+
return "\\x00";
|
|
1705
|
+
}
|
|
1706
|
+
// Otherwise, keep printing a literal \0 for the null character
|
|
1707
|
+
return "\\0";
|
|
1708
|
+
}
|
|
1709
|
+
return escapedCharsMap.get(c) || encodeUtf16EscapeSequence(c.charCodeAt(0));
|
|
1710
|
+
}
|
|
1711
|
+
/**
|
|
1712
|
+
* Based heavily on the abstract 'Quote'/'QuoteJSONString' operation from ECMA-262 (24.3.2.2),
|
|
1713
|
+
* but augmented for a few select characters (e.g. lineSeparator, paragraphSeparator, nextLine)
|
|
1714
|
+
* Note that this doesn't actually wrap the input in double quotes.
|
|
1715
|
+
*/
|
|
1716
|
+
export function escapeString(s, quoteChar) {
|
|
1717
|
+
const escapedCharsRegExp = quoteChar === 96 /* CharacterCodes.backtick */ ? backtickQuoteEscapedCharsRegExp :
|
|
1718
|
+
quoteChar === 39 /* CharacterCodes.singleQuote */ ? singleQuoteEscapedCharsRegExp :
|
|
1719
|
+
doubleQuoteEscapedCharsRegExp;
|
|
1720
|
+
return s.replace(escapedCharsRegExp, getReplacement);
|
|
1721
|
+
}
|
|
1722
|
+
const nonAsciiCharacters = /[^\u0000-\u007F]/g;
|
|
1723
|
+
export function escapeNonAsciiString(s, quoteChar) {
|
|
1724
|
+
s = escapeString(s, quoteChar);
|
|
1725
|
+
// Replace non-ASCII characters with '\uNNNN' escapes if any exist.
|
|
1726
|
+
// Otherwise just return the original string.
|
|
1727
|
+
return nonAsciiCharacters.test(s) ?
|
|
1728
|
+
s.replace(nonAsciiCharacters, c => encodeUtf16EscapeSequence(c.charCodeAt(0))) :
|
|
1729
|
+
s;
|
|
1730
|
+
}
|
|
1731
|
+
// This consists of the first 19 unprintable ASCII characters, JSX canonical escapes, lineSeparator,
|
|
1732
|
+
// paragraphSeparator, and nextLine. The latter three are just desirable to suppress new lines in
|
|
1733
|
+
// the language service. These characters should be escaped when printing, and if any characters are added,
|
|
1734
|
+
// the map below must be updated.
|
|
1735
|
+
const jsxDoubleQuoteEscapedCharsRegExp = /[\"\u0000-\u001f\u2028\u2029\u0085]/g;
|
|
1736
|
+
const jsxSingleQuoteEscapedCharsRegExp = /[\'\u0000-\u001f\u2028\u2029\u0085]/g;
|
|
1737
|
+
const jsxEscapedCharsMap = createMapFromTemplate({
|
|
1738
|
+
"\"": """,
|
|
1739
|
+
"\'": "'"
|
|
1740
|
+
});
|
|
1741
|
+
function encodeJsxCharacterEntity(charCode) {
|
|
1742
|
+
const hexCharCode = charCode.toString(16).toUpperCase();
|
|
1743
|
+
return "&#x" + hexCharCode + ";";
|
|
1744
|
+
}
|
|
1745
|
+
function getJsxAttributeStringReplacement(c) {
|
|
1746
|
+
if (c.charCodeAt(0) === 0 /* CharacterCodes.nullCharacter */) {
|
|
1747
|
+
return "�";
|
|
1748
|
+
}
|
|
1749
|
+
return jsxEscapedCharsMap.get(c) || encodeJsxCharacterEntity(c.charCodeAt(0));
|
|
1750
|
+
}
|
|
1751
|
+
export function escapeJsxAttributeString(s, quoteChar) {
|
|
1752
|
+
const escapedCharsRegExp = quoteChar === 39 /* CharacterCodes.singleQuote */ ? jsxSingleQuoteEscapedCharsRegExp :
|
|
1753
|
+
jsxDoubleQuoteEscapedCharsRegExp;
|
|
1754
|
+
return s.replace(escapedCharsRegExp, getJsxAttributeStringReplacement);
|
|
1755
|
+
}
|
|
1756
|
+
/** O texto sem as aspas simples, as duplas ou as crases que o cercam, quando as duas pontas são iguais. */
|
|
1757
|
+
export function stripQuotes(name) {
|
|
1758
|
+
const length = name.length;
|
|
1759
|
+
if (length >= 2 && name.charCodeAt(0) === name.charCodeAt(length - 1) && isQuoteOrBacktick(name.charCodeAt(0))) {
|
|
1760
|
+
return name.substring(1, length - 1);
|
|
1761
|
+
}
|
|
1762
|
+
return name;
|
|
1763
|
+
}
|
|
1764
|
+
function isQuoteOrBacktick(charCode) {
|
|
1765
|
+
return charCode === 39 /* CharacterCodes.singleQuote */ ||
|
|
1766
|
+
charCode === 34 /* CharacterCodes.doubleQuote */ ||
|
|
1767
|
+
charCode === 96 /* CharacterCodes.backtick */;
|
|
1768
|
+
}
|
|
1769
|
+
export function isIntrinsicJsxName(name) {
|
|
1770
|
+
const ch = name.charCodeAt(0);
|
|
1771
|
+
return (ch >= 97 /* CharacterCodes.a */ && ch <= 122 /* CharacterCodes.z */) || stringContains(name, "-");
|
|
1772
|
+
}
|
|
1773
|
+
const indentStrings = ["", " "];
|
|
1774
|
+
export function getIndentString(level) {
|
|
1775
|
+
if (indentStrings[level] === undefined) {
|
|
1776
|
+
indentStrings[level] = getIndentString(level - 1) + indentStrings[1];
|
|
1777
|
+
}
|
|
1778
|
+
return indentStrings[level];
|
|
1779
|
+
}
|
|
1780
|
+
export function getIndentSize() {
|
|
1781
|
+
return indentStrings[1].length;
|
|
1782
|
+
}
|
|
1783
|
+
export function hostUsesCaseSensitiveFileNames(host) {
|
|
1784
|
+
return host.useCaseSensitiveFileNames ? host.useCaseSensitiveFileNames() : false;
|
|
1785
|
+
}
|
|
1786
|
+
export function getLineOfLocalPosition(sourceFile, pos) {
|
|
1787
|
+
const lineStarts = getLineStarts(sourceFile);
|
|
1788
|
+
return computeLineOfPosition(lineStarts, pos);
|
|
1789
|
+
}
|
|
1790
|
+
export function getLineOfLocalPositionFromLineMap(lineMap, pos) {
|
|
1791
|
+
return computeLineOfPosition(lineMap, pos);
|
|
1792
|
+
}
|
|
1793
|
+
/** A anotação de tipo de uma variável, de um parâmetro ou de uma propriedade. */
|
|
1794
|
+
export function getEffectiveTypeAnnotationNode(node) {
|
|
1795
|
+
return node.type;
|
|
1796
|
+
}
|
|
1797
|
+
/** A anotação do retorno de uma assinatura. */
|
|
1798
|
+
export function getEffectiveReturnTypeNode(node) {
|
|
1799
|
+
return node.type;
|
|
1800
|
+
}
|
|
1801
|
+
export function hasModifiers(node) {
|
|
1802
|
+
return getModifierFlags(node) !== 0 /* ModifierFlags.None */;
|
|
1803
|
+
}
|
|
1804
|
+
export function hasModifier(node, flags) {
|
|
1805
|
+
return !!getSelectedModifierFlags(node, flags);
|
|
1806
|
+
}
|
|
1807
|
+
export function hasReadonlyModifier(node) {
|
|
1808
|
+
return hasModifier(node, 64 /* ModifierFlags.Readonly */);
|
|
1809
|
+
}
|
|
1810
|
+
export function getSelectedModifierFlags(node, flags) {
|
|
1811
|
+
return getModifierFlags(node) & flags;
|
|
1812
|
+
}
|
|
1813
|
+
export function getModifierFlags(node) {
|
|
1814
|
+
if (node.kind >= 0 /* SyntaxKind.FirstToken */ && node.kind <= 152 /* SyntaxKind.LastToken */) {
|
|
1815
|
+
return 0 /* ModifierFlags.None */;
|
|
1816
|
+
}
|
|
1817
|
+
if (node.modifierFlagsCache & 536870912 /* ModifierFlags.HasComputedFlags */) {
|
|
1818
|
+
return node.modifierFlagsCache & ~536870912 /* ModifierFlags.HasComputedFlags */;
|
|
1819
|
+
}
|
|
1820
|
+
const flags = getModifierFlagsNoCache(node);
|
|
1821
|
+
node.modifierFlagsCache = flags | 536870912 /* ModifierFlags.HasComputedFlags */;
|
|
1822
|
+
return flags;
|
|
1823
|
+
}
|
|
1824
|
+
export function getModifierFlagsNoCache(node) {
|
|
1825
|
+
let flags = 0 /* ModifierFlags.None */;
|
|
1826
|
+
if (node.modifiers) {
|
|
1827
|
+
for (const modifier of node.modifiers) {
|
|
1828
|
+
flags |= modifierToFlag(modifier.kind);
|
|
1829
|
+
}
|
|
1830
|
+
}
|
|
1831
|
+
if (node.flags & 4 /* NodeFlags.NestedNamespace */) {
|
|
1832
|
+
flags |= 1 /* ModifierFlags.Export */;
|
|
1833
|
+
}
|
|
1834
|
+
return flags;
|
|
1835
|
+
}
|
|
1836
|
+
export function modifierToFlag(token) {
|
|
1837
|
+
switch (token) {
|
|
1838
|
+
case 89 /* SyntaxKind.ExportKeyword */: return 1 /* ModifierFlags.Export */;
|
|
1839
|
+
case 130 /* SyntaxKind.DeclareKeyword */: return 2 /* ModifierFlags.Ambient */;
|
|
1840
|
+
case 126 /* SyntaxKind.AsyncKeyword */: return 256 /* ModifierFlags.Async */;
|
|
1841
|
+
case 138 /* SyntaxKind.ReadonlyKeyword */: return 64 /* ModifierFlags.Readonly */;
|
|
1842
|
+
}
|
|
1843
|
+
return 0 /* ModifierFlags.None */;
|
|
1844
|
+
}
|
|
1845
|
+
export function isAssignmentOperator(token) {
|
|
1846
|
+
return token >= 62 /* SyntaxKind.FirstAssignment */ && token <= 74 /* SyntaxKind.LastAssignment */;
|
|
1847
|
+
}
|
|
1848
|
+
export function isAssignmentExpression(node, excludeCompoundAssignment) {
|
|
1849
|
+
return isBinaryExpression(node)
|
|
1850
|
+
&& (excludeCompoundAssignment
|
|
1851
|
+
? node.operatorToken.kind === 62 /* SyntaxKind.EqualsToken */
|
|
1852
|
+
: isAssignmentOperator(node.operatorToken.kind))
|
|
1853
|
+
&& isLeftHandSideExpression(node.left);
|
|
1854
|
+
}
|
|
1855
|
+
export function isEntityNameExpression(node) {
|
|
1856
|
+
return node.kind === 75 /* SyntaxKind.Identifier */ || isPropertyAccessEntityNameExpression(node);
|
|
1857
|
+
}
|
|
1858
|
+
export function getFirstIdentifier(node) {
|
|
1859
|
+
switch (node.kind) {
|
|
1860
|
+
case 75 /* SyntaxKind.Identifier */:
|
|
1861
|
+
return node;
|
|
1862
|
+
case 153 /* SyntaxKind.QualifiedName */:
|
|
1863
|
+
do {
|
|
1864
|
+
node = node.left;
|
|
1865
|
+
} while (node.kind !== 75 /* SyntaxKind.Identifier */);
|
|
1866
|
+
return node;
|
|
1867
|
+
case 194 /* SyntaxKind.PropertyAccessExpression */:
|
|
1868
|
+
do {
|
|
1869
|
+
node = node.expression;
|
|
1870
|
+
} while (node.kind !== 75 /* SyntaxKind.Identifier */);
|
|
1871
|
+
return node;
|
|
1872
|
+
}
|
|
1873
|
+
}
|
|
1874
|
+
export function isDottedName(node) {
|
|
1875
|
+
return node.kind === 75 /* SyntaxKind.Identifier */ ||
|
|
1876
|
+
node.kind === 194 /* SyntaxKind.PropertyAccessExpression */ && isDottedName(node.expression) ||
|
|
1877
|
+
node.kind === 200 /* SyntaxKind.ParenthesizedExpression */ && isDottedName(node.expression);
|
|
1878
|
+
}
|
|
1879
|
+
export function isPropertyAccessEntityNameExpression(node) {
|
|
1880
|
+
return isPropertyAccessExpression(node) && isIdentifier(node.name) && isEntityNameExpression(node.expression);
|
|
1881
|
+
}
|
|
1882
|
+
export function tryGetPropertyAccessOrIdentifierToString(expr) {
|
|
1883
|
+
if (isPropertyAccessExpression(expr)) {
|
|
1884
|
+
const baseStr = tryGetPropertyAccessOrIdentifierToString(expr.expression);
|
|
1885
|
+
if (baseStr !== undefined) {
|
|
1886
|
+
return baseStr + "." + expr.name;
|
|
1887
|
+
}
|
|
1888
|
+
}
|
|
1889
|
+
else if (isIdentifier(expr)) {
|
|
1890
|
+
return unescapeLeadingUnderscores(expr.escapedText);
|
|
1891
|
+
}
|
|
1892
|
+
return undefined;
|
|
1893
|
+
}
|
|
1894
|
+
export function isPrototypeAccess(node) {
|
|
1895
|
+
return isBindableStaticAccessExpression(node) && getElementOrPropertyAccessName(node) === "prototype";
|
|
1896
|
+
}
|
|
1897
|
+
export function isRightSideOfQualifiedNameOrPropertyAccess(node) {
|
|
1898
|
+
return (node.parent.kind === 153 /* SyntaxKind.QualifiedName */ && node.parent.right === node) ||
|
|
1899
|
+
(node.parent.kind === 194 /* SyntaxKind.PropertyAccessExpression */ && node.parent.name === node);
|
|
1900
|
+
}
|
|
1901
|
+
export function isEmptyArrayLiteral(expression) {
|
|
1902
|
+
return expression.kind === 192 /* SyntaxKind.ArrayLiteralExpression */ &&
|
|
1903
|
+
expression.elements.length === 0;
|
|
1904
|
+
}
|
|
1905
|
+
/** Return ".ts", ".d.ts", or ".tsx", if that is the extension. */
|
|
1906
|
+
export function tryExtractTSExtension(fileName) {
|
|
1907
|
+
return find(supportedTSExtensionsForExtractExtension, extension => fileExtensionIs(fileName, extension));
|
|
1908
|
+
}
|
|
1909
|
+
export function createRange(pos, end = pos) {
|
|
1910
|
+
Debug.assert(end >= pos || end === -1);
|
|
1911
|
+
return { pos, end };
|
|
1912
|
+
}
|
|
1913
|
+
export function rangeIsOnSingleLine(range, sourceFile) {
|
|
1914
|
+
return rangeStartIsOnSameLineAsRangeEnd(range, range, sourceFile);
|
|
1915
|
+
}
|
|
1916
|
+
export function rangeStartPositionsAreOnSameLine(range1, range2, sourceFile) {
|
|
1917
|
+
return positionsAreOnSameLine(getStartPositionOfRange(range1, sourceFile, /*includeComments*/ false), getStartPositionOfRange(range2, sourceFile, /*includeComments*/ false), sourceFile);
|
|
1918
|
+
}
|
|
1919
|
+
export function rangeEndPositionsAreOnSameLine(range1, range2, sourceFile) {
|
|
1920
|
+
return positionsAreOnSameLine(range1.end, range2.end, sourceFile);
|
|
1921
|
+
}
|
|
1922
|
+
export function rangeStartIsOnSameLineAsRangeEnd(range1, range2, sourceFile) {
|
|
1923
|
+
return positionsAreOnSameLine(getStartPositionOfRange(range1, sourceFile, /*includeComments*/ false), range2.end, sourceFile);
|
|
1924
|
+
}
|
|
1925
|
+
export function rangeEndIsOnSameLineAsRangeStart(range1, range2, sourceFile) {
|
|
1926
|
+
return positionsAreOnSameLine(range1.end, getStartPositionOfRange(range2, sourceFile, /*includeComments*/ false), sourceFile);
|
|
1927
|
+
}
|
|
1928
|
+
export function getLinesBetweenRangeEndAndRangeStart(range1, range2, sourceFile, includeSecondRangeComments) {
|
|
1929
|
+
const range2Start = getStartPositionOfRange(range2, sourceFile, includeSecondRangeComments);
|
|
1930
|
+
return getLinesBetweenPositions(sourceFile, range1.end, range2Start);
|
|
1931
|
+
}
|
|
1932
|
+
export function isNodeArrayMultiLine(list, sourceFile) {
|
|
1933
|
+
return !positionsAreOnSameLine(list.pos, list.end, sourceFile);
|
|
1934
|
+
}
|
|
1935
|
+
export function positionsAreOnSameLine(pos1, pos2, sourceFile) {
|
|
1936
|
+
return getLinesBetweenPositions(sourceFile, pos1, pos2) === 0;
|
|
1937
|
+
}
|
|
1938
|
+
export function getStartPositionOfRange(range, sourceFile, includeComments) {
|
|
1939
|
+
return positionIsSynthesized(range.pos) ? -1 : skipTrivia(sourceFile.text, range.pos, /*stopAfterLineBreak*/ false, includeComments);
|
|
1940
|
+
}
|
|
1941
|
+
export function getLinesBetweenPositionAndPrecedingNonWhitespaceCharacter(pos, stopPos, sourceFile, includeComments) {
|
|
1942
|
+
const startPos = skipTrivia(sourceFile.text, pos, /*stopAfterLineBreak*/ false, includeComments);
|
|
1943
|
+
const prevPos = getPreviousNonWhitespacePosition(startPos, stopPos, sourceFile);
|
|
1944
|
+
return getLinesBetweenPositions(sourceFile, prevPos ?? stopPos, startPos);
|
|
1945
|
+
}
|
|
1946
|
+
export function getLinesBetweenPositionAndNextNonWhitespaceCharacter(pos, stopPos, sourceFile, includeComments) {
|
|
1947
|
+
const nextPos = skipTrivia(sourceFile.text, pos, /*stopAfterLineBreak*/ false, includeComments);
|
|
1948
|
+
return getLinesBetweenPositions(sourceFile, pos, Math.min(stopPos, nextPos));
|
|
1949
|
+
}
|
|
1950
|
+
function getPreviousNonWhitespacePosition(pos, stopPos = 0, sourceFile) {
|
|
1951
|
+
while (pos-- > stopPos) {
|
|
1952
|
+
if (!isWhiteSpaceLike(sourceFile.text.charCodeAt(pos))) {
|
|
1953
|
+
return pos;
|
|
1954
|
+
}
|
|
1955
|
+
}
|
|
1956
|
+
}
|
|
1957
|
+
/**
|
|
1958
|
+
* Os modificadores da declaração de valor do símbolo. A propriedade sintética de uma união e o protótipo não têm
|
|
1959
|
+
* declaração, e a acessibilidade e o `static` que o `tsc` dava a eles eram da classe.
|
|
1960
|
+
*/
|
|
1961
|
+
export function getDeclarationModifierFlagsFromSymbol(s) {
|
|
1962
|
+
return s.valueDeclaration ? getCombinedModifierFlags(s.valueDeclaration) : 0;
|
|
1963
|
+
}
|
|
1964
|
+
/**
|
|
1965
|
+
* As flags do símbolo somadas às do exportado dele: o membro exportado de um módulo ganha um símbolo local só com o
|
|
1966
|
+
* `ExportValue`, e as flags de verdade ficam no de exportação (o `declareModuleMember` do binder).
|
|
1967
|
+
*/
|
|
1968
|
+
export function getCombinedLocalAndExportSymbolFlags(symbol) {
|
|
1969
|
+
return symbol.exportSymbol ? symbol.exportSymbol.flags | symbol.flags : symbol.flags;
|
|
1970
|
+
}
|
|
1971
|
+
export function isWriteOnlyAccess(node) {
|
|
1972
|
+
return accessKind(node) === 1 /* AccessKind.Write */;
|
|
1973
|
+
}
|
|
1974
|
+
export function isWriteAccess(node) {
|
|
1975
|
+
return accessKind(node) !== 0 /* AccessKind.Read */;
|
|
1976
|
+
}
|
|
1977
|
+
var AccessKind;
|
|
1978
|
+
(function (AccessKind) {
|
|
1979
|
+
/** Only reads from a variable. */
|
|
1980
|
+
AccessKind[AccessKind["Read"] = 0] = "Read";
|
|
1981
|
+
/** Only writes to a variable without using the result. E.g.: `x++;`. */
|
|
1982
|
+
AccessKind[AccessKind["Write"] = 1] = "Write";
|
|
1983
|
+
/** Writes to a variable and uses the result as an expression. E.g.: `f(x++);`. */
|
|
1984
|
+
AccessKind[AccessKind["ReadWrite"] = 2] = "ReadWrite";
|
|
1985
|
+
})(AccessKind || (AccessKind = {}));
|
|
1986
|
+
function accessKind(node) {
|
|
1987
|
+
const { parent } = node;
|
|
1988
|
+
if (!parent)
|
|
1989
|
+
return 0 /* AccessKind.Read */;
|
|
1990
|
+
switch (parent.kind) {
|
|
1991
|
+
case 200 /* SyntaxKind.ParenthesizedExpression */:
|
|
1992
|
+
return accessKind(parent);
|
|
1993
|
+
case 208 /* SyntaxKind.PostfixUnaryExpression */:
|
|
1994
|
+
case 207 /* SyntaxKind.PrefixUnaryExpression */:
|
|
1995
|
+
const { operator } = parent;
|
|
1996
|
+
return operator === 45 /* SyntaxKind.PlusPlusToken */ || operator === 46 /* SyntaxKind.MinusMinusToken */ ? writeOrReadWrite() : 0 /* AccessKind.Read */;
|
|
1997
|
+
case 209 /* SyntaxKind.BinaryExpression */:
|
|
1998
|
+
const { left, operatorToken } = parent;
|
|
1999
|
+
return left === node && isAssignmentOperator(operatorToken.kind) ?
|
|
2000
|
+
operatorToken.kind === 62 /* SyntaxKind.EqualsToken */ ? 1 /* AccessKind.Write */ : writeOrReadWrite()
|
|
2001
|
+
: 0 /* AccessKind.Read */;
|
|
2002
|
+
case 194 /* SyntaxKind.PropertyAccessExpression */:
|
|
2003
|
+
return parent.name !== node ? 0 /* AccessKind.Read */ : accessKind(parent);
|
|
2004
|
+
case 281 /* SyntaxKind.PropertyAssignment */: {
|
|
2005
|
+
const parentAccess = accessKind(parent.parent);
|
|
2006
|
+
// In `({ x: varname }) = { x: 1 }`, the left `x` is a read, the right `x` is a write.
|
|
2007
|
+
return node === parent.name ? reverseAccessKind(parentAccess) : parentAccess;
|
|
2008
|
+
}
|
|
2009
|
+
case 282 /* SyntaxKind.ShorthandPropertyAssignment */:
|
|
2010
|
+
// Assume it's the local variable being accessed, since we don't check public properties for --noUnusedLocals.
|
|
2011
|
+
return node === parent.objectAssignmentInitializer ? 0 /* AccessKind.Read */ : accessKind(parent.parent);
|
|
2012
|
+
case 192 /* SyntaxKind.ArrayLiteralExpression */:
|
|
2013
|
+
return accessKind(parent);
|
|
2014
|
+
default:
|
|
2015
|
+
return 0 /* AccessKind.Read */;
|
|
2016
|
+
}
|
|
2017
|
+
function writeOrReadWrite() {
|
|
2018
|
+
// If grandparent is not an ExpressionStatement, this is used as an expression in addition to having a side effect.
|
|
2019
|
+
return parent.parent && skipParenthesesUp(parent.parent).kind === 226 /* SyntaxKind.ExpressionStatement */ ? 1 /* AccessKind.Write */ : 2 /* AccessKind.ReadWrite */;
|
|
2020
|
+
}
|
|
2021
|
+
}
|
|
2022
|
+
function reverseAccessKind(a) {
|
|
2023
|
+
switch (a) {
|
|
2024
|
+
case 0 /* AccessKind.Read */:
|
|
2025
|
+
return 1 /* AccessKind.Write */;
|
|
2026
|
+
case 1 /* AccessKind.Write */:
|
|
2027
|
+
return 0 /* AccessKind.Read */;
|
|
2028
|
+
case 2 /* AccessKind.ReadWrite */:
|
|
2029
|
+
return 2 /* AccessKind.ReadWrite */;
|
|
2030
|
+
default:
|
|
2031
|
+
return Debug.assertNever(a);
|
|
2032
|
+
}
|
|
2033
|
+
}
|
|
2034
|
+
export function compareDataObjects(dst, src) {
|
|
2035
|
+
if (!dst || !src || Object.keys(dst).length !== Object.keys(src).length) {
|
|
2036
|
+
return false;
|
|
2037
|
+
}
|
|
2038
|
+
for (const e in dst) {
|
|
2039
|
+
if (typeof dst[e] === "object") {
|
|
2040
|
+
if (!compareDataObjects(dst[e], src[e])) {
|
|
2041
|
+
return false;
|
|
2042
|
+
}
|
|
2043
|
+
}
|
|
2044
|
+
else if (typeof dst[e] !== "function") {
|
|
2045
|
+
if (dst[e] !== src[e]) {
|
|
2046
|
+
return false;
|
|
2047
|
+
}
|
|
2048
|
+
}
|
|
2049
|
+
}
|
|
2050
|
+
return true;
|
|
2051
|
+
}
|
|
2052
|
+
export function showModuleSpecifier({ moduleSpecifier }) {
|
|
2053
|
+
return isStringLiteral(moduleSpecifier) ? moduleSpecifier.text : getTextOfNode(moduleSpecifier);
|
|
2054
|
+
}
|
|
2055
|
+
export function getLastChild(node) {
|
|
2056
|
+
let lastChild;
|
|
2057
|
+
forEachChild(node, child => {
|
|
2058
|
+
if (nodeIsPresent(child))
|
|
2059
|
+
lastChild = child;
|
|
2060
|
+
}, children => {
|
|
2061
|
+
// As an optimization, jump straight to the end of the list.
|
|
2062
|
+
for (let i = children.length - 1; i >= 0; i--) {
|
|
2063
|
+
if (nodeIsPresent(children[i])) {
|
|
2064
|
+
lastChild = children[i];
|
|
2065
|
+
break;
|
|
2066
|
+
}
|
|
2067
|
+
}
|
|
2068
|
+
});
|
|
2069
|
+
return lastChild;
|
|
2070
|
+
}
|
|
2071
|
+
export function addToSeen(seen, key, value = true) {
|
|
2072
|
+
key = String(key);
|
|
2073
|
+
if (seen.has(key)) {
|
|
2074
|
+
return false;
|
|
2075
|
+
}
|
|
2076
|
+
seen.set(key, value);
|
|
2077
|
+
return true;
|
|
2078
|
+
}
|
|
2079
|
+
export function isObjectTypeDeclaration(node) {
|
|
2080
|
+
// Na tag, também a classe e a interface (CK-02).
|
|
2081
|
+
return isTypeLiteralNode(node);
|
|
2082
|
+
}
|
|
2083
|
+
export function isTypeNodeKind(kind) {
|
|
2084
|
+
return (kind >= 168 /* SyntaxKind.FirstTypeNode */ && kind <= 188 /* SyntaxKind.LastTypeNode */)
|
|
2085
|
+
|| kind === 125 /* SyntaxKind.AnyKeyword */
|
|
2086
|
+
|| kind === 148 /* SyntaxKind.UnknownKeyword */
|
|
2087
|
+
|| kind === 140 /* SyntaxKind.NumberKeyword */
|
|
2088
|
+
|| kind === 151 /* SyntaxKind.BigIntKeyword */
|
|
2089
|
+
|| kind === 141 /* SyntaxKind.ObjectKeyword */
|
|
2090
|
+
|| kind === 128 /* SyntaxKind.BooleanKeyword */
|
|
2091
|
+
|| kind === 143 /* SyntaxKind.StringKeyword */
|
|
2092
|
+
|| kind === 144 /* SyntaxKind.SymbolKeyword */
|
|
2093
|
+
|| kind === 110 /* SyntaxKind.VoidKeyword */
|
|
2094
|
+
|| kind === 146 /* SyntaxKind.UndefinedKeyword */
|
|
2095
|
+
|| kind === 100 /* SyntaxKind.NullKeyword */
|
|
2096
|
+
|| kind === 137 /* SyntaxKind.NeverKeyword */;
|
|
2097
|
+
}
|
|
2098
|
+
export function isAccessExpression(node) {
|
|
2099
|
+
return node.kind === 194 /* SyntaxKind.PropertyAccessExpression */ || node.kind === 195 /* SyntaxKind.ElementAccessExpression */;
|
|
2100
|
+
}
|
|
2101
|
+
export function isNamedImportsOrExports(node) {
|
|
2102
|
+
return node.kind === 257 /* SyntaxKind.NamedImports */ || node.kind === 261 /* SyntaxKind.NamedExports */;
|
|
2103
|
+
}
|
|
2104
|
+
function Symbol(flags, name) {
|
|
2105
|
+
this.flags = flags;
|
|
2106
|
+
this.escapedName = name;
|
|
2107
|
+
this.declarations = undefined;
|
|
2108
|
+
this.valueDeclaration = undefined;
|
|
2109
|
+
this.id = undefined;
|
|
2110
|
+
this.mergeId = undefined;
|
|
2111
|
+
this.parent = undefined;
|
|
2112
|
+
}
|
|
2113
|
+
function Node(kind, pos, end) {
|
|
2114
|
+
this.pos = pos;
|
|
2115
|
+
this.end = end;
|
|
2116
|
+
this.kind = kind;
|
|
2117
|
+
this.id = 0;
|
|
2118
|
+
this.flags = 0 /* NodeFlags.None */;
|
|
2119
|
+
this.modifierFlagsCache = 0 /* ModifierFlags.None */;
|
|
2120
|
+
this.transformFlags = 0 /* TransformFlags.None */;
|
|
2121
|
+
this.parent = undefined;
|
|
2122
|
+
this.original = undefined;
|
|
2123
|
+
}
|
|
2124
|
+
function Token(kind, pos, end) {
|
|
2125
|
+
this.pos = pos;
|
|
2126
|
+
this.end = end;
|
|
2127
|
+
this.kind = kind;
|
|
2128
|
+
this.id = 0;
|
|
2129
|
+
this.flags = 0 /* NodeFlags.None */;
|
|
2130
|
+
this.transformFlags = 0 /* TransformFlags.None */;
|
|
2131
|
+
this.parent = undefined;
|
|
2132
|
+
}
|
|
2133
|
+
function Identifier(kind, pos, end) {
|
|
2134
|
+
this.pos = pos;
|
|
2135
|
+
this.end = end;
|
|
2136
|
+
this.kind = kind;
|
|
2137
|
+
this.id = 0;
|
|
2138
|
+
this.flags = 0 /* NodeFlags.None */;
|
|
2139
|
+
this.transformFlags = 0 /* TransformFlags.None */;
|
|
2140
|
+
this.parent = undefined;
|
|
2141
|
+
this.original = undefined;
|
|
2142
|
+
this.flowNode = undefined;
|
|
2143
|
+
}
|
|
2144
|
+
function SourceMapSource(fileName, text, skipTrivia) {
|
|
2145
|
+
this.fileName = fileName;
|
|
2146
|
+
this.text = text;
|
|
2147
|
+
this.skipTrivia = skipTrivia || (pos => pos);
|
|
2148
|
+
}
|
|
2149
|
+
export let objectAllocator = {
|
|
2150
|
+
getNodeConstructor: () => Node,
|
|
2151
|
+
getTokenConstructor: () => Token,
|
|
2152
|
+
getIdentifierConstructor: () => Identifier,
|
|
2153
|
+
getSourceFileConstructor: () => Node,
|
|
2154
|
+
getSymbolConstructor: () => Symbol,
|
|
2155
|
+
getSourceMapSourceConstructor: () => SourceMapSource,
|
|
2156
|
+
};
|
|
2157
|
+
/**
|
|
2158
|
+
* Troca os construtores da árvore. O language service troca os de cada nó e o do símbolo pelos dele, que têm os métodos
|
|
2159
|
+
* que os serviços chamam (`node.getStart()`, `symbol.getDocumentationComment()`), ao carregar.
|
|
2160
|
+
*/
|
|
2161
|
+
export function setObjectAllocator(alloc) {
|
|
2162
|
+
objectAllocator = alloc;
|
|
2163
|
+
}
|
|
2164
|
+
export function formatStringFromArgs(text, args, baseIndex = 0) {
|
|
2165
|
+
return text.replace(/{(\d+)}/g, (_match, index) => "" + Debug.checkDefined(args[+index + baseIndex]));
|
|
2166
|
+
}
|
|
2167
|
+
export let localizedDiagnosticMessages;
|
|
2168
|
+
export function setLocalizedDiagnosticMessages(messages) {
|
|
2169
|
+
localizedDiagnosticMessages = messages;
|
|
2170
|
+
}
|
|
2171
|
+
export function getLocaleSpecificMessage(message) {
|
|
2172
|
+
return localizedDiagnosticMessages && localizedDiagnosticMessages[message.key] || message.message;
|
|
2173
|
+
}
|
|
2174
|
+
export function createFileDiagnostic(file, start, length, message) {
|
|
2175
|
+
Debug.assertGreaterThanOrEqual(start, 0);
|
|
2176
|
+
Debug.assertGreaterThanOrEqual(length, 0);
|
|
2177
|
+
if (file) {
|
|
2178
|
+
Debug.assertLessThanOrEqual(start, file.text.length);
|
|
2179
|
+
Debug.assertLessThanOrEqual(start + length, file.text.length);
|
|
2180
|
+
}
|
|
2181
|
+
let text = getLocaleSpecificMessage(message);
|
|
2182
|
+
if (arguments.length > 4) {
|
|
2183
|
+
text = formatStringFromArgs(text, arguments, 4);
|
|
2184
|
+
}
|
|
2185
|
+
return {
|
|
2186
|
+
file,
|
|
2187
|
+
start,
|
|
2188
|
+
length,
|
|
2189
|
+
messageText: text,
|
|
2190
|
+
category: message.category,
|
|
2191
|
+
code: message.code,
|
|
2192
|
+
reportsUnnecessary: message.reportsUnnecessary,
|
|
2193
|
+
};
|
|
2194
|
+
}
|
|
2195
|
+
export function formatMessage(_dummy, message) {
|
|
2196
|
+
let text = getLocaleSpecificMessage(message);
|
|
2197
|
+
if (arguments.length > 2) {
|
|
2198
|
+
text = formatStringFromArgs(text, arguments, 2);
|
|
2199
|
+
}
|
|
2200
|
+
return text;
|
|
2201
|
+
}
|
|
2202
|
+
export function createCompilerDiagnostic(message) {
|
|
2203
|
+
let text = getLocaleSpecificMessage(message);
|
|
2204
|
+
if (arguments.length > 1) {
|
|
2205
|
+
text = formatStringFromArgs(text, arguments, 1);
|
|
2206
|
+
}
|
|
2207
|
+
return {
|
|
2208
|
+
file: undefined,
|
|
2209
|
+
start: undefined,
|
|
2210
|
+
length: undefined,
|
|
2211
|
+
messageText: text,
|
|
2212
|
+
category: message.category,
|
|
2213
|
+
code: message.code,
|
|
2214
|
+
reportsUnnecessary: message.reportsUnnecessary,
|
|
2215
|
+
};
|
|
2216
|
+
}
|
|
2217
|
+
export function chainDiagnosticMessages(details, message) {
|
|
2218
|
+
let text = getLocaleSpecificMessage(message);
|
|
2219
|
+
if (arguments.length > 2) {
|
|
2220
|
+
text = formatStringFromArgs(text, arguments, 2);
|
|
2221
|
+
}
|
|
2222
|
+
return {
|
|
2223
|
+
messageText: text,
|
|
2224
|
+
category: message.category,
|
|
2225
|
+
code: message.code,
|
|
2226
|
+
next: details === undefined || Array.isArray(details) ? details : [details]
|
|
2227
|
+
};
|
|
2228
|
+
}
|
|
2229
|
+
export function concatenateDiagnosticMessageChains(headChain, tailChain) {
|
|
2230
|
+
let lastChain = headChain;
|
|
2231
|
+
while (lastChain.next) {
|
|
2232
|
+
lastChain = lastChain.next[0];
|
|
2233
|
+
}
|
|
2234
|
+
lastChain.next = [tailChain];
|
|
2235
|
+
}
|
|
2236
|
+
/** O texto inteiro de uma mensagem encadeada: cada elo numa linha, indentado de dois em dois espaços pela profundidade. */
|
|
2237
|
+
export function flattenDiagnosticMessageText(diag, newLine, indent = 0) {
|
|
2238
|
+
if (isString(diag)) {
|
|
2239
|
+
return diag;
|
|
2240
|
+
}
|
|
2241
|
+
else if (diag === undefined) {
|
|
2242
|
+
return "";
|
|
2243
|
+
}
|
|
2244
|
+
let result = "";
|
|
2245
|
+
if (indent) {
|
|
2246
|
+
result += newLine;
|
|
2247
|
+
for (let i = 0; i < indent; i++) {
|
|
2248
|
+
result += " ";
|
|
2249
|
+
}
|
|
2250
|
+
}
|
|
2251
|
+
result += diag.messageText;
|
|
2252
|
+
indent++;
|
|
2253
|
+
if (diag.next) {
|
|
2254
|
+
for (const kid of diag.next) {
|
|
2255
|
+
result += flattenDiagnosticMessageText(kid, newLine, indent);
|
|
2256
|
+
}
|
|
2257
|
+
}
|
|
2258
|
+
return result;
|
|
2259
|
+
}
|
|
2260
|
+
function getDiagnosticFilePath(diagnostic) {
|
|
2261
|
+
return diagnostic.file ? diagnostic.file.path : undefined;
|
|
2262
|
+
}
|
|
2263
|
+
export function compareDiagnostics(d1, d2) {
|
|
2264
|
+
return compareDiagnosticsSkipRelatedInformation(d1, d2) ||
|
|
2265
|
+
compareRelatedInformation(d1, d2) ||
|
|
2266
|
+
0 /* Comparison.EqualTo */;
|
|
2267
|
+
}
|
|
2268
|
+
export function compareDiagnosticsSkipRelatedInformation(d1, d2) {
|
|
2269
|
+
return compareStringsCaseSensitive(getDiagnosticFilePath(d1), getDiagnosticFilePath(d2)) ||
|
|
2270
|
+
compareValues(d1.start, d2.start) ||
|
|
2271
|
+
compareValues(d1.length, d2.length) ||
|
|
2272
|
+
compareValues(d1.code, d2.code) ||
|
|
2273
|
+
compareMessageText(d1.messageText, d2.messageText) ||
|
|
2274
|
+
0 /* Comparison.EqualTo */;
|
|
2275
|
+
}
|
|
2276
|
+
function compareRelatedInformation(d1, d2) {
|
|
2277
|
+
if (!d1.relatedInformation && !d2.relatedInformation) {
|
|
2278
|
+
return 0 /* Comparison.EqualTo */;
|
|
2279
|
+
}
|
|
2280
|
+
if (d1.relatedInformation && d2.relatedInformation) {
|
|
2281
|
+
return compareValues(d1.relatedInformation.length, d2.relatedInformation.length) || forEach(d1.relatedInformation, (d1i, index) => {
|
|
2282
|
+
const d2i = d2.relatedInformation[index];
|
|
2283
|
+
return compareDiagnostics(d1i, d2i); // EqualTo is 0, so falsy, and will cause the next item to be compared
|
|
2284
|
+
}) || 0 /* Comparison.EqualTo */;
|
|
2285
|
+
}
|
|
2286
|
+
return d1.relatedInformation ? -1 /* Comparison.LessThan */ : 1 /* Comparison.GreaterThan */;
|
|
2287
|
+
}
|
|
2288
|
+
function compareMessageText(t1, t2) {
|
|
2289
|
+
if (typeof t1 === "string" && typeof t2 === "string") {
|
|
2290
|
+
return compareStringsCaseSensitive(t1, t2);
|
|
2291
|
+
}
|
|
2292
|
+
else if (typeof t1 === "string") {
|
|
2293
|
+
return -1 /* Comparison.LessThan */;
|
|
2294
|
+
}
|
|
2295
|
+
else if (typeof t2 === "string") {
|
|
2296
|
+
return 1 /* Comparison.GreaterThan */;
|
|
2297
|
+
}
|
|
2298
|
+
let res = compareStringsCaseSensitive(t1.messageText, t2.messageText);
|
|
2299
|
+
if (res) {
|
|
2300
|
+
return res;
|
|
2301
|
+
}
|
|
2302
|
+
if (!t1.next && !t2.next) {
|
|
2303
|
+
return 0 /* Comparison.EqualTo */;
|
|
2304
|
+
}
|
|
2305
|
+
if (!t1.next) {
|
|
2306
|
+
return -1 /* Comparison.LessThan */;
|
|
2307
|
+
}
|
|
2308
|
+
if (!t2.next) {
|
|
2309
|
+
return 1 /* Comparison.GreaterThan */;
|
|
2310
|
+
}
|
|
2311
|
+
const len = Math.min(t1.next.length, t2.next.length);
|
|
2312
|
+
for (let i = 0; i < len; i++) {
|
|
2313
|
+
res = compareMessageText(t1.next[i], t2.next[i]);
|
|
2314
|
+
if (res) {
|
|
2315
|
+
return res;
|
|
2316
|
+
}
|
|
2317
|
+
}
|
|
2318
|
+
if (t1.next.length < t2.next.length) {
|
|
2319
|
+
return -1 /* Comparison.LessThan */;
|
|
2320
|
+
}
|
|
2321
|
+
else if (t1.next.length > t2.next.length) {
|
|
2322
|
+
return 1 /* Comparison.GreaterThan */;
|
|
2323
|
+
}
|
|
2324
|
+
return 0 /* Comparison.EqualTo */;
|
|
2325
|
+
}
|
|
2326
|
+
export function unreachableCodeIsError(options) {
|
|
2327
|
+
return options.allowUnreachableCode === false;
|
|
2328
|
+
}
|
|
2329
|
+
function stripLeadingDirectorySeparator(s) {
|
|
2330
|
+
return isAnyDirectorySeparator(s.charCodeAt(0)) ? s.slice(1) : undefined;
|
|
2331
|
+
}
|
|
2332
|
+
export function tryRemoveDirectoryPrefix(path, dirPath, getCanonicalFileName) {
|
|
2333
|
+
const withoutPrefix = tryRemovePrefix(path, dirPath, getCanonicalFileName);
|
|
2334
|
+
return withoutPrefix === undefined ? undefined : stripLeadingDirectorySeparator(withoutPrefix);
|
|
2335
|
+
}
|
|
2336
|
+
export function ensureScriptKind(fileName, scriptKind) {
|
|
2337
|
+
// Using scriptKind as a condition handles both:
|
|
2338
|
+
// - 'scriptKind' is unspecified and thus it is `undefined`
|
|
2339
|
+
// - 'scriptKind' is set and it is `Unknown` (0)
|
|
2340
|
+
// If the 'scriptKind' is 'undefined' or 'Unknown' then we attempt
|
|
2341
|
+
// to get the ScriptKind from the file name. If it cannot be resolved
|
|
2342
|
+
// from the file name then the default 'TS' script kind is returned.
|
|
2343
|
+
return scriptKind || getScriptKindFromFileName(fileName) || 3 /* ScriptKind.TS */;
|
|
2344
|
+
}
|
|
2345
|
+
export function getScriptKindFromFileName(fileName) {
|
|
2346
|
+
const ext = fileName.substr(fileName.lastIndexOf("."));
|
|
2347
|
+
switch (ext.toLowerCase()) {
|
|
2348
|
+
case ".js" /* Extension.Js */:
|
|
2349
|
+
return 1 /* ScriptKind.JS */;
|
|
2350
|
+
case ".jsx" /* Extension.Jsx */:
|
|
2351
|
+
return 2 /* ScriptKind.JSX */;
|
|
2352
|
+
case ".ts" /* Extension.Ts */:
|
|
2353
|
+
return 3 /* ScriptKind.TS */;
|
|
2354
|
+
case ".tsx" /* Extension.Tsx */:
|
|
2355
|
+
return 4 /* ScriptKind.TSX */;
|
|
2356
|
+
case ".json" /* Extension.Json */:
|
|
2357
|
+
return 6 /* ScriptKind.JSON */;
|
|
2358
|
+
default:
|
|
2359
|
+
return 0 /* ScriptKind.Unknown */;
|
|
2360
|
+
}
|
|
2361
|
+
}
|
|
2362
|
+
/** Must have ".d.ts" first because if ".ts" goes first, that will be detected as the extension instead of ".d.ts". */
|
|
2363
|
+
export const supportedTSExtensionsForExtractExtension = [".d.ts" /* Extension.Dts */, ".ts" /* Extension.Ts */, ".tsx" /* Extension.Tsx */];
|
|
2364
|
+
export const supportedJSExtensions = [".js" /* Extension.Js */, ".jsx" /* Extension.Jsx */];
|
|
2365
|
+
export function hasJSFileExtension(fileName) {
|
|
2366
|
+
return some(supportedJSExtensions, extension => fileExtensionIs(fileName, extension));
|
|
2367
|
+
}
|
|
2368
|
+
const extensionsToRemove = [".d.ts" /* Extension.Dts */, ".ts" /* Extension.Ts */, ".js" /* Extension.Js */, ".tsx" /* Extension.Tsx */, ".jsx" /* Extension.Jsx */, ".json" /* Extension.Json */];
|
|
2369
|
+
export function removeFileExtension(path) {
|
|
2370
|
+
for (const ext of extensionsToRemove) {
|
|
2371
|
+
const extensionless = tryRemoveExtension(path, ext);
|
|
2372
|
+
if (extensionless !== undefined) {
|
|
2373
|
+
return extensionless;
|
|
2374
|
+
}
|
|
2375
|
+
}
|
|
2376
|
+
return path;
|
|
2377
|
+
}
|
|
2378
|
+
export function tryRemoveExtension(path, extension) {
|
|
2379
|
+
return fileExtensionIs(path, extension) ? removeExtension(path, extension) : undefined;
|
|
2380
|
+
}
|
|
2381
|
+
export function removeExtension(path, extension) {
|
|
2382
|
+
return path.substring(0, path.length - extension.length);
|
|
2383
|
+
}
|
|
2384
|
+
export function positionIsSynthesized(pos) {
|
|
2385
|
+
// This is a fast way of testing the following conditions:
|
|
2386
|
+
// pos === undefined || pos === null || isNaN(pos) || pos < 0;
|
|
2387
|
+
return !(pos >= 0);
|
|
2388
|
+
}
|
|
2389
|
+
/** True if an extension is one of the supported TypeScript extensions. */
|
|
2390
|
+
export function extensionIsTS(ext) {
|
|
2391
|
+
return ext === ".ts" /* Extension.Ts */ || ext === ".tsx" /* Extension.Tsx */ || ext === ".d.ts" /* Extension.Dts */;
|
|
2392
|
+
}
|
|
2393
|
+
export function resolutionExtensionIsTSOrJson(ext) {
|
|
2394
|
+
return extensionIsTS(ext) || ext === ".json" /* Extension.Json */;
|
|
2395
|
+
}
|
|
2396
|
+
/**
|
|
2397
|
+
* O diagnóstico de um módulo resolvido que a extensão não deixa entrar no programa, ou `undefined`. Os parâmetros dele
|
|
2398
|
+
* são o nome do módulo importado e o arquivo a que resolveu; vale também para o módulo que fica sem tipo.
|
|
2399
|
+
*/
|
|
2400
|
+
export function getResolutionDiagnostic({ extension }) {
|
|
2401
|
+
switch (extension) {
|
|
2402
|
+
case ".ts" /* Extension.Ts */:
|
|
2403
|
+
case ".d.ts" /* Extension.Dts */:
|
|
2404
|
+
// O JSX não depende de opção (CK-19): o `.tsx` entra como o `.ts`.
|
|
2405
|
+
case ".tsx" /* Extension.Tsx */:
|
|
2406
|
+
return undefined;
|
|
2407
|
+
// Na configuração fixa (CK-24, CK-47), o `allowJs` e o `resolveJsonModule` são desligados, e o `noImplicitAny`
|
|
2408
|
+
// é ligado: o JavaScript e o JSON resolvidos não entram.
|
|
2409
|
+
case ".jsx" /* Extension.Jsx */:
|
|
2410
|
+
case ".js" /* Extension.Js */:
|
|
2411
|
+
return Diagnostics.Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type;
|
|
2412
|
+
case ".json" /* Extension.Json */:
|
|
2413
|
+
return Diagnostics.Module_0_was_resolved_to_1_but_resolveJsonModule_is_not_used;
|
|
2414
|
+
}
|
|
2415
|
+
}
|
|
2416
|
+
/**
|
|
2417
|
+
* Gets the extension from a path.
|
|
2418
|
+
* Path must have a valid extension.
|
|
2419
|
+
*/
|
|
2420
|
+
export function extensionFromPath(path) {
|
|
2421
|
+
const ext = tryGetExtensionFromPath(path);
|
|
2422
|
+
return ext !== undefined ? ext : Debug.fail(`File ${path} has unknown extension.`);
|
|
2423
|
+
}
|
|
2424
|
+
export function tryGetExtensionFromPath(path) {
|
|
2425
|
+
return find(extensionsToRemove, e => fileExtensionIs(path, e));
|
|
2426
|
+
}
|
|
2427
|
+
export function sliceAfter(arr, value) {
|
|
2428
|
+
const index = arr.indexOf(value);
|
|
2429
|
+
Debug.assert(index !== -1);
|
|
2430
|
+
return arr.slice(index);
|
|
2431
|
+
}
|
|
2432
|
+
export function addRelatedInfo(diagnostic, ...relatedInformation) {
|
|
2433
|
+
if (!relatedInformation.length) {
|
|
2434
|
+
return diagnostic;
|
|
2435
|
+
}
|
|
2436
|
+
if (!diagnostic.relatedInformation) {
|
|
2437
|
+
diagnostic.relatedInformation = [];
|
|
2438
|
+
}
|
|
2439
|
+
diagnostic.relatedInformation.push(...relatedInformation);
|
|
2440
|
+
return diagnostic;
|
|
2441
|
+
}
|
|
2442
|
+
export function minAndMax(arr, getValue) {
|
|
2443
|
+
Debug.assert(arr.length !== 0);
|
|
2444
|
+
let min = getValue(arr[0]);
|
|
2445
|
+
let max = min;
|
|
2446
|
+
for (let i = 1; i < arr.length; i++) {
|
|
2447
|
+
const value = getValue(arr[i]);
|
|
2448
|
+
if (value < min) {
|
|
2449
|
+
min = value;
|
|
2450
|
+
}
|
|
2451
|
+
else if (value > max) {
|
|
2452
|
+
max = value;
|
|
2453
|
+
}
|
|
2454
|
+
}
|
|
2455
|
+
return { min, max };
|
|
2456
|
+
}
|
|
2457
|
+
export class NodeSet {
|
|
2458
|
+
map = createMap();
|
|
2459
|
+
add(node) {
|
|
2460
|
+
this.map.set(String(getNodeId(node)), node);
|
|
2461
|
+
}
|
|
2462
|
+
tryAdd(node) {
|
|
2463
|
+
if (this.has(node))
|
|
2464
|
+
return false;
|
|
2465
|
+
this.add(node);
|
|
2466
|
+
return true;
|
|
2467
|
+
}
|
|
2468
|
+
has(node) {
|
|
2469
|
+
return this.map.has(String(getNodeId(node)));
|
|
2470
|
+
}
|
|
2471
|
+
forEach(cb) {
|
|
2472
|
+
this.map.forEach(cb);
|
|
2473
|
+
}
|
|
2474
|
+
some(pred) {
|
|
2475
|
+
return forEachEntry(this.map, pred) || false;
|
|
2476
|
+
}
|
|
2477
|
+
}
|
|
2478
|
+
export class NodeMap {
|
|
2479
|
+
map = createMap();
|
|
2480
|
+
get(node) {
|
|
2481
|
+
const res = this.map.get(String(getNodeId(node)));
|
|
2482
|
+
return res && res.value;
|
|
2483
|
+
}
|
|
2484
|
+
getOrUpdate(node, setValue) {
|
|
2485
|
+
const res = this.get(node);
|
|
2486
|
+
if (res)
|
|
2487
|
+
return res;
|
|
2488
|
+
const value = setValue();
|
|
2489
|
+
this.set(node, value);
|
|
2490
|
+
return value;
|
|
2491
|
+
}
|
|
2492
|
+
set(node, value) {
|
|
2493
|
+
this.map.set(String(getNodeId(node)), { node, value });
|
|
2494
|
+
}
|
|
2495
|
+
has(node) {
|
|
2496
|
+
return this.map.has(String(getNodeId(node)));
|
|
2497
|
+
}
|
|
2498
|
+
forEach(cb) {
|
|
2499
|
+
this.map.forEach(({ node, value }) => cb(value, node));
|
|
2500
|
+
}
|
|
2501
|
+
}
|
|
2502
|
+
export function rangeOfNode(node) {
|
|
2503
|
+
return { pos: getTokenPosOfNode(node), end: node.end };
|
|
2504
|
+
}
|
|
2505
|
+
export function rangeOfTypeParameters(typeParameters) {
|
|
2506
|
+
// Include the `<>`
|
|
2507
|
+
return { pos: typeParameters.pos - 1, end: typeParameters.end + 1 };
|
|
2508
|
+
}
|
|
2509
|
+
/**
|
|
2510
|
+
* Se o arquivo fica sem checagem: o que tem a diretiva `/// <reference no-default-lib="true"/>`, a lib, que se usa e
|
|
2511
|
+
* não se checa (o `skipDefaultLibCheck` da configuração fixa, CK-24; o `skipLibCheck` é desligado).
|
|
2512
|
+
*/
|
|
2513
|
+
export function skipTypeChecking(sourceFile) {
|
|
2514
|
+
return sourceFile.hasNoDefaultLib;
|
|
2515
|
+
}
|
|
2516
|
+
export function getOrUpdate(map, key, getDefault) {
|
|
2517
|
+
const got = map.get(key);
|
|
2518
|
+
if (got === undefined) {
|
|
2519
|
+
const value = getDefault();
|
|
2520
|
+
map.set(key, value);
|
|
2521
|
+
return value;
|
|
2522
|
+
}
|
|
2523
|
+
else {
|
|
2524
|
+
return got;
|
|
2525
|
+
}
|
|
2526
|
+
}
|
|
2527
|
+
/**
|
|
2528
|
+
* Converts a bigint literal string, e.g. `0x1234n`,
|
|
2529
|
+
* to its decimal string representation, e.g. `4660`.
|
|
2530
|
+
*/
|
|
2531
|
+
export function parsePseudoBigInt(stringValue) {
|
|
2532
|
+
let log2Base;
|
|
2533
|
+
switch (stringValue.charCodeAt(1)) { // "x" in "0x123"
|
|
2534
|
+
case 98 /* CharacterCodes.b */:
|
|
2535
|
+
case 66 /* CharacterCodes.B */: // 0b or 0B
|
|
2536
|
+
log2Base = 1;
|
|
2537
|
+
break;
|
|
2538
|
+
case 111 /* CharacterCodes.o */:
|
|
2539
|
+
case 79 /* CharacterCodes.O */: // 0o or 0O
|
|
2540
|
+
log2Base = 3;
|
|
2541
|
+
break;
|
|
2542
|
+
case 120 /* CharacterCodes.x */:
|
|
2543
|
+
case 88 /* CharacterCodes.X */: // 0x or 0X
|
|
2544
|
+
log2Base = 4;
|
|
2545
|
+
break;
|
|
2546
|
+
default: // already in decimal; omit trailing "n"
|
|
2547
|
+
const nIndex = stringValue.length - 1;
|
|
2548
|
+
// Skip leading 0s
|
|
2549
|
+
let nonZeroStart = 0;
|
|
2550
|
+
while (stringValue.charCodeAt(nonZeroStart) === 48 /* CharacterCodes._0 */) {
|
|
2551
|
+
nonZeroStart++;
|
|
2552
|
+
}
|
|
2553
|
+
return stringValue.slice(nonZeroStart, nIndex) || "0";
|
|
2554
|
+
}
|
|
2555
|
+
// Omit leading "0b", "0o", or "0x", and trailing "n"
|
|
2556
|
+
const startIndex = 2, endIndex = stringValue.length - 1;
|
|
2557
|
+
const bitsNeeded = (endIndex - startIndex) * log2Base;
|
|
2558
|
+
// Stores the value specified by the string as a LE array of 16-bit integers
|
|
2559
|
+
// using Uint16 instead of Uint32 so combining steps can use bitwise operators
|
|
2560
|
+
const segments = new Uint16Array((bitsNeeded >>> 4) + (bitsNeeded & 15 ? 1 : 0));
|
|
2561
|
+
// Add the digits, one at a time
|
|
2562
|
+
for (let i = endIndex - 1, bitOffset = 0; i >= startIndex; i--, bitOffset += log2Base) {
|
|
2563
|
+
const segment = bitOffset >>> 4;
|
|
2564
|
+
const digitChar = stringValue.charCodeAt(i);
|
|
2565
|
+
// Find character range: 0-9 < A-F < a-f
|
|
2566
|
+
const digit = digitChar <= 57 /* CharacterCodes._9 */
|
|
2567
|
+
? digitChar - 48 /* CharacterCodes._0 */
|
|
2568
|
+
: 10 + digitChar -
|
|
2569
|
+
(digitChar <= 70 /* CharacterCodes.F */ ? 65 /* CharacterCodes.A */ : 97 /* CharacterCodes.a */);
|
|
2570
|
+
const shiftedDigit = digit << (bitOffset & 15);
|
|
2571
|
+
segments[segment] |= shiftedDigit;
|
|
2572
|
+
const residual = shiftedDigit >>> 16;
|
|
2573
|
+
if (residual)
|
|
2574
|
+
segments[segment + 1] |= residual; // overflows segment
|
|
2575
|
+
}
|
|
2576
|
+
// Repeatedly divide segments by 10 and add remainder to base10Value
|
|
2577
|
+
let base10Value = "";
|
|
2578
|
+
let firstNonzeroSegment = segments.length - 1;
|
|
2579
|
+
let segmentsRemaining = true;
|
|
2580
|
+
while (segmentsRemaining) {
|
|
2581
|
+
let mod10 = 0;
|
|
2582
|
+
segmentsRemaining = false;
|
|
2583
|
+
for (let segment = firstNonzeroSegment; segment >= 0; segment--) {
|
|
2584
|
+
const newSegment = mod10 << 16 | segments[segment];
|
|
2585
|
+
const segmentValue = (newSegment / 10) | 0;
|
|
2586
|
+
segments[segment] = segmentValue;
|
|
2587
|
+
mod10 = newSegment - segmentValue * 10;
|
|
2588
|
+
if (segmentValue && !segmentsRemaining) {
|
|
2589
|
+
firstNonzeroSegment = segment;
|
|
2590
|
+
segmentsRemaining = true;
|
|
2591
|
+
}
|
|
2592
|
+
}
|
|
2593
|
+
base10Value = mod10 + base10Value;
|
|
2594
|
+
}
|
|
2595
|
+
return base10Value;
|
|
2596
|
+
}
|
|
2597
|
+
export function pseudoBigIntToString({ negative, base10Value }) {
|
|
2598
|
+
return (negative && base10Value !== "0" ? "-" : "") + base10Value;
|
|
2599
|
+
}
|
|
2600
|
+
export function isValidTypeOnlyAliasUseSite(useSite) {
|
|
2601
|
+
return !!(useSite.flags & 8388608 /* NodeFlags.Ambient */)
|
|
2602
|
+
|| isPartOfTypeQuery(useSite)
|
|
2603
|
+
|| isPartOfPossiblyValidTypeOrAbstractComputedPropertyName(useSite)
|
|
2604
|
+
|| !isExpressionNode(useSite);
|
|
2605
|
+
}
|
|
2606
|
+
export function typeOnlyDeclarationIsExport(typeOnlyDeclaration) {
|
|
2607
|
+
return typeOnlyDeclaration.kind === 263 /* SyntaxKind.ExportSpecifier */;
|
|
2608
|
+
}
|
|
2609
|
+
function isPartOfPossiblyValidTypeOrAbstractComputedPropertyName(node) {
|
|
2610
|
+
while (node.kind === 75 /* SyntaxKind.Identifier */ || node.kind === 194 /* SyntaxKind.PropertyAccessExpression */) {
|
|
2611
|
+
node = node.parent;
|
|
2612
|
+
}
|
|
2613
|
+
if (node.kind !== 154 /* SyntaxKind.ComputedPropertyName */) {
|
|
2614
|
+
return false;
|
|
2615
|
+
}
|
|
2616
|
+
const containerKind = node.parent.parent.kind;
|
|
2617
|
+
return containerKind === 173 /* SyntaxKind.TypeLiteral */;
|
|
2618
|
+
}
|
|
2619
|
+
export function isIdentifierTypeReference(node) {
|
|
2620
|
+
return isTypeReferenceNode(node) && isIdentifier(node.typeName);
|
|
2621
|
+
}
|
|
2622
|
+
export function arrayIsHomogeneous(array, comparer = equateValues) {
|
|
2623
|
+
if (array.length < 2)
|
|
2624
|
+
return true;
|
|
2625
|
+
const first = array[0];
|
|
2626
|
+
for (let i = 1, length = array.length; i < length; i++) {
|
|
2627
|
+
const target = array[i];
|
|
2628
|
+
if (!comparer(first, target))
|
|
2629
|
+
return false;
|
|
2630
|
+
}
|
|
2631
|
+
return true;
|
|
2632
|
+
}
|