@zzzen/pyright-internal 1.2.0-dev.20230423 → 1.2.0-dev.20230430

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.
Files changed (166) hide show
  1. package/dist/analyzer/analyzerFileInfo.d.ts +4 -1
  2. package/dist/analyzer/analyzerFileInfo.js.map +1 -1
  3. package/dist/analyzer/backgroundAnalysisProgram.d.ts +4 -4
  4. package/dist/analyzer/backgroundAnalysisProgram.js +10 -7
  5. package/dist/analyzer/backgroundAnalysisProgram.js.map +1 -1
  6. package/dist/analyzer/binder.js +12 -7
  7. package/dist/analyzer/binder.js.map +1 -1
  8. package/dist/analyzer/checker.js +6 -3
  9. package/dist/analyzer/checker.js.map +1 -1
  10. package/dist/analyzer/dataClasses.js +5 -2
  11. package/dist/analyzer/dataClasses.js.map +1 -1
  12. package/dist/analyzer/declarationUtils.d.ts +6 -1
  13. package/dist/analyzer/declarationUtils.js +10 -8
  14. package/dist/analyzer/declarationUtils.js.map +1 -1
  15. package/dist/analyzer/importResolver.d.ts +15 -15
  16. package/dist/analyzer/importResolver.js +477 -477
  17. package/dist/analyzer/importResolver.js.map +1 -1
  18. package/dist/analyzer/namedTuples.d.ts +1 -1
  19. package/dist/analyzer/namedTuples.js +29 -41
  20. package/dist/analyzer/namedTuples.js.map +1 -1
  21. package/dist/analyzer/packageTypeReport.d.ts +2 -1
  22. package/dist/analyzer/packageTypeReport.js +2 -1
  23. package/dist/analyzer/packageTypeReport.js.map +1 -1
  24. package/dist/analyzer/packageTypeVerifier.d.ts +1 -1
  25. package/dist/analyzer/packageTypeVerifier.js +27 -13
  26. package/dist/analyzer/packageTypeVerifier.js.map +1 -1
  27. package/dist/analyzer/program.d.ts +25 -37
  28. package/dist/analyzer/program.js +1356 -1508
  29. package/dist/analyzer/program.js.map +1 -1
  30. package/dist/analyzer/protocols.js +1 -1
  31. package/dist/analyzer/protocols.js.map +1 -1
  32. package/dist/analyzer/service.d.ts +12 -25
  33. package/dist/analyzer/service.js +76 -109
  34. package/dist/analyzer/service.js.map +1 -1
  35. package/dist/analyzer/sourceFile.d.ts +6 -18
  36. package/dist/analyzer/sourceFile.js +57 -121
  37. package/dist/analyzer/sourceFile.js.map +1 -1
  38. package/dist/analyzer/sourceFileInfoUtils.d.ts +7 -1
  39. package/dist/analyzer/sourceFileInfoUtils.js.map +1 -1
  40. package/dist/analyzer/typeEvaluator.js +354 -322
  41. package/dist/analyzer/typeEvaluator.js.map +1 -1
  42. package/dist/analyzer/typeEvaluatorTypes.d.ts +6 -2
  43. package/dist/analyzer/typeGuards.js +3 -1
  44. package/dist/analyzer/typeGuards.js.map +1 -1
  45. package/dist/analyzer/typeStubWriter.js.map +1 -1
  46. package/dist/analyzer/typeUtils.d.ts +1 -0
  47. package/dist/analyzer/typeUtils.js +35 -8
  48. package/dist/analyzer/typeUtils.js.map +1 -1
  49. package/dist/backgroundAnalysisBase.d.ts +10 -11
  50. package/dist/backgroundAnalysisBase.js +87 -87
  51. package/dist/backgroundAnalysisBase.js.map +1 -1
  52. package/dist/commands/dumpFileDebugInfoCommand.js +8 -8
  53. package/dist/commands/dumpFileDebugInfoCommand.js.map +1 -1
  54. package/dist/commands/quickActionCommand.js +4 -1
  55. package/dist/commands/quickActionCommand.js.map +1 -1
  56. package/dist/common/cancellationUtils.d.ts +1 -1
  57. package/dist/common/cancellationUtils.js +9 -9
  58. package/dist/common/cancellationUtils.js.map +1 -1
  59. package/dist/common/commandLineOptions.d.ts +1 -2
  60. package/dist/common/commandLineOptions.js.map +1 -1
  61. package/dist/common/configOptions.d.ts +2 -2
  62. package/dist/common/configOptions.js.map +1 -1
  63. package/dist/common/console.d.ts +5 -9
  64. package/dist/common/console.js +46 -33
  65. package/dist/common/console.js.map +1 -1
  66. package/dist/common/deferred.js +10 -10
  67. package/dist/common/deferred.js.map +1 -1
  68. package/dist/common/extensibility.d.ts +26 -5
  69. package/dist/common/extensibility.js +1 -1
  70. package/dist/common/extensibility.js.map +1 -1
  71. package/dist/common/fileBasedCancellationUtils.js +5 -5
  72. package/dist/common/fileBasedCancellationUtils.js.map +1 -1
  73. package/dist/common/fileSystem.d.ts +12 -10
  74. package/dist/common/fileSystem.js.map +1 -1
  75. package/dist/common/fullAccessHost.d.ts +3 -3
  76. package/dist/common/fullAccessHost.js +6 -6
  77. package/dist/common/fullAccessHost.js.map +1 -1
  78. package/dist/common/pathUtils.d.ts +2 -2
  79. package/dist/common/pathUtils.js.map +1 -1
  80. package/dist/common/realFileSystem.js +12 -7
  81. package/dist/common/realFileSystem.js.map +1 -1
  82. package/dist/common/uriParser.d.ts +2 -2
  83. package/dist/common/uriParser.js +3 -3
  84. package/dist/common/uriParser.js.map +1 -1
  85. package/dist/common/workspaceEditUtils.js +7 -4
  86. package/dist/common/workspaceEditUtils.js.map +1 -1
  87. package/dist/languageServerBase.d.ts +32 -30
  88. package/dist/languageServerBase.js +274 -336
  89. package/dist/languageServerBase.js.map +1 -1
  90. package/dist/languageService/analyzerServiceExecutor.js +0 -1
  91. package/dist/languageService/analyzerServiceExecutor.js.map +1 -1
  92. package/dist/languageService/callHierarchyProvider.d.ts +16 -12
  93. package/dist/languageService/callHierarchyProvider.js +125 -41
  94. package/dist/languageService/callHierarchyProvider.js.map +1 -1
  95. package/dist/languageService/definitionProvider.d.ts +23 -9
  96. package/dist/languageService/definitionProvider.js +116 -91
  97. package/dist/languageService/definitionProvider.js.map +1 -1
  98. package/dist/languageService/documentHighlightProvider.d.ts +8 -3
  99. package/dist/languageService/documentHighlightProvider.js +17 -6
  100. package/dist/languageService/documentHighlightProvider.js.map +1 -1
  101. package/dist/languageService/documentSymbolCollector.d.ts +2 -2
  102. package/dist/languageService/documentSymbolCollector.js +4 -3
  103. package/dist/languageService/documentSymbolCollector.js.map +1 -1
  104. package/dist/languageService/documentSymbolProvider.js +5 -3
  105. package/dist/languageService/documentSymbolProvider.js.map +1 -1
  106. package/dist/languageService/hoverProvider.js +1 -1
  107. package/dist/languageService/hoverProvider.js.map +1 -1
  108. package/dist/languageService/insertionPointUtils.js +3 -3
  109. package/dist/languageService/insertionPointUtils.js.map +1 -1
  110. package/dist/languageService/navigationUtils.d.ts +6 -0
  111. package/dist/languageService/navigationUtils.js +28 -0
  112. package/dist/languageService/navigationUtils.js.map +1 -0
  113. package/dist/languageService/quickActions.d.ts +2 -2
  114. package/dist/languageService/quickActions.js +12 -1
  115. package/dist/languageService/quickActions.js.map +1 -1
  116. package/dist/languageService/referencesProvider.d.ts +8 -2
  117. package/dist/languageService/referencesProvider.js +81 -3
  118. package/dist/languageService/referencesProvider.js.map +1 -1
  119. package/dist/languageService/renameModuleProvider.d.ts +13 -13
  120. package/dist/languageService/renameModuleProvider.js +43 -43
  121. package/dist/languageService/renameModuleProvider.js.map +1 -1
  122. package/dist/languageService/signatureHelpProvider.d.ts +19 -23
  123. package/dist/languageService/signatureHelpProvider.js +111 -18
  124. package/dist/languageService/signatureHelpProvider.js.map +1 -1
  125. package/dist/parser/characterStream.d.ts +3 -3
  126. package/dist/parser/characterStream.js +12 -12
  127. package/dist/parser/characterStream.js.map +1 -1
  128. package/dist/parser/parser.d.ts +1 -1
  129. package/dist/parser/parser.js.map +1 -1
  130. package/dist/pyright.js +57 -54
  131. package/dist/pyright.js.map +1 -1
  132. package/dist/pyrightFileSystem.d.ts +1 -1
  133. package/dist/pyrightFileSystem.js +21 -21
  134. package/dist/pyrightFileSystem.js.map +1 -1
  135. package/dist/readonlyAugmentedFileSystem.d.ts +6 -6
  136. package/dist/readonlyAugmentedFileSystem.js +28 -28
  137. package/dist/readonlyAugmentedFileSystem.js.map +1 -1
  138. package/dist/server.js +6 -6
  139. package/dist/server.js.map +1 -1
  140. package/dist/tests/chainedSourceFiles.test.js +1 -1
  141. package/dist/tests/chainedSourceFiles.test.js.map +1 -1
  142. package/dist/tests/checker.test.js +1 -1
  143. package/dist/tests/harness/fourslash/testLanguageService.d.ts +3 -3
  144. package/dist/tests/harness/fourslash/testLanguageService.js.map +1 -1
  145. package/dist/tests/harness/fourslash/testState.d.ts +8 -8
  146. package/dist/tests/harness/fourslash/testState.js +109 -99
  147. package/dist/tests/harness/fourslash/testState.js.map +1 -1
  148. package/dist/tests/harness/vfs/filesystem.d.ts +8 -8
  149. package/dist/tests/harness/vfs/filesystem.js +68 -68
  150. package/dist/tests/harness/vfs/filesystem.js.map +1 -1
  151. package/dist/tests/importStatementUtils.test.js +34 -0
  152. package/dist/tests/importStatementUtils.test.js.map +1 -1
  153. package/dist/tests/moveSymbol.updateReference.test.js +14 -0
  154. package/dist/tests/moveSymbol.updateReference.test.js.map +1 -1
  155. package/dist/tests/signatureHelp.test.js +5 -1
  156. package/dist/tests/signatureHelp.test.js.map +1 -1
  157. package/dist/tests/sourceFile.test.js +1 -1
  158. package/dist/tests/sourceFile.test.js.map +1 -1
  159. package/dist/tests/testStateUtils.js +1 -1
  160. package/dist/tests/testStateUtils.js.map +1 -1
  161. package/dist/tests/typeEvaluator1.test.js +8 -0
  162. package/dist/tests/typeEvaluator1.test.js.map +1 -1
  163. package/dist/tests/typeEvaluator2.test.js +12 -0
  164. package/dist/tests/typeEvaluator2.test.js.map +1 -1
  165. package/dist/tests/typeEvaluator3.test.js +1 -1
  166. package/package.json +1 -1
