@zzzen/pyright-internal 1.1.254
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/aliasDeclarationUtils.d.ts +9 -0
- package/dist/analyzer/aliasDeclarationUtils.js +128 -0
- package/dist/analyzer/aliasDeclarationUtils.js.map +1 -0
- package/dist/analyzer/analysis.d.ts +18 -0
- package/dist/analyzer/analysis.js +81 -0
- package/dist/analyzer/analysis.js.map +1 -0
- package/dist/analyzer/analyzerFileInfo.d.ts +39 -0
- package/dist/analyzer/analyzerFileInfo.js +17 -0
- package/dist/analyzer/analyzerFileInfo.js.map +1 -0
- package/dist/analyzer/analyzerNodeInfo.d.ts +32 -0
- package/dist/analyzer/analyzerNodeInfo.js +138 -0
- package/dist/analyzer/analyzerNodeInfo.js.map +1 -0
- package/dist/analyzer/backgroundAnalysisProgram.d.ts +54 -0
- package/dist/analyzer/backgroundAnalysisProgram.js +222 -0
- package/dist/analyzer/backgroundAnalysisProgram.js.map +1 -0
- package/dist/analyzer/binder.d.ts +149 -0
- package/dist/analyzer/binder.js +3195 -0
- package/dist/analyzer/binder.js.map +1 -0
- package/dist/analyzer/checker.d.ts +116 -0
- package/dist/analyzer/checker.js +3828 -0
- package/dist/analyzer/checker.js.map +1 -0
- package/dist/analyzer/circularDependency.d.ts +7 -0
- package/dist/analyzer/circularDependency.js +51 -0
- package/dist/analyzer/circularDependency.js.map +1 -0
- package/dist/analyzer/codeFlowEngine.d.ts +21 -0
- package/dist/analyzer/codeFlowEngine.js +1132 -0
- package/dist/analyzer/codeFlowEngine.js.map +1 -0
- package/dist/analyzer/codeFlowTypes.d.ts +82 -0
- package/dist/analyzer/codeFlowTypes.js +134 -0
- package/dist/analyzer/codeFlowTypes.js.map +1 -0
- package/dist/analyzer/codeFlowUtils.d.ts +2 -0
- package/dist/analyzer/codeFlowUtils.js +348 -0
- package/dist/analyzer/codeFlowUtils.js.map +1 -0
- package/dist/analyzer/commentUtils.d.ts +4 -0
- package/dist/analyzer/commentUtils.js +131 -0
- package/dist/analyzer/commentUtils.js.map +1 -0
- package/dist/analyzer/constraintSolver.d.ts +7 -0
- package/dist/analyzer/constraintSolver.js +605 -0
- package/dist/analyzer/constraintSolver.js.map +1 -0
- package/dist/analyzer/constructorTransform.d.ts +4 -0
- package/dist/analyzer/constructorTransform.js +219 -0
- package/dist/analyzer/constructorTransform.js.map +1 -0
- package/dist/analyzer/dataClasses.d.ts +9 -0
- package/dist/analyzer/dataClasses.js +762 -0
- package/dist/analyzer/dataClasses.js.map +1 -0
- package/dist/analyzer/declaration.d.ts +90 -0
- package/dist/analyzer/declaration.js +42 -0
- package/dist/analyzer/declaration.js.map +1 -0
- package/dist/analyzer/declarationUtils.d.ts +12 -0
- package/dist/analyzer/declarationUtils.js +212 -0
- package/dist/analyzer/declarationUtils.js.map +1 -0
- package/dist/analyzer/docStringConversion.d.ts +2 -0
- package/dist/analyzer/docStringConversion.js +699 -0
- package/dist/analyzer/docStringConversion.js.map +1 -0
- package/dist/analyzer/docStringUtils.d.ts +3 -0
- package/dist/analyzer/docStringUtils.js +103 -0
- package/dist/analyzer/docStringUtils.js.map +1 -0
- package/dist/analyzer/functionTransform.d.ts +4 -0
- package/dist/analyzer/functionTransform.js +96 -0
- package/dist/analyzer/functionTransform.js.map +1 -0
- package/dist/analyzer/importResolver.d.ts +97 -0
- package/dist/analyzer/importResolver.js +1617 -0
- package/dist/analyzer/importResolver.js.map +1 -0
- package/dist/analyzer/importResult.d.ts +33 -0
- package/dist/analyzer/importResult.js +11 -0
- package/dist/analyzer/importResult.js.map +1 -0
- package/dist/analyzer/importStatementUtils.d.ts +46 -0
- package/dist/analyzer/importStatementUtils.js +618 -0
- package/dist/analyzer/importStatementUtils.js.map +1 -0
- package/dist/analyzer/namedTuples.d.ts +5 -0
- package/dist/analyzer/namedTuples.js +342 -0
- package/dist/analyzer/namedTuples.js.map +1 -0
- package/dist/analyzer/packageTypeReport.d.ts +52 -0
- package/dist/analyzer/packageTypeReport.js +45 -0
- package/dist/analyzer/packageTypeReport.js.map +1 -0
- package/dist/analyzer/packageTypeVerifier.d.ts +37 -0
- package/dist/analyzer/packageTypeVerifier.js +908 -0
- package/dist/analyzer/packageTypeVerifier.js.map +1 -0
- package/dist/analyzer/parentDirectoryCache.d.ts +23 -0
- package/dist/analyzer/parentDirectoryCache.js +71 -0
- package/dist/analyzer/parentDirectoryCache.js.map +1 -0
- package/dist/analyzer/parseTreeCleaner.d.ts +8 -0
- package/dist/analyzer/parseTreeCleaner.js +51 -0
- package/dist/analyzer/parseTreeCleaner.js.map +1 -0
- package/dist/analyzer/parseTreeUtils.d.ts +98 -0
- package/dist/analyzer/parseTreeUtils.js +1753 -0
- package/dist/analyzer/parseTreeUtils.js.map +1 -0
- package/dist/analyzer/parseTreeWalker.d.ts +81 -0
- package/dist/analyzer/parseTreeWalker.js +437 -0
- package/dist/analyzer/parseTreeWalker.js.map +1 -0
- package/dist/analyzer/patternMatching.d.ts +6 -0
- package/dist/analyzer/patternMatching.js +866 -0
- package/dist/analyzer/patternMatching.js.map +1 -0
- package/dist/analyzer/program.d.ts +158 -0
- package/dist/analyzer/program.js +1902 -0
- package/dist/analyzer/program.js.map +1 -0
- package/dist/analyzer/properties.d.ts +10 -0
- package/dist/analyzer/properties.js +368 -0
- package/dist/analyzer/properties.js.map +1 -0
- package/dist/analyzer/protocols.d.ts +8 -0
- package/dist/analyzer/protocols.js +409 -0
- package/dist/analyzer/protocols.js.map +1 -0
- package/dist/analyzer/pyTypedUtils.d.ts +6 -0
- package/dist/analyzer/pyTypedUtils.js +42 -0
- package/dist/analyzer/pyTypedUtils.js.map +1 -0
- package/dist/analyzer/pythonPathUtils.d.ts +14 -0
- package/dist/analyzer/pythonPathUtils.js +173 -0
- package/dist/analyzer/pythonPathUtils.js.map +1 -0
- package/dist/analyzer/scope.d.ts +39 -0
- package/dist/analyzer/scope.js +110 -0
- package/dist/analyzer/scope.js.map +1 -0
- package/dist/analyzer/scopeUtils.d.ts +6 -0
- package/dist/analyzer/scopeUtils.js +72 -0
- package/dist/analyzer/scopeUtils.js.map +1 -0
- package/dist/analyzer/service.d.ts +144 -0
- package/dist/analyzer/service.js +1197 -0
- package/dist/analyzer/service.js.map +1 -0
- package/dist/analyzer/sourceFile.d.ts +123 -0
- package/dist/analyzer/sourceFile.js +908 -0
- package/dist/analyzer/sourceFile.js.map +1 -0
- package/dist/analyzer/sourceMapper.d.ts +47 -0
- package/dist/analyzer/sourceMapper.js +543 -0
- package/dist/analyzer/sourceMapper.js.map +1 -0
- package/dist/analyzer/staticExpressions.d.ts +4 -0
- package/dist/analyzer/staticExpressions.js +242 -0
- package/dist/analyzer/staticExpressions.js.map +1 -0
- package/dist/analyzer/symbol.d.ts +50 -0
- package/dist/analyzer/symbol.js +160 -0
- package/dist/analyzer/symbol.js.map +1 -0
- package/dist/analyzer/symbolNameUtils.d.ts +8 -0
- package/dist/analyzer/symbolNameUtils.js +53 -0
- package/dist/analyzer/symbolNameUtils.js.map +1 -0
- package/dist/analyzer/symbolUtils.d.ts +7 -0
- package/dist/analyzer/symbolUtils.js +46 -0
- package/dist/analyzer/symbolUtils.js.map +1 -0
- package/dist/analyzer/testWalker.d.ts +14 -0
- package/dist/analyzer/testWalker.js +92 -0
- package/dist/analyzer/testWalker.js.map +1 -0
- package/dist/analyzer/tracePrinter.d.ts +11 -0
- package/dist/analyzer/tracePrinter.js +222 -0
- package/dist/analyzer/tracePrinter.js.map +1 -0
- package/dist/analyzer/typeCache.d.ts +40 -0
- package/dist/analyzer/typeCache.js +134 -0
- package/dist/analyzer/typeCache.js.map +1 -0
- package/dist/analyzer/typeDocStringUtils.d.ts +12 -0
- package/dist/analyzer/typeDocStringUtils.js +293 -0
- package/dist/analyzer/typeDocStringUtils.js.map +1 -0
- package/dist/analyzer/typeEvaluator.d.ts +18 -0
- package/dist/analyzer/typeEvaluator.js +16598 -0
- package/dist/analyzer/typeEvaluator.js.map +1 -0
- package/dist/analyzer/typeEvaluatorTypes.d.ts +220 -0
- package/dist/analyzer/typeEvaluatorTypes.js +16 -0
- package/dist/analyzer/typeEvaluatorTypes.js.map +1 -0
- package/dist/analyzer/typeEvaluatorWithTracker.d.ts +6 -0
- package/dist/analyzer/typeEvaluatorWithTracker.js +121 -0
- package/dist/analyzer/typeEvaluatorWithTracker.js.map +1 -0
- package/dist/analyzer/typeGuards.d.ts +6 -0
- package/dist/analyzer/typeGuards.js +1293 -0
- package/dist/analyzer/typeGuards.js.map +1 -0
- package/dist/analyzer/typePrinter.d.ts +17 -0
- package/dist/analyzer/typePrinter.js +603 -0
- package/dist/analyzer/typePrinter.js.map +1 -0
- package/dist/analyzer/typeStubWriter.d.ts +48 -0
- package/dist/analyzer/typeStubWriter.js +605 -0
- package/dist/analyzer/typeStubWriter.js.map +1 -0
- package/dist/analyzer/typeUtils.d.ts +134 -0
- package/dist/analyzer/typeUtils.js +2380 -0
- package/dist/analyzer/typeUtils.js.map +1 -0
- package/dist/analyzer/typeVarContext.d.ts +50 -0
- package/dist/analyzer/typeVarContext.js +250 -0
- package/dist/analyzer/typeVarContext.js.map +1 -0
- package/dist/analyzer/typedDicts.d.ts +12 -0
- package/dist/analyzer/typedDicts.js +695 -0
- package/dist/analyzer/typedDicts.js.map +1 -0
- package/dist/analyzer/types.d.ts +484 -0
- package/dist/analyzer/types.js +1844 -0
- package/dist/analyzer/types.js.map +1 -0
- package/dist/backgroundAnalysis.d.ts +14 -0
- package/dist/backgroundAnalysis.js +42 -0
- package/dist/backgroundAnalysis.js.map +1 -0
- package/dist/backgroundAnalysisBase.d.ts +83 -0
- package/dist/backgroundAnalysisBase.js +429 -0
- package/dist/backgroundAnalysisBase.js.map +1 -0
- package/dist/backgroundThreadBase.d.ts +34 -0
- package/dist/backgroundThreadBase.js +134 -0
- package/dist/backgroundThreadBase.js.map +1 -0
- package/dist/commands/commandController.d.ts +13 -0
- package/dist/commands/commandController.js +48 -0
- package/dist/commands/commandController.js.map +1 -0
- package/dist/commands/commandResult.d.ts +9 -0
- package/dist/commands/commandResult.js +19 -0
- package/dist/commands/commandResult.js.map +1 -0
- package/dist/commands/commands.d.ts +7 -0
- package/dist/commands/commands.js +11 -0
- package/dist/commands/commands.js.map +1 -0
- package/dist/commands/createTypeStub.d.ts +8 -0
- package/dist/commands/createTypeStub.js +50 -0
- package/dist/commands/createTypeStub.js.map +1 -0
- package/dist/commands/quickActionCommand.d.ts +8 -0
- package/dist/commands/quickActionCommand.js +31 -0
- package/dist/commands/quickActionCommand.js.map +1 -0
- package/dist/commands/restartServer.d.ts +8 -0
- package/dist/commands/restartServer.js +20 -0
- package/dist/commands/restartServer.js.map +1 -0
- package/dist/common/cancellationUtils.d.ts +16 -0
- package/dist/common/cancellationUtils.js +60 -0
- package/dist/common/cancellationUtils.js.map +1 -0
- package/dist/common/chokidarFileWatcherProvider.d.ts +9 -0
- package/dist/common/chokidarFileWatcherProvider.js +88 -0
- package/dist/common/chokidarFileWatcherProvider.js.map +1 -0
- package/dist/common/collectionUtils.d.ts +114 -0
- package/dist/common/collectionUtils.js +292 -0
- package/dist/common/collectionUtils.js.map +1 -0
- package/dist/common/commandLineOptions.d.ts +41 -0
- package/dist/common/commandLineOptions.js +46 -0
- package/dist/common/commandLineOptions.js.map +1 -0
- package/dist/common/configOptions.d.ts +144 -0
- package/dist/common/configOptions.js +908 -0
- package/dist/common/configOptions.js.map +1 -0
- package/dist/common/console.d.ts +61 -0
- package/dist/common/console.js +191 -0
- package/dist/common/console.js.map +1 -0
- package/dist/common/core.d.ts +67 -0
- package/dist/common/core.js +118 -0
- package/dist/common/core.js.map +1 -0
- package/dist/common/crypto.d.ts +1 -0
- package/dist/common/crypto.js +37 -0
- package/dist/common/crypto.js.map +1 -0
- package/dist/common/debug.d.ts +13 -0
- package/dist/common/debug.js +131 -0
- package/dist/common/debug.js.map +1 -0
- package/dist/common/deferred.d.ts +11 -0
- package/dist/common/deferred.js +62 -0
- package/dist/common/deferred.js.map +1 -0
- package/dist/common/diagnostic.d.ts +59 -0
- package/dist/common/diagnostic.js +134 -0
- package/dist/common/diagnostic.js.map +1 -0
- package/dist/common/diagnosticRules.d.ts +67 -0
- package/dist/common/diagnosticRules.js +83 -0
- package/dist/common/diagnosticRules.js.map +1 -0
- package/dist/common/diagnosticSink.d.ts +34 -0
- package/dist/common/diagnosticSink.js +110 -0
- package/dist/common/diagnosticSink.js.map +1 -0
- package/dist/common/editAction.d.ts +29 -0
- package/dist/common/editAction.js +11 -0
- package/dist/common/editAction.js.map +1 -0
- package/dist/common/extensibility.d.ts +11 -0
- package/dist/common/extensibility.js +10 -0
- package/dist/common/extensibility.js.map +1 -0
- package/dist/common/extensions.d.ts +3 -0
- package/dist/common/extensions.js +15 -0
- package/dist/common/extensions.js.map +1 -0
- package/dist/common/fileBasedCancellationUtils.d.ts +11 -0
- package/dist/common/fileBasedCancellationUtils.js +259 -0
- package/dist/common/fileBasedCancellationUtils.js.map +1 -0
- package/dist/common/fileSystem.d.ts +72 -0
- package/dist/common/fileSystem.js +69 -0
- package/dist/common/fileSystem.js.map +1 -0
- package/dist/common/fullAccessHost.d.ts +19 -0
- package/dist/common/fullAccessHost.js +193 -0
- package/dist/common/fullAccessHost.js.map +1 -0
- package/dist/common/host.d.ts +21 -0
- package/dist/common/host.js +30 -0
- package/dist/common/host.js.map +1 -0
- package/dist/common/logTracker.d.ts +15 -0
- package/dist/common/logTracker.js +129 -0
- package/dist/common/logTracker.js.map +1 -0
- package/dist/common/lspUtils.d.ts +3 -0
- package/dist/common/lspUtils.js +20 -0
- package/dist/common/lspUtils.js.map +1 -0
- package/dist/common/memUtils.d.ts +3 -0
- package/dist/common/memUtils.js +37 -0
- package/dist/common/memUtils.js.map +1 -0
- package/dist/common/pathConsts.d.ts +8 -0
- package/dist/common/pathConsts.js +19 -0
- package/dist/common/pathConsts.js.map +1 -0
- package/dist/common/pathUtils.d.ts +170 -0
- package/dist/common/pathUtils.js +762 -0
- package/dist/common/pathUtils.js.map +1 -0
- package/dist/common/positionUtils.d.ts +7 -0
- package/dist/common/positionUtils.js +71 -0
- package/dist/common/positionUtils.js.map +1 -0
- package/dist/common/progressReporter.d.ts +15 -0
- package/dist/common/progressReporter.js +44 -0
- package/dist/common/progressReporter.js.map +1 -0
- package/dist/common/pythonVersion.d.ts +20 -0
- package/dist/common/pythonVersion.js +71 -0
- package/dist/common/pythonVersion.js.map +1 -0
- package/dist/common/realFileSystem.d.ts +8 -0
- package/dist/common/realFileSystem.js +368 -0
- package/dist/common/realFileSystem.js.map +1 -0
- package/dist/common/stringUtils.d.ts +47 -0
- package/dist/common/stringUtils.js +160 -0
- package/dist/common/stringUtils.js.map +1 -0
- package/dist/common/textEditUtils.d.ts +3 -0
- package/dist/common/textEditUtils.js +29 -0
- package/dist/common/textEditUtils.js.map +1 -0
- package/dist/common/textRange.d.ts +47 -0
- package/dist/common/textRange.js +211 -0
- package/dist/common/textRange.js.map +1 -0
- package/dist/common/textRangeCollection.d.ts +13 -0
- package/dist/common/textRangeCollection.js +108 -0
- package/dist/common/textRangeCollection.js.map +1 -0
- package/dist/common/timing.d.ts +31 -0
- package/dist/common/timing.js +100 -0
- package/dist/common/timing.js.map +1 -0
- package/dist/common/uriParser.d.ts +12 -0
- package/dist/common/uriParser.js +25 -0
- package/dist/common/uriParser.js.map +1 -0
- package/dist/common/workspaceEditUtils.d.ts +7 -0
- package/dist/common/workspaceEditUtils.js +63 -0
- package/dist/common/workspaceEditUtils.js.map +1 -0
- package/dist/languageServerBase.d.ts +211 -0
- package/dist/languageServerBase.js +923 -0
- package/dist/languageServerBase.js.map +1 -0
- package/dist/languageService/analyzerServiceExecutor.d.ts +8 -0
- package/dist/languageService/analyzerServiceExecutor.js +97 -0
- package/dist/languageService/analyzerServiceExecutor.js.map +1 -0
- package/dist/languageService/autoImporter.d.ts +84 -0
- package/dist/languageService/autoImporter.js +635 -0
- package/dist/languageService/autoImporter.js.map +1 -0
- package/dist/languageService/callHierarchyProvider.d.ts +12 -0
- package/dist/languageService/callHierarchyProvider.js +368 -0
- package/dist/languageService/callHierarchyProvider.js.map +1 -0
- package/dist/languageService/codeActionProvider.d.ts +6 -0
- package/dist/languageService/codeActionProvider.js +53 -0
- package/dist/languageService/codeActionProvider.js.map +1 -0
- package/dist/languageService/completionProvider.d.ts +147 -0
- package/dist/languageService/completionProvider.js +2220 -0
- package/dist/languageService/completionProvider.js.map +1 -0
- package/dist/languageService/definitionProvider.d.ts +17 -0
- package/dist/languageService/definitionProvider.js +206 -0
- package/dist/languageService/definitionProvider.js.map +1 -0
- package/dist/languageService/documentHighlightProvider.d.ts +7 -0
- package/dist/languageService/documentHighlightProvider.js +63 -0
- package/dist/languageService/documentHighlightProvider.js.map +1 -0
- package/dist/languageService/documentSymbolCollector.d.ts +37 -0
- package/dist/languageService/documentSymbolCollector.js +344 -0
- package/dist/languageService/documentSymbolCollector.js.map +1 -0
- package/dist/languageService/documentSymbolProvider.d.ts +37 -0
- package/dist/languageService/documentSymbolProvider.js +308 -0
- package/dist/languageService/documentSymbolProvider.js.map +1 -0
- package/dist/languageService/hoverProvider.d.ts +25 -0
- package/dist/languageService/hoverProvider.js +366 -0
- package/dist/languageService/hoverProvider.js.map +1 -0
- package/dist/languageService/importAdder.d.ts +24 -0
- package/dist/languageService/importAdder.js +296 -0
- package/dist/languageService/importAdder.js.map +1 -0
- package/dist/languageService/importSorter.d.ts +15 -0
- package/dist/languageService/importSorter.js +152 -0
- package/dist/languageService/importSorter.js.map +1 -0
- package/dist/languageService/indentationUtils.d.ts +4 -0
- package/dist/languageService/indentationUtils.js +597 -0
- package/dist/languageService/indentationUtils.js.map +1 -0
- package/dist/languageService/quickActions.d.ts +4 -0
- package/dist/languageService/quickActions.js +97 -0
- package/dist/languageService/quickActions.js.map +1 -0
- package/dist/languageService/referencesProvider.d.ts +36 -0
- package/dist/languageService/referencesProvider.js +236 -0
- package/dist/languageService/referencesProvider.js.map +1 -0
- package/dist/languageService/renameModuleProvider.d.ts +58 -0
- package/dist/languageService/renameModuleProvider.js +884 -0
- package/dist/languageService/renameModuleProvider.js.map +1 -0
- package/dist/languageService/signatureHelpProvider.d.ts +26 -0
- package/dist/languageService/signatureHelpProvider.js +180 -0
- package/dist/languageService/signatureHelpProvider.js.map +1 -0
- package/dist/languageService/tooltipUtils.d.ts +9 -0
- package/dist/languageService/tooltipUtils.js +129 -0
- package/dist/languageService/tooltipUtils.js.map +1 -0
- package/dist/localization/localize.d.ts +1324 -0
- package/dist/localization/localize.js +788 -0
- package/dist/localization/localize.js.map +1 -0
- package/dist/localization/package.nls.de.json +1 -0
- package/dist/localization/package.nls.en-us.json +636 -0
- package/dist/localization/package.nls.es.json +1 -0
- package/dist/localization/package.nls.fr.json +1 -0
- package/dist/localization/package.nls.ja.json +1 -0
- package/dist/localization/package.nls.ru.json +1 -0
- package/dist/localization/package.nls.zh-cn.json +1 -0
- package/dist/localization/package.nls.zh-tw.json +1 -0
- package/dist/nodeMain.d.ts +1 -0
- package/dist/nodeMain.js +21 -0
- package/dist/nodeMain.js.map +1 -0
- package/dist/nodeServer.d.ts +3 -0
- package/dist/nodeServer.js +31 -0
- package/dist/nodeServer.js.map +1 -0
- package/dist/parser/characterStream.d.ts +27 -0
- package/dist/parser/characterStream.js +120 -0
- package/dist/parser/characterStream.js.map +1 -0
- package/dist/parser/characters.d.ts +17 -0
- package/dist/parser/characters.js +240 -0
- package/dist/parser/characters.js.map +1 -0
- package/dist/parser/parseNodes.d.ts +750 -0
- package/dist/parser/parseNodes.js +1406 -0
- package/dist/parser/parseNodes.js.map +1 -0
- package/dist/parser/parser.d.ts +191 -0
- package/dist/parser/parser.js +3806 -0
- package/dist/parser/parser.js.map +1 -0
- package/dist/parser/stringTokenUtils.d.ts +25 -0
- package/dist/parser/stringTokenUtils.js +455 -0
- package/dist/parser/stringTokenUtils.js.map +1 -0
- package/dist/parser/tokenizer.d.ts +71 -0
- package/dist/parser/tokenizer.js +1111 -0
- package/dist/parser/tokenizer.js.map +1 -0
- package/dist/parser/tokenizerTypes.d.ts +223 -0
- package/dist/parser/tokenizerTypes.js +164 -0
- package/dist/parser/tokenizerTypes.js.map +1 -0
- package/dist/parser/unicode.d.ts +23 -0
- package/dist/parser/unicode.js +2899 -0
- package/dist/parser/unicode.js.map +1 -0
- package/dist/pyright.d.ts +1 -0
- package/dist/pyright.js +645 -0
- package/dist/pyright.js.map +1 -0
- package/dist/pyrightFileSystem.d.ts +28 -0
- package/dist/pyrightFileSystem.js +196 -0
- package/dist/pyrightFileSystem.js.map +1 -0
- package/dist/readonlyAugmentedFileSystem.d.ts +40 -0
- package/dist/readonlyAugmentedFileSystem.js +155 -0
- package/dist/readonlyAugmentedFileSystem.js.map +1 -0
- package/dist/server.d.ts +21 -0
- package/dist/server.js +232 -0
- package/dist/server.js.map +1 -0
- package/dist/tests/chainedSourceFiles.test.d.ts +1 -0
- package/dist/tests/chainedSourceFiles.test.js +153 -0
- package/dist/tests/chainedSourceFiles.test.js.map +1 -0
- package/dist/tests/checker.test.d.ts +1 -0
- package/dist/tests/checker.test.js +346 -0
- package/dist/tests/checker.test.js.map +1 -0
- package/dist/tests/collectionUtils.test.d.ts +1 -0
- package/dist/tests/collectionUtils.test.js +153 -0
- package/dist/tests/collectionUtils.test.js.map +1 -0
- package/dist/tests/common.test.d.ts +1 -0
- package/dist/tests/common.test.js +125 -0
- package/dist/tests/common.test.js.map +1 -0
- package/dist/tests/config.test.d.ts +1 -0
- package/dist/tests/config.test.js +230 -0
- package/dist/tests/config.test.js.map +1 -0
- package/dist/tests/debug.test.d.ts +1 -0
- package/dist/tests/debug.test.js +102 -0
- package/dist/tests/debug.test.js.map +1 -0
- package/dist/tests/deferred.test.d.ts +1 -0
- package/dist/tests/deferred.test.js +65 -0
- package/dist/tests/deferred.test.js.map +1 -0
- package/dist/tests/diagnosticOverrides.test.d.ts +1 -0
- package/dist/tests/diagnosticOverrides.test.js +108 -0
- package/dist/tests/diagnosticOverrides.test.js.map +1 -0
- package/dist/tests/docStringConversion.test.d.ts +1 -0
- package/dist/tests/docStringConversion.test.js +695 -0
- package/dist/tests/docStringConversion.test.js.map +1 -0
- package/dist/tests/docStringUtils.test.d.ts +1 -0
- package/dist/tests/docStringUtils.test.js +70 -0
- package/dist/tests/docStringUtils.test.js.map +1 -0
- package/dist/tests/documentSymbolCollector.test.d.ts +1 -0
- package/dist/tests/documentSymbolCollector.test.js +635 -0
- package/dist/tests/documentSymbolCollector.test.js.map +1 -0
- package/dist/tests/filesystem.test.d.ts +1 -0
- package/dist/tests/filesystem.test.js +194 -0
- package/dist/tests/filesystem.test.js.map +1 -0
- package/dist/tests/fourSlashParser.test.d.ts +1 -0
- package/dist/tests/fourSlashParser.test.js +281 -0
- package/dist/tests/fourSlashParser.test.js.map +1 -0
- package/dist/tests/fourSlashRunner.test.d.ts +1 -0
- package/dist/tests/fourSlashRunner.test.js +52 -0
- package/dist/tests/fourSlashRunner.test.js.map +1 -0
- package/dist/tests/fourslash/completions.autoimport.Lib.Found.Type.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.autoimport.Lib.Found.Type.fourslash.js +30 -0
- package/dist/tests/fourslash/completions.autoimport.Lib.Found.Type.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.autoimport.Lib.Found.duplication.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.autoimport.Lib.Found.duplication.fourslash.js +42 -0
- package/dist/tests/fourslash/completions.autoimport.Lib.Found.duplication.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.autoimport.Lib.NotFound.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.autoimport.Lib.NotFound.fourslash.js +13 -0
- package/dist/tests/fourslash/completions.autoimport.Lib.NotFound.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.autoimport.disabled.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.autoimport.disabled.fourslash.js +23 -0
- package/dist/tests/fourslash/completions.autoimport.disabled.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.autoimport.duplicates.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.autoimport.duplicates.fourslash.js +35 -0
- package/dist/tests/fourslash/completions.autoimport.duplicates.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.autoimport.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.autoimport.fourslash.js +27 -0
- package/dist/tests/fourslash/completions.autoimport.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.autoimport.fromImport.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.autoimport.fromImport.fourslash.js +128 -0
- package/dist/tests/fourslash/completions.autoimport.fromImport.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.autoimport.plainText.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.autoimport.plainText.fourslash.js +27 -0
- package/dist/tests/fourslash/completions.autoimport.plainText.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.autoimport.shadow.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.autoimport.shadow.fourslash.js +43 -0
- package/dist/tests/fourslash/completions.autoimport.shadow.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.autoimport.submodule.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.autoimport.submodule.fourslash.js +29 -0
- package/dist/tests/fourslash/completions.autoimport.submodule.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.autoimport.topLevel.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.autoimport.topLevel.fourslash.js +50 -0
- package/dist/tests/fourslash/completions.autoimport.topLevel.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.builtinDocstrings.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.builtinDocstrings.fourslash.js +116 -0
- package/dist/tests/fourslash/completions.builtinDocstrings.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.builtinOverride.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.builtinOverride.fourslash.js +21 -0
- package/dist/tests/fourslash/completions.builtinOverride.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.call.stringLiteral.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.call.stringLiteral.fourslash.js +54 -0
- package/dist/tests/fourslash/completions.call.stringLiteral.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.call.typedDict.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.call.typedDict.fourslash.js +245 -0
- package/dist/tests/fourslash/completions.call.typedDict.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.call.typedDict.list.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.call.typedDict.list.fourslash.js +162 -0
- package/dist/tests/fourslash/completions.call.typedDict.list.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.call.typedDict.states.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.call.typedDict.states.fourslash.js +132 -0
- package/dist/tests/fourslash/completions.call.typedDict.states.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.classVariable.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.classVariable.fourslash.js +37 -0
- package/dist/tests/fourslash/completions.classVariable.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.comment.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.comment.fourslash.js +27 -0
- package/dist/tests/fourslash/completions.comment.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.declNames.class.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.declNames.class.fourslash.js +30 -0
- package/dist/tests/fourslash/completions.declNames.class.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.declNames.exception.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.declNames.exception.fourslash.js +18 -0
- package/dist/tests/fourslash/completions.declNames.exception.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.declNames.for.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.declNames.for.fourslash.js +26 -0
- package/dist/tests/fourslash/completions.declNames.for.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.declNames.importAlias.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.declNames.importAlias.fourslash.js +15 -0
- package/dist/tests/fourslash/completions.declNames.importAlias.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.declNames.lambda.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.declNames.lambda.fourslash.js +36 -0
- package/dist/tests/fourslash/completions.declNames.lambda.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.declNames.method.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.declNames.method.fourslash.js +68 -0
- package/dist/tests/fourslash/completions.declNames.method.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.declNames.overload.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.declNames.overload.fourslash.js +147 -0
- package/dist/tests/fourslash/completions.declNames.overload.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.declNames.topLevelOverload.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.declNames.topLevelOverload.fourslash.js +131 -0
- package/dist/tests/fourslash/completions.declNames.topLevelOverload.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.dictionary.keys.complex.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.dictionary.keys.complex.fourslash.js +73 -0
- package/dist/tests/fourslash/completions.dictionary.keys.complex.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.dictionary.keys.expression.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.dictionary.keys.expression.fourslash.js +58 -0
- package/dist/tests/fourslash/completions.dictionary.keys.expression.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.dictionary.keys.literalTypes.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.dictionary.keys.literalTypes.fourslash.js +154 -0
- package/dist/tests/fourslash/completions.dictionary.keys.literalTypes.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.dictionary.keys.simple.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.dictionary.keys.simple.fourslash.js +143 -0
- package/dist/tests/fourslash/completions.dictionary.keys.simple.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.dictionary.keys.stringLiterals.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.dictionary.keys.stringLiterals.fourslash.js +109 -0
- package/dist/tests/fourslash/completions.dictionary.keys.stringLiterals.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.dictionary.keys.symbols.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.dictionary.keys.symbols.fourslash.js +50 -0
- package/dist/tests/fourslash/completions.dictionary.keys.symbols.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.enums.members.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.enums.members.fourslash.js +44 -0
- package/dist/tests/fourslash/completions.enums.members.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.excluded.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.excluded.fourslash.js +12 -0
- package/dist/tests/fourslash/completions.excluded.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.fourslash.js +51 -0
- package/dist/tests/fourslash/completions.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.fstring.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.fstring.fourslash.js +32 -0
- package/dist/tests/fourslash/completions.fstring.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.fstring.stringLiteral.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.fstring.stringLiteral.fourslash.js +96 -0
- package/dist/tests/fourslash/completions.fstring.stringLiteral.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.fuzzyMatching.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.fuzzyMatching.fourslash.js +30 -0
- package/dist/tests/fourslash/completions.fuzzyMatching.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.importDunderNames.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.importDunderNames.fourslash.js +29 -0
- package/dist/tests/fourslash/completions.importDunderNames.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.importSubmodule.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.importSubmodule.fourslash.js +22 -0
- package/dist/tests/fourslash/completions.importSubmodule.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.importsDuplicates.fourslash.d.ts +0 -0
- package/dist/tests/fourslash/completions.importsDuplicates.fourslash.js +22 -0
- package/dist/tests/fourslash/completions.importsDuplicates.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.inList.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.inList.fourslash.js +32 -0
- package/dist/tests/fourslash/completions.inList.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.included.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.included.fourslash.js +12 -0
- package/dist/tests/fourslash/completions.included.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.indexer.keys.getitem.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.indexer.keys.getitem.fourslash.js +54 -0
- package/dist/tests/fourslash/completions.indexer.keys.getitem.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.inherited.function.docFromStub.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.inherited.function.docFromStub.fourslash.js +26 -0
- package/dist/tests/fourslash/completions.inherited.function.docFromStub.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.inherited.overload.docFromScrWithStub.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.inherited.overload.docFromScrWithStub.fourslash.js +49 -0
- package/dist/tests/fourslash/completions.inherited.overload.docFromScrWithStub.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.inherited.overload.docFromStub.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.inherited.overload.docFromStub.fourslash.js +50 -0
- package/dist/tests/fourslash/completions.inherited.overload.docFromStub.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.inherited.property.docFromSrc.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.inherited.property.docFromSrc.fourslash.js +101 -0
- package/dist/tests/fourslash/completions.inherited.property.docFromSrc.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.inherited.property.docFromStub.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.inherited.property.docFromStub.fourslash.js +105 -0
- package/dist/tests/fourslash/completions.inherited.property.docFromStub.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.keywords.pythonVersion.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.keywords.pythonVersion.fourslash.js +67 -0
- package/dist/tests/fourslash/completions.keywords.pythonVersion.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.libCodeAndStub.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.libCodeAndStub.fourslash.js +75 -0
- package/dist/tests/fourslash/completions.libCodeAndStub.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.libCodeNoStub.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.libCodeNoStub.fourslash.js +66 -0
- package/dist/tests/fourslash/completions.libCodeNoStub.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.libStub.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.libStub.fourslash.js +66 -0
- package/dist/tests/fourslash/completions.libStub.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.literals.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.literals.fourslash.js +31 -0
- package/dist/tests/fourslash/completions.literals.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.localCode.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.localCode.fourslash.js +71 -0
- package/dist/tests/fourslash/completions.localCode.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.moduleContext.UnknownMemberOnInstance.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.moduleContext.UnknownMemberOnInstance.fourslash.js +17 -0
- package/dist/tests/fourslash/completions.moduleContext.UnknownMemberOnInstance.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.moduleContext.UnknownStaticFunctionOnClass.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.moduleContext.UnknownStaticFunctionOnClass.fourslash.js +57 -0
- package/dist/tests/fourslash/completions.moduleContext.UnknownStaticFunctionOnClass.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.moduleContext.libCodeNoStub.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.moduleContext.libCodeNoStub.fourslash.js +27 -0
- package/dist/tests/fourslash/completions.moduleContext.libCodeNoStub.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.overloads.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.overloads.fourslash.js +37 -0
- package/dist/tests/fourslash/completions.overloads.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.override.default.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.override.default.fourslash.js +47 -0
- package/dist/tests/fourslash/completions.override.default.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.override.default.importStub.d.ts +1 -0
- package/dist/tests/fourslash/completions.override.default.importStub.js +49 -0
- package/dist/tests/fourslash/completions.override.default.importStub.js.map +1 -0
- package/dist/tests/fourslash/completions.override.default.imported.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.override.default.imported.fourslash.js +60 -0
- package/dist/tests/fourslash/completions.override.default.imported.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.override.default.stub.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.override.default.stub.fourslash.js +47 -0
- package/dist/tests/fourslash/completions.override.default.stub.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.override.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.override.fourslash.js +47 -0
- package/dist/tests/fourslash/completions.override.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.override.property.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.override.property.fourslash.js +31 -0
- package/dist/tests/fourslash/completions.override.property.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.override.property.stub.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.override.property.stub.fourslash.js +31 -0
- package/dist/tests/fourslash/completions.override.property.stub.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.override.staticAndClassmethod.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.override.staticAndClassmethod.fourslash.js +63 -0
- package/dist/tests/fourslash/completions.override.staticAndClassmethod.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.override.stub.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.override.stub.fourslash.js +47 -0
- package/dist/tests/fourslash/completions.override.stub.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.override2.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.override2.fourslash.js +66 -0
- package/dist/tests/fourslash/completions.override2.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.parameters.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.parameters.fourslash.js +22 -0
- package/dist/tests/fourslash/completions.parameters.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.params.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.params.fourslash.js +23 -0
- package/dist/tests/fourslash/completions.params.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.parentFolder.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.parentFolder.fourslash.js +15 -0
- package/dist/tests/fourslash/completions.parentFolder.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.parentFolders.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.parentFolders.fourslash.js +68 -0
- package/dist/tests/fourslash/completions.parentFolders.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.plainText.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.plainText.fourslash.js +34 -0
- package/dist/tests/fourslash/completions.plainText.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.private.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.private.fourslash.js +61 -0
- package/dist/tests/fourslash/completions.private.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.property.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.property.fourslash.js +28 -0
- package/dist/tests/fourslash/completions.property.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.propertyDocStrings.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.propertyDocStrings.fourslash.js +64 -0
- package/dist/tests/fourslash/completions.propertyDocStrings.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.self.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.self.fourslash.js +43 -0
- package/dist/tests/fourslash/completions.self.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.stringLiteral.escape.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.stringLiteral.escape.fourslash.js +71 -0
- package/dist/tests/fourslash/completions.stringLiteral.escape.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.stringLiteral.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.stringLiteral.fourslash.js +78 -0
- package/dist/tests/fourslash/completions.stringLiteral.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.typeAlias.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.typeAlias.fourslash.js +29 -0
- package/dist/tests/fourslash/completions.typeAlias.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.typeshed.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.typeshed.fourslash.js +9 -0
- package/dist/tests/fourslash/completions.typeshed.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.vardecls.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.vardecls.fourslash.js +33 -0
- package/dist/tests/fourslash/completions.vardecls.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.variableDocStrings.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.variableDocStrings.fourslash.js +68 -0
- package/dist/tests/fourslash/completions.variableDocStrings.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.wildcardimports.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.wildcardimports.fourslash.js +109 -0
- package/dist/tests/fourslash/completions.wildcardimports.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.with.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.with.fourslash.js +25 -0
- package/dist/tests/fourslash/completions.with.fourslash.js.map +1 -0
- package/dist/tests/fourslash/diagnostics.missingModuleSource.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/diagnostics.missingModuleSource.fourslash.js +64 -0
- package/dist/tests/fourslash/diagnostics.missingModuleSource.fourslash.js.map +1 -0
- package/dist/tests/fourslash/findDefinitions.builtinClass.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/findDefinitions.builtinClass.fourslash.js +24 -0
- package/dist/tests/fourslash/findDefinitions.builtinClass.fourslash.js.map +1 -0
- package/dist/tests/fourslash/findDefinitions.classes.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/findDefinitions.classes.fourslash.js +93 -0
- package/dist/tests/fourslash/findDefinitions.classes.fourslash.js.map +1 -0
- package/dist/tests/fourslash/findDefinitions.definitionFilter.preferSource.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/findDefinitions.definitionFilter.preferSource.fourslash.js +23 -0
- package/dist/tests/fourslash/findDefinitions.definitionFilter.preferSource.fourslash.js.map +1 -0
- package/dist/tests/fourslash/findDefinitions.definitionFilter.preferSource.onlyStubs.d.ts +1 -0
- package/dist/tests/fourslash/findDefinitions.definitionFilter.preferSource.onlyStubs.js +19 -0
- package/dist/tests/fourslash/findDefinitions.definitionFilter.preferSource.onlyStubs.js.map +1 -0
- package/dist/tests/fourslash/findDefinitions.definitionFilter.preferStub.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/findDefinitions.definitionFilter.preferStub.fourslash.js +23 -0
- package/dist/tests/fourslash/findDefinitions.definitionFilter.preferStub.fourslash.js.map +1 -0
- package/dist/tests/fourslash/findDefinitions.definitionFilter.preferStub.onlySource.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/findDefinitions.definitionFilter.preferStub.onlySource.fourslash.js +20 -0
- package/dist/tests/fourslash/findDefinitions.definitionFilter.preferStub.onlySource.fourslash.js.map +1 -0
- package/dist/tests/fourslash/findDefinitions.fields.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/findDefinitions.fields.fourslash.js +123 -0
- package/dist/tests/fourslash/findDefinitions.fields.fourslash.js.map +1 -0
- package/dist/tests/fourslash/findDefinitions.functions.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/findDefinitions.functions.fourslash.js +79 -0
- package/dist/tests/fourslash/findDefinitions.functions.fourslash.js.map +1 -0
- package/dist/tests/fourslash/findDefinitions.methods.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/findDefinitions.methods.fourslash.js +154 -0
- package/dist/tests/fourslash/findDefinitions.methods.fourslash.js.map +1 -0
- package/dist/tests/fourslash/findDefinitions.modules.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/findDefinitions.modules.fourslash.js +42 -0
- package/dist/tests/fourslash/findDefinitions.modules.fourslash.js.map +1 -0
- package/dist/tests/fourslash/findDefinitions.namespaceImport.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/findDefinitions.namespaceImport.fourslash.js +34 -0
- package/dist/tests/fourslash/findDefinitions.namespaceImport.fourslash.js.map +1 -0
- package/dist/tests/fourslash/findDefinitions.overloads.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/findDefinitions.overloads.fourslash.js +213 -0
- package/dist/tests/fourslash/findDefinitions.overloads.fourslash.js.map +1 -0
- package/dist/tests/fourslash/findDefinitions.parameters.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/findDefinitions.parameters.fourslash.js +154 -0
- package/dist/tests/fourslash/findDefinitions.parameters.fourslash.js.map +1 -0
- package/dist/tests/fourslash/findDefinitions.sourceAndStub.function.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/findDefinitions.sourceAndStub.function.fourslash.js +23 -0
- package/dist/tests/fourslash/findDefinitions.sourceAndStub.function.fourslash.js.map +1 -0
- package/dist/tests/fourslash/findDefinitions.sourceAndStub.innerClass.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/findDefinitions.sourceAndStub.innerClass.fourslash.js +29 -0
- package/dist/tests/fourslash/findDefinitions.sourceAndStub.innerClass.fourslash.js.map +1 -0
- package/dist/tests/fourslash/findDefinitions.sourceAndStub.innerClassMethod.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/findDefinitions.sourceAndStub.innerClassMethod.fourslash.js +30 -0
- package/dist/tests/fourslash/findDefinitions.sourceAndStub.innerClassMethod.fourslash.js.map +1 -0
- package/dist/tests/fourslash/findDefinitions.sourceAndStub.outerClass.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/findDefinitions.sourceAndStub.outerClass.fourslash.js +25 -0
- package/dist/tests/fourslash/findDefinitions.sourceAndStub.outerClass.fourslash.js.map +1 -0
- package/dist/tests/fourslash/findDefinitions.sourceAndStub.outerClassMethod.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/findDefinitions.sourceAndStub.outerClassMethod.fourslash.js +26 -0
- package/dist/tests/fourslash/findDefinitions.sourceAndStub.outerClassMethod.fourslash.js.map +1 -0
- package/dist/tests/fourslash/findDefinitions.sourceAndStub.outerClassPropertyReadOnly.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/findDefinitions.sourceAndStub.outerClassPropertyReadOnly.fourslash.js +28 -0
- package/dist/tests/fourslash/findDefinitions.sourceAndStub.outerClassPropertyReadOnly.fourslash.js.map +1 -0
- package/dist/tests/fourslash/findDefinitions.sourceAndStub.outerClassPropertyReadWrite.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/findDefinitions.sourceAndStub.outerClassPropertyReadWrite.fourslash.js +33 -0
- package/dist/tests/fourslash/findDefinitions.sourceAndStub.outerClassPropertyReadWrite.fourslash.js.map +1 -0
- package/dist/tests/fourslash/findDefinitions.sourceOnly.class.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/findDefinitions.sourceOnly.class.fourslash.js +26 -0
- package/dist/tests/fourslash/findDefinitions.sourceOnly.class.fourslash.js.map +1 -0
- package/dist/tests/fourslash/findDefinitions.sourceOnly.function1.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/findDefinitions.sourceOnly.function1.fourslash.js +25 -0
- package/dist/tests/fourslash/findDefinitions.sourceOnly.function1.fourslash.js.map +1 -0
- package/dist/tests/fourslash/findDefinitions.sourceOnly.function2.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/findDefinitions.sourceOnly.function2.fourslash.js +25 -0
- package/dist/tests/fourslash/findDefinitions.sourceOnly.function2.fourslash.js.map +1 -0
- package/dist/tests/fourslash/findDefinitions.sourceOnly.relativeImport1.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/findDefinitions.sourceOnly.relativeImport1.fourslash.js +20 -0
- package/dist/tests/fourslash/findDefinitions.sourceOnly.relativeImport1.fourslash.js.map +1 -0
- package/dist/tests/fourslash/findDefinitions.sourceOnly.relativeImport2.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/findDefinitions.sourceOnly.relativeImport2.fourslash.js +20 -0
- package/dist/tests/fourslash/findDefinitions.sourceOnly.relativeImport2.fourslash.js.map +1 -0
- package/dist/tests/fourslash/findDefinitions.stubOnly.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/findDefinitions.stubOnly.fourslash.js +59 -0
- package/dist/tests/fourslash/findDefinitions.stubOnly.fourslash.js.map +1 -0
- package/dist/tests/fourslash/findDefinitions.stubPackages.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/findDefinitions.stubPackages.fourslash.js +59 -0
- package/dist/tests/fourslash/findDefinitions.stubPackages.fourslash.js.map +1 -0
- package/dist/tests/fourslash/findDefinitions.typedDict.keys.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/findDefinitions.typedDict.keys.fourslash.js +94 -0
- package/dist/tests/fourslash/findDefinitions.typedDict.keys.fourslash.js.map +1 -0
- package/dist/tests/fourslash/findDefinitions.variables.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/findDefinitions.variables.fourslash.js +79 -0
- package/dist/tests/fourslash/findDefinitions.variables.fourslash.js.map +1 -0
- package/dist/tests/fourslash/findDefinitions.wildcardimports.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/findDefinitions.wildcardimports.fourslash.js +106 -0
- package/dist/tests/fourslash/findDefinitions.wildcardimports.fourslash.js.map +1 -0
- package/dist/tests/fourslash/findTypeDefinitions.builtinClass.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/findTypeDefinitions.builtinClass.fourslash.js +24 -0
- package/dist/tests/fourslash/findTypeDefinitions.builtinClass.fourslash.js.map +1 -0
- package/dist/tests/fourslash/findTypeDefinitions.classes.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/findTypeDefinitions.classes.fourslash.js +66 -0
- package/dist/tests/fourslash/findTypeDefinitions.classes.fourslash.js.map +1 -0
- package/dist/tests/fourslash/findTypeDefinitions.unions.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/findTypeDefinitions.unions.fourslash.js +26 -0
- package/dist/tests/fourslash/findTypeDefinitions.unions.fourslash.js.map +1 -0
- package/dist/tests/fourslash/findallreferences.classPropertyReadWrite.d.ts +1 -0
- package/dist/tests/fourslash/findallreferences.classPropertyReadWrite.js +36 -0
- package/dist/tests/fourslash/findallreferences.classPropertyReadWrite.js.map +1 -0
- package/dist/tests/fourslash/findallreferences.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/findallreferences.fourslash.js +30 -0
- package/dist/tests/fourslash/findallreferences.fourslash.js.map +1 -0
- package/dist/tests/fourslash/findallreferences.importalias.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/findallreferences.importalias.fourslash.js +30 -0
- package/dist/tests/fourslash/findallreferences.importalias.fourslash.js.map +1 -0
- package/dist/tests/fourslash/findallreferences.invokedFromLibrary.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/findallreferences.invokedFromLibrary.fourslash.js +46 -0
- package/dist/tests/fourslash/findallreferences.invokedFromLibrary.fourslash.js.map +1 -0
- package/dist/tests/fourslash/findallreferences.module.nested.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/findallreferences.module.nested.fourslash.js +60 -0
- package/dist/tests/fourslash/findallreferences.module.nested.fourslash.js.map +1 -0
- package/dist/tests/fourslash/findallreferences.modules.duplicated.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/findallreferences.modules.duplicated.fourslash.js +54 -0
- package/dist/tests/fourslash/findallreferences.modules.duplicated.fourslash.js.map +1 -0
- package/dist/tests/fourslash/findallreferences.modules.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/findallreferences.modules.fourslash.js +41 -0
- package/dist/tests/fourslash/findallreferences.modules.fourslash.js.map +1 -0
- package/dist/tests/fourslash/findallreferences.modules.shadow.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/findallreferences.modules.shadow.fourslash.js +83 -0
- package/dist/tests/fourslash/findallreferences.modules.shadow.fourslash.js.map +1 -0
- package/dist/tests/fourslash/findallreferences.openFiles.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/findallreferences.openFiles.fourslash.js +32 -0
- package/dist/tests/fourslash/findallreferences.openFiles.fourslash.js.map +1 -0
- package/dist/tests/fourslash/findallreferences.parameter.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/findallreferences.parameter.fourslash.js +22 -0
- package/dist/tests/fourslash/findallreferences.parameter.fourslash.js.map +1 -0
- package/dist/tests/fourslash/findallreferences.sourceAndStub.class.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/findallreferences.sourceAndStub.class.fourslash.js +29 -0
- package/dist/tests/fourslash/findallreferences.sourceAndStub.class.fourslash.js.map +1 -0
- package/dist/tests/fourslash/findallreferences.sourceAndStub.classMethod.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/findallreferences.sourceAndStub.classMethod.fourslash.js +33 -0
- package/dist/tests/fourslash/findallreferences.sourceAndStub.classMethod.fourslash.js.map +1 -0
- package/dist/tests/fourslash/findallreferences.sourceAndStub.classPropertyReadOnly.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/findallreferences.sourceAndStub.classPropertyReadOnly.fourslash.js +36 -0
- package/dist/tests/fourslash/findallreferences.sourceAndStub.classPropertyReadOnly.fourslash.js.map +1 -0
- package/dist/tests/fourslash/findallreferences.sourceAndStub.classPropertyReadWrite.fourslash.skip.d.ts +1 -0
- package/dist/tests/fourslash/findallreferences.sourceAndStub.classPropertyReadWrite.fourslash.skip.js +44 -0
- package/dist/tests/fourslash/findallreferences.sourceAndStub.classPropertyReadWrite.fourslash.skip.js.map +1 -0
- package/dist/tests/fourslash/findallreferences.sourceAndStub.function.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/findallreferences.sourceAndStub.function.fourslash.js +31 -0
- package/dist/tests/fourslash/findallreferences.sourceAndStub.function.fourslash.js.map +1 -0
- package/dist/tests/fourslash/findallreferences.variable.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/findallreferences.variable.fourslash.js +22 -0
- package/dist/tests/fourslash/findallreferences.variable.fourslash.js.map +1 -0
- package/dist/tests/fourslash/fourslash.d.ts +301 -0
- package/dist/tests/fourslash/fourslash.js +25 -0
- package/dist/tests/fourslash/fourslash.js.map +1 -0
- package/dist/tests/fourslash/highlightreferences.attributes.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/highlightreferences.attributes.fourslash.js +30 -0
- package/dist/tests/fourslash/highlightreferences.attributes.fourslash.js.map +1 -0
- package/dist/tests/fourslash/hover.builtinDocstrings.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/hover.builtinDocstrings.fourslash.js +63 -0
- package/dist/tests/fourslash/hover.builtinDocstrings.fourslash.js.map +1 -0
- package/dist/tests/fourslash/hover.classNoInit.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/hover.classNoInit.fourslash.js +14 -0
- package/dist/tests/fourslash/hover.classNoInit.fourslash.js.map +1 -0
- package/dist/tests/fourslash/hover.docFromScr.stringFormat.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/hover.docFromScr.stringFormat.fourslash.js +47 -0
- package/dist/tests/fourslash/hover.docFromScr.stringFormat.fourslash.js.map +1 -0
- package/dist/tests/fourslash/hover.docFromSrc.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/hover.docFromSrc.fourslash.js +77 -0
- package/dist/tests/fourslash/hover.docFromSrc.fourslash.js.map +1 -0
- package/dist/tests/fourslash/hover.docFromSrc.pkg-vs-module1.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/hover.docFromSrc.pkg-vs-module1.fourslash.js +22 -0
- package/dist/tests/fourslash/hover.docFromSrc.pkg-vs-module1.fourslash.js.map +1 -0
- package/dist/tests/fourslash/hover.docFromSrc.pkg-vs-module2.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/hover.docFromSrc.pkg-vs-module2.fourslash.js +22 -0
- package/dist/tests/fourslash/hover.docFromSrc.pkg-vs-module2.fourslash.js.map +1 -0
- package/dist/tests/fourslash/hover.docFromSrc.relativeImport1.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/hover.docFromSrc.relativeImport1.fourslash.js +21 -0
- package/dist/tests/fourslash/hover.docFromSrc.relativeImport1.fourslash.js.map +1 -0
- package/dist/tests/fourslash/hover.docFromSrc.relativeImport2.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/hover.docFromSrc.relativeImport2.fourslash.js +20 -0
- package/dist/tests/fourslash/hover.docFromSrc.relativeImport2.fourslash.js.map +1 -0
- package/dist/tests/fourslash/hover.docFromSrc.relativeImport3.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/hover.docFromSrc.relativeImport3.fourslash.js +38 -0
- package/dist/tests/fourslash/hover.docFromSrc.relativeImport3.fourslash.js.map +1 -0
- package/dist/tests/fourslash/hover.docFromSrc.stubs-package.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/hover.docFromSrc.stubs-package.fourslash.js +25 -0
- package/dist/tests/fourslash/hover.docFromSrc.stubs-package.fourslash.js.map +1 -0
- package/dist/tests/fourslash/hover.docFromSrc.typeshed.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/hover.docFromSrc.typeshed.fourslash.js +18 -0
- package/dist/tests/fourslash/hover.docFromSrc.typeshed.fourslash.js.map +1 -0
- package/dist/tests/fourslash/hover.docstring.links.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/hover.docstring.links.fourslash.js +12 -0
- package/dist/tests/fourslash/hover.docstring.links.fourslash.js.map +1 -0
- package/dist/tests/fourslash/hover.docstring.overloads.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/hover.docstring.overloads.fourslash.js +38 -0
- package/dist/tests/fourslash/hover.docstring.overloads.fourslash.js.map +1 -0
- package/dist/tests/fourslash/hover.docstring.split.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/hover.docstring.split.fourslash.js +24 -0
- package/dist/tests/fourslash/hover.docstring.split.fourslash.js.map +1 -0
- package/dist/tests/fourslash/hover.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/hover.fourslash.js +20 -0
- package/dist/tests/fourslash/hover.fourslash.js.map +1 -0
- package/dist/tests/fourslash/hover.import.django.view.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/hover.import.django.view.fourslash.js +23 -0
- package/dist/tests/fourslash/hover.import.django.view.fourslash.js.map +1 -0
- package/dist/tests/fourslash/hover.import.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/hover.import.fourslash.js +10 -0
- package/dist/tests/fourslash/hover.import.fourslash.js.map +1 -0
- package/dist/tests/fourslash/hover.inherited.docFromSrc.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/hover.inherited.docFromSrc.fourslash.js +61 -0
- package/dist/tests/fourslash/hover.inherited.docFromSrc.fourslash.js.map +1 -0
- package/dist/tests/fourslash/hover.inherited.docFromSrcWithStub.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/hover.inherited.docFromSrcWithStub.fourslash.js +51 -0
- package/dist/tests/fourslash/hover.inherited.docFromSrcWithStub.fourslash.js.map +1 -0
- package/dist/tests/fourslash/hover.inherited.docFromStub.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/hover.inherited.docFromStub.fourslash.js +40 -0
- package/dist/tests/fourslash/hover.inherited.docFromStub.fourslash.js.map +1 -0
- package/dist/tests/fourslash/hover.inherited.overload.docFromSrcWithStub.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/hover.inherited.overload.docFromSrcWithStub.fourslash.js +43 -0
- package/dist/tests/fourslash/hover.inherited.overload.docFromSrcWithStub.fourslash.js.map +1 -0
- package/dist/tests/fourslash/hover.inherited.overload.docFromStub.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/hover.inherited.overload.docFromStub.fourslash.js +44 -0
- package/dist/tests/fourslash/hover.inherited.overload.docFromStub.fourslash.js.map +1 -0
- package/dist/tests/fourslash/hover.inherited.property.docFromSrcWithStub.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/hover.inherited.property.docFromSrcWithStub.fourslash.js +84 -0
- package/dist/tests/fourslash/hover.inherited.property.docFromSrcWithStub.fourslash.js.map +1 -0
- package/dist/tests/fourslash/hover.inherited.property.docFromStub.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/hover.inherited.property.docFromStub.fourslash.js +88 -0
- package/dist/tests/fourslash/hover.inherited.property.docFromStub.fourslash.js.map +1 -0
- package/dist/tests/fourslash/hover.init.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/hover.init.fourslash.js +38 -0
- package/dist/tests/fourslash/hover.init.fourslash.js.map +1 -0
- package/dist/tests/fourslash/hover.libCodeAndStub.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/hover.libCodeAndStub.fourslash.js +49 -0
- package/dist/tests/fourslash/hover.libCodeAndStub.fourslash.js.map +1 -0
- package/dist/tests/fourslash/hover.libCodeNoStub.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/hover.libCodeNoStub.fourslash.js +39 -0
- package/dist/tests/fourslash/hover.libCodeNoStub.fourslash.js.map +1 -0
- package/dist/tests/fourslash/hover.libStub.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/hover.libStub.fourslash.js +39 -0
- package/dist/tests/fourslash/hover.libStub.fourslash.js.map +1 -0
- package/dist/tests/fourslash/hover.optionalAliasParameter.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/hover.optionalAliasParameter.fourslash.js +14 -0
- package/dist/tests/fourslash/hover.optionalAliasParameter.fourslash.js.map +1 -0
- package/dist/tests/fourslash/hover.plainText.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/hover.plainText.fourslash.js +20 -0
- package/dist/tests/fourslash/hover.plainText.fourslash.js.map +1 -0
- package/dist/tests/fourslash/hover.typedDict.key.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/hover.typedDict.key.fourslash.js +50 -0
- package/dist/tests/fourslash/hover.typedDict.key.fourslash.js.map +1 -0
- package/dist/tests/fourslash/hover.variable.docString.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/hover.variable.docString.fourslash.js +35 -0
- package/dist/tests/fourslash/hover.variable.docString.fourslash.js.map +1 -0
- package/dist/tests/fourslash/hover.wildcardimports.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/hover.wildcardimports.fourslash.js +73 -0
- package/dist/tests/fourslash/hover.wildcardimports.fourslash.js.map +1 -0
- package/dist/tests/fourslash/import.publicSymbols.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/import.publicSymbols.fourslash.js +63 -0
- package/dist/tests/fourslash/import.publicSymbols.fourslash.js.map +1 -0
- package/dist/tests/fourslash/import.pytyped.dunderAll.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/import.pytyped.dunderAll.fourslash.js +72 -0
- package/dist/tests/fourslash/import.pytyped.dunderAll.fourslash.js.map +1 -0
- package/dist/tests/fourslash/import.pytyped.privateSymbols.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/import.pytyped.privateSymbols.fourslash.js +61 -0
- package/dist/tests/fourslash/import.pytyped.privateSymbols.fourslash.js.map +1 -0
- package/dist/tests/fourslash/import.pytyped.typeCheckingBasic.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/import.pytyped.typeCheckingBasic.fourslash.js +35 -0
- package/dist/tests/fourslash/import.pytyped.typeCheckingBasic.fourslash.js.map +1 -0
- package/dist/tests/fourslash/import.pytyped.typeCheckingOff.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/import.pytyped.typeCheckingOff.fourslash.js +35 -0
- package/dist/tests/fourslash/import.pytyped.typeCheckingOff.fourslash.js.map +1 -0
- package/dist/tests/fourslash/import.wildcard.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/import.wildcard.fourslash.js +24 -0
- package/dist/tests/fourslash/import.wildcard.fourslash.js.map +1 -0
- package/dist/tests/fourslash/importnotresolved.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/importnotresolved.fourslash.js +13 -0
- package/dist/tests/fourslash/importnotresolved.fourslash.js.map +1 -0
- package/dist/tests/fourslash/missingModuleSource.disablingInStrictMode.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/missingModuleSource.disablingInStrictMode.fourslash.js +18 -0
- package/dist/tests/fourslash/missingModuleSource.disablingInStrictMode.fourslash.js.map +1 -0
- package/dist/tests/fourslash/missingModuleSource.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/missingModuleSource.fourslash.js +13 -0
- package/dist/tests/fourslash/missingModuleSource.fourslash.js.map +1 -0
- package/dist/tests/fourslash/missingTypeStub.codeAction.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/missingTypeStub.codeAction.fourslash.js +31 -0
- package/dist/tests/fourslash/missingTypeStub.codeAction.fourslash.js.map +1 -0
- package/dist/tests/fourslash/missingTypeStub.command.multipart.fourslash.d.ts +7 -0
- package/dist/tests/fourslash/missingTypeStub.command.multipart.fourslash.js +44 -0
- package/dist/tests/fourslash/missingTypeStub.command.multipart.fourslash.js.map +1 -0
- package/dist/tests/fourslash/missingTypeStub.command.singlefile.fourslash.d.ts +7 -0
- package/dist/tests/fourslash/missingTypeStub.command.singlefile.fourslash.js +35 -0
- package/dist/tests/fourslash/missingTypeStub.command.singlefile.fourslash.js.map +1 -0
- package/dist/tests/fourslash/missingTypeStub.command.singlepart.fourslash.d.ts +7 -0
- package/dist/tests/fourslash/missingTypeStub.command.singlepart.fourslash.js +35 -0
- package/dist/tests/fourslash/missingTypeStub.command.singlepart.fourslash.js.map +1 -0
- package/dist/tests/fourslash/missingTypeStub.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/missingTypeStub.fourslash.js +18 -0
- package/dist/tests/fourslash/missingTypeStub.fourslash.js.map +1 -0
- package/dist/tests/fourslash/missingTypeStub.invokeCodeAction.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/missingTypeStub.invokeCodeAction.fourslash.js +34 -0
- package/dist/tests/fourslash/missingTypeStub.invokeCodeAction.fourslash.js.map +1 -0
- package/dist/tests/fourslash/noerrors.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/noerrors.fourslash.js +9 -0
- package/dist/tests/fourslash/noerrors.fourslash.js.map +1 -0
- package/dist/tests/fourslash/orderImports1.command.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/orderImports1.command.fourslash.js +17 -0
- package/dist/tests/fourslash/orderImports1.command.fourslash.js.map +1 -0
- package/dist/tests/fourslash/orderImports2.command.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/orderImports2.command.fourslash.js +21 -0
- package/dist/tests/fourslash/orderImports2.command.fourslash.js.map +1 -0
- package/dist/tests/fourslash/rename.externallyHidden.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/rename.externallyHidden.fourslash.js +23 -0
- package/dist/tests/fourslash/rename.externallyHidden.fourslash.js.map +1 -0
- package/dist/tests/fourslash/rename.externallyHidden.params.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/rename.externallyHidden.params.fourslash.js +23 -0
- package/dist/tests/fourslash/rename.externallyHidden.params.fourslash.js.map +1 -0
- package/dist/tests/fourslash/rename.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/rename.fourslash.js +26 -0
- package/dist/tests/fourslash/rename.fourslash.js.map +1 -0
- package/dist/tests/fourslash/rename.library.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/rename.library.fourslash.js +26 -0
- package/dist/tests/fourslash/rename.library.fourslash.js.map +1 -0
- package/dist/tests/fourslash/rename.library.sourceAndStub.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/rename.library.sourceAndStub.fourslash.js +29 -0
- package/dist/tests/fourslash/rename.library.sourceAndStub.fourslash.js.map +1 -0
- package/dist/tests/fourslash/rename.multipleDecl.fourslash.d.ts +2 -0
- package/dist/tests/fourslash/rename.multipleDecl.fourslash.js +19 -0
- package/dist/tests/fourslash/rename.multipleDecl.fourslash.js.map +1 -0
- package/dist/tests/fourslash/rename.sourceAndStub.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/rename.sourceAndStub.fourslash.js +33 -0
- package/dist/tests/fourslash/rename.sourceAndStub.fourslash.js.map +1 -0
- package/dist/tests/fourslash/rename.string.excluded.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/rename.string.excluded.fourslash.js +39 -0
- package/dist/tests/fourslash/rename.string.excluded.fourslash.js.map +1 -0
- package/dist/tests/fourslash/rename.string.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/rename.string.fourslash.js +25 -0
- package/dist/tests/fourslash/rename.string.fourslash.js.map +1 -0
- package/dist/tests/fourslash/signature.builtinDocstrings.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/signature.builtinDocstrings.fourslash.js +62 -0
- package/dist/tests/fourslash/signature.builtinDocstrings.fourslash.js.map +1 -0
- package/dist/tests/fourslash/signature.complicated.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/signature.complicated.fourslash.js +97 -0
- package/dist/tests/fourslash/signature.complicated.fourslash.js.map +1 -0
- package/dist/tests/fourslash/signature.cornercases.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/signature.cornercases.fourslash.js +22 -0
- package/dist/tests/fourslash/signature.cornercases.fourslash.js.map +1 -0
- package/dist/tests/fourslash/signature.docstrings.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/signature.docstrings.fourslash.js +42 -0
- package/dist/tests/fourslash/signature.docstrings.fourslash.js.map +1 -0
- package/dist/tests/fourslash/signature.docstrings.overloaded.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/signature.docstrings.overloaded.fourslash.js +49 -0
- package/dist/tests/fourslash/signature.docstrings.overloaded.fourslash.js.map +1 -0
- package/dist/tests/fourslash/signature.docstrings.wildcardimports.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/signature.docstrings.wildcardimports.fourslash.js +115 -0
- package/dist/tests/fourslash/signature.docstrings.wildcardimports.fourslash.js.map +1 -0
- package/dist/tests/fourslash/signature.overload.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/signature.overload.fourslash.js +63 -0
- package/dist/tests/fourslash/signature.overload.fourslash.js.map +1 -0
- package/dist/tests/fourslash/signature.simple.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/signature.simple.fourslash.js +104 -0
- package/dist/tests/fourslash/signature.simple.fourslash.js.map +1 -0
- package/dist/tests/harness/fourslash/fourSlashParser.d.ts +10 -0
- package/dist/tests/harness/fourslash/fourSlashParser.js +347 -0
- package/dist/tests/harness/fourslash/fourSlashParser.js.map +1 -0
- package/dist/tests/harness/fourslash/fourSlashTypes.d.ts +81 -0
- package/dist/tests/harness/fourslash/fourSlashTypes.js +65 -0
- package/dist/tests/harness/fourslash/fourSlashTypes.js.map +1 -0
- package/dist/tests/harness/fourslash/runner.d.ts +20 -0
- package/dist/tests/harness/fourslash/runner.js +93 -0
- package/dist/tests/harness/fourslash/runner.js.map +1 -0
- package/dist/tests/harness/fourslash/testLanguageService.d.ts +40 -0
- package/dist/tests/harness/fourslash/testLanguageService.js +120 -0
- package/dist/tests/harness/fourslash/testLanguageService.js.map +1 -0
- package/dist/tests/harness/fourslash/testState.Consts.d.ts +11 -0
- package/dist/tests/harness/fourslash/testState.Consts.js +50 -0
- package/dist/tests/harness/fourslash/testState.Consts.js.map +1 -0
- package/dist/tests/harness/fourslash/testState.d.ts +232 -0
- package/dist/tests/harness/fourslash/testState.js +1381 -0
- package/dist/tests/harness/fourslash/testState.js.map +1 -0
- package/dist/tests/harness/testAccessHost.d.ts +8 -0
- package/dist/tests/harness/testAccessHost.js +26 -0
- package/dist/tests/harness/testAccessHost.js.map +1 -0
- package/dist/tests/harness/testHost.d.ts +16 -0
- package/dist/tests/harness/testHost.js +161 -0
- package/dist/tests/harness/testHost.js.map +1 -0
- package/dist/tests/harness/utils.d.ts +74 -0
- package/dist/tests/harness/utils.js +328 -0
- package/dist/tests/harness/utils.js.map +1 -0
- package/dist/tests/harness/vfs/factory.d.ts +32 -0
- package/dist/tests/harness/vfs/factory.js +173 -0
- package/dist/tests/harness/vfs/factory.js.map +1 -0
- package/dist/tests/harness/vfs/filesystem.d.ts +430 -0
- package/dist/tests/harness/vfs/filesystem.js +1455 -0
- package/dist/tests/harness/vfs/filesystem.js.map +1 -0
- package/dist/tests/harness/vfs/pathValidation.d.ts +24 -0
- package/dist/tests/harness/vfs/pathValidation.js +123 -0
- package/dist/tests/harness/vfs/pathValidation.js.map +1 -0
- package/dist/tests/importAdder.test.d.ts +1 -0
- package/dist/tests/importAdder.test.js +1192 -0
- package/dist/tests/importAdder.test.js.map +1 -0
- package/dist/tests/importResolver.test.d.ts +1 -0
- package/dist/tests/importResolver.test.js +450 -0
- package/dist/tests/importResolver.test.js.map +1 -0
- package/dist/tests/importStatementUtils.test.d.ts +1 -0
- package/dist/tests/importStatementUtils.test.js +371 -0
- package/dist/tests/importStatementUtils.test.js.map +1 -0
- package/dist/tests/indentationUtils.ptvs.test.d.ts +1 -0
- package/dist/tests/indentationUtils.ptvs.test.js +324 -0
- package/dist/tests/indentationUtils.ptvs.test.js.map +1 -0
- package/dist/tests/indentationUtils.reindent.test.d.ts +1 -0
- package/dist/tests/indentationUtils.reindent.test.js +332 -0
- package/dist/tests/indentationUtils.reindent.test.js.map +1 -0
- package/dist/tests/indentationUtils.test.d.ts +1 -0
- package/dist/tests/indentationUtils.test.js +375 -0
- package/dist/tests/indentationUtils.test.js.map +1 -0
- package/dist/tests/ipythonMode.test.d.ts +1 -0
- package/dist/tests/ipythonMode.test.js +303 -0
- package/dist/tests/ipythonMode.test.js.map +1 -0
- package/dist/tests/localizer.test.d.ts +1 -0
- package/dist/tests/localizer.test.js +64 -0
- package/dist/tests/localizer.test.js.map +1 -0
- package/dist/tests/parseTreeUtils.test.d.ts +1 -0
- package/dist/tests/parseTreeUtils.test.js +228 -0
- package/dist/tests/parseTreeUtils.test.js.map +1 -0
- package/dist/tests/parser.test.d.ts +1 -0
- package/dist/tests/parser.test.js +101 -0
- package/dist/tests/parser.test.js.map +1 -0
- package/dist/tests/pathUtils.test.d.ts +1 -0
- package/dist/tests/pathUtils.test.js +253 -0
- package/dist/tests/pathUtils.test.js.map +1 -0
- package/dist/tests/pyrightFileSystem.test.d.ts +1 -0
- package/dist/tests/pyrightFileSystem.test.js +152 -0
- package/dist/tests/pyrightFileSystem.test.js.map +1 -0
- package/dist/tests/renameModule.folder.test.d.ts +1 -0
- package/dist/tests/renameModule.folder.test.js +229 -0
- package/dist/tests/renameModule.folder.test.js.map +1 -0
- package/dist/tests/renameModule.fromImports.test.d.ts +1 -0
- package/dist/tests/renameModule.fromImports.test.js +790 -0
- package/dist/tests/renameModule.fromImports.test.js.map +1 -0
- package/dist/tests/renameModule.imports.test.d.ts +1 -0
- package/dist/tests/renameModule.imports.test.js +380 -0
- package/dist/tests/renameModule.imports.test.js.map +1 -0
- package/dist/tests/renameModule.misc.test.d.ts +1 -0
- package/dist/tests/renameModule.misc.test.js +615 -0
- package/dist/tests/renameModule.misc.test.js.map +1 -0
- package/dist/tests/renameModule.relativePath.test.d.ts +1 -0
- package/dist/tests/renameModule.relativePath.test.js +231 -0
- package/dist/tests/renameModule.relativePath.test.js.map +1 -0
- package/dist/tests/renameModuleTestUtils.d.ts +4 -0
- package/dist/tests/renameModuleTestUtils.js +148 -0
- package/dist/tests/renameModuleTestUtils.js.map +1 -0
- package/dist/tests/sourceFile.test.d.ts +1 -0
- package/dist/tests/sourceFile.test.js +25 -0
- package/dist/tests/sourceFile.test.js.map +1 -0
- package/dist/tests/stringUtils.test.d.ts +1 -0
- package/dist/tests/stringUtils.test.js +69 -0
- package/dist/tests/stringUtils.test.js.map +1 -0
- package/dist/tests/symbolNameUtils.test.d.ts +1 -0
- package/dist/tests/symbolNameUtils.test.js +83 -0
- package/dist/tests/symbolNameUtils.test.js.map +1 -0
- package/dist/tests/testState.test.d.ts +1 -0
- package/dist/tests/testState.test.js +521 -0
- package/dist/tests/testState.test.js.map +1 -0
- package/dist/tests/testUtils.d.ts +27 -0
- package/dist/tests/testUtils.js +213 -0
- package/dist/tests/testUtils.js.map +1 -0
- package/dist/tests/tokenizer.test.d.ts +1 -0
- package/dist/tests/tokenizer.test.js +1277 -0
- package/dist/tests/tokenizer.test.js.map +1 -0
- package/dist/tests/typeEvaluator1.test.d.ts +1 -0
- package/dist/tests/typeEvaluator1.test.js +1023 -0
- package/dist/tests/typeEvaluator1.test.js.map +1 -0
- package/dist/tests/typeEvaluator2.test.d.ts +1 -0
- package/dist/tests/typeEvaluator2.test.js +869 -0
- package/dist/tests/typeEvaluator2.test.js.map +1 -0
- package/dist/tests/typeEvaluator3.test.d.ts +1 -0
- package/dist/tests/typeEvaluator3.test.js +915 -0
- package/dist/tests/typeEvaluator3.test.js.map +1 -0
- package/dist/tests/typeEvaluator4.test.d.ts +1 -0
- package/dist/tests/typeEvaluator4.test.js +901 -0
- package/dist/tests/typeEvaluator4.test.js.map +1 -0
- package/dist/tests/updateSymbolReference.test.d.ts +1 -0
- package/dist/tests/updateSymbolReference.test.js +980 -0
- package/dist/tests/updateSymbolReference.test.js.map +1 -0
- package/dist/tests/zipfs.test.d.ts +1 -0
- package/dist/tests/zipfs.test.js +112 -0
- package/dist/tests/zipfs.test.js.map +1 -0
- package/dist/workspaceMap.d.ts +6 -0
- package/dist/workspaceMap.js +73 -0
- package/dist/workspaceMap.js.map +1 -0
- package/package.json +45 -0
@@ -0,0 +1,3828 @@
|
|
1
|
+
"use strict";
|
2
|
+
/*
|
3
|
+
* checker.ts
|
4
|
+
* Copyright (c) Microsoft Corporation.
|
5
|
+
* Licensed under the MIT license.
|
6
|
+
* Author: Eric Traut
|
7
|
+
*
|
8
|
+
* A parse tree walker that performs static type checking for
|
9
|
+
* a source file. Most of its work is performed by the type
|
10
|
+
* evaluator, but this module touches every node in the file
|
11
|
+
* to ensure that all statements and expressions are evaluated
|
12
|
+
* and checked. It also performs some additional checks that
|
13
|
+
* cannot (or should not be) performed lazily.
|
14
|
+
*/
|
15
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
16
|
+
if (k2 === undefined) k2 = k;
|
17
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
18
|
+
}) : (function(o, m, k, k2) {
|
19
|
+
if (k2 === undefined) k2 = k;
|
20
|
+
o[k2] = m[k];
|
21
|
+
}));
|
22
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
23
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
24
|
+
}) : function(o, v) {
|
25
|
+
o["default"] = v;
|
26
|
+
});
|
27
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
28
|
+
if (mod && mod.__esModule) return mod;
|
29
|
+
var result = {};
|
30
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
31
|
+
__setModuleDefault(result, mod);
|
32
|
+
return result;
|
33
|
+
};
|
34
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
35
|
+
exports.Checker = void 0;
|
36
|
+
const debug_1 = require("../common/debug");
|
37
|
+
const diagnostic_1 = require("../common/diagnostic");
|
38
|
+
const diagnosticRules_1 = require("../common/diagnosticRules");
|
39
|
+
const pathUtils_1 = require("../common/pathUtils");
|
40
|
+
const pythonVersion_1 = require("../common/pythonVersion");
|
41
|
+
const textRange_1 = require("../common/textRange");
|
42
|
+
const localize_1 = require("../localization/localize");
|
43
|
+
const parseNodes_1 = require("../parser/parseNodes");
|
44
|
+
const stringTokenUtils_1 = require("../parser/stringTokenUtils");
|
45
|
+
const AnalyzerNodeInfo = __importStar(require("./analyzerNodeInfo"));
|
46
|
+
const declaration_1 = require("./declaration");
|
47
|
+
const declarationUtils_1 = require("./declarationUtils");
|
48
|
+
const importResolver_1 = require("./importResolver");
|
49
|
+
const importStatementUtils_1 = require("./importStatementUtils");
|
50
|
+
const ParseTreeUtils = __importStar(require("./parseTreeUtils"));
|
51
|
+
const parseTreeWalker_1 = require("./parseTreeWalker");
|
52
|
+
const patternMatching_1 = require("./patternMatching");
|
53
|
+
const protocols_1 = require("./protocols");
|
54
|
+
const scopeUtils_1 = require("./scopeUtils");
|
55
|
+
const sourceMapper_1 = require("./sourceMapper");
|
56
|
+
const staticExpressions_1 = require("./staticExpressions");
|
57
|
+
const SymbolNameUtils = __importStar(require("./symbolNameUtils"));
|
58
|
+
const symbolUtils_1 = require("./symbolUtils");
|
59
|
+
const typeEvaluator_1 = require("./typeEvaluator");
|
60
|
+
const types_1 = require("./types");
|
61
|
+
const typeUtils_1 = require("./typeUtils");
|
62
|
+
const typeVarContext_1 = require("./typeVarContext");
|
63
|
+
const deprecatedAliases = new Map([
|
64
|
+
['Tuple', { version: pythonVersion_1.PythonVersion.V3_9, fullName: 'builtins.tuple', replacementText: 'tuple' }],
|
65
|
+
['List', { version: pythonVersion_1.PythonVersion.V3_9, fullName: 'builtins.list', replacementText: 'list' }],
|
66
|
+
['Dict', { version: pythonVersion_1.PythonVersion.V3_9, fullName: 'builtins.dict', replacementText: 'dict' }],
|
67
|
+
['Set', { version: pythonVersion_1.PythonVersion.V3_9, fullName: 'builtins.set', replacementText: 'set' }],
|
68
|
+
['FrozenSet', { version: pythonVersion_1.PythonVersion.V3_9, fullName: 'builtins.frozenset', replacementText: 'frozenset' }],
|
69
|
+
['Type', { version: pythonVersion_1.PythonVersion.V3_9, fullName: 'builtins.type', replacementText: 'type' }],
|
70
|
+
['Deque', { version: pythonVersion_1.PythonVersion.V3_9, fullName: 'collections.deque', replacementText: 'collections.deque' }],
|
71
|
+
[
|
72
|
+
'DefaultDict',
|
73
|
+
{
|
74
|
+
version: pythonVersion_1.PythonVersion.V3_9,
|
75
|
+
fullName: 'collections.defaultdict',
|
76
|
+
replacementText: 'collections.defaultdict',
|
77
|
+
},
|
78
|
+
],
|
79
|
+
[
|
80
|
+
'OrderedDict',
|
81
|
+
{
|
82
|
+
version: pythonVersion_1.PythonVersion.V3_9,
|
83
|
+
fullName: 'collections.OrderedDict',
|
84
|
+
replacementText: 'collections.OrderedDict',
|
85
|
+
},
|
86
|
+
],
|
87
|
+
[
|
88
|
+
'Counter',
|
89
|
+
{ version: pythonVersion_1.PythonVersion.V3_9, fullName: 'collections.Counter', replacementText: 'collections.Counter' },
|
90
|
+
],
|
91
|
+
[
|
92
|
+
'ChainMap',
|
93
|
+
{ version: pythonVersion_1.PythonVersion.V3_9, fullName: 'collections.ChainMap', replacementText: 'collections.ChainMap' },
|
94
|
+
],
|
95
|
+
]);
|
96
|
+
const deprecatedSpecialForms = new Map([
|
97
|
+
['Optional', { version: pythonVersion_1.PythonVersion.V3_10, fullName: 'typing.Optional', replacementText: '| None' }],
|
98
|
+
['Union', { version: pythonVersion_1.PythonVersion.V3_10, fullName: 'typing.Union', replacementText: '|' }],
|
99
|
+
]);
|
100
|
+
// When enabled, this debug flag causes the code complexity of
|
101
|
+
// functions to be emitted.
|
102
|
+
const isPrintCodeComplexityEnabled = false;
|
103
|
+
class Checker extends parseTreeWalker_1.ParseTreeWalker {
|
104
|
+
constructor(_importResolver, _evaluator, _moduleNode) {
|
105
|
+
super();
|
106
|
+
this._importResolver = _importResolver;
|
107
|
+
this._evaluator = _evaluator;
|
108
|
+
this._moduleNode = _moduleNode;
|
109
|
+
this._isUnboundCheckSuppressed = false;
|
110
|
+
// A list of all nodes that are defined within the module that
|
111
|
+
// have their own scopes.
|
112
|
+
this._scopedNodes = [];
|
113
|
+
this._fileInfo = AnalyzerNodeInfo.getFileInfo(_moduleNode);
|
114
|
+
}
|
115
|
+
check() {
|
116
|
+
this._scopedNodes.push(this._moduleNode);
|
117
|
+
this._walkStatementsAndReportUnreachable(this._moduleNode.statements);
|
118
|
+
// Mark symbols accessed by __all__ as accessed.
|
119
|
+
const dunderAllInfo = AnalyzerNodeInfo.getDunderAllInfo(this._moduleNode);
|
120
|
+
if (dunderAllInfo) {
|
121
|
+
this._evaluator.markNamesAccessed(this._moduleNode, dunderAllInfo.names);
|
122
|
+
this._reportUnusedDunderAllSymbols(dunderAllInfo.stringNodes);
|
123
|
+
}
|
124
|
+
// Perform a one-time validation of symbols in all scopes
|
125
|
+
// defined in this module for things like unaccessed variables.
|
126
|
+
this._validateSymbolTables();
|
127
|
+
this._reportDuplicateImports();
|
128
|
+
MissingModuleSourceReporter.report(this._importResolver, this._evaluator, this._fileInfo, this._moduleNode);
|
129
|
+
}
|
130
|
+
walk(node) {
|
131
|
+
if (!AnalyzerNodeInfo.isCodeUnreachable(node)) {
|
132
|
+
super.walk(node);
|
133
|
+
}
|
134
|
+
else {
|
135
|
+
this._evaluator.suppressDiagnostics(node, () => {
|
136
|
+
super.walk(node);
|
137
|
+
});
|
138
|
+
}
|
139
|
+
}
|
140
|
+
visitSuite(node) {
|
141
|
+
this._walkStatementsAndReportUnreachable(node.statements);
|
142
|
+
return false;
|
143
|
+
}
|
144
|
+
visitStatementList(node) {
|
145
|
+
node.statements.forEach((statement) => {
|
146
|
+
if ((0, parseNodes_1.isExpressionNode)(statement)) {
|
147
|
+
// Evaluate the expression in case it wasn't otherwise evaluated
|
148
|
+
// through lazy analysis. This will mark referenced symbols as
|
149
|
+
// accessed and report any errors associated with it.
|
150
|
+
this._evaluator.getType(statement);
|
151
|
+
this._reportUnusedExpression(statement);
|
152
|
+
}
|
153
|
+
});
|
154
|
+
return true;
|
155
|
+
}
|
156
|
+
visitClass(node) {
|
157
|
+
const classTypeResult = this._evaluator.getTypeOfClass(node);
|
158
|
+
this.walk(node.suite);
|
159
|
+
this.walkMultiple(node.decorators);
|
160
|
+
this.walkMultiple(node.arguments);
|
161
|
+
if (classTypeResult) {
|
162
|
+
// Protocol classes cannot derive from non-protocol classes.
|
163
|
+
if (types_1.ClassType.isProtocolClass(classTypeResult.classType)) {
|
164
|
+
node.arguments.forEach((arg) => {
|
165
|
+
if (!arg.name) {
|
166
|
+
const baseClassType = this._evaluator.getType(arg.valueExpression);
|
167
|
+
if (baseClassType &&
|
168
|
+
(0, types_1.isInstantiableClass)(baseClassType) &&
|
169
|
+
!types_1.ClassType.isBuiltIn(baseClassType, 'Protocol') &&
|
170
|
+
!types_1.ClassType.isBuiltIn(baseClassType, 'Generic')) {
|
171
|
+
if (!types_1.ClassType.isProtocolClass(baseClassType)) {
|
172
|
+
this._evaluator.addError(localize_1.Localizer.Diagnostic.protocolBaseClass().format({
|
173
|
+
classType: this._evaluator.printType(classTypeResult.classType,
|
174
|
+
/* expandTypeAlias */ false),
|
175
|
+
baseType: this._evaluator.printType(baseClassType, /* expandTypeAlias */ false),
|
176
|
+
}), arg.valueExpression);
|
177
|
+
}
|
178
|
+
}
|
179
|
+
}
|
180
|
+
});
|
181
|
+
// If this is a generic protocol class, verify that its type variables
|
182
|
+
// have the proper variance.
|
183
|
+
this._validateProtocolTypeParamVariance(node, classTypeResult.classType);
|
184
|
+
}
|
185
|
+
// Skip the overrides check for stub files. Many of the built-in
|
186
|
+
// typeshed stub files trigger this diagnostic. Also skip the slots
|
187
|
+
// check because class variables declared in a stub file are
|
188
|
+
// interpreted as instance variables.
|
189
|
+
if (!this._fileInfo.isStubFile) {
|
190
|
+
this._validateBaseClassOverrides(classTypeResult.classType);
|
191
|
+
this._validateSlotsClassVarConflict(classTypeResult.classType);
|
192
|
+
}
|
193
|
+
this._validateMultipleInheritanceCompatibility(classTypeResult.classType, node.name);
|
194
|
+
this._validateConstructorConsistency(classTypeResult.classType);
|
195
|
+
this._validateFinalMemberOverrides(classTypeResult.classType);
|
196
|
+
this._validateInstanceVariableInitialization(classTypeResult.classType);
|
197
|
+
this._validateFinalClassNotAbstract(classTypeResult.classType, node);
|
198
|
+
this._validateDataClassPostInit(classTypeResult.classType, node);
|
199
|
+
this._validateProtocolCompatibility(classTypeResult.classType, node);
|
200
|
+
this._reportDuplicateEnumMembers(classTypeResult.classType);
|
201
|
+
if (types_1.ClassType.isTypedDictClass(classTypeResult.classType)) {
|
202
|
+
this._validateTypedDictClassSuite(node.suite);
|
203
|
+
}
|
204
|
+
if (types_1.ClassType.isEnumClass(classTypeResult.classType)) {
|
205
|
+
this._validateEnumClassOverride(node, classTypeResult.classType);
|
206
|
+
}
|
207
|
+
}
|
208
|
+
this._scopedNodes.push(node);
|
209
|
+
return false;
|
210
|
+
}
|
211
|
+
visitFunction(node) {
|
212
|
+
var _a;
|
213
|
+
const functionTypeResult = this._evaluator.getTypeOfFunction(node);
|
214
|
+
const containingClassNode = ParseTreeUtils.getEnclosingClass(node, /* stopAtFunction */ true);
|
215
|
+
if (functionTypeResult) {
|
216
|
+
// Track whether we have seen a *args: P.args parameter. Named
|
217
|
+
// parameters after this need to be flagged as an error.
|
218
|
+
let sawParamSpecArgs = false;
|
219
|
+
// Report any unknown or missing parameter types.
|
220
|
+
node.parameters.forEach((param, index) => {
|
221
|
+
if (param.name) {
|
222
|
+
// Determine whether this is a P.args parameter.
|
223
|
+
if (param.category === 1 /* VarArgList */) {
|
224
|
+
const annotationExpr = param.typeAnnotation || param.typeAnnotationComment;
|
225
|
+
if (annotationExpr &&
|
226
|
+
annotationExpr.nodeType === 35 /* MemberAccess */ &&
|
227
|
+
annotationExpr.memberName.value === 'args') {
|
228
|
+
const baseType = this._evaluator.getType(annotationExpr.leftExpression);
|
229
|
+
if (baseType && (0, types_1.isTypeVar)(baseType) && baseType.details.isParamSpec) {
|
230
|
+
sawParamSpecArgs = true;
|
231
|
+
}
|
232
|
+
}
|
233
|
+
}
|
234
|
+
else if (param.category === 2 /* VarArgDictionary */) {
|
235
|
+
sawParamSpecArgs = false;
|
236
|
+
}
|
237
|
+
}
|
238
|
+
if (param.name && param.category === 0 /* Simple */ && sawParamSpecArgs) {
|
239
|
+
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.namedParamAfterParamSpecArgs().format({ name: param.name.value }), param.name);
|
240
|
+
}
|
241
|
+
// Allow unknown and missing param types if the param is named '_'.
|
242
|
+
if (param.name && param.name.value !== '_') {
|
243
|
+
const functionTypeParam = functionTypeResult.functionType.details.parameters.find((p) => { var _a; return p.name === ((_a = param.name) === null || _a === void 0 ? void 0 : _a.value); });
|
244
|
+
if (functionTypeParam) {
|
245
|
+
const paramType = functionTypeParam.type;
|
246
|
+
if ((0, types_1.isUnknown)(paramType) ||
|
247
|
+
((0, types_1.isTypeVar)(paramType) &&
|
248
|
+
paramType.details.isSynthesized &&
|
249
|
+
!paramType.details.isSynthesizedSelf)) {
|
250
|
+
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportUnknownParameterType, diagnosticRules_1.DiagnosticRule.reportUnknownParameterType, localize_1.Localizer.Diagnostic.paramTypeUnknown().format({ paramName: param.name.value }), param.name);
|
251
|
+
}
|
252
|
+
else if ((0, typeUtils_1.isPartlyUnknown)(paramType)) {
|
253
|
+
const diagAddendum = new diagnostic_1.DiagnosticAddendum();
|
254
|
+
diagAddendum.addMessage(localize_1.Localizer.DiagnosticAddendum.paramType().format({
|
255
|
+
paramType: this._evaluator.printType(paramType, /* expandTypeAlias */ true),
|
256
|
+
}));
|
257
|
+
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportUnknownParameterType, diagnosticRules_1.DiagnosticRule.reportUnknownParameterType, localize_1.Localizer.Diagnostic.paramTypePartiallyUnknown().format({
|
258
|
+
paramName: param.name.value,
|
259
|
+
}) + diagAddendum.getString(), param.name);
|
260
|
+
}
|
261
|
+
let hasAnnotation = false;
|
262
|
+
if (functionTypeParam.typeAnnotation) {
|
263
|
+
hasAnnotation = true;
|
264
|
+
}
|
265
|
+
else {
|
266
|
+
// See if this is a "self" and "cls" parameter. They are exempt from this rule.
|
267
|
+
if ((0, types_1.isTypeVar)(paramType) && paramType.details.isSynthesizedSelf) {
|
268
|
+
hasAnnotation = true;
|
269
|
+
}
|
270
|
+
}
|
271
|
+
if (!hasAnnotation) {
|
272
|
+
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportMissingParameterType, diagnosticRules_1.DiagnosticRule.reportMissingParameterType, localize_1.Localizer.Diagnostic.paramAnnotationMissing().format({ name: param.name.value }), param.name);
|
273
|
+
}
|
274
|
+
}
|
275
|
+
}
|
276
|
+
// If it's a stub file, report an issue of the default value expression is not "...".
|
277
|
+
if (param.defaultValue && this._fileInfo.isStubFile) {
|
278
|
+
const defaultValueType = this._evaluator.getType(param.defaultValue);
|
279
|
+
if (!defaultValueType || !(0, typeUtils_1.isEllipsisType)(defaultValueType)) {
|
280
|
+
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportInvalidStubStatement, diagnosticRules_1.DiagnosticRule.reportInvalidStubStatement, localize_1.Localizer.Diagnostic.defaultValueNotEllipsis(), param.defaultValue);
|
281
|
+
}
|
282
|
+
}
|
283
|
+
});
|
284
|
+
// Check for invalid use of ParamSpec P.args and P.kwargs.
|
285
|
+
const paramSpecParams = functionTypeResult.functionType.details.parameters.filter((param) => {
|
286
|
+
if (param.typeAnnotation && (0, types_1.isTypeVar)(param.type) && (0, types_1.isParamSpec)(param.type)) {
|
287
|
+
if (param.category !== 0 /* Simple */ && param.name && param.type.paramSpecAccess) {
|
288
|
+
return true;
|
289
|
+
}
|
290
|
+
}
|
291
|
+
return false;
|
292
|
+
});
|
293
|
+
if (paramSpecParams.length === 1 && paramSpecParams[0].typeAnnotation) {
|
294
|
+
this._evaluator.addError(localize_1.Localizer.Diagnostic.paramSpecArgsKwargsUsage(), paramSpecParams[0].typeAnnotation);
|
295
|
+
}
|
296
|
+
// If this is a stub, ensure that the return type is specified.
|
297
|
+
if (this._fileInfo.isStubFile) {
|
298
|
+
const returnAnnotation = node.returnTypeAnnotation || ((_a = node.functionAnnotationComment) === null || _a === void 0 ? void 0 : _a.returnTypeAnnotation);
|
299
|
+
if (!returnAnnotation) {
|
300
|
+
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportUnknownParameterType, diagnosticRules_1.DiagnosticRule.reportUnknownParameterType, localize_1.Localizer.Diagnostic.returnTypeUnknown(), node.name);
|
301
|
+
}
|
302
|
+
}
|
303
|
+
if (containingClassNode) {
|
304
|
+
this._validateMethod(node, functionTypeResult.functionType, containingClassNode);
|
305
|
+
}
|
306
|
+
}
|
307
|
+
node.parameters.forEach((param, index) => {
|
308
|
+
if (param.defaultValue) {
|
309
|
+
this.walk(param.defaultValue);
|
310
|
+
}
|
311
|
+
if (param.typeAnnotation) {
|
312
|
+
this.walk(param.typeAnnotation);
|
313
|
+
}
|
314
|
+
if (param.typeAnnotationComment) {
|
315
|
+
this.walk(param.typeAnnotationComment);
|
316
|
+
}
|
317
|
+
if (functionTypeResult) {
|
318
|
+
const annotationNode = param.typeAnnotation || param.typeAnnotationComment;
|
319
|
+
if (annotationNode && index < functionTypeResult.functionType.details.parameters.length) {
|
320
|
+
const paramType = functionTypeResult.functionType.details.parameters[index].type;
|
321
|
+
if ((0, types_1.isTypeVar)(paramType) &&
|
322
|
+
paramType.details.variance === 1 /* Covariant */ &&
|
323
|
+
!paramType.details.isSynthesized &&
|
324
|
+
functionTypeResult.functionType.details.name !== '__init__') {
|
325
|
+
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.paramTypeCovariant(), annotationNode);
|
326
|
+
}
|
327
|
+
}
|
328
|
+
}
|
329
|
+
});
|
330
|
+
if (node.returnTypeAnnotation) {
|
331
|
+
this.walk(node.returnTypeAnnotation);
|
332
|
+
}
|
333
|
+
if (node.functionAnnotationComment) {
|
334
|
+
this.walk(node.functionAnnotationComment);
|
335
|
+
if (this._fileInfo.diagnosticRuleSet.reportTypeCommentUsage !== 'none' &&
|
336
|
+
this._fileInfo.executionEnvironment.pythonVersion >= pythonVersion_1.PythonVersion.V3_5) {
|
337
|
+
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportTypeCommentUsage, diagnosticRules_1.DiagnosticRule.reportTypeCommentUsage, localize_1.Localizer.Diagnostic.typeCommentDeprecated(), node.functionAnnotationComment);
|
338
|
+
}
|
339
|
+
}
|
340
|
+
this.walkMultiple(node.decorators);
|
341
|
+
node.parameters.forEach((param) => {
|
342
|
+
if (param.name) {
|
343
|
+
this.walk(param.name);
|
344
|
+
}
|
345
|
+
});
|
346
|
+
const codeComplexity = AnalyzerNodeInfo.getCodeFlowComplexity(node);
|
347
|
+
const isTooComplexToAnalyze = codeComplexity > typeEvaluator_1.maxCodeComplexity;
|
348
|
+
if (isPrintCodeComplexityEnabled) {
|
349
|
+
console.log(`Code complexity of function ${node.name.value} is ${codeComplexity.toString()}`);
|
350
|
+
}
|
351
|
+
if (isTooComplexToAnalyze) {
|
352
|
+
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.codeTooComplexToAnalyze(), node.name);
|
353
|
+
}
|
354
|
+
else {
|
355
|
+
this.walk(node.suite);
|
356
|
+
}
|
357
|
+
if (functionTypeResult) {
|
358
|
+
// Validate that the function returns the declared type.
|
359
|
+
if (!isTooComplexToAnalyze) {
|
360
|
+
this._validateFunctionReturn(node, functionTypeResult.functionType);
|
361
|
+
}
|
362
|
+
// Verify common dunder signatures.
|
363
|
+
this._validateDunderSignatures(node, functionTypeResult.functionType, containingClassNode !== undefined);
|
364
|
+
// Verify that strict type guard functions don't violate the constraints
|
365
|
+
// of strict type guards.
|
366
|
+
this._validateStrictTypeGuardFunction(node, functionTypeResult.functionType, containingClassNode !== undefined);
|
367
|
+
this._validateFunctionTypeVarUsage(node, functionTypeResult.functionType);
|
368
|
+
}
|
369
|
+
// If we're at the module level within a stub file, report a diagnostic
|
370
|
+
// if there is a '__getattr__' function defined when in strict mode.
|
371
|
+
// This signifies an incomplete stub file that obscures type errors.
|
372
|
+
if (this._fileInfo.isStubFile && node.name.value === '__getattr__') {
|
373
|
+
const scope = (0, scopeUtils_1.getScopeForNode)(node);
|
374
|
+
if ((scope === null || scope === void 0 ? void 0 : scope.type) === 3 /* Module */) {
|
375
|
+
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportIncompleteStub, diagnosticRules_1.DiagnosticRule.reportIncompleteStub, localize_1.Localizer.Diagnostic.stubUsesGetAttr(), node.name);
|
376
|
+
}
|
377
|
+
}
|
378
|
+
this._scopedNodes.push(node);
|
379
|
+
if (functionTypeResult && (0, types_1.isOverloadedFunction)(functionTypeResult.decoratedType)) {
|
380
|
+
const overloads = functionTypeResult.decoratedType.overloads;
|
381
|
+
if (overloads.length > 1) {
|
382
|
+
const maxOverloadConsistencyCheckLength = 100;
|
383
|
+
// The check is n^2 in time, so if the number of overloads
|
384
|
+
// is very large (which can happen for some generated code),
|
385
|
+
// skip this check to avoid quadratic analysis time.
|
386
|
+
if (overloads.length < maxOverloadConsistencyCheckLength) {
|
387
|
+
this._validateOverloadConsistency(node, overloads[overloads.length - 1], overloads.slice(0, overloads.length - 1));
|
388
|
+
}
|
389
|
+
}
|
390
|
+
}
|
391
|
+
return false;
|
392
|
+
}
|
393
|
+
visitLambda(node) {
|
394
|
+
this._evaluator.getType(node);
|
395
|
+
// Walk the children.
|
396
|
+
this.walkMultiple([...node.parameters, node.expression]);
|
397
|
+
node.parameters.forEach((param) => {
|
398
|
+
if (param.name) {
|
399
|
+
const paramType = this._evaluator.getType(param.name);
|
400
|
+
if (paramType) {
|
401
|
+
if ((0, types_1.isUnknown)(paramType)) {
|
402
|
+
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportUnknownLambdaType, diagnosticRules_1.DiagnosticRule.reportUnknownLambdaType, localize_1.Localizer.Diagnostic.paramTypeUnknown().format({ paramName: param.name.value }), param.name);
|
403
|
+
}
|
404
|
+
else if ((0, typeUtils_1.isPartlyUnknown)(paramType)) {
|
405
|
+
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportUnknownLambdaType, diagnosticRules_1.DiagnosticRule.reportUnknownLambdaType, localize_1.Localizer.Diagnostic.paramTypePartiallyUnknown().format({ paramName: param.name.value }), param.name);
|
406
|
+
}
|
407
|
+
}
|
408
|
+
}
|
409
|
+
});
|
410
|
+
const returnType = this._evaluator.getType(node.expression);
|
411
|
+
if (returnType) {
|
412
|
+
if ((0, types_1.isUnknown)(returnType)) {
|
413
|
+
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportUnknownLambdaType, diagnosticRules_1.DiagnosticRule.reportUnknownLambdaType, localize_1.Localizer.Diagnostic.lambdaReturnTypeUnknown(), node.expression);
|
414
|
+
}
|
415
|
+
else if ((0, typeUtils_1.isPartlyUnknown)(returnType)) {
|
416
|
+
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportUnknownLambdaType, diagnosticRules_1.DiagnosticRule.reportUnknownLambdaType, localize_1.Localizer.Diagnostic.lambdaReturnTypePartiallyUnknown().format({
|
417
|
+
returnType: this._evaluator.printType(returnType, /* expandTypeAlias */ true),
|
418
|
+
}), node.expression);
|
419
|
+
}
|
420
|
+
}
|
421
|
+
this._scopedNodes.push(node);
|
422
|
+
return false;
|
423
|
+
}
|
424
|
+
visitCall(node) {
|
425
|
+
var _a;
|
426
|
+
this._validateIsInstanceCall(node);
|
427
|
+
this._validateIllegalDefaultParamInitializer(node);
|
428
|
+
if (this._fileInfo.diagnosticRuleSet.reportUnusedCallResult !== 'none' ||
|
429
|
+
this._fileInfo.diagnosticRuleSet.reportUnusedCoroutine !== 'none') {
|
430
|
+
if (((_a = node.parent) === null || _a === void 0 ? void 0 : _a.nodeType) === 47 /* StatementList */) {
|
431
|
+
const isRevealTypeCall = node.leftExpression.nodeType === 38 /* Name */ && node.leftExpression.value === 'reveal_type';
|
432
|
+
const returnType = this._evaluator.getType(node);
|
433
|
+
if (!isRevealTypeCall && returnType && this._isTypeValidForUnusedValueTest(returnType)) {
|
434
|
+
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportUnusedCallResult, diagnosticRules_1.DiagnosticRule.reportUnusedCallResult, localize_1.Localizer.Diagnostic.unusedCallResult().format({
|
435
|
+
type: this._evaluator.printType(returnType, /* expandTypeAlias */ false),
|
436
|
+
}), node);
|
437
|
+
if ((0, types_1.isClassInstance)(returnType) && types_1.ClassType.isBuiltIn(returnType, 'Coroutine')) {
|
438
|
+
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportUnusedCoroutine, diagnosticRules_1.DiagnosticRule.reportUnusedCoroutine, localize_1.Localizer.Diagnostic.unusedCoroutine(), node);
|
439
|
+
}
|
440
|
+
}
|
441
|
+
}
|
442
|
+
}
|
443
|
+
return true;
|
444
|
+
}
|
445
|
+
visitAwait(node) {
|
446
|
+
var _a;
|
447
|
+
if (this._fileInfo.diagnosticRuleSet.reportUnusedCallResult !== 'none') {
|
448
|
+
if (((_a = node.parent) === null || _a === void 0 ? void 0 : _a.nodeType) === 47 /* StatementList */ &&
|
449
|
+
node.expression.nodeType === 9 /* Call */) {
|
450
|
+
const returnType = this._evaluator.getType(node);
|
451
|
+
if (returnType && this._isTypeValidForUnusedValueTest(returnType)) {
|
452
|
+
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportUnusedCallResult, diagnosticRules_1.DiagnosticRule.reportUnusedCallResult, localize_1.Localizer.Diagnostic.unusedCallResult().format({
|
453
|
+
type: this._evaluator.printType(returnType, /* expandTypeAlias */ false),
|
454
|
+
}), node);
|
455
|
+
}
|
456
|
+
}
|
457
|
+
}
|
458
|
+
return true;
|
459
|
+
}
|
460
|
+
visitFor(node) {
|
461
|
+
this._evaluator.evaluateTypesForStatement(node);
|
462
|
+
return true;
|
463
|
+
}
|
464
|
+
visitList(node) {
|
465
|
+
this._validateIllegalDefaultParamInitializer(node);
|
466
|
+
return true;
|
467
|
+
}
|
468
|
+
visitSet(node) {
|
469
|
+
this._validateIllegalDefaultParamInitializer(node);
|
470
|
+
return true;
|
471
|
+
}
|
472
|
+
visitDictionary(node) {
|
473
|
+
this._validateIllegalDefaultParamInitializer(node);
|
474
|
+
return true;
|
475
|
+
}
|
476
|
+
visitListComprehension(node) {
|
477
|
+
this._scopedNodes.push(node);
|
478
|
+
return true;
|
479
|
+
}
|
480
|
+
visitListComprehensionIf(node) {
|
481
|
+
this._reportUnnecessaryConditionExpression(node.testExpression);
|
482
|
+
return true;
|
483
|
+
}
|
484
|
+
visitIf(node) {
|
485
|
+
this._evaluator.getType(node.testExpression);
|
486
|
+
this._reportUnnecessaryConditionExpression(node.testExpression);
|
487
|
+
return true;
|
488
|
+
}
|
489
|
+
visitWhile(node) {
|
490
|
+
this._evaluator.getType(node.testExpression);
|
491
|
+
this._reportUnnecessaryConditionExpression(node.testExpression);
|
492
|
+
return true;
|
493
|
+
}
|
494
|
+
visitWith(node) {
|
495
|
+
node.withItems.forEach((item) => {
|
496
|
+
this._evaluator.evaluateTypesForStatement(item);
|
497
|
+
});
|
498
|
+
return true;
|
499
|
+
}
|
500
|
+
visitReturn(node) {
|
501
|
+
let returnType;
|
502
|
+
const enclosingFunctionNode = ParseTreeUtils.getEnclosingFunction(node);
|
503
|
+
const declaredReturnType = enclosingFunctionNode
|
504
|
+
? this._evaluator.getFunctionDeclaredReturnType(enclosingFunctionNode)
|
505
|
+
: undefined;
|
506
|
+
if (node.returnExpression) {
|
507
|
+
returnType = this._evaluator.getType(node.returnExpression) || types_1.UnknownType.create();
|
508
|
+
}
|
509
|
+
else {
|
510
|
+
// There is no return expression, so "None" is assumed.
|
511
|
+
returnType = types_1.NoneType.createInstance();
|
512
|
+
}
|
513
|
+
if (this._evaluator.isNodeReachable(node, /* sourceNode */ undefined) && enclosingFunctionNode) {
|
514
|
+
if (declaredReturnType) {
|
515
|
+
if ((0, types_1.isNever)(declaredReturnType)) {
|
516
|
+
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.noReturnContainsReturn(), node);
|
517
|
+
}
|
518
|
+
else {
|
519
|
+
const diagAddendum = new diagnostic_1.DiagnosticAddendum();
|
520
|
+
let returnTypeMatches = false;
|
521
|
+
if (this._evaluator.assignType(declaredReturnType, returnType, diagAddendum, new typeVarContext_1.TypeVarContext(),
|
522
|
+
/* srcTypeVarContext */ undefined, 64 /* AllowBoolTypeGuard */)) {
|
523
|
+
returnTypeMatches = true;
|
524
|
+
}
|
525
|
+
else {
|
526
|
+
// See if the declared return type includes one or more constrained TypeVars. If so,
|
527
|
+
// try to narrow these TypeVars to a single type.
|
528
|
+
const uniqueTypeVars = (0, typeUtils_1.getTypeVarArgumentsRecursive)(declaredReturnType);
|
529
|
+
if (uniqueTypeVars &&
|
530
|
+
uniqueTypeVars.some((typeVar) => typeVar.details.constraints.length > 0)) {
|
531
|
+
const typeVarContext = new typeVarContext_1.TypeVarContext();
|
532
|
+
for (const typeVar of uniqueTypeVars) {
|
533
|
+
if (typeVar.details.constraints.length > 0) {
|
534
|
+
const narrowedType = this._evaluator.narrowConstrainedTypeVar(node, typeVar);
|
535
|
+
if (narrowedType) {
|
536
|
+
typeVarContext.setTypeVarType(typeVar, narrowedType);
|
537
|
+
typeVarContext.addSolveForScope((0, typeUtils_1.getTypeVarScopeId)(typeVar));
|
538
|
+
}
|
539
|
+
}
|
540
|
+
}
|
541
|
+
if (!typeVarContext.isEmpty()) {
|
542
|
+
const adjustedReturnType = (0, typeUtils_1.applySolvedTypeVars)(declaredReturnType, typeVarContext);
|
543
|
+
if (this._evaluator.assignType(adjustedReturnType, returnType, diagAddendum,
|
544
|
+
/* destTypeVarContext */ undefined,
|
545
|
+
/* srcTypeVarContext */ undefined, 64 /* AllowBoolTypeGuard */)) {
|
546
|
+
returnTypeMatches = true;
|
547
|
+
}
|
548
|
+
}
|
549
|
+
}
|
550
|
+
}
|
551
|
+
if (!returnTypeMatches) {
|
552
|
+
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.returnTypeMismatch().format({
|
553
|
+
exprType: this._evaluator.printType(returnType, /* expandTypeAlias */ false),
|
554
|
+
returnType: this._evaluator.printType(declaredReturnType, /* expandTypeAlias */ false),
|
555
|
+
}) + diagAddendum.getString(), node.returnExpression ? node.returnExpression : node);
|
556
|
+
}
|
557
|
+
}
|
558
|
+
}
|
559
|
+
if ((0, types_1.isUnknown)(returnType)) {
|
560
|
+
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportUnknownVariableType, diagnosticRules_1.DiagnosticRule.reportUnknownVariableType, localize_1.Localizer.Diagnostic.returnTypeUnknown(), node.returnExpression);
|
561
|
+
}
|
562
|
+
else if ((0, typeUtils_1.isPartlyUnknown)(returnType)) {
|
563
|
+
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportUnknownVariableType, diagnosticRules_1.DiagnosticRule.reportUnknownVariableType, localize_1.Localizer.Diagnostic.returnTypePartiallyUnknown().format({
|
564
|
+
returnType: this._evaluator.printType(returnType, /* expandTypeAlias */ true),
|
565
|
+
}), node.returnExpression);
|
566
|
+
}
|
567
|
+
}
|
568
|
+
return true;
|
569
|
+
}
|
570
|
+
visitYield(node) {
|
571
|
+
const yieldType = node.expression ? this._evaluator.getType(node.expression) : types_1.NoneType.createInstance();
|
572
|
+
this._validateYieldType(node, yieldType || types_1.UnknownType.create());
|
573
|
+
return true;
|
574
|
+
}
|
575
|
+
visitYieldFrom(node) {
|
576
|
+
const yieldFromType = this._evaluator.getType(node.expression) || types_1.UnknownType.create();
|
577
|
+
let yieldType;
|
578
|
+
if ((0, types_1.isClassInstance)(yieldFromType) && types_1.ClassType.isBuiltIn(yieldFromType, 'Coroutine')) {
|
579
|
+
// Handle the case of old-style (pre-await) coroutines.
|
580
|
+
yieldType = types_1.UnknownType.create();
|
581
|
+
}
|
582
|
+
else {
|
583
|
+
yieldType =
|
584
|
+
this._evaluator.getTypeOfIterable(yieldFromType, /* isAsync */ false, node) || types_1.UnknownType.create();
|
585
|
+
// Does the iterator return a Generator? If so, get the yield type from it.
|
586
|
+
// If the iterator doesn't return a Generator, use the iterator return type
|
587
|
+
// directly.
|
588
|
+
const generatorTypeArgs = (0, typeUtils_1.getGeneratorTypeArgs)(yieldType);
|
589
|
+
if (generatorTypeArgs) {
|
590
|
+
yieldType = generatorTypeArgs.length >= 1 ? generatorTypeArgs[0] : types_1.UnknownType.create();
|
591
|
+
}
|
592
|
+
else {
|
593
|
+
yieldType =
|
594
|
+
this._evaluator.getTypeOfIterator(yieldFromType, /* isAsync */ false, node) || types_1.UnknownType.create();
|
595
|
+
}
|
596
|
+
}
|
597
|
+
this._validateYieldType(node, yieldType);
|
598
|
+
return true;
|
599
|
+
}
|
600
|
+
visitRaise(node) {
|
601
|
+
this._evaluator.verifyRaiseExceptionType(node);
|
602
|
+
if (node.valueExpression) {
|
603
|
+
const baseExceptionType = this._evaluator.getBuiltInType(node, 'BaseException');
|
604
|
+
const exceptionType = this._evaluator.getType(node.valueExpression);
|
605
|
+
// Validate that the argument of "raise" is an exception object or None.
|
606
|
+
if (exceptionType && baseExceptionType && (0, types_1.isInstantiableClass)(baseExceptionType)) {
|
607
|
+
const diagAddendum = new diagnostic_1.DiagnosticAddendum();
|
608
|
+
(0, typeUtils_1.doForEachSubtype)(exceptionType, (subtype) => {
|
609
|
+
subtype = this._evaluator.makeTopLevelTypeVarsConcrete(subtype);
|
610
|
+
if (!(0, types_1.isAnyOrUnknown)(subtype) && !(0, types_1.isNoneInstance)(subtype)) {
|
611
|
+
if ((0, types_1.isClass)(subtype)) {
|
612
|
+
if (!(0, typeUtils_1.derivesFromClassRecursive)(subtype, baseExceptionType, /* ignoreUnknown */ false)) {
|
613
|
+
diagAddendum.addMessage(localize_1.Localizer.Diagnostic.exceptionTypeIncorrect().format({
|
614
|
+
type: this._evaluator.printType(subtype, /* expandTypeAlias */ false),
|
615
|
+
}));
|
616
|
+
}
|
617
|
+
}
|
618
|
+
else {
|
619
|
+
diagAddendum.addMessage(localize_1.Localizer.Diagnostic.exceptionTypeIncorrect().format({
|
620
|
+
type: this._evaluator.printType(subtype, /* expandTypeAlias */ false),
|
621
|
+
}));
|
622
|
+
}
|
623
|
+
}
|
624
|
+
});
|
625
|
+
if (!diagAddendum.isEmpty()) {
|
626
|
+
this._evaluator.addError(localize_1.Localizer.Diagnostic.expectedExceptionObj() + diagAddendum.getString(), node.valueExpression);
|
627
|
+
}
|
628
|
+
}
|
629
|
+
}
|
630
|
+
return true;
|
631
|
+
}
|
632
|
+
visitExcept(node) {
|
633
|
+
if (node.typeExpression) {
|
634
|
+
this._evaluator.evaluateTypesForStatement(node);
|
635
|
+
const exceptionType = this._evaluator.getType(node.typeExpression);
|
636
|
+
if (exceptionType) {
|
637
|
+
this._validateExceptionType(exceptionType, node.typeExpression);
|
638
|
+
}
|
639
|
+
}
|
640
|
+
return true;
|
641
|
+
}
|
642
|
+
visitAssert(node) {
|
643
|
+
if (node.exceptionExpression) {
|
644
|
+
this._evaluator.getType(node.exceptionExpression);
|
645
|
+
}
|
646
|
+
// Specifically look for a common programming error where the two arguments
|
647
|
+
// to an assert are enclosed in parens and interpreted as a two-element tuple.
|
648
|
+
// assert (x > 3, "bad value x")
|
649
|
+
const type = this._evaluator.getType(node.testExpression);
|
650
|
+
if (type && (0, types_1.isClassInstance)(type)) {
|
651
|
+
if ((0, typeUtils_1.isTupleClass)(type) && type.tupleTypeArguments) {
|
652
|
+
if (type.tupleTypeArguments.length > 0) {
|
653
|
+
if (!(0, typeUtils_1.isUnboundedTupleClass)(type)) {
|
654
|
+
this._evaluator.addDiagnosticForTextRange(this._fileInfo, this._fileInfo.diagnosticRuleSet.reportAssertAlwaysTrue, diagnosticRules_1.DiagnosticRule.reportAssertAlwaysTrue, localize_1.Localizer.Diagnostic.assertAlwaysTrue(), node.testExpression);
|
655
|
+
}
|
656
|
+
}
|
657
|
+
}
|
658
|
+
}
|
659
|
+
return true;
|
660
|
+
}
|
661
|
+
visitAssignment(node) {
|
662
|
+
this._evaluator.evaluateTypesForStatement(node);
|
663
|
+
if (node.typeAnnotationComment) {
|
664
|
+
this._evaluator.getType(node.typeAnnotationComment);
|
665
|
+
if (this._fileInfo.diagnosticRuleSet.reportTypeCommentUsage !== 'none' &&
|
666
|
+
this._fileInfo.executionEnvironment.pythonVersion >= pythonVersion_1.PythonVersion.V3_6) {
|
667
|
+
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportTypeCommentUsage, diagnosticRules_1.DiagnosticRule.reportTypeCommentUsage, localize_1.Localizer.Diagnostic.typeCommentDeprecated(), node.typeAnnotationComment);
|
668
|
+
}
|
669
|
+
}
|
670
|
+
return true;
|
671
|
+
}
|
672
|
+
visitAssignmentExpression(node) {
|
673
|
+
this._evaluator.getType(node);
|
674
|
+
return true;
|
675
|
+
}
|
676
|
+
visitAugmentedAssignment(node) {
|
677
|
+
this._evaluator.evaluateTypesForStatement(node);
|
678
|
+
return true;
|
679
|
+
}
|
680
|
+
visitIndex(node) {
|
681
|
+
this._evaluator.getType(node);
|
682
|
+
// If the index is a literal integer, see if this is a tuple with
|
683
|
+
// a known length and the integer value exceeds the length.
|
684
|
+
const baseType = this._evaluator.getType(node.baseExpression);
|
685
|
+
if (baseType) {
|
686
|
+
(0, typeUtils_1.doForEachSubtype)(baseType, (subtype) => {
|
687
|
+
if ((0, types_1.isClassInstance)(subtype) && subtype.tupleTypeArguments && !(0, typeUtils_1.isUnboundedTupleClass)(subtype)) {
|
688
|
+
const tupleLength = subtype.tupleTypeArguments.length;
|
689
|
+
if (node.items.length === 1 &&
|
690
|
+
!node.trailingComma &&
|
691
|
+
node.items[0].argumentCategory === 0 /* Simple */ &&
|
692
|
+
!node.items[0].name) {
|
693
|
+
const subscriptType = this._evaluator.getType(node.items[0].valueExpression);
|
694
|
+
if (subscriptType &&
|
695
|
+
(0, types_1.isClassInstance)(subscriptType) &&
|
696
|
+
types_1.ClassType.isBuiltIn(subscriptType, 'int') &&
|
697
|
+
(0, typeUtils_1.isLiteralType)(subscriptType) &&
|
698
|
+
typeof subscriptType.literalValue === 'number') {
|
699
|
+
if ((subscriptType.literalValue >= 0 && subscriptType.literalValue >= tupleLength) ||
|
700
|
+
(subscriptType.literalValue < 0 && subscriptType.literalValue + tupleLength < 0)) {
|
701
|
+
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.tupleIndexOutOfRange().format({
|
702
|
+
index: subscriptType.literalValue,
|
703
|
+
type: this._evaluator.printType(subtype),
|
704
|
+
}), node);
|
705
|
+
}
|
706
|
+
}
|
707
|
+
}
|
708
|
+
}
|
709
|
+
});
|
710
|
+
}
|
711
|
+
return true;
|
712
|
+
}
|
713
|
+
visitBinaryOperation(node) {
|
714
|
+
if (node.operator === 12 /* Equals */ || node.operator === 28 /* NotEquals */) {
|
715
|
+
// Don't apply this rule if it's within an assert.
|
716
|
+
if (!ParseTreeUtils.isWithinAssertExpression(node)) {
|
717
|
+
this._validateComparisonTypes(node);
|
718
|
+
}
|
719
|
+
}
|
720
|
+
this._evaluator.getType(node);
|
721
|
+
return true;
|
722
|
+
}
|
723
|
+
visitSlice(node) {
|
724
|
+
this._evaluator.getType(node);
|
725
|
+
return true;
|
726
|
+
}
|
727
|
+
visitUnpack(node) {
|
728
|
+
this._evaluator.getType(node);
|
729
|
+
return true;
|
730
|
+
}
|
731
|
+
visitTuple(node) {
|
732
|
+
this._evaluator.getType(node);
|
733
|
+
return true;
|
734
|
+
}
|
735
|
+
visitUnaryOperation(node) {
|
736
|
+
this._evaluator.getType(node);
|
737
|
+
return true;
|
738
|
+
}
|
739
|
+
visitTernary(node) {
|
740
|
+
this._evaluator.getType(node);
|
741
|
+
this._reportUnnecessaryConditionExpression(node.testExpression);
|
742
|
+
return true;
|
743
|
+
}
|
744
|
+
visitStringList(node) {
|
745
|
+
for (const stringNode of node.strings) {
|
746
|
+
if (stringNode.hasUnescapeErrors) {
|
747
|
+
const unescapedResult = (0, stringTokenUtils_1.getUnescapedString)(stringNode.token);
|
748
|
+
unescapedResult.unescapeErrors.forEach((error) => {
|
749
|
+
const start = stringNode.token.start +
|
750
|
+
stringNode.token.prefixLength +
|
751
|
+
stringNode.token.quoteMarkLength +
|
752
|
+
error.offset;
|
753
|
+
const textRange = { start, length: error.length };
|
754
|
+
if (error.errorType === 0 /* InvalidEscapeSequence */) {
|
755
|
+
this._evaluator.addDiagnosticForTextRange(this._fileInfo, this._fileInfo.diagnosticRuleSet.reportInvalidStringEscapeSequence, diagnosticRules_1.DiagnosticRule.reportInvalidStringEscapeSequence, localize_1.Localizer.Diagnostic.stringUnsupportedEscape(), textRange);
|
756
|
+
}
|
757
|
+
else if (error.errorType === 1 /* EscapeWithinFormatExpression */) {
|
758
|
+
this._evaluator.addDiagnosticForTextRange(this._fileInfo, 'error', '', localize_1.Localizer.Diagnostic.formatStringEscape(), textRange);
|
759
|
+
}
|
760
|
+
else if (error.errorType === 2 /* SingleCloseBraceWithinFormatLiteral */) {
|
761
|
+
this._evaluator.addDiagnosticForTextRange(this._fileInfo, 'error', '', localize_1.Localizer.Diagnostic.formatStringBrace(), textRange);
|
762
|
+
}
|
763
|
+
else if (error.errorType === 3 /* UnterminatedFormatExpression */) {
|
764
|
+
this._evaluator.addDiagnosticForTextRange(this._fileInfo, 'error', '', localize_1.Localizer.Diagnostic.formatStringUnterminated(), textRange);
|
765
|
+
}
|
766
|
+
});
|
767
|
+
}
|
768
|
+
}
|
769
|
+
if (node.typeAnnotation) {
|
770
|
+
this._evaluator.getType(node);
|
771
|
+
}
|
772
|
+
if (node.strings.length > 1 && !node.isParenthesized) {
|
773
|
+
this._evaluator.addDiagnosticForTextRange(this._fileInfo, this._fileInfo.diagnosticRuleSet.reportImplicitStringConcatenation, diagnosticRules_1.DiagnosticRule.reportImplicitStringConcatenation, localize_1.Localizer.Diagnostic.implicitStringConcat(), node);
|
774
|
+
}
|
775
|
+
return true;
|
776
|
+
}
|
777
|
+
visitFormatString(node) {
|
778
|
+
node.expressions.forEach((formatExpr) => {
|
779
|
+
this._evaluator.getType(formatExpr);
|
780
|
+
});
|
781
|
+
return true;
|
782
|
+
}
|
783
|
+
visitGlobal(node) {
|
784
|
+
this._suppressUnboundCheck(() => {
|
785
|
+
node.nameList.forEach((name) => {
|
786
|
+
this._evaluator.getType(name);
|
787
|
+
this.walk(name);
|
788
|
+
});
|
789
|
+
});
|
790
|
+
return false;
|
791
|
+
}
|
792
|
+
visitNonlocal(node) {
|
793
|
+
this._suppressUnboundCheck(() => {
|
794
|
+
node.nameList.forEach((name) => {
|
795
|
+
this._evaluator.getType(name);
|
796
|
+
this.walk(name);
|
797
|
+
});
|
798
|
+
});
|
799
|
+
return false;
|
800
|
+
}
|
801
|
+
visitName(node) {
|
802
|
+
// Determine if we should log information about private usage.
|
803
|
+
this._conditionallyReportPrivateUsage(node);
|
804
|
+
// Determine if the name is possibly unbound.
|
805
|
+
if (!this._isUnboundCheckSuppressed) {
|
806
|
+
this._reportUnboundName(node);
|
807
|
+
}
|
808
|
+
// Report the use of a deprecated symbol. For now, this functionality
|
809
|
+
// is disabled. We'll leave it in place for the future.
|
810
|
+
// this._reportDeprecatedUse(node);
|
811
|
+
return true;
|
812
|
+
}
|
813
|
+
visitDel(node) {
|
814
|
+
this._suppressUnboundCheck(() => {
|
815
|
+
node.expressions.forEach((expr) => {
|
816
|
+
this._evaluator.verifyDeleteExpression(expr);
|
817
|
+
this.walk(expr);
|
818
|
+
});
|
819
|
+
});
|
820
|
+
return false;
|
821
|
+
}
|
822
|
+
visitMemberAccess(node) {
|
823
|
+
this._evaluator.getType(node);
|
824
|
+
this._conditionallyReportPrivateUsage(node.memberName);
|
825
|
+
// Walk the leftExpression but not the memberName.
|
826
|
+
this.walk(node.leftExpression);
|
827
|
+
return false;
|
828
|
+
}
|
829
|
+
visitImportAs(node) {
|
830
|
+
this._evaluator.evaluateTypesForStatement(node);
|
831
|
+
return false;
|
832
|
+
}
|
833
|
+
visitImportFrom(node) {
|
834
|
+
if (!node.isWildcardImport) {
|
835
|
+
node.imports.forEach((importAs) => {
|
836
|
+
this._evaluator.evaluateTypesForStatement(importAs);
|
837
|
+
});
|
838
|
+
}
|
839
|
+
else {
|
840
|
+
const importInfo = AnalyzerNodeInfo.getImportInfo(node.module);
|
841
|
+
if (importInfo &&
|
842
|
+
importInfo.isImportFound &&
|
843
|
+
importInfo.importType !== 2 /* Local */ &&
|
844
|
+
!this._fileInfo.isStubFile) {
|
845
|
+
this._evaluator.addDiagnosticForTextRange(this._fileInfo, this._fileInfo.diagnosticRuleSet.reportWildcardImportFromLibrary, diagnosticRules_1.DiagnosticRule.reportWildcardImportFromLibrary, localize_1.Localizer.Diagnostic.wildcardLibraryImport(), node.wildcardToken || node);
|
846
|
+
}
|
847
|
+
}
|
848
|
+
return false;
|
849
|
+
}
|
850
|
+
visitTypeAnnotation(node) {
|
851
|
+
this._evaluator.getType(node.typeAnnotation);
|
852
|
+
return true;
|
853
|
+
}
|
854
|
+
visitMatch(node) {
|
855
|
+
this._evaluator.getType(node.subjectExpression);
|
856
|
+
this._validateExhaustiveMatch(node);
|
857
|
+
return true;
|
858
|
+
}
|
859
|
+
visitCase(node) {
|
860
|
+
if (node.guardExpression) {
|
861
|
+
this._evaluator.getType(node.guardExpression);
|
862
|
+
}
|
863
|
+
this._evaluator.evaluateTypesForStatement(node.pattern);
|
864
|
+
return true;
|
865
|
+
}
|
866
|
+
visitPatternClass(node) {
|
867
|
+
(0, patternMatching_1.validateClassPattern)(this._evaluator, node);
|
868
|
+
return true;
|
869
|
+
}
|
870
|
+
visitTry(node) {
|
871
|
+
this._reportUnusedExceptStatements(node);
|
872
|
+
return true;
|
873
|
+
}
|
874
|
+
visitError(node) {
|
875
|
+
// Get the type of the child so it's available to
|
876
|
+
// the completion provider.
|
877
|
+
if (node.child) {
|
878
|
+
this._evaluator.getType(node.child);
|
879
|
+
}
|
880
|
+
// Don't explore further.
|
881
|
+
return false;
|
882
|
+
}
|
883
|
+
_reportUnnecessaryConditionExpression(expression) {
|
884
|
+
if (expression.nodeType === 7 /* BinaryOperation */) {
|
885
|
+
if (expression.operator === 36 /* And */ || expression.operator === 37 /* Or */) {
|
886
|
+
this._reportUnnecessaryConditionExpression(expression.leftExpression);
|
887
|
+
this._reportUnnecessaryConditionExpression(expression.rightExpression);
|
888
|
+
}
|
889
|
+
return;
|
890
|
+
}
|
891
|
+
else if (expression.nodeType === 55 /* UnaryOperation */) {
|
892
|
+
if (expression.operator === 38 /* Not */) {
|
893
|
+
this._reportUnnecessaryConditionExpression(expression.expression);
|
894
|
+
}
|
895
|
+
return;
|
896
|
+
}
|
897
|
+
const exprTypeResult = this._evaluator.getTypeOfExpression(expression);
|
898
|
+
let isExprFunction = true;
|
899
|
+
(0, typeUtils_1.doForEachSubtype)(exprTypeResult.type, (subtype) => {
|
900
|
+
subtype = this._evaluator.makeTopLevelTypeVarsConcrete(subtype);
|
901
|
+
if (!(0, types_1.isFunction)(subtype) && !(0, types_1.isOverloadedFunction)(subtype)) {
|
902
|
+
isExprFunction = false;
|
903
|
+
}
|
904
|
+
});
|
905
|
+
if (isExprFunction) {
|
906
|
+
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportUnnecessaryComparison, diagnosticRules_1.DiagnosticRule.reportUnnecessaryComparison, localize_1.Localizer.Diagnostic.functionInConditionalExpression(), expression);
|
907
|
+
}
|
908
|
+
}
|
909
|
+
_reportUnusedExpression(node) {
|
910
|
+
if (this._fileInfo.diagnosticRuleSet.reportUnusedExpression === 'none') {
|
911
|
+
return;
|
912
|
+
}
|
913
|
+
const simpleExpressionTypes = [
|
914
|
+
55 /* UnaryOperation */,
|
915
|
+
7 /* BinaryOperation */,
|
916
|
+
40 /* Number */,
|
917
|
+
11 /* Constant */,
|
918
|
+
38 /* Name */,
|
919
|
+
];
|
920
|
+
if (simpleExpressionTypes.some((nodeType) => nodeType === node.nodeType)) {
|
921
|
+
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportUnusedExpression, diagnosticRules_1.DiagnosticRule.reportUnusedExpression, localize_1.Localizer.Diagnostic.unusedExpression(), node);
|
922
|
+
}
|
923
|
+
}
|
924
|
+
_validateExhaustiveMatch(node) {
|
925
|
+
// This check can be expensive, so skip it if it's disabled.
|
926
|
+
if (this._fileInfo.diagnosticRuleSet.reportMatchNotExhaustive === 'none') {
|
927
|
+
return;
|
928
|
+
}
|
929
|
+
const narrowedTypeResult = this._evaluator.evaluateTypeForSubnode(node, () => {
|
930
|
+
this._evaluator.evaluateTypesForMatchStatement(node);
|
931
|
+
});
|
932
|
+
if (narrowedTypeResult && !(0, types_1.isNever)(narrowedTypeResult.type)) {
|
933
|
+
const diagAddendum = new diagnostic_1.DiagnosticAddendum();
|
934
|
+
diagAddendum.addMessage(localize_1.Localizer.DiagnosticAddendum.matchIsNotExhaustiveType().format({
|
935
|
+
type: this._evaluator.printType(narrowedTypeResult.type),
|
936
|
+
}));
|
937
|
+
diagAddendum.addMessage(localize_1.Localizer.DiagnosticAddendum.matchIsNotExhaustiveHint());
|
938
|
+
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportMatchNotExhaustive, diagnosticRules_1.DiagnosticRule.reportMatchNotExhaustive, localize_1.Localizer.Diagnostic.matchIsNotExhaustive() + diagAddendum.getString(), node.subjectExpression);
|
939
|
+
}
|
940
|
+
}
|
941
|
+
_suppressUnboundCheck(callback) {
|
942
|
+
const wasSuppressed = this._isUnboundCheckSuppressed;
|
943
|
+
this._isUnboundCheckSuppressed = true;
|
944
|
+
try {
|
945
|
+
callback();
|
946
|
+
}
|
947
|
+
finally {
|
948
|
+
this._isUnboundCheckSuppressed = wasSuppressed;
|
949
|
+
}
|
950
|
+
}
|
951
|
+
_validateIllegalDefaultParamInitializer(node) {
|
952
|
+
if (this._fileInfo.diagnosticRuleSet.reportCallInDefaultInitializer !== 'none') {
|
953
|
+
if (ParseTreeUtils.isWithinDefaultParamInitializer(node) && !this._fileInfo.isStubFile) {
|
954
|
+
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportCallInDefaultInitializer, diagnosticRules_1.DiagnosticRule.reportCallInDefaultInitializer, localize_1.Localizer.Diagnostic.defaultValueContainsCall(), node);
|
955
|
+
}
|
956
|
+
}
|
957
|
+
}
|
958
|
+
// Determines whether the types of the two operands for an == or != operation
|
959
|
+
// have overlapping types.
|
960
|
+
_validateComparisonTypes(node) {
|
961
|
+
const leftType = this._evaluator.getType(node.leftExpression);
|
962
|
+
const rightType = this._evaluator.getType(node.rightExpression);
|
963
|
+
if (!leftType || !rightType) {
|
964
|
+
return;
|
965
|
+
}
|
966
|
+
if ((0, types_1.isNever)(leftType) || (0, types_1.isNever)(rightType)) {
|
967
|
+
return;
|
968
|
+
}
|
969
|
+
const getMessage = () => {
|
970
|
+
return node.operator === 12 /* Equals */
|
971
|
+
? localize_1.Localizer.Diagnostic.comparisonAlwaysFalse()
|
972
|
+
: localize_1.Localizer.Diagnostic.comparisonAlwaysTrue();
|
973
|
+
};
|
974
|
+
// Check for the special case where the LHS and RHS are both literals.
|
975
|
+
if ((0, typeUtils_1.isLiteralTypeOrUnion)(rightType) && (0, typeUtils_1.isLiteralTypeOrUnion)(leftType)) {
|
976
|
+
if ((0, staticExpressions_1.evaluateStaticBoolExpression)(node, this._fileInfo.executionEnvironment, this._fileInfo.definedConstants) === undefined) {
|
977
|
+
let isPossiblyTrue = false;
|
978
|
+
(0, typeUtils_1.doForEachSubtype)(leftType, (leftSubtype) => {
|
979
|
+
if (this._evaluator.assignType(rightType, leftSubtype)) {
|
980
|
+
isPossiblyTrue = true;
|
981
|
+
}
|
982
|
+
});
|
983
|
+
if (!isPossiblyTrue) {
|
984
|
+
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportUnnecessaryComparison, diagnosticRules_1.DiagnosticRule.reportUnnecessaryComparison, getMessage().format({
|
985
|
+
leftType: this._evaluator.printType(leftType, /* expandTypeAlias */ true),
|
986
|
+
rightType: this._evaluator.printType(rightType, /* expandTypeAlias */ true),
|
987
|
+
}), node);
|
988
|
+
}
|
989
|
+
}
|
990
|
+
}
|
991
|
+
else {
|
992
|
+
let isComparable = false;
|
993
|
+
(0, typeUtils_1.doForEachSubtype)(leftType, (leftSubtype) => {
|
994
|
+
if (isComparable) {
|
995
|
+
return;
|
996
|
+
}
|
997
|
+
leftSubtype = this._evaluator.makeTopLevelTypeVarsConcrete(leftSubtype);
|
998
|
+
(0, typeUtils_1.doForEachSubtype)(rightType, (rightSubtype) => {
|
999
|
+
if (isComparable) {
|
1000
|
+
return;
|
1001
|
+
}
|
1002
|
+
rightSubtype = this._evaluator.makeTopLevelTypeVarsConcrete(rightSubtype);
|
1003
|
+
if (this._isTypeComparable(leftSubtype, rightSubtype)) {
|
1004
|
+
isComparable = true;
|
1005
|
+
}
|
1006
|
+
});
|
1007
|
+
});
|
1008
|
+
if (!isComparable) {
|
1009
|
+
const leftTypeText = this._evaluator.printType(leftType, /* expandTypeAlias */ true);
|
1010
|
+
const rightTypeText = this._evaluator.printType(rightType, /* expandTypeAlias */ true);
|
1011
|
+
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportUnnecessaryComparison, diagnosticRules_1.DiagnosticRule.reportUnnecessaryComparison, getMessage().format({
|
1012
|
+
leftType: leftTypeText,
|
1013
|
+
rightType: rightTypeText,
|
1014
|
+
}), node);
|
1015
|
+
}
|
1016
|
+
}
|
1017
|
+
}
|
1018
|
+
// Determines whether the two types are potentially comparable -- i.e.
|
1019
|
+
// their types overlap in such a way that it makes sense for them to
|
1020
|
+
// be compared with an == or != operator.
|
1021
|
+
_isTypeComparable(leftType, rightType) {
|
1022
|
+
if ((0, types_1.isAnyOrUnknown)(leftType) || (0, types_1.isAnyOrUnknown)(rightType)) {
|
1023
|
+
return true;
|
1024
|
+
}
|
1025
|
+
if ((0, types_1.isNever)(leftType) || (0, types_1.isNever)(rightType)) {
|
1026
|
+
return false;
|
1027
|
+
}
|
1028
|
+
if ((0, types_1.isModule)(leftType) || (0, types_1.isModule)(rightType)) {
|
1029
|
+
return (0, types_1.isTypeSame)(leftType, rightType);
|
1030
|
+
}
|
1031
|
+
if ((0, types_1.isNoneInstance)(leftType) || (0, types_1.isNoneInstance)(rightType)) {
|
1032
|
+
return (0, types_1.isTypeSame)(leftType, rightType);
|
1033
|
+
}
|
1034
|
+
const isLeftCallable = (0, types_1.isFunction)(leftType) || (0, types_1.isOverloadedFunction)(leftType);
|
1035
|
+
const isRightCallable = (0, types_1.isFunction)(rightType) || (0, types_1.isOverloadedFunction)(rightType);
|
1036
|
+
if (isLeftCallable !== isRightCallable) {
|
1037
|
+
return false;
|
1038
|
+
}
|
1039
|
+
if ((0, types_1.isInstantiableClass)(leftType) || ((0, types_1.isClassInstance)(leftType) && types_1.ClassType.isBuiltIn(leftType, 'type'))) {
|
1040
|
+
if ((0, types_1.isInstantiableClass)(rightType) ||
|
1041
|
+
((0, types_1.isClassInstance)(rightType) && types_1.ClassType.isBuiltIn(rightType, 'type'))) {
|
1042
|
+
const genericLeftType = types_1.ClassType.cloneForSpecialization(leftType,
|
1043
|
+
/* typeArguments */ undefined,
|
1044
|
+
/* isTypeArgumentExplicit */ false);
|
1045
|
+
const genericRightType = types_1.ClassType.cloneForSpecialization(rightType,
|
1046
|
+
/* typeArguments */ undefined,
|
1047
|
+
/* isTypeArgumentExplicit */ false);
|
1048
|
+
if (this._evaluator.assignType(genericLeftType, genericRightType) ||
|
1049
|
+
this._evaluator.assignType(genericRightType, genericLeftType)) {
|
1050
|
+
return true;
|
1051
|
+
}
|
1052
|
+
}
|
1053
|
+
// Does the class have an operator overload for eq?
|
1054
|
+
const metaclass = leftType.details.effectiveMetaclass;
|
1055
|
+
if (metaclass && (0, types_1.isClass)(metaclass)) {
|
1056
|
+
if ((0, typeUtils_1.lookUpClassMember)(metaclass, '__eq__', 4 /* SkipObjectBaseClass */)) {
|
1057
|
+
return true;
|
1058
|
+
}
|
1059
|
+
}
|
1060
|
+
return false;
|
1061
|
+
}
|
1062
|
+
if ((0, types_1.isClassInstance)(leftType)) {
|
1063
|
+
if ((0, types_1.isClassInstance)(rightType)) {
|
1064
|
+
const genericLeftType = types_1.ClassType.cloneForSpecialization(leftType,
|
1065
|
+
/* typeArguments */ undefined,
|
1066
|
+
/* isTypeArgumentExplicit */ false);
|
1067
|
+
const genericRightType = types_1.ClassType.cloneForSpecialization(rightType,
|
1068
|
+
/* typeArguments */ undefined,
|
1069
|
+
/* isTypeArgumentExplicit */ false);
|
1070
|
+
if (this._evaluator.assignType(genericLeftType, genericRightType) ||
|
1071
|
+
this._evaluator.assignType(genericRightType, genericLeftType)) {
|
1072
|
+
return true;
|
1073
|
+
}
|
1074
|
+
// Assume that if the types are disjoint and built-in classes that they
|
1075
|
+
// will never be comparable.
|
1076
|
+
if (types_1.ClassType.isBuiltIn(leftType) && types_1.ClassType.isBuiltIn(rightType)) {
|
1077
|
+
return false;
|
1078
|
+
}
|
1079
|
+
}
|
1080
|
+
// Does the class have an operator overload for eq?
|
1081
|
+
if ((0, typeUtils_1.lookUpClassMember)(types_1.ClassType.cloneAsInstantiable(leftType), '__eq__', 4 /* SkipObjectBaseClass */)) {
|
1082
|
+
return true;
|
1083
|
+
}
|
1084
|
+
return false;
|
1085
|
+
}
|
1086
|
+
return true;
|
1087
|
+
}
|
1088
|
+
// Determines whether the specified type is one that should trigger
|
1089
|
+
// an "unused" value diagnostic.
|
1090
|
+
_isTypeValidForUnusedValueTest(type) {
|
1091
|
+
return !(0, types_1.isNoneInstance)(type) && !(0, types_1.isNever)(type) && !(0, types_1.isAnyOrUnknown)(type);
|
1092
|
+
}
|
1093
|
+
// Verifies that each local type variable is used more than once.
|
1094
|
+
_validateFunctionTypeVarUsage(node, type) {
|
1095
|
+
// Skip this check entirely if it's disabled.
|
1096
|
+
if (this._fileInfo.diagnosticRuleSet.reportInvalidTypeVarUse === 'none') {
|
1097
|
+
return;
|
1098
|
+
}
|
1099
|
+
const localTypeVarUsage = new Map();
|
1100
|
+
const classTypeVarUsage = new Map();
|
1101
|
+
let exemptBoundTypeVar = true;
|
1102
|
+
let curParamNode;
|
1103
|
+
// Is this a constructor (an __init__ method) for a generic class?
|
1104
|
+
let constructorClass;
|
1105
|
+
if (types_1.FunctionType.isInstanceMethod(type) && node.name.value === '__init__') {
|
1106
|
+
const containingClassNode = ParseTreeUtils.getEnclosingClassOrFunction(node);
|
1107
|
+
if (containingClassNode && containingClassNode.nodeType === 10 /* Class */) {
|
1108
|
+
const classType = this._evaluator.getTypeOfClass(containingClassNode);
|
1109
|
+
if (classType && (0, types_1.isClass)(classType.classType)) {
|
1110
|
+
constructorClass = classType.classType;
|
1111
|
+
}
|
1112
|
+
}
|
1113
|
+
}
|
1114
|
+
const nameWalker = new ParseTreeUtils.NameNodeWalker((nameNode, subscriptIndex, baseExpression) => {
|
1115
|
+
var _a, _b, _c, _d, _e, _f;
|
1116
|
+
const nameType = this._evaluator.getType(nameNode);
|
1117
|
+
``;
|
1118
|
+
if (nameType && (0, types_1.isTypeVar)(nameType)) {
|
1119
|
+
// Does this name refer to a TypeVar that is scoped to this function?
|
1120
|
+
if (nameType.scopeId === this._evaluator.getScopeIdForNode(node)) {
|
1121
|
+
// We exempt constrained TypeVars, bound TypeVars that are type arguments of
|
1122
|
+
// other types, and ParamSpecs. There are legitimate uses for singleton
|
1123
|
+
// instances in these particular cases.
|
1124
|
+
let isExempt = nameType.details.constraints.length > 0 ||
|
1125
|
+
(exemptBoundTypeVar &&
|
1126
|
+
nameType.details.boundType !== undefined &&
|
1127
|
+
subscriptIndex !== undefined) ||
|
1128
|
+
(0, types_1.isParamSpec)(nameType);
|
1129
|
+
if (!isExempt && baseExpression && subscriptIndex !== undefined) {
|
1130
|
+
// Is this a type argument for a generic type alias? If so,
|
1131
|
+
// exempt it from the check because the type alias may repeat
|
1132
|
+
// the TypeVar multiple times.
|
1133
|
+
const baseType = this._evaluator.getType(baseExpression);
|
1134
|
+
if ((baseType === null || baseType === void 0 ? void 0 : baseType.typeAliasInfo) &&
|
1135
|
+
baseType.typeAliasInfo.typeParameters &&
|
1136
|
+
subscriptIndex < baseType.typeAliasInfo.typeParameters.length) {
|
1137
|
+
isExempt = true;
|
1138
|
+
}
|
1139
|
+
}
|
1140
|
+
const existingEntry = localTypeVarUsage.get(nameType.details.name);
|
1141
|
+
const isParamTypeWithEllipsisUsage = ((_a = curParamNode === null || curParamNode === void 0 ? void 0 : curParamNode.defaultValue) === null || _a === void 0 ? void 0 : _a.nodeType) === 18 /* Ellipsis */;
|
1142
|
+
if (!existingEntry) {
|
1143
|
+
localTypeVarUsage.set(nameType.details.name, {
|
1144
|
+
nodes: [nameNode],
|
1145
|
+
paramTypeUsageCount: curParamNode !== undefined ? 1 : 0,
|
1146
|
+
paramTypeWithEllipsisUsageCount: isParamTypeWithEllipsisUsage ? 1 : 0,
|
1147
|
+
returnTypeUsageCount: curParamNode === undefined ? 1 : 0,
|
1148
|
+
paramWithEllipsis: isParamTypeWithEllipsisUsage ? (_b = curParamNode === null || curParamNode === void 0 ? void 0 : curParamNode.name) === null || _b === void 0 ? void 0 : _b.value : undefined,
|
1149
|
+
isExempt,
|
1150
|
+
});
|
1151
|
+
}
|
1152
|
+
else {
|
1153
|
+
existingEntry.nodes.push(nameNode);
|
1154
|
+
if (curParamNode !== undefined) {
|
1155
|
+
existingEntry.paramTypeUsageCount += 1;
|
1156
|
+
if (isParamTypeWithEllipsisUsage) {
|
1157
|
+
existingEntry.paramTypeWithEllipsisUsageCount += 1;
|
1158
|
+
if (!existingEntry.paramWithEllipsis) {
|
1159
|
+
existingEntry.paramWithEllipsis = (_c = curParamNode === null || curParamNode === void 0 ? void 0 : curParamNode.name) === null || _c === void 0 ? void 0 : _c.value;
|
1160
|
+
}
|
1161
|
+
}
|
1162
|
+
}
|
1163
|
+
else {
|
1164
|
+
existingEntry.returnTypeUsageCount += 1;
|
1165
|
+
}
|
1166
|
+
}
|
1167
|
+
}
|
1168
|
+
// Does this name refer to a TypeVar that is scoped to the class associated with
|
1169
|
+
// this constructor method?
|
1170
|
+
if (constructorClass && nameType.scopeId === constructorClass.details.typeVarScopeId) {
|
1171
|
+
const existingEntry = classTypeVarUsage.get(nameType.details.name);
|
1172
|
+
const isParamTypeWithEllipsisUsage = ((_d = curParamNode === null || curParamNode === void 0 ? void 0 : curParamNode.defaultValue) === null || _d === void 0 ? void 0 : _d.nodeType) === 18 /* Ellipsis */;
|
1173
|
+
if (!existingEntry) {
|
1174
|
+
classTypeVarUsage.set(nameType.details.name, {
|
1175
|
+
nodes: [nameNode],
|
1176
|
+
paramTypeUsageCount: curParamNode !== undefined ? 1 : 0,
|
1177
|
+
paramTypeWithEllipsisUsageCount: isParamTypeWithEllipsisUsage ? 1 : 0,
|
1178
|
+
returnTypeUsageCount: 0,
|
1179
|
+
paramWithEllipsis: isParamTypeWithEllipsisUsage ? (_e = curParamNode === null || curParamNode === void 0 ? void 0 : curParamNode.name) === null || _e === void 0 ? void 0 : _e.value : undefined,
|
1180
|
+
isExempt: false,
|
1181
|
+
});
|
1182
|
+
}
|
1183
|
+
else {
|
1184
|
+
existingEntry.nodes.push(nameNode);
|
1185
|
+
if (curParamNode !== undefined) {
|
1186
|
+
existingEntry.paramTypeUsageCount += 1;
|
1187
|
+
if (isParamTypeWithEllipsisUsage) {
|
1188
|
+
existingEntry.paramTypeWithEllipsisUsageCount += 1;
|
1189
|
+
if (!existingEntry.paramWithEllipsis) {
|
1190
|
+
existingEntry.paramWithEllipsis = (_f = curParamNode === null || curParamNode === void 0 ? void 0 : curParamNode.name) === null || _f === void 0 ? void 0 : _f.value;
|
1191
|
+
}
|
1192
|
+
}
|
1193
|
+
}
|
1194
|
+
}
|
1195
|
+
}
|
1196
|
+
}
|
1197
|
+
});
|
1198
|
+
// Find all of the local type variables in signature.
|
1199
|
+
node.parameters.forEach((param) => {
|
1200
|
+
const annotation = param.typeAnnotation || param.typeAnnotationComment;
|
1201
|
+
if (annotation) {
|
1202
|
+
curParamNode = param;
|
1203
|
+
nameWalker.walk(annotation);
|
1204
|
+
}
|
1205
|
+
});
|
1206
|
+
curParamNode = undefined;
|
1207
|
+
if (node.returnTypeAnnotation) {
|
1208
|
+
// Don't exempt the use of a bound TypeVar when used as a type argument
|
1209
|
+
// within a return type. This exemption applies only to input parameter
|
1210
|
+
// annotations.
|
1211
|
+
exemptBoundTypeVar = false;
|
1212
|
+
nameWalker.walk(node.returnTypeAnnotation);
|
1213
|
+
}
|
1214
|
+
localTypeVarUsage.forEach((usage) => {
|
1215
|
+
var _a;
|
1216
|
+
// Report error for local type variable that appears only once.
|
1217
|
+
if (usage.nodes.length === 1 && !usage.isExempt) {
|
1218
|
+
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportInvalidTypeVarUse, diagnosticRules_1.DiagnosticRule.reportInvalidTypeVarUse, localize_1.Localizer.Diagnostic.typeVarUsedOnlyOnce().format({
|
1219
|
+
name: usage.nodes[0].value,
|
1220
|
+
}), usage.nodes[0]);
|
1221
|
+
}
|
1222
|
+
// Report error for local type variable that appears in return type
|
1223
|
+
// (but not as a top-level TypeVar within a union) and appears only
|
1224
|
+
// within parameters that have default values. These may go unsolved.
|
1225
|
+
let isUsedInReturnType = usage.returnTypeUsageCount > 0;
|
1226
|
+
if (usage.returnTypeUsageCount === 1 && type.details.declaredReturnType) {
|
1227
|
+
// If the TypeVar appears only once in the return type and it's a top-level
|
1228
|
+
// TypeVar within a union, exempt it from this check. Although these
|
1229
|
+
// TypeVars may go unsolved, they can be safely eliminated from the union
|
1230
|
+
// without generating an Unknown type.
|
1231
|
+
const returnType = type.details.declaredReturnType;
|
1232
|
+
if ((0, types_1.isUnion)(returnType) &&
|
1233
|
+
returnType.subtypes.some((subtype) => (0, types_1.isTypeVar)(subtype) && subtype.details.name === usage.nodes[0].value)) {
|
1234
|
+
isUsedInReturnType = false;
|
1235
|
+
}
|
1236
|
+
}
|
1237
|
+
if (isUsedInReturnType &&
|
1238
|
+
usage.paramTypeWithEllipsisUsageCount > 0 &&
|
1239
|
+
usage.paramTypeUsageCount === usage.paramTypeWithEllipsisUsageCount) {
|
1240
|
+
const diag = new diagnostic_1.DiagnosticAddendum();
|
1241
|
+
diag.addMessage(localize_1.Localizer.DiagnosticAddendum.typeVarUnsolvableRemedy());
|
1242
|
+
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportInvalidTypeVarUse, diagnosticRules_1.DiagnosticRule.reportInvalidTypeVarUse, localize_1.Localizer.Diagnostic.typeVarPossiblyUnsolvable().format({
|
1243
|
+
name: usage.nodes[0].value,
|
1244
|
+
param: (_a = usage.paramWithEllipsis) !== null && _a !== void 0 ? _a : '',
|
1245
|
+
}) + diag.getString(), usage.nodes[0]);
|
1246
|
+
}
|
1247
|
+
});
|
1248
|
+
// Report error for a class type variable that appears only within
|
1249
|
+
// constructor parameters that have default values. These may go unsolved.
|
1250
|
+
classTypeVarUsage.forEach((usage) => {
|
1251
|
+
var _a;
|
1252
|
+
if (usage.paramTypeWithEllipsisUsageCount > 0 &&
|
1253
|
+
usage.paramTypeUsageCount === usage.paramTypeWithEllipsisUsageCount) {
|
1254
|
+
const diag = new diagnostic_1.DiagnosticAddendum();
|
1255
|
+
diag.addMessage(localize_1.Localizer.DiagnosticAddendum.typeVarUnsolvableRemedy());
|
1256
|
+
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportInvalidTypeVarUse, diagnosticRules_1.DiagnosticRule.reportInvalidTypeVarUse, localize_1.Localizer.Diagnostic.typeVarPossiblyUnsolvable().format({
|
1257
|
+
name: usage.nodes[0].value,
|
1258
|
+
param: (_a = usage.paramWithEllipsis) !== null && _a !== void 0 ? _a : '',
|
1259
|
+
}) + diag.getString(), usage.nodes[0]);
|
1260
|
+
}
|
1261
|
+
});
|
1262
|
+
}
|
1263
|
+
_validateOverloadConsistency(node, functionType, prevOverloads) {
|
1264
|
+
for (let i = 0; i < prevOverloads.length; i++) {
|
1265
|
+
const prevOverload = prevOverloads[i];
|
1266
|
+
if (types_1.FunctionType.isOverloaded(functionType) &&
|
1267
|
+
types_1.FunctionType.isOverloaded(prevOverload) &&
|
1268
|
+
this._isOverlappingOverload(functionType, prevOverload)) {
|
1269
|
+
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportOverlappingOverload, diagnosticRules_1.DiagnosticRule.reportOverlappingOverload, localize_1.Localizer.Diagnostic.overlappingOverload().format({
|
1270
|
+
name: node.name.value,
|
1271
|
+
obscured: prevOverloads.length + 1,
|
1272
|
+
obscuredBy: i + 1,
|
1273
|
+
}), node.name);
|
1274
|
+
break;
|
1275
|
+
}
|
1276
|
+
}
|
1277
|
+
for (let i = 0; i < prevOverloads.length; i++) {
|
1278
|
+
const prevOverload = prevOverloads[i];
|
1279
|
+
if (types_1.FunctionType.isOverloaded(functionType) &&
|
1280
|
+
types_1.FunctionType.isOverloaded(prevOverload) &&
|
1281
|
+
this._isOverlappingOverload(prevOverload, functionType)) {
|
1282
|
+
const prevReturnType = types_1.FunctionType.getSpecializedReturnType(prevOverload);
|
1283
|
+
const returnType = types_1.FunctionType.getSpecializedReturnType(functionType);
|
1284
|
+
if (prevReturnType &&
|
1285
|
+
returnType &&
|
1286
|
+
!this._evaluator.assignType(returnType, prevReturnType,
|
1287
|
+
/* diag */ undefined, new typeVarContext_1.TypeVarContext(),
|
1288
|
+
/* srcTypeVarContext */ undefined, 8 /* SkipSolveTypeVars */ | 512 /* IgnoreTypeVarScope */)) {
|
1289
|
+
const altNode = this._findNodeForOverload(node, prevOverload);
|
1290
|
+
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportOverlappingOverload, diagnosticRules_1.DiagnosticRule.reportOverlappingOverload, localize_1.Localizer.Diagnostic.overloadReturnTypeMismatch().format({
|
1291
|
+
name: node.name.value,
|
1292
|
+
newIndex: prevOverloads.length + 1,
|
1293
|
+
prevIndex: i + 1,
|
1294
|
+
}), (altNode || node).name);
|
1295
|
+
break;
|
1296
|
+
}
|
1297
|
+
}
|
1298
|
+
}
|
1299
|
+
}
|
1300
|
+
// Mypy reports overlapping overload errors on the line that contains the
|
1301
|
+
// earlier overload. Typeshed stubs contain type: ignore comments on these
|
1302
|
+
// lines, so it is important for us to report them in the same manner.
|
1303
|
+
_findNodeForOverload(functionNode, overloadType) {
|
1304
|
+
const decls = this._evaluator.getDeclarationsForNameNode(functionNode.name);
|
1305
|
+
if (!decls) {
|
1306
|
+
return undefined;
|
1307
|
+
}
|
1308
|
+
for (const decl of decls) {
|
1309
|
+
if (decl.type === 3 /* Function */) {
|
1310
|
+
const functionType = this._evaluator.getTypeOfFunction(decl.node);
|
1311
|
+
if ((functionType === null || functionType === void 0 ? void 0 : functionType.functionType) === overloadType) {
|
1312
|
+
return decl.node;
|
1313
|
+
}
|
1314
|
+
}
|
1315
|
+
}
|
1316
|
+
return undefined;
|
1317
|
+
}
|
1318
|
+
_isOverlappingOverload(functionType, prevOverload) {
|
1319
|
+
// According to precedent, the __get__ method is special-cased and is
|
1320
|
+
// exempt from overlapping overload checks. It's not clear why this is
|
1321
|
+
// the case, but for consistency with other type checkers, we'll honor
|
1322
|
+
// this rule. See https://github.com/python/typing/issues/253#issuecomment-389262904
|
1323
|
+
// for details.
|
1324
|
+
if (types_1.FunctionType.isInstanceMethod(functionType) && functionType.details.name === '__get__') {
|
1325
|
+
return false;
|
1326
|
+
}
|
1327
|
+
return this._evaluator.assignType(functionType, prevOverload,
|
1328
|
+
/* diag */ undefined, new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(functionType)),
|
1329
|
+
/* srcTypeVarContext */ undefined, 8 /* SkipSolveTypeVars */ |
|
1330
|
+
32 /* SkipFunctionReturnTypeCheck */ |
|
1331
|
+
16 /* OverloadOverlapCheck */);
|
1332
|
+
}
|
1333
|
+
_isLegalOverloadImplementation(overload, implementation, diag) {
|
1334
|
+
var _a;
|
1335
|
+
const implTypeVarContext = new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(implementation));
|
1336
|
+
const overloadTypeVarContext = new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(overload));
|
1337
|
+
// First check the parameters to see if they are assignable.
|
1338
|
+
let isLegal = this._evaluator.assignType(overload, implementation, diag, overloadTypeVarContext, implTypeVarContext, 32 /* SkipFunctionReturnTypeCheck */ |
|
1339
|
+
2 /* ReverseTypeVarMatching */ |
|
1340
|
+
256 /* SkipSelfClsTypeCheck */);
|
1341
|
+
// Now check the return types.
|
1342
|
+
const overloadReturnType = (_a = overload.details.declaredReturnType) !== null && _a !== void 0 ? _a : this._evaluator.getFunctionInferredReturnType(overload);
|
1343
|
+
const implementationReturnType = (0, typeUtils_1.applySolvedTypeVars)(implementation.details.declaredReturnType || this._evaluator.getFunctionInferredReturnType(implementation), implTypeVarContext);
|
1344
|
+
const returnDiag = new diagnostic_1.DiagnosticAddendum();
|
1345
|
+
if (!(0, types_1.isNever)(overloadReturnType) &&
|
1346
|
+
!this._evaluator.assignType(implementationReturnType, overloadReturnType, returnDiag.createAddendum(), implTypeVarContext, overloadTypeVarContext, 8 /* SkipSolveTypeVars */)) {
|
1347
|
+
returnDiag.addMessage(localize_1.Localizer.DiagnosticAddendum.functionReturnTypeMismatch().format({
|
1348
|
+
sourceType: this._evaluator.printType(overloadReturnType, /* expandTypeAlias */ false),
|
1349
|
+
destType: this._evaluator.printType(implementationReturnType, /* expandTypeAlias */ false),
|
1350
|
+
}));
|
1351
|
+
diag === null || diag === void 0 ? void 0 : diag.addAddendum(returnDiag);
|
1352
|
+
isLegal = false;
|
1353
|
+
}
|
1354
|
+
return isLegal;
|
1355
|
+
}
|
1356
|
+
_walkStatementsAndReportUnreachable(statements) {
|
1357
|
+
let reportedUnreachable = false;
|
1358
|
+
let prevStatement;
|
1359
|
+
for (const statement of statements) {
|
1360
|
+
// No need to report unreachable more than once since the first time
|
1361
|
+
// covers all remaining statements in the statement list.
|
1362
|
+
if (!reportedUnreachable) {
|
1363
|
+
if (!this._evaluator.isNodeReachable(statement, prevStatement)) {
|
1364
|
+
// Create a text range that covers the next statement through
|
1365
|
+
// the end of the statement list.
|
1366
|
+
const start = statement.start;
|
1367
|
+
const lastStatement = statements[statements.length - 1];
|
1368
|
+
const end = textRange_1.TextRange.getEnd(lastStatement);
|
1369
|
+
this._evaluator.addUnusedCode(statement, { start, length: end - start });
|
1370
|
+
reportedUnreachable = true;
|
1371
|
+
}
|
1372
|
+
}
|
1373
|
+
if (!reportedUnreachable && this._fileInfo.isStubFile) {
|
1374
|
+
this._validateStubStatement(statement);
|
1375
|
+
}
|
1376
|
+
this.walk(statement);
|
1377
|
+
prevStatement = statement;
|
1378
|
+
}
|
1379
|
+
}
|
1380
|
+
_validateStubStatement(statement) {
|
1381
|
+
switch (statement.nodeType) {
|
1382
|
+
case 19 /* If */:
|
1383
|
+
case 28 /* Function */:
|
1384
|
+
case 10 /* Class */:
|
1385
|
+
case 0 /* Error */: {
|
1386
|
+
// These are allowed in a stub file.
|
1387
|
+
break;
|
1388
|
+
}
|
1389
|
+
case 57 /* While */:
|
1390
|
+
case 26 /* For */:
|
1391
|
+
case 53 /* Try */:
|
1392
|
+
case 58 /* With */: {
|
1393
|
+
// These are not allowed.
|
1394
|
+
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportInvalidStubStatement, diagnosticRules_1.DiagnosticRule.reportInvalidStubStatement, localize_1.Localizer.Diagnostic.invalidStubStatement(), statement);
|
1395
|
+
break;
|
1396
|
+
}
|
1397
|
+
case 47 /* StatementList */: {
|
1398
|
+
for (const substatement of statement.statements) {
|
1399
|
+
let isValid = true;
|
1400
|
+
switch (substatement.nodeType) {
|
1401
|
+
case 2 /* Assert */:
|
1402
|
+
case 4 /* AssignmentExpression */:
|
1403
|
+
case 6 /* Await */:
|
1404
|
+
case 7 /* BinaryOperation */:
|
1405
|
+
case 11 /* Constant */:
|
1406
|
+
case 14 /* Del */:
|
1407
|
+
case 15 /* Dictionary */:
|
1408
|
+
case 24 /* Index */:
|
1409
|
+
case 26 /* For */:
|
1410
|
+
case 27 /* FormatString */:
|
1411
|
+
case 29 /* Global */:
|
1412
|
+
case 30 /* Lambda */:
|
1413
|
+
case 31 /* List */:
|
1414
|
+
case 35 /* MemberAccess */:
|
1415
|
+
case 38 /* Name */:
|
1416
|
+
case 39 /* Nonlocal */:
|
1417
|
+
case 40 /* Number */:
|
1418
|
+
case 43 /* Raise */:
|
1419
|
+
case 44 /* Return */:
|
1420
|
+
case 45 /* Set */:
|
1421
|
+
case 46 /* Slice */:
|
1422
|
+
case 51 /* Ternary */:
|
1423
|
+
case 52 /* Tuple */:
|
1424
|
+
case 53 /* Try */:
|
1425
|
+
case 55 /* UnaryOperation */:
|
1426
|
+
case 56 /* Unpack */:
|
1427
|
+
case 57 /* While */:
|
1428
|
+
case 58 /* With */:
|
1429
|
+
case 59 /* WithItem */:
|
1430
|
+
case 60 /* Yield */:
|
1431
|
+
case 61 /* YieldFrom */: {
|
1432
|
+
isValid = false;
|
1433
|
+
break;
|
1434
|
+
}
|
1435
|
+
case 5 /* AugmentedAssignment */: {
|
1436
|
+
// Exempt __all__ manipulations.
|
1437
|
+
isValid =
|
1438
|
+
substatement.operator === 1 /* AddEqual */ &&
|
1439
|
+
substatement.leftExpression.nodeType === 38 /* Name */ &&
|
1440
|
+
substatement.leftExpression.value === '__all__';
|
1441
|
+
break;
|
1442
|
+
}
|
1443
|
+
case 9 /* Call */: {
|
1444
|
+
// Exempt __all__ manipulations.
|
1445
|
+
isValid =
|
1446
|
+
substatement.leftExpression.nodeType === 35 /* MemberAccess */ &&
|
1447
|
+
substatement.leftExpression.leftExpression.nodeType === 38 /* Name */ &&
|
1448
|
+
substatement.leftExpression.leftExpression.value === '__all__';
|
1449
|
+
break;
|
1450
|
+
}
|
1451
|
+
}
|
1452
|
+
if (!isValid) {
|
1453
|
+
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportInvalidStubStatement, diagnosticRules_1.DiagnosticRule.reportInvalidStubStatement, localize_1.Localizer.Diagnostic.invalidStubStatement(), substatement);
|
1454
|
+
}
|
1455
|
+
}
|
1456
|
+
}
|
1457
|
+
}
|
1458
|
+
}
|
1459
|
+
_validateExceptionType(exceptionType, errorNode) {
|
1460
|
+
const baseExceptionType = this._evaluator.getBuiltInType(errorNode, 'BaseException');
|
1461
|
+
const derivesFromBaseException = (classType) => {
|
1462
|
+
if (!baseExceptionType || !(0, types_1.isInstantiableClass)(baseExceptionType)) {
|
1463
|
+
return true;
|
1464
|
+
}
|
1465
|
+
return (0, typeUtils_1.derivesFromClassRecursive)(classType, baseExceptionType, /* ignoreUnknown */ false);
|
1466
|
+
};
|
1467
|
+
const diagAddendum = new diagnostic_1.DiagnosticAddendum();
|
1468
|
+
let resultingExceptionType;
|
1469
|
+
if ((0, types_1.isAnyOrUnknown)(exceptionType)) {
|
1470
|
+
resultingExceptionType = exceptionType;
|
1471
|
+
}
|
1472
|
+
else {
|
1473
|
+
if ((0, types_1.isInstantiableClass)(exceptionType)) {
|
1474
|
+
if (!derivesFromBaseException(exceptionType)) {
|
1475
|
+
diagAddendum.addMessage(localize_1.Localizer.Diagnostic.exceptionTypeIncorrect().format({
|
1476
|
+
type: this._evaluator.printType(exceptionType, /* expandTypeAlias */ false),
|
1477
|
+
}));
|
1478
|
+
}
|
1479
|
+
resultingExceptionType = types_1.ClassType.cloneAsInstance(exceptionType);
|
1480
|
+
}
|
1481
|
+
else if ((0, types_1.isClassInstance)(exceptionType)) {
|
1482
|
+
const iterableType = this._evaluator.getTypeOfIterator(exceptionType, /* isAsync */ false, errorNode) ||
|
1483
|
+
types_1.UnknownType.create();
|
1484
|
+
resultingExceptionType = (0, typeUtils_1.mapSubtypes)(iterableType, (subtype) => {
|
1485
|
+
if ((0, types_1.isAnyOrUnknown)(subtype)) {
|
1486
|
+
return subtype;
|
1487
|
+
}
|
1488
|
+
if ((0, types_1.isInstantiableClass)(subtype)) {
|
1489
|
+
if (!derivesFromBaseException(subtype)) {
|
1490
|
+
diagAddendum.addMessage(localize_1.Localizer.Diagnostic.exceptionTypeIncorrect().format({
|
1491
|
+
type: this._evaluator.printType(exceptionType, /* expandTypeAlias */ false),
|
1492
|
+
}));
|
1493
|
+
}
|
1494
|
+
return types_1.ClassType.cloneAsInstance(subtype);
|
1495
|
+
}
|
1496
|
+
diagAddendum.addMessage(localize_1.Localizer.Diagnostic.exceptionTypeIncorrect().format({
|
1497
|
+
type: this._evaluator.printType(exceptionType, /* expandTypeAlias */ false),
|
1498
|
+
}));
|
1499
|
+
return types_1.UnknownType.create();
|
1500
|
+
});
|
1501
|
+
}
|
1502
|
+
}
|
1503
|
+
if (!diagAddendum.isEmpty()) {
|
1504
|
+
this._evaluator.addError(localize_1.Localizer.Diagnostic.exceptionTypeNotClass().format({
|
1505
|
+
type: this._evaluator.printType(exceptionType, /* expandTypeAlias */ false),
|
1506
|
+
}), errorNode);
|
1507
|
+
}
|
1508
|
+
return resultingExceptionType || types_1.UnknownType.create();
|
1509
|
+
}
|
1510
|
+
_reportUnusedDunderAllSymbols(nodes) {
|
1511
|
+
// If this rule is disabled, don't bother doing the work.
|
1512
|
+
if (this._fileInfo.diagnosticRuleSet.reportUnsupportedDunderAll === 'none') {
|
1513
|
+
return;
|
1514
|
+
}
|
1515
|
+
const moduleScope = AnalyzerNodeInfo.getScope(this._moduleNode);
|
1516
|
+
if (!moduleScope) {
|
1517
|
+
return;
|
1518
|
+
}
|
1519
|
+
nodes.forEach((node) => {
|
1520
|
+
if (!moduleScope.symbolTable.has(node.value)) {
|
1521
|
+
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportUnsupportedDunderAll, diagnosticRules_1.DiagnosticRule.reportUnsupportedDunderAll, localize_1.Localizer.Diagnostic.dunderAllSymbolNotPresent().format({ name: node.value }), node);
|
1522
|
+
}
|
1523
|
+
});
|
1524
|
+
}
|
1525
|
+
_validateSymbolTables() {
|
1526
|
+
for (const scopedNode of this._scopedNodes) {
|
1527
|
+
const scope = AnalyzerNodeInfo.getScope(scopedNode);
|
1528
|
+
if (scope) {
|
1529
|
+
scope.symbolTable.forEach((symbol, name) => {
|
1530
|
+
this._conditionallyReportUnusedSymbol(name, symbol, scope.type);
|
1531
|
+
this._reportIncompatibleDeclarations(name, symbol);
|
1532
|
+
this._reportMultipleFinalDeclarations(name, symbol, scope.type);
|
1533
|
+
this._reportMultipleTypeAliasDeclarations(name, symbol);
|
1534
|
+
this._reportInvalidOverload(name, symbol);
|
1535
|
+
});
|
1536
|
+
}
|
1537
|
+
}
|
1538
|
+
}
|
1539
|
+
_reportInvalidOverload(name, symbol) {
|
1540
|
+
const typedDecls = symbol.getTypedDeclarations();
|
1541
|
+
if (typedDecls.length >= 1) {
|
1542
|
+
const primaryDecl = typedDecls[0];
|
1543
|
+
if (primaryDecl.type === 3 /* Function */) {
|
1544
|
+
const type = this._evaluator.getEffectiveTypeOfSymbol(symbol);
|
1545
|
+
const functions = (0, types_1.isOverloadedFunction)(type) ? type.overloads : (0, types_1.isFunction)(type) ? [type] : [];
|
1546
|
+
const overloadedFunctions = functions.filter((func) => types_1.FunctionType.isOverloaded(func));
|
1547
|
+
if (overloadedFunctions.length === 1) {
|
1548
|
+
// There should never be a single overload.
|
1549
|
+
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.singleOverload().format({ name }), primaryDecl.node.name);
|
1550
|
+
}
|
1551
|
+
overloadedFunctions.forEach((overload) => {
|
1552
|
+
if (overload.details.declaration &&
|
1553
|
+
!ParseTreeUtils.isFunctionSuiteEmpty(overload.details.declaration.node)) {
|
1554
|
+
const diag = new diagnostic_1.DiagnosticAddendum();
|
1555
|
+
diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overloadWithImplementation());
|
1556
|
+
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.overloadWithImplementation().format({ name }) + diag.getString(), overload.details.declaration.node.name);
|
1557
|
+
}
|
1558
|
+
});
|
1559
|
+
// If the file is not a stub and this is the first overload,
|
1560
|
+
// verify that there is an implementation.
|
1561
|
+
if (!this._fileInfo.isStubFile && overloadedFunctions.length > 0) {
|
1562
|
+
let implementationFunction;
|
1563
|
+
if ((0, types_1.isOverloadedFunction)(type) &&
|
1564
|
+
!types_1.FunctionType.isOverloaded(type.overloads[type.overloads.length - 1])) {
|
1565
|
+
implementationFunction = type.overloads[type.overloads.length - 1];
|
1566
|
+
}
|
1567
|
+
else if ((0, types_1.isFunction)(type) && !types_1.FunctionType.isOverloaded(type)) {
|
1568
|
+
implementationFunction = type;
|
1569
|
+
}
|
1570
|
+
if (!implementationFunction) {
|
1571
|
+
let isProtocolMethod = false;
|
1572
|
+
const containingClassNode = ParseTreeUtils.getEnclosingClassOrFunction(primaryDecl.node);
|
1573
|
+
if (containingClassNode && containingClassNode.nodeType === 10 /* Class */) {
|
1574
|
+
const classType = this._evaluator.getTypeOfClass(containingClassNode);
|
1575
|
+
if (classType && types_1.ClassType.isProtocolClass(classType.classType)) {
|
1576
|
+
isProtocolMethod = true;
|
1577
|
+
}
|
1578
|
+
}
|
1579
|
+
// If this is a method within a protocol class, don't require that
|
1580
|
+
// there is an implementation.
|
1581
|
+
if (!isProtocolMethod) {
|
1582
|
+
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.overloadWithoutImplementation().format({
|
1583
|
+
name: primaryDecl.node.name.value,
|
1584
|
+
}), primaryDecl.node.name);
|
1585
|
+
}
|
1586
|
+
}
|
1587
|
+
else if ((0, types_1.isOverloadedFunction)(type)) {
|
1588
|
+
// Verify that all overload signatures are assignable to implementation signature.
|
1589
|
+
type.overloads.forEach((overload, index) => {
|
1590
|
+
var _a, _b, _c, _d;
|
1591
|
+
if (overload === implementationFunction || !types_1.FunctionType.isOverloaded(overload)) {
|
1592
|
+
return;
|
1593
|
+
}
|
1594
|
+
const diag = new diagnostic_1.DiagnosticAddendum();
|
1595
|
+
if (!this._isLegalOverloadImplementation(overload, implementationFunction, diag)) {
|
1596
|
+
if (implementationFunction.details.declaration) {
|
1597
|
+
const diagnostic = this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.overloadImplementationMismatch().format({
|
1598
|
+
name,
|
1599
|
+
index: index + 1,
|
1600
|
+
}) + diag.getString(), implementationFunction.details.declaration.node.name);
|
1601
|
+
if (diagnostic && overload.details.declaration) {
|
1602
|
+
diagnostic.addRelatedInfo(localize_1.Localizer.DiagnosticAddendum.overloadSignature(), (_b = (_a = overload.details.declaration) === null || _a === void 0 ? void 0 : _a.path) !== null && _b !== void 0 ? _b : primaryDecl.path, (_d = (_c = overload.details.declaration) === null || _c === void 0 ? void 0 : _c.range) !== null && _d !== void 0 ? _d : primaryDecl.range);
|
1603
|
+
}
|
1604
|
+
}
|
1605
|
+
}
|
1606
|
+
});
|
1607
|
+
}
|
1608
|
+
}
|
1609
|
+
}
|
1610
|
+
}
|
1611
|
+
}
|
1612
|
+
_reportMultipleFinalDeclarations(name, symbol, scopeType) {
|
1613
|
+
if (!(0, symbolUtils_1.isFinalVariable)(symbol)) {
|
1614
|
+
return;
|
1615
|
+
}
|
1616
|
+
const decls = symbol.getDeclarations();
|
1617
|
+
let sawFinal = false;
|
1618
|
+
let sawAssignment = false;
|
1619
|
+
decls.forEach((decl) => {
|
1620
|
+
if ((0, declarationUtils_1.isFinalVariableDeclaration)(decl)) {
|
1621
|
+
if (sawFinal) {
|
1622
|
+
this._evaluator.addError(localize_1.Localizer.Diagnostic.finalRedeclaration().format({ name }), decl.node);
|
1623
|
+
}
|
1624
|
+
sawFinal = true;
|
1625
|
+
}
|
1626
|
+
if (decl.type === 1 /* Variable */ && decl.inferredTypeSource) {
|
1627
|
+
if (sawAssignment) {
|
1628
|
+
// We check for assignment of Final instance and class variables
|
1629
|
+
// the type evaluator because we need to take into account whether
|
1630
|
+
// the assignment is within an `__init__` method, so ignore class
|
1631
|
+
// scopes here.
|
1632
|
+
if (scopeType !== 2 /* Class */) {
|
1633
|
+
this._evaluator.addError(localize_1.Localizer.Diagnostic.finalReassigned().format({ name }), decl.node);
|
1634
|
+
}
|
1635
|
+
}
|
1636
|
+
sawAssignment = true;
|
1637
|
+
}
|
1638
|
+
});
|
1639
|
+
// If it's not a stub file, an assignment must be provided.
|
1640
|
+
if (!sawAssignment && !this._fileInfo.isStubFile) {
|
1641
|
+
const firstDecl = decls.find((decl) => decl.type === 1 /* Variable */ && decl.isFinal);
|
1642
|
+
if (firstDecl) {
|
1643
|
+
// Is this an instance variable declared within a dataclass? If so, it
|
1644
|
+
// is implicitly initialized by the synthesized `__init__` method and
|
1645
|
+
// therefore has an implied assignment.
|
1646
|
+
let isImplicitlyAssigned = false;
|
1647
|
+
if (symbol.isClassMember() && !symbol.isClassVar()) {
|
1648
|
+
const containingClass = ParseTreeUtils.getEnclosingClass(firstDecl.node, /* stopAtFunction */ true);
|
1649
|
+
if (containingClass) {
|
1650
|
+
const classType = this._evaluator.getTypeOfClass(containingClass);
|
1651
|
+
if (classType &&
|
1652
|
+
(0, types_1.isClass)(classType.decoratedType) &&
|
1653
|
+
types_1.ClassType.isDataClass(classType.decoratedType)) {
|
1654
|
+
isImplicitlyAssigned = true;
|
1655
|
+
}
|
1656
|
+
}
|
1657
|
+
}
|
1658
|
+
if (!isImplicitlyAssigned) {
|
1659
|
+
this._evaluator.addError(localize_1.Localizer.Diagnostic.finalUnassigned().format({ name }), firstDecl.node);
|
1660
|
+
}
|
1661
|
+
}
|
1662
|
+
}
|
1663
|
+
}
|
1664
|
+
_reportMultipleTypeAliasDeclarations(name, symbol) {
|
1665
|
+
const decls = symbol.getDeclarations();
|
1666
|
+
const typeAliasDecl = decls.find((decl) => (0, declarationUtils_1.isExplicitTypeAliasDeclaration)(decl));
|
1667
|
+
// If this is a type alias, there should be only one declaration.
|
1668
|
+
if (typeAliasDecl && decls.length > 1) {
|
1669
|
+
decls.forEach((decl) => {
|
1670
|
+
if (decl !== typeAliasDecl) {
|
1671
|
+
this._evaluator.addError(localize_1.Localizer.Diagnostic.typeAliasRedeclared().format({ name }), decl.node);
|
1672
|
+
}
|
1673
|
+
});
|
1674
|
+
}
|
1675
|
+
}
|
1676
|
+
_reportIncompatibleDeclarations(name, symbol) {
|
1677
|
+
// If there's one or more declaration with a declared type,
|
1678
|
+
// all other declarations should match. The only exception is
|
1679
|
+
// for functions that have an overload.
|
1680
|
+
const primaryDecl = (0, symbolUtils_1.getLastTypedDeclaredForSymbol)(symbol);
|
1681
|
+
// If there's no declaration with a declared type, we're done.
|
1682
|
+
if (!primaryDecl) {
|
1683
|
+
return;
|
1684
|
+
}
|
1685
|
+
// Special case the '_' symbol, which is used in single dispatch
|
1686
|
+
// code and other cases where the name does not matter.
|
1687
|
+
if (name === '_') {
|
1688
|
+
return;
|
1689
|
+
}
|
1690
|
+
let otherDecls = symbol.getDeclarations().filter((decl) => decl !== primaryDecl);
|
1691
|
+
// If it's a function, we can skip any other declarations
|
1692
|
+
// that are overloads or property setters/deleters.
|
1693
|
+
if (primaryDecl.type === 3 /* Function */) {
|
1694
|
+
const primaryDeclTypeInfo = this._evaluator.getTypeOfFunction(primaryDecl.node);
|
1695
|
+
otherDecls = otherDecls.filter((decl) => {
|
1696
|
+
if (decl.type !== 3 /* Function */) {
|
1697
|
+
return true;
|
1698
|
+
}
|
1699
|
+
const funcTypeInfo = this._evaluator.getTypeOfFunction(decl.node);
|
1700
|
+
if (!funcTypeInfo) {
|
1701
|
+
return true;
|
1702
|
+
}
|
1703
|
+
const decoratedType = primaryDeclTypeInfo
|
1704
|
+
? this._evaluator.makeTopLevelTypeVarsConcrete(primaryDeclTypeInfo.decoratedType)
|
1705
|
+
: undefined;
|
1706
|
+
// We need to handle properties in a careful manner because of
|
1707
|
+
// the way that setters and deleters are often defined using multiple
|
1708
|
+
// methods with the same name.
|
1709
|
+
if (decoratedType &&
|
1710
|
+
(0, types_1.isClassInstance)(decoratedType) &&
|
1711
|
+
types_1.ClassType.isPropertyClass(decoratedType) &&
|
1712
|
+
(0, types_1.isClassInstance)(funcTypeInfo.decoratedType) &&
|
1713
|
+
types_1.ClassType.isPropertyClass(funcTypeInfo.decoratedType)) {
|
1714
|
+
return funcTypeInfo.decoratedType.details.typeSourceId !== decoratedType.details.typeSourceId;
|
1715
|
+
}
|
1716
|
+
return !types_1.FunctionType.isOverloaded(funcTypeInfo.functionType);
|
1717
|
+
});
|
1718
|
+
}
|
1719
|
+
// If there are no other declarations to consider, we're done.
|
1720
|
+
if (otherDecls.length === 0) {
|
1721
|
+
return;
|
1722
|
+
}
|
1723
|
+
let primaryDeclInfo;
|
1724
|
+
if (primaryDecl.type === 3 /* Function */) {
|
1725
|
+
if (primaryDecl.isMethod) {
|
1726
|
+
primaryDeclInfo = localize_1.Localizer.DiagnosticAddendum.seeMethodDeclaration();
|
1727
|
+
}
|
1728
|
+
else {
|
1729
|
+
primaryDeclInfo = localize_1.Localizer.DiagnosticAddendum.seeFunctionDeclaration();
|
1730
|
+
}
|
1731
|
+
}
|
1732
|
+
else if (primaryDecl.type === 4 /* Class */) {
|
1733
|
+
primaryDeclInfo = localize_1.Localizer.DiagnosticAddendum.seeClassDeclaration();
|
1734
|
+
}
|
1735
|
+
else if (primaryDecl.type === 2 /* Parameter */) {
|
1736
|
+
primaryDeclInfo = localize_1.Localizer.DiagnosticAddendum.seeParameterDeclaration();
|
1737
|
+
}
|
1738
|
+
else if (primaryDecl.type === 1 /* Variable */) {
|
1739
|
+
primaryDeclInfo = localize_1.Localizer.DiagnosticAddendum.seeVariableDeclaration();
|
1740
|
+
}
|
1741
|
+
else {
|
1742
|
+
primaryDeclInfo = localize_1.Localizer.DiagnosticAddendum.seeDeclaration();
|
1743
|
+
}
|
1744
|
+
const addPrimaryDeclInfo = (diag) => {
|
1745
|
+
if (diag) {
|
1746
|
+
let primaryDeclNode;
|
1747
|
+
if (primaryDecl.type === 3 /* Function */ || primaryDecl.type === 4 /* Class */) {
|
1748
|
+
primaryDeclNode = primaryDecl.node.name;
|
1749
|
+
}
|
1750
|
+
else if (primaryDecl.type === 1 /* Variable */) {
|
1751
|
+
if (primaryDecl.node.nodeType === 38 /* Name */) {
|
1752
|
+
primaryDeclNode = primaryDecl.node;
|
1753
|
+
}
|
1754
|
+
}
|
1755
|
+
else if (primaryDecl.type === 2 /* Parameter */) {
|
1756
|
+
if (primaryDecl.node.name) {
|
1757
|
+
primaryDeclNode = primaryDecl.node.name;
|
1758
|
+
}
|
1759
|
+
}
|
1760
|
+
if (primaryDeclNode) {
|
1761
|
+
diag.addRelatedInfo(primaryDeclInfo, primaryDecl.path, primaryDecl.range);
|
1762
|
+
}
|
1763
|
+
}
|
1764
|
+
};
|
1765
|
+
for (const otherDecl of otherDecls) {
|
1766
|
+
if (otherDecl.type === 4 /* Class */) {
|
1767
|
+
const diag = this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.obscuredClassDeclaration().format({ name }), otherDecl.node.name);
|
1768
|
+
addPrimaryDeclInfo(diag);
|
1769
|
+
}
|
1770
|
+
else if (otherDecl.type === 3 /* Function */) {
|
1771
|
+
const primaryType = this._evaluator.getTypeForDeclaration(primaryDecl);
|
1772
|
+
// If the return type has not yet been inferred, do so now.
|
1773
|
+
if (primaryType && (0, types_1.isFunction)(primaryType)) {
|
1774
|
+
this._evaluator.getFunctionInferredReturnType(primaryType);
|
1775
|
+
}
|
1776
|
+
let duplicateIsOk = false;
|
1777
|
+
const otherType = this._evaluator.getTypeForDeclaration(otherDecl);
|
1778
|
+
const suite1 = ParseTreeUtils.getEnclosingSuite(primaryDecl.node);
|
1779
|
+
const suite2 = ParseTreeUtils.getEnclosingSuite(otherDecl.node);
|
1780
|
+
const isInSameStatementList = suite1 === suite2;
|
1781
|
+
// If the return type has not yet been inferred, do so now.
|
1782
|
+
if (otherType && (0, types_1.isFunction)(otherType)) {
|
1783
|
+
this._evaluator.getFunctionInferredReturnType(otherType);
|
1784
|
+
}
|
1785
|
+
// If both declarations are functions, it's OK if they
|
1786
|
+
// both have the same signatures.
|
1787
|
+
if (primaryType && otherType && (0, types_1.isTypeSame)(primaryType, otherType)) {
|
1788
|
+
duplicateIsOk = true;
|
1789
|
+
}
|
1790
|
+
if (!duplicateIsOk || isInSameStatementList) {
|
1791
|
+
const diag = this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, otherDecl.isMethod
|
1792
|
+
? localize_1.Localizer.Diagnostic.obscuredMethodDeclaration().format({ name })
|
1793
|
+
: localize_1.Localizer.Diagnostic.obscuredFunctionDeclaration().format({ name }), otherDecl.node.name);
|
1794
|
+
addPrimaryDeclInfo(diag);
|
1795
|
+
}
|
1796
|
+
}
|
1797
|
+
else if (otherDecl.type === 2 /* Parameter */) {
|
1798
|
+
if (otherDecl.node.name) {
|
1799
|
+
const diag = this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.obscuredParameterDeclaration().format({ name }), otherDecl.node.name);
|
1800
|
+
addPrimaryDeclInfo(diag);
|
1801
|
+
}
|
1802
|
+
}
|
1803
|
+
else if (otherDecl.type === 1 /* Variable */) {
|
1804
|
+
const primaryType = this._evaluator.getTypeForDeclaration(primaryDecl);
|
1805
|
+
if (otherDecl.typeAnnotationNode) {
|
1806
|
+
if (otherDecl.node.nodeType === 38 /* Name */) {
|
1807
|
+
let duplicateIsOk = false;
|
1808
|
+
// It's OK if they both have the same declared type.
|
1809
|
+
const otherType = this._evaluator.getTypeForDeclaration(otherDecl);
|
1810
|
+
if (primaryType && otherType && (0, types_1.isTypeSame)(primaryType, otherType)) {
|
1811
|
+
duplicateIsOk = true;
|
1812
|
+
}
|
1813
|
+
if (!duplicateIsOk) {
|
1814
|
+
const diag = this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.obscuredVariableDeclaration().format({ name }), otherDecl.node);
|
1815
|
+
addPrimaryDeclInfo(diag);
|
1816
|
+
}
|
1817
|
+
}
|
1818
|
+
}
|
1819
|
+
else if (primaryType && !(0, typeUtils_1.isProperty)(primaryType)) {
|
1820
|
+
if (primaryDecl.type === 3 /* Function */ || primaryDecl.type === 4 /* Class */) {
|
1821
|
+
const diag = this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.obscuredVariableDeclaration().format({ name }), otherDecl.node);
|
1822
|
+
addPrimaryDeclInfo(diag);
|
1823
|
+
}
|
1824
|
+
}
|
1825
|
+
}
|
1826
|
+
}
|
1827
|
+
}
|
1828
|
+
_conditionallyReportUnusedSymbol(name, symbol, scopeType) {
|
1829
|
+
const accessedSymbolMap = this._fileInfo.accessedSymbolMap;
|
1830
|
+
if (symbol.isIgnoredForProtocolMatch() || accessedSymbolMap.has(symbol.id)) {
|
1831
|
+
return;
|
1832
|
+
}
|
1833
|
+
// A name of "_" means "I know this symbol isn't used", so
|
1834
|
+
// don't report it as unused.
|
1835
|
+
if (name === '_') {
|
1836
|
+
return;
|
1837
|
+
}
|
1838
|
+
if (SymbolNameUtils.isDunderName(name)) {
|
1839
|
+
return;
|
1840
|
+
}
|
1841
|
+
const decls = symbol.getDeclarations();
|
1842
|
+
decls.forEach((decl) => {
|
1843
|
+
this._conditionallyReportUnusedDeclaration(decl, this._isSymbolPrivate(name, scopeType));
|
1844
|
+
});
|
1845
|
+
}
|
1846
|
+
_conditionallyReportUnusedDeclaration(decl, isPrivate) {
|
1847
|
+
let diagnosticLevel;
|
1848
|
+
let nameNode;
|
1849
|
+
let message;
|
1850
|
+
let rule;
|
1851
|
+
switch (decl.type) {
|
1852
|
+
case 6 /* Alias */:
|
1853
|
+
diagnosticLevel = this._fileInfo.diagnosticRuleSet.reportUnusedImport;
|
1854
|
+
rule = diagnosticRules_1.DiagnosticRule.reportUnusedImport;
|
1855
|
+
if (decl.node.nodeType === 21 /* ImportAs */) {
|
1856
|
+
if (decl.node.alias) {
|
1857
|
+
// Aliases in stub files are assumed to be re-exports.
|
1858
|
+
if (!this._fileInfo.isStubFile) {
|
1859
|
+
nameNode = decl.node.alias;
|
1860
|
+
}
|
1861
|
+
}
|
1862
|
+
else {
|
1863
|
+
// Handle multi-part names specially.
|
1864
|
+
const nameParts = decl.node.module.nameParts;
|
1865
|
+
if (nameParts.length > 0) {
|
1866
|
+
const multipartName = nameParts.map((np) => np.value).join('.');
|
1867
|
+
const textRange = { start: nameParts[0].start, length: nameParts[0].length };
|
1868
|
+
textRange_1.TextRange.extend(textRange, nameParts[nameParts.length - 1]);
|
1869
|
+
this._fileInfo.diagnosticSink.addUnusedCodeWithTextRange(localize_1.Localizer.Diagnostic.unaccessedSymbol().format({ name: multipartName }), textRange, { action: "pyright.unusedImport" /* unusedImport */ });
|
1870
|
+
this._evaluator.addDiagnosticForTextRange(this._fileInfo, this._fileInfo.diagnosticRuleSet.reportUnusedImport, diagnosticRules_1.DiagnosticRule.reportUnusedImport, localize_1.Localizer.Diagnostic.unaccessedImport().format({ name: multipartName }), textRange);
|
1871
|
+
return;
|
1872
|
+
}
|
1873
|
+
}
|
1874
|
+
}
|
1875
|
+
else if (decl.node.nodeType === 23 /* ImportFromAs */) {
|
1876
|
+
const importFrom = decl.node.parent;
|
1877
|
+
// If this is a stub file that is using the "from A import B as C" or "from . import C",
|
1878
|
+
// don't mark "C" as unaccessed because it's assumed to be re-exported.
|
1879
|
+
const isReexport = this._fileInfo.isStubFile && decl.node.alias !== undefined;
|
1880
|
+
// If this is a __future__ import, it's OK for the import symbol to be unaccessed.
|
1881
|
+
const isFuture = importFrom.module.nameParts.length === 1 &&
|
1882
|
+
importFrom.module.nameParts[0].value === '__future__';
|
1883
|
+
if (!isReexport && !isFuture) {
|
1884
|
+
nameNode = decl.node.alias || decl.node.name;
|
1885
|
+
}
|
1886
|
+
}
|
1887
|
+
if (nameNode) {
|
1888
|
+
message = localize_1.Localizer.Diagnostic.unaccessedImport().format({ name: nameNode.value });
|
1889
|
+
}
|
1890
|
+
break;
|
1891
|
+
case 1 /* Variable */:
|
1892
|
+
case 2 /* Parameter */:
|
1893
|
+
if (!isPrivate) {
|
1894
|
+
return;
|
1895
|
+
}
|
1896
|
+
if (this._fileInfo.isStubFile) {
|
1897
|
+
// Don't mark variables or parameters as unaccessed in
|
1898
|
+
// stub files. It's typical for them to be unaccessed here.
|
1899
|
+
return;
|
1900
|
+
}
|
1901
|
+
diagnosticLevel = this._fileInfo.diagnosticRuleSet.reportUnusedVariable;
|
1902
|
+
if (decl.node.nodeType === 38 /* Name */) {
|
1903
|
+
nameNode = decl.node;
|
1904
|
+
// Don't emit a diagnostic if the name starts with an underscore.
|
1905
|
+
// This indicates that the variable is unused.
|
1906
|
+
if (nameNode.value.startsWith('_')) {
|
1907
|
+
diagnosticLevel = 'none';
|
1908
|
+
}
|
1909
|
+
}
|
1910
|
+
else if (decl.node.nodeType === 41 /* Parameter */) {
|
1911
|
+
nameNode = decl.node.name;
|
1912
|
+
// Don't emit a diagnostic for unused parameters.
|
1913
|
+
diagnosticLevel = 'none';
|
1914
|
+
}
|
1915
|
+
if (nameNode) {
|
1916
|
+
rule = diagnosticRules_1.DiagnosticRule.reportUnusedVariable;
|
1917
|
+
message = localize_1.Localizer.Diagnostic.unaccessedVariable().format({ name: nameNode.value });
|
1918
|
+
}
|
1919
|
+
break;
|
1920
|
+
case 4 /* Class */:
|
1921
|
+
if (!isPrivate) {
|
1922
|
+
return;
|
1923
|
+
}
|
1924
|
+
// If a stub is exporting a private type, we'll assume that the author
|
1925
|
+
// knows what he or she is doing.
|
1926
|
+
if (this._fileInfo.isStubFile) {
|
1927
|
+
return;
|
1928
|
+
}
|
1929
|
+
diagnosticLevel = this._fileInfo.diagnosticRuleSet.reportUnusedClass;
|
1930
|
+
nameNode = decl.node.name;
|
1931
|
+
rule = diagnosticRules_1.DiagnosticRule.reportUnusedClass;
|
1932
|
+
message = localize_1.Localizer.Diagnostic.unaccessedClass().format({ name: nameNode.value });
|
1933
|
+
break;
|
1934
|
+
case 3 /* Function */:
|
1935
|
+
if (!isPrivate) {
|
1936
|
+
return;
|
1937
|
+
}
|
1938
|
+
// If a stub is exporting a private type, we'll assume that the author
|
1939
|
+
// knows what he or she is doing.
|
1940
|
+
if (this._fileInfo.isStubFile) {
|
1941
|
+
return;
|
1942
|
+
}
|
1943
|
+
diagnosticLevel = this._fileInfo.diagnosticRuleSet.reportUnusedFunction;
|
1944
|
+
nameNode = decl.node.name;
|
1945
|
+
rule = diagnosticRules_1.DiagnosticRule.reportUnusedFunction;
|
1946
|
+
message = localize_1.Localizer.Diagnostic.unaccessedFunction().format({ name: nameNode.value });
|
1947
|
+
break;
|
1948
|
+
default:
|
1949
|
+
return;
|
1950
|
+
}
|
1951
|
+
if (nameNode && rule !== undefined && message) {
|
1952
|
+
const action = rule === diagnosticRules_1.DiagnosticRule.reportUnusedImport ? { action: "pyright.unusedImport" /* unusedImport */ } : undefined;
|
1953
|
+
this._fileInfo.diagnosticSink.addUnusedCodeWithTextRange(localize_1.Localizer.Diagnostic.unaccessedSymbol().format({ name: nameNode.value }), nameNode, action);
|
1954
|
+
this._evaluator.addDiagnostic(diagnosticLevel, rule, message, nameNode);
|
1955
|
+
}
|
1956
|
+
}
|
1957
|
+
// Validates that a call to isinstance or issubclass are necessary. This is a
|
1958
|
+
// common source of programming errors. Also validates that arguments passed
|
1959
|
+
// to isinstance or issubclass won't generate exceptions.
|
1960
|
+
_validateIsInstanceCall(node) {
|
1961
|
+
if (node.leftExpression.nodeType !== 38 /* Name */ ||
|
1962
|
+
(node.leftExpression.value !== 'isinstance' && node.leftExpression.value !== 'issubclass') ||
|
1963
|
+
node.arguments.length !== 2) {
|
1964
|
+
return;
|
1965
|
+
}
|
1966
|
+
const callName = node.leftExpression.value;
|
1967
|
+
const isInstanceCheck = callName === 'isinstance';
|
1968
|
+
let arg0Type = this._evaluator.getType(node.arguments[0].valueExpression);
|
1969
|
+
if (!arg0Type) {
|
1970
|
+
return;
|
1971
|
+
}
|
1972
|
+
arg0Type = (0, typeUtils_1.mapSubtypes)(arg0Type, (subtype) => {
|
1973
|
+
return (0, typeUtils_1.transformPossibleRecursiveTypeAlias)(subtype);
|
1974
|
+
});
|
1975
|
+
const arg1Type = this._evaluator.getType(node.arguments[1].valueExpression);
|
1976
|
+
if (!arg1Type) {
|
1977
|
+
return;
|
1978
|
+
}
|
1979
|
+
let isValidType = true;
|
1980
|
+
(0, typeUtils_1.doForEachSubtype)(arg1Type, (arg1Subtype) => {
|
1981
|
+
if ((0, types_1.isClassInstance)(arg1Subtype) && types_1.ClassType.isTupleClass(arg1Subtype) && arg1Subtype.tupleTypeArguments) {
|
1982
|
+
if (arg1Subtype.tupleTypeArguments.some((typeArg) => !this._isTypeSupportedTypeForIsInstance(typeArg.type, isInstanceCheck))) {
|
1983
|
+
isValidType = false;
|
1984
|
+
}
|
1985
|
+
}
|
1986
|
+
else {
|
1987
|
+
if (!this._isTypeSupportedTypeForIsInstance(arg1Subtype, isInstanceCheck)) {
|
1988
|
+
isValidType = false;
|
1989
|
+
}
|
1990
|
+
}
|
1991
|
+
});
|
1992
|
+
if (!isValidType) {
|
1993
|
+
const diag = new diagnostic_1.DiagnosticAddendum();
|
1994
|
+
diag.addMessage(localize_1.Localizer.DiagnosticAddendum.typeVarNotAllowed());
|
1995
|
+
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, isInstanceCheck
|
1996
|
+
? localize_1.Localizer.Diagnostic.isInstanceInvalidType().format({
|
1997
|
+
type: this._evaluator.printType(arg1Type, /* expandTypeAlias */ false),
|
1998
|
+
}) + diag.getString()
|
1999
|
+
: localize_1.Localizer.Diagnostic.isSubclassInvalidType().format({
|
2000
|
+
type: this._evaluator.printType(arg1Type, /* expandTypeAlias */ false),
|
2001
|
+
}) + diag.getString(), node.arguments[1]);
|
2002
|
+
}
|
2003
|
+
// If this call is within an assert statement, we won't check whether
|
2004
|
+
// it's unnecessary.
|
2005
|
+
let curNode = node;
|
2006
|
+
while (curNode) {
|
2007
|
+
if (curNode.nodeType === 2 /* Assert */) {
|
2008
|
+
return;
|
2009
|
+
}
|
2010
|
+
curNode = curNode.parent;
|
2011
|
+
}
|
2012
|
+
// Several built-in classes don't follow the normal class hierarchy
|
2013
|
+
// rules, so we'll avoid emitting false-positive diagnostics if these
|
2014
|
+
// are used.
|
2015
|
+
const nonstandardClassTypes = [
|
2016
|
+
'FunctionType',
|
2017
|
+
'LambdaType',
|
2018
|
+
'BuiltinFunctionType',
|
2019
|
+
'BuiltinMethodType',
|
2020
|
+
'type',
|
2021
|
+
'Type',
|
2022
|
+
];
|
2023
|
+
const classTypeList = [];
|
2024
|
+
let arg1IncludesSubclasses = false;
|
2025
|
+
(0, typeUtils_1.doForEachSubtype)(arg1Type, (arg1Subtype) => {
|
2026
|
+
if ((0, types_1.isClass)(arg1Subtype)) {
|
2027
|
+
if (types_1.TypeBase.isInstantiable(arg1Subtype)) {
|
2028
|
+
if (arg1Subtype.literalValue === undefined) {
|
2029
|
+
classTypeList.push(arg1Subtype);
|
2030
|
+
if (types_1.ClassType.isBuiltIn(arg1Subtype) &&
|
2031
|
+
nonstandardClassTypes.some((name) => name === arg1Subtype.details.name)) {
|
2032
|
+
isValidType = false;
|
2033
|
+
}
|
2034
|
+
if (arg1Subtype.includeSubclasses) {
|
2035
|
+
arg1IncludesSubclasses = true;
|
2036
|
+
}
|
2037
|
+
}
|
2038
|
+
}
|
2039
|
+
else {
|
2040
|
+
// The isinstance and issubclass call supports a variation where the second
|
2041
|
+
// parameter is a tuple of classes.
|
2042
|
+
if ((0, typeUtils_1.isTupleClass)(arg1Subtype)) {
|
2043
|
+
if (arg1Subtype.tupleTypeArguments) {
|
2044
|
+
arg1Subtype.tupleTypeArguments.forEach((typeArg) => {
|
2045
|
+
if ((0, types_1.isInstantiableClass)(typeArg.type)) {
|
2046
|
+
classTypeList.push(typeArg.type);
|
2047
|
+
if (typeArg.type.includeSubclasses) {
|
2048
|
+
arg1IncludesSubclasses = true;
|
2049
|
+
}
|
2050
|
+
}
|
2051
|
+
else {
|
2052
|
+
isValidType = false;
|
2053
|
+
}
|
2054
|
+
});
|
2055
|
+
}
|
2056
|
+
}
|
2057
|
+
else {
|
2058
|
+
if (arg1Subtype.includeSubclasses) {
|
2059
|
+
arg1IncludesSubclasses = true;
|
2060
|
+
}
|
2061
|
+
}
|
2062
|
+
if (types_1.ClassType.isBuiltIn(arg1Subtype) &&
|
2063
|
+
nonstandardClassTypes.some((name) => name === arg1Subtype.details.name)) {
|
2064
|
+
isValidType = false;
|
2065
|
+
}
|
2066
|
+
}
|
2067
|
+
}
|
2068
|
+
else {
|
2069
|
+
isValidType = false;
|
2070
|
+
}
|
2071
|
+
});
|
2072
|
+
if (!isValidType) {
|
2073
|
+
return;
|
2074
|
+
}
|
2075
|
+
// According to PEP 544, protocol classes cannot be used as the right-hand
|
2076
|
+
// argument to isinstance or issubclass unless they are annotated as
|
2077
|
+
// "runtime checkable".
|
2078
|
+
if (classTypeList.some((type) => types_1.ClassType.isProtocolClass(type) && !types_1.ClassType.isRuntimeCheckable(type))) {
|
2079
|
+
this._evaluator.addError(localize_1.Localizer.Diagnostic.protocolUsedInCall().format({ name: callName }), node.arguments[1].valueExpression);
|
2080
|
+
}
|
2081
|
+
if ((0, typeUtils_1.derivesFromAnyOrUnknown)(arg0Type)) {
|
2082
|
+
return;
|
2083
|
+
}
|
2084
|
+
const finalizeFilteredTypeList = (types) => {
|
2085
|
+
return (0, types_1.combineTypes)(types);
|
2086
|
+
};
|
2087
|
+
const filterType = (varType) => {
|
2088
|
+
const filteredTypes = [];
|
2089
|
+
for (const filterType of classTypeList) {
|
2090
|
+
// Handle the special case where the variable type is a TypedDict and
|
2091
|
+
// we're filtering against 'dict'. TypedDict isn't derived from dict,
|
2092
|
+
// but at runtime, isinstance returns True.
|
2093
|
+
const filterIsSuperclass = types_1.ClassType.isDerivedFrom(varType, filterType) ||
|
2094
|
+
(isInstanceCheck &&
|
2095
|
+
types_1.ClassType.isProtocolClass(filterType) &&
|
2096
|
+
this._evaluator.assignType(filterType, varType)) ||
|
2097
|
+
(types_1.ClassType.isBuiltIn(filterType, 'dict') && types_1.ClassType.isTypedDictClass(varType));
|
2098
|
+
const filterIsSubclass = types_1.ClassType.isDerivedFrom(filterType, varType) ||
|
2099
|
+
(isInstanceCheck &&
|
2100
|
+
types_1.ClassType.isProtocolClass(varType) &&
|
2101
|
+
this._evaluator.assignType(varType, filterType));
|
2102
|
+
// Normally, a class should never be both a subclass and a
|
2103
|
+
// superclass. However, this can happen if one of the classes
|
2104
|
+
// derives from an unknown type. In this case, we'll add an
|
2105
|
+
// unknown type into the filtered type list to avoid any
|
2106
|
+
// false positives.
|
2107
|
+
const isClassRelationshipIndeterminate = filterIsSubclass && filterIsSubclass && !types_1.ClassType.isSameGenericClass(varType, filterType);
|
2108
|
+
if (isClassRelationshipIndeterminate) {
|
2109
|
+
filteredTypes.push(types_1.UnknownType.create());
|
2110
|
+
}
|
2111
|
+
else if (filterIsSuperclass) {
|
2112
|
+
// If the variable type is a subclass of the isinstance
|
2113
|
+
// filter, we haven't learned anything new about the
|
2114
|
+
// variable type.
|
2115
|
+
filteredTypes.push(varType);
|
2116
|
+
}
|
2117
|
+
else if (filterIsSubclass) {
|
2118
|
+
// If the variable type is a superclass of the isinstance
|
2119
|
+
// filter, we can narrow the type to the subclass.
|
2120
|
+
filteredTypes.push(filterType);
|
2121
|
+
}
|
2122
|
+
}
|
2123
|
+
if (!isInstanceCheck) {
|
2124
|
+
return filteredTypes;
|
2125
|
+
}
|
2126
|
+
// Make all instantiable classes into instances before returning them.
|
2127
|
+
return filteredTypes.map((t) => ((0, types_1.isInstantiableClass)(t) ? types_1.ClassType.cloneAsInstance(t) : t));
|
2128
|
+
};
|
2129
|
+
let filteredType;
|
2130
|
+
if (isInstanceCheck && (0, types_1.isClassInstance)(arg0Type)) {
|
2131
|
+
const remainingTypes = filterType(types_1.ClassType.cloneAsInstantiable(arg0Type));
|
2132
|
+
filteredType = finalizeFilteredTypeList(remainingTypes);
|
2133
|
+
}
|
2134
|
+
else if (!isInstanceCheck && (0, types_1.isInstantiableClass)(arg0Type)) {
|
2135
|
+
const remainingTypes = filterType(arg0Type);
|
2136
|
+
filteredType = finalizeFilteredTypeList(remainingTypes);
|
2137
|
+
}
|
2138
|
+
else if ((0, types_1.isUnion)(arg0Type)) {
|
2139
|
+
let remainingTypes = [];
|
2140
|
+
let foundAnyType = false;
|
2141
|
+
(0, typeUtils_1.doForEachSubtype)(arg0Type, (subtype) => {
|
2142
|
+
if ((0, types_1.isAnyOrUnknown)(subtype)) {
|
2143
|
+
foundAnyType = true;
|
2144
|
+
}
|
2145
|
+
if (isInstanceCheck && (0, types_1.isClassInstance)(subtype)) {
|
2146
|
+
remainingTypes = remainingTypes.concat(filterType(types_1.ClassType.cloneAsInstantiable(subtype)));
|
2147
|
+
}
|
2148
|
+
else if (!isInstanceCheck && (0, types_1.isInstantiableClass)(subtype)) {
|
2149
|
+
remainingTypes = remainingTypes.concat(filterType(subtype));
|
2150
|
+
}
|
2151
|
+
});
|
2152
|
+
filteredType = finalizeFilteredTypeList(remainingTypes);
|
2153
|
+
// If we found an any or unknown type, all bets are off.
|
2154
|
+
if (foundAnyType) {
|
2155
|
+
return;
|
2156
|
+
}
|
2157
|
+
}
|
2158
|
+
else {
|
2159
|
+
return;
|
2160
|
+
}
|
2161
|
+
const getTestType = () => {
|
2162
|
+
const objTypeList = classTypeList.map((t) => types_1.ClassType.cloneAsInstance(t));
|
2163
|
+
return (0, types_1.combineTypes)(objTypeList);
|
2164
|
+
};
|
2165
|
+
// If arg1IncludesSubclasses is true, it contains a Type[X] class rather than X. A Type[X]
|
2166
|
+
// could be a subclass of X, so the "unnecessary isinstance check" may be legit.
|
2167
|
+
if (!arg1IncludesSubclasses && (0, types_1.isTypeSame)(filteredType, arg0Type, /* ignorePseudoGeneric */ true)) {
|
2168
|
+
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportUnnecessaryIsInstance, diagnosticRules_1.DiagnosticRule.reportUnnecessaryIsInstance, isInstanceCheck
|
2169
|
+
? localize_1.Localizer.Diagnostic.unnecessaryIsInstanceAlways().format({
|
2170
|
+
testType: this._evaluator.printType(arg0Type, /* expandTypeAlias */ false),
|
2171
|
+
classType: this._evaluator.printType(getTestType(), /* expandTypeAlias */ false),
|
2172
|
+
})
|
2173
|
+
: localize_1.Localizer.Diagnostic.unnecessaryIsSubclassAlways().format({
|
2174
|
+
testType: this._evaluator.printType(arg0Type, /* expandTypeAlias */ false),
|
2175
|
+
classType: this._evaluator.printType(getTestType(), /* expandTypeAlias */ false),
|
2176
|
+
}), node);
|
2177
|
+
}
|
2178
|
+
}
|
2179
|
+
// Determines whether the specified type is allowed as the second argument
|
2180
|
+
// to an isinstance or issubclass check.
|
2181
|
+
_isTypeSupportedTypeForIsInstance(type, isInstanceCheck) {
|
2182
|
+
let isSupported = true;
|
2183
|
+
(0, typeUtils_1.doForEachSubtype)(type, (subtype) => {
|
2184
|
+
subtype = this._evaluator.makeTopLevelTypeVarsConcrete(subtype);
|
2185
|
+
switch (subtype.category) {
|
2186
|
+
case 2 /* Any */:
|
2187
|
+
case 1 /* Unknown */:
|
2188
|
+
case 0 /* Unbound */:
|
2189
|
+
break;
|
2190
|
+
case 7 /* Class */:
|
2191
|
+
// If it's a class, make sure that it has not been given explicit
|
2192
|
+
// type arguments. This will result in a TypeError exception.
|
2193
|
+
if (subtype.isTypeArgumentExplicit && !subtype.includeSubclasses) {
|
2194
|
+
isSupported = false;
|
2195
|
+
}
|
2196
|
+
break;
|
2197
|
+
case 3 /* None */:
|
2198
|
+
if (!isInstanceCheck) {
|
2199
|
+
isSupported = false;
|
2200
|
+
}
|
2201
|
+
else {
|
2202
|
+
isSupported = types_1.TypeBase.isInstantiable(subtype);
|
2203
|
+
}
|
2204
|
+
break;
|
2205
|
+
case 5 /* Function */:
|
2206
|
+
isSupported = types_1.TypeBase.isInstantiable(subtype);
|
2207
|
+
break;
|
2208
|
+
case 9 /* Union */:
|
2209
|
+
isSupported = this._isTypeSupportedTypeForIsInstance(subtype, isInstanceCheck);
|
2210
|
+
break;
|
2211
|
+
default:
|
2212
|
+
isSupported = false;
|
2213
|
+
break;
|
2214
|
+
}
|
2215
|
+
});
|
2216
|
+
return isSupported;
|
2217
|
+
}
|
2218
|
+
_isSymbolPrivate(nameValue, scopeType) {
|
2219
|
+
// All variables within the scope of a function or a list
|
2220
|
+
// comprehension are considered private.
|
2221
|
+
if (scopeType === 1 /* Function */ || scopeType === 0 /* ListComprehension */) {
|
2222
|
+
return true;
|
2223
|
+
}
|
2224
|
+
// See if the symbol is private.
|
2225
|
+
if (SymbolNameUtils.isPrivateName(nameValue)) {
|
2226
|
+
return true;
|
2227
|
+
}
|
2228
|
+
if (SymbolNameUtils.isProtectedName(nameValue)) {
|
2229
|
+
// Protected names outside of a class scope are considered private.
|
2230
|
+
const isClassScope = scopeType === 2 /* Class */;
|
2231
|
+
return !isClassScope;
|
2232
|
+
}
|
2233
|
+
return false;
|
2234
|
+
}
|
2235
|
+
_reportDeprecatedUse(node) {
|
2236
|
+
var _a;
|
2237
|
+
const deprecatedForm = (_a = deprecatedAliases.get(node.value)) !== null && _a !== void 0 ? _a : deprecatedSpecialForms.get(node.value);
|
2238
|
+
if (!deprecatedForm) {
|
2239
|
+
return;
|
2240
|
+
}
|
2241
|
+
const type = this._evaluator.getType(node);
|
2242
|
+
if (!type) {
|
2243
|
+
return;
|
2244
|
+
}
|
2245
|
+
if (!(0, types_1.isInstantiableClass)(type) || type.details.fullName !== deprecatedForm.fullName) {
|
2246
|
+
return;
|
2247
|
+
}
|
2248
|
+
if (this._fileInfo.executionEnvironment.pythonVersion >= deprecatedForm.version) {
|
2249
|
+
this._evaluator.addDeprecated(localize_1.Localizer.Diagnostic.deprecatedType().format({
|
2250
|
+
version: (0, pythonVersion_1.versionToString)(deprecatedForm.version),
|
2251
|
+
replacement: deprecatedForm.replacementText,
|
2252
|
+
}), node);
|
2253
|
+
}
|
2254
|
+
}
|
2255
|
+
_reportUnboundName(node) {
|
2256
|
+
if (this._fileInfo.diagnosticRuleSet.reportUnboundVariable === 'none') {
|
2257
|
+
return;
|
2258
|
+
}
|
2259
|
+
if (!AnalyzerNodeInfo.isCodeUnreachable(node)) {
|
2260
|
+
const type = this._evaluator.getType(node);
|
2261
|
+
if (type) {
|
2262
|
+
if ((0, types_1.isUnbound)(type)) {
|
2263
|
+
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportUnboundVariable, diagnosticRules_1.DiagnosticRule.reportUnboundVariable, localize_1.Localizer.Diagnostic.symbolIsUnbound().format({ name: node.value }), node);
|
2264
|
+
}
|
2265
|
+
else if ((0, types_1.isPossiblyUnbound)(type)) {
|
2266
|
+
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportUnboundVariable, diagnosticRules_1.DiagnosticRule.reportUnboundVariable, localize_1.Localizer.Diagnostic.symbolIsPossiblyUnbound().format({ name: node.value }), node);
|
2267
|
+
}
|
2268
|
+
}
|
2269
|
+
}
|
2270
|
+
}
|
2271
|
+
_conditionallyReportPrivateUsage(node) {
|
2272
|
+
var _a;
|
2273
|
+
if (this._fileInfo.diagnosticRuleSet.reportPrivateUsage === 'none') {
|
2274
|
+
return;
|
2275
|
+
}
|
2276
|
+
// Ignore privates in type stubs.
|
2277
|
+
if (this._fileInfo.isStubFile) {
|
2278
|
+
return;
|
2279
|
+
}
|
2280
|
+
// Ignore privates in named arguments.
|
2281
|
+
if (((_a = node.parent) === null || _a === void 0 ? void 0 : _a.nodeType) === 1 /* Argument */ && node.parent.name === node) {
|
2282
|
+
return;
|
2283
|
+
}
|
2284
|
+
const nameValue = node.value;
|
2285
|
+
const isPrivateName = SymbolNameUtils.isPrivateName(nameValue);
|
2286
|
+
const isProtectedName = SymbolNameUtils.isProtectedName(nameValue);
|
2287
|
+
// If it's not a protected or private name, don't bother with
|
2288
|
+
// any further checks.
|
2289
|
+
if (!isPrivateName && !isProtectedName) {
|
2290
|
+
return;
|
2291
|
+
}
|
2292
|
+
const declarations = this._evaluator.getDeclarationsForNameNode(node);
|
2293
|
+
let primaryDeclaration = declarations && declarations.length > 0 ? declarations[declarations.length - 1] : undefined;
|
2294
|
+
if (!primaryDeclaration || primaryDeclaration.node === node) {
|
2295
|
+
return;
|
2296
|
+
}
|
2297
|
+
if (primaryDeclaration.type === 6 /* Alias */) {
|
2298
|
+
// If this symbol is an import alias (i.e. it's a local name rather than the
|
2299
|
+
// original imported name), skip the private check.
|
2300
|
+
if (primaryDeclaration.usesLocalName) {
|
2301
|
+
return;
|
2302
|
+
}
|
2303
|
+
const resolvedAliasInfo = this._evaluator.resolveAliasDeclarationWithInfo(primaryDeclaration,
|
2304
|
+
/* resolveLocalNames */ true);
|
2305
|
+
if (!resolvedAliasInfo) {
|
2306
|
+
return;
|
2307
|
+
}
|
2308
|
+
primaryDeclaration = resolvedAliasInfo.declaration;
|
2309
|
+
// If the alias resolved to a stub file or py.typed source file
|
2310
|
+
// and the declaration is marked "externally visible", it is
|
2311
|
+
// exempt from private usage checks.
|
2312
|
+
if (!resolvedAliasInfo.isPrivate) {
|
2313
|
+
return;
|
2314
|
+
}
|
2315
|
+
}
|
2316
|
+
if (!primaryDeclaration || primaryDeclaration.node === node) {
|
2317
|
+
return;
|
2318
|
+
}
|
2319
|
+
let classNode;
|
2320
|
+
if (primaryDeclaration.node) {
|
2321
|
+
classNode = ParseTreeUtils.getEnclosingClass(primaryDeclaration.node);
|
2322
|
+
}
|
2323
|
+
// If this is the name of a class, find the class that contains it rather
|
2324
|
+
// than constraining the use of the class name within the class itself.
|
2325
|
+
if (primaryDeclaration.node && primaryDeclaration.node.parent && primaryDeclaration.node.parent === classNode) {
|
2326
|
+
classNode = ParseTreeUtils.getEnclosingClass(classNode);
|
2327
|
+
}
|
2328
|
+
// If it's a class member, check whether it's a legal protected access.
|
2329
|
+
let isProtectedAccess = false;
|
2330
|
+
if (classNode) {
|
2331
|
+
if (isProtectedName) {
|
2332
|
+
const declClassTypeInfo = this._evaluator.getTypeOfClass(classNode);
|
2333
|
+
if (declClassTypeInfo && (0, types_1.isInstantiableClass)(declClassTypeInfo.decoratedType)) {
|
2334
|
+
// If it's a member defined in a stub file, we'll assume that it's part
|
2335
|
+
// of the public contract even if it's named as though it's private.
|
2336
|
+
if (types_1.ClassType.isDefinedInStub(declClassTypeInfo.decoratedType)) {
|
2337
|
+
return;
|
2338
|
+
}
|
2339
|
+
// Note that the access is to a protected class member.
|
2340
|
+
isProtectedAccess = true;
|
2341
|
+
const enclosingClassNode = ParseTreeUtils.getEnclosingClass(node);
|
2342
|
+
if (enclosingClassNode) {
|
2343
|
+
const enclosingClassTypeInfo = this._evaluator.getTypeOfClass(enclosingClassNode);
|
2344
|
+
// If the referencing class is a subclass of the declaring class, it's
|
2345
|
+
// allowed to access a protected name.
|
2346
|
+
if (enclosingClassTypeInfo && (0, types_1.isInstantiableClass)(enclosingClassTypeInfo.decoratedType)) {
|
2347
|
+
if ((0, typeUtils_1.derivesFromClassRecursive)(enclosingClassTypeInfo.decoratedType, declClassTypeInfo.decoratedType,
|
2348
|
+
/* ignoreUnknown */ true)) {
|
2349
|
+
return;
|
2350
|
+
}
|
2351
|
+
}
|
2352
|
+
}
|
2353
|
+
}
|
2354
|
+
}
|
2355
|
+
}
|
2356
|
+
if (classNode && !ParseTreeUtils.isNodeContainedWithin(node, classNode)) {
|
2357
|
+
if (isProtectedAccess) {
|
2358
|
+
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportPrivateUsage, diagnosticRules_1.DiagnosticRule.reportPrivateUsage, localize_1.Localizer.Diagnostic.protectedUsedOutsideOfClass().format({ name: nameValue }), node);
|
2359
|
+
}
|
2360
|
+
else {
|
2361
|
+
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportPrivateUsage, diagnosticRules_1.DiagnosticRule.reportPrivateUsage, localize_1.Localizer.Diagnostic.privateUsedOutsideOfClass().format({ name: nameValue }), node);
|
2362
|
+
}
|
2363
|
+
}
|
2364
|
+
}
|
2365
|
+
// Validates that an enum class does not attempt to override another
|
2366
|
+
// enum class that has already defined values.
|
2367
|
+
_validateEnumClassOverride(node, classType) {
|
2368
|
+
classType.details.baseClasses.forEach((baseClass, index) => {
|
2369
|
+
if ((0, types_1.isClass)(baseClass) && types_1.ClassType.isEnumClass(baseClass)) {
|
2370
|
+
// Determine whether the base enum class defines an enumerated value.
|
2371
|
+
let baseEnumDefinesValue = false;
|
2372
|
+
baseClass.details.fields.forEach((symbol) => {
|
2373
|
+
const symbolType = this._evaluator.getEffectiveTypeOfSymbol(symbol);
|
2374
|
+
if ((0, types_1.isClassInstance)(symbolType) && types_1.ClassType.isSameGenericClass(symbolType, baseClass)) {
|
2375
|
+
baseEnumDefinesValue = true;
|
2376
|
+
}
|
2377
|
+
});
|
2378
|
+
if (baseEnumDefinesValue) {
|
2379
|
+
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.enumClassOverride().format({ name: baseClass.details.name }), node.arguments[index]);
|
2380
|
+
}
|
2381
|
+
}
|
2382
|
+
});
|
2383
|
+
}
|
2384
|
+
// Verifies the rules specified in PEP 589 about TypedDict classes.
|
2385
|
+
// They cannot have statements other than type annotations, doc
|
2386
|
+
// strings, and "pass" statements or ellipses.
|
2387
|
+
_validateTypedDictClassSuite(suiteNode) {
|
2388
|
+
const emitBadStatementError = (node) => {
|
2389
|
+
this._evaluator.addError(localize_1.Localizer.Diagnostic.typedDictBadVar(), node);
|
2390
|
+
};
|
2391
|
+
suiteNode.statements.forEach((statement) => {
|
2392
|
+
if (!AnalyzerNodeInfo.isCodeUnreachable(statement)) {
|
2393
|
+
if (statement.nodeType === 47 /* StatementList */) {
|
2394
|
+
for (const substatement of statement.statements) {
|
2395
|
+
if (substatement.nodeType !== 54 /* TypeAnnotation */ &&
|
2396
|
+
substatement.nodeType !== 18 /* Ellipsis */ &&
|
2397
|
+
substatement.nodeType !== 48 /* StringList */ &&
|
2398
|
+
substatement.nodeType !== 42 /* Pass */) {
|
2399
|
+
emitBadStatementError(substatement);
|
2400
|
+
}
|
2401
|
+
}
|
2402
|
+
}
|
2403
|
+
else {
|
2404
|
+
emitBadStatementError(statement);
|
2405
|
+
}
|
2406
|
+
}
|
2407
|
+
});
|
2408
|
+
}
|
2409
|
+
_validateStrictTypeGuardFunction(node, functionType, isMethod) {
|
2410
|
+
var _a;
|
2411
|
+
// Is this a strict type guard function?
|
2412
|
+
if (!functionType.details.declaredReturnType) {
|
2413
|
+
return;
|
2414
|
+
}
|
2415
|
+
if (!(0, types_1.isClassInstance)(functionType.details.declaredReturnType) ||
|
2416
|
+
!types_1.ClassType.isBuiltIn(functionType.details.declaredReturnType, 'StrictTypeGuard') ||
|
2417
|
+
!functionType.details.declaredReturnType.typeArguments ||
|
2418
|
+
functionType.details.declaredReturnType.typeArguments.length < 1) {
|
2419
|
+
return;
|
2420
|
+
}
|
2421
|
+
const typeGuardType = functionType.details.declaredReturnType.typeArguments[0];
|
2422
|
+
// Determine the type of the first parameter.
|
2423
|
+
const paramIndex = isMethod && !types_1.FunctionType.isStaticMethod(functionType) ? 1 : 0;
|
2424
|
+
if (paramIndex >= functionType.details.parameters.length) {
|
2425
|
+
return;
|
2426
|
+
}
|
2427
|
+
const paramType = types_1.FunctionType.getEffectiveParameterType(functionType, paramIndex);
|
2428
|
+
// Verify that the typeGuardType is a narrower type than the paramType.
|
2429
|
+
if (!this._evaluator.assignType(paramType, typeGuardType)) {
|
2430
|
+
const returnAnnotation = node.returnTypeAnnotation || ((_a = node.functionAnnotationComment) === null || _a === void 0 ? void 0 : _a.returnTypeAnnotation);
|
2431
|
+
if (returnAnnotation) {
|
2432
|
+
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.strictTypeGuardReturnType().format({
|
2433
|
+
type: this._evaluator.printType(paramType),
|
2434
|
+
returnType: this._evaluator.printType(typeGuardType),
|
2435
|
+
}), returnAnnotation);
|
2436
|
+
}
|
2437
|
+
}
|
2438
|
+
}
|
2439
|
+
_validateDunderSignatures(node, functionType, isMethod) {
|
2440
|
+
var _a;
|
2441
|
+
const functionName = functionType.details.name;
|
2442
|
+
// Is this an '__init__' method? Verify that it returns None.
|
2443
|
+
if (isMethod && functionName === '__init__') {
|
2444
|
+
const returnAnnotation = node.returnTypeAnnotation || ((_a = node.functionAnnotationComment) === null || _a === void 0 ? void 0 : _a.returnTypeAnnotation);
|
2445
|
+
const declaredReturnType = functionType.details.declaredReturnType;
|
2446
|
+
if (returnAnnotation && declaredReturnType) {
|
2447
|
+
if (!(0, types_1.isNoneInstance)(declaredReturnType) && !(0, types_1.isNever)(declaredReturnType)) {
|
2448
|
+
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.initMustReturnNone(), returnAnnotation);
|
2449
|
+
}
|
2450
|
+
}
|
2451
|
+
else {
|
2452
|
+
const inferredReturnType = this._evaluator.getFunctionInferredReturnType(functionType);
|
2453
|
+
if (!(0, types_1.isNever)(inferredReturnType) &&
|
2454
|
+
!(0, types_1.isNoneInstance)(inferredReturnType) &&
|
2455
|
+
!(0, types_1.isAnyOrUnknown)(inferredReturnType)) {
|
2456
|
+
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.initMustReturnNone(), node.name);
|
2457
|
+
}
|
2458
|
+
}
|
2459
|
+
}
|
2460
|
+
}
|
2461
|
+
_validateFunctionReturn(node, functionType) {
|
2462
|
+
var _a;
|
2463
|
+
// Stub files are allowed not to return an actual value,
|
2464
|
+
// so skip this if it's a stub file.
|
2465
|
+
if (this._fileInfo.isStubFile) {
|
2466
|
+
return;
|
2467
|
+
}
|
2468
|
+
const returnAnnotation = node.returnTypeAnnotation || ((_a = node.functionAnnotationComment) === null || _a === void 0 ? void 0 : _a.returnTypeAnnotation);
|
2469
|
+
if (returnAnnotation) {
|
2470
|
+
const functionNeverReturns = !this._evaluator.isAfterNodeReachable(node);
|
2471
|
+
const implicitlyReturnsNone = this._evaluator.isAfterNodeReachable(node.suite);
|
2472
|
+
let declaredReturnType = functionType.details.declaredReturnType;
|
2473
|
+
if (declaredReturnType) {
|
2474
|
+
if ((0, types_1.isUnknown)(declaredReturnType)) {
|
2475
|
+
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportUnknownVariableType, diagnosticRules_1.DiagnosticRule.reportUnknownVariableType, localize_1.Localizer.Diagnostic.declaredReturnTypeUnknown(), returnAnnotation);
|
2476
|
+
}
|
2477
|
+
else if ((0, typeUtils_1.isPartlyUnknown)(declaredReturnType)) {
|
2478
|
+
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportUnknownVariableType, diagnosticRules_1.DiagnosticRule.reportUnknownVariableType, localize_1.Localizer.Diagnostic.declaredReturnTypePartiallyUnknown().format({
|
2479
|
+
returnType: this._evaluator.printType(declaredReturnType, /* expandTypeAlias */ true),
|
2480
|
+
}), returnAnnotation);
|
2481
|
+
}
|
2482
|
+
const diag = new diagnostic_1.DiagnosticAddendum();
|
2483
|
+
if ((0, types_1.isTypeVar)(declaredReturnType) && declaredReturnType.details.variance === 2 /* Contravariant */) {
|
2484
|
+
diag.addMessage(localize_1.Localizer.DiagnosticAddendum.typeVarIsContravariant().format({
|
2485
|
+
name: types_1.TypeVarType.getReadableName(declaredReturnType),
|
2486
|
+
}));
|
2487
|
+
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.returnTypeContravariant() + diag.getString(), returnAnnotation);
|
2488
|
+
}
|
2489
|
+
}
|
2490
|
+
// Wrap the declared type in a generator type if the function is a generator.
|
2491
|
+
if (types_1.FunctionType.isGenerator(functionType)) {
|
2492
|
+
declaredReturnType = (0, typeUtils_1.getDeclaredGeneratorReturnType)(functionType);
|
2493
|
+
}
|
2494
|
+
// The types of all return statement expressions were already checked
|
2495
|
+
// against the declared type, but we need to verify the implicit None
|
2496
|
+
// at the end of the function.
|
2497
|
+
if (declaredReturnType && !functionNeverReturns && implicitlyReturnsNone) {
|
2498
|
+
if ((0, types_1.isNever)(declaredReturnType)) {
|
2499
|
+
// If the function consists entirely of "...", assume that it's
|
2500
|
+
// an abstract method or a protocol method and don't require that
|
2501
|
+
// the return type matches. This check can also be skipped for an overload.
|
2502
|
+
if (!ParseTreeUtils.isSuiteEmpty(node.suite) && !types_1.FunctionType.isOverloaded(functionType)) {
|
2503
|
+
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.noReturnReturnsNone(), returnAnnotation);
|
2504
|
+
}
|
2505
|
+
}
|
2506
|
+
else if (!types_1.FunctionType.isAbstractMethod(functionType)) {
|
2507
|
+
// Make sure that the function doesn't implicitly return None if the declared
|
2508
|
+
// type doesn't allow it. Skip this check for abstract methods.
|
2509
|
+
const diagAddendum = new diagnostic_1.DiagnosticAddendum();
|
2510
|
+
// If the declared type isn't compatible with 'None', flag an error.
|
2511
|
+
if (!this._evaluator.assignType(declaredReturnType, types_1.NoneType.createInstance(), diagAddendum)) {
|
2512
|
+
// If the function consists entirely of "...", assume that it's
|
2513
|
+
// an abstract method or a protocol method and don't require that
|
2514
|
+
// the return type matches. This check can also be skipped for an overload.
|
2515
|
+
if (!ParseTreeUtils.isSuiteEmpty(node.suite) && !types_1.FunctionType.isOverloaded(functionType)) {
|
2516
|
+
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.returnMissing().format({
|
2517
|
+
returnType: this._evaluator.printType(declaredReturnType,
|
2518
|
+
/* expandTypeAlias */ false),
|
2519
|
+
}) + diagAddendum.getString(), returnAnnotation);
|
2520
|
+
}
|
2521
|
+
}
|
2522
|
+
}
|
2523
|
+
}
|
2524
|
+
}
|
2525
|
+
else {
|
2526
|
+
const inferredReturnType = this._evaluator.getFunctionInferredReturnType(functionType);
|
2527
|
+
if ((0, types_1.isUnknown)(inferredReturnType)) {
|
2528
|
+
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportUnknownParameterType, diagnosticRules_1.DiagnosticRule.reportUnknownParameterType, localize_1.Localizer.Diagnostic.returnTypeUnknown(), node.name);
|
2529
|
+
}
|
2530
|
+
else if ((0, typeUtils_1.isPartlyUnknown)(inferredReturnType)) {
|
2531
|
+
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportUnknownParameterType, diagnosticRules_1.DiagnosticRule.reportUnknownParameterType, localize_1.Localizer.Diagnostic.returnTypePartiallyUnknown().format({
|
2532
|
+
returnType: this._evaluator.printType(inferredReturnType, /* expandTypeAlias */ true),
|
2533
|
+
}), node.name);
|
2534
|
+
}
|
2535
|
+
}
|
2536
|
+
}
|
2537
|
+
// Validates that any overridden member variables are not marked
|
2538
|
+
// as Final in parent classes.
|
2539
|
+
_validateFinalMemberOverrides(classType) {
|
2540
|
+
classType.details.fields.forEach((localSymbol, name) => {
|
2541
|
+
const parentSymbol = (0, typeUtils_1.lookUpClassMember)(classType, name, 1 /* SkipOriginalClass */);
|
2542
|
+
if (parentSymbol &&
|
2543
|
+
(0, types_1.isInstantiableClass)(parentSymbol.classType) &&
|
2544
|
+
(0, symbolUtils_1.isFinalVariable)(parentSymbol.symbol) &&
|
2545
|
+
!SymbolNameUtils.isPrivateName(name)) {
|
2546
|
+
const decl = localSymbol.getDeclarations()[0];
|
2547
|
+
this._evaluator.addError(localize_1.Localizer.Diagnostic.finalRedeclarationBySubclass().format({
|
2548
|
+
name,
|
2549
|
+
className: parentSymbol.classType.details.name,
|
2550
|
+
}), decl.node);
|
2551
|
+
}
|
2552
|
+
});
|
2553
|
+
}
|
2554
|
+
_reportDuplicateEnumMembers(classType) {
|
2555
|
+
if (!types_1.ClassType.isEnumClass(classType) || types_1.ClassType.isBuiltIn(classType)) {
|
2556
|
+
return;
|
2557
|
+
}
|
2558
|
+
classType.details.fields.forEach((symbol, name) => {
|
2559
|
+
// Enum members don't have type annotations.
|
2560
|
+
if (symbol.getTypedDeclarations().length > 0) {
|
2561
|
+
return;
|
2562
|
+
}
|
2563
|
+
const decls = symbol.getDeclarations();
|
2564
|
+
if (decls.length >= 2 && decls[0].type === 1 /* Variable */) {
|
2565
|
+
const symbolType = this._evaluator.getEffectiveTypeOfSymbol(symbol);
|
2566
|
+
// Is this symbol a literal instance of the enum class?
|
2567
|
+
if ((0, types_1.isClassInstance)(symbolType) &&
|
2568
|
+
types_1.ClassType.isSameGenericClass(symbolType, classType) &&
|
2569
|
+
symbolType.literalValue !== undefined) {
|
2570
|
+
this._evaluator.addError(localize_1.Localizer.Diagnostic.duplicateEnumMember().format({ name }), decls[1].node);
|
2571
|
+
}
|
2572
|
+
}
|
2573
|
+
});
|
2574
|
+
}
|
2575
|
+
// If a non-protocol class explicitly inherits from a protocol class, this method
|
2576
|
+
// verifies that any class or instance variables declared but not assigned
|
2577
|
+
// in the protocol class are implemented in the subclass. It also checks that any
|
2578
|
+
// empty functions declared in the protocol are implemented in the subclass.
|
2579
|
+
_validateProtocolCompatibility(classType, errorNode) {
|
2580
|
+
if (types_1.ClassType.isProtocolClass(classType)) {
|
2581
|
+
return;
|
2582
|
+
}
|
2583
|
+
const diagAddendum = new diagnostic_1.DiagnosticAddendum();
|
2584
|
+
const isSymbolImplemented = (name) => {
|
2585
|
+
return classType.details.mro.some((mroClass) => {
|
2586
|
+
return (0, types_1.isClass)(mroClass) && !types_1.ClassType.isProtocolClass(mroClass) && mroClass.details.fields.has(name);
|
2587
|
+
});
|
2588
|
+
};
|
2589
|
+
classType.details.baseClasses.forEach((baseClass) => {
|
2590
|
+
if (!(0, types_1.isClass)(baseClass) || !types_1.ClassType.isProtocolClass(baseClass)) {
|
2591
|
+
return;
|
2592
|
+
}
|
2593
|
+
const protocolSymbols = (0, typeUtils_1.getProtocolSymbols)(baseClass);
|
2594
|
+
protocolSymbols.forEach((member, name) => {
|
2595
|
+
const decls = member.symbol.getDeclarations();
|
2596
|
+
if (decls.length === 0 || !(0, types_1.isClass)(member.classType)) {
|
2597
|
+
return;
|
2598
|
+
}
|
2599
|
+
if (decls[0].type === 1 /* Variable */) {
|
2600
|
+
// If none of the declarations involve assignments, assume it's
|
2601
|
+
// not implemented in the protocol.
|
2602
|
+
if (!decls.some((decl) => decl.type === 1 /* Variable */ && !!decl.inferredTypeSource)) {
|
2603
|
+
// This is a variable declaration that is not implemented in the
|
2604
|
+
// protocol base class. Make sure it's implemented in the derived class.
|
2605
|
+
if (!isSymbolImplemented(name)) {
|
2606
|
+
diagAddendum.addMessage(localize_1.Localizer.DiagnosticAddendum.missingProtocolMember().format({
|
2607
|
+
name,
|
2608
|
+
classType: member.classType.details.name,
|
2609
|
+
}));
|
2610
|
+
}
|
2611
|
+
}
|
2612
|
+
}
|
2613
|
+
else if (decls[0].type === 3 /* Function */) {
|
2614
|
+
if (ParseTreeUtils.isSuiteEmpty(decls[0].node.suite) && decls[0]) {
|
2615
|
+
if ((0, pathUtils_1.getFileExtension)(decls[0].path).toLowerCase() !== '.pyi') {
|
2616
|
+
if (!isSymbolImplemented(name)) {
|
2617
|
+
diagAddendum.addMessage(localize_1.Localizer.DiagnosticAddendum.missingProtocolMember().format({
|
2618
|
+
name,
|
2619
|
+
classType: member.classType.details.name,
|
2620
|
+
}));
|
2621
|
+
}
|
2622
|
+
}
|
2623
|
+
}
|
2624
|
+
}
|
2625
|
+
});
|
2626
|
+
});
|
2627
|
+
if (!diagAddendum.isEmpty()) {
|
2628
|
+
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.missingProtocolMembers() + diagAddendum.getString(), errorNode.name);
|
2629
|
+
}
|
2630
|
+
}
|
2631
|
+
// If a class is a dataclass with a `__post_init__` method, verify that its
|
2632
|
+
// signature is correct.
|
2633
|
+
_validateDataClassPostInit(classType, errorNode) {
|
2634
|
+
if (!types_1.ClassType.isDataClass(classType)) {
|
2635
|
+
return;
|
2636
|
+
}
|
2637
|
+
const postInitMember = (0, typeUtils_1.lookUpClassMember)(classType, '__post_init__', 2 /* SkipBaseClasses */ | 16 /* DeclaredTypesOnly */);
|
2638
|
+
// If there's no __post_init__ method, there's nothing to check.
|
2639
|
+
if (!postInitMember) {
|
2640
|
+
return;
|
2641
|
+
}
|
2642
|
+
// If the class derives from Any, we can't reliably apply the check.
|
2643
|
+
if (types_1.ClassType.derivesFromAnyOrUnknown(classType)) {
|
2644
|
+
return;
|
2645
|
+
}
|
2646
|
+
// Collect the list of init-only variables in the order they were declared.
|
2647
|
+
const initOnlySymbolMap = new Map();
|
2648
|
+
for (let i = classType.details.mro.length - 1; i >= 0; i--) {
|
2649
|
+
const mroClass = classType.details.mro[i];
|
2650
|
+
if ((0, types_1.isClass)(mroClass) && types_1.ClassType.isDataClass(mroClass)) {
|
2651
|
+
mroClass.details.fields.forEach((symbol, name) => {
|
2652
|
+
if (symbol.isInitVar()) {
|
2653
|
+
initOnlySymbolMap.set(name, symbol);
|
2654
|
+
}
|
2655
|
+
});
|
2656
|
+
}
|
2657
|
+
}
|
2658
|
+
const postInitType = this._evaluator.getTypeOfMember(postInitMember);
|
2659
|
+
if (!(0, types_1.isFunction)(postInitType) ||
|
2660
|
+
!types_1.FunctionType.isInstanceMethod(postInitType) ||
|
2661
|
+
!postInitType.details.declaration) {
|
2662
|
+
return;
|
2663
|
+
}
|
2664
|
+
const paramListDetails = (0, typeUtils_1.getParameterListDetails)(postInitType);
|
2665
|
+
// If there is an *args or **kwargs parameter or a keyword-only separator,
|
2666
|
+
// don't bother checking.
|
2667
|
+
if (paramListDetails.argsIndex !== undefined ||
|
2668
|
+
paramListDetails.kwargsIndex !== undefined ||
|
2669
|
+
paramListDetails.firstKeywordOnlyIndex !== undefined) {
|
2670
|
+
return;
|
2671
|
+
}
|
2672
|
+
// Verify that the parameter count matches.
|
2673
|
+
const nonDefaultParams = paramListDetails.params.filter((paramInfo) => !paramInfo.param.hasDefault);
|
2674
|
+
// We expect to see one param for "self" plus one for each of the InitVars.
|
2675
|
+
const expectedParamCount = initOnlySymbolMap.size + 1;
|
2676
|
+
if (expectedParamCount < nonDefaultParams.length || expectedParamCount > paramListDetails.params.length) {
|
2677
|
+
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.dataClassPostInitParamCount().format({ expected: initOnlySymbolMap.size }), postInitType.details.declaration.node.name);
|
2678
|
+
}
|
2679
|
+
// Verify that the parameter types match.
|
2680
|
+
let paramIndex = 1;
|
2681
|
+
initOnlySymbolMap.forEach((symbol, fieldName) => {
|
2682
|
+
if (paramIndex >= paramListDetails.params.length) {
|
2683
|
+
return;
|
2684
|
+
}
|
2685
|
+
const param = paramListDetails.params[paramIndex].param;
|
2686
|
+
if (param.hasDeclaredType && param.typeAnnotation) {
|
2687
|
+
const fieldType = this._evaluator.getDeclaredTypeOfSymbol(symbol);
|
2688
|
+
const paramType = types_1.FunctionType.getEffectiveParameterType(postInitType, paramListDetails.params[paramIndex].index);
|
2689
|
+
const assignTypeDiag = new diagnostic_1.DiagnosticAddendum();
|
2690
|
+
if (fieldType && !this._evaluator.assignType(paramType, fieldType, assignTypeDiag)) {
|
2691
|
+
const diagnostic = this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.dataClassPostInitType().format({ fieldName }) + assignTypeDiag.getString(), param.typeAnnotation);
|
2692
|
+
if (diagnostic) {
|
2693
|
+
const fieldDecls = symbol.getTypedDeclarations();
|
2694
|
+
if (fieldDecls.length > 0) {
|
2695
|
+
diagnostic.addRelatedInfo(localize_1.Localizer.DiagnosticAddendum.dataClassFieldLocation(), fieldDecls[0].path, fieldDecls[0].range);
|
2696
|
+
}
|
2697
|
+
}
|
2698
|
+
}
|
2699
|
+
}
|
2700
|
+
paramIndex++;
|
2701
|
+
});
|
2702
|
+
}
|
2703
|
+
// If a class is marked final, it must implement all abstract methods,
|
2704
|
+
// otherwise it is of no use.
|
2705
|
+
_validateFinalClassNotAbstract(classType, errorNode) {
|
2706
|
+
if (!types_1.ClassType.isFinal(classType)) {
|
2707
|
+
return;
|
2708
|
+
}
|
2709
|
+
if (!types_1.ClassType.supportsAbstractMethods(classType)) {
|
2710
|
+
return;
|
2711
|
+
}
|
2712
|
+
const abstractMethods = this._evaluator.getAbstractMethods(classType);
|
2713
|
+
if (abstractMethods.length === 0) {
|
2714
|
+
return;
|
2715
|
+
}
|
2716
|
+
const diagAddendum = new diagnostic_1.DiagnosticAddendum();
|
2717
|
+
const errorsToDisplay = 2;
|
2718
|
+
abstractMethods.forEach((abstractMethod, index) => {
|
2719
|
+
if (index === errorsToDisplay) {
|
2720
|
+
diagAddendum.addMessage(localize_1.Localizer.DiagnosticAddendum.memberIsAbstractMore().format({
|
2721
|
+
count: abstractMethods.length - errorsToDisplay,
|
2722
|
+
}));
|
2723
|
+
}
|
2724
|
+
else if (index < errorsToDisplay) {
|
2725
|
+
if ((0, types_1.isInstantiableClass)(abstractMethod.classType)) {
|
2726
|
+
const className = abstractMethod.classType.details.name;
|
2727
|
+
diagAddendum.addMessage(localize_1.Localizer.DiagnosticAddendum.memberIsAbstract().format({
|
2728
|
+
type: className,
|
2729
|
+
name: abstractMethod.symbolName,
|
2730
|
+
}));
|
2731
|
+
}
|
2732
|
+
}
|
2733
|
+
});
|
2734
|
+
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.finalClassIsAbstract().format({
|
2735
|
+
type: classType.details.name,
|
2736
|
+
}) + diagAddendum.getString(), errorNode.name);
|
2737
|
+
}
|
2738
|
+
// Reports the case where an instance variable is not declared or initialized
|
2739
|
+
// within the class body or constructor method.
|
2740
|
+
_validateInstanceVariableInitialization(classType) {
|
2741
|
+
// This check can be expensive, so don't perform it if the corresponding
|
2742
|
+
// rule is disabled.
|
2743
|
+
if (this._fileInfo.diagnosticRuleSet.reportUninitializedInstanceVariable === 'none') {
|
2744
|
+
return;
|
2745
|
+
}
|
2746
|
+
classType.details.fields.forEach((localSymbol, name) => {
|
2747
|
+
// This applies only to instance members.
|
2748
|
+
if (!localSymbol.isInstanceMember()) {
|
2749
|
+
return;
|
2750
|
+
}
|
2751
|
+
const decls = localSymbol.getDeclarations();
|
2752
|
+
// If the symbol is assigned (or at least declared) within the
|
2753
|
+
// class body or within the __init__ method, it can be ignored.
|
2754
|
+
if (decls.find((decl) => {
|
2755
|
+
var _a, _b, _c;
|
2756
|
+
const containingClass = ParseTreeUtils.getEnclosingClassOrFunction(decl.node);
|
2757
|
+
if (!containingClass) {
|
2758
|
+
return true;
|
2759
|
+
}
|
2760
|
+
if (containingClass.nodeType === 10 /* Class */) {
|
2761
|
+
// If this is part of an assignment statement, assume it has been
|
2762
|
+
// initialized as a class variable.
|
2763
|
+
if (((_a = decl.node.parent) === null || _a === void 0 ? void 0 : _a.nodeType) === 3 /* Assignment */) {
|
2764
|
+
return true;
|
2765
|
+
}
|
2766
|
+
if (((_b = decl.node.parent) === null || _b === void 0 ? void 0 : _b.nodeType) === 54 /* TypeAnnotation */ &&
|
2767
|
+
((_c = decl.node.parent.parent) === null || _c === void 0 ? void 0 : _c.nodeType) === 3 /* Assignment */) {
|
2768
|
+
return true;
|
2769
|
+
}
|
2770
|
+
// If this is part of a dataclass or a class handled by a dataclass_transform,
|
2771
|
+
// exempt it because the class variable will be transformed into an instance
|
2772
|
+
// variable in this case.
|
2773
|
+
if (types_1.ClassType.isDataClass(classType)) {
|
2774
|
+
return true;
|
2775
|
+
}
|
2776
|
+
// If this is part of a TypedDict, exempt it because the class variables
|
2777
|
+
// are not actually class variables in a TypedDict.
|
2778
|
+
if (types_1.ClassType.isTypedDictClass(classType)) {
|
2779
|
+
return true;
|
2780
|
+
}
|
2781
|
+
}
|
2782
|
+
if (containingClass.name.value === '__init__') {
|
2783
|
+
return true;
|
2784
|
+
}
|
2785
|
+
return false;
|
2786
|
+
})) {
|
2787
|
+
return;
|
2788
|
+
}
|
2789
|
+
// If the symbol is declared by its parent, we can assume it
|
2790
|
+
// is initialized there.
|
2791
|
+
const parentSymbol = (0, typeUtils_1.lookUpClassMember)(classType, name, 1 /* SkipOriginalClass */);
|
2792
|
+
if (parentSymbol) {
|
2793
|
+
return;
|
2794
|
+
}
|
2795
|
+
// Report the variable as uninitialized only on the first decl.
|
2796
|
+
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportUninitializedInstanceVariable, diagnosticRules_1.DiagnosticRule.reportUninitializedInstanceVariable, localize_1.Localizer.Diagnostic.uninitializedInstanceVariable().format({ name: name }), decls[0].node);
|
2797
|
+
});
|
2798
|
+
}
|
2799
|
+
// Validates that the type variables used in a generic protocol class have
|
2800
|
+
// the proper variance (invariant, covariant, contravariant). See PEP 544
|
2801
|
+
// for an explanation for why this is important to enforce.
|
2802
|
+
_validateProtocolTypeParamVariance(errorNode, classType) {
|
2803
|
+
const origTypeParams = classType.details.typeParameters.filter((typeParam) => !(0, types_1.isParamSpec)(typeParam));
|
2804
|
+
// If this isn't a generic protocol, there's nothing to do here.
|
2805
|
+
if (origTypeParams.length === 0) {
|
2806
|
+
return;
|
2807
|
+
}
|
2808
|
+
const objectType = this._evaluator.getBuiltInType(errorNode, 'object');
|
2809
|
+
if (!(0, types_1.isInstantiableClass)(objectType)) {
|
2810
|
+
return;
|
2811
|
+
}
|
2812
|
+
// Replace all of the type parameters with invariant TypeVars.
|
2813
|
+
const updatedTypeParams = origTypeParams.map((typeParam) => (0, types_1.isVariadicTypeVar)(typeParam) ? typeParam : types_1.TypeVarType.cloneAsInvariant(typeParam));
|
2814
|
+
const updatedClassType = types_1.ClassType.cloneWithNewTypeParameters(classType, updatedTypeParams);
|
2815
|
+
const objectObject = types_1.ClassType.cloneAsInstance(objectType);
|
2816
|
+
const dummyTypeObject = types_1.ClassType.createInstantiable('__protocolVarianceDummy', '', '', '', 0, 0, undefined, undefined);
|
2817
|
+
updatedTypeParams.forEach((param, paramIndex) => {
|
2818
|
+
// Skip variadics.
|
2819
|
+
if (param.details.isVariadic) {
|
2820
|
+
return;
|
2821
|
+
}
|
2822
|
+
// Replace all type arguments with a dummy type except for the
|
2823
|
+
// TypeVar of interest, which is replaced with an object instance.
|
2824
|
+
const srcTypeArgs = updatedTypeParams.map((p, i) => {
|
2825
|
+
if (p.details.isVariadic) {
|
2826
|
+
return p;
|
2827
|
+
}
|
2828
|
+
return i === paramIndex ? objectObject : dummyTypeObject;
|
2829
|
+
});
|
2830
|
+
// Replace all type arguments with a dummy type except for the
|
2831
|
+
// TypeVar of interest, which is replaced with itself.
|
2832
|
+
const destTypeArgs = updatedTypeParams.map((p, i) => {
|
2833
|
+
return i === paramIndex || p.details.isVariadic ? p : dummyTypeObject;
|
2834
|
+
});
|
2835
|
+
const srcType = types_1.ClassType.cloneForSpecialization(updatedClassType, srcTypeArgs,
|
2836
|
+
/* isTypeArgumentExplicit */ true);
|
2837
|
+
const destType = types_1.ClassType.cloneForSpecialization(updatedClassType, destTypeArgs,
|
2838
|
+
/* isTypeArgumentExplicit */ true);
|
2839
|
+
const isDestSubtypeOfSrc = (0, protocols_1.assignProtocolClassToSelf)(this._evaluator, srcType, destType);
|
2840
|
+
let expectedVariance;
|
2841
|
+
if (isDestSubtypeOfSrc) {
|
2842
|
+
expectedVariance = 1 /* Covariant */;
|
2843
|
+
}
|
2844
|
+
else {
|
2845
|
+
const isSrcSubtypeOfDest = (0, protocols_1.assignProtocolClassToSelf)(this._evaluator, destType, srcType);
|
2846
|
+
if (isSrcSubtypeOfDest) {
|
2847
|
+
expectedVariance = 2 /* Contravariant */;
|
2848
|
+
}
|
2849
|
+
else {
|
2850
|
+
expectedVariance = 0 /* Invariant */;
|
2851
|
+
}
|
2852
|
+
}
|
2853
|
+
if (expectedVariance !== origTypeParams[paramIndex].details.variance) {
|
2854
|
+
let message;
|
2855
|
+
if (expectedVariance === 1 /* Covariant */) {
|
2856
|
+
message = localize_1.Localizer.Diagnostic.protocolVarianceCovariant().format({
|
2857
|
+
variable: param.details.name,
|
2858
|
+
class: classType.details.name,
|
2859
|
+
});
|
2860
|
+
}
|
2861
|
+
else if (expectedVariance === 2 /* Contravariant */) {
|
2862
|
+
message = localize_1.Localizer.Diagnostic.protocolVarianceContravariant().format({
|
2863
|
+
variable: param.details.name,
|
2864
|
+
class: classType.details.name,
|
2865
|
+
});
|
2866
|
+
}
|
2867
|
+
else {
|
2868
|
+
message = localize_1.Localizer.Diagnostic.protocolVarianceInvariant().format({
|
2869
|
+
variable: param.details.name,
|
2870
|
+
class: classType.details.name,
|
2871
|
+
});
|
2872
|
+
}
|
2873
|
+
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportInvalidTypeVarUse, diagnosticRules_1.DiagnosticRule.reportInvalidTypeVarUse, message, errorNode.name);
|
2874
|
+
}
|
2875
|
+
});
|
2876
|
+
}
|
2877
|
+
// Validates that a class variable doesn't conflict with a __slots__
|
2878
|
+
// name. This will generate a runtime exception.
|
2879
|
+
_validateSlotsClassVarConflict(classType) {
|
2880
|
+
if (!classType.details.localSlotsNames) {
|
2881
|
+
// Nothing to check, since this class doesn't use __slots__.
|
2882
|
+
return;
|
2883
|
+
}
|
2884
|
+
// Don't apply this for dataclasses because their class variables
|
2885
|
+
// are transformed into instance variables.
|
2886
|
+
if (types_1.ClassType.isDataClass(classType)) {
|
2887
|
+
return;
|
2888
|
+
}
|
2889
|
+
classType.details.fields.forEach((symbol, name) => {
|
2890
|
+
const decls = symbol.getDeclarations();
|
2891
|
+
const isDefinedBySlots = decls.some((decl) => decl.type === 1 /* Variable */ && decl.isDefinedBySlots);
|
2892
|
+
if (isDefinedBySlots) {
|
2893
|
+
decls.forEach((decl) => {
|
2894
|
+
if (decl.type === 1 /* Variable */ &&
|
2895
|
+
!decl.isDefinedBySlots &&
|
2896
|
+
!decl.isDefinedByMemberAccess) {
|
2897
|
+
if (decl.node.nodeType === 38 /* Name */ && ParseTreeUtils.isWriteAccess(decl.node)) {
|
2898
|
+
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.slotsClassVarConflict().format({ name }), decl.node);
|
2899
|
+
}
|
2900
|
+
}
|
2901
|
+
});
|
2902
|
+
}
|
2903
|
+
});
|
2904
|
+
}
|
2905
|
+
// Validates that the __init__ and __new__ method signatures are consistent.
|
2906
|
+
_validateConstructorConsistency(classType) {
|
2907
|
+
const initMember = (0, typeUtils_1.lookUpClassMember)(classType, '__init__', 4 /* SkipObjectBaseClass */ | 8 /* SkipInstanceVariables */);
|
2908
|
+
const newMember = (0, typeUtils_1.lookUpClassMember)(classType, '__new__', 4 /* SkipObjectBaseClass */ | 8 /* SkipInstanceVariables */);
|
2909
|
+
if (!initMember || !newMember || !(0, types_1.isClass)(initMember.classType) || !(0, types_1.isClass)(newMember.classType)) {
|
2910
|
+
return;
|
2911
|
+
}
|
2912
|
+
// If both the __new__ and __init__ come from subclasses, don't bother
|
2913
|
+
// checking for this class.
|
2914
|
+
if (!types_1.ClassType.isSameGenericClass(newMember.classType, classType) &&
|
2915
|
+
!types_1.ClassType.isSameGenericClass(initMember.classType, classType)) {
|
2916
|
+
return;
|
2917
|
+
}
|
2918
|
+
// If the class that provides the __new__ method has a custom metaclass with a
|
2919
|
+
// __call__ method, skip this check.
|
2920
|
+
const metaclass = newMember.classType.details.effectiveMetaclass;
|
2921
|
+
if (metaclass && (0, types_1.isClass)(metaclass) && !types_1.ClassType.isBuiltIn(metaclass, 'type')) {
|
2922
|
+
const callMethod = (0, typeUtils_1.lookUpClassMember)(metaclass, '__call__', 32 /* SkipTypeBaseClass */ | 8 /* SkipInstanceVariables */);
|
2923
|
+
if (callMethod) {
|
2924
|
+
return;
|
2925
|
+
}
|
2926
|
+
}
|
2927
|
+
let newMemberType = this._evaluator.getTypeOfMember(newMember);
|
2928
|
+
if (!(0, types_1.isFunction)(newMemberType) && !(0, types_1.isOverloadedFunction)(newMemberType)) {
|
2929
|
+
return;
|
2930
|
+
}
|
2931
|
+
newMemberType = this._evaluator.bindFunctionToClassOrObject(classType, newMemberType,
|
2932
|
+
/* memberClass */ undefined,
|
2933
|
+
/* errorNode */ undefined,
|
2934
|
+
/* recursionCount */ undefined,
|
2935
|
+
/* treatConstructorAsClassMember */ true);
|
2936
|
+
if (!newMemberType) {
|
2937
|
+
return;
|
2938
|
+
}
|
2939
|
+
if ((0, types_1.isOverloadedFunction)(newMemberType)) {
|
2940
|
+
// Find the implementation, not the overloaded signatures.
|
2941
|
+
newMemberType = newMemberType.overloads.find((func) => !types_1.FunctionType.isOverloaded(func));
|
2942
|
+
if (!newMemberType) {
|
2943
|
+
return;
|
2944
|
+
}
|
2945
|
+
}
|
2946
|
+
let initMemberType = this._evaluator.getTypeOfMember(initMember);
|
2947
|
+
if (!(0, types_1.isFunction)(initMemberType) && !(0, types_1.isOverloadedFunction)(initMemberType)) {
|
2948
|
+
return;
|
2949
|
+
}
|
2950
|
+
initMemberType = this._evaluator.bindFunctionToClassOrObject(types_1.ClassType.cloneAsInstance(classType), initMemberType);
|
2951
|
+
if (!initMemberType) {
|
2952
|
+
return;
|
2953
|
+
}
|
2954
|
+
if ((0, types_1.isOverloadedFunction)(initMemberType)) {
|
2955
|
+
// Find the implementation, not the overloaded signatures.
|
2956
|
+
initMemberType = initMemberType.overloads.find((func) => !types_1.FunctionType.isOverloaded(func));
|
2957
|
+
if (!initMemberType) {
|
2958
|
+
return;
|
2959
|
+
}
|
2960
|
+
}
|
2961
|
+
if (!(0, types_1.isFunction)(initMemberType) || !(0, types_1.isFunction)(newMemberType)) {
|
2962
|
+
return;
|
2963
|
+
}
|
2964
|
+
// If either of the functions has a default parameter signature
|
2965
|
+
// (* args: Any, ** kwargs: Any), don't proceed with the check.
|
2966
|
+
if (types_1.FunctionType.hasDefaultParameters(initMemberType) || types_1.FunctionType.hasDefaultParameters(newMemberType)) {
|
2967
|
+
return;
|
2968
|
+
}
|
2969
|
+
// We'll set the "SkipArgsKwargs" flag for pragmatic reasons since __new__
|
2970
|
+
// often has an *args and/or **kwargs. We'll also set the ParamSpecValue
|
2971
|
+
// because we don't care about the return type for this check.
|
2972
|
+
initMemberType = types_1.FunctionType.cloneWithNewFlags(initMemberType, initMemberType.details.flags |
|
2973
|
+
32768 /* SkipArgsKwargsCompatibilityCheck */ |
|
2974
|
+
65536 /* ParamSpecValue */);
|
2975
|
+
newMemberType = types_1.FunctionType.cloneWithNewFlags(newMemberType, initMemberType.details.flags |
|
2976
|
+
32768 /* SkipArgsKwargsCompatibilityCheck */ |
|
2977
|
+
65536 /* ParamSpecValue */);
|
2978
|
+
if (!this._evaluator.assignType(newMemberType, initMemberType,
|
2979
|
+
/* diag */ undefined,
|
2980
|
+
/* destTypeVarContext */ undefined,
|
2981
|
+
/* srcTypeVarContext */ undefined, 32 /* SkipFunctionReturnTypeCheck */) ||
|
2982
|
+
!this._evaluator.assignType(initMemberType, newMemberType,
|
2983
|
+
/* diag */ undefined,
|
2984
|
+
/* destTypeVarContext */ undefined,
|
2985
|
+
/* srcTypeVarContext */ undefined, 32 /* SkipFunctionReturnTypeCheck */)) {
|
2986
|
+
const displayOnInit = types_1.ClassType.isSameGenericClass(initMember.classType, classType);
|
2987
|
+
const initDecl = (0, symbolUtils_1.getLastTypedDeclaredForSymbol)(initMember.symbol);
|
2988
|
+
const newDecl = (0, symbolUtils_1.getLastTypedDeclaredForSymbol)(newMember.symbol);
|
2989
|
+
if (initDecl && newDecl) {
|
2990
|
+
const mainDecl = displayOnInit ? initDecl : newDecl;
|
2991
|
+
const mainDeclNode = mainDecl.node.nodeType === 28 /* Function */ ? mainDecl.node.name : mainDecl.node;
|
2992
|
+
const diagAddendum = new diagnostic_1.DiagnosticAddendum();
|
2993
|
+
const initSignature = this._evaluator.printType(initMemberType);
|
2994
|
+
const newSignature = this._evaluator.printType(newMemberType);
|
2995
|
+
diagAddendum.addMessage(localize_1.Localizer.DiagnosticAddendum.initMethodSignature().format({
|
2996
|
+
type: initSignature,
|
2997
|
+
}));
|
2998
|
+
diagAddendum.addMessage(localize_1.Localizer.DiagnosticAddendum.newMethodSignature().format({
|
2999
|
+
type: newSignature,
|
3000
|
+
}));
|
3001
|
+
const diagnostic = this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportInconsistentConstructor, diagnosticRules_1.DiagnosticRule.reportInconsistentConstructor, localize_1.Localizer.Diagnostic.constructorParametersMismatch().format({
|
3002
|
+
classType: this._evaluator.printType(types_1.ClassType.cloneAsInstance(displayOnInit ? initMember.classType : newMember.classType)),
|
3003
|
+
}) + diagAddendum.getString(), mainDeclNode);
|
3004
|
+
if (diagnostic) {
|
3005
|
+
const secondaryDecl = displayOnInit ? newDecl : initDecl;
|
3006
|
+
diagnostic.addRelatedInfo((displayOnInit
|
3007
|
+
? localize_1.Localizer.DiagnosticAddendum.newMethodLocation()
|
3008
|
+
: localize_1.Localizer.DiagnosticAddendum.initMethodLocation()).format({
|
3009
|
+
type: this._evaluator.printType(types_1.ClassType.cloneAsInstance(displayOnInit ? newMember.classType : initMember.classType)),
|
3010
|
+
}), secondaryDecl.path, secondaryDecl.range);
|
3011
|
+
}
|
3012
|
+
}
|
3013
|
+
}
|
3014
|
+
}
|
3015
|
+
// Validates that any methods and variables in multiple base classes are
|
3016
|
+
// compatible with each other.
|
3017
|
+
_validateMultipleInheritanceCompatibility(classType, errorNode) {
|
3018
|
+
// Skip this check if reportIncompatibleMethodOverride and reportIncompatibleVariableOverride
|
3019
|
+
// are disabled because it's a relatively expensive check.
|
3020
|
+
if (this._fileInfo.diagnosticRuleSet.reportIncompatibleMethodOverride === 'none' &&
|
3021
|
+
this._fileInfo.diagnosticRuleSet.reportIncompatibleVariableOverride === 'none') {
|
3022
|
+
return;
|
3023
|
+
}
|
3024
|
+
const baseClasses = [];
|
3025
|
+
// Filter any unknown base classes. Also remove Generic and Protocol
|
3026
|
+
// base classes.
|
3027
|
+
classType.details.baseClasses.forEach((baseClass) => {
|
3028
|
+
if ((0, types_1.isClass)(baseClass) &&
|
3029
|
+
!types_1.ClassType.isBuiltIn(baseClass, 'Generic') &&
|
3030
|
+
!types_1.ClassType.isBuiltIn(baseClass, 'Protocol')) {
|
3031
|
+
baseClasses.push(baseClass);
|
3032
|
+
}
|
3033
|
+
});
|
3034
|
+
// If there is only one base class, there's nothing to do.
|
3035
|
+
if (baseClasses.length < 2) {
|
3036
|
+
return;
|
3037
|
+
}
|
3038
|
+
// Build maps of symbols for each of the base classes.
|
3039
|
+
const symbolMaps = baseClasses.map((baseClass) => {
|
3040
|
+
const specializedBaseClass = classType.details.mro.find((c) => (0, types_1.isClass)(c) && types_1.ClassType.isSameGenericClass(c, baseClass));
|
3041
|
+
if (!specializedBaseClass || !(0, types_1.isClass)(specializedBaseClass)) {
|
3042
|
+
return new Map();
|
3043
|
+
}
|
3044
|
+
// Retrieve all of the specialized symbols from the base class and its ancestors.
|
3045
|
+
return (0, typeUtils_1.getClassFieldsRecursive)(specializedBaseClass);
|
3046
|
+
});
|
3047
|
+
for (let symbolMapBaseIndex = 1; symbolMapBaseIndex < symbolMaps.length; symbolMapBaseIndex++) {
|
3048
|
+
const baseSymbolMap = symbolMaps[symbolMapBaseIndex];
|
3049
|
+
for (const [name, baseClassAndSymbol] of baseSymbolMap) {
|
3050
|
+
// Special-case dundered methods, which can differ in signature. Also
|
3051
|
+
// exempt private symbols.
|
3052
|
+
if (SymbolNameUtils.isDunderName(name) || SymbolNameUtils.isPrivateName(name)) {
|
3053
|
+
continue;
|
3054
|
+
}
|
3055
|
+
const baseClassType = baseClassAndSymbol.classType;
|
3056
|
+
if (!(0, types_1.isClass)(baseClassType)) {
|
3057
|
+
continue;
|
3058
|
+
}
|
3059
|
+
for (let overrideIndex = 0; overrideIndex < symbolMapBaseIndex; overrideIndex++) {
|
3060
|
+
const overrideSymbolMap = symbolMaps[overrideIndex];
|
3061
|
+
const overrideClassAndSymbol = overrideSymbolMap.get(name);
|
3062
|
+
if (overrideClassAndSymbol) {
|
3063
|
+
this._validateMultipleInheritanceOverride(baseClassAndSymbol, overrideClassAndSymbol, classType, name, baseClasses[symbolMapBaseIndex], baseClasses[overrideIndex], errorNode);
|
3064
|
+
}
|
3065
|
+
}
|
3066
|
+
}
|
3067
|
+
}
|
3068
|
+
}
|
3069
|
+
_validateMultipleInheritanceOverride(baseClassAndSymbol, overrideClassAndSymbol, childClassType, memberName, baseClass1, baseClass2, errorNode) {
|
3070
|
+
if (!(0, types_1.isClass)(baseClassAndSymbol.classType) || !(0, types_1.isClass)(overrideClassAndSymbol.classType)) {
|
3071
|
+
return;
|
3072
|
+
}
|
3073
|
+
// Special case the '_' symbol, which is used in single dispatch
|
3074
|
+
// code and other cases where the name does not matter.
|
3075
|
+
if (memberName === '_') {
|
3076
|
+
return;
|
3077
|
+
}
|
3078
|
+
let baseType = this._evaluator.getEffectiveTypeOfSymbol(baseClassAndSymbol.symbol);
|
3079
|
+
baseType = (0, typeUtils_1.partiallySpecializeType)(baseType, baseClassAndSymbol.classType);
|
3080
|
+
const overrideSymbol = overrideClassAndSymbol.symbol;
|
3081
|
+
let overrideType = this._evaluator.getEffectiveTypeOfSymbol(overrideSymbol);
|
3082
|
+
overrideType = (0, typeUtils_1.partiallySpecializeType)(overrideType, overrideClassAndSymbol.classType);
|
3083
|
+
let diag;
|
3084
|
+
const overrideDecl = (0, symbolUtils_1.getLastTypedDeclaredForSymbol)(overrideClassAndSymbol.symbol);
|
3085
|
+
const baseDecl = (0, symbolUtils_1.getLastTypedDeclaredForSymbol)(baseClassAndSymbol.symbol);
|
3086
|
+
if ((0, types_1.isFunction)(baseType) || (0, types_1.isOverloadedFunction)(baseType)) {
|
3087
|
+
const diagAddendum = new diagnostic_1.DiagnosticAddendum();
|
3088
|
+
let overrideFunction;
|
3089
|
+
if ((0, types_1.isFunction)(overrideType)) {
|
3090
|
+
overrideFunction = overrideType;
|
3091
|
+
}
|
3092
|
+
else if ((0, types_1.isOverloadedFunction)(overrideType)) {
|
3093
|
+
// Use the last overload.
|
3094
|
+
overrideFunction = overrideType.overloads[overrideType.overloads.length - 1];
|
3095
|
+
// If the last overload isn't an implementation, skip the check for this symbol.
|
3096
|
+
if (types_1.FunctionType.isOverloaded(overrideFunction)) {
|
3097
|
+
return;
|
3098
|
+
}
|
3099
|
+
}
|
3100
|
+
if (overrideFunction) {
|
3101
|
+
if (!this._evaluator.validateOverrideMethod(baseType, overrideFunction, diagAddendum,
|
3102
|
+
/* enforceParamNameMatch */ true)) {
|
3103
|
+
const decl = overrideFunction.details.declaration;
|
3104
|
+
if (decl && decl.type === 3 /* Function */) {
|
3105
|
+
diag = this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportIncompatibleMethodOverride, diagnosticRules_1.DiagnosticRule.reportIncompatibleMethodOverride, localize_1.Localizer.Diagnostic.baseClassMethodTypeIncompatible().format({
|
3106
|
+
classType: childClassType.details.name,
|
3107
|
+
name: memberName,
|
3108
|
+
}) + diagAddendum.getString(), errorNode);
|
3109
|
+
}
|
3110
|
+
}
|
3111
|
+
}
|
3112
|
+
}
|
3113
|
+
else if ((0, typeUtils_1.isProperty)(baseType)) {
|
3114
|
+
// Handle properties specially.
|
3115
|
+
if (!(0, typeUtils_1.isProperty)(overrideType) && !(0, types_1.isAnyOrUnknown)(overrideType)) {
|
3116
|
+
const decls = overrideSymbol.getDeclarations();
|
3117
|
+
if (decls.length > 0) {
|
3118
|
+
diag = this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportIncompatibleVariableOverride, diagnosticRules_1.DiagnosticRule.reportIncompatibleVariableOverride, localize_1.Localizer.Diagnostic.baseClassVariableTypeIncompatible().format({
|
3119
|
+
classType: childClassType.details.name,
|
3120
|
+
name: memberName,
|
3121
|
+
}), errorNode);
|
3122
|
+
}
|
3123
|
+
}
|
3124
|
+
else {
|
3125
|
+
// TODO - check types of property methods fget, fset, fdel.
|
3126
|
+
}
|
3127
|
+
}
|
3128
|
+
else {
|
3129
|
+
// This check can be expensive, so don't perform it if the corresponding
|
3130
|
+
// rule is disabled.
|
3131
|
+
if (this._fileInfo.diagnosticRuleSet.reportIncompatibleVariableOverride !== 'none') {
|
3132
|
+
if (!(0, types_1.isAnyOrUnknown)(baseType) && !(0, types_1.isAnyOrUnknown)(overrideType) && !(0, types_1.isTypeSame)(baseType, overrideType)) {
|
3133
|
+
diag = this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportIncompatibleVariableOverride, diagnosticRules_1.DiagnosticRule.reportIncompatibleVariableOverride, localize_1.Localizer.Diagnostic.baseClassVariableTypeIncompatible().format({
|
3134
|
+
classType: childClassType.details.name,
|
3135
|
+
name: memberName,
|
3136
|
+
}), errorNode);
|
3137
|
+
}
|
3138
|
+
}
|
3139
|
+
}
|
3140
|
+
if (diag && overrideDecl && baseDecl) {
|
3141
|
+
diag.addRelatedInfo(localize_1.Localizer.DiagnosticAddendum.baseClassProvidesType().format({
|
3142
|
+
baseClass: this._evaluator.printType((0, typeUtils_1.convertToInstance)(baseClass1)),
|
3143
|
+
type: this._evaluator.printType(overrideType),
|
3144
|
+
}), overrideDecl.path, overrideDecl.range);
|
3145
|
+
diag.addRelatedInfo(localize_1.Localizer.DiagnosticAddendum.baseClassProvidesType().format({
|
3146
|
+
baseClass: this._evaluator.printType((0, typeUtils_1.convertToInstance)(baseClass2)),
|
3147
|
+
type: this._evaluator.printType(baseType),
|
3148
|
+
}), baseDecl.path, baseDecl.range);
|
3149
|
+
}
|
3150
|
+
}
|
3151
|
+
// Validates that any overridden methods or variables contain the same
|
3152
|
+
// types as the original method. Also marks the class as abstract if one
|
3153
|
+
// or more abstract methods are not overridden.
|
3154
|
+
_validateBaseClassOverrides(classType) {
|
3155
|
+
classType.details.fields.forEach((symbol, name) => {
|
3156
|
+
// Private symbols do not need to match in type since their
|
3157
|
+
// names are mangled, and subclasses can't access the value in
|
3158
|
+
// the parent class.
|
3159
|
+
if (SymbolNameUtils.isPrivateName(name)) {
|
3160
|
+
return;
|
3161
|
+
}
|
3162
|
+
// If the symbol has no declaration, and the type is inferred,
|
3163
|
+
// skip this check.
|
3164
|
+
if (!symbol.hasTypedDeclarations()) {
|
3165
|
+
return;
|
3166
|
+
}
|
3167
|
+
// Get the symbol type defined in this class.
|
3168
|
+
const typeOfSymbol = this._evaluator.getEffectiveTypeOfSymbol(symbol);
|
3169
|
+
// If the type of the override symbol isn't known, stop here.
|
3170
|
+
if ((0, types_1.isAnyOrUnknown)(typeOfSymbol)) {
|
3171
|
+
return;
|
3172
|
+
}
|
3173
|
+
for (const baseClass of classType.details.baseClasses) {
|
3174
|
+
if (!(0, types_1.isClass)(baseClass)) {
|
3175
|
+
continue;
|
3176
|
+
}
|
3177
|
+
// Look up the base class in the MRO list. It's the same generic class
|
3178
|
+
// but has already been specialized using the type variables of the classType.
|
3179
|
+
const mroBaseClass = classType.details.mro.find((mroClass) => (0, types_1.isClass)(mroClass) && types_1.ClassType.isSameGenericClass(mroClass, baseClass));
|
3180
|
+
if (!mroBaseClass) {
|
3181
|
+
continue;
|
3182
|
+
}
|
3183
|
+
const baseClassAndSymbol = (0, typeUtils_1.lookUpClassMember)(mroBaseClass, name, 0 /* Default */);
|
3184
|
+
if (!baseClassAndSymbol) {
|
3185
|
+
continue;
|
3186
|
+
}
|
3187
|
+
this._validateBaseClassOverride(baseClassAndSymbol, symbol, typeOfSymbol, classType, name);
|
3188
|
+
}
|
3189
|
+
});
|
3190
|
+
}
|
3191
|
+
_validateBaseClassOverride(baseClassAndSymbol, overrideSymbol, overrideType, childClassType, memberName) {
|
3192
|
+
var _a;
|
3193
|
+
if (!(0, types_1.isInstantiableClass)(baseClassAndSymbol.classType)) {
|
3194
|
+
return;
|
3195
|
+
}
|
3196
|
+
// If the base class doesn't provide a type declaration, we won't bother
|
3197
|
+
// proceeding with additional checks. Type inference is too inaccurate
|
3198
|
+
// in this case, plus it would be very slow.
|
3199
|
+
if (!baseClassAndSymbol.symbol.hasTypedDeclarations()) {
|
3200
|
+
return;
|
3201
|
+
}
|
3202
|
+
// Special case the '_' symbol, which is used in single dispatch
|
3203
|
+
// code and other cases where the name does not matter.
|
3204
|
+
if (memberName === '_') {
|
3205
|
+
return;
|
3206
|
+
}
|
3207
|
+
const baseType = (0, typeUtils_1.partiallySpecializeType)(this._evaluator.getEffectiveTypeOfSymbol(baseClassAndSymbol.symbol), baseClassAndSymbol.classType);
|
3208
|
+
if ((0, types_1.isFunction)(baseType) || (0, types_1.isOverloadedFunction)(baseType)) {
|
3209
|
+
const diagAddendum = new diagnostic_1.DiagnosticAddendum();
|
3210
|
+
let overrideFunction;
|
3211
|
+
if ((0, types_1.isFunction)(overrideType)) {
|
3212
|
+
overrideFunction = overrideType;
|
3213
|
+
}
|
3214
|
+
else if ((0, types_1.isOverloadedFunction)(overrideType)) {
|
3215
|
+
// Use the last overload.
|
3216
|
+
overrideFunction = overrideType.overloads[overrideType.overloads.length - 1];
|
3217
|
+
}
|
3218
|
+
if (overrideFunction) {
|
3219
|
+
const exemptMethods = ['__init__', '__new__', '__init_subclass__'];
|
3220
|
+
// Don't enforce parameter names for dundered methods. Many of them
|
3221
|
+
// are misnamed in typeshed stubs, so this would result in many
|
3222
|
+
// false positives.
|
3223
|
+
const enforceParamNameMatch = !SymbolNameUtils.isDunderName(memberName);
|
3224
|
+
// Don't check certain magic functions or private symbols.
|
3225
|
+
if (!exemptMethods.some((exempt) => exempt === memberName) &&
|
3226
|
+
!SymbolNameUtils.isPrivateName(memberName)) {
|
3227
|
+
if (!this._evaluator.validateOverrideMethod(baseType, overrideFunction, diagAddendum, enforceParamNameMatch)) {
|
3228
|
+
const decl = (_a = overrideFunction.details.declaration) !== null && _a !== void 0 ? _a : (0, symbolUtils_1.getLastTypedDeclaredForSymbol)(overrideSymbol);
|
3229
|
+
if (decl) {
|
3230
|
+
const diag = this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportIncompatibleMethodOverride, diagnosticRules_1.DiagnosticRule.reportIncompatibleMethodOverride, localize_1.Localizer.Diagnostic.incompatibleMethodOverride().format({
|
3231
|
+
name: memberName,
|
3232
|
+
className: baseClassAndSymbol.classType.details.name,
|
3233
|
+
}) + diagAddendum.getString(), decl.type === 3 /* Function */ ? decl.node.name : decl.node);
|
3234
|
+
const origDecl = (0, symbolUtils_1.getLastTypedDeclaredForSymbol)(baseClassAndSymbol.symbol);
|
3235
|
+
if (diag && origDecl) {
|
3236
|
+
diag.addRelatedInfo(localize_1.Localizer.DiagnosticAddendum.overriddenMethod(), origDecl.path, origDecl.range);
|
3237
|
+
}
|
3238
|
+
}
|
3239
|
+
}
|
3240
|
+
}
|
3241
|
+
if ((0, types_1.isFunction)(baseType)) {
|
3242
|
+
// Private names (starting with double underscore) are exempt from this check.
|
3243
|
+
if (!SymbolNameUtils.isPrivateName(memberName) && types_1.FunctionType.isFinal(baseType)) {
|
3244
|
+
const decl = (0, symbolUtils_1.getLastTypedDeclaredForSymbol)(overrideSymbol);
|
3245
|
+
if (decl && decl.type === 3 /* Function */) {
|
3246
|
+
const diag = this._evaluator.addError(localize_1.Localizer.Diagnostic.finalMethodOverride().format({
|
3247
|
+
name: memberName,
|
3248
|
+
className: baseClassAndSymbol.classType.details.name,
|
3249
|
+
}), decl.node.name);
|
3250
|
+
const origDecl = (0, symbolUtils_1.getLastTypedDeclaredForSymbol)(baseClassAndSymbol.symbol);
|
3251
|
+
if (diag && origDecl) {
|
3252
|
+
diag.addRelatedInfo(localize_1.Localizer.DiagnosticAddendum.finalMethod(), origDecl.path, origDecl.range);
|
3253
|
+
}
|
3254
|
+
}
|
3255
|
+
}
|
3256
|
+
}
|
3257
|
+
}
|
3258
|
+
else if (!(0, types_1.isAnyOrUnknown)(overrideType)) {
|
3259
|
+
// Special-case overrides of methods in '_TypedDict', since
|
3260
|
+
// TypedDict attributes aren't manifest as attributes but rather
|
3261
|
+
// as named keys.
|
3262
|
+
if (!types_1.ClassType.isBuiltIn(baseClassAndSymbol.classType, '_TypedDict')) {
|
3263
|
+
const decls = overrideSymbol.getDeclarations();
|
3264
|
+
if (decls.length > 0) {
|
3265
|
+
const lastDecl = decls[decls.length - 1];
|
3266
|
+
const diag = this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportIncompatibleMethodOverride, diagnosticRules_1.DiagnosticRule.reportIncompatibleMethodOverride, localize_1.Localizer.Diagnostic.methodOverridden().format({
|
3267
|
+
name: memberName,
|
3268
|
+
className: baseClassAndSymbol.classType.details.name,
|
3269
|
+
type: this._evaluator.printType(overrideType, /* expandTypeAlias */ false),
|
3270
|
+
}), lastDecl.node);
|
3271
|
+
const origDecl = (0, symbolUtils_1.getLastTypedDeclaredForSymbol)(baseClassAndSymbol.symbol);
|
3272
|
+
if (diag && origDecl) {
|
3273
|
+
diag.addRelatedInfo(localize_1.Localizer.DiagnosticAddendum.overriddenMethod(), origDecl.path, origDecl.range);
|
3274
|
+
}
|
3275
|
+
}
|
3276
|
+
}
|
3277
|
+
}
|
3278
|
+
}
|
3279
|
+
else if ((0, typeUtils_1.isProperty)(baseType)) {
|
3280
|
+
// Handle properties specially.
|
3281
|
+
if (!(0, typeUtils_1.isProperty)(overrideType)) {
|
3282
|
+
const decls = overrideSymbol.getDeclarations();
|
3283
|
+
if (decls.length > 0) {
|
3284
|
+
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportIncompatibleMethodOverride, diagnosticRules_1.DiagnosticRule.reportIncompatibleMethodOverride, localize_1.Localizer.Diagnostic.propertyOverridden().format({
|
3285
|
+
name: memberName,
|
3286
|
+
className: baseClassAndSymbol.classType.details.name,
|
3287
|
+
}), decls[decls.length - 1].node);
|
3288
|
+
}
|
3289
|
+
}
|
3290
|
+
else {
|
3291
|
+
const basePropFields = baseType.details.fields;
|
3292
|
+
const subclassPropFields = overrideType.details.fields;
|
3293
|
+
const baseClassType = baseClassAndSymbol.classType;
|
3294
|
+
['fget', 'fset', 'fdel'].forEach((methodName) => {
|
3295
|
+
const diagAddendum = new diagnostic_1.DiagnosticAddendum();
|
3296
|
+
const baseClassPropMethod = basePropFields.get(methodName);
|
3297
|
+
const subclassPropMethod = subclassPropFields.get(methodName);
|
3298
|
+
// Is the method present on the base class but missing in the subclass?
|
3299
|
+
if (baseClassPropMethod) {
|
3300
|
+
const baseClassMethodType = (0, typeUtils_1.partiallySpecializeType)(this._evaluator.getEffectiveTypeOfSymbol(baseClassPropMethod), baseClassType);
|
3301
|
+
if ((0, types_1.isFunction)(baseClassMethodType)) {
|
3302
|
+
if (!subclassPropMethod) {
|
3303
|
+
// The method is missing.
|
3304
|
+
diagAddendum.addMessage(localize_1.Localizer.DiagnosticAddendum.propertyMethodMissing().format({
|
3305
|
+
name: methodName,
|
3306
|
+
}));
|
3307
|
+
const decls = overrideSymbol.getDeclarations();
|
3308
|
+
if (decls.length > 0) {
|
3309
|
+
const diag = this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportIncompatibleMethodOverride, diagnosticRules_1.DiagnosticRule.reportIncompatibleMethodOverride, localize_1.Localizer.Diagnostic.propertyOverridden().format({
|
3310
|
+
name: memberName,
|
3311
|
+
className: baseClassType.details.name,
|
3312
|
+
}) + diagAddendum.getString(), decls[decls.length - 1].node);
|
3313
|
+
const origDecl = baseClassMethodType.details.declaration;
|
3314
|
+
if (diag && origDecl) {
|
3315
|
+
diag.addRelatedInfo(localize_1.Localizer.DiagnosticAddendum.overriddenMethod(), origDecl.path, origDecl.range);
|
3316
|
+
}
|
3317
|
+
}
|
3318
|
+
}
|
3319
|
+
else {
|
3320
|
+
const subclassMethodType = (0, typeUtils_1.partiallySpecializeType)(this._evaluator.getEffectiveTypeOfSymbol(subclassPropMethod), childClassType);
|
3321
|
+
if ((0, types_1.isFunction)(subclassMethodType)) {
|
3322
|
+
if (!this._evaluator.validateOverrideMethod(baseClassMethodType, subclassMethodType, diagAddendum.createAddendum())) {
|
3323
|
+
diagAddendum.addMessage(localize_1.Localizer.DiagnosticAddendum.propertyMethodIncompatible().format({
|
3324
|
+
name: methodName,
|
3325
|
+
}));
|
3326
|
+
const decl = subclassMethodType.details.declaration;
|
3327
|
+
if (decl && decl.type === 3 /* Function */) {
|
3328
|
+
const diag = this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportIncompatibleMethodOverride, diagnosticRules_1.DiagnosticRule.reportIncompatibleMethodOverride, localize_1.Localizer.Diagnostic.propertyOverridden().format({
|
3329
|
+
name: memberName,
|
3330
|
+
className: baseClassType.details.name,
|
3331
|
+
}) + diagAddendum.getString(), decl.node.name);
|
3332
|
+
const origDecl = baseClassMethodType.details.declaration;
|
3333
|
+
if (diag && origDecl) {
|
3334
|
+
diag.addRelatedInfo(localize_1.Localizer.DiagnosticAddendum.overriddenMethod(), origDecl.path, origDecl.range);
|
3335
|
+
}
|
3336
|
+
}
|
3337
|
+
}
|
3338
|
+
}
|
3339
|
+
}
|
3340
|
+
}
|
3341
|
+
}
|
3342
|
+
});
|
3343
|
+
}
|
3344
|
+
}
|
3345
|
+
else {
|
3346
|
+
// This check can be expensive, so don't perform it if the corresponding
|
3347
|
+
// rule is disabled.
|
3348
|
+
if (this._fileInfo.diagnosticRuleSet.reportIncompatibleVariableOverride !== 'none') {
|
3349
|
+
const decls = overrideSymbol.getDeclarations();
|
3350
|
+
if (decls.length > 0) {
|
3351
|
+
const lastDecl = decls[decls.length - 1];
|
3352
|
+
// Verify that the override type is assignable to (same or narrower than)
|
3353
|
+
// the declared type of the base symbol.
|
3354
|
+
const diagAddendum = new diagnostic_1.DiagnosticAddendum();
|
3355
|
+
if (!this._evaluator.assignType(baseType, overrideType, diagAddendum)) {
|
3356
|
+
const diag = this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportIncompatibleVariableOverride, diagnosticRules_1.DiagnosticRule.reportIncompatibleVariableOverride, localize_1.Localizer.Diagnostic.symbolOverridden().format({
|
3357
|
+
name: memberName,
|
3358
|
+
className: baseClassAndSymbol.classType.details.name,
|
3359
|
+
}) + diagAddendum.getString(), lastDecl.node);
|
3360
|
+
const origDecl = (0, symbolUtils_1.getLastTypedDeclaredForSymbol)(baseClassAndSymbol.symbol);
|
3361
|
+
if (diag && origDecl) {
|
3362
|
+
diag.addRelatedInfo(localize_1.Localizer.DiagnosticAddendum.overriddenSymbol(), origDecl.path, origDecl.range);
|
3363
|
+
}
|
3364
|
+
}
|
3365
|
+
// Verify that a class variable isn't overriding an instance
|
3366
|
+
// variable or vice versa.
|
3367
|
+
const isBaseClassVar = baseClassAndSymbol.symbol.isClassVar();
|
3368
|
+
let isClassVar = overrideSymbol.isClassVar();
|
3369
|
+
if (isBaseClassVar && !isClassVar) {
|
3370
|
+
// If the subclass doesn't redeclare the type but simply assigns
|
3371
|
+
// it without declaring its type, we won't consider it an instance
|
3372
|
+
// variable.
|
3373
|
+
if (!overrideSymbol.hasTypedDeclarations()) {
|
3374
|
+
isClassVar = true;
|
3375
|
+
}
|
3376
|
+
// If the subclass is declaring an inner class, we'll consider that
|
3377
|
+
// to be a ClassVar.
|
3378
|
+
if (overrideSymbol.getTypedDeclarations().every((decl) => decl.type === 4 /* Class */)) {
|
3379
|
+
isClassVar = true;
|
3380
|
+
}
|
3381
|
+
}
|
3382
|
+
if (isBaseClassVar !== isClassVar) {
|
3383
|
+
const unformattedMessage = overrideSymbol.isClassVar()
|
3384
|
+
? localize_1.Localizer.Diagnostic.classVarOverridesInstanceVar()
|
3385
|
+
: localize_1.Localizer.Diagnostic.instanceVarOverridesClassVar();
|
3386
|
+
const diag = this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportIncompatibleVariableOverride, diagnosticRules_1.DiagnosticRule.reportIncompatibleVariableOverride, unformattedMessage.format({
|
3387
|
+
name: memberName,
|
3388
|
+
className: baseClassAndSymbol.classType.details.name,
|
3389
|
+
}), lastDecl.node);
|
3390
|
+
const origDecl = (0, symbolUtils_1.getLastTypedDeclaredForSymbol)(baseClassAndSymbol.symbol);
|
3391
|
+
if (diag && origDecl) {
|
3392
|
+
diag.addRelatedInfo(localize_1.Localizer.DiagnosticAddendum.overriddenSymbol(), origDecl.path, origDecl.range);
|
3393
|
+
}
|
3394
|
+
}
|
3395
|
+
}
|
3396
|
+
}
|
3397
|
+
}
|
3398
|
+
}
|
3399
|
+
// Performs checks on a function that is located within a class
|
3400
|
+
// and has been determined not to be a property accessor.
|
3401
|
+
_validateMethod(node, functionType, classNode) {
|
3402
|
+
const classTypeInfo = this._evaluator.getTypeOfClass(classNode);
|
3403
|
+
const classType = classTypeInfo === null || classTypeInfo === void 0 ? void 0 : classTypeInfo.classType;
|
3404
|
+
if (node.name && classType) {
|
3405
|
+
const superCheckMethods = ['__init__', '__init_subclass__', '__enter__', '__exit__'];
|
3406
|
+
if (superCheckMethods.some((name) => name === node.name.value)) {
|
3407
|
+
if (!types_1.FunctionType.isAbstractMethod(functionType) &&
|
3408
|
+
!types_1.FunctionType.isOverloaded(functionType) &&
|
3409
|
+
!this._fileInfo.isStubFile) {
|
3410
|
+
this._validateSuperCallForMethod(node, functionType, classType);
|
3411
|
+
}
|
3412
|
+
}
|
3413
|
+
}
|
3414
|
+
if (node.name && node.name.value === '__new__') {
|
3415
|
+
// __new__ overrides should have a "cls" parameter.
|
3416
|
+
if (node.parameters.length === 0 ||
|
3417
|
+
!node.parameters[0].name ||
|
3418
|
+
!['cls', '_cls', '__cls', '__mcls'].some((name) => node.parameters[0].name.value === name)) {
|
3419
|
+
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportSelfClsParameterName, diagnosticRules_1.DiagnosticRule.reportSelfClsParameterName, localize_1.Localizer.Diagnostic.newClsParam(), node.parameters.length > 0 ? node.parameters[0] : node.name);
|
3420
|
+
}
|
3421
|
+
if (classType) {
|
3422
|
+
this._validateClsSelfParameterType(functionType, classType, /* isCls */ true);
|
3423
|
+
}
|
3424
|
+
}
|
3425
|
+
else if (node.name && node.name.value === '__init_subclass__') {
|
3426
|
+
// __init_subclass__ overrides should have a "cls" parameter.
|
3427
|
+
if (node.parameters.length === 0 || !node.parameters[0].name || node.parameters[0].name.value !== 'cls') {
|
3428
|
+
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportSelfClsParameterName, diagnosticRules_1.DiagnosticRule.reportSelfClsParameterName, localize_1.Localizer.Diagnostic.initSubclassClsParam(), node.parameters.length > 0 ? node.parameters[0] : node.name);
|
3429
|
+
}
|
3430
|
+
if (classType) {
|
3431
|
+
this._validateClsSelfParameterType(functionType, classType, /* isCls */ true);
|
3432
|
+
}
|
3433
|
+
}
|
3434
|
+
else if (node.name && node.name.value === '__class_getitem__') {
|
3435
|
+
// __class_getitem__ overrides should have a "cls" parameter.
|
3436
|
+
if (node.parameters.length === 0 || !node.parameters[0].name || node.parameters[0].name.value !== 'cls') {
|
3437
|
+
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportSelfClsParameterName, diagnosticRules_1.DiagnosticRule.reportSelfClsParameterName, localize_1.Localizer.Diagnostic.classGetItemClsParam(), node.parameters.length > 0 ? node.parameters[0] : node.name);
|
3438
|
+
}
|
3439
|
+
if (classType) {
|
3440
|
+
this._validateClsSelfParameterType(functionType, classType, /* isCls */ true);
|
3441
|
+
}
|
3442
|
+
}
|
3443
|
+
else if (types_1.FunctionType.isStaticMethod(functionType)) {
|
3444
|
+
// Static methods should not have "self" or "cls" parameters.
|
3445
|
+
if (node.parameters.length > 0 && node.parameters[0].name) {
|
3446
|
+
const paramName = node.parameters[0].name.value;
|
3447
|
+
if (paramName === 'self' || paramName === 'cls') {
|
3448
|
+
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportSelfClsParameterName, diagnosticRules_1.DiagnosticRule.reportSelfClsParameterName, localize_1.Localizer.Diagnostic.staticClsSelfParam(), node.parameters[0].name);
|
3449
|
+
}
|
3450
|
+
}
|
3451
|
+
}
|
3452
|
+
else if (types_1.FunctionType.isClassMethod(functionType)) {
|
3453
|
+
let paramName = '';
|
3454
|
+
if (node.parameters.length > 0 && node.parameters[0].name) {
|
3455
|
+
paramName = node.parameters[0].name.value;
|
3456
|
+
}
|
3457
|
+
// Class methods should have a "cls" parameter. We'll exempt parameter
|
3458
|
+
// names that start with an underscore since those are used in a few
|
3459
|
+
// cases in the stdlib pyi files.
|
3460
|
+
if (paramName !== 'cls') {
|
3461
|
+
if (!this._fileInfo.isStubFile || (!paramName.startsWith('_') && paramName !== 'metacls')) {
|
3462
|
+
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportSelfClsParameterName, diagnosticRules_1.DiagnosticRule.reportSelfClsParameterName, localize_1.Localizer.Diagnostic.classMethodClsParam(), node.parameters.length > 0 ? node.parameters[0] : node.name);
|
3463
|
+
}
|
3464
|
+
}
|
3465
|
+
if (classType) {
|
3466
|
+
this._validateClsSelfParameterType(functionType, classType, /* isCls */ true);
|
3467
|
+
}
|
3468
|
+
}
|
3469
|
+
else {
|
3470
|
+
// The presence of a decorator can change the behavior, so we need
|
3471
|
+
// to back off from this check if a decorator is present.
|
3472
|
+
if (node.decorators.length === 0) {
|
3473
|
+
let paramName = '';
|
3474
|
+
let firstParamIsSimple = true;
|
3475
|
+
if (node.parameters.length > 0) {
|
3476
|
+
if (node.parameters[0].name) {
|
3477
|
+
paramName = node.parameters[0].name.value;
|
3478
|
+
}
|
3479
|
+
if (node.parameters[0].category !== 0 /* Simple */) {
|
3480
|
+
firstParamIsSimple = false;
|
3481
|
+
}
|
3482
|
+
}
|
3483
|
+
// Instance methods should have a "self" parameter.
|
3484
|
+
if (firstParamIsSimple && paramName !== 'self') {
|
3485
|
+
// Special-case metaclasses, which can use "cls".
|
3486
|
+
let isLegalMetaclassName = false;
|
3487
|
+
if (paramName === 'cls') {
|
3488
|
+
const classTypeInfo = this._evaluator.getTypeOfClass(classNode);
|
3489
|
+
const typeType = this._evaluator.getBuiltInType(classNode, 'type');
|
3490
|
+
if (typeType &&
|
3491
|
+
(0, types_1.isInstantiableClass)(typeType) &&
|
3492
|
+
classTypeInfo &&
|
3493
|
+
(0, types_1.isInstantiableClass)(classTypeInfo.classType)) {
|
3494
|
+
if ((0, typeUtils_1.derivesFromClassRecursive)(classTypeInfo.classType, typeType, /* ignoreUnknown */ true)) {
|
3495
|
+
isLegalMetaclassName = true;
|
3496
|
+
}
|
3497
|
+
}
|
3498
|
+
}
|
3499
|
+
// Some typeshed stubs use a name that starts with an underscore to designate
|
3500
|
+
// a parameter that cannot be positional.
|
3501
|
+
const isPrivateName = SymbolNameUtils.isPrivateOrProtectedName(paramName);
|
3502
|
+
if (!isLegalMetaclassName && !isPrivateName) {
|
3503
|
+
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportSelfClsParameterName, diagnosticRules_1.DiagnosticRule.reportSelfClsParameterName, localize_1.Localizer.Diagnostic.instanceMethodSelfParam(), node.parameters.length > 0 ? node.parameters[0] : node.name);
|
3504
|
+
}
|
3505
|
+
}
|
3506
|
+
}
|
3507
|
+
if (classType) {
|
3508
|
+
this._validateClsSelfParameterType(functionType, classType, /* isCls */ false);
|
3509
|
+
}
|
3510
|
+
}
|
3511
|
+
}
|
3512
|
+
// Determines whether the method properly calls through to the same method in all
|
3513
|
+
// parent classes that expose a same-named method.
|
3514
|
+
_validateSuperCallForMethod(node, methodType, classType) {
|
3515
|
+
// This is an expensive test, so if it's not enabled, don't do any work.
|
3516
|
+
if (this._fileInfo.diagnosticRuleSet.reportMissingSuperCall === 'none') {
|
3517
|
+
return;
|
3518
|
+
}
|
3519
|
+
// If the class is marked final, we can skip the "object" base class
|
3520
|
+
// because we know that the `__init__` method in `object` doesn't do
|
3521
|
+
// anything. It's not safe to do this if the class isn't final because
|
3522
|
+
// it could be combined with other classes in a multi-inheritance
|
3523
|
+
// situation that effectively adds new superclasses that we don't know
|
3524
|
+
// about statically.
|
3525
|
+
let effectiveFlags = 8 /* SkipInstanceVariables */ | 1 /* SkipOriginalClass */;
|
3526
|
+
if (types_1.ClassType.isFinal(classType)) {
|
3527
|
+
effectiveFlags |= 4 /* SkipObjectBaseClass */;
|
3528
|
+
}
|
3529
|
+
const methodMember = (0, typeUtils_1.lookUpClassMember)(classType, methodType.details.name, effectiveFlags);
|
3530
|
+
if (!methodMember) {
|
3531
|
+
return;
|
3532
|
+
}
|
3533
|
+
let foundCallOfMember = false;
|
3534
|
+
// Now scan the implementation of the method to determine whether
|
3535
|
+
// super().<method> has been called for all of the required base classes.
|
3536
|
+
const callNodeWalker = new ParseTreeUtils.CallNodeWalker((node) => {
|
3537
|
+
if (node.leftExpression.nodeType === 35 /* MemberAccess */) {
|
3538
|
+
// Is it accessing the method by the same name?
|
3539
|
+
if (node.leftExpression.memberName.value === methodType.details.name) {
|
3540
|
+
const memberBaseExpr = node.leftExpression.leftExpression;
|
3541
|
+
// Is it a "super" call?
|
3542
|
+
if (memberBaseExpr.nodeType === 9 /* Call */ &&
|
3543
|
+
memberBaseExpr.leftExpression.nodeType === 38 /* Name */ &&
|
3544
|
+
memberBaseExpr.leftExpression.value === 'super') {
|
3545
|
+
foundCallOfMember = true;
|
3546
|
+
}
|
3547
|
+
else {
|
3548
|
+
// Is it an X.<method> direct call?
|
3549
|
+
const baseType = this._evaluator.getType(memberBaseExpr);
|
3550
|
+
if (baseType && (0, types_1.isInstantiableClass)(baseType)) {
|
3551
|
+
foundCallOfMember = true;
|
3552
|
+
}
|
3553
|
+
}
|
3554
|
+
}
|
3555
|
+
}
|
3556
|
+
});
|
3557
|
+
callNodeWalker.walk(node.suite);
|
3558
|
+
// If we didn't find a call to at least one base class, report the problem.
|
3559
|
+
if (!foundCallOfMember) {
|
3560
|
+
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportMissingSuperCall, diagnosticRules_1.DiagnosticRule.reportMissingSuperCall, localize_1.Localizer.Diagnostic.missingSuperCall().format({
|
3561
|
+
methodName: methodType.details.name,
|
3562
|
+
}), node.name);
|
3563
|
+
}
|
3564
|
+
}
|
3565
|
+
// Validates that the annotated type of a "self" or "cls" parameter is
|
3566
|
+
// compatible with the type of the class that contains it.
|
3567
|
+
_validateClsSelfParameterType(functionType, classType, isCls) {
|
3568
|
+
if (functionType.details.parameters.length < 1) {
|
3569
|
+
return;
|
3570
|
+
}
|
3571
|
+
// If there is no type annotation, there's nothing to check because
|
3572
|
+
// the type will be inferred.
|
3573
|
+
const paramInfo = functionType.details.parameters[0];
|
3574
|
+
if (!paramInfo.typeAnnotation || !paramInfo.name) {
|
3575
|
+
return;
|
3576
|
+
}
|
3577
|
+
// If this is a protocol class, the self and cls parameters can be bound
|
3578
|
+
// to something other than the class.
|
3579
|
+
if (types_1.ClassType.isProtocolClass(classType)) {
|
3580
|
+
return;
|
3581
|
+
}
|
3582
|
+
const paramType = this._evaluator.makeTopLevelTypeVarsConcrete(paramInfo.type);
|
3583
|
+
const expectedType = isCls ? classType : (0, typeUtils_1.convertToInstance)(classType);
|
3584
|
+
// If the declared type is a protocol class or instance, skip
|
3585
|
+
// the check. This has legitimate uses for mix-in classes.
|
3586
|
+
if ((0, types_1.isInstantiableClass)(paramType) && types_1.ClassType.isProtocolClass(paramType)) {
|
3587
|
+
return;
|
3588
|
+
}
|
3589
|
+
if ((0, types_1.isClassInstance)(paramType) && types_1.ClassType.isProtocolClass(paramType)) {
|
3590
|
+
return;
|
3591
|
+
}
|
3592
|
+
// Don't enforce this for an overloaded method because the "self" param
|
3593
|
+
// annotation can be used as a filter for the overload.
|
3594
|
+
if (types_1.FunctionType.isOverloaded(functionType)) {
|
3595
|
+
return;
|
3596
|
+
}
|
3597
|
+
if (!this._evaluator.assignType(paramType, expectedType)) {
|
3598
|
+
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.clsSelfParamTypeMismatch().format({
|
3599
|
+
name: paramInfo.name,
|
3600
|
+
classType: this._evaluator.printType(expectedType, /* expandTypeAlias */ false),
|
3601
|
+
}), paramInfo.typeAnnotation);
|
3602
|
+
}
|
3603
|
+
}
|
3604
|
+
_validateYieldType(node, yieldType) {
|
3605
|
+
let declaredReturnType;
|
3606
|
+
let declaredYieldType;
|
3607
|
+
const enclosingFunctionNode = ParseTreeUtils.getEnclosingFunction(node);
|
3608
|
+
if (enclosingFunctionNode) {
|
3609
|
+
const functionTypeResult = this._evaluator.getTypeOfFunction(enclosingFunctionNode);
|
3610
|
+
if (functionTypeResult) {
|
3611
|
+
(0, debug_1.assert)((0, types_1.isFunction)(functionTypeResult.functionType));
|
3612
|
+
declaredReturnType = types_1.FunctionType.getSpecializedReturnType(functionTypeResult.functionType);
|
3613
|
+
if (declaredReturnType) {
|
3614
|
+
declaredYieldType = (0, typeUtils_1.getGeneratorYieldType)(declaredReturnType, !!enclosingFunctionNode.isAsync);
|
3615
|
+
}
|
3616
|
+
if (declaredReturnType && !declaredYieldType && enclosingFunctionNode.returnTypeAnnotation) {
|
3617
|
+
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, enclosingFunctionNode.isAsync
|
3618
|
+
? localize_1.Localizer.Diagnostic.generatorAsyncReturnType()
|
3619
|
+
: localize_1.Localizer.Diagnostic.generatorSyncReturnType(), enclosingFunctionNode.returnTypeAnnotation);
|
3620
|
+
}
|
3621
|
+
}
|
3622
|
+
}
|
3623
|
+
if (this._evaluator.isNodeReachable(node, /* sourceNode */ undefined)) {
|
3624
|
+
if (declaredReturnType && (0, types_1.isNever)(declaredReturnType)) {
|
3625
|
+
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.noReturnContainsYield(), node);
|
3626
|
+
}
|
3627
|
+
else if (declaredYieldType) {
|
3628
|
+
const diagAddendum = new diagnostic_1.DiagnosticAddendum();
|
3629
|
+
if (!this._evaluator.assignType(declaredYieldType, yieldType, diagAddendum)) {
|
3630
|
+
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.yieldTypeMismatch().format({
|
3631
|
+
exprType: this._evaluator.printType(yieldType, /* expandTypeAlias */ false),
|
3632
|
+
yieldType: this._evaluator.printType(declaredYieldType, /* expandTypeAlias */ false),
|
3633
|
+
}) + diagAddendum.getString(), node.expression || node);
|
3634
|
+
}
|
3635
|
+
}
|
3636
|
+
}
|
3637
|
+
}
|
3638
|
+
// Determines whether any of the except statements are unreachable because
|
3639
|
+
// they are redundant.
|
3640
|
+
_reportUnusedExceptStatements(node) {
|
3641
|
+
let sawUnknownExceptionType = false;
|
3642
|
+
const exceptionTypesSoFar = [];
|
3643
|
+
node.exceptClauses.forEach((except) => {
|
3644
|
+
if (sawUnknownExceptionType || except.isExceptGroup || !except.typeExpression) {
|
3645
|
+
return;
|
3646
|
+
}
|
3647
|
+
const exceptionType = this._evaluator.getType(except.typeExpression);
|
3648
|
+
if (!exceptionType || (0, types_1.isAnyOrUnknown)(exceptionType)) {
|
3649
|
+
sawUnknownExceptionType = true;
|
3650
|
+
return;
|
3651
|
+
}
|
3652
|
+
const typesOfThisExcept = [];
|
3653
|
+
if ((0, types_1.isInstantiableClass)(exceptionType)) {
|
3654
|
+
// If the exception type is a variable whose type could represent
|
3655
|
+
// subclasses, the actual exception type is statically unknown.
|
3656
|
+
if (exceptionType.includeSubclasses) {
|
3657
|
+
sawUnknownExceptionType = true;
|
3658
|
+
}
|
3659
|
+
typesOfThisExcept.push(exceptionType);
|
3660
|
+
}
|
3661
|
+
else if ((0, types_1.isClassInstance)(exceptionType)) {
|
3662
|
+
const iterableType = this._evaluator.getTypeOfIterator(exceptionType, /* isAsync */ false, /* errorNode */ undefined) ||
|
3663
|
+
types_1.UnknownType.create();
|
3664
|
+
(0, typeUtils_1.doForEachSubtype)(iterableType, (subtype) => {
|
3665
|
+
if ((0, types_1.isAnyOrUnknown)(subtype)) {
|
3666
|
+
sawUnknownExceptionType = true;
|
3667
|
+
}
|
3668
|
+
if ((0, types_1.isInstantiableClass)(subtype)) {
|
3669
|
+
// If the exception type is a variable whose type could represent
|
3670
|
+
// subclasses, the actual exception type is statically unknown.
|
3671
|
+
if (subtype.includeSubclasses) {
|
3672
|
+
sawUnknownExceptionType = true;
|
3673
|
+
}
|
3674
|
+
typesOfThisExcept.push(subtype);
|
3675
|
+
}
|
3676
|
+
});
|
3677
|
+
}
|
3678
|
+
else {
|
3679
|
+
sawUnknownExceptionType = true;
|
3680
|
+
}
|
3681
|
+
if (exceptionTypesSoFar.length > 0 && !sawUnknownExceptionType) {
|
3682
|
+
const diagAddendum = new diagnostic_1.DiagnosticAddendum();
|
3683
|
+
let overriddenExceptionCount = 0;
|
3684
|
+
typesOfThisExcept.forEach((thisExceptType) => {
|
3685
|
+
const subtype = exceptionTypesSoFar.find((previousExceptType) => {
|
3686
|
+
return (0, typeUtils_1.derivesFromClassRecursive)(thisExceptType, previousExceptType, /* ignoreUnknown */ true);
|
3687
|
+
});
|
3688
|
+
if (subtype) {
|
3689
|
+
diagAddendum.addMessage(localize_1.Localizer.DiagnosticAddendum.unreachableExcept().format({
|
3690
|
+
exceptionType: this._evaluator.printType((0, typeUtils_1.convertToInstance)(thisExceptType)),
|
3691
|
+
parentType: this._evaluator.printType((0, typeUtils_1.convertToInstance)(subtype)),
|
3692
|
+
}));
|
3693
|
+
overriddenExceptionCount++;
|
3694
|
+
}
|
3695
|
+
});
|
3696
|
+
// Were all of the exception types overridden?
|
3697
|
+
if (typesOfThisExcept.length === overriddenExceptionCount) {
|
3698
|
+
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.unreachableExcept() + diagAddendum.getString(), except.typeExpression);
|
3699
|
+
this._evaluator.addUnusedCode(except, except.exceptSuite);
|
3700
|
+
}
|
3701
|
+
}
|
3702
|
+
exceptionTypesSoFar.push(...typesOfThisExcept);
|
3703
|
+
});
|
3704
|
+
}
|
3705
|
+
_reportDuplicateImports() {
|
3706
|
+
const importStatements = (0, importStatementUtils_1.getTopLevelImports)(this._moduleNode);
|
3707
|
+
const importModuleMap = new Map();
|
3708
|
+
importStatements.orderedImports.forEach((importStatement) => {
|
3709
|
+
if (importStatement.node.nodeType === 22 /* ImportFrom */) {
|
3710
|
+
const symbolMap = new Map();
|
3711
|
+
importStatement.node.imports.forEach((importFromAs) => {
|
3712
|
+
// Ignore duplicates if they're aliased.
|
3713
|
+
if (!importFromAs.alias) {
|
3714
|
+
const prevImport = symbolMap.get(importFromAs.name.value);
|
3715
|
+
if (prevImport) {
|
3716
|
+
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportDuplicateImport, diagnosticRules_1.DiagnosticRule.reportDuplicateImport, localize_1.Localizer.Diagnostic.duplicateImport().format({ importName: importFromAs.name.value }), importFromAs.name);
|
3717
|
+
}
|
3718
|
+
else {
|
3719
|
+
symbolMap.set(importFromAs.name.value, importFromAs);
|
3720
|
+
}
|
3721
|
+
}
|
3722
|
+
});
|
3723
|
+
}
|
3724
|
+
else if (importStatement.subnode) {
|
3725
|
+
// Ignore duplicates if they're aliased.
|
3726
|
+
if (!importStatement.subnode.alias) {
|
3727
|
+
const prevImport = importModuleMap.get(importStatement.moduleName);
|
3728
|
+
if (prevImport) {
|
3729
|
+
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportDuplicateImport, diagnosticRules_1.DiagnosticRule.reportDuplicateImport, localize_1.Localizer.Diagnostic.duplicateImport().format({ importName: importStatement.moduleName }), importStatement.subnode);
|
3730
|
+
}
|
3731
|
+
else {
|
3732
|
+
importModuleMap.set(importStatement.moduleName, importStatement.subnode);
|
3733
|
+
}
|
3734
|
+
}
|
3735
|
+
}
|
3736
|
+
});
|
3737
|
+
}
|
3738
|
+
}
|
3739
|
+
exports.Checker = Checker;
|
3740
|
+
class MissingModuleSourceReporter extends parseTreeWalker_1.ParseTreeWalker {
|
3741
|
+
constructor(_importResolver, _evaluator, _fileInfo) {
|
3742
|
+
super();
|
3743
|
+
this._importResolver = _importResolver;
|
3744
|
+
this._evaluator = _evaluator;
|
3745
|
+
this._fileInfo = _fileInfo;
|
3746
|
+
}
|
3747
|
+
static report(importResolver, evaluator, fileInfo, node) {
|
3748
|
+
if (fileInfo.isStubFile) {
|
3749
|
+
// Don't report this for stub files.
|
3750
|
+
return;
|
3751
|
+
}
|
3752
|
+
new MissingModuleSourceReporter(importResolver, evaluator, fileInfo).walk(node);
|
3753
|
+
}
|
3754
|
+
visitNode(node) {
|
3755
|
+
// Optimization. don't walk into expressions which can't
|
3756
|
+
// have import statement as child nodes.
|
3757
|
+
if ((0, parseNodes_1.isExpressionNode)(node)) {
|
3758
|
+
return [];
|
3759
|
+
}
|
3760
|
+
return super.visitNode(node);
|
3761
|
+
}
|
3762
|
+
visitModule(node) {
|
3763
|
+
const codeComplexity = AnalyzerNodeInfo.getCodeFlowComplexity(node);
|
3764
|
+
if (isPrintCodeComplexityEnabled) {
|
3765
|
+
console.log(`Code complexity of module ${this._fileInfo.filePath} is ${codeComplexity.toString()}`);
|
3766
|
+
}
|
3767
|
+
if (codeComplexity > typeEvaluator_1.maxCodeComplexity) {
|
3768
|
+
this._evaluator.addDiagnosticForTextRange(this._fileInfo, this._fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.codeTooComplexToAnalyze(), { start: 0, length: 0 });
|
3769
|
+
return false;
|
3770
|
+
}
|
3771
|
+
return true;
|
3772
|
+
}
|
3773
|
+
visitModuleName(node) {
|
3774
|
+
const importResult = AnalyzerNodeInfo.getImportInfo(node);
|
3775
|
+
(0, debug_1.assert)(importResult !== undefined);
|
3776
|
+
this._addMissingModuleSourceDiagnosticIfNeeded(importResult, node);
|
3777
|
+
return false;
|
3778
|
+
}
|
3779
|
+
visitImportFromAs(node) {
|
3780
|
+
const decls = this._evaluator.getDeclarationsForNameNode(node.name);
|
3781
|
+
if (!decls) {
|
3782
|
+
return false;
|
3783
|
+
}
|
3784
|
+
for (const decl of decls) {
|
3785
|
+
if (!(0, declaration_1.isAliasDeclaration)(decl) || !decl.submoduleFallback || decl.node !== node) {
|
3786
|
+
// If it is not implicitly imported module, move to next.
|
3787
|
+
continue;
|
3788
|
+
}
|
3789
|
+
const resolvedAlias = this._evaluator.resolveAliasDeclaration(decl, /* resolveLocalNames */ true);
|
3790
|
+
if (!(resolvedAlias === null || resolvedAlias === void 0 ? void 0 : resolvedAlias.path) || !(0, sourceMapper_1.isStubFile)(resolvedAlias.path)) {
|
3791
|
+
continue;
|
3792
|
+
}
|
3793
|
+
const importResult = this._getImportResult(node, resolvedAlias.path);
|
3794
|
+
if (!importResult) {
|
3795
|
+
continue;
|
3796
|
+
}
|
3797
|
+
this._addMissingModuleSourceDiagnosticIfNeeded(importResult, node.name);
|
3798
|
+
break;
|
3799
|
+
}
|
3800
|
+
return false;
|
3801
|
+
}
|
3802
|
+
_getImportResult(node, filePath) {
|
3803
|
+
const execEnv = this._importResolver.getConfigOption().findExecEnvironment(filePath);
|
3804
|
+
const moduleNameNode = node.parent.module;
|
3805
|
+
// Handle both absolute and relative imports.
|
3806
|
+
const moduleName = moduleNameNode.leadingDots === 0
|
3807
|
+
? this._importResolver.getModuleNameForImport(filePath, execEnv).moduleName
|
3808
|
+
: (0, importStatementUtils_1.getRelativeModuleName)(this._importResolver.fileSystem, this._fileInfo.filePath, filePath);
|
3809
|
+
if (!moduleName) {
|
3810
|
+
return undefined;
|
3811
|
+
}
|
3812
|
+
return this._importResolver.resolveImport(this._fileInfo.filePath, execEnv, (0, importResolver_1.createImportedModuleDescriptor)(moduleName));
|
3813
|
+
}
|
3814
|
+
_addMissingModuleSourceDiagnosticIfNeeded(importResult, node) {
|
3815
|
+
if (importResult.isNativeLib ||
|
3816
|
+
!importResult.isStubFile ||
|
3817
|
+
importResult.importType === 0 /* BuiltIn */ ||
|
3818
|
+
!importResult.nonStubImportResult ||
|
3819
|
+
importResult.nonStubImportResult.isImportFound) {
|
3820
|
+
return;
|
3821
|
+
}
|
3822
|
+
// Type stub found, but source is missing.
|
3823
|
+
this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportMissingModuleSource, diagnosticRules_1.DiagnosticRule.reportMissingModuleSource, localize_1.Localizer.Diagnostic.importSourceResolveFailure().format({
|
3824
|
+
importName: importResult.importName,
|
3825
|
+
}), node);
|
3826
|
+
}
|
3827
|
+
}
|
3828
|
+
//# sourceMappingURL=checker.js.map
|