@zzzen/pyright-internal 1.2.0-dev.20230212 → 1.2.0-dev.20230226
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/dist/analyzer/backgroundAnalysisProgram.d.ts +1 -0
- package/dist/analyzer/backgroundAnalysisProgram.js +5 -0
- package/dist/analyzer/backgroundAnalysisProgram.js.map +1 -1
- package/dist/analyzer/binder.js +9 -1
- package/dist/analyzer/binder.js.map +1 -1
- package/dist/analyzer/checker.js +12 -6
- package/dist/analyzer/checker.js.map +1 -1
- package/dist/analyzer/codeFlowEngine.js +1 -1
- package/dist/analyzer/codeFlowEngine.js.map +1 -1
- package/dist/analyzer/commentUtils.d.ts +6 -1
- package/dist/analyzer/commentUtils.js +100 -25
- package/dist/analyzer/commentUtils.js.map +1 -1
- package/dist/analyzer/constraintSolver.js +0 -10
- package/dist/analyzer/constraintSolver.js.map +1 -1
- package/dist/analyzer/declaration.d.ts +2 -0
- package/dist/analyzer/declaration.js.map +1 -1
- package/dist/analyzer/importResolver.d.ts +3 -2
- package/dist/analyzer/importResolver.js +28 -19
- package/dist/analyzer/importResolver.js.map +1 -1
- package/dist/analyzer/importStatementUtils.d.ts +1 -0
- package/dist/analyzer/importStatementUtils.js +14 -1
- package/dist/analyzer/importStatementUtils.js.map +1 -1
- package/dist/analyzer/parseTreeUtils.d.ts +5 -2
- package/dist/analyzer/parseTreeUtils.js +21 -3
- package/dist/analyzer/parseTreeUtils.js.map +1 -1
- package/dist/analyzer/patternMatching.d.ts +1 -0
- package/dist/analyzer/patternMatching.js +54 -6
- package/dist/analyzer/patternMatching.js.map +1 -1
- package/dist/analyzer/program.d.ts +11 -4
- package/dist/analyzer/program.js +122 -25
- package/dist/analyzer/program.js.map +1 -1
- package/dist/analyzer/properties.js +5 -1
- package/dist/analyzer/properties.js.map +1 -1
- package/dist/analyzer/protocols.js +4 -3
- package/dist/analyzer/protocols.js.map +1 -1
- package/dist/analyzer/service.d.ts +7 -6
- package/dist/analyzer/service.js +31 -39
- package/dist/analyzer/service.js.map +1 -1
- package/dist/analyzer/sourceFile.d.ts +4 -0
- package/dist/analyzer/sourceFile.js +85 -16
- package/dist/analyzer/sourceFile.js.map +1 -1
- package/dist/analyzer/typeEvaluator.js +127 -76
- package/dist/analyzer/typeEvaluator.js.map +1 -1
- package/dist/backgroundAnalysisBase.d.ts +2 -2
- package/dist/backgroundAnalysisBase.js +21 -8
- package/dist/backgroundAnalysisBase.js.map +1 -1
- package/dist/backgroundThreadBase.js +1 -0
- package/dist/backgroundThreadBase.js.map +1 -1
- package/dist/commands/commandController.js +1 -0
- package/dist/commands/commandController.js.map +1 -1
- package/dist/commands/quickActionCommand.js +2 -2
- package/dist/commands/quickActionCommand.js.map +1 -1
- package/dist/common/cancellationUtils.d.ts +18 -2
- package/dist/common/cancellationUtils.js +80 -3
- package/dist/common/cancellationUtils.js.map +1 -1
- package/dist/common/commandLineOptions.d.ts +2 -0
- package/dist/common/commandLineOptions.js.map +1 -1
- package/dist/common/configOptions.d.ts +3 -0
- package/dist/common/configOptions.js +10 -1
- package/dist/common/configOptions.js.map +1 -1
- package/dist/common/core.d.ts +2 -0
- package/dist/common/core.js +9 -1
- package/dist/common/core.js.map +1 -1
- package/dist/common/diagnostic.d.ts +15 -3
- package/dist/common/diagnostic.js +13 -4
- package/dist/common/diagnostic.js.map +1 -1
- package/dist/common/editAction.d.ts +1 -0
- package/dist/common/editAction.js +8 -0
- package/dist/common/editAction.js.map +1 -1
- package/dist/common/extensibility.d.ts +36 -12
- package/dist/common/extensibility.js +63 -18
- package/dist/common/extensibility.js.map +1 -1
- package/dist/common/fileBasedCancellationUtils.d.ts +0 -1
- package/dist/common/fileBasedCancellationUtils.js +7 -81
- package/dist/common/fileBasedCancellationUtils.js.map +1 -1
- package/dist/common/pathUtils.d.ts +3 -0
- package/dist/common/pathUtils.js +18 -0
- package/dist/common/pathUtils.js.map +1 -1
- package/dist/common/textEditTracker.d.ts +37 -0
- package/dist/common/textEditTracker.js +301 -0
- package/dist/common/textEditTracker.js.map +1 -0
- package/dist/common/workspaceEditUtils.d.ts +14 -8
- package/dist/common/workspaceEditUtils.js +115 -59
- package/dist/common/workspaceEditUtils.js.map +1 -1
- package/dist/languageServerBase.d.ts +3 -0
- package/dist/languageServerBase.js +93 -4
- package/dist/languageServerBase.js.map +1 -1
- package/dist/languageService/analyzerServiceExecutor.js +1 -0
- package/dist/languageService/analyzerServiceExecutor.js.map +1 -1
- package/dist/languageService/codeActionProvider.js +1 -1
- package/dist/languageService/codeActionProvider.js.map +1 -1
- package/dist/languageService/completionProvider.js +3 -3
- package/dist/languageService/completionProvider.js.map +1 -1
- package/dist/languageService/definitionProvider.js +1 -1
- package/dist/languageService/definitionProvider.js.map +1 -1
- package/dist/languageService/documentSymbolCollector.js +1 -1
- package/dist/languageService/documentSymbolCollector.js.map +1 -1
- package/dist/languageService/hoverProvider.js +13 -6
- package/dist/languageService/hoverProvider.js.map +1 -1
- package/dist/languageService/importAdder.d.ts +5 -1
- package/dist/languageService/importAdder.js +50 -14
- package/dist/languageService/importAdder.js.map +1 -1
- package/dist/languageService/indentationUtils.d.ts +5 -1
- package/dist/languageService/indentationUtils.js +12 -2
- package/dist/languageService/indentationUtils.js.map +1 -1
- package/dist/languageService/insertionPointUtils.js +28 -7
- package/dist/languageService/insertionPointUtils.js.map +1 -1
- package/dist/languageService/renameModuleProvider.d.ts +20 -10
- package/dist/languageService/renameModuleProvider.js +300 -229
- package/dist/languageService/renameModuleProvider.js.map +1 -1
- package/dist/localization/localize.d.ts +12 -0
- package/dist/localization/localize.js +6 -0
- package/dist/localization/localize.js.map +1 -1
- package/dist/localization/package.nls.en-us.json +8 -1
- package/dist/tests/checker.test.js +5 -0
- package/dist/tests/checker.test.js.map +1 -1
- package/dist/tests/fourslash/hover.docstring.parameter.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/hover.docstring.parameter.fourslash.js +57 -0
- package/dist/tests/fourslash/hover.docstring.parameter.fourslash.js.map +1 -0
- package/dist/tests/fourslash/hover.inferred.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/hover.inferred.fourslash.js +24 -0
- package/dist/tests/fourslash/hover.inferred.fourslash.js.map +1 -0
- package/dist/tests/harness/fourslash/testState.js +9 -2
- package/dist/tests/harness/fourslash/testState.js.map +1 -1
- package/dist/tests/importAdder.test.js +40 -3
- package/dist/tests/importAdder.test.js.map +1 -1
- package/dist/tests/indentationUtils.reindent.test.js +1 -1
- package/dist/tests/indentationUtils.reindent.test.js.map +1 -1
- package/dist/tests/insertionPointUtils.test.js +70 -3
- package/dist/tests/insertionPointUtils.test.js.map +1 -1
- package/dist/tests/moveSymbol.importAdder.test.js +192 -0
- package/dist/tests/moveSymbol.importAdder.test.js.map +1 -0
- package/dist/tests/moveSymbol.insertion.test.d.ts +1 -0
- package/dist/tests/moveSymbol.insertion.test.js +397 -0
- package/dist/tests/moveSymbol.insertion.test.js.map +1 -0
- package/dist/tests/moveSymbol.misc.test.d.ts +1 -0
- package/dist/tests/moveSymbol.misc.test.js +142 -0
- package/dist/tests/moveSymbol.misc.test.js.map +1 -0
- package/dist/tests/moveSymbol.updateReference.test.d.ts +1 -0
- package/dist/tests/{updateSymbolReference.test.js → moveSymbol.updateReference.test.js} +235 -158
- package/dist/tests/moveSymbol.updateReference.test.js.map +1 -0
- package/dist/tests/parseTreeUtils.test.js +36 -13
- package/dist/tests/parseTreeUtils.test.js.map +1 -1
- package/dist/tests/renameModuleTestUtils.js +9 -3
- package/dist/tests/renameModuleTestUtils.js.map +1 -1
- package/dist/tests/testStateUtils.d.ts +2 -0
- package/dist/tests/testStateUtils.js +25 -22
- package/dist/tests/testStateUtils.js.map +1 -1
- package/dist/tests/textEditUtil.test.d.ts +1 -0
- package/dist/tests/textEditUtil.test.js +107 -0
- package/dist/tests/textEditUtil.test.js.map +1 -0
- package/dist/tests/typeEvaluator1.test.js +4 -0
- package/dist/tests/typeEvaluator1.test.js.map +1 -1
- package/dist/tests/typeEvaluator2.test.js +12 -0
- package/dist/tests/typeEvaluator2.test.js.map +1 -1
- package/dist/tests/typeEvaluator3.test.js +9 -0
- package/dist/tests/typeEvaluator3.test.js.map +1 -1
- package/dist/tests/typeEvaluator4.test.js +5 -1
- package/dist/tests/typeEvaluator4.test.js.map +1 -1
- package/dist/tests/workspaceEditUtils.test.js +7 -7
- package/dist/tests/workspaceEditUtils.test.js.map +1 -1
- package/dist/workspaceMap.d.ts +0 -1
- package/dist/workspaceMap.js +0 -11
- package/dist/workspaceMap.js.map +1 -1
- package/package.json +3 -3
- package/dist/common/textEditUtils.d.ts +0 -24
- package/dist/common/textEditUtils.js +0 -167
- package/dist/common/textEditUtils.js.map +0 -1
- package/dist/tests/updateSymbolReference.test.js.map +0 -1
- /package/dist/tests/{updateSymbolReference.test.d.ts → moveSymbol.importAdder.test.d.ts} +0 -0
@@ -17,11 +17,12 @@ const importStatementUtils_1 = require("../analyzer/importStatementUtils");
|
|
17
17
|
const parseTreeUtils_1 = require("../analyzer/parseTreeUtils");
|
18
18
|
const parseTreeWalker_1 = require("../analyzer/parseTreeWalker");
|
19
19
|
const sourceMapper_1 = require("../analyzer/sourceMapper");
|
20
|
+
const symbolNameUtils_1 = require("../analyzer/symbolNameUtils");
|
20
21
|
const collectionUtils_1 = require("../common/collectionUtils");
|
21
22
|
const debug_1 = require("../common/debug");
|
22
23
|
const pathUtils_1 = require("../common/pathUtils");
|
23
24
|
const positionUtils_1 = require("../common/positionUtils");
|
24
|
-
const
|
25
|
+
const textEditTracker_1 = require("../common/textEditTracker");
|
25
26
|
const textRange_1 = require("../common/textRange");
|
26
27
|
const parseNodes_1 = require("../parser/parseNodes");
|
27
28
|
const documentSymbolCollector_1 = require("./documentSymbolCollector");
|
@@ -32,32 +33,22 @@ var UpdateType;
|
|
32
33
|
UpdateType[UpdateType["Symbol"] = 2] = "Symbol";
|
33
34
|
})(UpdateType || (UpdateType = {}));
|
34
35
|
class RenameModuleProvider {
|
35
|
-
constructor(_fs, _evaluator, _moduleFilePath, newModuleFilePath, _moduleNameAndType, _newModuleNameAndType, _type,
|
36
|
+
constructor(_fs, _evaluator, _moduleFilePath, newModuleFilePath, _moduleNameAndType, _newModuleNameAndType, _type, declarations, _token) {
|
36
37
|
this._fs = _fs;
|
37
38
|
this._evaluator = _evaluator;
|
38
39
|
this._moduleFilePath = _moduleFilePath;
|
39
40
|
this._moduleNameAndType = _moduleNameAndType;
|
40
41
|
this._newModuleNameAndType = _newModuleNameAndType;
|
41
42
|
this._type = _type;
|
42
|
-
this.
|
43
|
+
this.declarations = declarations;
|
43
44
|
this._token = _token;
|
44
45
|
this._aliasIntroduced = new Set();
|
45
|
-
this._textEditTracker = new
|
46
|
+
this._textEditTracker = new textEditTracker_1.TextEditTracker();
|
46
47
|
// moduleName and newModuleName are always in the absolute path form.
|
47
48
|
this._newModuleFilePath = (0, pathUtils_1.resolvePaths)(newModuleFilePath);
|
48
49
|
this._moduleNames = this._moduleName.split('.');
|
49
50
|
this._newModuleNames = this._newModuleName.split('.');
|
50
|
-
|
51
|
-
this._onlyNameChanged = false;
|
52
|
-
return;
|
53
|
-
}
|
54
|
-
let i = 0;
|
55
|
-
for (i = 0; i < this._moduleNames.length - 1; i++) {
|
56
|
-
if (this._moduleNames[i] !== this._newModuleNames[i]) {
|
57
|
-
break;
|
58
|
-
}
|
59
|
-
}
|
60
|
-
this._onlyNameChanged = i === this._moduleNames.length - 1;
|
51
|
+
this._onlyNameChanged = (0, importStatementUtils_1.haveSameParentModule)(this._moduleNames, this._newModuleNames);
|
61
52
|
(0, debug_1.assert)(this._type !== UpdateType.Folder || this._onlyNameChanged, 'We only support simple rename for folder');
|
62
53
|
}
|
63
54
|
static createForModule(importResolver, configOptions, evaluator, path, newPath, token) {
|
@@ -95,6 +86,68 @@ class RenameModuleProvider {
|
|
95
86
|
}
|
96
87
|
return this._create(importResolver, configOptions, evaluator, path, newPath, UpdateType.Symbol, filteredDecls, token);
|
97
88
|
}
|
89
|
+
static canMoveSymbol(evaluator, node) {
|
90
|
+
if ((0, symbolNameUtils_1.isPrivateName)(node.value)) {
|
91
|
+
return false;
|
92
|
+
}
|
93
|
+
const lookUpResult = evaluator.lookUpSymbolRecursive(node, node.value, /* honorCodeFlow */ false);
|
94
|
+
if (lookUpResult === undefined || lookUpResult.scope.type !== 3 /* Module */) {
|
95
|
+
// We only allow moving a symbol at the module level.
|
96
|
+
return false;
|
97
|
+
}
|
98
|
+
// For now, we only supports module level variable, function and class.
|
99
|
+
const declarations = lookUpResult.symbol.getDeclarations();
|
100
|
+
if (declarations.length === 0) {
|
101
|
+
return false;
|
102
|
+
}
|
103
|
+
return declarations.every((d) => {
|
104
|
+
var _a, _b, _c;
|
105
|
+
if (!textRange_1.TextRange.containsRange(d.node, node)) {
|
106
|
+
return false;
|
107
|
+
}
|
108
|
+
if ((0, declaration_1.isFunctionDeclaration)(d) || (0, declaration_1.isClassDeclaration)(d)) {
|
109
|
+
return true;
|
110
|
+
}
|
111
|
+
if ((0, declaration_1.isVariableDeclaration)(d)) {
|
112
|
+
// We only support simple variable assignment.
|
113
|
+
// ex) a = 1
|
114
|
+
if (d.typeAliasAnnotation) {
|
115
|
+
return false;
|
116
|
+
}
|
117
|
+
if (d.inferredTypeSource && (0, parseNodes_1.isExpressionNode)(d.inferredTypeSource)) {
|
118
|
+
const type = evaluator.getType(d.inferredTypeSource);
|
119
|
+
if ((type === null || type === void 0 ? void 0 : type.category) === 10 /* TypeVar */) {
|
120
|
+
return false;
|
121
|
+
}
|
122
|
+
}
|
123
|
+
// This make sure we are not one of these
|
124
|
+
// ex) a = b = 1
|
125
|
+
// a, b = 1, 2
|
126
|
+
if (((_a = d.node.parent) === null || _a === void 0 ? void 0 : _a.nodeType) !== 3 /* Assignment */ ||
|
127
|
+
((_c = (_b = d.node.parent) === null || _b === void 0 ? void 0 : _b.parent) === null || _c === void 0 ? void 0 : _c.nodeType) !== 47 /* StatementList */) {
|
128
|
+
return false;
|
129
|
+
}
|
130
|
+
if (d.node.start !== d.node.parent.start) {
|
131
|
+
return false;
|
132
|
+
}
|
133
|
+
return true;
|
134
|
+
}
|
135
|
+
return false;
|
136
|
+
});
|
137
|
+
}
|
138
|
+
static getSymbolTextRange(parseResults, decl) {
|
139
|
+
var _a;
|
140
|
+
if ((0, declaration_1.isVariableDeclaration)(decl)) {
|
141
|
+
const range = (0, parseTreeUtils_1.getFullStatementRange)(decl.node, parseResults);
|
142
|
+
return (_a = (0, positionUtils_1.convertRangeToTextRange)(range, parseResults.tokenizerOutput.lines)) !== null && _a !== void 0 ? _a : decl.node;
|
143
|
+
}
|
144
|
+
return decl.node;
|
145
|
+
}
|
146
|
+
static getSymbolFullStatementTextRange(parseResults, decl) {
|
147
|
+
var _a;
|
148
|
+
const range = (0, parseTreeUtils_1.getFullStatementRange)(decl.node, parseResults, { includeTrailingBlankLines: true });
|
149
|
+
return (_a = (0, positionUtils_1.convertRangeToTextRange)(range, parseResults.tokenizerOutput.lines)) !== null && _a !== void 0 ? _a : decl.node;
|
150
|
+
}
|
98
151
|
static getRenameModulePath(declarations) {
|
99
152
|
// If we have a decl with no node, we will prefer that decl over others.
|
100
153
|
// The decl with no node is a synthesized alias decl created only for IDE case
|
@@ -154,21 +207,50 @@ class RenameModuleProvider {
|
|
154
207
|
}
|
155
208
|
return new RenameModuleProvider(importResolver.fileSystem, evaluator, moduleFilePath, newModuleFilePath, moduleName, newModuleName, type, declarations, token);
|
156
209
|
}
|
157
|
-
|
210
|
+
get lastModuleName() {
|
211
|
+
return this._moduleNames[this._moduleNames.length - 1];
|
212
|
+
}
|
213
|
+
get textEditTracker() {
|
214
|
+
return this._textEditTracker;
|
215
|
+
}
|
216
|
+
getEdits() {
|
217
|
+
return this._textEditTracker.getEdits(this._token);
|
218
|
+
}
|
219
|
+
renameReferences(parseResults) {
|
158
220
|
switch (this._type) {
|
159
221
|
case UpdateType.Folder:
|
160
|
-
return this._renameFolderReferences(
|
222
|
+
return this._renameFolderReferences(parseResults);
|
161
223
|
case UpdateType.File:
|
162
|
-
return this._renameModuleReferences(
|
224
|
+
return this._renameModuleReferences(parseResults);
|
163
225
|
case UpdateType.Symbol:
|
164
|
-
return this._updateSymbolReferences(
|
226
|
+
return this._updateSymbolReferences(parseResults);
|
165
227
|
default:
|
166
228
|
return (0, debug_1.assertNever)(this._type, `${this._type} is unknown`);
|
167
229
|
}
|
168
230
|
}
|
169
|
-
|
231
|
+
tryGetFirstSymbolUsage(parseResults, symbol) {
|
170
232
|
var _a, _b, _c;
|
171
|
-
const
|
233
|
+
const name = (_b = (_a = symbol === null || symbol === void 0 ? void 0 : symbol.name) !== null && _a !== void 0 ? _a : (0, declarationUtils_1.getNameFromDeclaration)(this.declarations[0])) !== null && _b !== void 0 ? _b : '';
|
234
|
+
const collector = new documentSymbolCollector_1.DocumentSymbolCollector([name], (_c = symbol === null || symbol === void 0 ? void 0 : symbol.decls) !== null && _c !== void 0 ? _c : this.declarations, this._evaluator, this._token, parseResults.parseTree,
|
235
|
+
/* treatModuleImportAndFromImportSame */ true,
|
236
|
+
/* skipUnreachableCode */ false);
|
237
|
+
for (const result of collector.collect().sort((r1, r2) => r1.range.start - r2.range.start)) {
|
238
|
+
// We only care about symbol usages, not alias decl of the symbol.
|
239
|
+
if ((0, parseTreeUtils_1.isImportModuleName)(result.node) ||
|
240
|
+
(0, parseTreeUtils_1.isImportAlias)(result.node) ||
|
241
|
+
(0, parseTreeUtils_1.isFromImportModuleName)(result.node) ||
|
242
|
+
(0, parseTreeUtils_1.isFromImportName)(result.node) ||
|
243
|
+
(0, parseTreeUtils_1.isFromImportAlias)(result.node)) {
|
244
|
+
continue;
|
245
|
+
}
|
246
|
+
return result.range.start;
|
247
|
+
}
|
248
|
+
return undefined;
|
249
|
+
}
|
250
|
+
_updateSymbolReferences(parseResults) {
|
251
|
+
const filePath = (0, analyzerNodeInfo_1.getFileInfo)(parseResults.parseTree).filePath;
|
252
|
+
const isSource = filePath === this._moduleFilePath;
|
253
|
+
const collector = new documentSymbolCollector_1.DocumentSymbolCollector([(0, declarationUtils_1.getNameFromDeclaration)(this.declarations[0]) || ''], this.declarations, this._evaluator, this._token, parseResults.parseTree,
|
172
254
|
/* treatModuleImportAndFromImportSame */ true,
|
173
255
|
/* skipUnreachableCode */ false);
|
174
256
|
// See if we need to insert new import statement
|
@@ -176,76 +258,73 @@ class RenameModuleProvider {
|
|
176
258
|
// See whether we have existing import statement for the same module
|
177
259
|
// ex) import [moduleName] or from ... import [moduleName]
|
178
260
|
const imported = importStatements.orderedImports.find((i) => i.moduleName === this._newModuleName);
|
179
|
-
|
261
|
+
// Indicate whether current file has any usage of the symbol
|
262
|
+
let hasSymbolUsage = false;
|
263
|
+
const wildcardImports = new Map();
|
180
264
|
const importUsed = new Map();
|
181
265
|
for (const result of collector.collect()) {
|
182
266
|
const nodeFound = result.node;
|
183
267
|
if (nodeFound.nodeType === 49 /* String */) {
|
184
|
-
|
185
|
-
|
268
|
+
if (isSource) {
|
269
|
+
// Delete the symbol reference in __all__ if the file is the source file.
|
270
|
+
this._textEditTracker.addEditWithTextRange(parseResults, nodeFound, '');
|
271
|
+
}
|
186
272
|
continue;
|
187
273
|
}
|
188
274
|
if ((0, parseTreeUtils_1.isFromImportName)(nodeFound)) {
|
189
|
-
|
190
|
-
const fromNode = (_a = nodeFound.parent) === null || _a === void 0 ? void 0 : _a.parent;
|
191
|
-
const newModuleName = this._getNewModuleName(filePath, fromNode.module.leadingDots > 0,
|
192
|
-
/* isLastPartImportName */ false);
|
193
|
-
if (fromNode.imports.length === 1) {
|
194
|
-
// ex) "from [module] import symbol" to "from [module.changed] import symbol"
|
195
|
-
this._addResultWithTextRange(filePath, fromNode.module, parseResults, newModuleName);
|
196
|
-
}
|
197
|
-
else {
|
198
|
-
// ex) "from module import symbol, another_symbol" to
|
199
|
-
// "from module import another_symbol" and "from module.changed import symbol"
|
200
|
-
// Delete the existing import name including alias.
|
201
|
-
const importFromAs = nodeFound.parent;
|
202
|
-
this._addFromImportNameDeletion(filePath, parseResults, nameRemoved, fromNode.imports, importFromAs);
|
203
|
-
// For now, this won't merge absolute and relative path "from import" statement.
|
204
|
-
const importNameInfo = {
|
205
|
-
name: importFromAs.name.value,
|
206
|
-
alias: (_b = importFromAs.alias) === null || _b === void 0 ? void 0 : _b.value,
|
207
|
-
};
|
208
|
-
this._addResultEdits(this._getTextEditsForNewOrExistingFromImport(filePath, fromNode, parseResults, nameRemoved, importStatements, newModuleName, [importNameInfo]));
|
209
|
-
}
|
275
|
+
this._updateNameInFromImportForSymbolReferences(parseResults, importStatements, nodeFound);
|
210
276
|
continue;
|
211
277
|
}
|
278
|
+
// Exclude symbol decl itself.
|
279
|
+
hasSymbolUsage = isSource
|
280
|
+
? !this.declarations.some((d) => textRange_1.TextRange.containsRange(d.node, nodeFound))
|
281
|
+
: true;
|
212
282
|
const dottedName = (0, parseTreeUtils_1.getDottedNameWithGivenNodeAsLastName)(nodeFound);
|
213
283
|
if (dottedName === nodeFound || dottedName.nodeType !== 35 /* MemberAccess */) {
|
284
|
+
this._collectWildcardImports(nodeFound, wildcardImports);
|
214
285
|
// ex) from module import foo
|
215
286
|
// foo
|
216
287
|
// foo.method()
|
217
|
-
//
|
218
|
-
// from module import *
|
219
|
-
// foo()
|
220
|
-
// bar()
|
221
|
-
//
|
222
|
-
// we don't need to do anything for wild card case since
|
223
|
-
// we will preserve __all__ entries.
|
224
|
-
continue;
|
225
|
-
}
|
226
|
-
const moduleName = dottedName.leftExpression.nodeType === 35 /* MemberAccess */
|
227
|
-
? dottedName.leftExpression.memberName
|
228
|
-
: dottedName.leftExpression.nodeType === 38 /* Name */
|
229
|
-
? dottedName.leftExpression
|
230
|
-
: undefined;
|
231
|
-
if (!moduleName) {
|
232
|
-
// ex) from module import foo
|
233
|
-
// getModule().foo
|
234
288
|
continue;
|
235
289
|
}
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
(0
|
246
|
-
|
290
|
+
this._collectSymbolReferencesPerImports(dottedName, importUsed);
|
291
|
+
}
|
292
|
+
if (isSource && hasSymbolUsage) {
|
293
|
+
// If the original file has references to the symbol moved, we need to either
|
294
|
+
// insert import statement or update existing one.
|
295
|
+
const newModuleName = (imported === null || imported === void 0 ? void 0 : imported.node.nodeType) === 22 /* ImportFrom */
|
296
|
+
? this._getNewModuleName(filePath, imported.node.module.leadingDots > 0,
|
297
|
+
/* isLastPartImportName */ false)
|
298
|
+
: undefined;
|
299
|
+
const options = (imported === null || imported === void 0 ? void 0 : imported.node.nodeType) === 22 /* ImportFrom */
|
300
|
+
? {
|
301
|
+
currentFromImport: imported.node,
|
302
|
+
originalModuleName: this._moduleName,
|
303
|
+
}
|
304
|
+
: undefined;
|
305
|
+
this._textEditTracker.addOrUpdateImport(parseResults, importStatements, { name: this._newModuleName, nameForImportFrom: newModuleName }, (0, importStatementUtils_1.getImportGroupFromModuleNameAndType)(this._newModuleNameAndType), [{ name: (0, declarationUtils_1.getNameFromDeclaration)(this.declarations[0]) }], options);
|
247
306
|
}
|
307
|
+
// Handle symbol references that are used off wildcard imports.
|
308
|
+
this._processSymbolReferenceOffWildcardImports(parseResults, importStatements, wildcardImports);
|
248
309
|
// Handle symbol references that are used off imported modules.
|
310
|
+
this._processSymbolReferenceOffImports(parseResults, importStatements, imported, importUsed);
|
311
|
+
}
|
312
|
+
_processSymbolReferenceOffImports(parseResults, importStatements, imported, importUsed) {
|
313
|
+
const filePath = (0, analyzerNodeInfo_1.getFileInfo)(parseResults.parseTree).filePath;
|
314
|
+
const isDestination = filePath === this._newModuleFilePath;
|
315
|
+
if (isDestination) {
|
316
|
+
for (const [key, value] of importUsed) {
|
317
|
+
if (this._canReplaceImportName(parseResults, key, value)) {
|
318
|
+
// We can remove existing import statement.
|
319
|
+
this._textEditTracker.deleteImportName(parseResults, key);
|
320
|
+
}
|
321
|
+
for (const node of value) {
|
322
|
+
this._textEditTracker.addEditWithTextRange(parseResults, textRange_1.TextRange.fromBounds(node.start, node.memberName.start), '');
|
323
|
+
}
|
324
|
+
}
|
325
|
+
return;
|
326
|
+
}
|
327
|
+
// Other files.
|
249
328
|
for (const [key, value] of importUsed) {
|
250
329
|
let referenceModuleName;
|
251
330
|
if (this._canReplaceImportName(parseResults, key, value)) {
|
@@ -253,25 +332,25 @@ class RenameModuleProvider {
|
|
253
332
|
if (key.nodeType === 21 /* ImportAs */) {
|
254
333
|
if (moduleName) {
|
255
334
|
referenceModuleName = moduleName;
|
256
|
-
this.
|
335
|
+
this._textEditTracker.deleteImportName(parseResults, key);
|
257
336
|
}
|
258
337
|
else {
|
259
338
|
referenceModuleName = key.alias ? key.alias.value : this._newModuleName;
|
260
|
-
this.
|
339
|
+
this._textEditTracker.addEditWithTextRange(parseResults, key.module, this._newModuleName);
|
261
340
|
}
|
262
341
|
}
|
263
342
|
else {
|
264
343
|
if (moduleName) {
|
265
344
|
referenceModuleName = moduleName;
|
266
|
-
this.
|
345
|
+
this._textEditTracker.deleteImportName(parseResults, key);
|
267
346
|
}
|
268
347
|
else {
|
269
348
|
const fromNode = key.parent;
|
270
349
|
const newModuleName = this._getNewModuleName(filePath, fromNode.module.leadingDots > 0,
|
271
350
|
/* isLastPartImportName */ true);
|
272
351
|
referenceModuleName = key.alias ? key.alias.value : this._newLastModuleName;
|
273
|
-
this.
|
274
|
-
this.
|
352
|
+
this._textEditTracker.addEditWithTextRange(parseResults, fromNode.module, newModuleName);
|
353
|
+
this._textEditTracker.addEditWithTextRange(parseResults, key.name, this._newLastModuleName);
|
275
354
|
}
|
276
355
|
}
|
277
356
|
}
|
@@ -282,14 +361,102 @@ class RenameModuleProvider {
|
|
282
361
|
}
|
283
362
|
else {
|
284
363
|
referenceModuleName = this._newModuleName;
|
285
|
-
this.
|
364
|
+
this._textEditTracker.addOrUpdateImport(parseResults, importStatements, { name: this._newModuleName }, (0, importStatementUtils_1.getImportGroupFromModuleNameAndType)(this._newModuleNameAndType));
|
286
365
|
}
|
287
366
|
}
|
288
367
|
for (const node of value) {
|
289
|
-
this.
|
368
|
+
this._textEditTracker.addEditWithTextRange(parseResults, node.leftExpression, referenceModuleName);
|
290
369
|
}
|
291
370
|
}
|
292
371
|
}
|
372
|
+
_processSymbolReferenceOffWildcardImports(parseResults, importStatements, wildcardImports) {
|
373
|
+
const filePath = (0, analyzerNodeInfo_1.getFileInfo)(parseResults.parseTree).filePath;
|
374
|
+
const isDestination = filePath === this._newModuleFilePath;
|
375
|
+
if (isDestination) {
|
376
|
+
// Destination file contains the moved symbol decl. no need to insert
|
377
|
+
// import statement for the symbol moved.
|
378
|
+
return;
|
379
|
+
}
|
380
|
+
for (const [key, value] of wildcardImports) {
|
381
|
+
const fromNode = key;
|
382
|
+
const newModuleName = this._getNewModuleName(filePath, fromNode.module.leadingDots > 0,
|
383
|
+
/* isLastPartImportName */ false);
|
384
|
+
this._textEditTracker.addOrUpdateImport(parseResults, importStatements, { name: this._newModuleName, nameForImportFrom: newModuleName }, (0, importStatementUtils_1.getImportGroupFromModuleNameAndType)(this._newModuleNameAndType), [...value].map((v) => ({ name: v })), {
|
385
|
+
currentFromImport: fromNode,
|
386
|
+
originalModuleName: this._moduleName,
|
387
|
+
});
|
388
|
+
}
|
389
|
+
}
|
390
|
+
_collectSymbolReferencesPerImports(dottedName, importUsed) {
|
391
|
+
var _a;
|
392
|
+
const moduleName = dottedName.leftExpression.nodeType === 35 /* MemberAccess */
|
393
|
+
? dottedName.leftExpression.memberName
|
394
|
+
: dottedName.leftExpression.nodeType === 38 /* Name */
|
395
|
+
? dottedName.leftExpression
|
396
|
+
: undefined;
|
397
|
+
if (!moduleName) {
|
398
|
+
// ex) from module import foo
|
399
|
+
// getModule().foo
|
400
|
+
return;
|
401
|
+
}
|
402
|
+
const moduleDecl = (_a = this._evaluator
|
403
|
+
.getDeclarationsForNameNode(moduleName)) === null || _a === void 0 ? void 0 : _a.filter((d) => (0, declaration_1.isAliasDeclaration)(d) &&
|
404
|
+
(d.node.nodeType === 21 /* ImportAs */ || d.node.nodeType === 23 /* ImportFromAs */));
|
405
|
+
if (!moduleDecl || moduleDecl.length === 0) {
|
406
|
+
// ex) from xxx import yyy
|
407
|
+
// yyy.property.foo
|
408
|
+
return;
|
409
|
+
}
|
410
|
+
const importAs = moduleDecl[0].node;
|
411
|
+
(0, collectionUtils_1.getOrAdd)(importUsed, importAs, () => []).push(dottedName);
|
412
|
+
}
|
413
|
+
_collectWildcardImports(nodeFound, wildcardImports) {
|
414
|
+
const nameDecls = this._evaluator.getDeclarationsForNameNode(nodeFound);
|
415
|
+
const aliasDeclFromWildCardImport = nameDecls === null || nameDecls === void 0 ? void 0 : nameDecls.find((d) => d.node.nodeType === 22 /* ImportFrom */ && d.node.isWildcardImport);
|
416
|
+
if (!aliasDeclFromWildCardImport || !(0, declaration_1.isAliasDeclaration)(aliasDeclFromWildCardImport)) {
|
417
|
+
return;
|
418
|
+
}
|
419
|
+
// ex) from module import *
|
420
|
+
// foo()
|
421
|
+
// bar()
|
422
|
+
(0, collectionUtils_1.getOrAdd)(wildcardImports, aliasDeclFromWildCardImport.node, () => new Set()).add(nodeFound.value);
|
423
|
+
}
|
424
|
+
_updateNameInFromImportForSymbolReferences(parseResults, importStatements, nodeFound) {
|
425
|
+
var _a;
|
426
|
+
const filePath = (0, analyzerNodeInfo_1.getFileInfo)(parseResults.parseTree).filePath;
|
427
|
+
const isDestination = filePath === this._newModuleFilePath;
|
428
|
+
// ex) from ... import [symbol] ...
|
429
|
+
const importFromAs = nodeFound.parent;
|
430
|
+
const fromNode = importFromAs === null || importFromAs === void 0 ? void 0 : importFromAs.parent;
|
431
|
+
const newModuleName = this._getNewModuleName(filePath, fromNode.module.leadingDots > 0,
|
432
|
+
/* isLastPartImportName */ false);
|
433
|
+
if (isDestination) {
|
434
|
+
// If we have import statement for the symbol in the destination file,
|
435
|
+
// we need to remove it.
|
436
|
+
// ex) "from module import symbol, another_symbol" to
|
437
|
+
// "from module import another_symbol"
|
438
|
+
this._textEditTracker.deleteImportName(parseResults, importFromAs);
|
439
|
+
return;
|
440
|
+
}
|
441
|
+
if (fromNode.imports.length === 1) {
|
442
|
+
// ex) "from [module] import symbol" to "from [module.changed] import symbol"
|
443
|
+
this._textEditTracker.addEditWithTextRange(parseResults, fromNode.module, newModuleName);
|
444
|
+
return;
|
445
|
+
}
|
446
|
+
// ex) "from module import symbol, another_symbol" to
|
447
|
+
// "from module import another_symbol" and "from module.changed import symbol"
|
448
|
+
// Delete the existing import name including alias.
|
449
|
+
this._textEditTracker.deleteImportName(parseResults, importFromAs);
|
450
|
+
// For now, this won't merge absolute and relative path "from import" statement.
|
451
|
+
const importNameInfo = {
|
452
|
+
name: importFromAs.name.value,
|
453
|
+
alias: (_a = importFromAs.alias) === null || _a === void 0 ? void 0 : _a.value,
|
454
|
+
};
|
455
|
+
this._textEditTracker.addOrUpdateImport(parseResults, importStatements, { name: this._newModuleName, nameForImportFrom: newModuleName }, (0, importStatementUtils_1.getImportGroupFromModuleNameAndType)(this._newModuleNameAndType), [importNameInfo], {
|
456
|
+
currentFromImport: fromNode,
|
457
|
+
originalModuleName: this._moduleName,
|
458
|
+
});
|
459
|
+
}
|
293
460
|
_getReferenceModuleName(importStatements, imported) {
|
294
461
|
var _a, _b;
|
295
462
|
if (imported && imported.node.nodeType === 20 /* Import */) {
|
@@ -323,34 +490,35 @@ class RenameModuleProvider {
|
|
323
490
|
// collector will report decls as well. ignore decls.
|
324
491
|
continue;
|
325
492
|
}
|
493
|
+
// other symbols from the module are used in the file.
|
326
494
|
if (!symbolReferences.some((s) => textRange_1.TextRange.containsRange(s, result.node))) {
|
327
495
|
return false;
|
328
496
|
}
|
329
497
|
}
|
330
498
|
return true;
|
331
499
|
}
|
332
|
-
_renameFolderReferences(
|
333
|
-
const collector = new documentSymbolCollector_1.DocumentSymbolCollector([this.lastModuleName], this.
|
500
|
+
_renameFolderReferences(parseResults) {
|
501
|
+
const collector = new documentSymbolCollector_1.DocumentSymbolCollector([this.lastModuleName], this.declarations, this._evaluator, this._token, parseResults.parseTree,
|
334
502
|
/* treatModuleImportAndFromImportSame */ true,
|
335
503
|
/* skipUnreachableCode */ false);
|
336
504
|
// We only support simple rename of folder. Change all occurrence of the old folder name
|
337
505
|
// to new name.
|
338
506
|
for (const result of collector.collect()) {
|
339
|
-
this.
|
507
|
+
this._textEditTracker.addEditWithTextRange(parseResults, result.range, this._newLastModuleName);
|
340
508
|
}
|
341
509
|
}
|
342
|
-
_renameModuleReferences(
|
343
|
-
const collector = new documentSymbolCollector_1.DocumentSymbolCollector([this.lastModuleName], this.
|
510
|
+
_renameModuleReferences(parseResults) {
|
511
|
+
const collector = new documentSymbolCollector_1.DocumentSymbolCollector([this.lastModuleName], this.declarations, this._evaluator, this._token, parseResults.parseTree,
|
344
512
|
/* treatModuleImportAndFromImportSame */ true,
|
345
513
|
/* skipUnreachableCode */ false);
|
346
|
-
const nameRemoved = new Set();
|
347
514
|
const results = collector.collect();
|
348
515
|
// Update module references first.
|
349
|
-
this._updateModuleReferences(
|
516
|
+
this._updateModuleReferences(parseResults, results);
|
350
517
|
// If the module file has moved, we need to update all relative paths used in the file to reflect the move.
|
351
|
-
this._updateRelativeModuleNamePath(
|
518
|
+
this._updateRelativeModuleNamePath(parseResults, results);
|
352
519
|
}
|
353
|
-
_updateRelativeModuleNamePath(
|
520
|
+
_updateRelativeModuleNamePath(parseResults, results) {
|
521
|
+
const filePath = (0, analyzerNodeInfo_1.getFileInfo)(parseResults.parseTree).filePath;
|
354
522
|
if (filePath !== this._moduleFilePath) {
|
355
523
|
// We only update relative import paths for the file that has moved.
|
356
524
|
return;
|
@@ -358,7 +526,7 @@ class RenameModuleProvider {
|
|
358
526
|
let importStatements;
|
359
527
|
// Filter out module name that is already re-written.
|
360
528
|
for (const edit of this._getNewRelativeModuleNamesForFileMoved(filePath, ModuleNameCollector.collect(parseResults.parseTree).filter((m) => !results.some((r) => textRange_1.TextRange.containsRange(m.parent, r.node))))) {
|
361
|
-
this.
|
529
|
+
this._textEditTracker.addEditWithTextRange(parseResults, edit.moduleName, edit.newModuleName);
|
362
530
|
if (!edit.itemsToMove) {
|
363
531
|
continue;
|
364
532
|
}
|
@@ -370,28 +538,35 @@ class RenameModuleProvider {
|
|
370
538
|
const fromNode = edit.moduleName.parent;
|
371
539
|
// First, delete existing exported symbols from "from import" statement.
|
372
540
|
for (const importFromAs of edit.itemsToMove) {
|
373
|
-
this.
|
541
|
+
this._textEditTracker.deleteImportName(parseResults, importFromAs);
|
374
542
|
}
|
375
543
|
importStatements =
|
376
544
|
importStatements !== null && importStatements !== void 0 ? importStatements : (0, importStatementUtils_1.getTopLevelImports)(parseResults.parseTree, /* includeImplicitImports */ false);
|
377
545
|
// For now, this won't merge absolute and relative path "from import"
|
378
546
|
// statement.
|
379
|
-
this.
|
380
|
-
|
381
|
-
|
547
|
+
this._textEditTracker.addOrUpdateImport(parseResults, importStatements, {
|
548
|
+
name: this._newModuleName,
|
549
|
+
nameForImportFrom: (0, importStatementUtils_1.getRelativeModuleName)(this._fs, this._newModuleFilePath, this._newModuleFilePath,
|
550
|
+
/* ignoreFolderStructure */ false,
|
551
|
+
/* sourceIsFile */ true),
|
552
|
+
}, (0, importStatementUtils_1.getImportGroupFromModuleNameAndType)(this._newModuleNameAndType), edit.itemsToMove.map((i) => {
|
382
553
|
var _a;
|
383
554
|
return { name: i.name.value, alias: (_a = i.alias) === null || _a === void 0 ? void 0 : _a.value };
|
384
|
-
})
|
555
|
+
}), {
|
556
|
+
currentFromImport: fromNode,
|
557
|
+
originalModuleName: this._moduleName,
|
558
|
+
});
|
385
559
|
}
|
386
560
|
}
|
387
|
-
_updateModuleReferences(
|
561
|
+
_updateModuleReferences(parseResults, results) {
|
388
562
|
var _a, _b, _c, _d, _e;
|
563
|
+
const filePath = (0, analyzerNodeInfo_1.getFileInfo)(parseResults.parseTree).filePath;
|
389
564
|
let importStatements;
|
390
565
|
for (const result of results) {
|
391
566
|
const nodeFound = result.node;
|
392
567
|
if (nodeFound.nodeType === 49 /* String */) {
|
393
568
|
// ex) __all__ = ["[a]"]
|
394
|
-
this.
|
569
|
+
this._textEditTracker.addEditWithTextRange(parseResults, result.range, this._newLastModuleName);
|
395
570
|
continue;
|
396
571
|
}
|
397
572
|
if ((0, parseTreeUtils_1.isImportModuleName)(nodeFound)) {
|
@@ -419,17 +594,17 @@ class RenameModuleProvider {
|
|
419
594
|
!moduleNameNode.parent.alias &&
|
420
595
|
this._newModuleNames.length > 1) {
|
421
596
|
this._aliasIntroduced.add(moduleNameNode.parent);
|
422
|
-
this.
|
597
|
+
this._textEditTracker.addEditWithTextRange(parseResults, moduleNameNode, `${this._newModuleName} as ${this._newLastModuleName}`);
|
423
598
|
continue;
|
424
599
|
}
|
425
600
|
// Otherwise, update whole module name to new name
|
426
601
|
// ex) import [xxx.yyy] to import [aaa.bbb]
|
427
|
-
this.
|
602
|
+
this._textEditTracker.addEditWithTextRange(parseResults, moduleNameNode, this._newModuleName);
|
428
603
|
continue;
|
429
604
|
}
|
430
605
|
if ((0, parseTreeUtils_1.isImportAlias)(nodeFound)) {
|
431
606
|
// ex) import xxx as [yyy] to import xxx as [zzz]
|
432
|
-
this.
|
607
|
+
this._textEditTracker.addEditWithTextRange(parseResults, result.range, this._newLastModuleName);
|
433
608
|
continue;
|
434
609
|
}
|
435
610
|
if ((0, parseTreeUtils_1.isFromImportModuleName)(nodeFound)) {
|
@@ -456,7 +631,7 @@ class RenameModuleProvider {
|
|
456
631
|
// We don't have any sub modules, we can change module name to new one.
|
457
632
|
// Update whole module name to new name.
|
458
633
|
// ex) from [xxx.yyy] import zzz to from [aaa.bbb] import zzz
|
459
|
-
this.
|
634
|
+
this._textEditTracker.addEditWithTextRange(parseResults, moduleNameNode, this._getNewModuleName(filePath, moduleNameNode.leadingDots > 0,
|
460
635
|
/* isLastPartImportName */ false));
|
461
636
|
continue;
|
462
637
|
}
|
@@ -470,31 +645,32 @@ class RenameModuleProvider {
|
|
470
645
|
// Update module name if needed.
|
471
646
|
if (fromNode.module.leadingDots > 0) {
|
472
647
|
for (const edit of this._getNewRelativeModuleNamesForFileMoved(filePath, [fromNode.module])) {
|
473
|
-
this.
|
648
|
+
this._textEditTracker.addEditWithTextRange(parseResults, edit.moduleName, edit.newModuleName);
|
474
649
|
}
|
475
650
|
}
|
476
651
|
// First, delete existing exported symbols from "from import" statement.
|
477
652
|
for (const importFromAs of exportedSymbols) {
|
478
|
-
this.
|
653
|
+
this._textEditTracker.deleteImportName(parseResults, importFromAs);
|
479
654
|
}
|
480
655
|
importStatements =
|
481
656
|
importStatements !== null && importStatements !== void 0 ? importStatements : (0, importStatementUtils_1.getTopLevelImports)(parseResults.parseTree, /* includeImplicitImports */ false);
|
482
657
|
// For now, this won't merge absolute and relative path "from import"
|
483
658
|
// statement.
|
484
|
-
this.
|
659
|
+
this._textEditTracker.addOrUpdateImport(parseResults, importStatements, { name: this._newModuleName }, (0, importStatementUtils_1.getImportGroupFromModuleNameAndType)(this._newModuleNameAndType), exportedSymbols.map((i) => {
|
485
660
|
var _a;
|
486
|
-
const name = results.findIndex((r) => r.node === i.name) >= 0
|
487
|
-
? this._newLastModuleName
|
488
|
-
: i.name.value;
|
661
|
+
const name = results.findIndex((r) => r.node === i.name) >= 0 ? this._newLastModuleName : i.name.value;
|
489
662
|
const alias = results.findIndex((r) => r.node === i.alias) >= 0
|
490
663
|
? this._newLastModuleName
|
491
664
|
: (_a = i.alias) === null || _a === void 0 ? void 0 : _a.value;
|
492
665
|
return { name, alias };
|
493
|
-
})
|
666
|
+
}), {
|
667
|
+
currentFromImport: fromNode,
|
668
|
+
originalModuleName: this._moduleName,
|
669
|
+
});
|
494
670
|
continue;
|
495
671
|
}
|
496
672
|
if ((0, parseTreeUtils_1.isFromImportName)(nodeFound)) {
|
497
|
-
if (
|
673
|
+
if (this._textEditTracker.isNodeRemoved(nodeFound)) {
|
498
674
|
// Import name is already removed.
|
499
675
|
continue;
|
500
676
|
}
|
@@ -505,13 +681,13 @@ class RenameModuleProvider {
|
|
505
681
|
// Existing logic should make sure re-exported symbol name work as before after
|
506
682
|
// symbol rename.
|
507
683
|
if (this._isExportedSymbol(nodeFound)) {
|
508
|
-
this.
|
684
|
+
this._textEditTracker.addEditWithTextRange(parseResults, result.range, this._newLastModuleName);
|
509
685
|
continue;
|
510
686
|
}
|
511
687
|
if (fromNode.imports.length === 1) {
|
512
688
|
// ex) from xxx import [yyy] to from [aaa.bbb] import [zzz]
|
513
|
-
this.
|
514
|
-
this.
|
689
|
+
this._textEditTracker.addEditWithTextRange(parseResults, fromNode.module, newModuleName);
|
690
|
+
this._textEditTracker.addEditWithTextRange(parseResults, result.range, this._newLastModuleName);
|
515
691
|
}
|
516
692
|
else {
|
517
693
|
// Delete the existing import name including alias.
|
@@ -519,10 +695,10 @@ class RenameModuleProvider {
|
|
519
695
|
// Update module name if needed.
|
520
696
|
if (fromNode.module.leadingDots > 0) {
|
521
697
|
for (const edit of this._getNewRelativeModuleNamesForFileMoved(filePath, [fromNode.module])) {
|
522
|
-
this.
|
698
|
+
this._textEditTracker.addEditWithTextRange(parseResults, edit.moduleName, edit.newModuleName);
|
523
699
|
}
|
524
700
|
}
|
525
|
-
this.
|
701
|
+
this._textEditTracker.deleteImportName(parseResults, importFromAs);
|
526
702
|
importStatements =
|
527
703
|
importStatements !== null && importStatements !== void 0 ? importStatements : (0, importStatementUtils_1.getTopLevelImports)(parseResults.parseTree, /* includeImplicitImports */ false);
|
528
704
|
// ex) from xxx import yyy, [zzz] to
|
@@ -541,17 +717,20 @@ class RenameModuleProvider {
|
|
541
717
|
? this._newLastModuleName
|
542
718
|
: (_d = importFromAs.alias) === null || _d === void 0 ? void 0 : _d.value,
|
543
719
|
};
|
544
|
-
this.
|
720
|
+
this._textEditTracker.addOrUpdateImport(parseResults, importStatements, { name: this._newModuleName, nameForImportFrom: newModuleName }, (0, importStatementUtils_1.getImportGroupFromModuleNameAndType)(this._newModuleNameAndType), [importNameInfo], {
|
721
|
+
currentFromImport: fromNode,
|
722
|
+
originalModuleName: this._moduleName,
|
723
|
+
});
|
545
724
|
}
|
546
725
|
continue;
|
547
726
|
}
|
548
727
|
if ((0, parseTreeUtils_1.isFromImportAlias)(nodeFound)) {
|
549
|
-
if (
|
728
|
+
if (this._textEditTracker.isNodeRemoved(nodeFound)) {
|
550
729
|
// alias is already removed.
|
551
730
|
continue;
|
552
731
|
}
|
553
732
|
// ex) from ccc import xxx as [yyy] to from ccc import xxx as [zzz]
|
554
|
-
this.
|
733
|
+
this._textEditTracker.addEditWithTextRange(parseResults, result.range, this._newLastModuleName);
|
555
734
|
continue;
|
556
735
|
}
|
557
736
|
/** TODO: if we get more than 1 decls, flag it as attention needed */
|
@@ -561,7 +740,7 @@ class RenameModuleProvider {
|
|
561
740
|
// Simple case. only name has changed. but not path.
|
562
741
|
// Just replace name to new symbol name.
|
563
742
|
// ex) a.[b].foo() to a.[z].foo()
|
564
|
-
this.
|
743
|
+
this._textEditTracker.addEditWithTextRange(parseResults, result.range, this._newLastModuleName);
|
565
744
|
continue;
|
566
745
|
}
|
567
746
|
if (decls === null || decls === void 0 ? void 0 : decls.some((d) => !d.usesLocalName &&
|
@@ -570,7 +749,7 @@ class RenameModuleProvider {
|
|
570
749
|
const dottedName = (0, parseTreeUtils_1.getDottedNameWithGivenNodeAsLastName)(nodeFound);
|
571
750
|
if (((_e = dottedName.parent) === null || _e === void 0 ? void 0 : _e.nodeType) !== 35 /* MemberAccess */) {
|
572
751
|
// Replace whole dotted name with new module name.
|
573
|
-
this.
|
752
|
+
this._textEditTracker.addEditWithTextRange(parseResults, dottedName, this._newModuleName);
|
574
753
|
continue;
|
575
754
|
}
|
576
755
|
// Check whether name after me is sub module or not.
|
@@ -586,11 +765,11 @@ class RenameModuleProvider {
|
|
586
765
|
// Next name is actual symbol. Replace whole name to new module name.
|
587
766
|
// ex) import a.b.c
|
588
767
|
// [a.b.c].[foo]()
|
589
|
-
this.
|
768
|
+
this._textEditTracker.addEditWithTextRange(parseResults, dottedName, this._newModuleName);
|
590
769
|
continue;
|
591
770
|
}
|
592
771
|
if (result.node.value !== this._newLastModuleName) {
|
593
|
-
this.
|
772
|
+
this._textEditTracker.addEditWithTextRange(parseResults, result.range, this._newLastModuleName);
|
594
773
|
continue;
|
595
774
|
}
|
596
775
|
}
|
@@ -705,12 +884,6 @@ class RenameModuleProvider {
|
|
705
884
|
// ex) x.y.z used in "from x.y.z import ..."
|
706
885
|
return moduleName;
|
707
886
|
}
|
708
|
-
getEdits() {
|
709
|
-
return this._textEditTracker.getEdits(this._token);
|
710
|
-
}
|
711
|
-
get lastModuleName() {
|
712
|
-
return this._moduleNames[this._moduleNames.length - 1];
|
713
|
-
}
|
714
887
|
get _moduleName() {
|
715
888
|
return this._moduleNameAndType.moduleName;
|
716
889
|
}
|
@@ -720,108 +893,6 @@ class RenameModuleProvider {
|
|
720
893
|
get _newModuleName() {
|
721
894
|
return this._newModuleNameAndType.moduleName;
|
722
895
|
}
|
723
|
-
_addImportNameDeletion(filePath, parseResults, nameRemoved, imports, importToDelete) {
|
724
|
-
this._addImportNameDeletionInternal(filePath, parseResults, nameRemoved, imports, importToDelete, 20 /* Import */);
|
725
|
-
// Mark that we don't need to process these node again later.
|
726
|
-
nameRemoved.add(importToDelete.module.id);
|
727
|
-
importToDelete.module.nameParts.forEach((n) => nameRemoved.add(n.id));
|
728
|
-
if (importToDelete.alias) {
|
729
|
-
nameRemoved.add(importToDelete.alias.id);
|
730
|
-
}
|
731
|
-
}
|
732
|
-
_addFromImportNameDeletion(filePath, parseResults, nameRemoved, imports, importToDelete) {
|
733
|
-
this._addImportNameDeletionInternal(filePath, parseResults, nameRemoved, imports, importToDelete, 22 /* ImportFrom */);
|
734
|
-
// Mark that we don't need to process these node again later.
|
735
|
-
nameRemoved.add(importToDelete.name.id);
|
736
|
-
if (importToDelete.alias) {
|
737
|
-
nameRemoved.add(importToDelete.alias.id);
|
738
|
-
}
|
739
|
-
}
|
740
|
-
_addImportNameDeletionInternal(filePath, parseResults, nameRemoved, imports, importToDelete, importKind) {
|
741
|
-
const ranges = (0, importStatementUtils_1.getTextRangeForImportNameDeletion)(imports, imports.findIndex((v) => v === importToDelete));
|
742
|
-
ranges.forEach((r) => this._addResultWithTextRange(filePath, r, parseResults, ''));
|
743
|
-
// Mark that we don't need to process these node again later.
|
744
|
-
nameRemoved.add(importToDelete.id);
|
745
|
-
// Check whether we have deleted all trailing import names.
|
746
|
-
// If either no trailing import is deleted or handled properly
|
747
|
-
// then, there is nothing to do. otherwise, either delete the whole statement
|
748
|
-
// or remove trailing comma.
|
749
|
-
// ex) from x import [y], z or from x import y[, z]
|
750
|
-
let lastImportIndexNotDeleted = 0;
|
751
|
-
for (lastImportIndexNotDeleted = imports.length - 1; lastImportIndexNotDeleted >= 0; lastImportIndexNotDeleted--) {
|
752
|
-
if (!nameRemoved.has(imports[lastImportIndexNotDeleted].id)) {
|
753
|
-
break;
|
754
|
-
}
|
755
|
-
}
|
756
|
-
if (lastImportIndexNotDeleted === -1) {
|
757
|
-
// Whole statement is deleted. Remove the statement itself.
|
758
|
-
// ex) [from x import a, b, c] or [import a]
|
759
|
-
const importStatement = (0, parseTreeUtils_1.getFirstAncestorOrSelfOfKind)(importToDelete, importKind);
|
760
|
-
if (importStatement) {
|
761
|
-
this._textEditTracker.addEdit(filePath, (0, parseTreeUtils_1.getFullStatementRange)(importStatement, parseResults.tokenizerOutput), '');
|
762
|
-
}
|
763
|
-
}
|
764
|
-
else if (lastImportIndexNotDeleted >= 0 && lastImportIndexNotDeleted < imports.length - 2) {
|
765
|
-
// We need to delete trailing comma
|
766
|
-
// ex) from x import a, [b, c]
|
767
|
-
const start = textRange_1.TextRange.getEnd(imports[lastImportIndexNotDeleted]);
|
768
|
-
const length = textRange_1.TextRange.getEnd(imports[lastImportIndexNotDeleted + 1]) - start;
|
769
|
-
this._addResultWithTextRange(filePath, { start, length }, parseResults, '');
|
770
|
-
}
|
771
|
-
}
|
772
|
-
_addResultWithTextRange(filePath, range, parseResults, newName) {
|
773
|
-
const existing = parseResults.text.substr(range.start, range.length);
|
774
|
-
if (existing === newName) {
|
775
|
-
// No change. Return as it is.
|
776
|
-
return;
|
777
|
-
}
|
778
|
-
this._textEditTracker.addEdit(filePath, (0, positionUtils_1.convertTextRangeToRange)(range, parseResults.tokenizerOutput.lines), newName);
|
779
|
-
}
|
780
|
-
_addResultEdits(edits) {
|
781
|
-
this._textEditTracker.addEdits(...edits);
|
782
|
-
}
|
783
|
-
_getTextEditsForNewOrExistingFromImport(filePath, currentFromImport, parseResults, nameRemoved, importStatements, moduleName, importNameInfo) {
|
784
|
-
// See whether we have existing from import statement for the same module
|
785
|
-
// ex) from [|moduleName|] import subModule
|
786
|
-
const imported = importStatements.orderedImports.find((i) => i.moduleName === moduleName);
|
787
|
-
if (imported && imported.node.nodeType === 22 /* ImportFrom */ && !imported.node.isWildcardImport) {
|
788
|
-
const edits = (0, importStatementUtils_1.getTextEditsForAutoImportSymbolAddition)(importNameInfo, imported, parseResults);
|
789
|
-
if (imported.node !== currentFromImport) {
|
790
|
-
// Add what we want to the existing "import from" statement as long as it is not the same import
|
791
|
-
// node we are working on.
|
792
|
-
return edits.map((e) => ({ filePath, range: e.range, replacementText: e.replacementText }));
|
793
|
-
}
|
794
|
-
// Check whether we can avoid creating a new statement. We can't just merge with existing one since
|
795
|
-
// we could create invalid text edits (2 edits that change the same span, or invalid replacement text since
|
796
|
-
// texts on the node has changed)
|
797
|
-
if (this._onlyNameChanged && importNameInfo.length === 1 && edits.length === 1) {
|
798
|
-
const deletions = this._textEditTracker.getDeletionsForSpan(filePath, edits[0].range);
|
799
|
-
if (deletions.length === 0) {
|
800
|
-
return [{ filePath, range: edits[0].range, replacementText: edits[0].replacementText }];
|
801
|
-
}
|
802
|
-
else {
|
803
|
-
const alias = importNameInfo[0].alias === this._newLastModuleName
|
804
|
-
? this.lastModuleName
|
805
|
-
: importNameInfo[0].alias;
|
806
|
-
const importName = currentFromImport.imports.find((i) => { var _a; return i.name.value === this.lastModuleName && ((_a = i.alias) === null || _a === void 0 ? void 0 : _a.value) === alias; });
|
807
|
-
if (importName) {
|
808
|
-
this._textEditTracker.removeEdits(filePath, deletions);
|
809
|
-
if (importName.alias) {
|
810
|
-
nameRemoved.delete(importName.alias.id);
|
811
|
-
}
|
812
|
-
return [
|
813
|
-
{
|
814
|
-
filePath,
|
815
|
-
range: (0, positionUtils_1.convertTextRangeToRange)(importName.name, parseResults.tokenizerOutput.lines),
|
816
|
-
replacementText: this._newLastModuleName,
|
817
|
-
},
|
818
|
-
];
|
819
|
-
}
|
820
|
-
}
|
821
|
-
}
|
822
|
-
}
|
823
|
-
return (0, importStatementUtils_1.getTextEditsForAutoImportInsertion)(importNameInfo, { name: moduleName }, importStatements, (0, importStatementUtils_1.getImportGroupFromModuleNameAndType)(this._newModuleNameAndType), parseResults, (0, positionUtils_1.convertOffsetToPosition)(parseResults.parseTree.length, parseResults.tokenizerOutput.lines)).map((e) => ({ filePath, range: e.range, replacementText: e.replacementText }));
|
824
|
-
}
|
825
896
|
}
|
826
897
|
exports.RenameModuleProvider = RenameModuleProvider;
|
827
898
|
class ModuleNameCollector extends parseTreeWalker_1.ParseTreeWalker {
|