.gitignore added
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / tsutils / util / usage.js
1 "use strict";\r
2 Object.defineProperty(exports, "__esModule", { value: true });\r
3 exports.collectVariableUsage = exports.getDeclarationDomain = exports.getUsageDomain = exports.UsageDomain = exports.DeclarationDomain = void 0;\r
4 const util_1 = require("./util");\r
5 const ts = require("typescript");\r
6 var DeclarationDomain;\r
7 (function (DeclarationDomain) {\r
8     DeclarationDomain[DeclarationDomain["Namespace"] = 1] = "Namespace";\r
9     DeclarationDomain[DeclarationDomain["Type"] = 2] = "Type";\r
10     DeclarationDomain[DeclarationDomain["Value"] = 4] = "Value";\r
11     DeclarationDomain[DeclarationDomain["Import"] = 8] = "Import";\r
12     DeclarationDomain[DeclarationDomain["Any"] = 7] = "Any";\r
13 })(DeclarationDomain = exports.DeclarationDomain || (exports.DeclarationDomain = {}));\r
14 var UsageDomain;\r
15 (function (UsageDomain) {\r
16     UsageDomain[UsageDomain["Namespace"] = 1] = "Namespace";\r
17     UsageDomain[UsageDomain["Type"] = 2] = "Type";\r
18     UsageDomain[UsageDomain["Value"] = 4] = "Value";\r
19     UsageDomain[UsageDomain["ValueOrNamespace"] = 5] = "ValueOrNamespace";\r
20     UsageDomain[UsageDomain["Any"] = 7] = "Any";\r
21     UsageDomain[UsageDomain["TypeQuery"] = 8] = "TypeQuery";\r
22 })(UsageDomain = exports.UsageDomain || (exports.UsageDomain = {}));\r
23 // TODO handle cases where values are used only for their types, e.g. `declare [propSymbol]: number`\r
24 function getUsageDomain(node) {\r
25     const parent = node.parent;\r
26     switch (parent.kind) {\r
27         case ts.SyntaxKind.TypeReference:\r
28             return node.originalKeywordKind !== ts.SyntaxKind.ConstKeyword ? 2 /* Type */ : undefined;\r
29         case ts.SyntaxKind.ExpressionWithTypeArguments:\r
30             return parent.parent.token === ts.SyntaxKind.ImplementsKeyword ||\r
31                 parent.parent.parent.kind === ts.SyntaxKind.InterfaceDeclaration\r
32                 ? 2 /* Type */\r
33                 : 4 /* Value */;\r
34         case ts.SyntaxKind.TypeQuery:\r
35             return 5 /* ValueOrNamespace */ | 8 /* TypeQuery */;\r
36         case ts.SyntaxKind.QualifiedName:\r
37             if (parent.left === node) {\r
38                 if (getEntityNameParent(parent).kind === ts.SyntaxKind.TypeQuery)\r
39                     return 1 /* Namespace */ | 8 /* TypeQuery */;\r
40                 return 1 /* Namespace */;\r
41             }\r
42             break;\r
43         case ts.SyntaxKind.ExportSpecifier:\r
44             // either {name} or {propertyName as name}\r
45             if (parent.propertyName === undefined ||\r
46                 parent.propertyName === node)\r
47                 return 7 /* Any */; // TODO handle type-only exports\r
48             break;\r
49         case ts.SyntaxKind.ExportAssignment:\r
50             return 7 /* Any */;\r
51         // Value\r
52         case ts.SyntaxKind.BindingElement:\r
53             if (parent.initializer === node)\r
54                 return 5 /* ValueOrNamespace */;\r
55             break;\r
56         case ts.SyntaxKind.Parameter:\r
57         case ts.SyntaxKind.EnumMember:\r
58         case ts.SyntaxKind.PropertyDeclaration:\r
59         case ts.SyntaxKind.VariableDeclaration:\r
60         case ts.SyntaxKind.PropertyAssignment:\r
61         case ts.SyntaxKind.PropertyAccessExpression:\r
62         case ts.SyntaxKind.ImportEqualsDeclaration:\r
63             if (parent.name !== node)\r
64                 return 5 /* ValueOrNamespace */; // TODO handle type-only imports\r
65             break;\r
66         case ts.SyntaxKind.JsxAttribute:\r
67         case ts.SyntaxKind.FunctionDeclaration:\r
68         case ts.SyntaxKind.FunctionExpression:\r
69         case ts.SyntaxKind.NamespaceImport:\r
70         case ts.SyntaxKind.ClassDeclaration:\r
71         case ts.SyntaxKind.ClassExpression:\r
72         case ts.SyntaxKind.ModuleDeclaration:\r
73         case ts.SyntaxKind.MethodDeclaration:\r
74         case ts.SyntaxKind.EnumDeclaration:\r
75         case ts.SyntaxKind.GetAccessor:\r
76         case ts.SyntaxKind.SetAccessor:\r
77         case ts.SyntaxKind.LabeledStatement:\r
78         case ts.SyntaxKind.BreakStatement:\r
79         case ts.SyntaxKind.ContinueStatement:\r
80         case ts.SyntaxKind.ImportClause:\r
81         case ts.SyntaxKind.ImportSpecifier:\r
82         case ts.SyntaxKind.TypePredicate: // TODO this actually references a parameter\r
83         case ts.SyntaxKind.MethodSignature:\r
84         case ts.SyntaxKind.PropertySignature:\r
85         case ts.SyntaxKind.NamespaceExportDeclaration:\r
86         case ts.SyntaxKind.NamespaceExport:\r
87         case ts.SyntaxKind.InterfaceDeclaration:\r
88         case ts.SyntaxKind.TypeAliasDeclaration:\r
89         case ts.SyntaxKind.TypeParameter:\r
90         case ts.SyntaxKind.NamedTupleMember:\r
91             break;\r
92         default:\r
93             return 5 /* ValueOrNamespace */;\r
94     }\r
95 }\r
96 exports.getUsageDomain = getUsageDomain;\r
97 function getDeclarationDomain(node) {\r
98     switch (node.parent.kind) {\r
99         case ts.SyntaxKind.TypeParameter:\r
100         case ts.SyntaxKind.InterfaceDeclaration:\r
101         case ts.SyntaxKind.TypeAliasDeclaration:\r
102             return 2 /* Type */;\r
103         case ts.SyntaxKind.ClassDeclaration:\r
104         case ts.SyntaxKind.ClassExpression:\r
105             return 2 /* Type */ | 4 /* Value */;\r
106         case ts.SyntaxKind.EnumDeclaration:\r
107             return 7 /* Any */;\r
108         case ts.SyntaxKind.NamespaceImport:\r
109         case ts.SyntaxKind.ImportClause:\r
110             return 7 /* Any */ | 8 /* Import */; // TODO handle type-only imports\r
111         case ts.SyntaxKind.ImportEqualsDeclaration:\r
112         case ts.SyntaxKind.ImportSpecifier:\r
113             return node.parent.name === node\r
114                 ? 7 /* Any */ | 8 /* Import */ // TODO handle type-only imports\r
115                 : undefined;\r
116         case ts.SyntaxKind.ModuleDeclaration:\r
117             return 1 /* Namespace */;\r
118         case ts.SyntaxKind.Parameter:\r
119             if (node.parent.parent.kind === ts.SyntaxKind.IndexSignature || node.originalKeywordKind === ts.SyntaxKind.ThisKeyword)\r
120                 return;\r
121         // falls through\r
122         case ts.SyntaxKind.BindingElement:\r
123         case ts.SyntaxKind.VariableDeclaration:\r
124             return node.parent.name === node ? 4 /* Value */ : undefined;\r
125         case ts.SyntaxKind.FunctionDeclaration:\r
126         case ts.SyntaxKind.FunctionExpression:\r
127             return 4 /* Value */;\r
128     }\r
129 }\r
130 exports.getDeclarationDomain = getDeclarationDomain;\r
131 function collectVariableUsage(sourceFile) {\r
132     return new UsageWalker().getUsage(sourceFile);\r
133 }\r
134 exports.collectVariableUsage = collectVariableUsage;\r
135 class AbstractScope {\r
136     constructor(_global) {\r
137         this._global = _global;\r
138         this._variables = new Map();\r
139         this._uses = [];\r
140         this._namespaceScopes = undefined;\r
141         this._enumScopes = undefined;\r
142     }\r
143     addVariable(identifier, name, selector, exported, domain) {\r
144         const variables = this.getDestinationScope(selector).getVariables();\r
145         const declaration = {\r
146             domain,\r
147             exported,\r
148             declaration: name,\r
149         };\r
150         const variable = variables.get(identifier);\r
151         if (variable === undefined) {\r
152             variables.set(identifier, {\r
153                 domain,\r
154                 declarations: [declaration],\r
155                 uses: [],\r
156             });\r
157         }\r
158         else {\r
159             variable.domain |= domain;\r
160             variable.declarations.push(declaration);\r
161         }\r
162     }\r
163     addUse(use) {\r
164         this._uses.push(use);\r
165     }\r
166     getVariables() {\r
167         return this._variables;\r
168     }\r
169     getFunctionScope() {\r
170         return this;\r
171     }\r
172     end(cb) {\r
173         if (this._namespaceScopes !== undefined)\r
174             this._namespaceScopes.forEach((value) => value.finish(cb));\r
175         this._namespaceScopes = this._enumScopes = undefined;\r
176         this._applyUses();\r
177         this._variables.forEach((variable) => {\r
178             for (const declaration of variable.declarations) {\r
179                 const result = {\r
180                     declarations: [],\r
181                     domain: declaration.domain,\r
182                     exported: declaration.exported,\r
183                     inGlobalScope: this._global,\r
184                     uses: [],\r
185                 };\r
186                 for (const other of variable.declarations)\r
187                     if (other.domain & declaration.domain)\r
188                         result.declarations.push(other.declaration);\r
189                 for (const use of variable.uses)\r
190                     if (use.domain & declaration.domain)\r
191                         result.uses.push(use);\r
192                 cb(result, declaration.declaration, this);\r
193             }\r
194         });\r
195     }\r
196     // tslint:disable-next-line:prefer-function-over-method\r
197     markExported(_name) { } // only relevant for the root scope\r
198     createOrReuseNamespaceScope(name, _exported, ambient, hasExportStatement) {\r
199         let scope;\r
200         if (this._namespaceScopes === undefined) {\r
201             this._namespaceScopes = new Map();\r
202         }\r
203         else {\r
204             scope = this._namespaceScopes.get(name);\r
205         }\r
206         if (scope === undefined) {\r
207             scope = new NamespaceScope(ambient, hasExportStatement, this);\r
208             this._namespaceScopes.set(name, scope);\r
209         }\r
210         else {\r
211             scope.refresh(ambient, hasExportStatement);\r
212         }\r
213         return scope;\r
214     }\r
215     createOrReuseEnumScope(name, _exported) {\r
216         let scope;\r
217         if (this._enumScopes === undefined) {\r
218             this._enumScopes = new Map();\r
219         }\r
220         else {\r
221             scope = this._enumScopes.get(name);\r
222         }\r
223         if (scope === undefined) {\r
224             scope = new EnumScope(this);\r
225             this._enumScopes.set(name, scope);\r
226         }\r
227         return scope;\r
228     }\r
229     _applyUses() {\r
230         for (const use of this._uses)\r
231             if (!this._applyUse(use))\r
232                 this._addUseToParent(use);\r
233         this._uses = [];\r
234     }\r
235     _applyUse(use, variables = this._variables) {\r
236         const variable = variables.get(use.location.text);\r
237         if (variable === undefined || (variable.domain & use.domain) === 0)\r
238             return false;\r
239         variable.uses.push(use);\r
240         return true;\r
241     }\r
242     _addUseToParent(_use) { } // tslint:disable-line:prefer-function-over-method\r
243 }\r
244 class RootScope extends AbstractScope {\r
245     constructor(_exportAll, global) {\r
246         super(global);\r
247         this._exportAll = _exportAll;\r
248         this._exports = undefined;\r
249         this._innerScope = new NonRootScope(this, 1 /* Function */);\r
250     }\r
251     addVariable(identifier, name, selector, exported, domain) {\r
252         if (domain & 8 /* Import */)\r
253             return super.addVariable(identifier, name, selector, exported, domain);\r
254         return this._innerScope.addVariable(identifier, name, selector, exported, domain);\r
255     }\r
256     addUse(use, origin) {\r
257         if (origin === this._innerScope)\r
258             return super.addUse(use);\r
259         return this._innerScope.addUse(use);\r
260     }\r
261     markExported(id) {\r
262         if (this._exports === undefined) {\r
263             this._exports = [id.text];\r
264         }\r
265         else {\r
266             this._exports.push(id.text);\r
267         }\r
268     }\r
269     end(cb) {\r
270         this._innerScope.end((value, key) => {\r
271             value.exported = value.exported || this._exportAll\r
272                 || this._exports !== undefined && this._exports.includes(key.text);\r
273             value.inGlobalScope = this._global;\r
274             return cb(value, key, this);\r
275         });\r
276         return super.end((value, key, scope) => {\r
277             value.exported = value.exported || scope === this\r
278                 && this._exports !== undefined && this._exports.includes(key.text);\r
279             return cb(value, key, scope);\r
280         });\r
281     }\r
282     getDestinationScope() {\r
283         return this;\r
284     }\r
285 }\r
286 class NonRootScope extends AbstractScope {\r
287     constructor(_parent, _boundary) {\r
288         super(false);\r
289         this._parent = _parent;\r
290         this._boundary = _boundary;\r
291     }\r
292     _addUseToParent(use) {\r
293         return this._parent.addUse(use, this);\r
294     }\r
295     getDestinationScope(selector) {\r
296         return this._boundary & selector\r
297             ? this\r
298             : this._parent.getDestinationScope(selector);\r
299     }\r
300 }\r
301 class EnumScope extends NonRootScope {\r
302     constructor(parent) {\r
303         super(parent, 1 /* Function */);\r
304     }\r
305     end() {\r
306         this._applyUses();\r
307     }\r
308 }\r
309 class ConditionalTypeScope extends NonRootScope {\r
310     constructor(parent) {\r
311         super(parent, 8 /* ConditionalType */);\r
312         this._state = 0 /* Initial */;\r
313     }\r
314     updateState(newState) {\r
315         this._state = newState;\r
316     }\r
317     addUse(use) {\r
318         if (this._state === 2 /* TrueType */)\r
319             return void this._uses.push(use);\r
320         return this._parent.addUse(use, this);\r
321     }\r
322 }\r
323 class FunctionScope extends NonRootScope {\r
324     constructor(parent) {\r
325         super(parent, 1 /* Function */);\r
326     }\r
327     beginBody() {\r
328         this._applyUses();\r
329     }\r
330 }\r
331 class AbstractNamedExpressionScope extends NonRootScope {\r
332     constructor(_name, _domain, parent) {\r
333         super(parent, 1 /* Function */);\r
334         this._name = _name;\r
335         this._domain = _domain;\r
336     }\r
337     end(cb) {\r
338         this._innerScope.end(cb);\r
339         return cb({\r
340             declarations: [this._name],\r
341             domain: this._domain,\r
342             exported: false,\r
343             uses: this._uses,\r
344             inGlobalScope: false,\r
345         }, this._name, this);\r
346     }\r
347     addUse(use, source) {\r
348         if (source !== this._innerScope)\r
349             return this._innerScope.addUse(use);\r
350         if (use.domain & this._domain && use.location.text === this._name.text) {\r
351             this._uses.push(use);\r
352         }\r
353         else {\r
354             return this._parent.addUse(use, this);\r
355         }\r
356     }\r
357     getFunctionScope() {\r
358         return this._innerScope;\r
359     }\r
360     getDestinationScope() {\r
361         return this._innerScope;\r
362     }\r
363 }\r
364 class FunctionExpressionScope extends AbstractNamedExpressionScope {\r
365     constructor(name, parent) {\r
366         super(name, 4 /* Value */, parent);\r
367         this._innerScope = new FunctionScope(this);\r
368     }\r
369     beginBody() {\r
370         return this._innerScope.beginBody();\r
371     }\r
372 }\r
373 class ClassExpressionScope extends AbstractNamedExpressionScope {\r
374     constructor(name, parent) {\r
375         super(name, 4 /* Value */ | 2 /* Type */, parent);\r
376         this._innerScope = new NonRootScope(this, 1 /* Function */);\r
377     }\r
378 }\r
379 class BlockScope extends NonRootScope {\r
380     constructor(_functionScope, parent) {\r
381         super(parent, 2 /* Block */);\r
382         this._functionScope = _functionScope;\r
383     }\r
384     getFunctionScope() {\r
385         return this._functionScope;\r
386     }\r
387 }\r
388 function mapDeclaration(declaration) {\r
389     return {\r
390         declaration,\r
391         exported: true,\r
392         domain: getDeclarationDomain(declaration),\r
393     };\r
394 }\r
395 class NamespaceScope extends NonRootScope {\r
396     constructor(_ambient, _hasExport, parent) {\r
397         super(parent, 1 /* Function */);\r
398         this._ambient = _ambient;\r
399         this._hasExport = _hasExport;\r
400         this._innerScope = new NonRootScope(this, 1 /* Function */);\r
401         this._exports = undefined;\r
402     }\r
403     finish(cb) {\r
404         return super.end(cb);\r
405     }\r
406     end(cb) {\r
407         this._innerScope.end((variable, key, scope) => {\r
408             if (scope !== this._innerScope ||\r
409                 !variable.exported && (!this._ambient || this._exports !== undefined && !this._exports.has(key.text)))\r
410                 return cb(variable, key, scope);\r
411             const namespaceVar = this._variables.get(key.text);\r
412             if (namespaceVar === undefined) {\r
413                 this._variables.set(key.text, {\r
414                     declarations: variable.declarations.map(mapDeclaration),\r
415                     domain: variable.domain,\r
416                     uses: [...variable.uses],\r
417                 });\r
418             }\r
419             else {\r
420                 outer: for (const declaration of variable.declarations) {\r
421                     for (const existing of namespaceVar.declarations)\r
422                         if (existing.declaration === declaration)\r
423                             continue outer;\r
424                     namespaceVar.declarations.push(mapDeclaration(declaration));\r
425                 }\r
426                 namespaceVar.domain |= variable.domain;\r
427                 for (const use of variable.uses) {\r
428                     if (namespaceVar.uses.includes(use))\r
429                         continue;\r
430                     namespaceVar.uses.push(use);\r
431                 }\r
432             }\r
433         });\r
434         this._applyUses();\r
435         this._innerScope = new NonRootScope(this, 1 /* Function */);\r
436     }\r
437     createOrReuseNamespaceScope(name, exported, ambient, hasExportStatement) {\r
438         if (!exported && (!this._ambient || this._hasExport))\r
439             return this._innerScope.createOrReuseNamespaceScope(name, exported, ambient || this._ambient, hasExportStatement);\r
440         return super.createOrReuseNamespaceScope(name, exported, ambient || this._ambient, hasExportStatement);\r
441     }\r
442     createOrReuseEnumScope(name, exported) {\r
443         if (!exported && (!this._ambient || this._hasExport))\r
444             return this._innerScope.createOrReuseEnumScope(name, exported);\r
445         return super.createOrReuseEnumScope(name, exported);\r
446     }\r
447     addUse(use, source) {\r
448         if (source !== this._innerScope)\r
449             return this._innerScope.addUse(use);\r
450         this._uses.push(use);\r
451     }\r
452     refresh(ambient, hasExport) {\r
453         this._ambient = ambient;\r
454         this._hasExport = hasExport;\r
455     }\r
456     markExported(name, _as) {\r
457         if (this._exports === undefined)\r
458             this._exports = new Set();\r
459         this._exports.add(name.text);\r
460     }\r
461     getDestinationScope() {\r
462         return this._innerScope;\r
463     }\r
464 }\r
465 function getEntityNameParent(name) {\r
466     let parent = name.parent;\r
467     while (parent.kind === ts.SyntaxKind.QualifiedName)\r
468         parent = parent.parent;\r
469     return parent;\r
470 }\r
471 // TODO class decorators resolve outside of class, element and parameter decorator resolve inside/at the class\r
472 // TODO computed property name resolves inside/at the cass\r
473 // TODO this and super in all of them are resolved outside of the class\r
474 class UsageWalker {\r
475     constructor() {\r
476         this._result = new Map();\r
477     }\r
478     getUsage(sourceFile) {\r
479         const variableCallback = (variable, key) => {\r
480             this._result.set(key, variable);\r
481         };\r
482         const isModule = ts.isExternalModule(sourceFile);\r
483         this._scope = new RootScope(sourceFile.isDeclarationFile && isModule && !containsExportStatement(sourceFile), !isModule);\r
484         const cb = (node) => {\r
485             if (util_1.isBlockScopeBoundary(node))\r
486                 return continueWithScope(node, new BlockScope(this._scope.getFunctionScope(), this._scope), handleBlockScope);\r
487             switch (node.kind) {\r
488                 case ts.SyntaxKind.ClassExpression:\r
489                     return continueWithScope(node, node.name !== undefined\r
490                         ? new ClassExpressionScope(node.name, this._scope)\r
491                         : new NonRootScope(this._scope, 1 /* Function */));\r
492                 case ts.SyntaxKind.ClassDeclaration:\r
493                     this._handleDeclaration(node, true, 4 /* Value */ | 2 /* Type */);\r
494                     return continueWithScope(node, new NonRootScope(this._scope, 1 /* Function */));\r
495                 case ts.SyntaxKind.InterfaceDeclaration:\r
496                 case ts.SyntaxKind.TypeAliasDeclaration:\r
497                     this._handleDeclaration(node, true, 2 /* Type */);\r
498                     return continueWithScope(node, new NonRootScope(this._scope, 4 /* Type */));\r
499                 case ts.SyntaxKind.EnumDeclaration:\r
500                     this._handleDeclaration(node, true, 7 /* Any */);\r
501                     return continueWithScope(node, this._scope.createOrReuseEnumScope(node.name.text, util_1.hasModifier(node.modifiers, ts.SyntaxKind.ExportKeyword)));\r
502                 case ts.SyntaxKind.ModuleDeclaration:\r
503                     return this._handleModule(node, continueWithScope);\r
504                 case ts.SyntaxKind.MappedType:\r
505                     return continueWithScope(node, new NonRootScope(this._scope, 4 /* Type */));\r
506                 case ts.SyntaxKind.FunctionExpression:\r
507                 case ts.SyntaxKind.ArrowFunction:\r
508                 case ts.SyntaxKind.Constructor:\r
509                 case ts.SyntaxKind.MethodDeclaration:\r
510                 case ts.SyntaxKind.FunctionDeclaration:\r
511                 case ts.SyntaxKind.GetAccessor:\r
512                 case ts.SyntaxKind.SetAccessor:\r
513                 case ts.SyntaxKind.MethodSignature:\r
514                 case ts.SyntaxKind.CallSignature:\r
515                 case ts.SyntaxKind.ConstructSignature:\r
516                 case ts.SyntaxKind.ConstructorType:\r
517                 case ts.SyntaxKind.FunctionType:\r
518                     return this._handleFunctionLikeDeclaration(node, cb, variableCallback);\r
519                 case ts.SyntaxKind.ConditionalType:\r
520                     return this._handleConditionalType(node, cb, variableCallback);\r
521                 // End of Scope specific handling\r
522                 case ts.SyntaxKind.VariableDeclarationList:\r
523                     this._handleVariableDeclaration(node);\r
524                     break;\r
525                 case ts.SyntaxKind.Parameter:\r
526                     if (node.parent.kind !== ts.SyntaxKind.IndexSignature &&\r
527                         (node.name.kind !== ts.SyntaxKind.Identifier ||\r
528                             node.name.originalKeywordKind !== ts.SyntaxKind.ThisKeyword))\r
529                         this._handleBindingName(node.name, false, false);\r
530                     break;\r
531                 case ts.SyntaxKind.EnumMember:\r
532                     this._scope.addVariable(util_1.getPropertyName(node.name), node.name, 1 /* Function */, true, 4 /* Value */);\r
533                     break;\r
534                 case ts.SyntaxKind.ImportClause:\r
535                 case ts.SyntaxKind.ImportSpecifier:\r
536                 case ts.SyntaxKind.NamespaceImport:\r
537                 case ts.SyntaxKind.ImportEqualsDeclaration:\r
538                     this._handleDeclaration(node, false, 7 /* Any */ | 8 /* Import */);\r
539                     break;\r
540                 case ts.SyntaxKind.TypeParameter:\r
541                     this._scope.addVariable(node.name.text, node.name, node.parent.kind === ts.SyntaxKind.InferType ? 8 /* InferType */ : 7 /* Type */, false, 2 /* Type */);\r
542                     break;\r
543                 case ts.SyntaxKind.ExportSpecifier:\r
544                     if (node.propertyName !== undefined)\r
545                         return this._scope.markExported(node.propertyName, node.name);\r
546                     return this._scope.markExported(node.name);\r
547                 case ts.SyntaxKind.ExportAssignment:\r
548                     if (node.expression.kind === ts.SyntaxKind.Identifier)\r
549                         return this._scope.markExported(node.expression);\r
550                     break;\r
551                 case ts.SyntaxKind.Identifier:\r
552                     const domain = getUsageDomain(node);\r
553                     if (domain !== undefined)\r
554                         this._scope.addUse({ domain, location: node });\r
555                     return;\r
556             }\r
557             return ts.forEachChild(node, cb);\r
558         };\r
559         const continueWithScope = (node, scope, next = forEachChild) => {\r
560             const savedScope = this._scope;\r
561             this._scope = scope;\r
562             next(node);\r
563             this._scope.end(variableCallback);\r
564             this._scope = savedScope;\r
565         };\r
566         const handleBlockScope = (node) => {\r
567             if (node.kind === ts.SyntaxKind.CatchClause && node.variableDeclaration !== undefined)\r
568                 this._handleBindingName(node.variableDeclaration.name, true, false);\r
569             return ts.forEachChild(node, cb);\r
570         };\r
571         ts.forEachChild(sourceFile, cb);\r
572         this._scope.end(variableCallback);\r
573         return this._result;\r
574         function forEachChild(node) {\r
575             return ts.forEachChild(node, cb);\r
576         }\r
577     }\r
578     _handleConditionalType(node, cb, varCb) {\r
579         const savedScope = this._scope;\r
580         const scope = this._scope = new ConditionalTypeScope(savedScope);\r
581         cb(node.checkType);\r
582         scope.updateState(1 /* Extends */);\r
583         cb(node.extendsType);\r
584         scope.updateState(2 /* TrueType */);\r
585         cb(node.trueType);\r
586         scope.updateState(3 /* FalseType */);\r
587         cb(node.falseType);\r
588         scope.end(varCb);\r
589         this._scope = savedScope;\r
590     }\r
591     _handleFunctionLikeDeclaration(node, cb, varCb) {\r
592         if (node.decorators !== undefined)\r
593             node.decorators.forEach(cb);\r
594         const savedScope = this._scope;\r
595         if (node.kind === ts.SyntaxKind.FunctionDeclaration)\r
596             this._handleDeclaration(node, false, 4 /* Value */);\r
597         const scope = this._scope = node.kind === ts.SyntaxKind.FunctionExpression && node.name !== undefined\r
598             ? new FunctionExpressionScope(node.name, savedScope)\r
599             : new FunctionScope(savedScope);\r
600         if (node.name !== undefined)\r
601             cb(node.name);\r
602         if (node.typeParameters !== undefined)\r
603             node.typeParameters.forEach(cb);\r
604         node.parameters.forEach(cb);\r
605         if (node.type !== undefined)\r
606             cb(node.type);\r
607         if (node.body !== undefined) {\r
608             scope.beginBody();\r
609             cb(node.body);\r
610         }\r
611         scope.end(varCb);\r
612         this._scope = savedScope;\r
613     }\r
614     _handleModule(node, next) {\r
615         if (node.flags & ts.NodeFlags.GlobalAugmentation)\r
616             return next(node, this._scope.createOrReuseNamespaceScope('-global', false, true, false));\r
617         if (node.name.kind === ts.SyntaxKind.Identifier) {\r
618             const exported = isNamespaceExported(node);\r
619             this._scope.addVariable(node.name.text, node.name, 1 /* Function */, exported, 1 /* Namespace */ | 4 /* Value */);\r
620             const ambient = util_1.hasModifier(node.modifiers, ts.SyntaxKind.DeclareKeyword);\r
621             return next(node, this._scope.createOrReuseNamespaceScope(node.name.text, exported, ambient, ambient && namespaceHasExportStatement(node)));\r
622         }\r
623         return next(node, this._scope.createOrReuseNamespaceScope(`"${node.name.text}"`, false, true, namespaceHasExportStatement(node)));\r
624     }\r
625     _handleDeclaration(node, blockScoped, domain) {\r
626         if (node.name !== undefined)\r
627             this._scope.addVariable(node.name.text, node.name, blockScoped ? 3 /* Block */ : 1 /* Function */, util_1.hasModifier(node.modifiers, ts.SyntaxKind.ExportKeyword), domain);\r
628     }\r
629     _handleBindingName(name, blockScoped, exported) {\r
630         if (name.kind === ts.SyntaxKind.Identifier)\r
631             return this._scope.addVariable(name.text, name, blockScoped ? 3 /* Block */ : 1 /* Function */, exported, 4 /* Value */);\r
632         util_1.forEachDestructuringIdentifier(name, (declaration) => {\r
633             this._scope.addVariable(declaration.name.text, declaration.name, blockScoped ? 3 /* Block */ : 1 /* Function */, exported, 4 /* Value */);\r
634         });\r
635     }\r
636     _handleVariableDeclaration(declarationList) {\r
637         const blockScoped = util_1.isBlockScopedVariableDeclarationList(declarationList);\r
638         const exported = declarationList.parent.kind === ts.SyntaxKind.VariableStatement &&\r
639             util_1.hasModifier(declarationList.parent.modifiers, ts.SyntaxKind.ExportKeyword);\r
640         for (const declaration of declarationList.declarations)\r
641             this._handleBindingName(declaration.name, blockScoped, exported);\r
642     }\r
643 }\r
644 function isNamespaceExported(node) {\r
645     return node.parent.kind === ts.SyntaxKind.ModuleDeclaration || util_1.hasModifier(node.modifiers, ts.SyntaxKind.ExportKeyword);\r
646 }\r
647 function namespaceHasExportStatement(ns) {\r
648     if (ns.body === undefined || ns.body.kind !== ts.SyntaxKind.ModuleBlock)\r
649         return false;\r
650     return containsExportStatement(ns.body);\r
651 }\r
652 function containsExportStatement(block) {\r
653     for (const statement of block.statements)\r
654         if (statement.kind === ts.SyntaxKind.ExportDeclaration || statement.kind === ts.SyntaxKind.ExportAssignment)\r
655             return true;\r
656     return false;\r
657 }\r
658 //# sourceMappingURL=usage.js.map