@tslite/services 0.0.0-stage → 1.13.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 +13 -0
- package/dist/_namespaces/edit.d.ts +8 -0
- package/dist/_namespaces/edit.js +11 -0
- package/dist/_namespaces/ts.Completions.StringCompletions.d.ts +1 -0
- package/dist/_namespaces/ts.Completions.StringCompletions.js +2 -0
- package/dist/_namespaces/ts.Completions.d.ts +2 -0
- package/dist/_namespaces/ts.Completions.js +3 -0
- package/dist/_namespaces/ts.FindAllReferences.d.ts +2 -0
- package/dist/_namespaces/ts.FindAllReferences.js +3 -0
- package/dist/_namespaces/ts.GoToDefinition.d.ts +1 -0
- package/dist/_namespaces/ts.GoToDefinition.js +2 -0
- package/dist/_namespaces/ts.NavigationBar.d.ts +1 -0
- package/dist/_namespaces/ts.NavigationBar.js +2 -0
- package/dist/_namespaces/ts.OrganizeImports.d.ts +1 -0
- package/dist/_namespaces/ts.OrganizeImports.js +2 -0
- package/dist/_namespaces/ts.OutliningElementsCollector.d.ts +1 -0
- package/dist/_namespaces/ts.OutliningElementsCollector.js +2 -0
- package/dist/_namespaces/ts.Rename.d.ts +1 -0
- package/dist/_namespaces/ts.Rename.js +2 -0
- package/dist/_namespaces/ts.SignatureHelp.d.ts +1 -0
- package/dist/_namespaces/ts.SignatureHelp.js +2 -0
- package/dist/_namespaces/ts.SmartSelectionRange.d.ts +1 -0
- package/dist/_namespaces/ts.SmartSelectionRange.js +2 -0
- package/dist/_namespaces/ts.SymbolDisplay.d.ts +1 -0
- package/dist/_namespaces/ts.SymbolDisplay.js +2 -0
- package/dist/_namespaces/ts.codefix.d.ts +26 -0
- package/dist/_namespaces/ts.codefix.js +27 -0
- package/dist/_namespaces/ts.d.ts +17 -0
- package/dist/_namespaces/ts.formatting.d.ts +7 -0
- package/dist/_namespaces/ts.formatting.js +8 -0
- package/dist/_namespaces/ts.js +20 -0
- package/dist/_namespaces/ts.refactor.addOrRemoveBracesToArrowFunction.d.ts +1 -0
- package/dist/_namespaces/ts.refactor.addOrRemoveBracesToArrowFunction.js +2 -0
- package/dist/_namespaces/ts.refactor.convertParamsToDestructuredObject.d.ts +1 -0
- package/dist/_namespaces/ts.refactor.convertParamsToDestructuredObject.js +2 -0
- package/dist/_namespaces/ts.refactor.convertStringOrTemplateLiteral.d.ts +1 -0
- package/dist/_namespaces/ts.refactor.convertStringOrTemplateLiteral.js +2 -0
- package/dist/_namespaces/ts.refactor.d.ts +9 -0
- package/dist/_namespaces/ts.refactor.extractSymbol.d.ts +1 -0
- package/dist/_namespaces/ts.refactor.extractSymbol.js +2 -0
- package/dist/_namespaces/ts.refactor.js +10 -0
- package/dist/_namespaces/ts.textChanges.d.ts +1 -0
- package/dist/_namespaces/ts.textChanges.js +2 -0
- package/dist/classifier.d.ts +5 -0
- package/dist/classifier.js +439 -0
- package/dist/codeFixProvider.d.ts +13 -0
- package/dist/codeFixProvider.js +84 -0
- package/dist/codefixes/addConvertToUnknownForNonOverlappingTypes.d.ts +1 -0
- package/dist/codefixes/addConvertToUnknownForNonOverlappingTypes.js +21 -0
- package/dist/codefixes/addEmptyExportDeclaration.d.ts +1 -0
- package/dist/codefixes/addEmptyExportDeclaration.js +17 -0
- package/dist/codefixes/addMissingAsync.d.ts +1 -0
- package/dist/codefixes/addMissingAsync.js +75 -0
- package/dist/codefixes/addMissingAwait.d.ts +1 -0
- package/dist/codefixes/addMissingAwait.js +236 -0
- package/dist/codefixes/addMissingConst.d.ts +1 -0
- package/dist/codefixes/addMissingConst.js +91 -0
- package/dist/codefixes/addNameToNamelessParameter.d.ts +1 -0
- package/dist/codefixes/addNameToNamelessParameter.js +29 -0
- package/dist/codefixes/convertConstToLet.d.ts +1 -0
- package/dist/codefixes/convertConstToLet.js +30 -0
- package/dist/codefixes/convertToAsyncFunction.d.ts +1 -0
- package/dist/codefixes/convertToAsyncFunction.js +495 -0
- package/dist/codefixes/convertToMappedObjectType.d.ts +1 -0
- package/dist/codefixes/convertToMappedObjectType.js +48 -0
- package/dist/codefixes/correctQualifiedNameToIndexedAccessType.d.ts +1 -0
- package/dist/codefixes/correctQualifiedNameToIndexedAccessType.js +33 -0
- package/dist/codefixes/fixAddModuleReferTypeMissingTypeof.d.ts +1 -0
- package/dist/codefixes/fixAddModuleReferTypeMissingTypeof.js +27 -0
- package/dist/codefixes/fixAwaitInSyncFunction.d.ts +1 -0
- package/dist/codefixes/fixAwaitInSyncFunction.js +69 -0
- package/dist/codefixes/fixExpectedComma.d.ts +1 -0
- package/dist/codefixes/fixExpectedComma.js +35 -0
- package/dist/codefixes/fixInvalidJsxCharacters.d.ts +1 -0
- package/dist/codefixes/fixInvalidJsxCharacters.js +41 -0
- package/dist/codefixes/fixMissingCallParentheses.d.ts +1 -0
- package/dist/codefixes/fixMissingCallParentheses.js +42 -0
- package/dist/codefixes/fixSpelling.d.ts +1 -0
- package/dist/codefixes/fixSpelling.js +94 -0
- package/dist/codefixes/fixUnreachableCode.d.ts +1 -0
- package/dist/codefixes/fixUnreachableCode.js +65 -0
- package/dist/codefixes/fixUnusedIdentifier.d.ts +1 -0
- package/dist/codefixes/fixUnusedIdentifier.js +224 -0
- package/dist/codefixes/helpers.d.ts +8 -0
- package/dist/codefixes/helpers.js +53 -0
- package/dist/codefixes/importFixes.d.ts +14 -0
- package/dist/codefixes/importFixes.js +441 -0
- package/dist/codefixes/inferFromUsage.d.ts +1 -0
- package/dist/codefixes/inferFromUsage.js +742 -0
- package/dist/codefixes/removeUnnecessaryAwait.d.ts +1 -0
- package/dist/codefixes/removeUnnecessaryAwait.js +41 -0
- package/dist/codefixes/returnValueCorrect.d.ts +1 -0
- package/dist/codefixes/returnValueCorrect.js +132 -0
- package/dist/codefixes/splitTypeOnlyImport.d.ts +1 -0
- package/dist/codefixes/splitTypeOnlyImport.js +32 -0
- package/dist/codefixes/useBigintLiteral.d.ts +1 -0
- package/dist/codefixes/useBigintLiteral.js +29 -0
- package/dist/completions.d.ts +83 -0
- package/dist/completions.js +1720 -0
- package/dist/documentHighlights.d.ts +8 -0
- package/dist/documentHighlights.js +367 -0
- package/dist/documentRegistry.d.ts +36 -0
- package/dist/documentRegistry.js +63 -0
- package/dist/editingServices.d.ts +1 -0
- package/dist/editingServices.js +4 -0
- package/dist/findAllReferences.d.ts +113 -0
- package/dist/findAllReferences.js +1366 -0
- package/dist/formatting/formatting.d.ts +26 -0
- package/dist/formatting/formatting.js +1021 -0
- package/dist/formatting/formattingContext.d.ts +34 -0
- package/dist/formatting/formattingContext.js +78 -0
- package/dist/formatting/formattingScanner.d.ts +14 -0
- package/dist/formatting/formattingScanner.js +228 -0
- package/dist/formatting/rule.d.ts +31 -0
- package/dist/formatting/rule.js +22 -0
- package/dist/formatting/rules.d.ts +7 -0
- package/dist/formatting/rules.js +610 -0
- package/dist/formatting/rulesMap.d.ts +5 -0
- package/dist/formatting/rulesMap.js +127 -0
- package/dist/formatting/smartIndenter.d.ts +44 -0
- package/dist/formatting/smartIndenter.js +518 -0
- package/dist/getEditsForFileRename.d.ts +6 -0
- package/dist/getEditsForFileRename.js +86 -0
- package/dist/goToDefinition.d.ts +8 -0
- package/dist/goToDefinition.js +246 -0
- package/dist/importTracker.d.ts +50 -0
- package/dist/importTracker.js +422 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +3 -0
- package/dist/navigationBar.d.ts +3 -0
- package/dist/navigationBar.js +549 -0
- package/dist/organizeImports.d.ts +18 -0
- package/dist/organizeImports.js +290 -0
- package/dist/outliningElementsCollector.d.ts +2 -0
- package/dist/outliningElementsCollector.js +261 -0
- package/dist/refactorProvider.d.ts +5 -0
- package/dist/refactorProvider.js +16 -0
- package/dist/refactors/addOrRemoveBracesToArrowFunction.d.ts +1 -0
- package/dist/refactors/addOrRemoveBracesToArrowFunction.js +86 -0
- package/dist/refactors/convertExport.d.ts +1 -0
- package/dist/refactors/convertExport.js +126 -0
- package/dist/refactors/convertImport.d.ts +1 -0
- package/dist/refactors/convertImport.js +116 -0
- package/dist/refactors/convertParamsToDestructuredObject.d.ts +1 -0
- package/dist/refactors/convertParamsToDestructuredObject.js +282 -0
- package/dist/refactors/convertStringOrTemplateLiteral.d.ts +1 -0
- package/dist/refactors/convertStringOrTemplateLiteral.js +148 -0
- package/dist/refactors/extractSymbol.d.ts +60 -0
- package/dist/refactors/extractSymbol.js +1281 -0
- package/dist/refactors/extractType.d.ts +1 -0
- package/dist/refactors/extractType.js +102 -0
- package/dist/refactors/moveToNewFile.d.ts +1 -0
- package/dist/refactors/moveToNewFile.js +477 -0
- package/dist/rename.d.ts +2 -0
- package/dist/rename.js +100 -0
- package/dist/services.d.ts +48 -0
- package/dist/services.js +1480 -0
- package/dist/signatureHelp.d.ts +8 -0
- package/dist/signatureHelp.js +414 -0
- package/dist/smartSelection.d.ts +2 -0
- package/dist/smartSelection.js +243 -0
- package/dist/stringCompletions.d.ts +4 -0
- package/dist/stringCompletions.js +220 -0
- package/dist/suggestionDiagnostics.d.ts +6 -0
- package/dist/suggestionDiagnostics.js +92 -0
- package/dist/symbolDisplay.d.ts +16 -0
- package/dist/symbolDisplay.js +400 -0
- package/dist/textChanges.d.ts +161 -0
- package/dist/textChanges.js +1163 -0
- package/dist/types.d.ts +908 -0
- package/dist/types.js +263 -0
- package/dist/utilities.d.ts +283 -0
- package/dist/utilities.js +1981 -0
- package/package.json +45 -3
- package/README.md +0 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
// Modificado de microsoft/TypeScript v3.9.10, src/services/refactors/convertExport.ts: o namespace virou módulo ES, com os imports explícitos.
|
|
2
|
+
// Fica a conversão de um export nomeado em default. Sai a conversão de volta, de um default em nomeado: ela atuava no
|
|
3
|
+
// modificador `default` de uma declaração, que só vinha diante da `function` e da classe (CK-02), e o `export default` que
|
|
4
|
+
// fica é de expressão (CK-46). Saem também a `function`, a classe, a interface e o enum exportados (CK-02).
|
|
5
|
+
import { Debug, Diagnostics, FindAllReferences, InternalSymbolName, ModifierFlags, NodeFlags, SyntaxKind, createExportDefault, createExportSpecifier, createIdentifier, emptyArray, findModifier, first, getModifierFlags, getParentNodeInSpan, getRefactorContextSpan, getTokenAtPosition, isAmbientModule, isIdentifier, isModuleBlock, isSourceFile, textChanges, } from "../_namespaces/edit.js";
|
|
6
|
+
import { registerRefactor, } from "../_namespaces/ts.refactor.js";
|
|
7
|
+
const refactorName = "Convert export";
|
|
8
|
+
const actionNameNamedToDefault = "Convert named export to default export";
|
|
9
|
+
registerRefactor(refactorName, {
|
|
10
|
+
getAvailableActions(context) {
|
|
11
|
+
const info = getInfo(context);
|
|
12
|
+
if (!info)
|
|
13
|
+
return emptyArray;
|
|
14
|
+
const description = Diagnostics.Convert_named_export_to_default_export.message;
|
|
15
|
+
const actionName = actionNameNamedToDefault;
|
|
16
|
+
return [{ name: refactorName, description, actions: [{ name: actionName, description }] }];
|
|
17
|
+
},
|
|
18
|
+
getEditsForAction(context, actionName) {
|
|
19
|
+
Debug.assert(actionName === actionNameNamedToDefault, "Unexpected action name");
|
|
20
|
+
const edits = textChanges.ChangeTracker.with(context, t => doChange(context.file, context.program, Debug.checkDefined(getInfo(context), "context must have info"), t, context.cancellationToken));
|
|
21
|
+
return { edits, renameFilename: undefined, renameLocation: undefined };
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
function getInfo(context) {
|
|
25
|
+
const { file } = context;
|
|
26
|
+
const span = getRefactorContextSpan(context);
|
|
27
|
+
const token = getTokenAtPosition(file, span.start);
|
|
28
|
+
const exportNode = getParentNodeInSpan(token, file, span);
|
|
29
|
+
if (!exportNode || (!isSourceFile(exportNode.parent) && !(isModuleBlock(exportNode.parent) && isAmbientModule(exportNode.parent.parent)))) {
|
|
30
|
+
return undefined;
|
|
31
|
+
}
|
|
32
|
+
const exportingModuleSymbol = isSourceFile(exportNode.parent) ? exportNode.parent.symbol : exportNode.parent.parent.symbol;
|
|
33
|
+
const flags = getModifierFlags(exportNode);
|
|
34
|
+
// If source file already has a default export, don't offer refactor.
|
|
35
|
+
if (!(flags & ModifierFlags.Export) || exportingModuleSymbol.exports.has(InternalSymbolName.Default)) {
|
|
36
|
+
return undefined;
|
|
37
|
+
}
|
|
38
|
+
switch (exportNode.kind) {
|
|
39
|
+
case SyntaxKind.TypeAliasDeclaration:
|
|
40
|
+
case SyntaxKind.ModuleDeclaration: {
|
|
41
|
+
const node = exportNode;
|
|
42
|
+
return node.name && isIdentifier(node.name) ? { exportNode: node, exportName: node.name, exportingModuleSymbol } : undefined;
|
|
43
|
+
}
|
|
44
|
+
case SyntaxKind.VariableStatement: {
|
|
45
|
+
const vs = exportNode;
|
|
46
|
+
// Must be `export const x = something;`.
|
|
47
|
+
if (!(vs.declarationList.flags & NodeFlags.Const) || vs.declarationList.declarations.length !== 1) {
|
|
48
|
+
return undefined;
|
|
49
|
+
}
|
|
50
|
+
const decl = first(vs.declarationList.declarations);
|
|
51
|
+
if (!decl.initializer)
|
|
52
|
+
return undefined;
|
|
53
|
+
return isIdentifier(decl.name) ? { exportNode: vs, exportName: decl.name, exportingModuleSymbol } : undefined;
|
|
54
|
+
}
|
|
55
|
+
default:
|
|
56
|
+
return undefined;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
function doChange(exportingSourceFile, program, info, changes, cancellationToken) {
|
|
60
|
+
changeExport(exportingSourceFile, info, changes, program.getTypeChecker());
|
|
61
|
+
changeImports(program, info, changes, cancellationToken);
|
|
62
|
+
}
|
|
63
|
+
function changeExport(exportingSourceFile, { exportNode, exportName }, changes, checker) {
|
|
64
|
+
const exportKeyword = Debug.checkDefined(findModifier(exportNode, SyntaxKind.ExportKeyword), "Should find an export keyword in modifier list");
|
|
65
|
+
switch (exportNode.kind) {
|
|
66
|
+
case SyntaxKind.VariableStatement:
|
|
67
|
+
// If 'x' isn't used in this file, `export const x = 0;` --> `export default 0;`
|
|
68
|
+
if (!FindAllReferences.Core.isSymbolReferencedInFile(exportName, checker, exportingSourceFile)) {
|
|
69
|
+
// We checked in `getInfo` that an initializer exists.
|
|
70
|
+
changes.replaceNode(exportingSourceFile, exportNode, createExportDefault(Debug.checkDefined(first(exportNode.declarationList.declarations).initializer, "Initializer was previously known to be present")));
|
|
71
|
+
break;
|
|
72
|
+
}
|
|
73
|
+
// falls through
|
|
74
|
+
case SyntaxKind.TypeAliasDeclaration:
|
|
75
|
+
case SyntaxKind.ModuleDeclaration:
|
|
76
|
+
// `export type T = number;` -> `type T = number; export default T;`
|
|
77
|
+
changes.deleteModifier(exportingSourceFile, exportKeyword);
|
|
78
|
+
changes.insertNodeAfter(exportingSourceFile, exportNode, createExportDefault(createIdentifier(exportName.text)));
|
|
79
|
+
break;
|
|
80
|
+
default:
|
|
81
|
+
Debug.assertNever(exportNode, `Unexpected exportNode kind ${exportNode.kind}`);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
function changeImports(program, { exportName, exportingModuleSymbol }, changes, cancellationToken) {
|
|
85
|
+
const checker = program.getTypeChecker();
|
|
86
|
+
const exportSymbol = Debug.checkDefined(checker.getSymbolAtLocation(exportName), "Export name should resolve to a symbol");
|
|
87
|
+
FindAllReferences.Core.eachExportReference(program.getSourceFiles(), checker, cancellationToken, exportSymbol, exportingModuleSymbol, exportName.text, /*isDefaultExport*/ false, ref => {
|
|
88
|
+
const importingSourceFile = ref.getSourceFile();
|
|
89
|
+
changeNamedToDefaultImport(importingSourceFile, ref, changes);
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
function changeNamedToDefaultImport(importingSourceFile, ref, changes) {
|
|
93
|
+
const parent = ref.parent;
|
|
94
|
+
switch (parent.kind) {
|
|
95
|
+
case SyntaxKind.PropertyAccessExpression:
|
|
96
|
+
// `a.foo` --> `a.default`
|
|
97
|
+
changes.replaceNode(importingSourceFile, ref, createIdentifier("default"));
|
|
98
|
+
break;
|
|
99
|
+
case SyntaxKind.ImportSpecifier: {
|
|
100
|
+
// `import { foo } from "./a";` --> `import foo from "./a";`
|
|
101
|
+
// `import { foo as bar } from "./a";` --> `import bar from "./a";`
|
|
102
|
+
const defaultImport = createIdentifier(parent.name.text);
|
|
103
|
+
if (parent.parent.elements.length === 1) {
|
|
104
|
+
changes.replaceNode(importingSourceFile, parent.parent, defaultImport);
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
changes.delete(importingSourceFile, parent);
|
|
108
|
+
changes.insertNodeBefore(importingSourceFile, parent.parent, defaultImport);
|
|
109
|
+
}
|
|
110
|
+
break;
|
|
111
|
+
}
|
|
112
|
+
case SyntaxKind.ExportSpecifier: {
|
|
113
|
+
// `export { foo } from "./a";` --> `export { default as foo } from "./a";`
|
|
114
|
+
// `export { foo as bar } from "./a";` --> `export { default as bar } from "./a";`
|
|
115
|
+
// `export { foo as default } from "./a";` --> `export { default } from "./a";`
|
|
116
|
+
// (Because `export foo from "./a";` isn't valid syntax.)
|
|
117
|
+
changes.replaceNode(importingSourceFile, parent, makeExportSpecifier("default", parent.name.text));
|
|
118
|
+
break;
|
|
119
|
+
}
|
|
120
|
+
default:
|
|
121
|
+
Debug.assertNever(parent, `Unexpected parent kind ${parent.kind}`);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
function makeExportSpecifier(propertyName, name) {
|
|
125
|
+
return createExportSpecifier(propertyName === name ? undefined : createIdentifier(propertyName), createIdentifier(name));
|
|
126
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
// Modificado de microsoft/TypeScript v3.9.10, src/services/refactors/convertImport.ts: o namespace virou módulo ES, com os imports explícitos.
|
|
2
|
+
import { Debug, Diagnostics, FindAllReferences, ScriptTarget, SymbolFlags, SyntaxKind, cast, createIdentifier, createImportClause, createImportDeclaration, createImportSpecifier, createMap, createNamedImports, createNamespaceImport, createPropertyAccess, createPropertyAssignment, emptyArray, getParentNodeInSpan, getRefactorContextSpan, getTokenAtPosition, getUniqueName, isExportSpecifier, isImportDeclaration, isPropertyAccessExpression, isShorthandPropertyAssignment, isStringLiteral, moduleSpecifierToValidIdentifier, textChanges, } from "../_namespaces/edit.js";
|
|
3
|
+
import { registerRefactor, } from "../_namespaces/ts.refactor.js";
|
|
4
|
+
const refactorName = "Convert import";
|
|
5
|
+
const actionNameNamespaceToNamed = "Convert namespace import to named imports";
|
|
6
|
+
const actionNameNamedToNamespace = "Convert named imports to namespace import";
|
|
7
|
+
registerRefactor(refactorName, {
|
|
8
|
+
getAvailableActions(context) {
|
|
9
|
+
const i = getImportToConvert(context);
|
|
10
|
+
if (!i)
|
|
11
|
+
return emptyArray;
|
|
12
|
+
const description = i.kind === SyntaxKind.NamespaceImport ? Diagnostics.Convert_namespace_import_to_named_imports.message : Diagnostics.Convert_named_imports_to_namespace_import.message;
|
|
13
|
+
const actionName = i.kind === SyntaxKind.NamespaceImport ? actionNameNamespaceToNamed : actionNameNamedToNamespace;
|
|
14
|
+
return [{ name: refactorName, description, actions: [{ name: actionName, description }] }];
|
|
15
|
+
},
|
|
16
|
+
getEditsForAction(context, actionName) {
|
|
17
|
+
Debug.assert(actionName === actionNameNamespaceToNamed || actionName === actionNameNamedToNamespace, "Unexpected action name");
|
|
18
|
+
const edits = textChanges.ChangeTracker.with(context, t => doChange(context.file, context.program, t, Debug.checkDefined(getImportToConvert(context), "Context must provide an import to convert")));
|
|
19
|
+
return { edits, renameFilename: undefined, renameLocation: undefined };
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
// Can convert imports of the form `import * as m from "m";` or `import d, { x, y } from "m";`.
|
|
23
|
+
function getImportToConvert(context) {
|
|
24
|
+
const { file } = context;
|
|
25
|
+
const span = getRefactorContextSpan(context);
|
|
26
|
+
const token = getTokenAtPosition(file, span.start);
|
|
27
|
+
const importDecl = getParentNodeInSpan(token, file, span);
|
|
28
|
+
if (!importDecl || !isImportDeclaration(importDecl))
|
|
29
|
+
return undefined;
|
|
30
|
+
const { importClause } = importDecl;
|
|
31
|
+
return importClause && importClause.namedBindings;
|
|
32
|
+
}
|
|
33
|
+
function doChange(sourceFile, program, changes, toConvert) {
|
|
34
|
+
const checker = program.getTypeChecker();
|
|
35
|
+
if (toConvert.kind === SyntaxKind.NamespaceImport) {
|
|
36
|
+
doChangeNamespaceToNamed(sourceFile, checker, changes, toConvert);
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
doChangeNamedToNamespace(sourceFile, checker, changes, toConvert);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
// Na tag, o `allowSyntheticDefaultImports` das opções decidia se o namespace usado como valor virava um import default; a
|
|
43
|
+
// configuração fixa o deixa desligado (CK-24), e o import de namespace usado como valor fica.
|
|
44
|
+
function doChangeNamespaceToNamed(sourceFile, checker, changes, toConvert) {
|
|
45
|
+
let usedAsNamespaceOrDefault = false;
|
|
46
|
+
const nodesToReplace = [];
|
|
47
|
+
const conflictingNames = createMap();
|
|
48
|
+
FindAllReferences.Core.eachSymbolReferenceInFile(toConvert.name, checker, sourceFile, id => {
|
|
49
|
+
if (!isPropertyAccessExpression(id.parent)) {
|
|
50
|
+
usedAsNamespaceOrDefault = true;
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
const parent = cast(id.parent, isPropertyAccessExpression);
|
|
54
|
+
const exportName = parent.name.text;
|
|
55
|
+
if (checker.resolveName(exportName, id, SymbolFlags.All, /*excludeGlobals*/ true)) {
|
|
56
|
+
conflictingNames.set(exportName, true);
|
|
57
|
+
}
|
|
58
|
+
Debug.assert(parent.expression === id, "Parent expression should match id");
|
|
59
|
+
nodesToReplace.push(parent);
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
// We may need to change `mod.x` to `_x` to avoid a name conflict.
|
|
63
|
+
const exportNameToImportName = createMap();
|
|
64
|
+
for (const propertyAccess of nodesToReplace) {
|
|
65
|
+
const exportName = propertyAccess.name.text;
|
|
66
|
+
let importName = exportNameToImportName.get(exportName);
|
|
67
|
+
if (importName === undefined) {
|
|
68
|
+
exportNameToImportName.set(exportName, importName = conflictingNames.has(exportName) ? getUniqueName(exportName, sourceFile) : exportName);
|
|
69
|
+
}
|
|
70
|
+
changes.replaceNode(sourceFile, propertyAccess, createIdentifier(importName));
|
|
71
|
+
}
|
|
72
|
+
const importSpecifiers = [];
|
|
73
|
+
exportNameToImportName.forEach((name, propertyName) => {
|
|
74
|
+
importSpecifiers.push(createImportSpecifier(name === propertyName ? undefined : createIdentifier(propertyName), createIdentifier(name)));
|
|
75
|
+
});
|
|
76
|
+
const importDecl = toConvert.parent.parent;
|
|
77
|
+
if (usedAsNamespaceOrDefault) {
|
|
78
|
+
// Need to leave the namespace import alone
|
|
79
|
+
changes.insertNodeAfter(sourceFile, importDecl, updateImport(importDecl, /*defaultImportName*/ undefined, importSpecifiers));
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
changes.replaceNode(sourceFile, importDecl, updateImport(importDecl, /*defaultImportName*/ undefined, importSpecifiers));
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
function doChangeNamedToNamespace(sourceFile, checker, changes, toConvert) {
|
|
86
|
+
const importDecl = toConvert.parent.parent;
|
|
87
|
+
const { moduleSpecifier } = importDecl;
|
|
88
|
+
const preferredName = moduleSpecifier && isStringLiteral(moduleSpecifier) ? moduleSpecifierToValidIdentifier(moduleSpecifier.text, ScriptTarget.ESNext) : "module";
|
|
89
|
+
const namespaceNameConflicts = toConvert.elements.some(element => FindAllReferences.Core.eachSymbolReferenceInFile(element.name, checker, sourceFile, id => !!checker.resolveName(preferredName, id, SymbolFlags.All, /*excludeGlobals*/ true)) || false);
|
|
90
|
+
const namespaceImportName = namespaceNameConflicts ? getUniqueName(preferredName, sourceFile) : preferredName;
|
|
91
|
+
const neededNamedImports = [];
|
|
92
|
+
for (const element of toConvert.elements) {
|
|
93
|
+
const propertyName = (element.propertyName || element.name).text;
|
|
94
|
+
FindAllReferences.Core.eachSymbolReferenceInFile(element.name, checker, sourceFile, id => {
|
|
95
|
+
const access = createPropertyAccess(createIdentifier(namespaceImportName), propertyName);
|
|
96
|
+
if (isShorthandPropertyAssignment(id.parent)) {
|
|
97
|
+
changes.replaceNode(sourceFile, id.parent, createPropertyAssignment(id.text, access));
|
|
98
|
+
}
|
|
99
|
+
else if (isExportSpecifier(id.parent) && !id.parent.propertyName) {
|
|
100
|
+
if (!neededNamedImports.some(n => n.name === element.name)) {
|
|
101
|
+
neededNamedImports.push(createImportSpecifier(element.propertyName && createIdentifier(element.propertyName.text), createIdentifier(element.name.text)));
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
changes.replaceNode(sourceFile, id, access);
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
changes.replaceNode(sourceFile, toConvert, createNamespaceImport(createIdentifier(namespaceImportName)));
|
|
110
|
+
if (neededNamedImports.length) {
|
|
111
|
+
changes.insertNodeAfter(sourceFile, toConvert.parent.parent, updateImport(importDecl, /*defaultImportName*/ undefined, neededNamedImports));
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
function updateImport(old, defaultImportName, elements) {
|
|
115
|
+
return createImportDeclaration(/*modifiers*/ undefined, createImportClause(defaultImportName, elements && elements.length ? createNamedImports(elements) : undefined), old.moduleSpecifier);
|
|
116
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
// Modificado de microsoft/TypeScript v3.9.10, src/services/refactors/convertParamsToDestructuredObject.ts: o namespace virou módulo ES, com os imports explícitos.
|
|
2
|
+
// Fica a arrow guardada num `const`, que é a função da Linguagem com nome. Saem a `function` declarada, o método, o
|
|
3
|
+
// construtor e a function expression, com a sobrecarga, o modificador `default`, a classe e as referências a ela, o `new`
|
|
4
|
+
// e o parâmetro `this` (CK-02); e o arquivo JavaScript e o JSDoc (CK-03).
|
|
5
|
+
import { Debug, Diagnostics, EmitFlags, FindAllReferences, SyntaxKind, addEmitFlags, compareValues, contains, copyComments, createArrayLiteral, createBindingElement, createNodeArray, createObjectBindingPattern, createObjectLiteral, createParameter, createPropertyAssignment, createPropertySignature, createShorthandPropertyAssignment, createToken, createTypeLiteralNode, deduplicate, emptyArray, equateValues, every, first, flatMap, getContainingFunctionDeclaration, getLocaleSpecificMessage, getSourceFileOfNode, getSymbolTarget, getSynthesizedDeepClone, getTextOfIdentifierOrLiteral, getTouchingToken, getTypeNodeIfAccessible, isCallOrNewExpression, isDeclaration, isElementAccessExpression, isExportAssignment, isExportSpecifier, isIdentifier, isImportClause, isImportSpecifier, isNamespaceImport, isPropertyAccessExpression, isPropertyAssignment, isRestParameter, isVarConst, isVariableDeclaration, last, map, rangeContainsRange, sortAndDeduplicate, suppressLeadingAndTrailingTrivia, textChanges, tryCast, } from "../_namespaces/edit.js";
|
|
6
|
+
import { registerRefactor, } from "../_namespaces/ts.refactor.js";
|
|
7
|
+
const refactorName = "Convert parameters to destructured object";
|
|
8
|
+
const minimumParameterLength = 2;
|
|
9
|
+
registerRefactor(refactorName, { getEditsForAction, getAvailableActions });
|
|
10
|
+
function getAvailableActions(context) {
|
|
11
|
+
const { file, startPosition } = context;
|
|
12
|
+
const functionDeclaration = getFunctionDeclarationAtPosition(file, startPosition, context.program.getTypeChecker());
|
|
13
|
+
if (!functionDeclaration)
|
|
14
|
+
return emptyArray;
|
|
15
|
+
const description = getLocaleSpecificMessage(Diagnostics.Convert_parameters_to_destructured_object);
|
|
16
|
+
return [{
|
|
17
|
+
name: refactorName,
|
|
18
|
+
description,
|
|
19
|
+
actions: [{
|
|
20
|
+
name: refactorName,
|
|
21
|
+
description
|
|
22
|
+
}]
|
|
23
|
+
}];
|
|
24
|
+
}
|
|
25
|
+
function getEditsForAction(context, actionName) {
|
|
26
|
+
Debug.assert(actionName === refactorName, "Unexpected action name");
|
|
27
|
+
const { file, startPosition, program, cancellationToken, host } = context;
|
|
28
|
+
const functionDeclaration = getFunctionDeclarationAtPosition(file, startPosition, program.getTypeChecker());
|
|
29
|
+
if (!functionDeclaration || !cancellationToken)
|
|
30
|
+
return undefined;
|
|
31
|
+
const groupedReferences = getGroupedReferences(functionDeclaration, program, cancellationToken);
|
|
32
|
+
if (groupedReferences.valid) {
|
|
33
|
+
const edits = textChanges.ChangeTracker.with(context, t => doChange(file, program, host, t, functionDeclaration, groupedReferences));
|
|
34
|
+
return { renameFilename: undefined, renameLocation: undefined, edits };
|
|
35
|
+
}
|
|
36
|
+
return { edits: [] };
|
|
37
|
+
}
|
|
38
|
+
function doChange(sourceFile, program, host, changes, functionDeclaration, groupedReferences) {
|
|
39
|
+
const newParamDeclaration = map(createNewParameters(functionDeclaration, program, host), param => getSynthesizedDeepClone(param));
|
|
40
|
+
changes.replaceNodeRangeWithNodes(sourceFile, first(functionDeclaration.parameters), last(functionDeclaration.parameters), newParamDeclaration, { joiner: ", ",
|
|
41
|
+
// A tag zerava o recuo para o parâmetro de objeto não recuar quando havia um parâmetro `this` (CK-02).
|
|
42
|
+
indentation: 0,
|
|
43
|
+
leadingTriviaOption: textChanges.LeadingTriviaOption.IncludeAll,
|
|
44
|
+
trailingTriviaOption: textChanges.TrailingTriviaOption.Include
|
|
45
|
+
});
|
|
46
|
+
const functionCalls = sortAndDeduplicate(groupedReferences.functionCalls, /*comparer*/ (a, b) => compareValues(a.pos, b.pos));
|
|
47
|
+
for (const call of functionCalls) {
|
|
48
|
+
if (call.arguments && call.arguments.length) {
|
|
49
|
+
const newArgument = getSynthesizedDeepClone(createNewArgument(functionDeclaration, call.arguments), /*includeTrivia*/ true);
|
|
50
|
+
changes.replaceNodeRange(getSourceFileOfNode(call), first(call.arguments), last(call.arguments), newArgument, { leadingTriviaOption: textChanges.LeadingTriviaOption.IncludeAll, trailingTriviaOption: textChanges.TrailingTriviaOption.Include });
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
function getGroupedReferences(functionDeclaration, program, cancellationToken) {
|
|
55
|
+
const functionNames = getFunctionNames(functionDeclaration);
|
|
56
|
+
const names = deduplicate(functionNames, equateValues);
|
|
57
|
+
const checker = program.getTypeChecker();
|
|
58
|
+
const references = flatMap(names, /*mapfn*/ /*mapfn*/ name => FindAllReferences.getReferenceEntriesForNode(-1, name, program, program.getSourceFiles(), cancellationToken));
|
|
59
|
+
const groupedReferences = groupReferences(references);
|
|
60
|
+
if (!every(groupedReferences.declarations, /*callback*/ /*callback*/ decl => contains(names, decl))) {
|
|
61
|
+
groupedReferences.valid = false;
|
|
62
|
+
}
|
|
63
|
+
return groupedReferences;
|
|
64
|
+
function groupReferences(referenceEntries) {
|
|
65
|
+
const groupedReferences = { functionCalls: [], declarations: [], valid: true };
|
|
66
|
+
const functionSymbols = map(functionNames, getSymbolTargetAtLocation);
|
|
67
|
+
for (const entry of referenceEntries) {
|
|
68
|
+
if (entry.kind !== 1 /* FindAllReferences.EntryKind.Node */) {
|
|
69
|
+
groupedReferences.valid = false;
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
// A busca das referências pode dar uma que talvez não seja a da função do refactor: a chamada de um membro de
|
|
73
|
+
// uma união de tipos que têm, cada um, uma função de mesmo nome. Por isso o símbolo se compara. Na tag, também a
|
|
74
|
+
// chamada de um construtor por uma subclasse, que tem o símbolo da classe (CK-02).
|
|
75
|
+
if (contains(functionSymbols, getSymbolTargetAtLocation(entry.node))) {
|
|
76
|
+
const importOrExportReference = entryToImportOrExport(entry);
|
|
77
|
+
if (importOrExportReference) {
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
const decl = entryToDeclaration(entry);
|
|
81
|
+
if (decl) {
|
|
82
|
+
groupedReferences.declarations.push(decl);
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
const call = entryToFunctionCall(entry);
|
|
86
|
+
if (call) {
|
|
87
|
+
groupedReferences.functionCalls.push(call);
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
// Na tag, também as referências à classe de um construtor (CK-02).
|
|
92
|
+
groupedReferences.valid = false;
|
|
93
|
+
}
|
|
94
|
+
return groupedReferences;
|
|
95
|
+
}
|
|
96
|
+
function getSymbolTargetAtLocation(node) {
|
|
97
|
+
const symbol = checker.getSymbolAtLocation(node);
|
|
98
|
+
return symbol && getSymbolTarget(symbol, checker);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
function entryToImportOrExport(entry) {
|
|
102
|
+
const node = entry.node;
|
|
103
|
+
// Na tag, também o `import =` (CK-03).
|
|
104
|
+
if (isImportSpecifier(node.parent)
|
|
105
|
+
|| isImportClause(node.parent)
|
|
106
|
+
|| isNamespaceImport(node.parent)) {
|
|
107
|
+
return node;
|
|
108
|
+
}
|
|
109
|
+
if (isExportSpecifier(node.parent) || isExportAssignment(node.parent)) {
|
|
110
|
+
return node;
|
|
111
|
+
}
|
|
112
|
+
return undefined;
|
|
113
|
+
}
|
|
114
|
+
function entryToDeclaration(entry) {
|
|
115
|
+
if (isDeclaration(entry.node.parent)) {
|
|
116
|
+
return entry.node;
|
|
117
|
+
}
|
|
118
|
+
return undefined;
|
|
119
|
+
}
|
|
120
|
+
function entryToFunctionCall(entry) {
|
|
121
|
+
if (entry.node.parent) {
|
|
122
|
+
const functionReference = entry.node;
|
|
123
|
+
const parent = functionReference.parent;
|
|
124
|
+
switch (parent.kind) {
|
|
125
|
+
// foo(...); na tag, também o `super(...)` e o `new Foo(...)` (CK-02)
|
|
126
|
+
case SyntaxKind.CallExpression:
|
|
127
|
+
const callOrNewExpression = tryCast(parent, isCallOrNewExpression);
|
|
128
|
+
if (callOrNewExpression && callOrNewExpression.expression === functionReference) {
|
|
129
|
+
return callOrNewExpression;
|
|
130
|
+
}
|
|
131
|
+
break;
|
|
132
|
+
// x.foo(...)
|
|
133
|
+
case SyntaxKind.PropertyAccessExpression:
|
|
134
|
+
const propertyAccessExpression = tryCast(parent, isPropertyAccessExpression);
|
|
135
|
+
if (propertyAccessExpression && propertyAccessExpression.parent && propertyAccessExpression.name === functionReference) {
|
|
136
|
+
const callOrNewExpression = tryCast(propertyAccessExpression.parent, isCallOrNewExpression);
|
|
137
|
+
if (callOrNewExpression && callOrNewExpression.expression === propertyAccessExpression) {
|
|
138
|
+
return callOrNewExpression;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
break;
|
|
142
|
+
// x["foo"](...)
|
|
143
|
+
case SyntaxKind.ElementAccessExpression:
|
|
144
|
+
const elementAccessExpression = tryCast(parent, isElementAccessExpression);
|
|
145
|
+
if (elementAccessExpression && elementAccessExpression.parent && elementAccessExpression.argumentExpression === functionReference) {
|
|
146
|
+
const callOrNewExpression = tryCast(elementAccessExpression.parent, isCallOrNewExpression);
|
|
147
|
+
if (callOrNewExpression && callOrNewExpression.expression === elementAccessExpression) {
|
|
148
|
+
return callOrNewExpression;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
break;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
return undefined;
|
|
155
|
+
}
|
|
156
|
+
function getFunctionDeclarationAtPosition(file, startPosition, checker) {
|
|
157
|
+
const node = getTouchingToken(file, startPosition);
|
|
158
|
+
const functionDeclaration = getContainingFunctionDeclaration(node);
|
|
159
|
+
// Na tag, o refactor não se oferecia no JSDoc de topo de uma função (CK-03).
|
|
160
|
+
if (functionDeclaration
|
|
161
|
+
&& isValidFunctionDeclaration(functionDeclaration, checker)
|
|
162
|
+
&& rangeContainsRange(functionDeclaration, node)
|
|
163
|
+
&& !(functionDeclaration.body && rangeContainsRange(functionDeclaration.body, node)))
|
|
164
|
+
return functionDeclaration;
|
|
165
|
+
return undefined;
|
|
166
|
+
}
|
|
167
|
+
function isValidFunctionDeclaration(functionDeclaration, checker) {
|
|
168
|
+
if (!isValidParameterNodeArray(functionDeclaration.parameters, checker))
|
|
169
|
+
return false;
|
|
170
|
+
switch (functionDeclaration.kind) {
|
|
171
|
+
case SyntaxKind.ArrowFunction:
|
|
172
|
+
return isValidVariableDeclaration(functionDeclaration.parent);
|
|
173
|
+
}
|
|
174
|
+
return false;
|
|
175
|
+
}
|
|
176
|
+
function isValidParameterNodeArray(parameters, checker) {
|
|
177
|
+
return parameters.length >= minimumParameterLength
|
|
178
|
+
&& every(parameters, /*callback*/ /*callback*/ paramDecl => isValidParameterDeclaration(paramDecl, checker));
|
|
179
|
+
}
|
|
180
|
+
function isValidParameterDeclaration(parameterDeclaration, checker) {
|
|
181
|
+
if (isRestParameter(parameterDeclaration)) {
|
|
182
|
+
const type = checker.getTypeAtLocation(parameterDeclaration);
|
|
183
|
+
if (!checker.isArrayType(type) && !checker.isTupleType(type))
|
|
184
|
+
return false;
|
|
185
|
+
}
|
|
186
|
+
return !parameterDeclaration.modifiers && isIdentifier(parameterDeclaration.name);
|
|
187
|
+
}
|
|
188
|
+
function isValidVariableDeclaration(node) {
|
|
189
|
+
return isVariableDeclaration(node) && isVarConst(node) && isIdentifier(node.name) && !node.type;
|
|
190
|
+
}
|
|
191
|
+
function createPropertyOrShorthandAssignment(name, initializer) {
|
|
192
|
+
if (isIdentifier(initializer) && getTextOfIdentifierOrLiteral(initializer) === name) {
|
|
193
|
+
return createShorthandPropertyAssignment(name);
|
|
194
|
+
}
|
|
195
|
+
return createPropertyAssignment(name, initializer);
|
|
196
|
+
}
|
|
197
|
+
function createNewArgument(functionDeclaration, functionArguments) {
|
|
198
|
+
const parameters = functionDeclaration.parameters;
|
|
199
|
+
const hasRestParameter = isRestParameter(last(parameters));
|
|
200
|
+
const nonRestArguments = hasRestParameter ? functionArguments.slice(0, parameters.length - 1) : functionArguments;
|
|
201
|
+
const properties = map(nonRestArguments, (arg, i) => {
|
|
202
|
+
const parameterName = getParameterName(parameters[i]);
|
|
203
|
+
const property = createPropertyOrShorthandAssignment(parameterName, arg);
|
|
204
|
+
suppressLeadingAndTrailingTrivia(property.name);
|
|
205
|
+
if (isPropertyAssignment(property))
|
|
206
|
+
suppressLeadingAndTrailingTrivia(property.initializer);
|
|
207
|
+
copyComments(arg, property);
|
|
208
|
+
return property;
|
|
209
|
+
});
|
|
210
|
+
if (hasRestParameter && functionArguments.length >= parameters.length) {
|
|
211
|
+
const restArguments = functionArguments.slice(parameters.length - 1);
|
|
212
|
+
const restProperty = createPropertyAssignment(getParameterName(last(parameters)), createArrayLiteral(restArguments));
|
|
213
|
+
properties.push(restProperty);
|
|
214
|
+
}
|
|
215
|
+
const objectLiteral = createObjectLiteral(properties, /*multiLine*/ false);
|
|
216
|
+
return objectLiteral;
|
|
217
|
+
}
|
|
218
|
+
function createNewParameters(functionDeclaration, program, host) {
|
|
219
|
+
const checker = program.getTypeChecker();
|
|
220
|
+
const refactorableParameters = functionDeclaration.parameters;
|
|
221
|
+
const bindingElements = map(refactorableParameters, createBindingElementFromParameterDeclaration);
|
|
222
|
+
const objectParameterName = createObjectBindingPattern(bindingElements);
|
|
223
|
+
const objectParameterType = createParameterTypeNode(refactorableParameters);
|
|
224
|
+
let objectInitializer;
|
|
225
|
+
// If every parameter in the original function was optional, add an empty object initializer to the new object parameter
|
|
226
|
+
if (every(refactorableParameters, isOptionalParameter)) {
|
|
227
|
+
objectInitializer = createObjectLiteral();
|
|
228
|
+
}
|
|
229
|
+
const objectParameter = createParameter(
|
|
230
|
+
/*modifiers*/ undefined,
|
|
231
|
+
/*dotDotDotToken*/ undefined, objectParameterName,
|
|
232
|
+
/*questionToken*/ undefined, objectParameterType, objectInitializer);
|
|
233
|
+
return createNodeArray([objectParameter]);
|
|
234
|
+
function createBindingElementFromParameterDeclaration(parameterDeclaration) {
|
|
235
|
+
const element = createBindingElement(
|
|
236
|
+
/*dotDotDotToken*/ undefined,
|
|
237
|
+
/*propertyName*/ undefined, getParameterName(parameterDeclaration), isRestParameter(parameterDeclaration) && isOptionalParameter(parameterDeclaration) ? createArrayLiteral() : parameterDeclaration.initializer);
|
|
238
|
+
suppressLeadingAndTrailingTrivia(element);
|
|
239
|
+
if (parameterDeclaration.initializer && element.initializer) {
|
|
240
|
+
copyComments(parameterDeclaration.initializer, element.initializer);
|
|
241
|
+
}
|
|
242
|
+
return element;
|
|
243
|
+
}
|
|
244
|
+
function createParameterTypeNode(parameters) {
|
|
245
|
+
const members = map(parameters, createPropertySignatureFromParameterDeclaration);
|
|
246
|
+
const typeNode = addEmitFlags(createTypeLiteralNode(members), EmitFlags.SingleLine);
|
|
247
|
+
return typeNode;
|
|
248
|
+
}
|
|
249
|
+
function createPropertySignatureFromParameterDeclaration(parameterDeclaration) {
|
|
250
|
+
let parameterType = parameterDeclaration.type;
|
|
251
|
+
if (!parameterType && (parameterDeclaration.initializer || isRestParameter(parameterDeclaration))) {
|
|
252
|
+
parameterType = getTypeNode(parameterDeclaration);
|
|
253
|
+
}
|
|
254
|
+
const propertySignature = createPropertySignature(
|
|
255
|
+
/*modifiers*/ undefined, getParameterName(parameterDeclaration), isOptionalParameter(parameterDeclaration) ? createToken(SyntaxKind.QuestionToken) : parameterDeclaration.questionToken, parameterType,
|
|
256
|
+
/*initializer*/ undefined);
|
|
257
|
+
suppressLeadingAndTrailingTrivia(propertySignature);
|
|
258
|
+
copyComments(parameterDeclaration.name, propertySignature.name);
|
|
259
|
+
if (parameterDeclaration.type && propertySignature.type) {
|
|
260
|
+
copyComments(parameterDeclaration.type, propertySignature.type);
|
|
261
|
+
}
|
|
262
|
+
return propertySignature;
|
|
263
|
+
}
|
|
264
|
+
function getTypeNode(node) {
|
|
265
|
+
const type = checker.getTypeAtLocation(node);
|
|
266
|
+
return getTypeNodeIfAccessible(type, node, program, host);
|
|
267
|
+
}
|
|
268
|
+
function isOptionalParameter(parameterDeclaration) {
|
|
269
|
+
if (isRestParameter(parameterDeclaration)) {
|
|
270
|
+
const type = checker.getTypeAtLocation(parameterDeclaration);
|
|
271
|
+
return !checker.isTupleType(type);
|
|
272
|
+
}
|
|
273
|
+
return checker.isOptionalParameter(parameterDeclaration);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
function getParameterName(paramDeclaration) {
|
|
277
|
+
return getTextOfIdentifierOrLiteral(paramDeclaration.name);
|
|
278
|
+
}
|
|
279
|
+
// Na tag, um `switch` pelo tipo da função; a arrow é o único que fica (CK-02).
|
|
280
|
+
function getFunctionNames(functionDeclaration) {
|
|
281
|
+
return [functionDeclaration.parent.name];
|
|
282
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|