@@ -34,8 +34,8 @@ const configOptions_1 = require("../common/configOptions");
34
34
  const pathConsts_1 = require("../common/pathConsts");
35
35
  const pathUtils_1 = require("../common/pathUtils");
36
36
  const pythonVersion_1 = require("../common/pythonVersion");
37
- const stringUtils_1 = require("../common/stringUtils");
38
37
  const StringUtils = __importStar(require("../common/stringUtils"));
38
+ const stringUtils_1 = require("../common/stringUtils");
39
39
  const characters_1 = require("../parser/characters");
40
40
  const pyrightFileSystem_1 = require("../pyrightFileSystem");
41
41
  const importStatementUtils_1 = require("./importStatementUtils");
@@ -94,120 +94,9 @@ class ImportResolver {
94
94
  // Resolves the import and returns the path if it exists, otherwise
95
95
  // returns undefined.
96
96
  resolveImport(sourceFilePath, execEnv, moduleDescriptor) {
97
- // Wrap internal call to _resolveImport() to prevent calling any
97
+ // Wrap internal call to resolveImportInternal() to prevent calling any
98
98
  // child class version of resolveImport().
99
- return this._resolveImport(sourceFilePath, execEnv, moduleDescriptor);
100
- }
101
- // Resolves the import and returns the path if it exists, otherwise
102
- // returns undefined.
103
- _resolveImport(sourceFilePath, execEnv, moduleDescriptor) {
104
- const importName = this.formatImportName(moduleDescriptor);
105
- const importFailureInfo = [];
106
- const importResult = this._resolveImportStrict(importName, sourceFilePath, execEnv, moduleDescriptor, importFailureInfo);
107
- if (importResult.isImportFound || moduleDescriptor.leadingDots > 0) {
108
- return importResult;
109
- }
110
- // If the import is absolute and no other method works, try resolving the
111
- // absolute in the importing file's directory, then the parent directory,
112
- // and so on, until the import root is reached.
113
- sourceFilePath = (0, pathUtils_1.normalizePathCase)(this.fileSystem, (0, pathUtils_1.normalizePath)(sourceFilePath));
114
- const origin = (0, pathUtils_1.ensureTrailingDirectorySeparator)((0, pathUtils_1.getDirectoryPath)(sourceFilePath));
115
- const result = this.cachedParentImportResults.getImportResult(origin, importName, importResult);
116
- if (result) {
117
- // Already ran the parent directory resolution for this import name on this location.
118
- return this.filterImplicitImports(result, moduleDescriptor.importedSymbols);
119
- }
120
- // Check whether the given file is in the parent directory import resolution cache.
121
- const root = this.getParentImportResolutionRoot(sourceFilePath, execEnv.root);
122
- if (!this.cachedParentImportResults.checkValidPath(this.fileSystem, sourceFilePath, root)) {
123
- return importResult;
124
- }
125
- const importPath = { importPath: undefined };
126
- // Going up the given folder one by one until we can resolve the import.
127
- let current = origin;
128
- while (this._shouldWalkUp(current, root, execEnv)) {
129
- const result = this.resolveAbsoluteImport(sourceFilePath, current, execEnv, moduleDescriptor, importName, [],
130
- /* allowPartial */ undefined,
131
- /* allowNativeLib */ undefined,
132
- /* useStubPackage */ false,
133
- /* allowPyi */ true);
134
- this.cachedParentImportResults.checked(current, importName, importPath);
135
- if (result.isImportFound) {
136
- // This will make cache to point to actual path that contains the module we found
137
- importPath.importPath = current;
138
- this.cachedParentImportResults.add({
139
- importResult: result,
140
- path: current,
141
- importName,
142
- });
143
- return this.filterImplicitImports(result, moduleDescriptor.importedSymbols);
144
- }
145
- let success;
146
- [success, current] = this._tryWalkUp(current);
147
- if (!success) {
148
- break;
149
- }
150
- }
151
- this.cachedParentImportResults.checked(current, importName, importPath);
152
- return importResult;
153
- }
154
- _resolveImportStrict(importName, sourceFilePath, execEnv, moduleDescriptor, importFailureInfo) {
155
- const fromUserFile = (0, configOptions_1.matchFileSpecs)(this._configOptions, sourceFilePath);
156
- const notFoundResult = {
157
- importName,
158
- isRelative: false,
159
- isImportFound: false,
160
- isPartlyResolved: false,
161
- isNamespacePackage: false,
162
- isInitFilePresent: false,
163
- isStubPackage: false,
164
- importFailureInfo,
165
- resolvedPaths: [],
166
- importType: 2 /* Local */,
167
- isStubFile: false,
168
- isNativeLib: false,
169
- implicitImports: [],
170
- filteredImplicitImports: [],
171
- nonStubImportResult: undefined,
172
- };
173
- this.ensurePartialStubPackages(execEnv);
174
- // Is it a relative import?
175
- if (moduleDescriptor.leadingDots > 0) {
176
- const relativeImport = this._resolveRelativeImport(sourceFilePath, execEnv, moduleDescriptor, importName, importFailureInfo);
177
- if (relativeImport) {
178
- relativeImport.isRelative = true;
179
- return relativeImport;
180
- }
181
- }
182
- else {
183
- // Is it already cached?
184
- const cachedResults = this._lookUpResultsInCache(execEnv, importName, moduleDescriptor.importedSymbols, fromUserFile);
185
- if (cachedResults) {
186
- // In most cases, we can simply return a cached entry. However, there are cases
187
- // where the cached entry refers to a previously-resolved namespace package
188
- // that does not resolve the symbols specified in the module descriptor.
189
- // In this case, we will ignore the cached value and run the full import
190
- // resolution again to try to find a package that resolves the import.
191
- const isUnresolvedNamespace = cachedResults.isImportFound &&
192
- cachedResults.isNamespacePackage &&
193
- !this._isNamespacePackageResolved(moduleDescriptor, cachedResults.implicitImports);
194
- if (!isUnresolvedNamespace) {
195
- return cachedResults;
196
- }
197
- }
198
- const bestImport = this._resolveBestAbsoluteImport(sourceFilePath, execEnv, moduleDescriptor,
199
- /* allowPyi */ true);
200
- if (bestImport) {
201
- if (bestImport.isStubFile) {
202
- bestImport.nonStubImportResult =
203
- this._resolveBestAbsoluteImport(sourceFilePath, execEnv, moduleDescriptor,
204
- /* allowPyi */ false) || notFoundResult;
205
- }
206
- return this.addResultsToCache(execEnv, importName, bestImport, moduleDescriptor.importedSymbols, fromUserFile);
207
- }
208
- }
209
- return this.addResultsToCache(execEnv, importName, notFoundResult,
210
- /* importedSymbols */ undefined, fromUserFile);
99
+ return this.resolveImportInternal(sourceFilePath, execEnv, moduleDescriptor);
211
100
  }
212
101
  getCompletionSuggestions(sourceFilePath, execEnv, moduleDescriptor) {
213
102
  const suggestions = this._getCompletionSuggestionsStrict(sourceFilePath, execEnv, moduleDescriptor);
@@ -236,39 +125,6 @@ class ImportResolver {
236
125
  this._configOptions = configOptions;
237
126
  this.invalidateCache();
238
127
  }
239
- _getCompletionSuggestionsStrict(sourceFilePath, execEnv, moduleDescriptor) {
240
- const importFailureInfo = [];
241
- const suggestions = new Map();
242
- // Is it a relative import?
243
- if (moduleDescriptor.leadingDots > 0) {
244
- this._getCompletionSuggestionsRelative(sourceFilePath, execEnv, moduleDescriptor, suggestions);
245
- }
246
- else {
247
- // First check for a typeshed file.
248
- if (moduleDescriptor.nameParts.length > 0) {
249
- this._getCompletionSuggestionsTypeshedPath(sourceFilePath, execEnv, moduleDescriptor, true, suggestions);
250
- }
251
- // Look for it in the root directory of the execution environment.
252
- if (execEnv.root) {
253
- this._getCompletionSuggestionsAbsolute(sourceFilePath, execEnv, execEnv.root, moduleDescriptor, suggestions);
254
- }
255
- for (const extraPath of execEnv.extraPaths) {
256
- this._getCompletionSuggestionsAbsolute(sourceFilePath, execEnv, extraPath, moduleDescriptor, suggestions);
257
- }
258
- // Check for a typings file.
259
- if (this._configOptions.stubPath) {
260
- this._getCompletionSuggestionsAbsolute(sourceFilePath, execEnv, this._configOptions.stubPath, moduleDescriptor, suggestions);
261
- }
262
- // Check for a typeshed file.
263
- this._getCompletionSuggestionsTypeshedPath(sourceFilePath, execEnv, moduleDescriptor, false, suggestions);
264
- // Look for the import in the list of third-party packages.
265
- const pythonSearchPaths = this.getPythonSearchPaths(importFailureInfo);
266
- for (const searchPath of pythonSearchPaths) {
267
- this._getCompletionSuggestionsAbsolute(sourceFilePath, execEnv, searchPath, moduleDescriptor, suggestions);
268
- }
269
- }
270
- return suggestions;
271
- }
272
128
  // Returns the implementation file(s) for the given stub file.
273
129
  getSourceFilesFromStub(stubFilePath, execEnv, _mapCompiled) {
274
130
  const sourceFilePaths = [];
@@ -369,167 +225,42 @@ class ImportResolver {
369
225
  const cache = (0, collectionUtils_1.getOrAdd)(this._cachedModuleNameResults, execEnv.root, () => new Map());
370
226
  return (0, collectionUtils_1.getOrAdd)(cache, filePath, () => this._getModuleNameForImport(filePath, execEnv, allowInvalidModuleName));
371
227
  }
372
- _getModuleNameForImport(filePath, execEnv, allowInvalidModuleName) {
373
- let moduleName;
374
- let importType = 0 /* BuiltIn */;
375
- let isLocalTypingsFile = false;
228
+ getTypeshedStdLibPath(execEnv) {
229
+ const unused = [];
230
+ return this._getStdlibTypeshedPath(execEnv, unused);
231
+ }
232
+ getTypeshedThirdPartyPath(execEnv) {
233
+ const unused = [];
234
+ return this._getThirdPartyTypeshedPath(execEnv, unused);
235
+ }
236
+ isStdlibModule(module, execEnv) {
237
+ if (!this._stdlibModules) {
238
+ this._stdlibModules = this._buildStdlibCache(this.getTypeshedStdLibPath(execEnv));
239
+ }
240
+ return this._stdlibModules.has(module.nameParts.join('.'));
241
+ }
242
+ getImportRoots(execEnv, forLogging = false) {
376
243
  const importFailureInfo = [];
377
- // If we cannot find a fully-qualified module name with legal characters,
378
- // look for one with invalid characters (e.g. "-"). This is important to
379
- // differentiate between different modules in a project in case they
380
- // declare types with the same (local) name.
381
- let moduleNameWithInvalidCharacters;
382
- // Is this a stdlib typeshed path?
383
- const stdLibTypeshedPath = this._getStdlibTypeshedPath(execEnv, importFailureInfo);
384
- if (stdLibTypeshedPath) {
385
- moduleName = this.getModuleNameFromPath(stdLibTypeshedPath, filePath);
386
- if (moduleName) {
387
- const moduleDescriptor = {
388
- leadingDots: 0,
389
- nameParts: moduleName.split('.'),
390
- importedSymbols: undefined,
391
- };
392
- if (this._isStdlibTypeshedStubValidForVersion(moduleDescriptor, execEnv, [])) {
393
- return { moduleName, importType, isLocalTypingsFile };
394
- }
395
- }
244
+ const roots = [];
245
+ const stdTypeshed = this._getStdlibTypeshedPath(execEnv, importFailureInfo);
246
+ if (stdTypeshed) {
247
+ roots.push(stdTypeshed);
396
248
  }
397
- // Look for it in the root directory of the execution environment.
249
+ // The "default" workspace has a root-less execution environment; ignore it.
398
250
  if (execEnv.root) {
399
- const candidateModuleNameInfo = this.getModuleNameInfoFromPath(execEnv.root, filePath);
400
- if (candidateModuleNameInfo) {
401
- if (candidateModuleNameInfo.containsInvalidCharacters) {
402
- moduleNameWithInvalidCharacters = candidateModuleNameInfo.moduleName;
403
- }
404
- else {
405
- moduleName = candidateModuleNameInfo.moduleName;
406
- }
407
- }
408
- importType = 2 /* Local */;
409
- }
410
- for (const extraPath of execEnv.extraPaths) {
411
- const candidateModuleNameInfo = this.getModuleNameInfoFromPath(extraPath, filePath);
412
- if (candidateModuleNameInfo) {
413
- if (candidateModuleNameInfo.containsInvalidCharacters) {
414
- moduleNameWithInvalidCharacters = candidateModuleNameInfo.moduleName;
415
- }
416
- else {
417
- // Does this candidate look better than the previous best module name?
418
- // We'll always try to use the shortest version.
419
- const candidateModuleName = candidateModuleNameInfo.moduleName;
420
- if (!moduleName || (candidateModuleName && candidateModuleName.length < moduleName.length)) {
421
- moduleName = candidateModuleName;
422
- importType = 2 /* Local */;
423
- }
424
- }
425
- }
251
+ roots.push(execEnv.root);
426
252
  }
427
- // Check for a typings file.
253
+ (0, collectionUtils_1.appendArray)(roots, execEnv.extraPaths);
428
254
  if (this._configOptions.stubPath) {
429
- const candidateModuleNameInfo = this.getModuleNameInfoFromPath(this._configOptions.stubPath, filePath);
430
- if (candidateModuleNameInfo) {
431
- if (candidateModuleNameInfo.containsInvalidCharacters) {
432
- moduleNameWithInvalidCharacters = candidateModuleNameInfo.moduleName;
433
- }
434
- else {
435
- // Does this candidate look better than the previous best module name?
436
- // We'll always try to use the shortest version.
437
- const candidateModuleName = candidateModuleNameInfo.moduleName;
438
- if (!moduleName || (candidateModuleName && candidateModuleName.length < moduleName.length)) {
439
- moduleName = candidateModuleName;
440
- // Treat the typings path as a local import so errors are reported for it.
441
- importType = 2 /* Local */;
442
- isLocalTypingsFile = true;
443
- }
444
- }
445
- }
255
+ roots.push(this._configOptions.stubPath);
446
256
  }
447
- // Check for a typeshed file.
448
- const thirdPartyTypeshedPath = this._getThirdPartyTypeshedPath(execEnv, importFailureInfo);
449
- if (thirdPartyTypeshedPath) {
450
- const candidateModuleName = this.getModuleNameFromPath(thirdPartyTypeshedPath, filePath,
451
- /* stripTopContainerDir */ true);
452
- // Does this candidate look better than the previous best module name?
453
- // We'll always try to use the shortest version.
454
- if (!moduleName || (candidateModuleName && candidateModuleName.length < moduleName.length)) {
455
- moduleName = candidateModuleName;
456
- importType = 1 /* ThirdParty */;
457
- }
458
- }
459
- const thirdPartyTypeshedPathEx = this.getTypeshedPathEx(execEnv, importFailureInfo);
460
- if (thirdPartyTypeshedPathEx) {
461
- const candidateModuleName = this.getModuleNameFromPath(thirdPartyTypeshedPathEx, filePath);
462
- // Does this candidate look better than the previous best module name?
463
- // We'll always try to use the shortest version.
464
- if (!moduleName || (candidateModuleName && candidateModuleName.length < moduleName.length)) {
465
- moduleName = candidateModuleName;
466
- importType = 1 /* ThirdParty */;
467
- }
468
- }
469
- // Look for the import in the list of third-party packages.
470
- const pythonSearchPaths = this.getPythonSearchPaths(importFailureInfo);
471
- for (const searchPath of pythonSearchPaths) {
472
- const candidateModuleNameInfo = this.getModuleNameInfoFromPath(searchPath, filePath);
473
- if (candidateModuleNameInfo) {
474
- if (candidateModuleNameInfo.containsInvalidCharacters) {
475
- moduleNameWithInvalidCharacters = candidateModuleNameInfo.moduleName;
476
- }
477
- else {
478
- // Does this candidate look better than the previous best module name?
479
- // We'll always try to use the shortest version.
480
- const candidateModuleName = candidateModuleNameInfo.moduleName;
481
- if (!moduleName || (candidateModuleName && candidateModuleName.length < moduleName.length)) {
482
- moduleName = candidateModuleName;
483
- importType = 1 /* ThirdParty */;
484
- }
485
- }
486
- }
487
- }
488
- if (moduleName) {
489
- return { moduleName, importType, isLocalTypingsFile };
490
- }
491
- if (allowInvalidModuleName && moduleNameWithInvalidCharacters) {
492
- return { moduleName: moduleNameWithInvalidCharacters, importType, isLocalTypingsFile };
493
- }
494
- // We didn't find any module name.
495
- return { moduleName: '', importType: 2 /* Local */, isLocalTypingsFile };
496
- }
497
- getTypeshedStdLibPath(execEnv) {
498
- const unused = [];
499
- return this._getStdlibTypeshedPath(execEnv, unused);
500
- }
501
- getTypeshedThirdPartyPath(execEnv) {
502
- const unused = [];
503
- return this._getThirdPartyTypeshedPath(execEnv, unused);
504
- }
505
- isStdlibModule(module, execEnv) {
506
- if (!this._stdlibModules) {
507
- this._stdlibModules = this._buildStdlibCache(this.getTypeshedStdLibPath(execEnv));
508
- }
509
- return this._stdlibModules.has(module.nameParts.join('.'));
510
- }
511
- getImportRoots(execEnv, forLogging = false) {
512
- const importFailureInfo = [];
513
- const roots = [];
514
- const stdTypeshed = this._getStdlibTypeshedPath(execEnv, importFailureInfo);
515
- if (stdTypeshed) {
516
- roots.push(stdTypeshed);
517
- }
518
- // The "default" workspace has a root-less execution environment; ignore it.
519
- if (execEnv.root) {
520
- roots.push(execEnv.root);
521
- }
522
- (0, collectionUtils_1.appendArray)(roots, execEnv.extraPaths);
523
- if (this._configOptions.stubPath) {
524
- roots.push(this._configOptions.stubPath);
525
- }
526
- if (forLogging) {
527
- // There's one path for each third party package, which blows up logging.
528
- // Just get the root directly and show it with `...` to indicate that this
529
- // is where the third party folder is in the roots.
530
- const thirdPartyRoot = this._getThirdPartyTypeshedPath(execEnv, importFailureInfo);
531
- if (thirdPartyRoot) {
532
- roots.push((0, pathUtils_1.combinePaths)(thirdPartyRoot, '...'));
257
+ if (forLogging) {
258
+ // There's one path for each third party package, which blows up logging.
259
+ // Just get the root directly and show it with `...` to indicate that this
260
+ // is where the third party folder is in the roots.
261
+ const thirdPartyRoot = this._getThirdPartyTypeshedPath(execEnv, importFailureInfo);
262
+ if (thirdPartyRoot) {
263
+ roots.push((0, pathUtils_1.combinePaths)(thirdPartyRoot, '...'));
533
264
  }
534
265
  }
535
266
  else {
@@ -546,6 +277,45 @@ class ImportResolver {
546
277
  }
547
278
  return roots;
548
279
  }
280
+ ensurePartialStubPackages(execEnv) {
281
+ if (!pyrightFileSystem_1.SupportPartialStubs.is(this.fileSystem)) {
282
+ return false;
283
+ }
284
+ if (this.fileSystem.isPartialStubPackagesScanned(execEnv)) {
285
+ return false;
286
+ }
287
+ const fs = this.fileSystem;
288
+ const ignored = [];
289
+ const paths = [];
290
+ const typeshedPathEx = this.getTypeshedPathEx(execEnv, ignored);
291
+ // Add paths to search stub packages.
292
+ addPaths(this._configOptions.stubPath);
293
+ addPaths(execEnv.root);
294
+ execEnv.extraPaths.forEach((p) => addPaths(p));
295
+ addPaths(typeshedPathEx);
296
+ this.getPythonSearchPaths(ignored).forEach((p) => addPaths(p));
297
+ this.fileSystem.processPartialStubPackages(paths, this.getImportRoots(execEnv), typeshedPathEx);
298
+ this._invalidateFileSystemCache();
299
+ return true;
300
+ function addPaths(path) {
301
+ if (!path || fs.isPathScanned(path)) {
302
+ return;
303
+ }
304
+ paths.push(path);
305
+ }
306
+ }
307
+ getPythonSearchPaths(importFailureInfo) {
308
+ // Find the site packages for the configured virtual environment.
309
+ if (!this._cachedPythonSearchPaths) {
310
+ const info = [];
311
+ const paths = (PythonPathUtils.findPythonSearchPaths(this.fileSystem, this._configOptions, this.host, info) || []).map((p) => this.fileSystem.realCasePath(p));
312
+ // Remove duplicates (yes, it happens).
313
+ this._cachedPythonSearchPaths = { paths: [...new Set(paths)], failureInfo: info };
314
+ }
315
+ // Make sure we cache the logs as well so we can find out why search path failed.
316
+ importFailureInfo.push(...this._cachedPythonSearchPaths.failureInfo);
317
+ return this._cachedPythonSearchPaths.paths;
318
+ }
549
319
  readdirEntriesCached(path) {
550
320
  const cachedValue = this._cachedEntriesForPath.get(path);
551
321
  if (cachedValue) {
@@ -562,6 +332,59 @@ class ImportResolver {
562
332
  this._cachedEntriesForPath.set(path, newCacheValue);
563
333
  return newCacheValue;
564
334
  }
335
+ // Resolves the import and returns the path if it exists, otherwise
336
+ // returns undefined.
337
+ resolveImportInternal(sourceFilePath, execEnv, moduleDescriptor) {
338
+ const importName = this.formatImportName(moduleDescriptor);
339
+ const importFailureInfo = [];
340
+ const importResult = this._resolveImportStrict(importName, sourceFilePath, execEnv, moduleDescriptor, importFailureInfo);
341
+ if (importResult.isImportFound || moduleDescriptor.leadingDots > 0) {
342
+ return importResult;
343
+ }
344
+ // If the import is absolute and no other method works, try resolving the
345
+ // absolute in the importing file's directory, then the parent directory,
346
+ // and so on, until the import root is reached.
347
+ sourceFilePath = (0, pathUtils_1.normalizePathCase)(this.fileSystem, (0, pathUtils_1.normalizePath)(sourceFilePath));
348
+ const origin = (0, pathUtils_1.ensureTrailingDirectorySeparator)((0, pathUtils_1.getDirectoryPath)(sourceFilePath));
349
+ const result = this.cachedParentImportResults.getImportResult(origin, importName, importResult);
350
+ if (result) {
351
+ // Already ran the parent directory resolution for this import name on this location.
352
+ return this.filterImplicitImports(result, moduleDescriptor.importedSymbols);
353
+ }
354
+ // Check whether the given file is in the parent directory import resolution cache.
355
+ const root = this.getParentImportResolutionRoot(sourceFilePath, execEnv.root);
356
+ if (!this.cachedParentImportResults.checkValidPath(this.fileSystem, sourceFilePath, root)) {
357
+ return importResult;
358
+ }
359
+ const importPath = { importPath: undefined };
360
+ // Going up the given folder one by one until we can resolve the import.
361
+ let current = origin;
362
+ while (this._shouldWalkUp(current, root, execEnv)) {
363
+ const result = this.resolveAbsoluteImport(sourceFilePath, current, execEnv, moduleDescriptor, importName, [],
364
+ /* allowPartial */ undefined,
365
+ /* allowNativeLib */ undefined,
366
+ /* useStubPackage */ false,
367
+ /* allowPyi */ true);
368
+ this.cachedParentImportResults.checked(current, importName, importPath);
369
+ if (result.isImportFound) {
370
+ // This will make cache to point to actual path that contains the module we found
371
+ importPath.importPath = current;
372
+ this.cachedParentImportResults.add({
373
+ importResult: result,
374
+ path: current,
375
+ importName,
376
+ });
377
+ return this.filterImplicitImports(result, moduleDescriptor.importedSymbols);
378
+ }
379
+ let success;
380
+ [success, current] = this._tryWalkUp(current);
381
+ if (!success) {
382
+ break;
383
+ }
384
+ }
385
+ this.cachedParentImportResults.checked(current, importName, importPath);
386
+ return importResult;
387
+ }
565
388
  fileExistsCached(path) {
566
389
  var _a, _b;
567
390
  const splitPath = this._splitPath(path);
@@ -591,75 +414,367 @@ class ImportResolver {
591
414
  if (!this.fileSystem.existsSync(path)) {
592
415
  return false;
593
416
  }
594
- return (_b = (_a = (0, pathUtils_1.tryStat)(this.fileSystem, path)) === null || _a === void 0 ? void 0 : _a.isDirectory()) !== null && _b !== void 0 ? _b : false;
595
- }
596
- const entries = this.readdirEntriesCached(splitPath[0]);
597
- const entry = entries.find((entry) => entry.name === splitPath[1]);
598
- if (entry === null || entry === void 0 ? void 0 : entry.isDirectory()) {
599
- return true;
417
+ return (_b = (_a = (0, pathUtils_1.tryStat)(this.fileSystem, path)) === null || _a === void 0 ? void 0 : _a.isDirectory()) !== null && _b !== void 0 ? _b : false;
418
+ }
419
+ const entries = this.readdirEntriesCached(splitPath[0]);
420
+ const entry = entries.find((entry) => entry.name === splitPath[1]);
421
+ if (entry === null || entry === void 0 ? void 0 : entry.isDirectory()) {
422
+ return true;
423
+ }
424
+ if (entry === null || entry === void 0 ? void 0 : entry.isSymbolicLink()) {
425
+ const realPath = (0, pathUtils_1.tryRealpath)(this.fileSystem, path);
426
+ if (realPath && this.fileSystem.existsSync(realPath) && (0, pathUtils_1.isDirectory)(this.fileSystem, realPath)) {
427
+ return true;
428
+ }
429
+ }
430
+ return false;
431
+ }
432
+ addResultsToCache(execEnv, importName, importResult, importedSymbols, fromUserFile) {
433
+ (0, collectionUtils_1.getOrAdd)(this._cachedImportResults, execEnv.root, () => new Map()).set(this._getCacheKey(importName, fromUserFile), importResult);
434
+ return this.filterImplicitImports(importResult, importedSymbols);
435
+ }
436
+ // Follows import resolution algorithm defined in PEP-420:
437
+ // https://www.python.org/dev/peps/pep-0420/
438
+ resolveAbsoluteImport(sourceFilePath, rootPath, execEnv, moduleDescriptor, importName, importFailureInfo, allowPartial = false, allowNativeLib = false, useStubPackage = false, allowPyi = true, lookForPyTyped = false) {
439
+ if (allowPyi && useStubPackage) {
440
+ // Look for packaged stubs first. PEP 561 indicates that package authors can ship
441
+ // their stubs separately from their package implementation by appending the string
442
+ // '-stubs' to its top - level directory name. We'll look there first.
443
+ const importResult = this._resolveAbsoluteImport(sourceFilePath, rootPath, execEnv, moduleDescriptor, importName, importFailureInfo, allowPartial,
444
+ /* allowNativeLib */ false,
445
+ /* useStubPackage */ true,
446
+ /* allowPyi */ true,
447
+ /* lookForPyTyped */ true);
448
+ // We found fully typed stub packages.
449
+ if (importResult.packageDirectory) {
450
+ // If this is a namespace package that wasn't resolved, assume that
451
+ // it's a partial stub package and continue looking for a real package.
452
+ if (!importResult.isNamespacePackage || importResult.isImportFound) {
453
+ return importResult;
454
+ }
455
+ }
456
+ }
457
+ return this._resolveAbsoluteImport(sourceFilePath, rootPath, execEnv, moduleDescriptor, importName, importFailureInfo, allowPartial, allowNativeLib,
458
+ /* useStubPackage */ false, allowPyi, lookForPyTyped);
459
+ }
460
+ // Intended to be overridden by subclasses to provide additional stub
461
+ // path capabilities. Return undefined if no extra stub path were found.
462
+ getTypeshedPathEx(execEnv, importFailureInfo) {
463
+ return undefined;
464
+ }
465
+ // Intended to be overridden by subclasses to provide additional stub
466
+ // resolving capabilities. Return undefined if no stubs were found for
467
+ // this import.
468
+ resolveImportEx(sourceFilePath, execEnv, moduleDescriptor, importName, importFailureInfo = [], allowPyi = true) {
469
+ return undefined;
470
+ }
471
+ // Intended to be overridden by subclasses to provide additional stub
472
+ // resolving capabilities for native (compiled) modules. Returns undefined
473
+ // if no stubs were found for this import.
474
+ resolveNativeImportEx(libraryFilePath, importName, importFailureInfo = []) {
475
+ return undefined;
476
+ }
477
+ getNativeModuleName(fileName) {
478
+ const fileExtension = (0, pathUtils_1.getFileExtension)(fileName, /* multiDotExtension */ false).toLowerCase();
479
+ if (this._isNativeModuleFileExtension(fileExtension)) {
480
+ return (0, pathUtils_1.stripFileExtension)((0, pathUtils_1.stripFileExtension)(fileName));
481
+ }
482
+ return undefined;
483
+ }
484
+ getModuleNameFromPath(containerPath, filePath, stripTopContainerDir = false) {
485
+ const moduleNameInfo = this.getModuleNameInfoFromPath(containerPath, filePath, stripTopContainerDir);
486
+ if (!moduleNameInfo || moduleNameInfo.containsInvalidCharacters) {
487
+ return undefined;
488
+ }
489
+ return moduleNameInfo.moduleName;
490
+ }
491
+ getModuleNameInfoFromPath(containerPath, filePath, stripTopContainerDir = false) {
492
+ containerPath = (0, pathUtils_1.ensureTrailingDirectorySeparator)(containerPath);
493
+ let filePathWithoutExtension = (0, pathUtils_1.stripFileExtension)(filePath);
494
+ // If module is native, strip platform part, such as 'cp36-win_amd64' in 'mtrand.cp36-win_amd64'.
495
+ if (this._isNativeModuleFileExtension((0, pathUtils_1.getFileExtension)(filePath))) {
496
+ filePathWithoutExtension = (0, pathUtils_1.stripFileExtension)(filePathWithoutExtension);
497
+ }
498
+ if (!filePathWithoutExtension.startsWith(containerPath)) {
499
+ return undefined;
500
+ }
501
+ // Strip off the '/__init__' if it's present.
502
+ if (filePathWithoutExtension.endsWith('__init__')) {
503
+ filePathWithoutExtension = filePathWithoutExtension.substr(0, filePathWithoutExtension.length - 9);
504
+ }
505
+ const relativeFilePath = filePathWithoutExtension.substr(containerPath.length);
506
+ const parts = (0, pathUtils_1.getPathComponents)(relativeFilePath);
507
+ parts.shift();
508
+ if (stripTopContainerDir) {
509
+ if (parts.length === 0) {
510
+ return undefined;
511
+ }
512
+ parts.shift();
513
+ }
514
+ if (parts.length === 0) {
515
+ return undefined;
516
+ }
517
+ // Handle the case where the symbol was resolved to a stubs package
518
+ // rather than the real package. We'll strip off the "-stubs" suffix
519
+ // in this case.
520
+ if (parts[0].endsWith(pathConsts_1.stubsSuffix)) {
521
+ parts[0] = parts[0].substr(0, parts[0].length - pathConsts_1.stubsSuffix.length);
522
+ }
523
+ // Check whether parts contains invalid characters.
524
+ const containsInvalidCharacters = parts.some((p) => !this._isIdentifier(p));
525
+ return {
526
+ moduleName: parts.join('.'),
527
+ containsInvalidCharacters,
528
+ };
529
+ }
530
+ // Potentially modifies the ImportResult by removing some or all of the
531
+ // implicit import entries. Only the imported symbols should be included.
532
+ filterImplicitImports(importResult, importedSymbols) {
533
+ if (importedSymbols === undefined) {
534
+ const newImportResult = Object.assign({}, importResult);
535
+ newImportResult.filteredImplicitImports = [];
536
+ return newImportResult;
537
+ }
538
+ if (importedSymbols.length === 0) {
539
+ return importResult;
540
+ }
541
+ if (importResult.implicitImports.length === 0) {
542
+ return importResult;
543
+ }
544
+ const filteredImplicitImports = importResult.implicitImports.filter((implicitImport) => {
545
+ return importedSymbols.some((sym) => sym === implicitImport.name);
546
+ });
547
+ if (filteredImplicitImports.length === importResult.implicitImports.length) {
548
+ return importResult;
549
+ }
550
+ const newImportResult = Object.assign({}, importResult);
551
+ newImportResult.filteredImplicitImports = filteredImplicitImports;
552
+ return newImportResult;
553
+ }
554
+ formatImportName(moduleDescriptor) {
555
+ return '.'.repeat(moduleDescriptor.leadingDots) + moduleDescriptor.nameParts.join('.');
556
+ }
557
+ getParentImportResolutionRoot(sourceFilePath, executionRoot) {
558
+ if (executionRoot) {
559
+ return (0, pathUtils_1.ensureTrailingDirectorySeparator)((0, pathUtils_1.normalizePathCase)(this.fileSystem, (0, pathUtils_1.normalizePath)(executionRoot)));
560
+ }
561
+ return (0, pathUtils_1.ensureTrailingDirectorySeparator)((0, pathUtils_1.getDirectoryPath)(sourceFilePath));
562
+ }
563
+ _resolveImportStrict(importName, sourceFilePath, execEnv, moduleDescriptor, importFailureInfo) {
564
+ const fromUserFile = (0, configOptions_1.matchFileSpecs)(this._configOptions, sourceFilePath);
565
+ const notFoundResult = {
566
+ importName,
567
+ isRelative: false,
568
+ isImportFound: false,
569
+ isPartlyResolved: false,
570
+ isNamespacePackage: false,
571
+ isInitFilePresent: false,
572
+ isStubPackage: false,
573
+ importFailureInfo,
574
+ resolvedPaths: [],
575
+ importType: 2 /* Local */,
576
+ isStubFile: false,
577
+ isNativeLib: false,
578
+ implicitImports: [],
579
+ filteredImplicitImports: [],
580
+ nonStubImportResult: undefined,
581
+ };
582
+ this.ensurePartialStubPackages(execEnv);
583
+ // Is it a relative import?
584
+ if (moduleDescriptor.leadingDots > 0) {
585
+ const relativeImport = this._resolveRelativeImport(sourceFilePath, execEnv, moduleDescriptor, importName, importFailureInfo);
586
+ if (relativeImport) {
587
+ relativeImport.isRelative = true;
588
+ return relativeImport;
589
+ }
590
+ }
591
+ else {
592
+ // Is it already cached?
593
+ const cachedResults = this._lookUpResultsInCache(execEnv, importName, moduleDescriptor.importedSymbols, fromUserFile);
594
+ if (cachedResults) {
595
+ // In most cases, we can simply return a cached entry. However, there are cases
596
+ // where the cached entry refers to a previously-resolved namespace package
597
+ // that does not resolve the symbols specified in the module descriptor.
598
+ // In this case, we will ignore the cached value and run the full import
599
+ // resolution again to try to find a package that resolves the import.
600
+ const isUnresolvedNamespace = cachedResults.isImportFound &&
601
+ cachedResults.isNamespacePackage &&
602
+ !this._isNamespacePackageResolved(moduleDescriptor, cachedResults.implicitImports);
603
+ if (!isUnresolvedNamespace) {
604
+ return cachedResults;
605
+ }
606
+ }
607
+ const bestImport = this._resolveBestAbsoluteImport(sourceFilePath, execEnv, moduleDescriptor,
608
+ /* allowPyi */ true);
609
+ if (bestImport) {
610
+ if (bestImport.isStubFile) {
611
+ bestImport.nonStubImportResult =
612
+ this._resolveBestAbsoluteImport(sourceFilePath, execEnv, moduleDescriptor,
613
+ /* allowPyi */ false) || notFoundResult;
614
+ }
615
+ return this.addResultsToCache(execEnv, importName, bestImport, moduleDescriptor.importedSymbols, fromUserFile);
616
+ }
617
+ }
618
+ return this.addResultsToCache(execEnv, importName, notFoundResult,
619
+ /* importedSymbols */ undefined, fromUserFile);
620
+ }
621
+ _getCompletionSuggestionsStrict(sourceFilePath, execEnv, moduleDescriptor) {
622
+ const importFailureInfo = [];
623
+ const suggestions = new Map();
624
+ // Is it a relative import?
625
+ if (moduleDescriptor.leadingDots > 0) {
626
+ this._getCompletionSuggestionsRelative(sourceFilePath, execEnv, moduleDescriptor, suggestions);
627
+ }
628
+ else {
629
+ // First check for a typeshed file.
630
+ if (moduleDescriptor.nameParts.length > 0) {
631
+ this._getCompletionSuggestionsTypeshedPath(sourceFilePath, execEnv, moduleDescriptor, true, suggestions);
632
+ }
633
+ // Look for it in the root directory of the execution environment.
634
+ if (execEnv.root) {
635
+ this._getCompletionSuggestionsAbsolute(sourceFilePath, execEnv, execEnv.root, moduleDescriptor, suggestions);
636
+ }
637
+ for (const extraPath of execEnv.extraPaths) {
638
+ this._getCompletionSuggestionsAbsolute(sourceFilePath, execEnv, extraPath, moduleDescriptor, suggestions);
639
+ }
640
+ // Check for a typings file.
641
+ if (this._configOptions.stubPath) {
642
+ this._getCompletionSuggestionsAbsolute(sourceFilePath, execEnv, this._configOptions.stubPath, moduleDescriptor, suggestions);
643
+ }
644
+ // Check for a typeshed file.
645
+ this._getCompletionSuggestionsTypeshedPath(sourceFilePath, execEnv, moduleDescriptor, false, suggestions);
646
+ // Look for the import in the list of third-party packages.
647
+ const pythonSearchPaths = this.getPythonSearchPaths(importFailureInfo);
648
+ for (const searchPath of pythonSearchPaths) {
649
+ this._getCompletionSuggestionsAbsolute(sourceFilePath, execEnv, searchPath, moduleDescriptor, suggestions);
650
+ }
651
+ }
652
+ return suggestions;
653
+ }
654
+ _getModuleNameForImport(filePath, execEnv, allowInvalidModuleName) {
655
+ let moduleName;
656
+ let importType = 0 /* BuiltIn */;
657
+ let isLocalTypingsFile = false;
658
+ const importFailureInfo = [];
659
+ // If we cannot find a fully-qualified module name with legal characters,
660
+ // look for one with invalid characters (e.g. "-"). This is important to
661
+ // differentiate between different modules in a project in case they
662
+ // declare types with the same (local) name.
663
+ let moduleNameWithInvalidCharacters;
664
+ // Is this a stdlib typeshed path?
665
+ const stdLibTypeshedPath = this._getStdlibTypeshedPath(execEnv, importFailureInfo);
666
+ if (stdLibTypeshedPath) {
667
+ moduleName = this.getModuleNameFromPath(stdLibTypeshedPath, filePath);
668
+ if (moduleName) {
669
+ const moduleDescriptor = {
670
+ leadingDots: 0,
671
+ nameParts: moduleName.split('.'),
672
+ importedSymbols: undefined,
673
+ };
674
+ if (this._isStdlibTypeshedStubValidForVersion(moduleDescriptor, execEnv, [])) {
675
+ return { moduleName, importType, isLocalTypingsFile };
676
+ }
677
+ }
678
+ }
679
+ // Look for it in the root directory of the execution environment.
680
+ if (execEnv.root) {
681
+ const candidateModuleNameInfo = this.getModuleNameInfoFromPath(execEnv.root, filePath);
682
+ if (candidateModuleNameInfo) {
683
+ if (candidateModuleNameInfo.containsInvalidCharacters) {
684
+ moduleNameWithInvalidCharacters = candidateModuleNameInfo.moduleName;
685
+ }
686
+ else {
687
+ moduleName = candidateModuleNameInfo.moduleName;
688
+ }
689
+ }
690
+ importType = 2 /* Local */;
600
691
  }
601
- if (entry === null || entry === void 0 ? void 0 : entry.isSymbolicLink()) {
602
- const realPath = (0, pathUtils_1.tryRealpath)(this.fileSystem, path);
603
- if (realPath && this.fileSystem.existsSync(realPath) && (0, pathUtils_1.isDirectory)(this.fileSystem, realPath)) {
604
- return true;
692
+ for (const extraPath of execEnv.extraPaths) {
693
+ const candidateModuleNameInfo = this.getModuleNameInfoFromPath(extraPath, filePath);
694
+ if (candidateModuleNameInfo) {
695
+ if (candidateModuleNameInfo.containsInvalidCharacters) {
696
+ moduleNameWithInvalidCharacters = candidateModuleNameInfo.moduleName;
697
+ }
698
+ else {
699
+ // Does this candidate look better than the previous best module name?
700
+ // We'll always try to use the shortest version.
701
+ const candidateModuleName = candidateModuleNameInfo.moduleName;
702
+ if (!moduleName || (candidateModuleName && candidateModuleName.length < moduleName.length)) {
703
+ moduleName = candidateModuleName;
704
+ importType = 2 /* Local */;
705
+ }
706
+ }
605
707
  }
606
708
  }
607
- return false;
608
- }
609
- ensurePartialStubPackages(execEnv) {
610
- if (!pyrightFileSystem_1.SupportPartialStubs.is(this.fileSystem)) {
611
- return false;
709
+ // Check for a typings file.
710
+ if (this._configOptions.stubPath) {
711
+ const candidateModuleNameInfo = this.getModuleNameInfoFromPath(this._configOptions.stubPath, filePath);
712
+ if (candidateModuleNameInfo) {
713
+ if (candidateModuleNameInfo.containsInvalidCharacters) {
714
+ moduleNameWithInvalidCharacters = candidateModuleNameInfo.moduleName;
715
+ }
716
+ else {
717
+ // Does this candidate look better than the previous best module name?
718
+ // We'll always try to use the shortest version.
719
+ const candidateModuleName = candidateModuleNameInfo.moduleName;
720
+ if (!moduleName || (candidateModuleName && candidateModuleName.length < moduleName.length)) {
721
+ moduleName = candidateModuleName;
722
+ // Treat the typings path as a local import so errors are reported for it.
723
+ importType = 2 /* Local */;
724
+ isLocalTypingsFile = true;
725
+ }
726
+ }
727
+ }
612
728
  }
613
- if (this.fileSystem.isPartialStubPackagesScanned(execEnv)) {
614
- return false;
729
+ // Check for a typeshed file.
730
+ const thirdPartyTypeshedPath = this._getThirdPartyTypeshedPath(execEnv, importFailureInfo);
731
+ if (thirdPartyTypeshedPath) {
732
+ const candidateModuleName = this.getModuleNameFromPath(thirdPartyTypeshedPath, filePath,
733
+ /* stripTopContainerDir */ true);
734
+ // Does this candidate look better than the previous best module name?
735
+ // We'll always try to use the shortest version.
736
+ if (!moduleName || (candidateModuleName && candidateModuleName.length < moduleName.length)) {
737
+ moduleName = candidateModuleName;
738
+ importType = 1 /* ThirdParty */;
739
+ }
615
740
  }
616
- const fs = this.fileSystem;
617
- const ignored = [];
618
- const paths = [];
619
- const typeshedPathEx = this.getTypeshedPathEx(execEnv, ignored);
620
- // Add paths to search stub packages.
621
- addPaths(this._configOptions.stubPath);
622
- addPaths(execEnv.root);
623
- execEnv.extraPaths.forEach((p) => addPaths(p));
624
- addPaths(typeshedPathEx);
625
- this.getPythonSearchPaths(ignored).forEach((p) => addPaths(p));
626
- this.fileSystem.processPartialStubPackages(paths, this.getImportRoots(execEnv), typeshedPathEx);
627
- this._invalidateFileSystemCache();
628
- return true;
629
- function addPaths(path) {
630
- if (!path || fs.isPathScanned(path)) {
631
- return;
741
+ const thirdPartyTypeshedPathEx = this.getTypeshedPathEx(execEnv, importFailureInfo);
742
+ if (thirdPartyTypeshedPathEx) {
743
+ const candidateModuleName = this.getModuleNameFromPath(thirdPartyTypeshedPathEx, filePath);
744
+ // Does this candidate look better than the previous best module name?
745
+ // We'll always try to use the shortest version.
746
+ if (!moduleName || (candidateModuleName && candidateModuleName.length < moduleName.length)) {
747
+ moduleName = candidateModuleName;
748
+ importType = 1 /* ThirdParty */;
632
749
  }
633
- paths.push(path);
634
750
  }
635
- }
636
- addResultsToCache(execEnv, importName, importResult, importedSymbols, fromUserFile) {
637
- (0, collectionUtils_1.getOrAdd)(this._cachedImportResults, execEnv.root, () => new Map()).set(this._getCacheKey(importName, fromUserFile), importResult);
638
- return this.filterImplicitImports(importResult, importedSymbols);
639
- }
640
- // Follows import resolution algorithm defined in PEP-420:
641
- // https://www.python.org/dev/peps/pep-0420/
642
- resolveAbsoluteImport(sourceFilePath, rootPath, execEnv, moduleDescriptor, importName, importFailureInfo, allowPartial = false, allowNativeLib = false, useStubPackage = false, allowPyi = true, lookForPyTyped = false) {
643
- if (allowPyi && useStubPackage) {
644
- // Look for packaged stubs first. PEP 561 indicates that package authors can ship
645
- // their stubs separately from their package implementation by appending the string
646
- // '-stubs' to its top - level directory name. We'll look there first.
647
- const importResult = this._resolveAbsoluteImport(sourceFilePath, rootPath, execEnv, moduleDescriptor, importName, importFailureInfo, allowPartial,
648
- /* allowNativeLib */ false,
649
- /* useStubPackage */ true,
650
- /* allowPyi */ true,
651
- /* lookForPyTyped */ true);
652
- // We found fully typed stub packages.
653
- if (importResult.packageDirectory) {
654
- // If this is a namespace package that wasn't resolved, assume that
655
- // it's a partial stub package and continue looking for a real package.
656
- if (!importResult.isNamespacePackage || importResult.isImportFound) {
657
- return importResult;
751
+ // Look for the import in the list of third-party packages.
752
+ const pythonSearchPaths = this.getPythonSearchPaths(importFailureInfo);
753
+ for (const searchPath of pythonSearchPaths) {
754
+ const candidateModuleNameInfo = this.getModuleNameInfoFromPath(searchPath, filePath);
755
+ if (candidateModuleNameInfo) {
756
+ if (candidateModuleNameInfo.containsInvalidCharacters) {
757
+ moduleNameWithInvalidCharacters = candidateModuleNameInfo.moduleName;
758
+ }
759
+ else {
760
+ // Does this candidate look better than the previous best module name?
761
+ // We'll always try to use the shortest version.
762
+ const candidateModuleName = candidateModuleNameInfo.moduleName;
763
+ if (!moduleName || (candidateModuleName && candidateModuleName.length < moduleName.length)) {
764
+ moduleName = candidateModuleName;
765
+ importType = 1 /* ThirdParty */;
766
+ }
658
767
  }
659
768
  }
660
769
  }
661
- return this._resolveAbsoluteImport(sourceFilePath, rootPath, execEnv, moduleDescriptor, importName, importFailureInfo, allowPartial, allowNativeLib,
662
- /* useStubPackage */ false, allowPyi, lookForPyTyped);
770
+ if (moduleName) {
771
+ return { moduleName, importType, isLocalTypingsFile };
772
+ }
773
+ if (allowInvalidModuleName && moduleNameWithInvalidCharacters) {
774
+ return { moduleName: moduleNameWithInvalidCharacters, importType, isLocalTypingsFile };
775
+ }
776
+ // We didn't find any module name.
777
+ return { moduleName: '', importType: 2 /* Local */, isLocalTypingsFile };
663
778
  }
664
779
  _invalidateFileSystemCache() {
665
780
  this._cachedEntriesForPath.clear();
@@ -842,30 +957,6 @@ class ImportResolver {
842
957
  packageDirectory,
843
958
  };
844
959
  }
845
- // Intended to be overridden by subclasses to provide additional stub
846
- // path capabilities. Return undefined if no extra stub path were found.
847
- getTypeshedPathEx(execEnv, importFailureInfo) {
848
- return undefined;
849
- }
850
- // Intended to be overridden by subclasses to provide additional stub
851
- // resolving capabilities. Return undefined if no stubs were found for
852
- // this import.
853
- resolveImportEx(sourceFilePath, execEnv, moduleDescriptor, importName, importFailureInfo = [], allowPyi = true) {
854
- return undefined;
855
- }
856
- // Intended to be overridden by subclasses to provide additional stub
857
- // resolving capabilities for native (compiled) modules. Returns undefined
858
- // if no stubs were found for this import.
859
- resolveNativeImportEx(libraryFilePath, importName, importFailureInfo = []) {
860
- return undefined;
861
- }
862
- getNativeModuleName(fileName) {
863
- const fileExtension = (0, pathUtils_1.getFileExtension)(fileName, /* multiDotExtension */ false).toLowerCase();
864
- if (this._isNativeModuleFileExtension(fileExtension)) {
865
- return (0, pathUtils_1.stripFileExtension)((0, pathUtils_1.stripFileExtension)(fileName));
866
- }
867
- return undefined;
868
- }
869
960
  _getCacheKey(importName, fromUserFile) {
870
961
  return `${importName}-${fromUserFile}`;
871
962
  }
@@ -900,52 +991,6 @@ class ImportResolver {
900
991
  }
901
992
  return true;
902
993
  }
903
- getModuleNameFromPath(containerPath, filePath, stripTopContainerDir = false) {
904
- const moduleNameInfo = this.getModuleNameInfoFromPath(containerPath, filePath, stripTopContainerDir);
905
- if (!moduleNameInfo || moduleNameInfo.containsInvalidCharacters) {
906
- return undefined;
907
- }
908
- return moduleNameInfo.moduleName;
909
- }
910
- getModuleNameInfoFromPath(containerPath, filePath, stripTopContainerDir = false) {
911
- containerPath = (0, pathUtils_1.ensureTrailingDirectorySeparator)(containerPath);
912
- let filePathWithoutExtension = (0, pathUtils_1.stripFileExtension)(filePath);
913
- // If module is native, strip platform part, such as 'cp36-win_amd64' in 'mtrand.cp36-win_amd64'.
914
- if (this._isNativeModuleFileExtension((0, pathUtils_1.getFileExtension)(filePath))) {
915
- filePathWithoutExtension = (0, pathUtils_1.stripFileExtension)(filePathWithoutExtension);
916
- }
917
- if (!filePathWithoutExtension.startsWith(containerPath)) {
918
- return undefined;
919
- }
920
- // Strip off the '/__init__' if it's present.
921
- if (filePathWithoutExtension.endsWith('__init__')) {
922
- filePathWithoutExtension = filePathWithoutExtension.substr(0, filePathWithoutExtension.length - 9);
923
- }
924
- const relativeFilePath = filePathWithoutExtension.substr(containerPath.length);
925
- const parts = (0, pathUtils_1.getPathComponents)(relativeFilePath);
926
- parts.shift();
927
- if (stripTopContainerDir) {
928
- if (parts.length === 0) {
929
- return undefined;
930
- }
931
- parts.shift();
932
- }
933
- if (parts.length === 0) {
934
- return undefined;
935
- }
936
- // Handle the case where the symbol was resolved to a stubs package
937
- // rather than the real package. We'll strip off the "-stubs" suffix
938
- // in this case.
939
- if (parts[0].endsWith(pathConsts_1.stubsSuffix)) {
940
- parts[0] = parts[0].substr(0, parts[0].length - pathConsts_1.stubsSuffix.length);
941
- }
942
- // Check whether parts contains invalid characters.
943
- const containsInvalidCharacters = parts.some((p) => !this._isIdentifier(p));
944
- return {
945
- moduleName: parts.join('.'),
946
- containsInvalidCharacters,
947
- };
948
- }
949
994
  _resolveBestAbsoluteImport(sourceFilePath, execEnv, moduleDescriptor, allowPyi) {
950
995
  const importName = this.formatImportName(moduleDescriptor);
951
996
  const importFailureInfo = [];
@@ -1125,18 +1170,6 @@ class ImportResolver {
1125
1170
  }
1126
1171
  return true;
1127
1172
  }
1128
- getPythonSearchPaths(importFailureInfo) {
1129
- // Find the site packages for the configured virtual environment.
1130
- if (!this._cachedPythonSearchPaths) {
1131
- const info = [];
1132
- const paths = (PythonPathUtils.findPythonSearchPaths(this.fileSystem, this._configOptions, this.host, info) || []).map((p) => this.fileSystem.realCasePath(p));
1133
- // Remove duplicates (yes, it happens).
1134
- this._cachedPythonSearchPaths = { paths: [...new Set(paths)], failureInfo: info };
1135
- }
1136
- // Make sure we cache the logs as well so we can find out why search path failed.
1137
- importFailureInfo.push(...this._cachedPythonSearchPaths.failureInfo);
1138
- return this._cachedPythonSearchPaths.paths;
1139
- }
1140
1173
  _findTypeshedPath(execEnv, moduleDescriptor, importName, isStdLib, importFailureInfo) {
1141
1174
  importFailureInfo.push(`Looking for typeshed ${isStdLib ? PythonPathUtils.stdLibFolderName : PythonPathUtils.thirdPartyFolderName} path`);
1142
1175
  let typeshedPaths;
@@ -1572,7 +1605,7 @@ class ImportResolver {
1572
1605
  return this._resolveImportStrict(importName, sourceFilePath, execEnv, moduleDescriptor, importFailureInfo)
1573
1606
  .isImportFound;
1574
1607
  }
1575
- return this._resolveImport(sourceFilePath, execEnv, moduleDescriptor).isImportFound;
1608
+ return this.resolveImportInternal(sourceFilePath, execEnv, moduleDescriptor).isImportFound;
1576
1609
  }
1577
1610
  _isUniqueValidSuggestion(suggestionToAdd, suggestions) {
1578
1611
  if (suggestions.has(suggestionToAdd)) {
@@ -1588,30 +1621,6 @@ class ImportResolver {
1588
1621
  }
1589
1622
  return true;
1590
1623
  }
1591
- // Potentially modifies the ImportResult by removing some or all of the
1592
- // implicit import entries. Only the imported symbols should be included.
1593
- filterImplicitImports(importResult, importedSymbols) {
1594
- if (importedSymbols === undefined) {
1595
- const newImportResult = Object.assign({}, importResult);
1596
- newImportResult.filteredImplicitImports = [];
1597
- return newImportResult;
1598
- }
1599
- if (importedSymbols.length === 0) {
1600
- return importResult;
1601
- }
1602
- if (importResult.implicitImports.length === 0) {
1603
- return importResult;
1604
- }
1605
- const filteredImplicitImports = importResult.implicitImports.filter((implicitImport) => {
1606
- return importedSymbols.some((sym) => sym === implicitImport.name);
1607
- });
1608
- if (filteredImplicitImports.length === importResult.implicitImports.length) {
1609
- return importResult;
1610
- }
1611
- const newImportResult = Object.assign({}, importResult);
1612
- newImportResult.filteredImplicitImports = filteredImplicitImports;
1613
- return newImportResult;
1614
- }
1615
1624
  _findImplicitImports(importingModuleName, dirPath, exclusions) {
1616
1625
  const implicitImportMap = new Map();
1617
1626
  // Enumerate all of the files and directories in the path, expanding links.
@@ -1686,9 +1695,6 @@ class ImportResolver {
1686
1695
  }
1687
1696
  return [...implicitImportMap.values()];
1688
1697
  }
1689
- formatImportName(moduleDescriptor) {
1690
- return '.'.repeat(moduleDescriptor.leadingDots) + moduleDescriptor.nameParts.join('.');
1691
- }
1692
1698
  _resolveNativeModuleStub(nativeLibPath, execEnv, importName, moduleDescriptor, importFailureInfo, resolvedPaths) {
1693
1699
  let moduleFullName = importName;
1694
1700
  if (moduleDescriptor.leadingDots > 0) {
@@ -1730,12 +1736,6 @@ class ImportResolver {
1730
1736
  _shouldWalkUp(current, root, execEnv) {
1731
1737
  return current.length > root.length || (current === root && !execEnv.root);
1732
1738
  }
1733
- getParentImportResolutionRoot(sourceFilePath, executionRoot) {
1734
- if (executionRoot) {
1735
- return (0, pathUtils_1.ensureTrailingDirectorySeparator)((0, pathUtils_1.normalizePathCase)(this.fileSystem, (0, pathUtils_1.normalizePath)(executionRoot)));
1736
- }
1737
- return (0, pathUtils_1.ensureTrailingDirectorySeparator)((0, pathUtils_1.getDirectoryPath)(sourceFilePath));
1738
- }
1739
1739
  }
1740
1740
  exports.ImportResolver = ImportResolver;
1741
1741
  //# sourceMappingURL=importResolver.js.map