@zzzen/pyright-internal 1.2.0-dev.20261018 → 1.2.0-dev.20261108
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/binder.js +29 -12
- package/dist/analyzer/binder.js.map +1 -1
- package/dist/analyzer/checker.js +4 -0
- package/dist/analyzer/checker.js.map +1 -1
- package/dist/analyzer/codeFlowEngine.js +3 -3
- package/dist/analyzer/codeFlowEngine.js.map +1 -1
- package/dist/analyzer/constructorTransform.js +12 -0
- package/dist/analyzer/constructorTransform.js.map +1 -1
- package/dist/analyzer/constructors.d.ts +1 -1
- package/dist/analyzer/constructors.js +1 -1
- package/dist/analyzer/constructors.js.map +1 -1
- package/dist/analyzer/dataClasses.js +14 -5
- package/dist/analyzer/dataClasses.js.map +1 -1
- package/dist/analyzer/decorators.d.ts +2 -2
- package/dist/analyzer/decorators.js +22 -2
- package/dist/analyzer/decorators.js.map +1 -1
- package/dist/analyzer/functionTransform.d.ts +5 -0
- package/dist/analyzer/functionTransform.js +6 -3
- package/dist/analyzer/functionTransform.js.map +1 -1
- package/dist/analyzer/missingBindingMetadata.d.ts +6 -0
- package/dist/analyzer/missingBindingMetadata.js +22 -0
- package/dist/analyzer/missingBindingMetadata.js.map +1 -0
- package/dist/analyzer/namedTuples.d.ts +5 -1
- package/dist/analyzer/namedTuples.js +64 -35
- package/dist/analyzer/namedTuples.js.map +1 -1
- package/dist/analyzer/operations.js +45 -1
- package/dist/analyzer/operations.js.map +1 -1
- package/dist/analyzer/parseTreeUtils.d.ts +2 -0
- package/dist/analyzer/parseTreeUtils.js +43 -0
- package/dist/analyzer/parseTreeUtils.js.map +1 -1
- package/dist/analyzer/patternMatching.d.ts +5 -1
- package/dist/analyzer/patternMatching.js +6 -1
- package/dist/analyzer/patternMatching.js.map +1 -1
- package/dist/analyzer/program.d.ts +3 -0
- package/dist/analyzer/program.js +71 -1
- package/dist/analyzer/program.js.map +1 -1
- package/dist/analyzer/sentinel.js +7 -1
- package/dist/analyzer/sentinel.js.map +1 -1
- package/dist/analyzer/sourceFile.js +13 -6
- package/dist/analyzer/sourceFile.js.map +1 -1
- package/dist/analyzer/tupleComparison.d.ts +6 -0
- package/dist/analyzer/tupleComparison.js +731 -0
- package/dist/analyzer/tupleComparison.js.map +1 -0
- package/dist/analyzer/tuples.d.ts +1 -1
- package/dist/analyzer/tuples.js +35 -4
- package/dist/analyzer/tuples.js.map +1 -1
- package/dist/analyzer/typeCacheUtils.d.ts +1 -0
- package/dist/analyzer/typeCacheUtils.js +10 -0
- package/dist/analyzer/typeCacheUtils.js.map +1 -1
- package/dist/analyzer/typeEvaluator/boundMethodSpecialization.d.ts +15 -0
- package/dist/analyzer/typeEvaluator/boundMethodSpecialization.js +98 -0
- package/dist/analyzer/typeEvaluator/boundMethodSpecialization.js.map +1 -0
- package/dist/analyzer/typeEvaluator/classConstruction.d.ts +25 -0
- package/dist/analyzer/typeEvaluator/classConstruction.js +251 -0
- package/dist/analyzer/typeEvaluator/classConstruction.js.map +1 -0
- package/dist/analyzer/typeEvaluator/collectionInference.d.ts +41 -0
- package/dist/analyzer/typeEvaluator/collectionInference.js +695 -0
- package/dist/analyzer/typeEvaluator/collectionInference.js.map +1 -0
- package/dist/analyzer/typeEvaluator/diagnostics.d.ts +33 -0
- package/dist/analyzer/typeEvaluator/diagnostics.js +198 -0
- package/dist/analyzer/typeEvaluator/diagnostics.js.map +1 -0
- package/dist/analyzer/typeEvaluator/evaluatorCore.d.ts +80 -0
- package/dist/analyzer/typeEvaluator/evaluatorCore.js +1126 -0
- package/dist/analyzer/typeEvaluator/evaluatorCore.js.map +1 -0
- package/dist/analyzer/typeEvaluator/evaluatorNarrowing.d.ts +17 -0
- package/dist/analyzer/typeEvaluator/evaluatorNarrowing.js +370 -0
- package/dist/analyzer/typeEvaluator/evaluatorNarrowing.js.map +1 -0
- package/dist/analyzer/typeEvaluator/expressionEvaluation.d.ts +81 -0
- package/dist/analyzer/typeEvaluator/expressionEvaluation.js +1802 -0
- package/dist/analyzer/typeEvaluator/expressionEvaluation.js.map +1 -0
- package/dist/analyzer/typeEvaluator/flowAnalysis.d.ts +33 -0
- package/dist/analyzer/typeEvaluator/flowAnalysis.js +217 -0
- package/dist/analyzer/typeEvaluator/flowAnalysis.js.map +1 -0
- package/dist/analyzer/typeEvaluator/internals.d.ts +137 -0
- package/dist/analyzer/typeEvaluator/internals.js +10 -0
- package/dist/analyzer/typeEvaluator/internals.js.map +1 -0
- package/dist/analyzer/typeEvaluator/literalTypes.d.ts +3 -0
- package/dist/analyzer/typeEvaluator/literalTypes.js +52 -0
- package/dist/analyzer/typeEvaluator/literalTypes.js.map +1 -0
- package/dist/analyzer/typeEvaluator/memberResolution.d.ts +79 -0
- package/dist/analyzer/typeEvaluator/memberResolution.js +1007 -0
- package/dist/analyzer/typeEvaluator/memberResolution.js.map +1 -0
- package/dist/analyzer/typeEvaluator/overrideValidation.d.ts +15 -0
- package/dist/analyzer/typeEvaluator/overrideValidation.js +422 -0
- package/dist/analyzer/typeEvaluator/overrideValidation.js.map +1 -0
- package/dist/analyzer/typeEvaluator/returnTypeInference.d.ts +33 -0
- package/dist/analyzer/typeEvaluator/returnTypeInference.js +226 -0
- package/dist/analyzer/typeEvaluator/returnTypeInference.js.map +1 -0
- package/dist/analyzer/typeEvaluator/specialFormCreation.d.ts +39 -0
- package/dist/analyzer/typeEvaluator/specialFormCreation.js +1728 -0
- package/dist/analyzer/typeEvaluator/specialFormCreation.js.map +1 -0
- package/dist/analyzer/typeEvaluator/tupleUnpacking.d.ts +2 -0
- package/dist/analyzer/typeEvaluator/tupleUnpacking.js +36 -0
- package/dist/analyzer/typeEvaluator/tupleUnpacking.js.map +1 -0
- package/dist/analyzer/typeEvaluator/typeCompatibility.d.ts +36 -0
- package/dist/analyzer/typeEvaluator/typeCompatibility.js +1320 -0
- package/dist/analyzer/typeEvaluator/typeCompatibility.js.map +1 -0
- package/dist/analyzer/typeEvaluator/typeGuardNarrowing.d.ts +186 -0
- package/dist/analyzer/typeEvaluator/typeGuardNarrowing.js +1683 -0
- package/dist/analyzer/typeEvaluator/typeGuardNarrowing.js.map +1 -0
- package/dist/analyzer/typeEvaluator/typeVarHandling.d.ts +48 -0
- package/dist/analyzer/typeEvaluator/typeVarHandling.js +756 -0
- package/dist/analyzer/typeEvaluator/typeVarHandling.js.map +1 -0
- package/dist/analyzer/typeEvaluator.d.ts +3 -31
- package/dist/analyzer/typeEvaluator.js +5140 -13656
- package/dist/analyzer/typeEvaluator.js.map +1 -1
- package/dist/analyzer/typeEvaluatorTypes.d.ts +1 -1
- package/dist/analyzer/typeEvaluatorTypes.js +2 -3
- package/dist/analyzer/typeEvaluatorTypes.js.map +1 -1
- package/dist/analyzer/typeGuards.d.ts +3 -2
- package/dist/analyzer/typeGuards.js +236 -1375
- package/dist/analyzer/typeGuards.js.map +1 -1
- package/dist/analyzer/typeUtils.js +9 -2
- package/dist/analyzer/typeUtils.js.map +1 -1
- package/dist/analyzer/typedDicts.js +111 -0
- package/dist/analyzer/typedDicts.js.map +1 -1
- package/dist/analyzer/types.d.ts +14 -0
- package/dist/analyzer/types.js +215 -10
- package/dist/analyzer/types.js.map +1 -1
- package/dist/browser/browserConnection.d.ts +12 -0
- package/dist/browser/browserConnection.js +23 -0
- package/dist/browser/browserConnection.js.map +1 -0
- package/dist/browser/browserFileSystem.d.ts +73 -0
- package/dist/browser/browserFileSystem.js +578 -0
- package/dist/browser/browserFileSystem.js.map +1 -0
- package/dist/browser/browserHost.d.ts +4 -0
- package/dist/browser/browserHost.js +10 -0
- package/dist/browser/browserHost.js.map +1 -0
- package/dist/browser/browserProcess.d.ts +1 -0
- package/dist/browser/browserProcess.js +17 -0
- package/dist/browser/browserProcess.js.map +1 -0
- package/dist/browser/browserServer.d.ts +8 -0
- package/dist/browser/browserServer.js +32 -0
- package/dist/browser/browserServer.js.map +1 -0
- package/dist/browser/cancellation/common.d.ts +10 -0
- package/dist/browser/cancellation/common.js +114 -0
- package/dist/browser/cancellation/common.js.map +1 -0
- package/dist/browser/cancellation/objectURLReceiverStrategy.d.ts +5 -0
- package/dist/browser/cancellation/objectURLReceiverStrategy.js +37 -0
- package/dist/browser/cancellation/objectURLReceiverStrategy.js.map +1 -0
- package/dist/browser/cancellation/objectURLSenderStrategy.d.ts +7 -0
- package/dist/browser/cancellation/objectURLSenderStrategy.js +32 -0
- package/dist/browser/cancellation/objectURLSenderStrategy.js.map +1 -0
- package/dist/browser/worker.d.ts +1 -0
- package/dist/browser/worker.js +33 -0
- package/dist/browser/worker.js.map +1 -0
- package/dist/common/processUtils.d.ts +6 -0
- package/dist/common/processUtils.js +56 -1
- package/dist/common/processUtils.js.map +1 -1
- package/dist/common/textEditTracker.js +1 -1
- package/dist/common/textEditTracker.js.map +1 -1
- package/dist/common/windowsProcessTree.d.ts +2 -0
- package/dist/common/windowsProcessTree.js +23 -0
- package/dist/common/windowsProcessTree.js.map +1 -1
- package/dist/common/windowsProcessTree.json +23 -3
- package/dist/languageServerBase.d.ts +3 -0
- package/dist/languageServerBase.js +44 -12
- package/dist/languageServerBase.js.map +1 -1
- package/dist/languageService/callHierarchyProvider.js +6 -6
- package/dist/languageService/callHierarchyProvider.js.map +1 -1
- package/dist/languageService/referencesProvider.js +3 -3
- package/dist/languageService/referencesProvider.js.map +1 -1
- package/dist/languageService/renameProvider.js +1 -1
- package/dist/languageService/renameProvider.js.map +1 -1
- package/dist/languageService/symbolIndexer.js +2 -2
- package/dist/languageService/symbolIndexer.js.map +1 -1
- package/dist/localization/localize.d.ts +2 -0
- package/dist/localization/localize.js +2 -0
- package/dist/localization/localize.js.map +1 -1
- package/dist/localization/package.nls.en-us.json +8 -0
- package/dist/parser/parseTreeTokenReuse.d.ts +34 -0
- package/dist/parser/parseTreeTokenReuse.js +897 -0
- package/dist/parser/parseTreeTokenReuse.js.map +1 -0
- package/dist/parser/tokenizer.d.ts +10 -1
- package/dist/parser/tokenizer.js +184 -130
- package/dist/parser/tokenizer.js.map +1 -1
- package/dist/pyrightServer.d.ts +34 -0
- package/dist/pyrightServer.js +239 -0
- package/dist/pyrightServer.js.map +1 -0
- package/dist/server.d.ts +3 -23
- package/dist/server.js +12 -232
- package/dist/server.js.map +1 -1
- package/dist/tests/benchmarks/typeInferenceComparison.d.ts +1 -0
- package/dist/tests/benchmarks/typeInferenceComparison.js +1235 -0
- package/dist/tests/benchmarks/typeInferenceComparison.js.map +1 -0
- package/dist/tests/benchmarks/typeInferencePyrightEntry.d.ts +1 -0
- package/dist/tests/benchmarks/typeInferencePyrightEntry.js +53 -0
- package/dist/tests/benchmarks/typeInferencePyrightEntry.js.map +1 -0
- package/dist/tests/browserCancellation.test.d.ts +1 -0
- package/dist/tests/browserCancellation.test.js +63 -0
- package/dist/tests/browserCancellation.test.js.map +1 -0
- package/dist/tests/browserServer.test.d.ts +1 -0
- package/dist/tests/browserServer.test.js +177 -0
- package/dist/tests/browserServer.test.js.map +1 -0
- package/dist/tests/checker.test.js +8 -0
- package/dist/tests/checker.test.js.map +1 -1
- package/dist/tests/constraintSolver.test.js +45 -0
- package/dist/tests/constraintSolver.test.js.map +1 -1
- package/dist/tests/fourSlashParser.test.js +35 -0
- package/dist/tests/fourSlashParser.test.js.map +1 -1
- package/dist/tests/harness/fourslash/fourSlashParser.js +14 -4
- package/dist/tests/harness/fourslash/fourSlashParser.js.map +1 -1
- package/dist/tests/languageServer.test.js +15 -0
- package/dist/tests/languageServer.test.js.map +1 -1
- package/dist/tests/lsp/languageServer.js +6 -6
- package/dist/tests/lsp/languageServer.js.map +1 -1
- package/dist/tests/mypyPrimerAnalysis.test.js +148 -1
- package/dist/tests/mypyPrimerAnalysis.test.js.map +1 -1
- package/dist/tests/typeCacheUtils.test.js +46 -0
- package/dist/tests/typeCacheUtils.test.js.map +1 -1
- package/dist/tests/typeEvaluator1.test.js +78 -1
- package/dist/tests/typeEvaluator1.test.js.map +1 -1
- package/dist/tests/typeEvaluator2.test.js +54 -1
- package/dist/tests/typeEvaluator2.test.js.map +1 -1
- package/dist/tests/typeEvaluator3.test.js +4 -0
- package/dist/tests/typeEvaluator3.test.js.map +1 -1
- package/dist/tests/typeEvaluator4.test.js +42 -3
- package/dist/tests/typeEvaluator4.test.js.map +1 -1
- package/dist/tests/typeEvaluator6.test.js +35 -0
- package/dist/tests/typeEvaluator6.test.js.map +1 -1
- package/dist/tests/typeEvaluator7.test.js +414 -0
- package/dist/tests/typeEvaluator7.test.js.map +1 -1
- package/dist/tests/typeEvaluator8.test.js +1291 -1
- package/dist/tests/typeEvaluator8.test.js.map +1 -1
- package/dist/tests/typeUtils.test.js +28 -0
- package/dist/tests/typeUtils.test.js.map +1 -1
- package/dist/tests/types.test.js +55 -0
- package/dist/tests/types.test.js.map +1 -1
- package/dist/typeServer/programWrapper.js +8 -2
- package/dist/typeServer/programWrapper.js.map +1 -1
- package/dist/typeServer/server.d.ts +12 -2
- package/dist/typeServer/server.js +97 -0
- package/dist/typeServer/server.js.map +1 -1
- package/dist/typeServer/stubGenerator.js +136 -3
- package/dist/typeServer/stubGenerator.js.map +1 -1
- package/dist/typeServer/typeServerConversionUtils.js +13 -0
- package/dist/typeServer/typeServerConversionUtils.js.map +1 -1
- package/package.json +3 -1
|
@@ -0,0 +1,1007 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* memberResolution.ts
|
|
4
|
+
* Copyright (c) Microsoft Corporation.
|
|
5
|
+
* Licensed under the MIT license.
|
|
6
|
+
*
|
|
7
|
+
* memberResolution implementation, using evaluator-owned dependencies and state.
|
|
8
|
+
*/
|
|
9
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
12
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
13
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
14
|
+
}
|
|
15
|
+
Object.defineProperty(o, k2, desc);
|
|
16
|
+
}) : (function(o, m, k, k2) {
|
|
17
|
+
if (k2 === undefined) k2 = k;
|
|
18
|
+
o[k2] = m[k];
|
|
19
|
+
}));
|
|
20
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
21
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
22
|
+
}) : function(o, v) {
|
|
23
|
+
o["default"] = v;
|
|
24
|
+
});
|
|
25
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
26
|
+
var ownKeys = function(o) {
|
|
27
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
28
|
+
var ar = [];
|
|
29
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
30
|
+
return ar;
|
|
31
|
+
};
|
|
32
|
+
return ownKeys(o);
|
|
33
|
+
};
|
|
34
|
+
return function (mod) {
|
|
35
|
+
if (mod && mod.__esModule) return mod;
|
|
36
|
+
var result = {};
|
|
37
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
38
|
+
__setModuleDefault(result, mod);
|
|
39
|
+
return result;
|
|
40
|
+
};
|
|
41
|
+
})();
|
|
42
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
43
|
+
exports.createMemberResolution = createMemberResolution;
|
|
44
|
+
const collectionUtils_1 = require("../../common/collectionUtils");
|
|
45
|
+
const debug_1 = require("../../common/debug");
|
|
46
|
+
const diagnostic_1 = require("../../common/diagnostic");
|
|
47
|
+
const diagnosticRules_1 = require("../../common/diagnosticRules");
|
|
48
|
+
const localize_1 = require("../../localization/localize");
|
|
49
|
+
const analyzerFileInfo_1 = require("../analyzerFileInfo");
|
|
50
|
+
const constructors_1 = require("../constructors");
|
|
51
|
+
const declarationUtils_1 = require("../declarationUtils");
|
|
52
|
+
const parameterUtils_1 = require("../parameterUtils");
|
|
53
|
+
const ParseTreeUtils = __importStar(require("../parseTreeUtils"));
|
|
54
|
+
const typeEvaluatorTypes_1 = require("../typeEvaluatorTypes");
|
|
55
|
+
const types_1 = require("../types");
|
|
56
|
+
const typeUtils_1 = require("../typeUtils");
|
|
57
|
+
// Resolves names, members and declarations; member return types are inferred before specialization.
|
|
58
|
+
function createMemberResolution(context) {
|
|
59
|
+
const { addClassEntryDeclsForKeywordArgIfPresent: _addClassEntryDeclsForKeywordArgIfPresent, addSymbolDeclInfo: _addSymbolDeclInfo, shouldFallBackToClassEntryForKeywordArg: _shouldFallBackToClassEntryForKeywordArg, tryAddPartialKeywordParamDecls: _tryAddPartialKeywordParamDecls, addDiagnostic, codeFlowEngine, evaluateTypesForStatement, evaluatorOptions, getAbstractSymbolInfo, getBoundMagicMethod, getEffectiveTypeOfSymbol, getEffectiveTypeOfSymbolForUsage, getExpectedType, getInferredTypeOfDeclaration, getScopeForNode, getScopeIdForNode, getType, getTypeClassType, getTypeOfAnnotation, getTypeOfBoundMember, getTypeOfClass, getTypeOfFunction, inferReturnTypeIfNecessary, isFlowPathBetweenNodes, isLegalTypeAliasExpressionForm, isSymbolValidTypeExpression, makeTopLevelTypeVarsConcrete, nodeInfo, partiallySpecializeBoundMethod, resolveAliasDeclarationWithInfo, symbolResolutionStack, validateCallArgs, validateInitSubclassArgs, } = context;
|
|
60
|
+
function getIndexOfSymbolResolution(symbol, declaration) {
|
|
61
|
+
return symbolResolutionStack.findIndex((entry) => entry.symbolId === symbol.id && entry.declaration === declaration);
|
|
62
|
+
}
|
|
63
|
+
function pushSymbolResolution(symbol, declaration) {
|
|
64
|
+
const index = getIndexOfSymbolResolution(symbol, declaration);
|
|
65
|
+
if (index >= 0) {
|
|
66
|
+
// Mark all of the entries between these two as invalid.
|
|
67
|
+
for (let i = index + 1; i < symbolResolutionStack.length; i++) {
|
|
68
|
+
symbolResolutionStack[i].isResultValid = false;
|
|
69
|
+
}
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
symbolResolutionStack.push({
|
|
73
|
+
symbolId: symbol.id,
|
|
74
|
+
declaration,
|
|
75
|
+
isResultValid: true,
|
|
76
|
+
});
|
|
77
|
+
return true;
|
|
78
|
+
}
|
|
79
|
+
function popSymbolResolution(symbol) {
|
|
80
|
+
const poppedEntry = symbolResolutionStack.pop();
|
|
81
|
+
(0, debug_1.assert)(poppedEntry !== undefined && poppedEntry.symbolId === symbol.id, `Symbol resolution stack mismatch: expected symbol ${symbol.id}, got ${poppedEntry?.symbolId ?? 'empty stack'}`);
|
|
82
|
+
return poppedEntry.isResultValid;
|
|
83
|
+
}
|
|
84
|
+
function setSymbolResolutionPartialType(symbol, declaration, type) {
|
|
85
|
+
const index = getIndexOfSymbolResolution(symbol, declaration);
|
|
86
|
+
if (index >= 0) {
|
|
87
|
+
symbolResolutionStack[index].partialType = type;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
function getSymbolResolutionPartialType(symbol, declaration) {
|
|
91
|
+
const index = getIndexOfSymbolResolution(symbol, declaration);
|
|
92
|
+
if (index >= 0) {
|
|
93
|
+
return symbolResolutionStack[index].partialType;
|
|
94
|
+
}
|
|
95
|
+
return undefined;
|
|
96
|
+
}
|
|
97
|
+
function isDeclaredTypeAlias(expression) {
|
|
98
|
+
if (expression.nodeType === 54 /* ParseNodeType.TypeAnnotation */) {
|
|
99
|
+
if (expression.d.valueExpr.nodeType === 38 /* ParseNodeType.Name */) {
|
|
100
|
+
const symbolWithScope = lookUpSymbolRecursive(expression, expression.d.valueExpr.d.value,
|
|
101
|
+
/* honorCodeFlow */ false);
|
|
102
|
+
if (symbolWithScope) {
|
|
103
|
+
const symbol = symbolWithScope.symbol;
|
|
104
|
+
return symbol.getDeclarations().find((decl) => isExplicitTypeAliasDeclaration(decl)) !== undefined;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return false;
|
|
109
|
+
}
|
|
110
|
+
function validateSymbolIsTypeExpression(node, type, includesVarDecl) {
|
|
111
|
+
if (isSymbolValidTypeExpression(type, includesVarDecl)) {
|
|
112
|
+
return type;
|
|
113
|
+
}
|
|
114
|
+
// Disable for assignments in the typings.pyi file, since it defines special forms.
|
|
115
|
+
const fileInfo = nodeInfo.getFileInfo(node);
|
|
116
|
+
if (fileInfo.isTypingStubFile) {
|
|
117
|
+
return type;
|
|
118
|
+
}
|
|
119
|
+
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportInvalidTypeForm, localize_1.LocMessage.typeAnnotationVariable(), node);
|
|
120
|
+
return types_1.UnknownType.create();
|
|
121
|
+
}
|
|
122
|
+
function getTypeOfMember(member) {
|
|
123
|
+
if ((0, types_1.isInstantiableClass)(member.classType)) {
|
|
124
|
+
return (0, typeUtils_1.partiallySpecializeType)(getEffectiveTypeOfSymbol(member.symbol), member.classType, getTypeClassType(),
|
|
125
|
+
/* selfClass */ undefined);
|
|
126
|
+
}
|
|
127
|
+
return types_1.UnknownType.create();
|
|
128
|
+
}
|
|
129
|
+
function getTypeOfMemberInternal(errorNode, member, selfClass, flags) {
|
|
130
|
+
if ((0, types_1.isAnyOrUnknown)(member.classType)) {
|
|
131
|
+
return {
|
|
132
|
+
type: member.classType,
|
|
133
|
+
isIncomplete: false,
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
if (!(0, types_1.isInstantiableClass)(member.classType)) {
|
|
137
|
+
return undefined;
|
|
138
|
+
}
|
|
139
|
+
const typeResult = getEffectiveTypeOfSymbolForUsage(member.symbol);
|
|
140
|
+
if (!typeResult) {
|
|
141
|
+
return undefined;
|
|
142
|
+
}
|
|
143
|
+
// Report inappropriate use of variables in type expressions.
|
|
144
|
+
if ((flags & 2048 /* MemberAccessFlags.TypeExpression */) !== 0 && errorNode) {
|
|
145
|
+
typeResult.type = validateSymbolIsTypeExpression(errorNode, typeResult.type, !!typeResult.includesVariableDecl);
|
|
146
|
+
}
|
|
147
|
+
// If the type is a function or overloaded function, infer
|
|
148
|
+
// and cache the return type if necessary. This needs to be done
|
|
149
|
+
// prior to specializing.
|
|
150
|
+
inferReturnTypeIfNecessary(typeResult.type);
|
|
151
|
+
// Check for ambiguous accesses to attributes with generic types?
|
|
152
|
+
if (errorNode &&
|
|
153
|
+
selfClass &&
|
|
154
|
+
(0, types_1.isClass)(selfClass) &&
|
|
155
|
+
member.isInstanceMember &&
|
|
156
|
+
(0, types_1.isClass)(member.unspecializedClassType) &&
|
|
157
|
+
(flags & 1024 /* MemberAccessFlags.DisallowGenericInstanceVariableAccess */) !== 0 &&
|
|
158
|
+
(0, typeUtils_1.requiresSpecialization)(typeResult.type, { ignoreSelf: true, ignoreImplicitTypeArgs: true })) {
|
|
159
|
+
const specializedType = (0, typeUtils_1.partiallySpecializeType)(typeResult.type, member.unspecializedClassType, getTypeClassType(), (0, typeUtils_1.selfSpecializeClass)(selfClass, { overrideTypeArgs: true }));
|
|
160
|
+
if ((0, types_1.findSubtype)(specializedType, (subtype) => !(0, types_1.isFunctionOrOverloaded)(subtype) &&
|
|
161
|
+
(0, typeUtils_1.requiresSpecialization)(subtype, { ignoreSelf: true, ignoreImplicitTypeArgs: true }))) {
|
|
162
|
+
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.LocMessage.genericInstanceVariableAccess(), errorNode);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
return {
|
|
166
|
+
type: (0, typeUtils_1.partiallySpecializeType)(typeResult.type, member.classType, getTypeClassType(), selfClass),
|
|
167
|
+
isIncomplete: !!typeResult.isIncomplete,
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
function bindMethodForMemberAccess(type, concreteType, memberInfo, classType, selfType, flags, memberName, usage, diag, recursionCount = 0) {
|
|
171
|
+
// Check for an attempt to overwrite a final method.
|
|
172
|
+
if (usage.method === 'set') {
|
|
173
|
+
const impl = (0, types_1.isFunction)(concreteType) ? concreteType : types_1.OverloadedType.getImplementation(concreteType);
|
|
174
|
+
if (impl && (0, types_1.isFunction)(impl) && types_1.FunctionType.isFinal(impl) && memberInfo && (0, types_1.isClass)(memberInfo.classType)) {
|
|
175
|
+
diag?.addMessage(localize_1.LocMessage.finalMethodOverride().format({
|
|
176
|
+
name: memberName,
|
|
177
|
+
className: memberInfo.classType.shared.name,
|
|
178
|
+
}));
|
|
179
|
+
return { type: types_1.UnknownType.create(), typeErrors: true };
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
// If this function is an instance member (e.g. a lambda that was
|
|
183
|
+
// assigned to an instance variable), don't perform any binding.
|
|
184
|
+
if (types_1.TypeBase.isInstance(classType)) {
|
|
185
|
+
if (!memberInfo || memberInfo.isInstanceMember) {
|
|
186
|
+
return { type: type };
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
const boundType = bindFunctionToClassOrObject(classType, concreteType, memberInfo && (0, types_1.isInstantiableClass)(memberInfo.classType) ? memberInfo.classType : undefined, (flags & 256 /* MemberAccessFlags.TreatConstructorAsClassMethod */) !== 0, selfType && (0, types_1.isClass)(selfType) ? types_1.ClassType.cloneIncludeSubclasses(selfType) : selfType, diag, recursionCount);
|
|
190
|
+
return { type: boundType ?? types_1.UnknownType.create(), typeErrors: !boundType };
|
|
191
|
+
}
|
|
192
|
+
function isAsymmetricDescriptorClass(classType) {
|
|
193
|
+
// If the value has already been cached in this type, return the cached value.
|
|
194
|
+
if (classType.priv.isAsymmetricDescriptor !== undefined) {
|
|
195
|
+
return classType.priv.isAsymmetricDescriptor;
|
|
196
|
+
}
|
|
197
|
+
let isAsymmetric = false;
|
|
198
|
+
// Accessors can be defined at different levels of the descriptor's MRO.
|
|
199
|
+
// Ignore instance members so an instance attribute that happens to share
|
|
200
|
+
// a dunder name doesn't shadow the descriptor protocol during this check.
|
|
201
|
+
const accessorFlags = 16 /* MemberAccessFlags.SkipInstanceMembers */ | 512 /* MemberAccessFlags.SkipAttributeAccessOverride */;
|
|
202
|
+
const getterSymbolResult = (0, typeUtils_1.lookUpClassMember)(classType, '__get__', accessorFlags);
|
|
203
|
+
const setterSymbolResult = (0, typeUtils_1.lookUpClassMember)(classType, '__set__', accessorFlags);
|
|
204
|
+
if (!getterSymbolResult || !setterSymbolResult) {
|
|
205
|
+
isAsymmetric = false;
|
|
206
|
+
}
|
|
207
|
+
else {
|
|
208
|
+
let getterType = getTypeOfMember(getterSymbolResult);
|
|
209
|
+
let setterType = getTypeOfMember(setterSymbolResult);
|
|
210
|
+
// The getter and setter can be declared on different classes. Specialize
|
|
211
|
+
// both against the concrete descriptor class so Self and inherited type
|
|
212
|
+
// variables are compared in the same context.
|
|
213
|
+
if (getterSymbolResult.classType && (0, types_1.isInstantiableClass)(getterSymbolResult.classType)) {
|
|
214
|
+
getterType = (0, typeUtils_1.partiallySpecializeType)(getterType, getterSymbolResult.classType, getTypeClassType(), classType);
|
|
215
|
+
}
|
|
216
|
+
if (setterSymbolResult.classType && (0, types_1.isInstantiableClass)(setterSymbolResult.classType)) {
|
|
217
|
+
setterType = (0, typeUtils_1.partiallySpecializeType)(setterType, setterSymbolResult.classType, getTypeClassType(), classType);
|
|
218
|
+
}
|
|
219
|
+
// If this is an overload, find the appropriate overload.
|
|
220
|
+
if ((0, types_1.isOverloaded)(getterType)) {
|
|
221
|
+
const getOverloads = types_1.OverloadedType.getOverloads(getterType).filter((overload) => {
|
|
222
|
+
if (overload.shared.parameters.length < 2) {
|
|
223
|
+
return false;
|
|
224
|
+
}
|
|
225
|
+
const param1Type = types_1.FunctionType.getParamType(overload, 1);
|
|
226
|
+
return !(0, typeUtils_1.isNoneInstance)(param1Type);
|
|
227
|
+
});
|
|
228
|
+
if (getOverloads.length === 1) {
|
|
229
|
+
getterType = getOverloads[0];
|
|
230
|
+
}
|
|
231
|
+
else {
|
|
232
|
+
isAsymmetric = true;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
// If this is an overload, find the appropriate overload.
|
|
236
|
+
if ((0, types_1.isOverloaded)(setterType)) {
|
|
237
|
+
isAsymmetric = true;
|
|
238
|
+
}
|
|
239
|
+
// If either the setter or getter is an overload (or some other non-function type),
|
|
240
|
+
// conservatively assume that it's not asymmetric.
|
|
241
|
+
if ((0, types_1.isFunction)(getterType) && (0, types_1.isFunction)(setterType)) {
|
|
242
|
+
// If there's no declared return type on the getter, assume it's symmetric.
|
|
243
|
+
if (setterType.shared.parameters.length >= 3 && getterType.shared.declaredReturnType) {
|
|
244
|
+
const setterValueType = types_1.FunctionType.getParamType(setterType, 2);
|
|
245
|
+
const getterReturnType = types_1.FunctionType.getEffectiveReturnType(getterType) ?? types_1.UnknownType.create();
|
|
246
|
+
if (!(0, types_1.isTypeSame)(setterValueType, getterReturnType)) {
|
|
247
|
+
isAsymmetric = true;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
// Cache the value for next time.
|
|
253
|
+
classType.priv.isAsymmetricDescriptor = isAsymmetric;
|
|
254
|
+
return isAsymmetric;
|
|
255
|
+
}
|
|
256
|
+
function applyAttributeAccessOverride(errorNode, classType, usage, memberName, selfType) {
|
|
257
|
+
const getAttributeAccessMember = (name) => {
|
|
258
|
+
return getTypeOfBoundMember(errorNode, classType, name,
|
|
259
|
+
/* usage */ undefined,
|
|
260
|
+
/* diag */ undefined, 16 /* MemberAccessFlags.SkipInstanceMembers */ |
|
|
261
|
+
4 /* MemberAccessFlags.SkipObjectBaseClass */ |
|
|
262
|
+
8 /* MemberAccessFlags.SkipTypeBaseClass */ |
|
|
263
|
+
512 /* MemberAccessFlags.SkipAttributeAccessOverride */, selfType)?.type;
|
|
264
|
+
};
|
|
265
|
+
let accessMemberType;
|
|
266
|
+
if (usage.method === 'get') {
|
|
267
|
+
accessMemberType = getAttributeAccessMember('__getattribute__') ?? getAttributeAccessMember('__getattr__');
|
|
268
|
+
}
|
|
269
|
+
else if (usage.method === 'set') {
|
|
270
|
+
accessMemberType = getAttributeAccessMember('__setattr__');
|
|
271
|
+
}
|
|
272
|
+
else {
|
|
273
|
+
(0, debug_1.assert)(usage.method === 'del');
|
|
274
|
+
accessMemberType = getAttributeAccessMember('__delattr__');
|
|
275
|
+
}
|
|
276
|
+
if (!accessMemberType) {
|
|
277
|
+
return undefined;
|
|
278
|
+
}
|
|
279
|
+
const argList = [];
|
|
280
|
+
// Provide "name" argument.
|
|
281
|
+
argList.push({
|
|
282
|
+
argCategory: 0 /* ArgCategory.Simple */,
|
|
283
|
+
typeResult: {
|
|
284
|
+
type: context.prefetched?.strClass && (0, types_1.isInstantiableClass)(context.prefetched.strClass)
|
|
285
|
+
? types_1.ClassType.cloneWithLiteral(types_1.ClassType.cloneAsInstance(context.prefetched.strClass), memberName)
|
|
286
|
+
: types_1.AnyType.create(),
|
|
287
|
+
},
|
|
288
|
+
});
|
|
289
|
+
if (usage.method === 'set') {
|
|
290
|
+
// Provide "value" argument.
|
|
291
|
+
argList.push({
|
|
292
|
+
argCategory: 0 /* ArgCategory.Simple */,
|
|
293
|
+
typeResult: {
|
|
294
|
+
type: usage.setType?.type ?? types_1.UnknownType.create(),
|
|
295
|
+
isIncomplete: !!usage.setType?.isIncomplete,
|
|
296
|
+
},
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
if (!(0, types_1.isFunctionOrOverloaded)(accessMemberType)) {
|
|
300
|
+
if ((0, types_1.isAnyOrUnknown)(accessMemberType)) {
|
|
301
|
+
return { type: accessMemberType };
|
|
302
|
+
}
|
|
303
|
+
// TODO - emit an error for this condition.
|
|
304
|
+
return undefined;
|
|
305
|
+
}
|
|
306
|
+
const callResult = validateCallArgs(errorNode, argList, { type: accessMemberType },
|
|
307
|
+
/* constraints */ undefined,
|
|
308
|
+
/* skipUnknownArgCheck */ true,
|
|
309
|
+
/* inferenceContext */ undefined);
|
|
310
|
+
let isAsymmetricAccessor = false;
|
|
311
|
+
if (usage.method === 'set') {
|
|
312
|
+
isAsymmetricAccessor = isClassWithAsymmetricAttributeAccessor(classType);
|
|
313
|
+
}
|
|
314
|
+
return {
|
|
315
|
+
type: callResult.returnType ?? types_1.UnknownType.create(),
|
|
316
|
+
typeErrors: callResult.argumentErrors,
|
|
317
|
+
isAsymmetricAccessor,
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
function synthesizeTypeAliasPlaceholder(nameNode, isTypeAliasType = false) {
|
|
321
|
+
const placeholder = types_1.TypeVarType.createInstantiable(`__type_alias_${nameNode.d.value}`);
|
|
322
|
+
placeholder.shared.isSynthesized = true;
|
|
323
|
+
const typeVarScopeId = getScopeIdForNode(nameNode);
|
|
324
|
+
const fileInfo = nodeInfo.getFileInfo(nameNode);
|
|
325
|
+
placeholder.shared.recursiveAlias = {
|
|
326
|
+
name: nameNode.d.value,
|
|
327
|
+
fullName: ParseTreeUtils.getClassFullName(nameNode, fileInfo.moduleName, nameNode.d.value),
|
|
328
|
+
moduleName: fileInfo.moduleName,
|
|
329
|
+
fileUri: fileInfo.fileUri,
|
|
330
|
+
typeVarScopeId,
|
|
331
|
+
isTypeAliasType,
|
|
332
|
+
typeParams: undefined,
|
|
333
|
+
computedVariance: undefined,
|
|
334
|
+
};
|
|
335
|
+
placeholder.priv.scopeId = typeVarScopeId;
|
|
336
|
+
return placeholder;
|
|
337
|
+
}
|
|
338
|
+
function getAliasedSymbolTypeForName(node, name) {
|
|
339
|
+
const symbolWithScope = lookUpSymbolRecursive(node, name, /* honorCodeFlow */ true);
|
|
340
|
+
if (!symbolWithScope) {
|
|
341
|
+
return undefined;
|
|
342
|
+
}
|
|
343
|
+
// Normally there will be at most one decl associated with the import node, but
|
|
344
|
+
// there can be multiple in the case of the "from .X import X" statement. In such
|
|
345
|
+
// case, we want to choose the last declaration.
|
|
346
|
+
const filteredDecls = symbolWithScope.symbol
|
|
347
|
+
.getDeclarations()
|
|
348
|
+
.filter((decl) => ParseTreeUtils.isNodeContainedWithin(node, decl.node) && decl.type === 8 /* DeclarationType.Alias */);
|
|
349
|
+
let aliasDecl = filteredDecls.length > 0 ? filteredDecls[filteredDecls.length - 1] : undefined;
|
|
350
|
+
// If we didn't find an exact match, look for any alias associated with
|
|
351
|
+
// this symbol. In cases where we have multiple ImportAs nodes that share
|
|
352
|
+
// the same first-part name (e.g. "import asyncio" and "import asyncio.tasks"),
|
|
353
|
+
// we may not find the declaration associated with this node.
|
|
354
|
+
if (!aliasDecl) {
|
|
355
|
+
aliasDecl = symbolWithScope.symbol.getDeclarations().find((decl) => decl.type === 8 /* DeclarationType.Alias */);
|
|
356
|
+
}
|
|
357
|
+
if (!aliasDecl) {
|
|
358
|
+
return undefined;
|
|
359
|
+
}
|
|
360
|
+
(0, debug_1.assert)(aliasDecl.type === 8 /* DeclarationType.Alias */);
|
|
361
|
+
const fileInfo = nodeInfo.getFileInfo(node);
|
|
362
|
+
// Try to resolve the alias while honoring external visibility.
|
|
363
|
+
const resolvedAliasInfo = resolveAliasDeclarationWithInfo(aliasDecl, /* resolveLocalNames */ true, {
|
|
364
|
+
allowExternallyHiddenAccess: fileInfo.isStubFile,
|
|
365
|
+
});
|
|
366
|
+
if (!resolvedAliasInfo) {
|
|
367
|
+
return undefined;
|
|
368
|
+
}
|
|
369
|
+
if (!resolvedAliasInfo.declaration) {
|
|
370
|
+
return evaluatorOptions.evaluateUnknownImportsAsAny ? types_1.AnyType.create() : types_1.UnknownType.create();
|
|
371
|
+
}
|
|
372
|
+
if (node.nodeType === 26 /* ParseNodeType.ImportFromAs */) {
|
|
373
|
+
if (resolvedAliasInfo.isPrivate) {
|
|
374
|
+
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportPrivateUsage, localize_1.LocMessage.privateUsedOutsideOfModule().format({
|
|
375
|
+
name: node.d.name.d.value,
|
|
376
|
+
}), node.d.name);
|
|
377
|
+
}
|
|
378
|
+
if (resolvedAliasInfo.privatePyTypedImporter) {
|
|
379
|
+
const diag = new diagnostic_1.DiagnosticAddendum();
|
|
380
|
+
if (resolvedAliasInfo.privatePyTypedImported) {
|
|
381
|
+
diag.addMessage(localize_1.LocAddendum.privateImportFromPyTypedSource().format({
|
|
382
|
+
module: resolvedAliasInfo.privatePyTypedImported,
|
|
383
|
+
}));
|
|
384
|
+
}
|
|
385
|
+
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportPrivateImportUsage, localize_1.LocMessage.privateImportFromPyTypedModule().format({
|
|
386
|
+
name: node.d.name.d.value,
|
|
387
|
+
module: resolvedAliasInfo.privatePyTypedImporter,
|
|
388
|
+
}) + diag.getString(), node.d.name);
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
return getInferredTypeOfDeclaration(symbolWithScope.symbol, aliasDecl);
|
|
392
|
+
}
|
|
393
|
+
function lookUpSymbolRecursive(node, name, honorCodeFlow, preferGlobalScope = false) {
|
|
394
|
+
const scopeNodeInfo = ParseTreeUtils.getEvaluationScopeNode(node, nodeInfo);
|
|
395
|
+
const scope = nodeInfo.getScope(scopeNodeInfo.node);
|
|
396
|
+
let symbolWithScope = scope?.lookUpSymbolRecursive(name, {
|
|
397
|
+
useProxyScope: !!scopeNodeInfo.useProxyScope,
|
|
398
|
+
useChainedModuleLevelScopes: !!scopeNodeInfo.useChainedModuleLevelScopes,
|
|
399
|
+
});
|
|
400
|
+
const scopeType = scope?.type ?? 4 /* ScopeType.Module */;
|
|
401
|
+
// Functions and list comprehensions don't allow access to implicitly
|
|
402
|
+
// aliased symbols in outer scopes if they haven't yet been assigned
|
|
403
|
+
// within the local scope.
|
|
404
|
+
let scopeTypeHonorsCodeFlow = scopeType !== 2 /* ScopeType.Function */ && scopeType !== 1 /* ScopeType.Comprehension */;
|
|
405
|
+
// Type parameter scopes don't honor code flow.
|
|
406
|
+
if (symbolWithScope?.scope.type === 0 /* ScopeType.TypeParameter */) {
|
|
407
|
+
scopeTypeHonorsCodeFlow = false;
|
|
408
|
+
}
|
|
409
|
+
if (symbolWithScope && honorCodeFlow && scopeTypeHonorsCodeFlow) {
|
|
410
|
+
// Filter the declarations based on flow reachability.
|
|
411
|
+
const reachableDecl = symbolWithScope.symbol.getDeclarations().find((decl) => {
|
|
412
|
+
if (decl.type !== 8 /* DeclarationType.Alias */ && decl.type !== 0 /* DeclarationType.Intrinsic */) {
|
|
413
|
+
// Determine if the declaration is in the same execution scope as the "usageNode" node.
|
|
414
|
+
let usageScopeNode = ParseTreeUtils.getExecutionScopeNode(node, nodeInfo);
|
|
415
|
+
const declNode = decl.type === 6 /* DeclarationType.Class */ ||
|
|
416
|
+
decl.type === 5 /* DeclarationType.Function */ ||
|
|
417
|
+
decl.type === 4 /* DeclarationType.TypeAlias */
|
|
418
|
+
? decl.node.d.name
|
|
419
|
+
: decl.node;
|
|
420
|
+
const declScopeNode = ParseTreeUtils.getExecutionScopeNode(declNode, nodeInfo);
|
|
421
|
+
// If this is a type parameter scope, it will be a proxy for its
|
|
422
|
+
// containing scope, so we need to use that instead.
|
|
423
|
+
const usageScope = nodeInfo.getScope(usageScopeNode);
|
|
424
|
+
if (usageScope?.proxy) {
|
|
425
|
+
const typeParamScope = nodeInfo.getScope(usageScopeNode);
|
|
426
|
+
if (!typeParamScope?.symbolTable.has(name) && usageScopeNode.parent) {
|
|
427
|
+
usageScopeNode = ParseTreeUtils.getExecutionScopeNode(usageScopeNode.parent, nodeInfo);
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
if (usageScopeNode === declScopeNode) {
|
|
431
|
+
if (!isFlowPathBetweenNodes(declNode, node)) {
|
|
432
|
+
// If there was no control flow path from the usage back
|
|
433
|
+
// to the source, see if the usage node is reachable by
|
|
434
|
+
// any path.
|
|
435
|
+
const flowNode = nodeInfo.getFlowNode(node);
|
|
436
|
+
const isReachable = flowNode &&
|
|
437
|
+
codeFlowEngine.getFlowNodeReachability(flowNode,
|
|
438
|
+
/* sourceFlowNode */ undefined,
|
|
439
|
+
/* ignoreNoReturn */ true) === typeEvaluatorTypes_1.Reachability.Reachable;
|
|
440
|
+
return !isReachable;
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
return true;
|
|
445
|
+
});
|
|
446
|
+
// If none of the declarations are reachable from the current node,
|
|
447
|
+
// search for the symbol in outer scopes.
|
|
448
|
+
if (!reachableDecl) {
|
|
449
|
+
if (symbolWithScope.scope.type !== 2 /* ScopeType.Function */) {
|
|
450
|
+
let nextScopeToSearch = symbolWithScope.scope.parent;
|
|
451
|
+
const isOutsideCallerModule = symbolWithScope.isOutsideCallerModule || symbolWithScope.scope.type === 4 /* ScopeType.Module */;
|
|
452
|
+
let isBeyondExecutionScope = symbolWithScope.isBeyondExecutionScope || symbolWithScope.scope.isIndependentlyExecutable();
|
|
453
|
+
if (symbolWithScope.scope.type === 3 /* ScopeType.Class */) {
|
|
454
|
+
// There is an odd documented behavior for classes in that
|
|
455
|
+
// symbol resolution skips to the global scope rather than
|
|
456
|
+
// the next scope in the chain.
|
|
457
|
+
const globalScopeResult = symbolWithScope.scope.getGlobalScope();
|
|
458
|
+
nextScopeToSearch = globalScopeResult.scope;
|
|
459
|
+
if (globalScopeResult.isBeyondExecutionScope) {
|
|
460
|
+
isBeyondExecutionScope = true;
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
if (nextScopeToSearch) {
|
|
464
|
+
symbolWithScope = nextScopeToSearch.lookUpSymbolRecursive(name, {
|
|
465
|
+
isOutsideCallerModule,
|
|
466
|
+
isBeyondExecutionScope,
|
|
467
|
+
});
|
|
468
|
+
}
|
|
469
|
+
else {
|
|
470
|
+
symbolWithScope = undefined;
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
else {
|
|
474
|
+
symbolWithScope = undefined;
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
// PEP 563 indicates that if a forward reference can be resolved in the module
|
|
479
|
+
// scope (or, by implication, in the builtins scope), it should prefer that
|
|
480
|
+
// resolution over local resolutions. This doesn't apply to a PEP 695 "type"
|
|
481
|
+
// statement's target, which binds synchronously in the scope where it appears
|
|
482
|
+
// (including a class scope) rather than being deferred like other annotations.
|
|
483
|
+
const isTypeAliasStatementTarget = symbolWithScope?.symbol
|
|
484
|
+
.getDeclarations()
|
|
485
|
+
.some((decl) => decl.type === 4 /* DeclarationType.TypeAlias */);
|
|
486
|
+
if (symbolWithScope && preferGlobalScope && !isTypeAliasStatementTarget) {
|
|
487
|
+
let curSymbolWithScope = symbolWithScope;
|
|
488
|
+
while (curSymbolWithScope.scope.type !== 4 /* ScopeType.Module */ &&
|
|
489
|
+
curSymbolWithScope.scope.type !== 5 /* ScopeType.Builtin */ &&
|
|
490
|
+
curSymbolWithScope.scope.type !== 0 /* ScopeType.TypeParameter */ &&
|
|
491
|
+
curSymbolWithScope.scope.parent) {
|
|
492
|
+
curSymbolWithScope = curSymbolWithScope.scope.parent.lookUpSymbolRecursive(name, {
|
|
493
|
+
isOutsideCallerModule: curSymbolWithScope.isOutsideCallerModule,
|
|
494
|
+
isBeyondExecutionScope: curSymbolWithScope.isBeyondExecutionScope ||
|
|
495
|
+
curSymbolWithScope.scope.isIndependentlyExecutable(),
|
|
496
|
+
});
|
|
497
|
+
if (!curSymbolWithScope) {
|
|
498
|
+
break;
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
if (curSymbolWithScope?.scope.type === 4 /* ScopeType.Module */ ||
|
|
502
|
+
curSymbolWithScope?.scope.type === 5 /* ScopeType.Builtin */) {
|
|
503
|
+
symbolWithScope = curSymbolWithScope;
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
return symbolWithScope;
|
|
507
|
+
}
|
|
508
|
+
function getDeclarationFromKeywordParam(type, paramName) {
|
|
509
|
+
if ((0, types_1.isFunction)(type)) {
|
|
510
|
+
if (type.shared.declaration) {
|
|
511
|
+
const functionDecl = type.shared.declaration;
|
|
512
|
+
if (functionDecl.type === 5 /* DeclarationType.Function */) {
|
|
513
|
+
const functionNode = functionDecl.node;
|
|
514
|
+
const functionScope = nodeInfo.getScope(functionNode);
|
|
515
|
+
if (functionScope) {
|
|
516
|
+
const paramSymbol = functionScope.lookUpSymbol(paramName);
|
|
517
|
+
if (paramSymbol) {
|
|
518
|
+
return paramSymbol.getDeclarations().find((decl) => decl.type === 2 /* DeclarationType.Param */);
|
|
519
|
+
}
|
|
520
|
+
const parameterDetails = (0, parameterUtils_1.getParamListDetails)(type);
|
|
521
|
+
if (parameterDetails.unpackedKwargsTypedDictType) {
|
|
522
|
+
const lookupResults = (0, typeUtils_1.lookUpClassMember)(parameterDetails.unpackedKwargsTypedDictType, paramName);
|
|
523
|
+
if (lookupResults) {
|
|
524
|
+
return lookupResults.symbol
|
|
525
|
+
.getDeclarations()
|
|
526
|
+
.find((decl) => decl.type === 1 /* DeclarationType.Variable */);
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
return undefined;
|
|
534
|
+
}
|
|
535
|
+
function getAliasFromImport(node) {
|
|
536
|
+
if (node.parent &&
|
|
537
|
+
node.parent.nodeType === 26 /* ParseNodeType.ImportFromAs */ &&
|
|
538
|
+
node.parent.d.alias &&
|
|
539
|
+
node === node.parent.d.name) {
|
|
540
|
+
return node.parent.d.alias;
|
|
541
|
+
}
|
|
542
|
+
return undefined;
|
|
543
|
+
}
|
|
544
|
+
function getDeclInfoForStringNode(node) {
|
|
545
|
+
const decls = [];
|
|
546
|
+
const synthesizedTypes = [];
|
|
547
|
+
const expectedType = getExpectedType(node)?.type;
|
|
548
|
+
if (expectedType) {
|
|
549
|
+
(0, typeUtils_1.doForEachSubtype)(expectedType, (subtype) => {
|
|
550
|
+
// If the expected type is a TypedDict then the node is either a key expression
|
|
551
|
+
// or a single entry in a set. We then need to check that the value of the node
|
|
552
|
+
// is a valid entry in the TypedDict to avoid resolving declarations for
|
|
553
|
+
// synthesized symbols such as 'get'.
|
|
554
|
+
if ((0, types_1.isClassInstance)(subtype) && types_1.ClassType.isTypedDictClass(subtype)) {
|
|
555
|
+
const entry = subtype.shared.typedDictEntries?.knownItems.get(node.d.value);
|
|
556
|
+
if (entry) {
|
|
557
|
+
const symbol = (0, typeUtils_1.lookUpObjectMember)(subtype, node.d.value)?.symbol;
|
|
558
|
+
if (symbol) {
|
|
559
|
+
_addSymbolDeclInfo(symbol, decls, synthesizedTypes);
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
});
|
|
564
|
+
}
|
|
565
|
+
return decls.length === 0 ? undefined : { decls, synthesizedTypes };
|
|
566
|
+
}
|
|
567
|
+
function getDeclInfoForNameNode(node, skipUnreachableCode = true) {
|
|
568
|
+
if (skipUnreachableCode && nodeInfo.isCodeUnreachable(node)) {
|
|
569
|
+
return undefined;
|
|
570
|
+
}
|
|
571
|
+
const decls = [];
|
|
572
|
+
const synthesizedTypes = [];
|
|
573
|
+
// If the node is part of a "from X import Y as Z" statement and the node
|
|
574
|
+
// is the "Y" (non-aliased) name, we need to look up the alias symbol
|
|
575
|
+
// since the non-aliased name is not in the symbol table.
|
|
576
|
+
const alias = getAliasFromImport(node);
|
|
577
|
+
if (alias) {
|
|
578
|
+
const scope = getScopeForNode(node);
|
|
579
|
+
if (scope) {
|
|
580
|
+
// Look up the alias symbol.
|
|
581
|
+
const symbolInScope = scope.lookUpSymbolRecursive(alias.d.value);
|
|
582
|
+
if (symbolInScope) {
|
|
583
|
+
// The alias could have more decls that don't refer to this import. Filter
|
|
584
|
+
// out the one(s) that specifically associated with this import statement.
|
|
585
|
+
const declsForThisImport = symbolInScope.symbol.getDeclarations().filter((decl) => {
|
|
586
|
+
return decl.type === 8 /* DeclarationType.Alias */ && decl.node === node.parent;
|
|
587
|
+
});
|
|
588
|
+
(0, collectionUtils_1.appendArray)(decls, (0, declarationUtils_1.getDeclarationsWithUsesLocalNameRemoved)(declsForThisImport));
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
else if (node.parent &&
|
|
593
|
+
node.parent.nodeType === 35 /* ParseNodeType.MemberAccess */ &&
|
|
594
|
+
node === node.parent.d.member) {
|
|
595
|
+
let baseType = getType(node.parent.d.leftExpr);
|
|
596
|
+
if (baseType) {
|
|
597
|
+
baseType = makeTopLevelTypeVarsConcrete(baseType);
|
|
598
|
+
const memberName = node.parent.d.member.d.value;
|
|
599
|
+
(0, typeUtils_1.doForEachSubtype)(baseType, (subtype) => {
|
|
600
|
+
let symbol;
|
|
601
|
+
subtype = makeTopLevelTypeVarsConcrete(subtype);
|
|
602
|
+
if ((0, types_1.isInstantiableClass)(subtype)) {
|
|
603
|
+
// Try to find a member that has a declared type. If so, that
|
|
604
|
+
// overrides any inferred types.
|
|
605
|
+
let member = (0, typeUtils_1.lookUpClassMember)(subtype, memberName, 64 /* MemberAccessFlags.DeclaredTypesOnly */);
|
|
606
|
+
if (!member) {
|
|
607
|
+
member = (0, typeUtils_1.lookUpClassMember)(subtype, memberName);
|
|
608
|
+
}
|
|
609
|
+
if (!member) {
|
|
610
|
+
const metaclass = subtype.shared.effectiveMetaclass;
|
|
611
|
+
if (metaclass && (0, types_1.isInstantiableClass)(metaclass)) {
|
|
612
|
+
member = (0, typeUtils_1.lookUpClassMember)(metaclass, memberName);
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
if (member) {
|
|
616
|
+
symbol = member.symbol;
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
else if ((0, types_1.isClassInstance)(subtype)) {
|
|
620
|
+
// Try to find a member that has a declared type. If so, that
|
|
621
|
+
// overrides any inferred types.
|
|
622
|
+
let member = (0, typeUtils_1.lookUpObjectMember)(subtype, memberName, 64 /* MemberAccessFlags.DeclaredTypesOnly */);
|
|
623
|
+
if (!member) {
|
|
624
|
+
member = (0, typeUtils_1.lookUpObjectMember)(subtype, memberName);
|
|
625
|
+
}
|
|
626
|
+
if (member) {
|
|
627
|
+
symbol = member.symbol;
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
else if ((0, types_1.isModule)(subtype)) {
|
|
631
|
+
symbol = types_1.ModuleType.getField(subtype, memberName);
|
|
632
|
+
}
|
|
633
|
+
if (symbol) {
|
|
634
|
+
// By default, report only the declarations that have type annotations.
|
|
635
|
+
// If there are none, then report all of the unannotated declarations,
|
|
636
|
+
// which includes every assignment of that symbol.
|
|
637
|
+
_addSymbolDeclInfo(symbol, decls, synthesizedTypes, /* preferTypedDeclarations */ true);
|
|
638
|
+
}
|
|
639
|
+
});
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
else if (node.parent && node.parent.nodeType === 37 /* ParseNodeType.ModuleName */) {
|
|
643
|
+
const namePartIndex = node.parent.d.nameParts.findIndex((part) => part === node);
|
|
644
|
+
const importInfo = nodeInfo.getImportInfo(node.parent);
|
|
645
|
+
if (namePartIndex >= 0 &&
|
|
646
|
+
importInfo &&
|
|
647
|
+
!importInfo.isNativeLib &&
|
|
648
|
+
namePartIndex < importInfo.resolvedUris.length) {
|
|
649
|
+
if (importInfo.resolvedUris[namePartIndex]) {
|
|
650
|
+
evaluateTypesForStatement(node);
|
|
651
|
+
// Synthesize an alias declaration for this name part. The only
|
|
652
|
+
// time this case is used is for IDE services such as
|
|
653
|
+
// the find all references, hover provider and etc.
|
|
654
|
+
decls.push((0, declarationUtils_1.synthesizeAliasDeclaration)(importInfo.resolvedUris[namePartIndex]));
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
else if (node.parent && node.parent.nodeType === 1 /* ParseNodeType.Argument */ && node === node.parent.d.name) {
|
|
659
|
+
// The target node is the name in a keyword argument. We need to determine whether
|
|
660
|
+
// the corresponding keyword parameter can be determined from the context.
|
|
661
|
+
const argNode = node.parent;
|
|
662
|
+
const paramName = node.d.value;
|
|
663
|
+
if (argNode.parent?.nodeType === 9 /* ParseNodeType.Call */) {
|
|
664
|
+
const baseType = getType(argNode.parent.d.leftExpr);
|
|
665
|
+
if (baseType) {
|
|
666
|
+
if (_tryAddPartialKeywordParamDecls(baseType, argNode.parent, paramName, decls)) {
|
|
667
|
+
// functools.partial keyword args are resolved against the wrapped callable.
|
|
668
|
+
}
|
|
669
|
+
else if ((0, types_1.isFunction)(baseType) && baseType.shared.declaration) {
|
|
670
|
+
const paramDecl = getDeclarationFromKeywordParam(baseType, paramName);
|
|
671
|
+
if (paramDecl) {
|
|
672
|
+
decls.push(paramDecl);
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
else if ((0, types_1.isOverloaded)(baseType)) {
|
|
676
|
+
types_1.OverloadedType.getOverloads(baseType).forEach((f) => {
|
|
677
|
+
const paramDecl = getDeclarationFromKeywordParam(f, paramName);
|
|
678
|
+
if (paramDecl) {
|
|
679
|
+
decls.push(paramDecl);
|
|
680
|
+
}
|
|
681
|
+
});
|
|
682
|
+
}
|
|
683
|
+
else if ((0, types_1.isInstantiableClass)(baseType)) {
|
|
684
|
+
const initMethodType = (0, constructors_1.getBoundInitMethod)(context, argNode.parent.d.leftExpr, types_1.ClassType.cloneAsInstance(baseType))?.type;
|
|
685
|
+
if (initMethodType && (0, types_1.isFunction)(initMethodType)) {
|
|
686
|
+
const paramDecl = getDeclarationFromKeywordParam(initMethodType, paramName);
|
|
687
|
+
if (paramDecl) {
|
|
688
|
+
decls.push(paramDecl);
|
|
689
|
+
}
|
|
690
|
+
else if (_shouldFallBackToClassEntryForKeywordArg(baseType, paramName)) {
|
|
691
|
+
_addClassEntryDeclsForKeywordArgIfPresent(baseType, paramName, decls, synthesizedTypes);
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
else if (_shouldFallBackToClassEntryForKeywordArg(baseType, paramName)) {
|
|
695
|
+
// Some synthesized callables (notably TypedDict "constructors") don't have a
|
|
696
|
+
// meaningful __init__ signature we can map keyword arguments to. In these cases,
|
|
697
|
+
// treat the keyword as referring to the class entry so IDE features like
|
|
698
|
+
// go-to-definition and rename can bind to the field declaration.
|
|
699
|
+
_addClassEntryDeclsForKeywordArgIfPresent(baseType, paramName, decls, synthesizedTypes);
|
|
700
|
+
}
|
|
701
|
+
}
|
|
702
|
+
}
|
|
703
|
+
}
|
|
704
|
+
else if (argNode.parent?.nodeType === 10 /* ParseNodeType.Class */) {
|
|
705
|
+
const classTypeResult = getTypeOfClass(argNode.parent);
|
|
706
|
+
// Validate the init subclass args for this class so we can properly
|
|
707
|
+
// evaluate its custom keyword parameters.
|
|
708
|
+
if (classTypeResult) {
|
|
709
|
+
validateInitSubclassArgs(argNode.parent, classTypeResult.classType);
|
|
710
|
+
}
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
else if (node.parent &&
|
|
714
|
+
node.parent.nodeType === 74 /* ParseNodeType.PatternClassArgument */ &&
|
|
715
|
+
node === node.parent.d.name &&
|
|
716
|
+
node.parent.parent?.nodeType === 68 /* ParseNodeType.PatternClass */) {
|
|
717
|
+
// The target node is the keyword name in a class pattern argument
|
|
718
|
+
// (e.g. `case Foo(prop=...)`). Map it to the corresponding class member
|
|
719
|
+
// declaration so that find-all-references and rename bind to the attribute.
|
|
720
|
+
// Only the keyword (left of `=`) is handled here; the capture target on the
|
|
721
|
+
// right (e.g. the second `prop` in `case Foo(prop=prop)`) is a separate local
|
|
722
|
+
// binding that is resolved through the normal name-lookup path.
|
|
723
|
+
const memberName = node.d.value;
|
|
724
|
+
let classType = getType(node.parent.parent.d.className);
|
|
725
|
+
if (classType) {
|
|
726
|
+
classType = makeTopLevelTypeVarsConcrete(classType);
|
|
727
|
+
(0, typeUtils_1.doForEachSubtype)(classType, (subtype) => {
|
|
728
|
+
subtype = makeTopLevelTypeVarsConcrete(subtype);
|
|
729
|
+
// The class name in a class pattern usually evaluates to an instantiable class,
|
|
730
|
+
// but analysis can still yield Unknown/Any (e.g. an unresolved class name), so
|
|
731
|
+
// the isInstantiableClass gate skips those subtypes rather than assuming
|
|
732
|
+
// every subtype is a class.
|
|
733
|
+
if ((0, types_1.isInstantiableClass)(subtype)) {
|
|
734
|
+
// Try to find a member that has a declared type. If so, that
|
|
735
|
+
// overrides any inferred types.
|
|
736
|
+
let member = (0, typeUtils_1.lookUpClassMember)(subtype, memberName, 64 /* MemberAccessFlags.DeclaredTypesOnly */);
|
|
737
|
+
if (!member) {
|
|
738
|
+
member = (0, typeUtils_1.lookUpClassMember)(subtype, memberName);
|
|
739
|
+
}
|
|
740
|
+
if (member) {
|
|
741
|
+
_addSymbolDeclInfo(member.symbol, decls, synthesizedTypes,
|
|
742
|
+
/* preferTypedDeclarations */ true);
|
|
743
|
+
}
|
|
744
|
+
}
|
|
745
|
+
});
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
else {
|
|
749
|
+
const fileInfo = nodeInfo.getFileInfo(node);
|
|
750
|
+
// Determine if this node is within a quoted type annotation.
|
|
751
|
+
const isWithinTypeAnnotation = ParseTreeUtils.isWithinTypeAnnotation(node, !(0, analyzerFileInfo_1.isAnnotationEvaluationPostponed)(nodeInfo.getFileInfo(node)), nodeInfo);
|
|
752
|
+
// Determine if this is part of a "type" statement.
|
|
753
|
+
const isWithinTypeAliasStatement = !!ParseTreeUtils.getParentNodeOfType(node, 77 /* ParseNodeType.TypeAlias */);
|
|
754
|
+
const allowForwardReferences = isWithinTypeAnnotation || isWithinTypeAliasStatement || fileInfo.isStubFile;
|
|
755
|
+
const symbolWithScope = lookUpSymbolRecursive(node, node.d.value, !allowForwardReferences, isWithinTypeAnnotation);
|
|
756
|
+
if (symbolWithScope) {
|
|
757
|
+
_addSymbolDeclInfo(symbolWithScope.symbol, decls, synthesizedTypes);
|
|
758
|
+
}
|
|
759
|
+
}
|
|
760
|
+
return { decls, synthesizedTypes };
|
|
761
|
+
}
|
|
762
|
+
function includesVariableTypeDecl(decls) {
|
|
763
|
+
return decls.some((decl) => {
|
|
764
|
+
if (decl.type === 1 /* DeclarationType.Variable */) {
|
|
765
|
+
// Exempt typing.pyi and typingExtensions.pyi, which use variables to
|
|
766
|
+
// define some special forms.
|
|
767
|
+
const fileInfo = nodeInfo.getFileInfo(decl.node);
|
|
768
|
+
if (!fileInfo.isTypingStubFile && !fileInfo.isTypingExtensionsStubFile) {
|
|
769
|
+
return true;
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
if (decl.type === 2 /* DeclarationType.Param */) {
|
|
773
|
+
return true;
|
|
774
|
+
}
|
|
775
|
+
return false;
|
|
776
|
+
});
|
|
777
|
+
}
|
|
778
|
+
function getDeclaredReturnType(node) {
|
|
779
|
+
const functionTypeInfo = getTypeOfFunction(node);
|
|
780
|
+
const returnType = functionTypeInfo?.functionType.shared.declaredReturnType;
|
|
781
|
+
if (!returnType) {
|
|
782
|
+
return undefined;
|
|
783
|
+
}
|
|
784
|
+
if (types_1.FunctionType.isGenerator(functionTypeInfo.functionType)) {
|
|
785
|
+
return (0, typeUtils_1.getDeclaredGeneratorReturnType)(functionTypeInfo.functionType);
|
|
786
|
+
}
|
|
787
|
+
return returnType;
|
|
788
|
+
}
|
|
789
|
+
function getCallbackProtocolType(objType, recursionCount = 0) {
|
|
790
|
+
if (!(0, types_1.isClassInstance)(objType) || !types_1.ClassType.isProtocolClass(objType)) {
|
|
791
|
+
return undefined;
|
|
792
|
+
}
|
|
793
|
+
// Make sure that the protocol class doesn't define any fields that
|
|
794
|
+
// a normal function wouldn't be compatible with.
|
|
795
|
+
for (const mroClass of objType.shared.mro) {
|
|
796
|
+
if ((0, types_1.isClass)(mroClass) && types_1.ClassType.isProtocolClass(mroClass)) {
|
|
797
|
+
for (const field of types_1.ClassType.getSymbolTable(mroClass)) {
|
|
798
|
+
const fieldName = field[0];
|
|
799
|
+
const fieldSymbol = field[1];
|
|
800
|
+
// We're expecting a __call__ method. We will also ignore a
|
|
801
|
+
// __slots__ definition, which is (by convention) ignored for
|
|
802
|
+
// protocol matching.
|
|
803
|
+
if (fieldName === '__call__' || fieldName === '__slots__') {
|
|
804
|
+
continue;
|
|
805
|
+
}
|
|
806
|
+
if (fieldSymbol.isIgnoredForProtocolMatch()) {
|
|
807
|
+
continue;
|
|
808
|
+
}
|
|
809
|
+
let fieldIsPartOfFunction = false;
|
|
810
|
+
if (context.prefetched?.functionClass && (0, types_1.isClass)(context.prefetched.functionClass)) {
|
|
811
|
+
if (types_1.ClassType.getSymbolTable(context.prefetched.functionClass).has(field[0])) {
|
|
812
|
+
fieldIsPartOfFunction = true;
|
|
813
|
+
}
|
|
814
|
+
}
|
|
815
|
+
if (!fieldIsPartOfFunction) {
|
|
816
|
+
return undefined;
|
|
817
|
+
}
|
|
818
|
+
}
|
|
819
|
+
}
|
|
820
|
+
}
|
|
821
|
+
const callType = getBoundMagicMethod(objType, '__call__',
|
|
822
|
+
/* selfType */ undefined,
|
|
823
|
+
/* errorNode */ undefined,
|
|
824
|
+
/* diag */ undefined, recursionCount);
|
|
825
|
+
if (!callType) {
|
|
826
|
+
return undefined;
|
|
827
|
+
}
|
|
828
|
+
return (0, typeUtils_1.makeFunctionTypeVarsBound)(callType);
|
|
829
|
+
}
|
|
830
|
+
function getAbstractSymbols(classType) {
|
|
831
|
+
const symbolTable = new Map();
|
|
832
|
+
types_1.ClassType.getReverseMro(classType).forEach((mroClass) => {
|
|
833
|
+
if ((0, types_1.isInstantiableClass)(mroClass)) {
|
|
834
|
+
// See if this class is introducing a new abstract symbol that has not been
|
|
835
|
+
// introduced previously or if it is overriding an abstract symbol with
|
|
836
|
+
// a non-abstract one.
|
|
837
|
+
types_1.ClassType.getSymbolTable(mroClass).forEach((symbol, symbolName) => {
|
|
838
|
+
const abstractSymbolInfo = getAbstractSymbolInfo(mroClass, symbolName);
|
|
839
|
+
if (abstractSymbolInfo) {
|
|
840
|
+
symbolTable.set(symbolName, abstractSymbolInfo);
|
|
841
|
+
}
|
|
842
|
+
else {
|
|
843
|
+
symbolTable.delete(symbolName);
|
|
844
|
+
}
|
|
845
|
+
});
|
|
846
|
+
}
|
|
847
|
+
});
|
|
848
|
+
// Create a final list of symbols that are abstract.
|
|
849
|
+
const symbolList = [];
|
|
850
|
+
symbolTable.forEach((method) => {
|
|
851
|
+
symbolList.push(method);
|
|
852
|
+
});
|
|
853
|
+
return symbolList;
|
|
854
|
+
}
|
|
855
|
+
function bindFunctionToClassOrObject(baseType, memberType, memberClass, treatConstructorAsClassMethod = false, selfType, diag, recursionCount = 0) {
|
|
856
|
+
return (0, typeUtils_1.mapSignatures)(memberType, (functionType) => {
|
|
857
|
+
// If the caller specified no base type, always strip the
|
|
858
|
+
// first parameter. This is used in cases like constructors.
|
|
859
|
+
if (!baseType) {
|
|
860
|
+
return types_1.FunctionType.clone(functionType, /* stripFirstParam */ true);
|
|
861
|
+
}
|
|
862
|
+
// If the first parameter was already stripped, it has already been
|
|
863
|
+
// bound. Don't attempt to rebind.
|
|
864
|
+
if (functionType.priv.strippedFirstParamType) {
|
|
865
|
+
return functionType;
|
|
866
|
+
}
|
|
867
|
+
if (types_1.FunctionType.isInstanceMethod(functionType) && !treatConstructorAsClassMethod) {
|
|
868
|
+
// If the baseType is a metaclass, don't specialize the function.
|
|
869
|
+
if ((0, typeUtils_1.isInstantiableMetaclass)(baseType)) {
|
|
870
|
+
return functionType;
|
|
871
|
+
}
|
|
872
|
+
const baseObj = (0, types_1.isClassInstance)(baseType)
|
|
873
|
+
? baseType
|
|
874
|
+
: types_1.ClassType.cloneAsInstance((0, typeUtils_1.specializeWithDefaultTypeArgs)(baseType));
|
|
875
|
+
let stripFirstParam = false;
|
|
876
|
+
if ((0, types_1.isClassInstance)(baseType)) {
|
|
877
|
+
stripFirstParam = true;
|
|
878
|
+
}
|
|
879
|
+
else if (memberClass && (0, typeUtils_1.isInstantiableMetaclass)(memberClass)) {
|
|
880
|
+
stripFirstParam = true;
|
|
881
|
+
}
|
|
882
|
+
return partiallySpecializeBoundMethod(baseType, functionType, diag, recursionCount, selfType ?? baseObj, stripFirstParam);
|
|
883
|
+
}
|
|
884
|
+
if (types_1.FunctionType.isClassMethod(functionType) || treatConstructorAsClassMethod) {
|
|
885
|
+
const baseClass = (0, types_1.isInstantiableClass)(baseType) ? baseType : types_1.ClassType.cloneAsInstantiable(baseType);
|
|
886
|
+
const clsType = selfType ? (0, typeUtils_1.convertToInstantiable)(selfType) : undefined;
|
|
887
|
+
return partiallySpecializeBoundMethod(baseClass, functionType, diag, recursionCount, clsType ?? baseClass,
|
|
888
|
+
/* stripFirstParam */ true);
|
|
889
|
+
}
|
|
890
|
+
if (types_1.FunctionType.isStaticMethod(functionType)) {
|
|
891
|
+
const baseClass = (0, types_1.isInstantiableClass)(baseType) ? baseType : types_1.ClassType.cloneAsInstantiable(baseType);
|
|
892
|
+
return partiallySpecializeBoundMethod(baseClass, functionType, diag, recursionCount,
|
|
893
|
+
/* firstParamType */ undefined,
|
|
894
|
+
/* stripFirstParam */ false);
|
|
895
|
+
}
|
|
896
|
+
return functionType;
|
|
897
|
+
});
|
|
898
|
+
}
|
|
899
|
+
function isExplicitTypeAliasDeclaration(decl) {
|
|
900
|
+
if (decl.type !== 1 /* DeclarationType.Variable */ || !decl.typeAnnotationNode) {
|
|
901
|
+
return false;
|
|
902
|
+
}
|
|
903
|
+
if (decl.typeAnnotationNode.nodeType !== 38 /* ParseNodeType.Name */ &&
|
|
904
|
+
decl.typeAnnotationNode.nodeType !== 35 /* ParseNodeType.MemberAccess */ &&
|
|
905
|
+
decl.typeAnnotationNode.nodeType !== 48 /* ParseNodeType.StringList */) {
|
|
906
|
+
return false;
|
|
907
|
+
}
|
|
908
|
+
const type = getTypeOfAnnotation(decl.typeAnnotationNode, { varTypeAnnotation: true, allowClassVar: true });
|
|
909
|
+
return (0, types_1.isClassInstance)(type) && types_1.ClassType.isBuiltIn(type, 'TypeAlias');
|
|
910
|
+
}
|
|
911
|
+
function isPossibleTypeAliasDeclaration(decl) {
|
|
912
|
+
if (decl.type !== 1 /* DeclarationType.Variable */ || !decl.typeAliasName || decl.typeAnnotationNode) {
|
|
913
|
+
return false;
|
|
914
|
+
}
|
|
915
|
+
if (decl.node.parent?.nodeType !== 3 /* ParseNodeType.Assignment */) {
|
|
916
|
+
return false;
|
|
917
|
+
}
|
|
918
|
+
// Perform a sanity check on the RHS expression. Some expression
|
|
919
|
+
// forms should never be considered legitimate for type aliases.
|
|
920
|
+
return isLegalTypeAliasExpressionForm(decl.node.parent.d.rightExpr, /* allowStrLiteral */ false);
|
|
921
|
+
}
|
|
922
|
+
function isLegalImplicitTypeAliasType(type) {
|
|
923
|
+
// We explicitly exclude "..." and "Unknown".
|
|
924
|
+
if ((0, typeUtils_1.isEllipsisType)(type)) {
|
|
925
|
+
return false;
|
|
926
|
+
}
|
|
927
|
+
if ((0, types_1.isUnknown)(type)) {
|
|
928
|
+
// If this is a union type, we'll assume that it was meant as a type
|
|
929
|
+
// alias even though all of the union subtypes are Unknown.
|
|
930
|
+
if (type.props?.specialForm && types_1.ClassType.isBuiltIn(type.props.specialForm, 'UnionType')) {
|
|
931
|
+
return true;
|
|
932
|
+
}
|
|
933
|
+
return false;
|
|
934
|
+
}
|
|
935
|
+
// Look at the subtypes within the union. If any of them are not
|
|
936
|
+
// instantiable (other than "None" which is special-cased), it is
|
|
937
|
+
// not a legal type alias type.
|
|
938
|
+
let isLegal = true;
|
|
939
|
+
(0, typeUtils_1.doForEachSubtype)(type, (subtype) => {
|
|
940
|
+
if (!types_1.TypeBase.isInstantiable(subtype) && !(0, typeUtils_1.isNoneInstance)(subtype)) {
|
|
941
|
+
isLegal = false;
|
|
942
|
+
}
|
|
943
|
+
});
|
|
944
|
+
return isLegal;
|
|
945
|
+
}
|
|
946
|
+
function isClassWithAsymmetricAttributeAccessor(classType) {
|
|
947
|
+
// If the value has already been cached in this type, return the cached value.
|
|
948
|
+
if (classType.priv.isAsymmetricAttributeAccessor !== undefined) {
|
|
949
|
+
return classType.priv.isAsymmetricAttributeAccessor;
|
|
950
|
+
}
|
|
951
|
+
let isAsymmetric = false;
|
|
952
|
+
const getterSymbolResult = (0, typeUtils_1.lookUpClassMember)(classType, '__getattr__', 2 /* MemberAccessFlags.SkipBaseClasses */);
|
|
953
|
+
const setterSymbolResult = (0, typeUtils_1.lookUpClassMember)(classType, '__setattr__', 2 /* MemberAccessFlags.SkipBaseClasses */);
|
|
954
|
+
if (!getterSymbolResult || !setterSymbolResult) {
|
|
955
|
+
isAsymmetric = false;
|
|
956
|
+
}
|
|
957
|
+
else {
|
|
958
|
+
const getterType = getEffectiveTypeOfSymbol(getterSymbolResult.symbol);
|
|
959
|
+
const setterType = getEffectiveTypeOfSymbol(setterSymbolResult.symbol);
|
|
960
|
+
// If either the setter or getter is an overload (or some other non-function type),
|
|
961
|
+
// conservatively assume that it's not asymmetric.
|
|
962
|
+
if ((0, types_1.isFunction)(getterType) && (0, types_1.isFunction)(setterType)) {
|
|
963
|
+
// If there's no declared return type on the getter, assume it's symmetric.
|
|
964
|
+
if (setterType.shared.parameters.length >= 3 && getterType.shared.declaredReturnType) {
|
|
965
|
+
const setterValueType = types_1.FunctionType.getParamType(setterType, 2);
|
|
966
|
+
const getterReturnType = types_1.FunctionType.getEffectiveReturnType(getterType) ?? types_1.UnknownType.create();
|
|
967
|
+
if (!(0, types_1.isTypeSame)(setterValueType, getterReturnType)) {
|
|
968
|
+
isAsymmetric = true;
|
|
969
|
+
}
|
|
970
|
+
}
|
|
971
|
+
}
|
|
972
|
+
}
|
|
973
|
+
// Cache the value for next time.
|
|
974
|
+
classType.priv.isAsymmetricAttributeAccessor = isAsymmetric;
|
|
975
|
+
return isAsymmetric;
|
|
976
|
+
}
|
|
977
|
+
return {
|
|
978
|
+
pushSymbolResolution,
|
|
979
|
+
popSymbolResolution,
|
|
980
|
+
setSymbolResolutionPartialType,
|
|
981
|
+
getSymbolResolutionPartialType,
|
|
982
|
+
isDeclaredTypeAlias,
|
|
983
|
+
validateSymbolIsTypeExpression,
|
|
984
|
+
bindMethodForMemberAccess,
|
|
985
|
+
isAsymmetricDescriptorClass,
|
|
986
|
+
applyAttributeAccessOverride,
|
|
987
|
+
synthesizeTypeAliasPlaceholder,
|
|
988
|
+
getAliasedSymbolTypeForName,
|
|
989
|
+
lookUpSymbolRecursive,
|
|
990
|
+
getDeclInfoForStringNode,
|
|
991
|
+
getDeclInfoForNameNode,
|
|
992
|
+
includesVariableTypeDecl,
|
|
993
|
+
getDeclaredReturnType,
|
|
994
|
+
getCallbackProtocolType,
|
|
995
|
+
getAbstractSymbols,
|
|
996
|
+
bindFunctionToClassOrObject,
|
|
997
|
+
isExplicitTypeAliasDeclaration,
|
|
998
|
+
isPossibleTypeAliasDeclaration,
|
|
999
|
+
isLegalImplicitTypeAliasType,
|
|
1000
|
+
getTypeOfMember,
|
|
1001
|
+
getTypeOfMemberInternal,
|
|
1002
|
+
getIndexOfSymbolResolution,
|
|
1003
|
+
getDeclarationFromKeywordParam,
|
|
1004
|
+
getAliasFromImport,
|
|
1005
|
+
};
|
|
1006
|
+
}
|
|
1007
|
+
//# sourceMappingURL=memberResolution.js.map
|