mirror of
https://github.com/microsoft/pyright.git
synced 2024-10-06 12:57:14 +03:00
Modified parser data structures to make parse nodes monomorphic and improve performance. (#8416)
This commit is contained in:
parent
5ac7f49a3f
commit
210bb144d7
@ -81,109 +81,135 @@ export type ScopedNode = ModuleNode | ClassNode | FunctionNode | LambdaNode | Co
|
||||
// Cleans out all fields that are added by the analyzer phases
|
||||
// (after the post-parse walker).
|
||||
export function cleanNodeAnalysisInfo(node: ParseNode) {
|
||||
const analyzerNode = node as AnalyzerNodeInfo;
|
||||
delete analyzerNode.scope;
|
||||
delete analyzerNode.declaration;
|
||||
delete analyzerNode.flowNode;
|
||||
delete analyzerNode.afterFlowNode;
|
||||
delete analyzerNode.fileInfo;
|
||||
delete analyzerNode.codeFlowExpressions;
|
||||
delete analyzerNode.codeFlowComplexity;
|
||||
delete analyzerNode.dunderAllInfo;
|
||||
delete analyzerNode.typeParameterSymbol;
|
||||
const info = getAnalyzerInfo(node);
|
||||
if (info?.scope) {
|
||||
info.scope = undefined;
|
||||
}
|
||||
|
||||
if (info?.declaration) {
|
||||
info.declaration = undefined;
|
||||
}
|
||||
|
||||
if (info?.flowNode) {
|
||||
info.flowNode = undefined;
|
||||
}
|
||||
|
||||
if (info?.afterFlowNode) {
|
||||
info.afterFlowNode = undefined;
|
||||
}
|
||||
|
||||
if (info?.fileInfo) {
|
||||
info.fileInfo = undefined;
|
||||
}
|
||||
|
||||
if (info?.codeFlowExpressions) {
|
||||
info.codeFlowExpressions = undefined;
|
||||
}
|
||||
|
||||
if (info?.codeFlowComplexity) {
|
||||
info.codeFlowComplexity = undefined;
|
||||
}
|
||||
|
||||
if (info?.dunderAllInfo) {
|
||||
info.dunderAllInfo = undefined;
|
||||
}
|
||||
|
||||
if (info?.typeParameterSymbol) {
|
||||
info.typeParameterSymbol = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
export function getImportInfo(node: ParseNode): ImportResult | undefined {
|
||||
const analyzerNode = node as AnalyzerNodeInfo;
|
||||
return analyzerNode.importInfo;
|
||||
const info = getAnalyzerInfo(node);
|
||||
return info?.importInfo;
|
||||
}
|
||||
|
||||
export function setImportInfo(node: ParseNode, importInfo: ImportResult) {
|
||||
const analyzerNode = node as AnalyzerNodeInfo;
|
||||
analyzerNode.importInfo = importInfo;
|
||||
const info = getAnalyzerInfoForWrite(node);
|
||||
info.importInfo = importInfo;
|
||||
}
|
||||
|
||||
export function getScope(node: ParseNode): Scope | undefined {
|
||||
const analyzerNode = node as AnalyzerNodeInfo;
|
||||
return analyzerNode.scope;
|
||||
const info = getAnalyzerInfo(node);
|
||||
return info?.scope;
|
||||
}
|
||||
|
||||
export function setScope(node: ParseNode, scope: Scope) {
|
||||
const analyzerNode = node as AnalyzerNodeInfo;
|
||||
analyzerNode.scope = scope;
|
||||
const info = getAnalyzerInfoForWrite(node);
|
||||
info.scope = scope;
|
||||
}
|
||||
|
||||
export function getDeclaration(node: ParseNode): Declaration | undefined {
|
||||
const analyzerNode = node as AnalyzerNodeInfo;
|
||||
return analyzerNode.declaration;
|
||||
const info = getAnalyzerInfo(node);
|
||||
return info?.declaration;
|
||||
}
|
||||
|
||||
export function setDeclaration(node: ParseNode, decl: Declaration) {
|
||||
const analyzerNode = node as AnalyzerNodeInfo;
|
||||
analyzerNode.declaration = decl;
|
||||
const info = getAnalyzerInfoForWrite(node);
|
||||
info.declaration = decl;
|
||||
}
|
||||
|
||||
export function getFlowNode(node: ParseNode): FlowNode | undefined {
|
||||
const analyzerNode = node as AnalyzerNodeInfo;
|
||||
return analyzerNode.flowNode;
|
||||
const info = getAnalyzerInfo(node);
|
||||
return info?.flowNode;
|
||||
}
|
||||
|
||||
export function setFlowNode(node: ParseNode, flowNode: FlowNode) {
|
||||
const analyzerNode = node as AnalyzerNodeInfo;
|
||||
analyzerNode.flowNode = flowNode;
|
||||
const info = getAnalyzerInfoForWrite(node);
|
||||
info.flowNode = flowNode;
|
||||
}
|
||||
|
||||
export function getAfterFlowNode(node: ParseNode): FlowNode | undefined {
|
||||
const analyzerNode = node as AnalyzerNodeInfo;
|
||||
return analyzerNode.afterFlowNode;
|
||||
const info = getAnalyzerInfo(node);
|
||||
return info?.afterFlowNode;
|
||||
}
|
||||
|
||||
export function setAfterFlowNode(node: ParseNode, flowNode: FlowNode) {
|
||||
const analyzerNode = node as AnalyzerNodeInfo;
|
||||
analyzerNode.afterFlowNode = flowNode;
|
||||
const info = getAnalyzerInfoForWrite(node);
|
||||
info.afterFlowNode = flowNode;
|
||||
}
|
||||
|
||||
export function getFileInfo(node: ParseNode): AnalyzerFileInfo {
|
||||
while (node.nodeType !== ParseNodeType.Module) {
|
||||
node = node.parent!;
|
||||
}
|
||||
const analyzerNode = node as AnalyzerNodeInfo;
|
||||
return analyzerNode.fileInfo!;
|
||||
const info = getAnalyzerInfo(node);
|
||||
return info!.fileInfo!;
|
||||
}
|
||||
|
||||
export function setFileInfo(node: ModuleNode, fileInfo: AnalyzerFileInfo) {
|
||||
const analyzerNode = node as AnalyzerNodeInfo;
|
||||
analyzerNode.fileInfo = fileInfo;
|
||||
const info = getAnalyzerInfoForWrite(node);
|
||||
info.fileInfo = fileInfo;
|
||||
}
|
||||
|
||||
export function getCodeFlowExpressions(node: ExecutionScopeNode): Set<string> | undefined {
|
||||
const analyzerNode = node as AnalyzerNodeInfo;
|
||||
return analyzerNode.codeFlowExpressions;
|
||||
const info = getAnalyzerInfo(node);
|
||||
return info?.codeFlowExpressions;
|
||||
}
|
||||
|
||||
export function setCodeFlowExpressions(node: ExecutionScopeNode, expressions: Set<string>) {
|
||||
const analyzerNode = node as AnalyzerNodeInfo;
|
||||
analyzerNode.codeFlowExpressions = expressions;
|
||||
const info = getAnalyzerInfoForWrite(node);
|
||||
info.codeFlowExpressions = expressions;
|
||||
}
|
||||
|
||||
export function getCodeFlowComplexity(node: ExecutionScopeNode) {
|
||||
const analyzerNode = node as AnalyzerNodeInfo;
|
||||
return analyzerNode.codeFlowComplexity ?? 0;
|
||||
const info = getAnalyzerInfo(node);
|
||||
return info?.codeFlowComplexity ?? 0;
|
||||
}
|
||||
|
||||
export function setCodeFlowComplexity(node: ExecutionScopeNode, complexity: number) {
|
||||
const analyzerNode = node as AnalyzerNodeInfo;
|
||||
analyzerNode.codeFlowComplexity = complexity;
|
||||
const info = getAnalyzerInfoForWrite(node);
|
||||
info.codeFlowComplexity = complexity;
|
||||
}
|
||||
|
||||
export function getDunderAllInfo(node: ModuleNode): DunderAllInfo | undefined {
|
||||
const analyzerNode = node as AnalyzerNodeInfo;
|
||||
return analyzerNode.dunderAllInfo;
|
||||
const info = getAnalyzerInfo(node);
|
||||
return info?.dunderAllInfo;
|
||||
}
|
||||
|
||||
export function setDunderAllInfo(node: ModuleNode, names: DunderAllInfo | undefined) {
|
||||
const analyzerNode = node as AnalyzerNodeInfo;
|
||||
analyzerNode.dunderAllInfo = names;
|
||||
const info = getAnalyzerInfoForWrite(node);
|
||||
info.dunderAllInfo = names;
|
||||
}
|
||||
|
||||
export function isCodeUnreachable(node: ParseNode): boolean {
|
||||
@ -201,3 +227,15 @@ export function isCodeUnreachable(node: ParseNode): boolean {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function getAnalyzerInfo(node: ParseNode): AnalyzerNodeInfo | undefined {
|
||||
return node.a as AnalyzerNodeInfo | undefined;
|
||||
}
|
||||
|
||||
function getAnalyzerInfoForWrite(node: ParseNode): AnalyzerNodeInfo {
|
||||
let info = node.a as AnalyzerNodeInfo | undefined;
|
||||
if (!info) {
|
||||
node.a = info = {};
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -65,6 +65,7 @@ import {
|
||||
} from './types';
|
||||
import {
|
||||
cleanIncompleteUnknown,
|
||||
convertArgumentNodeToFunctionArgument,
|
||||
derivesFromStdlibClass,
|
||||
doForEachSubtype,
|
||||
isIncompleteUnknown,
|
||||
@ -523,19 +524,20 @@ export function getCodeFlowEngine(
|
||||
// base type.
|
||||
if (
|
||||
targetNode.nodeType === ParseNodeType.Index &&
|
||||
isMatchingExpression(reference, targetNode.baseExpression)
|
||||
isMatchingExpression(reference, targetNode.d.baseExpression)
|
||||
) {
|
||||
if (
|
||||
targetNode.parent?.nodeType === ParseNodeType.Assignment &&
|
||||
targetNode.items.length === 1 &&
|
||||
!targetNode.trailingComma &&
|
||||
!targetNode.items[0].name &&
|
||||
targetNode.items[0].argumentCategory === ArgumentCategory.Simple &&
|
||||
targetNode.items[0].valueExpression.nodeType === ParseNodeType.StringList &&
|
||||
targetNode.items[0].valueExpression.strings.length === 1 &&
|
||||
targetNode.items[0].valueExpression.strings[0].nodeType === ParseNodeType.String
|
||||
targetNode.d.items.length === 1 &&
|
||||
!targetNode.d.trailingComma &&
|
||||
!targetNode.d.items[0].d.name &&
|
||||
targetNode.d.items[0].d.argumentCategory === ArgumentCategory.Simple &&
|
||||
targetNode.d.items[0].d.valueExpression.nodeType === ParseNodeType.StringList &&
|
||||
targetNode.d.items[0].d.valueExpression.d.strings.length === 1 &&
|
||||
targetNode.d.items[0].d.valueExpression.d.strings[0].nodeType ===
|
||||
ParseNodeType.String
|
||||
) {
|
||||
const keyValue = targetNode.items[0].valueExpression.strings[0].value;
|
||||
const keyValue = targetNode.d.items[0].d.valueExpression.d.strings[0].d.value;
|
||||
const narrowedResult = preventRecursion(assignmentFlowNode, () => {
|
||||
const flowTypeResult = getTypeFromFlowNode(assignmentFlowNode.antecedent);
|
||||
|
||||
@ -693,7 +695,7 @@ export function getCodeFlowEngine(
|
||||
// too expensive.
|
||||
const symbolWithScope = evaluator.lookUpSymbolRecursive(
|
||||
conditionalFlowNode.reference,
|
||||
conditionalFlowNode.reference.value,
|
||||
conditionalFlowNode.reference.d.value,
|
||||
/* honorCodeFlow */ false
|
||||
);
|
||||
|
||||
@ -862,7 +864,7 @@ export function getCodeFlowEngine(
|
||||
if (curFlowNode.flags & FlowFlags.WildcardImport) {
|
||||
const wildcardImportFlowNode = curFlowNode as FlowWildcardImport;
|
||||
if (reference && reference.nodeType === ParseNodeType.Name) {
|
||||
const nameValue = reference.value;
|
||||
const nameValue = reference.d.value;
|
||||
if (wildcardImportFlowNode.names.some((name) => name === nameValue)) {
|
||||
return preventRecursion(curFlowNode, () => {
|
||||
const type = getTypeFromWildcardImport(wildcardImportFlowNode, nameValue);
|
||||
@ -1284,7 +1286,7 @@ export function getCodeFlowEngine(
|
||||
// too expensive.
|
||||
const symbolWithScope = evaluator.lookUpSymbolRecursive(
|
||||
conditionalFlowNode.reference,
|
||||
conditionalFlowNode.reference.value,
|
||||
conditionalFlowNode.reference.d.value,
|
||||
/* honorCodeFlow */ false
|
||||
);
|
||||
|
||||
@ -1474,17 +1476,17 @@ export function getCodeFlowEngine(
|
||||
).type;
|
||||
|
||||
if (isCompatibleWithConstrainedTypeVar(subjectType, typeVar)) {
|
||||
const patternNode = narrowForPatternFlowNode.statement.pattern;
|
||||
const patternNode = narrowForPatternFlowNode.statement.d.pattern;
|
||||
|
||||
if (
|
||||
patternNode.nodeType === ParseNodeType.PatternAs &&
|
||||
patternNode.orPatterns.length === 1 &&
|
||||
patternNode.orPatterns[0].nodeType === ParseNodeType.PatternClass
|
||||
patternNode.d.orPatterns.length === 1 &&
|
||||
patternNode.d.orPatterns[0].nodeType === ParseNodeType.PatternClass
|
||||
) {
|
||||
const classPatternNode = patternNode.orPatterns[0];
|
||||
const classPatternNode = patternNode.d.orPatterns[0];
|
||||
|
||||
const classType = evaluator.getTypeOfExpression(
|
||||
classPatternNode.className,
|
||||
classPatternNode.d.className,
|
||||
EvalFlags.CallBaseDefaults
|
||||
).type;
|
||||
|
||||
@ -1514,11 +1516,11 @@ export function getCodeFlowEngine(
|
||||
|
||||
if (
|
||||
testExpression.nodeType === ParseNodeType.Call &&
|
||||
testExpression.leftExpression.nodeType === ParseNodeType.Name &&
|
||||
testExpression.leftExpression.value === 'isinstance' &&
|
||||
testExpression.arguments.length === 2
|
||||
testExpression.d.leftExpression.nodeType === ParseNodeType.Name &&
|
||||
testExpression.d.leftExpression.d.value === 'isinstance' &&
|
||||
testExpression.d.arguments.length === 2
|
||||
) {
|
||||
const arg0Expr = testExpression.arguments[0].valueExpression;
|
||||
const arg0Expr = testExpression.d.arguments[0].d.valueExpression;
|
||||
|
||||
const arg0Type = evaluator.getTypeOfExpression(arg0Expr).type;
|
||||
|
||||
@ -1531,7 +1533,7 @@ export function getCodeFlowEngine(
|
||||
);
|
||||
visitedFlowNodeMap.delete(curFlowNode.id);
|
||||
|
||||
const arg1Expr = testExpression.arguments[1].valueExpression;
|
||||
const arg1Expr = testExpression.d.arguments[1].d.valueExpression;
|
||||
const arg1Type = evaluator.getTypeOfExpression(
|
||||
arg1Expr,
|
||||
EvalFlags.AllowMissingTypeArgs |
|
||||
@ -1645,7 +1647,7 @@ export function getCodeFlowEngine(
|
||||
|
||||
// Don't attempt to evaluate a lambda call. We need to evaluate these in the
|
||||
// context of its arguments.
|
||||
if (node.leftExpression.nodeType === ParseNodeType.Lambda) {
|
||||
if (node.d.leftExpression.nodeType === ParseNodeType.Lambda) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1659,7 +1661,7 @@ export function getCodeFlowEngine(
|
||||
let subtypeCount = 0;
|
||||
|
||||
// Evaluate the call base type.
|
||||
const callTypeResult = evaluator.getTypeOfExpression(node.leftExpression, EvalFlags.CallBaseDefaults);
|
||||
const callTypeResult = evaluator.getTypeOfExpression(node.d.leftExpression, EvalFlags.CallBaseDefaults);
|
||||
const callType = callTypeResult.type;
|
||||
|
||||
doForEachSubtype(callType, (callSubtype) => {
|
||||
@ -1716,7 +1718,7 @@ export function getCodeFlowEngine(
|
||||
// the applicable overload returns a NoReturn.
|
||||
const callResult = evaluator.validateOverloadedFunctionArguments(
|
||||
node,
|
||||
node.arguments,
|
||||
node.d.arguments.map((arg) => convertArgumentNodeToFunctionArgument(arg)),
|
||||
{ type: callSubtype, isIncomplete: callTypeResult.isIncomplete },
|
||||
/* typeVarContext */ undefined,
|
||||
/* skipUnknownArgCheck */ false,
|
||||
@ -1777,22 +1779,22 @@ export function getCodeFlowEngine(
|
||||
) {
|
||||
// Check specifically for a common idiom where the only statement
|
||||
// (other than a possible docstring) is a "raise NotImplementedError".
|
||||
const functionStatements = functionType.shared.declaration.node.suite.statements;
|
||||
const functionStatements = functionType.shared.declaration.node.d.suite.d.statements;
|
||||
|
||||
let foundRaiseNotImplemented = false;
|
||||
for (const statement of functionStatements) {
|
||||
if (statement.nodeType !== ParseNodeType.StatementList || statement.statements.length !== 1) {
|
||||
if (statement.nodeType !== ParseNodeType.StatementList || statement.d.statements.length !== 1) {
|
||||
break;
|
||||
}
|
||||
|
||||
const simpleStatement = statement.statements[0];
|
||||
const simpleStatement = statement.d.statements[0];
|
||||
if (simpleStatement.nodeType === ParseNodeType.StringList) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (simpleStatement.nodeType === ParseNodeType.Raise && simpleStatement.typeExpression) {
|
||||
if (simpleStatement.nodeType === ParseNodeType.Raise && simpleStatement.d.typeExpression) {
|
||||
// Check for a raising about 'NotImplementedError' or a subtype thereof.
|
||||
const exceptionType = evaluator.getType(simpleStatement.typeExpression);
|
||||
const exceptionType = evaluator.getType(simpleStatement.d.typeExpression);
|
||||
|
||||
if (
|
||||
exceptionType &&
|
||||
@ -1889,9 +1891,9 @@ export function getCodeFlowEngine(
|
||||
}
|
||||
|
||||
function getTypeFromWildcardImport(flowNode: FlowWildcardImport, name: string): Type {
|
||||
const importInfo = getImportInfo(flowNode.node.module);
|
||||
const importInfo = getImportInfo(flowNode.node.d.module);
|
||||
assert(importInfo !== undefined && importInfo.isImportFound);
|
||||
assert(flowNode.node.isWildcardImport);
|
||||
assert(flowNode.node.d.isWildcardImport);
|
||||
|
||||
const symbolWithScope = evaluator.lookUpSymbolRecursive(flowNode.node, name, /* honorCodeFlow */ false);
|
||||
assert(symbolWithScope !== undefined);
|
||||
|
@ -173,40 +173,42 @@ export function isCodeFlowSupportedForReference(
|
||||
}
|
||||
|
||||
if (reference.nodeType === ParseNodeType.MemberAccess) {
|
||||
return isCodeFlowSupportedForReference(reference.leftExpression);
|
||||
return isCodeFlowSupportedForReference(reference.d.leftExpression);
|
||||
}
|
||||
|
||||
if (reference.nodeType === ParseNodeType.Index) {
|
||||
// Allow index expressions that have a single subscript that is a
|
||||
// literal integer or string value.
|
||||
if (
|
||||
reference.items.length !== 1 ||
|
||||
reference.trailingComma ||
|
||||
reference.items[0].name !== undefined ||
|
||||
reference.items[0].argumentCategory !== ArgumentCategory.Simple
|
||||
reference.d.items.length !== 1 ||
|
||||
reference.d.trailingComma ||
|
||||
reference.d.items[0].d.name !== undefined ||
|
||||
reference.d.items[0].d.argumentCategory !== ArgumentCategory.Simple
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const subscriptNode = reference.items[0].valueExpression;
|
||||
const subscriptNode = reference.d.items[0].d.valueExpression;
|
||||
const isIntegerIndex =
|
||||
subscriptNode.nodeType === ParseNodeType.Number && !subscriptNode.isImaginary && subscriptNode.isInteger;
|
||||
subscriptNode.nodeType === ParseNodeType.Number &&
|
||||
!subscriptNode.d.isImaginary &&
|
||||
subscriptNode.d.isInteger;
|
||||
const isNegativeIntegerIndex =
|
||||
subscriptNode.nodeType === ParseNodeType.UnaryOperation &&
|
||||
subscriptNode.operator === OperatorType.Subtract &&
|
||||
subscriptNode.expression.nodeType === ParseNodeType.Number &&
|
||||
!subscriptNode.expression.isImaginary &&
|
||||
subscriptNode.expression.isInteger;
|
||||
subscriptNode.d.operator === OperatorType.Subtract &&
|
||||
subscriptNode.d.expression.nodeType === ParseNodeType.Number &&
|
||||
!subscriptNode.d.expression.d.isImaginary &&
|
||||
subscriptNode.d.expression.d.isInteger;
|
||||
const isStringIndex =
|
||||
subscriptNode.nodeType === ParseNodeType.StringList &&
|
||||
subscriptNode.strings.length === 1 &&
|
||||
subscriptNode.strings[0].nodeType === ParseNodeType.String;
|
||||
subscriptNode.d.strings.length === 1 &&
|
||||
subscriptNode.d.strings[0].nodeType === ParseNodeType.String;
|
||||
|
||||
if (!isIntegerIndex && !isNegativeIntegerIndex && !isStringIndex) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return isCodeFlowSupportedForReference(reference.baseExpression);
|
||||
return isCodeFlowSupportedForReference(reference.d.baseExpression);
|
||||
}
|
||||
|
||||
return false;
|
||||
@ -215,26 +217,26 @@ export function isCodeFlowSupportedForReference(
|
||||
export function createKeyForReference(reference: CodeFlowReferenceExpressionNode): string {
|
||||
let key;
|
||||
if (reference.nodeType === ParseNodeType.Name) {
|
||||
key = reference.value;
|
||||
key = reference.d.value;
|
||||
} else if (reference.nodeType === ParseNodeType.MemberAccess) {
|
||||
const leftKey = createKeyForReference(reference.leftExpression as CodeFlowReferenceExpressionNode);
|
||||
key = `${leftKey}.${reference.memberName.value}`;
|
||||
const leftKey = createKeyForReference(reference.d.leftExpression as CodeFlowReferenceExpressionNode);
|
||||
key = `${leftKey}.${reference.d.memberName.d.value}`;
|
||||
} else if (reference.nodeType === ParseNodeType.Index) {
|
||||
const leftKey = createKeyForReference(reference.baseExpression as CodeFlowReferenceExpressionNode);
|
||||
assert(reference.items.length === 1);
|
||||
const expr = reference.items[0].valueExpression;
|
||||
const leftKey = createKeyForReference(reference.d.baseExpression as CodeFlowReferenceExpressionNode);
|
||||
assert(reference.d.items.length === 1);
|
||||
const expr = reference.d.items[0].d.valueExpression;
|
||||
if (expr.nodeType === ParseNodeType.Number) {
|
||||
key = `${leftKey}[${(expr as NumberNode).value.toString()}]`;
|
||||
key = `${leftKey}[${(expr as NumberNode).d.value.toString()}]`;
|
||||
} else if (expr.nodeType === ParseNodeType.StringList) {
|
||||
const valExpr = expr;
|
||||
assert(valExpr.strings.length === 1 && valExpr.strings[0].nodeType === ParseNodeType.String);
|
||||
key = `${leftKey}["${(valExpr.strings[0] as StringNode).value}"]`;
|
||||
assert(valExpr.d.strings.length === 1 && valExpr.d.strings[0].nodeType === ParseNodeType.String);
|
||||
key = `${leftKey}["${(valExpr.d.strings[0] as StringNode).d.value}"]`;
|
||||
} else if (
|
||||
expr.nodeType === ParseNodeType.UnaryOperation &&
|
||||
expr.operator === OperatorType.Subtract &&
|
||||
expr.expression.nodeType === ParseNodeType.Number
|
||||
expr.d.operator === OperatorType.Subtract &&
|
||||
expr.d.expression.nodeType === ParseNodeType.Number
|
||||
) {
|
||||
key = `${leftKey}[-${(expr.expression as NumberNode).value.toString()}]`;
|
||||
key = `${leftKey}[-${(expr.d.expression as NumberNode).d.value.toString()}]`;
|
||||
} else {
|
||||
fail('createKeyForReference received unexpected index type');
|
||||
}
|
||||
@ -252,14 +254,14 @@ export function createKeysForReferenceSubexpressions(reference: CodeFlowReferenc
|
||||
|
||||
if (reference.nodeType === ParseNodeType.MemberAccess) {
|
||||
return [
|
||||
...createKeysForReferenceSubexpressions(reference.leftExpression as CodeFlowReferenceExpressionNode),
|
||||
...createKeysForReferenceSubexpressions(reference.d.leftExpression as CodeFlowReferenceExpressionNode),
|
||||
createKeyForReference(reference),
|
||||
];
|
||||
}
|
||||
|
||||
if (reference.nodeType === ParseNodeType.Index) {
|
||||
return [
|
||||
...createKeysForReferenceSubexpressions(reference.baseExpression as CodeFlowReferenceExpressionNode),
|
||||
...createKeysForReferenceSubexpressions(reference.d.baseExpression as CodeFlowReferenceExpressionNode),
|
||||
createKeyForReference(reference),
|
||||
];
|
||||
}
|
||||
|
@ -330,7 +330,7 @@ function applyPartialTransformToFunction(
|
||||
}
|
||||
} else {
|
||||
const matchingParam = paramListDetails.params.find(
|
||||
(paramInfo) => paramInfo.param.name === arg.name?.value && paramInfo.kind !== ParameterKind.Positional
|
||||
(paramInfo) => paramInfo.param.name === arg.name?.d.value && paramInfo.kind !== ParameterKind.Positional
|
||||
);
|
||||
|
||||
if (!matchingParam) {
|
||||
@ -339,7 +339,7 @@ function applyPartialTransformToFunction(
|
||||
if (errorNode) {
|
||||
evaluator.addDiagnostic(
|
||||
DiagnosticRule.reportCallIssue,
|
||||
LocMessage.paramNameMissing().format({ name: arg.name.value }),
|
||||
LocMessage.paramNameMissing().format({ name: arg.name.d.value }),
|
||||
arg.name
|
||||
);
|
||||
}
|
||||
@ -382,7 +382,7 @@ function applyPartialTransformToFunction(
|
||||
if (errorNode) {
|
||||
evaluator.addDiagnostic(
|
||||
DiagnosticRule.reportCallIssue,
|
||||
LocMessage.paramAlreadyAssigned().format({ name: arg.name.value }),
|
||||
LocMessage.paramAlreadyAssigned().format({ name: arg.name.d.value }),
|
||||
arg.name
|
||||
);
|
||||
}
|
||||
|
@ -61,6 +61,7 @@ import {
|
||||
applySolvedTypeVars,
|
||||
buildTypeVarContextFromSpecializedClass,
|
||||
computeMroLinearization,
|
||||
convertArgumentNodeToFunctionArgument,
|
||||
convertToInstance,
|
||||
doForEachSignature,
|
||||
getTypeVarScopeId,
|
||||
@ -199,14 +200,14 @@ export function synthesizeDataClassMethods(
|
||||
|
||||
if (statement.nodeType === ParseNodeType.Assignment) {
|
||||
if (
|
||||
statement.leftExpression.nodeType === ParseNodeType.TypeAnnotation &&
|
||||
statement.leftExpression.valueExpression.nodeType === ParseNodeType.Name
|
||||
statement.d.leftExpression.nodeType === ParseNodeType.TypeAnnotation &&
|
||||
statement.d.leftExpression.d.valueExpression.nodeType === ParseNodeType.Name
|
||||
) {
|
||||
variableNameNode = statement.leftExpression.valueExpression;
|
||||
variableNameNode = statement.d.leftExpression.d.valueExpression;
|
||||
const assignmentStatement = statement;
|
||||
variableTypeEvaluator = () =>
|
||||
evaluator.getTypeOfAnnotation(
|
||||
(assignmentStatement.leftExpression as TypeAnnotationNode).typeAnnotation,
|
||||
(assignmentStatement.d.leftExpression as TypeAnnotationNode).d.typeAnnotation,
|
||||
{
|
||||
isVariableAnnotation: true,
|
||||
allowFinal: true,
|
||||
@ -219,9 +220,9 @@ export function synthesizeDataClassMethods(
|
||||
|
||||
// If the RHS of the assignment is assigning a field instance where the
|
||||
// "init" parameter is set to false, do not include it in the init method.
|
||||
if (statement.rightExpression.nodeType === ParseNodeType.Call) {
|
||||
if (statement.d.rightExpression.nodeType === ParseNodeType.Call) {
|
||||
const callTypeResult = evaluator.getTypeOfExpression(
|
||||
statement.rightExpression.leftExpression,
|
||||
statement.d.rightExpression.d.leftExpression,
|
||||
EvalFlags.CallBaseDefaults
|
||||
);
|
||||
const callType = callTypeResult.type;
|
||||
@ -233,12 +234,14 @@ export function synthesizeDataClassMethods(
|
||||
classType.shared.dataClassBehaviors?.fieldDescriptorNames || []
|
||||
)
|
||||
) {
|
||||
const initArg = statement.rightExpression.arguments.find((arg) => arg.name?.value === 'init');
|
||||
if (initArg && initArg.valueExpression) {
|
||||
const initArg = statement.d.rightExpression.d.arguments.find(
|
||||
(arg) => arg.d.name?.d.value === 'init'
|
||||
);
|
||||
if (initArg && initArg.d.valueExpression) {
|
||||
const fileInfo = AnalyzerNodeInfo.getFileInfo(node);
|
||||
includeInInit =
|
||||
evaluateStaticBoolExpression(
|
||||
initArg.valueExpression,
|
||||
initArg.d.valueExpression,
|
||||
fileInfo.executionEnvironment,
|
||||
fileInfo.definedConstants
|
||||
) ?? includeInInit;
|
||||
@ -246,20 +249,20 @@ export function synthesizeDataClassMethods(
|
||||
includeInInit =
|
||||
getDefaultArgValueForFieldSpecifier(
|
||||
evaluator,
|
||||
statement.rightExpression,
|
||||
statement.d.rightExpression,
|
||||
callTypeResult,
|
||||
'init'
|
||||
) ?? includeInInit;
|
||||
}
|
||||
|
||||
const kwOnlyArg = statement.rightExpression.arguments.find(
|
||||
(arg) => arg.name?.value === 'kw_only'
|
||||
const kwOnlyArg = statement.d.rightExpression.d.arguments.find(
|
||||
(arg) => arg.d.name?.d.value === 'kw_only'
|
||||
);
|
||||
if (kwOnlyArg && kwOnlyArg.valueExpression) {
|
||||
if (kwOnlyArg && kwOnlyArg.d.valueExpression) {
|
||||
const fileInfo = AnalyzerNodeInfo.getFileInfo(node);
|
||||
isKeywordOnly =
|
||||
evaluateStaticBoolExpression(
|
||||
kwOnlyArg.valueExpression,
|
||||
kwOnlyArg.d.valueExpression,
|
||||
fileInfo.executionEnvironment,
|
||||
fileInfo.definedConstants
|
||||
) ?? isKeywordOnly;
|
||||
@ -267,24 +270,26 @@ export function synthesizeDataClassMethods(
|
||||
isKeywordOnly =
|
||||
getDefaultArgValueForFieldSpecifier(
|
||||
evaluator,
|
||||
statement.rightExpression,
|
||||
statement.d.rightExpression,
|
||||
callTypeResult,
|
||||
'kw_only'
|
||||
) ?? isKeywordOnly;
|
||||
}
|
||||
|
||||
const defaultArg = statement.rightExpression.arguments.find(
|
||||
const defaultArg = statement.d.rightExpression.d.arguments.find(
|
||||
(arg) =>
|
||||
arg.name?.value === 'default' ||
|
||||
arg.name?.value === 'default_factory' ||
|
||||
arg.name?.value === 'factory'
|
||||
arg.d.name?.d.value === 'default' ||
|
||||
arg.d.name?.d.value === 'default_factory' ||
|
||||
arg.d.name?.d.value === 'factory'
|
||||
);
|
||||
|
||||
hasDefaultValue = !!defaultArg;
|
||||
|
||||
const aliasArg = statement.rightExpression.arguments.find((arg) => arg.name?.value === 'alias');
|
||||
const aliasArg = statement.d.rightExpression.d.arguments.find(
|
||||
(arg) => arg.d.name?.d.value === 'alias'
|
||||
);
|
||||
if (aliasArg) {
|
||||
const valueType = evaluator.getTypeOfExpression(aliasArg.valueExpression).type;
|
||||
const valueType = evaluator.getTypeOfExpression(aliasArg.d.valueExpression).type;
|
||||
if (
|
||||
isClassInstance(valueType) &&
|
||||
ClassType.isBuiltIn(valueType, 'str') &&
|
||||
@ -294,10 +299,10 @@ export function synthesizeDataClassMethods(
|
||||
}
|
||||
}
|
||||
|
||||
const converterArg = statement.rightExpression.arguments.find(
|
||||
(arg) => arg.name?.value === 'converter'
|
||||
const converterArg = statement.d.rightExpression.d.arguments.find(
|
||||
(arg) => arg.d.name?.d.value === 'converter'
|
||||
);
|
||||
if (converterArg && converterArg.valueExpression) {
|
||||
if (converterArg && converterArg.d.valueExpression) {
|
||||
// Converter support is dependent on PEP 712, which has not yet been approved.
|
||||
if (AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.enableExperimentalFeatures) {
|
||||
converter = converterArg;
|
||||
@ -306,18 +311,18 @@ export function synthesizeDataClassMethods(
|
||||
}
|
||||
}
|
||||
} else if (statement.nodeType === ParseNodeType.TypeAnnotation) {
|
||||
if (statement.valueExpression.nodeType === ParseNodeType.Name) {
|
||||
variableNameNode = statement.valueExpression;
|
||||
if (statement.d.valueExpression.nodeType === ParseNodeType.Name) {
|
||||
variableNameNode = statement.d.valueExpression;
|
||||
const annotationStatement = statement;
|
||||
variableTypeEvaluator = () =>
|
||||
evaluator.getTypeOfAnnotation(annotationStatement.typeAnnotation, {
|
||||
evaluator.getTypeOfAnnotation(annotationStatement.d.typeAnnotation, {
|
||||
isVariableAnnotation: true,
|
||||
allowFinal: true,
|
||||
allowClassVar: true,
|
||||
});
|
||||
|
||||
// Is this a KW_ONLY separator introduced in Python 3.10?
|
||||
if (!isNamedTuple && statement.valueExpression.value === '_') {
|
||||
if (!isNamedTuple && statement.d.valueExpression.d.value === '_') {
|
||||
const annotatedType = variableTypeEvaluator();
|
||||
|
||||
if (isClassInstance(annotatedType) && ClassType.isBuiltIn(annotatedType, 'KW_ONLY')) {
|
||||
@ -330,7 +335,7 @@ export function synthesizeDataClassMethods(
|
||||
}
|
||||
|
||||
if (variableNameNode && variableTypeEvaluator) {
|
||||
const variableName = variableNameNode.value;
|
||||
const variableName = variableNameNode.d.value;
|
||||
|
||||
// Don't include class vars. PEP 557 indicates that they shouldn't
|
||||
// be considered data class entries.
|
||||
@ -446,9 +451,9 @@ export function synthesizeDataClassMethods(
|
||||
|
||||
// If the RHS of the assignment is assigning a field instance where the
|
||||
// "init" parameter is set to false, do not include it in the init method.
|
||||
if (statement.rightExpression.nodeType === ParseNodeType.Call) {
|
||||
if (statement.d.rightExpression.nodeType === ParseNodeType.Call) {
|
||||
const callType = evaluator.getTypeOfExpression(
|
||||
statement.rightExpression.leftExpression,
|
||||
statement.d.rightExpression.d.leftExpression,
|
||||
EvalFlags.CallBaseDefaults
|
||||
).type;
|
||||
|
||||
@ -461,7 +466,7 @@ export function synthesizeDataClassMethods(
|
||||
evaluator.addDiagnostic(
|
||||
DiagnosticRule.reportGeneralTypeIssues,
|
||||
LocMessage.dataClassFieldWithoutAnnotation(),
|
||||
statement.rightExpression
|
||||
statement.d.rightExpression
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -519,7 +524,7 @@ export function synthesizeDataClassMethods(
|
||||
|
||||
const effectiveName = entry.alias || entry.name;
|
||||
|
||||
if (!entry.alias && entry.nameNode && isPrivateName(entry.nameNode.value)) {
|
||||
if (!entry.alias && entry.nameNode && isPrivateName(entry.nameNode.d.value)) {
|
||||
evaluator.addDiagnostic(
|
||||
DiagnosticRule.reportGeneralTypeIssues,
|
||||
LocMessage.dataClassFieldWithPrivateName(),
|
||||
@ -712,7 +717,7 @@ function getDefaultArgValueForFieldSpecifier(
|
||||
callTarget = evaluator.getBestOverloadForArguments(
|
||||
callNode,
|
||||
{ type: callType, isIncomplete: callTypeResult.isIncomplete },
|
||||
callNode.arguments
|
||||
callNode.d.arguments.map((arg) => convertArgumentNodeToFunctionArgument(arg))
|
||||
);
|
||||
} else if (isInstantiableClass(callType)) {
|
||||
const initMethodResult = getBoundInitMethod(evaluator, callNode, callType);
|
||||
@ -723,7 +728,7 @@ function getDefaultArgValueForFieldSpecifier(
|
||||
callTarget = evaluator.getBestOverloadForArguments(
|
||||
callNode,
|
||||
{ type: initMethodResult.type },
|
||||
callNode.arguments
|
||||
callNode.d.arguments.map((arg) => convertArgumentNodeToFunctionArgument(arg))
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -765,7 +770,7 @@ function getConverterInputType(
|
||||
): Type {
|
||||
const converterType = getConverterAsFunction(
|
||||
evaluator,
|
||||
evaluator.getTypeOfExpression(converterNode.valueExpression).type
|
||||
evaluator.getTypeOfExpression(converterNode.d.valueExpression).type
|
||||
);
|
||||
|
||||
if (!converterType) {
|
||||
@ -1051,8 +1056,8 @@ export function validateDataClassTransformDecorator(
|
||||
const fileInfo = AnalyzerNodeInfo.getFileInfo(node);
|
||||
|
||||
// Parse the arguments to the call.
|
||||
node.arguments.forEach((arg) => {
|
||||
if (!arg.name || arg.argumentCategory !== ArgumentCategory.Simple) {
|
||||
node.d.arguments.forEach((arg) => {
|
||||
if (!arg.d.name || arg.d.argumentCategory !== ArgumentCategory.Simple) {
|
||||
evaluator.addDiagnostic(
|
||||
DiagnosticRule.reportCallIssue,
|
||||
LocMessage.dataClassTransformPositionalParam(),
|
||||
@ -1061,10 +1066,10 @@ export function validateDataClassTransformDecorator(
|
||||
return;
|
||||
}
|
||||
|
||||
switch (arg.name.value) {
|
||||
switch (arg.d.name.d.value) {
|
||||
case 'kw_only_default': {
|
||||
const value = evaluateStaticBoolExpression(
|
||||
arg.valueExpression,
|
||||
arg.d.valueExpression,
|
||||
fileInfo.executionEnvironment,
|
||||
fileInfo.definedConstants
|
||||
);
|
||||
@ -1072,7 +1077,7 @@ export function validateDataClassTransformDecorator(
|
||||
evaluator.addDiagnostic(
|
||||
DiagnosticRule.reportGeneralTypeIssues,
|
||||
LocMessage.dataClassTransformExpectedBoolLiteral(),
|
||||
arg.valueExpression
|
||||
arg.d.valueExpression
|
||||
);
|
||||
return;
|
||||
}
|
||||
@ -1083,7 +1088,7 @@ export function validateDataClassTransformDecorator(
|
||||
|
||||
case 'eq_default': {
|
||||
const value = evaluateStaticBoolExpression(
|
||||
arg.valueExpression,
|
||||
arg.d.valueExpression,
|
||||
fileInfo.executionEnvironment,
|
||||
fileInfo.definedConstants
|
||||
);
|
||||
@ -1091,7 +1096,7 @@ export function validateDataClassTransformDecorator(
|
||||
evaluator.addDiagnostic(
|
||||
DiagnosticRule.reportGeneralTypeIssues,
|
||||
LocMessage.dataClassTransformExpectedBoolLiteral(),
|
||||
arg.valueExpression
|
||||
arg.d.valueExpression
|
||||
);
|
||||
return;
|
||||
}
|
||||
@ -1102,7 +1107,7 @@ export function validateDataClassTransformDecorator(
|
||||
|
||||
case 'order_default': {
|
||||
const value = evaluateStaticBoolExpression(
|
||||
arg.valueExpression,
|
||||
arg.d.valueExpression,
|
||||
fileInfo.executionEnvironment,
|
||||
fileInfo.definedConstants
|
||||
);
|
||||
@ -1110,7 +1115,7 @@ export function validateDataClassTransformDecorator(
|
||||
evaluator.addDiagnostic(
|
||||
DiagnosticRule.reportGeneralTypeIssues,
|
||||
LocMessage.dataClassTransformExpectedBoolLiteral(),
|
||||
arg.valueExpression
|
||||
arg.d.valueExpression
|
||||
);
|
||||
return;
|
||||
}
|
||||
@ -1121,7 +1126,7 @@ export function validateDataClassTransformDecorator(
|
||||
|
||||
case 'frozen_default': {
|
||||
const value = evaluateStaticBoolExpression(
|
||||
arg.valueExpression,
|
||||
arg.d.valueExpression,
|
||||
fileInfo.executionEnvironment,
|
||||
fileInfo.definedConstants
|
||||
);
|
||||
@ -1129,7 +1134,7 @@ export function validateDataClassTransformDecorator(
|
||||
evaluator.addDiagnostic(
|
||||
DiagnosticRule.reportGeneralTypeIssues,
|
||||
LocMessage.dataClassTransformExpectedBoolLiteral(),
|
||||
arg.valueExpression
|
||||
arg.d.valueExpression
|
||||
);
|
||||
return;
|
||||
}
|
||||
@ -1149,7 +1154,7 @@ export function validateDataClassTransformDecorator(
|
||||
// form that supported this older parameter name.
|
||||
case 'field_descriptors':
|
||||
case 'field_specifiers': {
|
||||
const valueType = evaluator.getTypeOfExpression(arg.valueExpression).type;
|
||||
const valueType = evaluator.getTypeOfExpression(arg.d.valueExpression).type;
|
||||
if (
|
||||
!isClassInstance(valueType) ||
|
||||
!ClassType.isBuiltIn(valueType, 'tuple') ||
|
||||
@ -1166,7 +1171,7 @@ export function validateDataClassTransformDecorator(
|
||||
LocMessage.dataClassTransformFieldSpecifier().format({
|
||||
type: evaluator.printType(valueType),
|
||||
}),
|
||||
arg.valueExpression
|
||||
arg.d.valueExpression
|
||||
);
|
||||
return;
|
||||
}
|
||||
@ -1184,8 +1189,8 @@ export function validateDataClassTransformDecorator(
|
||||
default:
|
||||
evaluator.addDiagnostic(
|
||||
DiagnosticRule.reportGeneralTypeIssues,
|
||||
LocMessage.dataClassTransformUnknownArgument().format({ name: arg.name.value }),
|
||||
arg.valueExpression
|
||||
LocMessage.dataClassTransformUnknownArgument().format({ name: arg.d.name.d.value }),
|
||||
arg.d.valueExpression
|
||||
);
|
||||
break;
|
||||
}
|
||||
@ -1370,12 +1375,12 @@ export function applyDataClassClassBehaviorOverrides(
|
||||
evaluator,
|
||||
arg.name,
|
||||
classType,
|
||||
arg.name.value,
|
||||
arg.name.d.value,
|
||||
arg.valueExpression,
|
||||
behaviors
|
||||
);
|
||||
|
||||
if (arg.name.value === 'frozen') {
|
||||
if (arg.name.d.value === 'frozen') {
|
||||
sawFrozenArg = true;
|
||||
}
|
||||
}
|
||||
@ -1403,5 +1408,11 @@ export function applyDataClassDecorator(
|
||||
defaultBehaviors: DataClassBehaviors,
|
||||
callNode: CallNode | undefined
|
||||
) {
|
||||
applyDataClassClassBehaviorOverrides(evaluator, errorNode, classType, callNode?.arguments ?? [], defaultBehaviors);
|
||||
applyDataClassClassBehaviorOverrides(
|
||||
evaluator,
|
||||
errorNode,
|
||||
classType,
|
||||
(callNode?.d.arguments ?? []).map((arg) => convertArgumentNodeToFunctionArgument(arg)),
|
||||
defaultBehaviors
|
||||
);
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ export function hasTypeForDeclaration(declaration: Declaration): boolean {
|
||||
return true;
|
||||
|
||||
case DeclarationType.Parameter: {
|
||||
if (declaration.node.typeAnnotation || declaration.node.typeAnnotationComment) {
|
||||
if (declaration.node.d.typeAnnotation || declaration.node.d.typeAnnotationComment) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -41,16 +41,16 @@ export function hasTypeForDeclaration(declaration: Declaration): boolean {
|
||||
const parameterParent = declaration.node.parent;
|
||||
if (parameterParent?.nodeType === ParseNodeType.Function) {
|
||||
if (
|
||||
parameterParent.functionAnnotationComment &&
|
||||
!parameterParent.functionAnnotationComment.isParamListEllipsis
|
||||
parameterParent.d.functionAnnotationComment &&
|
||||
!parameterParent.d.functionAnnotationComment.d.isParamListEllipsis
|
||||
) {
|
||||
const paramAnnotations = parameterParent.functionAnnotationComment.paramTypeAnnotations;
|
||||
const paramAnnotations = parameterParent.d.functionAnnotationComment.d.paramTypeAnnotations;
|
||||
|
||||
// Handle the case where the annotation comment is missing an
|
||||
// annotation for the first parameter (self or cls).
|
||||
if (
|
||||
parameterParent.parameters.length > paramAnnotations.length &&
|
||||
declaration.node === parameterParent.parameters[0]
|
||||
parameterParent.d.parameters.length > paramAnnotations.length &&
|
||||
declaration.node === parameterParent.d.parameters[0]
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
@ -127,19 +127,19 @@ export function getNameFromDeclaration(declaration: Declaration) {
|
||||
case DeclarationType.Function:
|
||||
case DeclarationType.TypeParameter:
|
||||
case DeclarationType.TypeAlias:
|
||||
return declaration.node.name.value;
|
||||
return declaration.node.d.name.d.value;
|
||||
|
||||
case DeclarationType.Parameter:
|
||||
return declaration.node.name?.value;
|
||||
return declaration.node.d.name?.d.value;
|
||||
|
||||
case DeclarationType.Variable:
|
||||
return declaration.node.nodeType === ParseNodeType.Name ? declaration.node.value : undefined;
|
||||
return declaration.node.nodeType === ParseNodeType.Name ? declaration.node.d.value : undefined;
|
||||
|
||||
case DeclarationType.Intrinsic:
|
||||
case DeclarationType.SpecialBuiltInClass:
|
||||
return declaration.node.nodeType === ParseNodeType.TypeAnnotation &&
|
||||
declaration.node.valueExpression.nodeType === ParseNodeType.Name
|
||||
? declaration.node.valueExpression.value
|
||||
declaration.node.d.valueExpression.nodeType === ParseNodeType.Name
|
||||
? declaration.node.d.valueExpression.d.value
|
||||
: undefined;
|
||||
}
|
||||
|
||||
@ -150,11 +150,11 @@ export function getNameNodeForDeclaration(declaration: Declaration): NameNode |
|
||||
switch (declaration.type) {
|
||||
case DeclarationType.Alias:
|
||||
if (declaration.node.nodeType === ParseNodeType.ImportAs) {
|
||||
return declaration.node.alias ?? declaration.node.module.nameParts[0];
|
||||
return declaration.node.d.alias ?? declaration.node.d.module.d.nameParts[0];
|
||||
} else if (declaration.node.nodeType === ParseNodeType.ImportFromAs) {
|
||||
return declaration.node.alias ?? declaration.node.name;
|
||||
return declaration.node.d.alias ?? declaration.node.d.name;
|
||||
} else {
|
||||
return declaration.node.module.nameParts[0];
|
||||
return declaration.node.d.module.d.nameParts[0];
|
||||
}
|
||||
|
||||
case DeclarationType.Class:
|
||||
@ -162,7 +162,7 @@ export function getNameNodeForDeclaration(declaration: Declaration): NameNode |
|
||||
case DeclarationType.TypeParameter:
|
||||
case DeclarationType.Parameter:
|
||||
case DeclarationType.TypeAlias:
|
||||
return declaration.node.name;
|
||||
return declaration.node.d.name;
|
||||
|
||||
case DeclarationType.Variable:
|
||||
return declaration.node.nodeType === ParseNodeType.Name ? declaration.node : undefined;
|
||||
|
@ -72,26 +72,26 @@ export function getFunctionInfoFromDecorators(
|
||||
if (isInClass) {
|
||||
// The "__new__" magic method is not an instance method.
|
||||
// It acts as a static method instead.
|
||||
if (node.name.value === '__new__') {
|
||||
if (node.d.name.d.value === '__new__') {
|
||||
flags |= FunctionTypeFlags.ConstructorMethod;
|
||||
}
|
||||
|
||||
// Several magic methods are treated as class methods implicitly
|
||||
// by the runtime. Check for these here.
|
||||
const implicitClassMethods = ['__init_subclass__', '__class_getitem__'];
|
||||
if (implicitClassMethods.some((name) => node.name.value === name)) {
|
||||
if (implicitClassMethods.some((name) => node.d.name.d.value === name)) {
|
||||
flags |= FunctionTypeFlags.ClassMethod;
|
||||
}
|
||||
}
|
||||
|
||||
for (const decoratorNode of node.decorators) {
|
||||
for (const decoratorNode of node.d.decorators) {
|
||||
// Some stub files (e.g. builtins.pyi) rely on forward declarations of decorators.
|
||||
let evaluatorFlags = fileInfo.isStubFile ? EvalFlags.ForwardRefs : EvalFlags.None;
|
||||
if (decoratorNode.expression.nodeType !== ParseNodeType.Call) {
|
||||
if (decoratorNode.d.expression.nodeType !== ParseNodeType.Call) {
|
||||
evaluatorFlags |= EvalFlags.CallBaseDefaults;
|
||||
}
|
||||
|
||||
const decoratorTypeResult = evaluator.getTypeOfExpression(decoratorNode.expression, evaluatorFlags);
|
||||
const decoratorTypeResult = evaluator.getTypeOfExpression(decoratorNode.d.expression, evaluatorFlags);
|
||||
const decoratorType = decoratorTypeResult.type;
|
||||
|
||||
if (isFunction(decoratorType)) {
|
||||
@ -145,11 +145,11 @@ export function applyFunctionDecorator(
|
||||
|
||||
// Some stub files (e.g. builtins.pyi) rely on forward declarations of decorators.
|
||||
let evaluatorFlags = fileInfo.isStubFile ? EvalFlags.ForwardRefs : EvalFlags.None;
|
||||
if (decoratorNode.expression.nodeType !== ParseNodeType.Call) {
|
||||
if (decoratorNode.d.expression.nodeType !== ParseNodeType.Call) {
|
||||
evaluatorFlags |= EvalFlags.CallBaseDefaults;
|
||||
}
|
||||
|
||||
const decoratorTypeResult = evaluator.getTypeOfExpression(decoratorNode.expression, evaluatorFlags);
|
||||
const decoratorTypeResult = evaluator.getTypeOfExpression(decoratorNode.d.expression, evaluatorFlags);
|
||||
const decoratorType = decoratorTypeResult.type;
|
||||
|
||||
// Special-case the "overload" because it has no definition. Older versions of typeshed
|
||||
@ -165,9 +165,9 @@ export function applyFunctionDecorator(
|
||||
}
|
||||
}
|
||||
|
||||
if (decoratorNode.expression.nodeType === ParseNodeType.Call) {
|
||||
if (decoratorNode.d.expression.nodeType === ParseNodeType.Call) {
|
||||
const decoratorCallType = evaluator.getTypeOfExpression(
|
||||
decoratorNode.expression.leftExpression,
|
||||
decoratorNode.d.expression.d.leftExpression,
|
||||
evaluatorFlags | EvalFlags.CallBaseDefaults
|
||||
).type;
|
||||
|
||||
@ -178,7 +178,7 @@ export function applyFunctionDecorator(
|
||||
) {
|
||||
undecoratedType.shared.decoratorDataClassBehaviors = validateDataClassTransformDecorator(
|
||||
evaluator,
|
||||
decoratorNode.expression
|
||||
decoratorNode.d.expression
|
||||
);
|
||||
return inputFunctionType;
|
||||
}
|
||||
@ -199,14 +199,14 @@ export function applyFunctionDecorator(
|
||||
}
|
||||
|
||||
// Handle property setters and deleters.
|
||||
if (decoratorNode.expression.nodeType === ParseNodeType.MemberAccess) {
|
||||
if (decoratorNode.d.expression.nodeType === ParseNodeType.MemberAccess) {
|
||||
const baseType = evaluator.getTypeOfExpression(
|
||||
decoratorNode.expression.leftExpression,
|
||||
decoratorNode.d.expression.d.leftExpression,
|
||||
evaluatorFlags | EvalFlags.MemberAccessBaseDefaults
|
||||
).type;
|
||||
|
||||
if (isProperty(baseType)) {
|
||||
const memberName = decoratorNode.expression.memberName.value;
|
||||
const memberName = decoratorNode.d.expression.d.memberName.d.value;
|
||||
if (memberName === 'setter') {
|
||||
if (isFunction(inputFunctionType)) {
|
||||
validatePropertyMethod(evaluator, inputFunctionType, decoratorNode);
|
||||
@ -300,14 +300,14 @@ export function applyClassDecorator(
|
||||
): Type {
|
||||
const fileInfo = getFileInfo(decoratorNode);
|
||||
let flags = fileInfo.isStubFile ? EvalFlags.ForwardRefs : EvalFlags.None;
|
||||
if (decoratorNode.expression.nodeType !== ParseNodeType.Call) {
|
||||
if (decoratorNode.d.expression.nodeType !== ParseNodeType.Call) {
|
||||
flags |= EvalFlags.CallBaseDefaults;
|
||||
}
|
||||
const decoratorType = evaluator.getTypeOfExpression(decoratorNode.expression, flags).type;
|
||||
const decoratorType = evaluator.getTypeOfExpression(decoratorNode.d.expression, flags).type;
|
||||
|
||||
if (decoratorNode.expression.nodeType === ParseNodeType.Call) {
|
||||
if (decoratorNode.d.expression.nodeType === ParseNodeType.Call) {
|
||||
const decoratorCallType = evaluator.getTypeOfExpression(
|
||||
decoratorNode.expression.leftExpression,
|
||||
decoratorNode.d.expression.d.leftExpression,
|
||||
flags | EvalFlags.CallBaseDefaults
|
||||
).type;
|
||||
|
||||
@ -318,7 +318,7 @@ export function applyClassDecorator(
|
||||
) {
|
||||
originalClassType.shared.classDataClassTransform = validateDataClassTransformDecorator(
|
||||
evaluator,
|
||||
decoratorNode.expression
|
||||
decoratorNode.d.expression
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -364,15 +364,15 @@ export function applyClassDecorator(
|
||||
let dataclassBehaviors: DataClassBehaviors | undefined;
|
||||
let callNode: CallNode | undefined;
|
||||
|
||||
if (decoratorNode.expression.nodeType === ParseNodeType.Call) {
|
||||
callNode = decoratorNode.expression;
|
||||
if (decoratorNode.d.expression.nodeType === ParseNodeType.Call) {
|
||||
callNode = decoratorNode.d.expression;
|
||||
const decoratorCallType = evaluator.getTypeOfExpression(
|
||||
callNode.leftExpression,
|
||||
callNode.d.leftExpression,
|
||||
flags | EvalFlags.CallBaseDefaults
|
||||
).type;
|
||||
dataclassBehaviors = getDataclassDecoratorBehaviors(decoratorCallType);
|
||||
} else {
|
||||
const decoratorType = evaluator.getTypeOfExpression(decoratorNode.expression, flags).type;
|
||||
const decoratorType = evaluator.getTypeOfExpression(decoratorNode.d.expression, flags).type;
|
||||
dataclassBehaviors = getDataclassDecoratorBehaviors(decoratorType);
|
||||
}
|
||||
|
||||
@ -393,11 +393,11 @@ export function applyClassDecorator(
|
||||
function getTypeOfDecorator(evaluator: TypeEvaluator, node: DecoratorNode, functionOrClassType: Type): Type {
|
||||
// Evaluate the type of the decorator expression.
|
||||
let flags = getFileInfo(node).isStubFile ? EvalFlags.ForwardRefs : EvalFlags.None;
|
||||
if (node.expression.nodeType !== ParseNodeType.Call) {
|
||||
if (node.d.expression.nodeType !== ParseNodeType.Call) {
|
||||
flags |= EvalFlags.CallBaseDefaults;
|
||||
}
|
||||
|
||||
const decoratorTypeResult = evaluator.getTypeOfExpression(node.expression, flags);
|
||||
const decoratorTypeResult = evaluator.getTypeOfExpression(node.d.expression, flags);
|
||||
|
||||
// Special-case the combination of a classmethod decorator applied
|
||||
// to a property. This is allowed in Python 3.9, but it's not reflected
|
||||
@ -418,7 +418,7 @@ function getTypeOfDecorator(evaluator: TypeEvaluator, node: DecoratorNode, funct
|
||||
];
|
||||
|
||||
const callTypeResult = evaluator.validateCallArguments(
|
||||
node.expression,
|
||||
node.d.expression,
|
||||
argList,
|
||||
decoratorTypeResult,
|
||||
/* typeVarContext */ undefined,
|
||||
@ -486,7 +486,7 @@ export function addOverloadsToFunctionType(evaluator: TypeEvaluator, node: Funct
|
||||
if (decl) {
|
||||
functionDecl = decl as FunctionDeclaration;
|
||||
}
|
||||
const symbolWithScope = evaluator.lookUpSymbolRecursive(node, node.name.value, /* honorCodeFlow */ false);
|
||||
const symbolWithScope = evaluator.lookUpSymbolRecursive(node, node.d.name.d.value, /* honorCodeFlow */ false);
|
||||
if (symbolWithScope) {
|
||||
const decls = symbolWithScope.symbol.getDeclarations();
|
||||
|
||||
@ -566,8 +566,8 @@ export function addOverloadsToFunctionType(evaluator: TypeEvaluator, node: Funct
|
||||
if (isPrevOverloadAbstract !== isCurrentOverloadAbstract) {
|
||||
evaluator.addDiagnostic(
|
||||
DiagnosticRule.reportInconsistentOverload,
|
||||
LocMessage.overloadAbstractMismatch().format({ name: node.name.value }),
|
||||
node.name
|
||||
LocMessage.overloadAbstractMismatch().format({ name: node.d.name.d.value }),
|
||||
node.d.name
|
||||
);
|
||||
}
|
||||
|
||||
@ -582,12 +582,12 @@ export function addOverloadsToFunctionType(evaluator: TypeEvaluator, node: Funct
|
||||
// deprecation message if one is provided.
|
||||
export function getDeprecatedMessageFromCall(node: CallNode): string {
|
||||
if (
|
||||
node.arguments.length > 0 &&
|
||||
node.arguments[0].argumentCategory === ArgumentCategory.Simple &&
|
||||
node.arguments[0].valueExpression.nodeType === ParseNodeType.StringList
|
||||
node.d.arguments.length > 0 &&
|
||||
node.d.arguments[0].d.argumentCategory === ArgumentCategory.Simple &&
|
||||
node.d.arguments[0].d.valueExpression.nodeType === ParseNodeType.StringList
|
||||
) {
|
||||
const stringListNode = node.arguments[0].valueExpression;
|
||||
const message = stringListNode.strings.map((s) => s.value).join('');
|
||||
const stringListNode = node.d.arguments[0].d.valueExpression;
|
||||
const message = stringListNode.d.strings.map((s) => s.d.value).join('');
|
||||
return convertDocStringToPlainText(message);
|
||||
}
|
||||
|
||||
|
@ -82,13 +82,13 @@ export function createEnumType(
|
||||
nameArg.argumentCategory !== ArgumentCategory.Simple ||
|
||||
!nameArg.valueExpression ||
|
||||
nameArg.valueExpression.nodeType !== ParseNodeType.StringList ||
|
||||
nameArg.valueExpression.strings.length !== 1 ||
|
||||
nameArg.valueExpression.strings[0].nodeType !== ParseNodeType.String
|
||||
nameArg.valueExpression.d.strings.length !== 1 ||
|
||||
nameArg.valueExpression.d.strings[0].nodeType !== ParseNodeType.String
|
||||
) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const className = nameArg.valueExpression.strings.map((s) => s.value).join('');
|
||||
const className = nameArg.valueExpression.d.strings.map((s) => s.d.value).join('');
|
||||
const classType = ClassType.createInstantiable(
|
||||
className,
|
||||
getClassFullName(errorNode, fileInfo.moduleName, className),
|
||||
@ -133,12 +133,12 @@ export function createEnumType(
|
||||
// Enum('name', {'a': 1, 'b': 2, 'c': 3})
|
||||
if (initArg.valueExpression.nodeType === ParseNodeType.StringList) {
|
||||
// Don't allow format strings in the init arg.
|
||||
if (!initArg.valueExpression.strings.every((str) => str.nodeType === ParseNodeType.String)) {
|
||||
if (!initArg.valueExpression.d.strings.every((str) => str.nodeType === ParseNodeType.String)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const initStr = initArg.valueExpression.strings
|
||||
.map((s) => s.value)
|
||||
const initStr = initArg.valueExpression.d.strings
|
||||
.map((s) => s.d.value)
|
||||
.join('')
|
||||
.trim();
|
||||
|
||||
@ -171,8 +171,8 @@ export function createEnumType(
|
||||
) {
|
||||
const entries =
|
||||
initArg.valueExpression.nodeType === ParseNodeType.List
|
||||
? initArg.valueExpression.entries
|
||||
: initArg.valueExpression.expressions;
|
||||
? initArg.valueExpression.d.entries
|
||||
: initArg.valueExpression.d.expressions;
|
||||
|
||||
if (entries.length === 0) {
|
||||
return undefined;
|
||||
@ -201,24 +201,24 @@ export function createEnumType(
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (entry.expressions.length !== 2) {
|
||||
if (entry.d.expressions.length !== 2) {
|
||||
return undefined;
|
||||
}
|
||||
nameNode = entry.expressions[0];
|
||||
valueType = evaluator.getTypeOfExpression(entry.expressions[1]).type;
|
||||
nameNode = entry.d.expressions[0];
|
||||
valueType = evaluator.getTypeOfExpression(entry.d.expressions[1]).type;
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (
|
||||
nameNode.nodeType !== ParseNodeType.StringList ||
|
||||
nameNode.strings.length !== 1 ||
|
||||
nameNode.strings[0].nodeType !== ParseNodeType.String
|
||||
nameNode.d.strings.length !== 1 ||
|
||||
nameNode.d.strings[0].nodeType !== ParseNodeType.String
|
||||
) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const entryName = nameNode.strings[0].value;
|
||||
const entryName = nameNode.d.strings[0].d.value;
|
||||
|
||||
const enumLiteral = new EnumLiteral(classType.shared.fullName, classType.shared.name, entryName, valueType);
|
||||
|
||||
@ -232,7 +232,7 @@ export function createEnumType(
|
||||
}
|
||||
|
||||
if (initArg.valueExpression.nodeType === ParseNodeType.Dictionary) {
|
||||
const entries = initArg.valueExpression.entries;
|
||||
const entries = initArg.valueExpression.d.entries;
|
||||
if (entries.length === 0) {
|
||||
return undefined;
|
||||
}
|
||||
@ -243,18 +243,18 @@ export function createEnumType(
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const nameNode = entry.keyExpression;
|
||||
const valueType = evaluator.getTypeOfExpression(entry.valueExpression).type;
|
||||
const nameNode = entry.d.keyExpression;
|
||||
const valueType = evaluator.getTypeOfExpression(entry.d.valueExpression).type;
|
||||
|
||||
if (
|
||||
nameNode.nodeType !== ParseNodeType.StringList ||
|
||||
nameNode.strings.length !== 1 ||
|
||||
nameNode.strings[0].nodeType !== ParseNodeType.String
|
||||
nameNode.d.strings.length !== 1 ||
|
||||
nameNode.d.strings[0].nodeType !== ParseNodeType.String
|
||||
) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const entryName = nameNode.strings[0].value;
|
||||
const entryName = nameNode.d.strings[0].d.value;
|
||||
const enumLiteral = new EnumLiteral(classType.shared.fullName, classType.shared.name, entryName, valueType);
|
||||
|
||||
const newSymbol = Symbol.createWithType(
|
||||
@ -318,29 +318,29 @@ export function transformTypeForEnumMember(
|
||||
primaryDecl.node.nodeType === ParseNodeType.Class
|
||||
) {
|
||||
// Handle the case where a method or class is decorated with @enum.member.
|
||||
nameNode = primaryDecl.node.name;
|
||||
nameNode = primaryDecl.node.d.name;
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (nameNode.parent?.nodeType === ParseNodeType.Assignment && nameNode.parent.leftExpression === nameNode) {
|
||||
if (nameNode.parent?.nodeType === ParseNodeType.Assignment && nameNode.parent.d.leftExpression === nameNode) {
|
||||
isMemberOfEnumeration = true;
|
||||
valueTypeExprNode = nameNode.parent.rightExpression;
|
||||
valueTypeExprNode = nameNode.parent.d.rightExpression;
|
||||
} else if (
|
||||
nameNode.parent?.nodeType === ParseNodeType.Tuple &&
|
||||
nameNode.parent.parent?.nodeType === ParseNodeType.Assignment
|
||||
) {
|
||||
isMemberOfEnumeration = true;
|
||||
isUnpackedTuple = true;
|
||||
valueTypeExprNode = nameNode.parent.parent.rightExpression;
|
||||
valueTypeExprNode = nameNode.parent.parent.d.rightExpression;
|
||||
} else if (
|
||||
nameNode.parent?.nodeType === ParseNodeType.TypeAnnotation &&
|
||||
nameNode.parent.valueExpression === nameNode
|
||||
nameNode.parent.d.valueExpression === nameNode
|
||||
) {
|
||||
if (ignoreAnnotation) {
|
||||
isMemberOfEnumeration = true;
|
||||
}
|
||||
declaredTypeNode = nameNode.parent.typeAnnotation;
|
||||
declaredTypeNode = nameNode.parent.d.typeAnnotation;
|
||||
}
|
||||
|
||||
// The spec specifically excludes names that start and end with a single underscore.
|
||||
@ -363,11 +363,11 @@ export function transformTypeForEnumMember(
|
||||
}
|
||||
|
||||
// Handle aliases to other enum members within the same enum.
|
||||
if (valueTypeExprNode?.nodeType === ParseNodeType.Name && valueTypeExprNode.value !== memberName) {
|
||||
if (valueTypeExprNode?.nodeType === ParseNodeType.Name && valueTypeExprNode.d.value !== memberName) {
|
||||
const aliasedEnumType = transformTypeForEnumMember(
|
||||
evaluator,
|
||||
classType,
|
||||
valueTypeExprNode.value,
|
||||
valueTypeExprNode.d.value,
|
||||
/* ignoreAnnotation */ false,
|
||||
recursionCount
|
||||
);
|
||||
@ -435,10 +435,10 @@ export function transformTypeForEnumMember(
|
||||
if (
|
||||
!assignedType &&
|
||||
nameNode.parent?.nodeType === ParseNodeType.Assignment &&
|
||||
nameNode.parent.leftExpression === nameNode
|
||||
nameNode.parent.d.leftExpression === nameNode
|
||||
) {
|
||||
assignedType = evaluator.getTypeOfExpression(
|
||||
nameNode.parent.rightExpression,
|
||||
nameNode.parent.d.rightExpression,
|
||||
/* flags */ undefined,
|
||||
makeInferenceContext(declaredType)
|
||||
).type;
|
||||
|
@ -124,9 +124,9 @@ export function getTopLevelImports(parseTree: ModuleNode, includeImplicitImports
|
||||
let followsNonImportStatement = false;
|
||||
let foundFirstImportStatement = false;
|
||||
|
||||
parseTree.statements.forEach((statement) => {
|
||||
parseTree.d.statements.forEach((statement) => {
|
||||
if (statement.nodeType === ParseNodeType.StatementList) {
|
||||
statement.statements.forEach((subStatement) => {
|
||||
statement.d.statements.forEach((subStatement) => {
|
||||
if (subStatement.nodeType === ParseNodeType.Import) {
|
||||
foundFirstImportStatement = true;
|
||||
_processImportNode(subStatement, localImports, followsNonImportStatement);
|
||||
@ -173,7 +173,7 @@ export function getTextEditsForAutoImportSymbolAddition(
|
||||
if (
|
||||
!importStatement.node ||
|
||||
importStatement.node.nodeType !== ParseNodeType.ImportFrom ||
|
||||
importStatement.node.isWildcardImport
|
||||
importStatement.node.d.isWildcardImport
|
||||
) {
|
||||
return additionEdits;
|
||||
}
|
||||
@ -184,8 +184,8 @@ export function getTextEditsForAutoImportSymbolAddition(
|
||||
importNameInfo = (Array.isArray(importNameInfo) ? importNameInfo : [importNameInfo]).filter(
|
||||
(info) =>
|
||||
!!info.name &&
|
||||
!importFrom.imports.some(
|
||||
(importAs) => importAs.name.value === info.name && importAs.alias?.value === info.alias
|
||||
!importFrom.d.imports.some(
|
||||
(importAs) => importAs.d.name.d.value === info.name && importAs.d.alias?.d.value === info.alias
|
||||
)
|
||||
);
|
||||
|
||||
@ -256,8 +256,8 @@ function _getTextEditsForAutoImportSymbolAddition(
|
||||
// Scan through the import symbols to find the right insertion point,
|
||||
// assuming we want to keep the imports alphabetized.
|
||||
let priorImport: ImportFromAsNode | undefined;
|
||||
for (const curImport of node.imports) {
|
||||
if (_compareImportNames(curImport.name.value, importName) > 0) {
|
||||
for (const curImport of node.d.imports) {
|
||||
if (_compareImportNames(curImport.d.name.d.value, importName) > 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
@ -274,12 +274,12 @@ function _getTextEditsForAutoImportSymbolAddition(
|
||||
// )
|
||||
let useOnePerLineFormatting = false;
|
||||
let indentText = '';
|
||||
if (node.imports.length > 0) {
|
||||
if (node.d.imports.length > 0) {
|
||||
const importStatementPos = convertOffsetToPosition(node.start, parseFileResults.tokenizerOutput.lines);
|
||||
const firstSymbolPos = convertOffsetToPosition(node.imports[0].start, parseFileResults.tokenizerOutput.lines);
|
||||
const firstSymbolPos = convertOffsetToPosition(node.d.imports[0].start, parseFileResults.tokenizerOutput.lines);
|
||||
const secondSymbolPos =
|
||||
node.imports.length > 1
|
||||
? convertOffsetToPosition(node.imports[1].start, parseFileResults.tokenizerOutput.lines)
|
||||
node.d.imports.length > 1
|
||||
? convertOffsetToPosition(node.d.imports[1].start, parseFileResults.tokenizerOutput.lines)
|
||||
: undefined;
|
||||
|
||||
if (
|
||||
@ -301,8 +301,8 @@ function _getTextEditsForAutoImportSymbolAddition(
|
||||
|
||||
const insertionOffset = priorImport
|
||||
? TextRange.getEnd(priorImport)
|
||||
: node.imports.length > 0
|
||||
? node.imports[0].start
|
||||
: node.d.imports.length > 0
|
||||
? node.d.imports[0].start
|
||||
: node.start + node.length;
|
||||
const insertionPosition = convertOffsetToPosition(insertionOffset, parseFileResults.tokenizerOutput.lines);
|
||||
|
||||
@ -581,17 +581,17 @@ function _getInsertionEditForAutoImportInsertion(
|
||||
insertionPosition = { line: 0, character: 0 };
|
||||
let addNewLineBefore = false;
|
||||
|
||||
for (const statement of parseFileResults.parserOutput.parseTree.statements) {
|
||||
for (const statement of parseFileResults.parserOutput.parseTree.d.statements) {
|
||||
let stopHere = true;
|
||||
if (statement.nodeType === ParseNodeType.StatementList && statement.statements.length === 1) {
|
||||
const simpleStatement = statement.statements[0];
|
||||
if (statement.nodeType === ParseNodeType.StatementList && statement.d.statements.length === 1) {
|
||||
const simpleStatement = statement.d.statements[0];
|
||||
|
||||
if (simpleStatement.nodeType === ParseNodeType.StringList) {
|
||||
// Assume that it's a file header doc string.
|
||||
stopHere = false;
|
||||
} else if (simpleStatement.nodeType === ParseNodeType.Assignment) {
|
||||
if (simpleStatement.leftExpression.nodeType === ParseNodeType.Name) {
|
||||
if (SymbolNameUtils.isDunderName(simpleStatement.leftExpression.value)) {
|
||||
if (simpleStatement.d.leftExpression.nodeType === ParseNodeType.Name) {
|
||||
if (SymbolNameUtils.isDunderName(simpleStatement.d.leftExpression.d.value)) {
|
||||
// Assume that it's an assignment of __copyright__, __author__, etc.
|
||||
stopHere = false;
|
||||
}
|
||||
@ -628,8 +628,8 @@ function _getInsertionEditForAutoImportInsertion(
|
||||
}
|
||||
|
||||
function _processImportNode(node: ImportNode, localImports: ImportStatements, followsNonImportStatement: boolean) {
|
||||
node.list.forEach((importAsNode) => {
|
||||
const importResult = AnalyzerNodeInfo.getImportInfo(importAsNode.module);
|
||||
node.d.list.forEach((importAsNode) => {
|
||||
const importResult = AnalyzerNodeInfo.getImportInfo(importAsNode.d.module);
|
||||
let resolvedPath: Uri | undefined;
|
||||
|
||||
if (importResult && importResult.isImportFound) {
|
||||
@ -641,7 +641,7 @@ function _processImportNode(node: ImportNode, localImports: ImportStatements, fo
|
||||
subnode: importAsNode,
|
||||
importResult,
|
||||
resolvedPath,
|
||||
moduleName: _formatModuleName(importAsNode.module),
|
||||
moduleName: _formatModuleName(importAsNode.d.module),
|
||||
followsNonImportStatement,
|
||||
};
|
||||
|
||||
@ -665,7 +665,7 @@ function _processImportFromNode(
|
||||
followsNonImportStatement: boolean,
|
||||
includeImplicitImports: boolean
|
||||
) {
|
||||
const importResult = AnalyzerNodeInfo.getImportInfo(node.module);
|
||||
const importResult = AnalyzerNodeInfo.getImportInfo(node.d.module);
|
||||
let resolvedPath: Uri | undefined;
|
||||
|
||||
if (importResult && importResult.isImportFound) {
|
||||
@ -676,7 +676,7 @@ function _processImportFromNode(
|
||||
localImports.implicitImports = localImports.implicitImports ?? new Map<string, ImportFromAsNode>();
|
||||
|
||||
for (const implicitImport of importResult.implicitImports.values()) {
|
||||
const importFromAs = node.imports.find((i) => i.name.value === implicitImport.name);
|
||||
const importFromAs = node.d.imports.find((i) => i.d.name.d.value === implicitImport.name);
|
||||
if (importFromAs) {
|
||||
localImports.implicitImports.set(implicitImport.uri.key, importFromAs);
|
||||
}
|
||||
@ -687,7 +687,7 @@ function _processImportFromNode(
|
||||
node,
|
||||
importResult,
|
||||
resolvedPath,
|
||||
moduleName: _formatModuleName(node.module),
|
||||
moduleName: _formatModuleName(node.d.module),
|
||||
followsNonImportStatement,
|
||||
};
|
||||
|
||||
@ -711,11 +711,11 @@ function _processImportFromNode(
|
||||
|
||||
function _formatModuleName(node: ModuleNameNode): string {
|
||||
let moduleName = '';
|
||||
for (let i = 0; i < node.leadingDots; i++) {
|
||||
for (let i = 0; i < node.d.leadingDots; i++) {
|
||||
moduleName = moduleName + '.';
|
||||
}
|
||||
|
||||
moduleName += node.nameParts.map((part) => part.value).join('.');
|
||||
moduleName += node.d.nameParts.map((part) => part.d.value).join('.');
|
||||
|
||||
return moduleName;
|
||||
}
|
||||
@ -737,11 +737,11 @@ export function getContainingImportStatement(node: ParseNode | undefined, token:
|
||||
export function getAllImportNames(node: ImportNode | ImportFromNode) {
|
||||
if (node.nodeType === ParseNodeType.Import) {
|
||||
const importNode = node as ImportNode;
|
||||
return importNode.list;
|
||||
return importNode.d.list;
|
||||
}
|
||||
|
||||
const importFromNode = node as ImportFromNode;
|
||||
return importFromNode.imports;
|
||||
return importFromNode.d.imports;
|
||||
}
|
||||
|
||||
export function getImportGroupFromModuleNameAndType(moduleNameAndType: ModuleNameAndType): ImportGroup {
|
||||
|
@ -68,7 +68,7 @@ export function createNamedTupleType(
|
||||
let allowRename = false;
|
||||
if (!includesTypes) {
|
||||
const renameArg = argList.find(
|
||||
(arg) => arg.argumentCategory === ArgumentCategory.Simple && arg.name?.value === 'rename'
|
||||
(arg) => arg.argumentCategory === ArgumentCategory.Simple && arg.name?.d.value === 'rename'
|
||||
);
|
||||
|
||||
if (renameArg?.valueExpression) {
|
||||
@ -94,13 +94,13 @@ export function createNamedTupleType(
|
||||
argList[0].valueExpression || errorNode
|
||||
);
|
||||
} else if (nameArg.valueExpression && nameArg.valueExpression.nodeType === ParseNodeType.StringList) {
|
||||
className = nameArg.valueExpression.strings.map((s) => s.value).join('');
|
||||
className = nameArg.valueExpression.d.strings.map((s) => s.d.value).join('');
|
||||
}
|
||||
}
|
||||
|
||||
// Is there is a default arg? If so, is it defined in a way that we
|
||||
// can determine its length statically?
|
||||
const defaultsArg = argList.find((arg) => arg.name?.value === 'defaults');
|
||||
const defaultsArg = argList.find((arg) => arg.name?.d.value === 'defaults');
|
||||
let defaultArgCount: number | undefined = 0;
|
||||
if (defaultsArg && defaultsArg.valueExpression) {
|
||||
const defaultsArgType = evaluator.getTypeOfExpression(defaultsArg.valueExpression).type;
|
||||
@ -175,8 +175,8 @@ export function createNamedTupleType(
|
||||
entriesArg.valueExpression &&
|
||||
entriesArg.valueExpression.nodeType === ParseNodeType.StringList
|
||||
) {
|
||||
const entries = entriesArg.valueExpression.strings
|
||||
.map((s) => s.value)
|
||||
const entries = entriesArg.valueExpression.d.strings
|
||||
.map((s) => s.d.value)
|
||||
.join('')
|
||||
.split(/[,\s]+/);
|
||||
const firstParamWithDefaultIndex =
|
||||
@ -236,8 +236,8 @@ export function createNamedTupleType(
|
||||
const entryMap = new Map<string, string>();
|
||||
const entryExpressions =
|
||||
entriesArg.valueExpression?.nodeType === ParseNodeType.List
|
||||
? entriesArg.valueExpression.entries
|
||||
: entriesArg.valueExpression.expressions;
|
||||
? entriesArg.valueExpression.d.entries
|
||||
: entriesArg.valueExpression.d.expressions;
|
||||
|
||||
const firstParamWithDefaultIndex =
|
||||
defaultArgCount === undefined ? 0 : Math.max(0, entryExpressions.length - defaultArgCount);
|
||||
@ -250,9 +250,9 @@ export function createNamedTupleType(
|
||||
|
||||
if (includesTypes) {
|
||||
// Handle the variant that includes name/type tuples.
|
||||
if (entry.nodeType === ParseNodeType.Tuple && entry.expressions.length === 2) {
|
||||
entryNameNode = entry.expressions[0];
|
||||
entryTypeNode = entry.expressions[1];
|
||||
if (entry.nodeType === ParseNodeType.Tuple && entry.d.expressions.length === 2) {
|
||||
entryNameNode = entry.d.expressions[0];
|
||||
entryTypeNode = entry.d.expressions[1];
|
||||
entryType = convertToInstance(
|
||||
evaluator.getTypeOfExpressionExpectingType(entryTypeNode).type
|
||||
);
|
||||
|
@ -504,25 +504,25 @@ export function getTypeOfBinaryOperation(
|
||||
flags: EvalFlags,
|
||||
inferenceContext: InferenceContext | undefined
|
||||
): TypeResult {
|
||||
const leftExpression = node.leftExpression;
|
||||
let rightExpression = node.rightExpression;
|
||||
const leftExpression = node.d.leftExpression;
|
||||
let rightExpression = node.d.rightExpression;
|
||||
let isIncomplete = false;
|
||||
let typeErrors = false;
|
||||
|
||||
// If this is a comparison and the left expression is also a comparison,
|
||||
// we need to change the behavior to accommodate python's "chained
|
||||
// comparisons" feature.
|
||||
if (operatorSupportsChaining(node.operator)) {
|
||||
if (operatorSupportsChaining(node.d.operator)) {
|
||||
if (
|
||||
rightExpression.nodeType === ParseNodeType.BinaryOperation &&
|
||||
!rightExpression.isParenthesized &&
|
||||
operatorSupportsChaining(rightExpression.operator)
|
||||
!rightExpression.d.isParenthesized &&
|
||||
operatorSupportsChaining(rightExpression.d.operator)
|
||||
) {
|
||||
// Evaluate the right expression so it is type checked.
|
||||
getTypeOfBinaryOperation(evaluator, rightExpression, flags, inferenceContext);
|
||||
|
||||
// Use the left side of the right expression for comparison purposes.
|
||||
rightExpression = rightExpression.leftExpression;
|
||||
rightExpression = rightExpression.d.leftExpression;
|
||||
}
|
||||
}
|
||||
|
||||
@ -530,7 +530,7 @@ export function getTypeOfBinaryOperation(
|
||||
// of the magic method for that operation. However, the "or" and "and" operators
|
||||
// have no magic method, so we apply the expected type directly to both operands.
|
||||
let expectedOperandType =
|
||||
node.operator === OperatorType.Or || node.operator === OperatorType.And
|
||||
node.d.operator === OperatorType.Or || node.d.operator === OperatorType.And
|
||||
? inferenceContext?.expectedType
|
||||
: undefined;
|
||||
|
||||
@ -539,13 +539,13 @@ export function getTypeOfBinaryOperation(
|
||||
// of "x: List[Optional[X]] = [None] * y" where y is an integer literal.
|
||||
let expectedLeftOperandType: Type | undefined;
|
||||
if (
|
||||
node.operator === OperatorType.Multiply &&
|
||||
node.d.operator === OperatorType.Multiply &&
|
||||
inferenceContext &&
|
||||
isClassInstance(inferenceContext.expectedType) &&
|
||||
ClassType.isBuiltIn(inferenceContext.expectedType, 'list') &&
|
||||
inferenceContext.expectedType.priv.typeArguments &&
|
||||
inferenceContext.expectedType.priv.typeArguments.length >= 1 &&
|
||||
node.leftExpression.nodeType === ParseNodeType.List
|
||||
node.d.leftExpression.nodeType === ParseNodeType.List
|
||||
) {
|
||||
expectedLeftOperandType = inferenceContext.expectedType;
|
||||
}
|
||||
@ -559,7 +559,7 @@ export function getTypeOfBinaryOperation(
|
||||
let leftType = leftTypeResult.type;
|
||||
|
||||
if (!expectedOperandType) {
|
||||
if (node.operator === OperatorType.Or || node.operator === OperatorType.And) {
|
||||
if (node.d.operator === OperatorType.Or || node.d.operator === OperatorType.And) {
|
||||
// For "or" and "and", use the type of the left operand under certain
|
||||
// circumstances. This allows us to infer a better type for expressions
|
||||
// like `x or []`. Do this only if it's a generic class (like list or dict)
|
||||
@ -575,11 +575,11 @@ export function getTypeOfBinaryOperation(
|
||||
) {
|
||||
expectedOperandType = leftType;
|
||||
}
|
||||
} else if (node.operator === OperatorType.Add && node.rightExpression.nodeType === ParseNodeType.List) {
|
||||
} else if (node.d.operator === OperatorType.Add && node.d.rightExpression.nodeType === ParseNodeType.List) {
|
||||
// For the "+" operator , use this technique only if the right operand is
|
||||
// a list expression. This heuristic handles the common case of `my_list + [0]`.
|
||||
expectedOperandType = leftType;
|
||||
} else if (node.operator === OperatorType.BitwiseOr) {
|
||||
} else if (node.d.operator === OperatorType.BitwiseOr) {
|
||||
// If this is a bitwise or ("|"), use the type of the left operand. This allows
|
||||
// us to support the case where a TypedDict is being updated with a dict expression.
|
||||
if (isClassInstance(leftType) && ClassType.isTypedDictClass(leftType)) {
|
||||
@ -602,7 +602,7 @@ export function getTypeOfBinaryOperation(
|
||||
// Is this a "|" operator used in a context where it is supposed to be
|
||||
// interpreted as a union operator?
|
||||
if (
|
||||
node.operator === OperatorType.BitwiseOr &&
|
||||
node.d.operator === OperatorType.BitwiseOr &&
|
||||
!customMetaclassSupportsMethod(leftType, '__or__') &&
|
||||
!customMetaclassSupportsMethod(rightType, '__ror__')
|
||||
) {
|
||||
@ -633,7 +633,7 @@ export function getTypeOfBinaryOperation(
|
||||
DiagnosticRule.reportGeneralTypeIssues,
|
||||
LocMessage.unionSyntaxIllegal(),
|
||||
node,
|
||||
node.operatorToken
|
||||
node.d.operatorToken
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -646,12 +646,12 @@ export function getTypeOfBinaryOperation(
|
||||
}
|
||||
|
||||
adjustedLeftType = evaluator.reportMissingTypeArguments(
|
||||
node.leftExpression,
|
||||
node.d.leftExpression,
|
||||
adjustedLeftType,
|
||||
flags | EvalFlags.InstantiableType
|
||||
);
|
||||
adjustedRightType = evaluator.reportMissingTypeArguments(
|
||||
node.rightExpression,
|
||||
node.d.rightExpression,
|
||||
adjustedRightType,
|
||||
flags | EvalFlags.InstantiableType
|
||||
);
|
||||
@ -705,7 +705,7 @@ export function getTypeOfBinaryOperation(
|
||||
|
||||
if ((flags & EvalFlags.TypeExpression) !== 0) {
|
||||
// Exempt "|" because it might be a union operation involving unknowns.
|
||||
if (node.operator !== OperatorType.BitwiseOr) {
|
||||
if (node.d.operator !== OperatorType.BitwiseOr) {
|
||||
evaluator.addDiagnostic(DiagnosticRule.reportInvalidTypeForm, LocMessage.binaryOperationNotAllowed(), node);
|
||||
return { type: UnknownType.create() };
|
||||
}
|
||||
@ -713,16 +713,16 @@ export function getTypeOfBinaryOperation(
|
||||
|
||||
// Optional checks apply to all operations except for boolean operations.
|
||||
let isLeftOptionalType = false;
|
||||
if (booleanOperatorMap[node.operator] === undefined) {
|
||||
if (booleanOperatorMap[node.d.operator] === undefined) {
|
||||
// None is a valid operand for == and != even if the type stub says otherwise.
|
||||
if (node.operator === OperatorType.Equals || node.operator === OperatorType.NotEquals) {
|
||||
if (node.d.operator === OperatorType.Equals || node.d.operator === OperatorType.NotEquals) {
|
||||
leftType = removeNoneFromUnion(leftType);
|
||||
} else {
|
||||
isLeftOptionalType = isOptionalType(leftType);
|
||||
}
|
||||
|
||||
// None is a valid operand for == and != even if the type stub says otherwise.
|
||||
if (node.operator === OperatorType.Equals || node.operator === OperatorType.NotEquals) {
|
||||
if (node.d.operator === OperatorType.Equals || node.d.operator === OperatorType.NotEquals) {
|
||||
rightType = removeNoneFromUnion(rightType);
|
||||
}
|
||||
}
|
||||
@ -742,7 +742,7 @@ export function getTypeOfBinaryOperation(
|
||||
|
||||
const type = validateBinaryOperation(
|
||||
evaluator,
|
||||
node.operator,
|
||||
node.d.operator,
|
||||
{ type: leftType, isIncomplete: leftTypeResult.isIncomplete },
|
||||
{ type: rightType, isIncomplete: rightTypeResult.isIncomplete },
|
||||
node,
|
||||
@ -763,9 +763,9 @@ export function getTypeOfBinaryOperation(
|
||||
evaluator.addDiagnostic(
|
||||
DiagnosticRule.reportOptionalOperand,
|
||||
LocMessage.noneOperator().format({
|
||||
operator: printOperator(node.operator),
|
||||
operator: printOperator(node.d.operator),
|
||||
}),
|
||||
node.leftExpression
|
||||
node.d.leftExpression
|
||||
);
|
||||
} else {
|
||||
// If neither the LHS or RHS are unions, don't include a diagnostic addendum
|
||||
@ -782,7 +782,7 @@ export function getTypeOfBinaryOperation(
|
||||
evaluator.addDiagnostic(
|
||||
DiagnosticRule.reportOperatorIssue,
|
||||
LocMessage.typeNotSupportBinaryOperator().format({
|
||||
operator: printOperator(node.operator),
|
||||
operator: printOperator(node.d.operator),
|
||||
leftType: evaluator.printType(leftType),
|
||||
rightType: evaluator.printType(rightType),
|
||||
}) + diagString,
|
||||
@ -820,18 +820,18 @@ export function getTypeOfAugmentedAssignment(
|
||||
let typeResult: TypeResult | undefined;
|
||||
const diag = new DiagnosticAddendum();
|
||||
|
||||
const leftTypeResult = evaluator.getTypeOfExpression(node.leftExpression);
|
||||
const leftTypeResult = evaluator.getTypeOfExpression(node.d.leftExpression);
|
||||
const leftType = leftTypeResult.type;
|
||||
|
||||
let expectedOperandType: Type | undefined;
|
||||
if (node.operator === OperatorType.BitwiseOrEqual) {
|
||||
if (node.d.operator === OperatorType.BitwiseOrEqual) {
|
||||
// If this is a bitwise or ("|="), use the type of the left operand. This allows
|
||||
// us to support the case where a TypedDict is being updated with a dict expression.
|
||||
expectedOperandType = leftType;
|
||||
}
|
||||
|
||||
const rightTypeResult = evaluator.getTypeOfExpression(
|
||||
node.rightExpression,
|
||||
node.d.rightExpression,
|
||||
/* flags */ undefined,
|
||||
makeInferenceContext(expectedOperandType)
|
||||
);
|
||||
@ -853,7 +853,7 @@ export function getTypeOfAugmentedAssignment(
|
||||
return preserveUnknown(leftSubtypeUnexpanded, rightSubtypeUnexpanded);
|
||||
}
|
||||
|
||||
const magicMethodName = operatorMap[node.operator][0];
|
||||
const magicMethodName = operatorMap[node.d.operator][0];
|
||||
let returnType = evaluator.getTypeOfMagicMethodCall(
|
||||
leftSubtypeUnexpanded,
|
||||
magicMethodName,
|
||||
@ -887,13 +887,13 @@ export function getTypeOfAugmentedAssignment(
|
||||
if (!returnType) {
|
||||
// If the LHS class didn't support the magic method for augmented
|
||||
// assignment, fall back on the normal binary expression evaluator.
|
||||
const binaryOperator = operatorMap[node.operator][1];
|
||||
const binaryOperator = operatorMap[node.d.operator][1];
|
||||
|
||||
// Don't use literal math if the operation is within a loop
|
||||
// because the literal values may change each time.
|
||||
const isLiteralMathAllowed =
|
||||
!isWithinLoop(node) &&
|
||||
isExpressionLocalVariable(evaluator, node.leftExpression) &&
|
||||
isExpressionLocalVariable(evaluator, node.d.leftExpression) &&
|
||||
getUnionSubtypeCount(leftType) * getUnionSubtypeCount(rightType) <
|
||||
maxLiteralMathSubtypeCount;
|
||||
|
||||
@ -927,7 +927,7 @@ export function getTypeOfAugmentedAssignment(
|
||||
evaluator.addDiagnostic(
|
||||
DiagnosticRule.reportOperatorIssue,
|
||||
LocMessage.typeNotSupportBinaryOperator().format({
|
||||
operator: printOperator(node.operator),
|
||||
operator: printOperator(node.d.operator),
|
||||
leftType: evaluator.printType(leftType),
|
||||
rightType: evaluator.printType(rightType),
|
||||
}) + diag.getString(),
|
||||
@ -939,7 +939,7 @@ export function getTypeOfAugmentedAssignment(
|
||||
typeResult = { type, isIncomplete };
|
||||
}
|
||||
|
||||
evaluator.assignTypeToExpression(node.destExpression, typeResult, node.rightExpression);
|
||||
evaluator.assignTypeToExpression(node.d.destExpression, typeResult, node.d.rightExpression);
|
||||
|
||||
return typeResult;
|
||||
}
|
||||
@ -955,7 +955,7 @@ export function getTypeOfUnaryOperation(
|
||||
return { type: UnknownType.create() };
|
||||
}
|
||||
|
||||
const exprTypeResult = evaluator.getTypeOfExpression(node.expression);
|
||||
const exprTypeResult = evaluator.getTypeOfExpression(node.d.expression);
|
||||
let exprType = evaluator.makeTopLevelTypeVarsConcrete(transformPossibleRecursiveTypeAlias(exprTypeResult.type));
|
||||
|
||||
const isIncomplete = exprTypeResult.isIncomplete;
|
||||
@ -974,14 +974,14 @@ export function getTypeOfUnaryOperation(
|
||||
|
||||
let type: Type | undefined;
|
||||
|
||||
if (node.operator !== OperatorType.Not) {
|
||||
if (node.d.operator !== OperatorType.Not) {
|
||||
if (isOptionalType(exprType)) {
|
||||
evaluator.addDiagnostic(
|
||||
DiagnosticRule.reportOptionalOperand,
|
||||
LocMessage.noneOperator().format({
|
||||
operator: printOperator(node.operator),
|
||||
operator: printOperator(node.d.operator),
|
||||
}),
|
||||
node.expression
|
||||
node.d.expression
|
||||
);
|
||||
exprType = removeNoneFromUnion(exprType);
|
||||
}
|
||||
@ -994,9 +994,9 @@ export function getTypeOfUnaryOperation(
|
||||
if (!exprTypeResult.isIncomplete) {
|
||||
const literalClassName = getLiteralTypeClassName(exprType);
|
||||
if (literalClassName === 'int') {
|
||||
if (node.operator === OperatorType.Add) {
|
||||
if (node.d.operator === OperatorType.Add) {
|
||||
type = exprType;
|
||||
} else if (node.operator === OperatorType.Subtract) {
|
||||
} else if (node.d.operator === OperatorType.Subtract) {
|
||||
type = mapSubtypes(exprType, (subtype) => {
|
||||
const classSubtype = subtype as ClassType;
|
||||
return ClassType.cloneWithLiteral(
|
||||
@ -1006,7 +1006,7 @@ export function getTypeOfUnaryOperation(
|
||||
});
|
||||
}
|
||||
} else if (literalClassName === 'bool') {
|
||||
if (node.operator === OperatorType.Not) {
|
||||
if (node.d.operator === OperatorType.Not) {
|
||||
type = mapSubtypes(exprType, (subtype) => {
|
||||
const classSubtype = subtype as ClassType;
|
||||
return ClassType.cloneWithLiteral(classSubtype, !(classSubtype.priv.literalValue as boolean));
|
||||
@ -1017,7 +1017,7 @@ export function getTypeOfUnaryOperation(
|
||||
|
||||
if (!type) {
|
||||
// __not__ always returns a boolean.
|
||||
if (node.operator === OperatorType.Not) {
|
||||
if (node.d.operator === OperatorType.Not) {
|
||||
type = evaluator.getBuiltInObject(node, 'bool');
|
||||
if (!type) {
|
||||
type = UnknownType.create();
|
||||
@ -1026,7 +1026,7 @@ export function getTypeOfUnaryOperation(
|
||||
if (isAnyOrUnknown(exprType)) {
|
||||
type = exprType;
|
||||
} else {
|
||||
const magicMethodName = unaryOperatorMap[node.operator];
|
||||
const magicMethodName = unaryOperatorMap[node.d.operator];
|
||||
let isResultValid = true;
|
||||
|
||||
type = evaluator.mapSubtypesExpandTypeVars(exprType, /* options */ undefined, (subtypeExpanded) => {
|
||||
@ -1056,7 +1056,7 @@ export function getTypeOfUnaryOperation(
|
||||
evaluator.addDiagnostic(
|
||||
DiagnosticRule.reportOperatorIssue,
|
||||
LocMessage.typeNotSupportUnaryOperatorBidirectional().format({
|
||||
operator: printOperator(node.operator),
|
||||
operator: printOperator(node.d.operator),
|
||||
type: evaluator.printType(exprType),
|
||||
expectedType: evaluator.printType(inferenceContext.expectedType),
|
||||
}),
|
||||
@ -1066,7 +1066,7 @@ export function getTypeOfUnaryOperation(
|
||||
evaluator.addDiagnostic(
|
||||
DiagnosticRule.reportOperatorIssue,
|
||||
LocMessage.typeNotSupportUnaryOperator().format({
|
||||
operator: printOperator(node.operator),
|
||||
operator: printOperator(node.d.operator),
|
||||
type: evaluator.printType(exprType),
|
||||
}),
|
||||
node
|
||||
@ -1095,20 +1095,20 @@ export function getTypeOfTernaryOperation(
|
||||
return { type: UnknownType.create() };
|
||||
}
|
||||
|
||||
evaluator.getTypeOfExpression(node.testExpression);
|
||||
evaluator.getTypeOfExpression(node.d.testExpression);
|
||||
|
||||
const typesToCombine: Type[] = [];
|
||||
let isIncomplete = false;
|
||||
let typeErrors = false;
|
||||
|
||||
const constExprValue = evaluateStaticBoolExpression(
|
||||
node.testExpression,
|
||||
node.d.testExpression,
|
||||
fileInfo.executionEnvironment,
|
||||
fileInfo.definedConstants
|
||||
);
|
||||
|
||||
if (constExprValue !== false && evaluator.isNodeReachable(node.ifExpression)) {
|
||||
const ifType = evaluator.getTypeOfExpression(node.ifExpression, flags, inferenceContext);
|
||||
if (constExprValue !== false && evaluator.isNodeReachable(node.d.ifExpression)) {
|
||||
const ifType = evaluator.getTypeOfExpression(node.d.ifExpression, flags, inferenceContext);
|
||||
typesToCombine.push(ifType.type);
|
||||
if (ifType.isIncomplete) {
|
||||
isIncomplete = true;
|
||||
@ -1118,8 +1118,8 @@ export function getTypeOfTernaryOperation(
|
||||
}
|
||||
}
|
||||
|
||||
if (constExprValue !== true && evaluator.isNodeReachable(node.elseExpression)) {
|
||||
const elseType = evaluator.getTypeOfExpression(node.elseExpression, flags, inferenceContext);
|
||||
if (constExprValue !== true && evaluator.isNodeReachable(node.d.elseExpression)) {
|
||||
const elseType = evaluator.getTypeOfExpression(node.d.elseExpression, flags, inferenceContext);
|
||||
typesToCombine.push(elseType.type);
|
||||
if (elseType.isIncomplete) {
|
||||
isIncomplete = true;
|
||||
@ -1183,7 +1183,7 @@ function isExpressionLocalVariable(evaluator: TypeEvaluator, node: ExpressionNod
|
||||
return false;
|
||||
}
|
||||
|
||||
const symbolWithScope = evaluator.lookUpSymbolRecursive(node, node.value, /* honorCodeFlow */ false);
|
||||
const symbolWithScope = evaluator.lookUpSymbolRecursive(node, node.d.value, /* honorCodeFlow */ false);
|
||||
if (!symbolWithScope) {
|
||||
return false;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -96,49 +96,49 @@ import {
|
||||
export function getChildNodes(node: ParseNode): (ParseNode | undefined)[] {
|
||||
switch (node.nodeType) {
|
||||
case ParseNodeType.Error:
|
||||
return [node.child, ...(node.decorators ?? [])];
|
||||
return [node.d.child, ...(node.d.decorators ?? [])];
|
||||
|
||||
case ParseNodeType.Argument:
|
||||
return [node.name, node.valueExpression];
|
||||
return [node.d.name, node.d.valueExpression];
|
||||
|
||||
case ParseNodeType.Assert:
|
||||
return [node.testExpression, node.exceptionExpression];
|
||||
return [node.d.testExpression, node.d.exceptionExpression];
|
||||
|
||||
case ParseNodeType.AssignmentExpression:
|
||||
return [node.name, node.rightExpression];
|
||||
return [node.d.name, node.d.rightExpression];
|
||||
|
||||
case ParseNodeType.Assignment:
|
||||
return [node.leftExpression, node.rightExpression, node.typeAnnotationComment];
|
||||
return [node.d.leftExpression, node.d.rightExpression, node.d.typeAnnotationComment];
|
||||
|
||||
case ParseNodeType.AugmentedAssignment:
|
||||
return [node.leftExpression, node.rightExpression];
|
||||
return [node.d.leftExpression, node.d.rightExpression];
|
||||
|
||||
case ParseNodeType.Await:
|
||||
return [node.expression];
|
||||
return [node.d.expression];
|
||||
|
||||
case ParseNodeType.BinaryOperation:
|
||||
return [node.leftExpression, node.rightExpression];
|
||||
return [node.d.leftExpression, node.d.rightExpression];
|
||||
|
||||
case ParseNodeType.Break:
|
||||
return [];
|
||||
|
||||
case ParseNodeType.Call:
|
||||
return [node.leftExpression, ...node.arguments];
|
||||
return [node.d.leftExpression, ...node.d.arguments];
|
||||
|
||||
case ParseNodeType.Case:
|
||||
return [node.pattern, node.guardExpression, node.suite];
|
||||
return [node.d.pattern, node.d.guardExpression, node.d.suite];
|
||||
|
||||
case ParseNodeType.Class:
|
||||
return [...node.decorators, node.name, node.typeParameters, ...node.arguments, node.suite];
|
||||
return [...node.d.decorators, node.d.name, node.d.typeParameters, ...node.d.arguments, node.d.suite];
|
||||
|
||||
case ParseNodeType.Comprehension:
|
||||
return [node.expression, ...node.forIfNodes];
|
||||
return [node.d.expression, ...node.d.forIfNodes];
|
||||
|
||||
case ParseNodeType.ComprehensionFor:
|
||||
return [node.targetExpression, node.iterableExpression];
|
||||
return [node.d.targetExpression, node.d.iterableExpression];
|
||||
|
||||
case ParseNodeType.ComprehensionIf:
|
||||
return [node.testExpression];
|
||||
return [node.d.testExpression];
|
||||
|
||||
case ParseNodeType.Constant:
|
||||
return [];
|
||||
@ -147,195 +147,195 @@ export function getChildNodes(node: ParseNode): (ParseNode | undefined)[] {
|
||||
return [];
|
||||
|
||||
case ParseNodeType.Decorator:
|
||||
return [node.expression];
|
||||
return [node.d.expression];
|
||||
|
||||
case ParseNodeType.Del:
|
||||
return node.expressions;
|
||||
return node.d.expressions;
|
||||
|
||||
case ParseNodeType.Dictionary:
|
||||
return node.entries;
|
||||
return node.d.entries;
|
||||
|
||||
case ParseNodeType.DictionaryExpandEntry:
|
||||
return [node.expandExpression];
|
||||
return [node.d.expandExpression];
|
||||
|
||||
case ParseNodeType.DictionaryKeyEntry:
|
||||
return [node.keyExpression, node.valueExpression];
|
||||
return [node.d.keyExpression, node.d.valueExpression];
|
||||
|
||||
case ParseNodeType.Ellipsis:
|
||||
return [];
|
||||
|
||||
case ParseNodeType.If:
|
||||
return [node.testExpression, node.ifSuite, node.elseSuite];
|
||||
return [node.d.testExpression, node.d.ifSuite, node.d.elseSuite];
|
||||
|
||||
case ParseNodeType.Import:
|
||||
return node.list;
|
||||
return node.d.list;
|
||||
|
||||
case ParseNodeType.ImportAs:
|
||||
return [node.module, node.alias];
|
||||
return [node.d.module, node.d.alias];
|
||||
|
||||
case ParseNodeType.ImportFrom:
|
||||
return [node.module, ...node.imports];
|
||||
return [node.d.module, ...node.d.imports];
|
||||
|
||||
case ParseNodeType.ImportFromAs:
|
||||
return [node.name, node.alias];
|
||||
return [node.d.name, node.d.alias];
|
||||
|
||||
case ParseNodeType.Index:
|
||||
return [node.baseExpression, ...node.items];
|
||||
return [node.d.baseExpression, ...node.d.items];
|
||||
|
||||
case ParseNodeType.Except:
|
||||
return [node.typeExpression, node.name, node.exceptSuite];
|
||||
return [node.d.typeExpression, node.d.name, node.d.exceptSuite];
|
||||
|
||||
case ParseNodeType.For:
|
||||
return [node.targetExpression, node.iterableExpression, node.forSuite, node.elseSuite];
|
||||
return [node.d.targetExpression, node.d.iterableExpression, node.d.forSuite, node.d.elseSuite];
|
||||
|
||||
case ParseNodeType.FormatString:
|
||||
return [...node.fieldExpressions, ...(node.formatExpressions ?? [])];
|
||||
return [...node.d.fieldExpressions, ...(node.d.formatExpressions ?? [])];
|
||||
|
||||
case ParseNodeType.Function:
|
||||
return [
|
||||
...node.decorators,
|
||||
node.name,
|
||||
node.typeParameters,
|
||||
...node.parameters,
|
||||
node.returnTypeAnnotation,
|
||||
node.functionAnnotationComment,
|
||||
node.suite,
|
||||
...node.d.decorators,
|
||||
node.d.name,
|
||||
node.d.typeParameters,
|
||||
...node.d.parameters,
|
||||
node.d.returnTypeAnnotation,
|
||||
node.d.functionAnnotationComment,
|
||||
node.d.suite,
|
||||
];
|
||||
|
||||
case ParseNodeType.FunctionAnnotation:
|
||||
return [...node.paramTypeAnnotations, node.returnTypeAnnotation];
|
||||
return [...node.d.paramTypeAnnotations, node.d.returnTypeAnnotation];
|
||||
|
||||
case ParseNodeType.Global:
|
||||
return node.nameList;
|
||||
return node.d.nameList;
|
||||
|
||||
case ParseNodeType.Lambda:
|
||||
return [...node.parameters, node.expression];
|
||||
return [...node.d.parameters, node.d.expression];
|
||||
|
||||
case ParseNodeType.List:
|
||||
return node.entries;
|
||||
return node.d.entries;
|
||||
|
||||
case ParseNodeType.Match:
|
||||
return [node.subjectExpression, ...node.cases];
|
||||
return [node.d.subjectExpression, ...node.d.cases];
|
||||
|
||||
case ParseNodeType.MemberAccess:
|
||||
return [node.leftExpression, node.memberName];
|
||||
return [node.d.leftExpression, node.d.memberName];
|
||||
|
||||
case ParseNodeType.ModuleName:
|
||||
return node.nameParts;
|
||||
return node.d.nameParts;
|
||||
|
||||
case ParseNodeType.Module:
|
||||
return [...node.statements];
|
||||
return [...node.d.statements];
|
||||
|
||||
case ParseNodeType.Name:
|
||||
return [];
|
||||
|
||||
case ParseNodeType.Nonlocal:
|
||||
return node.nameList;
|
||||
return node.d.nameList;
|
||||
|
||||
case ParseNodeType.Number:
|
||||
return [];
|
||||
|
||||
case ParseNodeType.Parameter:
|
||||
return [node.name, node.typeAnnotation, node.typeAnnotationComment, node.defaultValue];
|
||||
return [node.d.name, node.d.typeAnnotation, node.d.typeAnnotationComment, node.d.defaultValue];
|
||||
|
||||
case ParseNodeType.Pass:
|
||||
return [];
|
||||
|
||||
case ParseNodeType.PatternAs:
|
||||
return [...node.orPatterns, node.target];
|
||||
return [...node.d.orPatterns, node.d.target];
|
||||
|
||||
case ParseNodeType.PatternClass:
|
||||
return [node.className, ...node.arguments];
|
||||
return [node.d.className, ...node.d.arguments];
|
||||
|
||||
case ParseNodeType.PatternClassArgument:
|
||||
return [node.name, node.pattern];
|
||||
return [node.d.name, node.d.pattern];
|
||||
|
||||
case ParseNodeType.PatternCapture:
|
||||
return [node.target];
|
||||
return [node.d.target];
|
||||
|
||||
case ParseNodeType.PatternLiteral:
|
||||
return [node.expression];
|
||||
return [node.d.expression];
|
||||
|
||||
case ParseNodeType.PatternMappingExpandEntry:
|
||||
return [node.target];
|
||||
return [node.d.target];
|
||||
|
||||
case ParseNodeType.PatternMappingKeyEntry:
|
||||
return [node.keyPattern, node.valuePattern];
|
||||
return [node.d.keyPattern, node.d.valuePattern];
|
||||
|
||||
case ParseNodeType.PatternMapping:
|
||||
return [...node.entries];
|
||||
return [...node.d.entries];
|
||||
|
||||
case ParseNodeType.PatternSequence:
|
||||
return [...node.entries];
|
||||
return [...node.d.entries];
|
||||
|
||||
case ParseNodeType.PatternValue:
|
||||
return [node.expression];
|
||||
return [node.d.expression];
|
||||
|
||||
case ParseNodeType.Raise:
|
||||
return [node.typeExpression, node.valueExpression, node.tracebackExpression];
|
||||
return [node.d.typeExpression, node.d.valueExpression, node.d.tracebackExpression];
|
||||
|
||||
case ParseNodeType.Return:
|
||||
return [node.returnExpression];
|
||||
return [node.d.returnExpression];
|
||||
|
||||
case ParseNodeType.Set:
|
||||
return node.entries;
|
||||
return node.d.entries;
|
||||
|
||||
case ParseNodeType.Slice:
|
||||
return [node.startValue, node.endValue, node.stepValue];
|
||||
return [node.d.startValue, node.d.endValue, node.d.stepValue];
|
||||
|
||||
case ParseNodeType.StatementList:
|
||||
return node.statements;
|
||||
return node.d.statements;
|
||||
|
||||
case ParseNodeType.StringList:
|
||||
return [node.typeAnnotation, ...node.strings];
|
||||
return [node.d.typeAnnotation, ...node.d.strings];
|
||||
|
||||
case ParseNodeType.String:
|
||||
return [];
|
||||
|
||||
case ParseNodeType.Suite:
|
||||
return [...node.statements];
|
||||
return [...node.d.statements];
|
||||
|
||||
case ParseNodeType.Ternary:
|
||||
return [node.ifExpression, node.testExpression, node.elseExpression];
|
||||
return [node.d.ifExpression, node.d.testExpression, node.d.elseExpression];
|
||||
|
||||
case ParseNodeType.Tuple:
|
||||
return node.expressions;
|
||||
return node.d.expressions;
|
||||
|
||||
case ParseNodeType.Try:
|
||||
return [node.trySuite, ...node.exceptClauses, node.elseSuite, node.finallySuite];
|
||||
return [node.d.trySuite, ...node.d.exceptClauses, node.d.elseSuite, node.d.finallySuite];
|
||||
|
||||
case ParseNodeType.TypeAlias:
|
||||
return [node.name, node.typeParameters, node.expression];
|
||||
return [node.d.name, node.d.typeParameters, node.d.expression];
|
||||
|
||||
case ParseNodeType.TypeAnnotation:
|
||||
return [node.valueExpression, node.typeAnnotation];
|
||||
return [node.d.valueExpression, node.d.typeAnnotation];
|
||||
|
||||
case ParseNodeType.TypeParameter:
|
||||
return [node.name, node.boundExpression, node.defaultExpression];
|
||||
return [node.d.name, node.d.boundExpression, node.d.defaultExpression];
|
||||
|
||||
case ParseNodeType.TypeParameterList:
|
||||
return [...node.parameters];
|
||||
return [...node.d.parameters];
|
||||
|
||||
case ParseNodeType.UnaryOperation:
|
||||
return [node.expression];
|
||||
return [node.d.expression];
|
||||
|
||||
case ParseNodeType.Unpack:
|
||||
return [node.expression];
|
||||
return [node.d.expression];
|
||||
|
||||
case ParseNodeType.While:
|
||||
return [node.testExpression, node.whileSuite, node.elseSuite];
|
||||
return [node.d.testExpression, node.d.whileSuite, node.d.elseSuite];
|
||||
|
||||
case ParseNodeType.With:
|
||||
return [...node.withItems, node.suite];
|
||||
return [...node.d.withItems, node.d.suite];
|
||||
|
||||
case ParseNodeType.WithItem:
|
||||
return [node.expression, node.target];
|
||||
return [node.d.expression, node.d.target];
|
||||
|
||||
case ParseNodeType.Yield:
|
||||
return [node.expression];
|
||||
return [node.d.expression];
|
||||
|
||||
case ParseNodeType.YieldFrom:
|
||||
return [node.expression];
|
||||
return [node.d.expression];
|
||||
|
||||
default:
|
||||
debug.assertNever(node, `Unknown node type ${node}`);
|
||||
|
@ -172,9 +172,9 @@ export function narrowTypeBasedOnPattern(
|
||||
export function checkForUnusedPattern(evaluator: TypeEvaluator, pattern: PatternAtomNode, subjectType: Type): void {
|
||||
if (isNever(subjectType)) {
|
||||
reportUnnecessaryPattern(evaluator, pattern, subjectType);
|
||||
} else if (pattern.nodeType === ParseNodeType.PatternAs && pattern.orPatterns.length > 1) {
|
||||
} else if (pattern.nodeType === ParseNodeType.PatternAs && pattern.d.orPatterns.length > 1) {
|
||||
// Check each of the or patterns separately.
|
||||
pattern.orPatterns.forEach((orPattern) => {
|
||||
pattern.d.orPatterns.forEach((orPattern) => {
|
||||
const subjectTypeMatch = narrowTypeBasedOnPattern(
|
||||
evaluator,
|
||||
subjectType,
|
||||
@ -238,7 +238,7 @@ function narrowTypeBasedOnSequencePattern(
|
||||
// If the pattern includes a "star" entry that aligns exactly with
|
||||
// the corresponding unbounded entry in the tuple, we can narrow
|
||||
// the tuple type.
|
||||
if (pattern.starEntryIndex === undefined || pattern.starEntryIndex !== unboundedIndex) {
|
||||
if (pattern.d.starEntryIndex === undefined || pattern.d.starEntryIndex !== unboundedIndex) {
|
||||
canNarrowTuple = false;
|
||||
}
|
||||
}
|
||||
@ -249,27 +249,27 @@ function narrowTypeBasedOnSequencePattern(
|
||||
// an arbitrary number of entries or accepts at least one non-star entry,
|
||||
// we can't prove that it's a definite match.
|
||||
if (entry.isIndeterminateLength) {
|
||||
if (pattern.entries.length !== 1 || pattern.starEntryIndex !== 0) {
|
||||
if (pattern.d.entries.length !== 1 || pattern.d.starEntryIndex !== 0) {
|
||||
isDefiniteMatch = false;
|
||||
}
|
||||
}
|
||||
|
||||
let negativeEntriesNarrowed = 0;
|
||||
pattern.entries.forEach((sequenceEntry, index) => {
|
||||
pattern.d.entries.forEach((sequenceEntry, index) => {
|
||||
const entryType = getTypeOfPatternSequenceEntry(
|
||||
evaluator,
|
||||
pattern,
|
||||
entry,
|
||||
index,
|
||||
pattern.entries.length,
|
||||
pattern.starEntryIndex,
|
||||
pattern.d.entries.length,
|
||||
pattern.d.starEntryIndex,
|
||||
/* unpackStarEntry */ true
|
||||
);
|
||||
|
||||
const narrowedEntryType = narrowTypeBasedOnPattern(evaluator, entryType, sequenceEntry, isPositiveTest);
|
||||
|
||||
if (isPositiveTest) {
|
||||
if (index === pattern.starEntryIndex) {
|
||||
if (index === pattern.d.starEntryIndex) {
|
||||
if (
|
||||
isClassInstance(narrowedEntryType) &&
|
||||
narrowedEntryType.priv.tupleTypeArguments &&
|
||||
@ -308,13 +308,13 @@ function narrowTypeBasedOnSequencePattern(
|
||||
narrowedEntryTypes.push(entryType);
|
||||
}
|
||||
|
||||
if (index === pattern.starEntryIndex) {
|
||||
if (index === pattern.d.starEntryIndex) {
|
||||
canNarrowTuple = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (pattern.entries.length === 0) {
|
||||
if (pattern.d.entries.length === 0) {
|
||||
// If the pattern is an empty sequence, use the entry types.
|
||||
if (entry.entryTypes.length > 0) {
|
||||
narrowedEntryTypes.push(combineTypes(entry.entryTypes));
|
||||
@ -400,13 +400,13 @@ function narrowTypeBasedOnAsPattern(
|
||||
let remainingType = type;
|
||||
|
||||
if (!isPositiveTest) {
|
||||
pattern.orPatterns.forEach((subpattern) => {
|
||||
pattern.d.orPatterns.forEach((subpattern) => {
|
||||
remainingType = narrowTypeBasedOnPattern(evaluator, remainingType, subpattern, /* isPositiveTest */ false);
|
||||
});
|
||||
return remainingType;
|
||||
}
|
||||
|
||||
const narrowedTypes = pattern.orPatterns.map((subpattern) => {
|
||||
const narrowedTypes = pattern.d.orPatterns.map((subpattern) => {
|
||||
const narrowedSubtype = narrowTypeBasedOnPattern(
|
||||
evaluator,
|
||||
remainingType,
|
||||
@ -429,28 +429,31 @@ function narrowTypeBasedOnMappingPattern(
|
||||
|
||||
if (!isPositiveTest) {
|
||||
// Handle the case where the pattern consists only of a "**x" entry.
|
||||
if (pattern.entries.length === 1 && pattern.entries[0].nodeType === ParseNodeType.PatternMappingExpandEntry) {
|
||||
if (
|
||||
pattern.d.entries.length === 1 &&
|
||||
pattern.d.entries[0].nodeType === ParseNodeType.PatternMappingExpandEntry
|
||||
) {
|
||||
const mappingInfo = getMappingPatternInfo(evaluator, type, pattern);
|
||||
return combineTypes(mappingInfo.filter((m) => !m.isDefinitelyMapping).map((m) => m.subtype));
|
||||
}
|
||||
|
||||
if (pattern.entries.length !== 1 || pattern.entries[0].nodeType !== ParseNodeType.PatternMappingKeyEntry) {
|
||||
if (pattern.d.entries.length !== 1 || pattern.d.entries[0].nodeType !== ParseNodeType.PatternMappingKeyEntry) {
|
||||
return type;
|
||||
}
|
||||
|
||||
// Handle the case where the type is a union that includes a TypedDict with
|
||||
// a field discriminated by a literal.
|
||||
const keyPattern = pattern.entries[0].keyPattern;
|
||||
const valuePattern = pattern.entries[0].valuePattern;
|
||||
const keyPattern = pattern.d.entries[0].d.keyPattern;
|
||||
const valuePattern = pattern.d.entries[0].d.valuePattern;
|
||||
if (
|
||||
keyPattern.nodeType !== ParseNodeType.PatternLiteral ||
|
||||
valuePattern.nodeType !== ParseNodeType.PatternAs ||
|
||||
!valuePattern.orPatterns.every((orPattern) => orPattern.nodeType === ParseNodeType.PatternLiteral)
|
||||
!valuePattern.d.orPatterns.every((orPattern) => orPattern.nodeType === ParseNodeType.PatternLiteral)
|
||||
) {
|
||||
return type;
|
||||
}
|
||||
|
||||
const keyType = evaluator.getTypeOfExpression(keyPattern.expression).type;
|
||||
const keyType = evaluator.getTypeOfExpression(keyPattern.d.expression).type;
|
||||
|
||||
// The key type must be a str literal.
|
||||
if (
|
||||
@ -462,8 +465,8 @@ function narrowTypeBasedOnMappingPattern(
|
||||
}
|
||||
const keyValue = keyType.priv.literalValue as string;
|
||||
|
||||
const valueTypes = valuePattern.orPatterns.map(
|
||||
(orPattern) => evaluator.getTypeOfExpression((orPattern as PatternLiteralNode).expression).type
|
||||
const valueTypes = valuePattern.d.orPatterns.map(
|
||||
(orPattern) => evaluator.getTypeOfExpression((orPattern as PatternLiteralNode).d.expression).type
|
||||
);
|
||||
|
||||
return mapSubtypes(type, (subtype) => {
|
||||
@ -503,13 +506,13 @@ function narrowTypeBasedOnMappingPattern(
|
||||
|
||||
let isPlausibleMatch = true;
|
||||
|
||||
pattern.entries.forEach((mappingEntry) => {
|
||||
pattern.d.entries.forEach((mappingEntry) => {
|
||||
if (mappingSubtypeInfo.typedDict) {
|
||||
if (mappingEntry.nodeType === ParseNodeType.PatternMappingKeyEntry) {
|
||||
const narrowedKeyType = narrowTypeBasedOnPattern(
|
||||
evaluator,
|
||||
evaluator.getBuiltInObject(pattern, 'str'),
|
||||
mappingEntry.keyPattern,
|
||||
mappingEntry.d.keyPattern,
|
||||
isPositiveTest
|
||||
);
|
||||
|
||||
@ -533,7 +536,7 @@ function narrowTypeBasedOnMappingPattern(
|
||||
const narrowedValueType = narrowTypeBasedOnPattern(
|
||||
evaluator,
|
||||
valueEntry.valueType,
|
||||
mappingEntry.valuePattern,
|
||||
mappingEntry.d.valuePattern,
|
||||
/* isPositiveTest */ true
|
||||
);
|
||||
if (!isNever(narrowedValueType)) {
|
||||
@ -581,13 +584,13 @@ function narrowTypeBasedOnMappingPattern(
|
||||
const narrowedKeyType = narrowTypeBasedOnPattern(
|
||||
evaluator,
|
||||
mappingSubtypeInfo.dictTypeArgs.key,
|
||||
mappingEntry.keyPattern,
|
||||
mappingEntry.d.keyPattern,
|
||||
isPositiveTest
|
||||
);
|
||||
const narrowedValueType = narrowTypeBasedOnPattern(
|
||||
evaluator,
|
||||
mappingSubtypeInfo.dictTypeArgs.value,
|
||||
mappingEntry.valuePattern,
|
||||
mappingEntry.d.valuePattern,
|
||||
isPositiveTest
|
||||
);
|
||||
if (isNever(narrowedKeyType) || isNever(narrowedValueType)) {
|
||||
@ -638,7 +641,7 @@ function narrowTypeBasedOnLiteralPattern(
|
||||
pattern: PatternLiteralNode,
|
||||
isPositiveTest: boolean
|
||||
): Type {
|
||||
const literalType = evaluator.getTypeOfExpression(pattern.expression).type;
|
||||
const literalType = evaluator.getTypeOfExpression(pattern.d.expression).type;
|
||||
|
||||
if (!isPositiveTest) {
|
||||
return evaluator.mapSubtypesExpandTypeVars(
|
||||
@ -703,7 +706,7 @@ function narrowTypeBasedOnClassPattern(
|
||||
pattern: PatternClassNode,
|
||||
isPositiveTest: boolean
|
||||
): Type {
|
||||
let exprType = evaluator.getTypeOfExpression(pattern.className, EvalFlags.CallBaseDefaults).type;
|
||||
let exprType = evaluator.getTypeOfExpression(pattern.d.className, EvalFlags.CallBaseDefaults).type;
|
||||
|
||||
// If this is a class (but not a type alias that refers to a class),
|
||||
// specialize it with Unknown type arguments.
|
||||
@ -715,7 +718,7 @@ function narrowTypeBasedOnClassPattern(
|
||||
// Are there any positional arguments? If so, try to get the mappings for
|
||||
// these arguments by fetching the __match_args__ symbol from the class.
|
||||
let positionalArgNames: string[] = [];
|
||||
if (pattern.arguments.some((arg) => !arg.name) && isInstantiableClass(exprType)) {
|
||||
if (pattern.d.arguments.some((arg) => !arg.d.name) && isInstantiableClass(exprType)) {
|
||||
positionalArgNames = getPositionalMatchArgNames(evaluator, exprType);
|
||||
}
|
||||
|
||||
@ -783,7 +786,7 @@ function narrowTypeBasedOnClassPattern(
|
||||
return subjectSubtypeExpanded;
|
||||
}
|
||||
|
||||
if (pattern.arguments.length === 0) {
|
||||
if (pattern.d.arguments.length === 0) {
|
||||
if (isClass(classInstance) && isClass(subjectSubtypeExpanded)) {
|
||||
// We know that this match will always succeed, so we can
|
||||
// eliminate this subtype.
|
||||
@ -807,10 +810,10 @@ function narrowTypeBasedOnClassPattern(
|
||||
}
|
||||
}
|
||||
|
||||
for (let index = 0; index < pattern.arguments.length; index++) {
|
||||
for (let index = 0; index < pattern.d.arguments.length; index++) {
|
||||
const narrowedArgType = narrowTypeOfClassPatternArgument(
|
||||
evaluator,
|
||||
pattern.arguments[index],
|
||||
pattern.d.arguments[index],
|
||||
index,
|
||||
positionalArgNames,
|
||||
subjectSubtypeExpanded,
|
||||
@ -832,7 +835,7 @@ function narrowTypeBasedOnClassPattern(
|
||||
evaluator.addDiagnostic(
|
||||
DiagnosticRule.reportGeneralTypeIssues,
|
||||
LocAddendum.typeNotClass().format({ type: evaluator.printType(exprType) }),
|
||||
pattern.className
|
||||
pattern.d.className
|
||||
);
|
||||
return NeverType.createNever();
|
||||
} else if (
|
||||
@ -843,7 +846,7 @@ function narrowTypeBasedOnClassPattern(
|
||||
evaluator.addDiagnostic(
|
||||
DiagnosticRule.reportGeneralTypeIssues,
|
||||
LocAddendum.protocolRequiresRuntimeCheckable(),
|
||||
pattern.className
|
||||
pattern.d.className
|
||||
);
|
||||
}
|
||||
|
||||
@ -968,12 +971,12 @@ function narrowTypeBasedOnClassPattern(
|
||||
// Are there any positional arguments? If so, try to get the mappings for
|
||||
// these arguments by fetching the __match_args__ symbol from the class.
|
||||
let positionalArgNames: string[] = [];
|
||||
if (pattern.arguments.some((arg) => !arg.name)) {
|
||||
if (pattern.d.arguments.some((arg) => !arg.d.name)) {
|
||||
positionalArgNames = getPositionalMatchArgNames(evaluator, expandedSubtype);
|
||||
}
|
||||
|
||||
let isMatchValid = true;
|
||||
pattern.arguments.forEach((arg, index) => {
|
||||
pattern.d.arguments.forEach((arg, index) => {
|
||||
// Narrow the arg pattern. It's possible that the actual type of the object
|
||||
// being matched is a subtype of the resultType, so it might contain additional
|
||||
// attributes that we don't know about.
|
||||
@ -1039,8 +1042,8 @@ function narrowTypeOfClassPatternArgument(
|
||||
) {
|
||||
let argName: string | undefined;
|
||||
|
||||
if (arg.name) {
|
||||
argName = arg.name.value;
|
||||
if (arg.d.name) {
|
||||
argName = arg.d.name.d.value;
|
||||
} else if (argIndex < positionalArgNames.length) {
|
||||
argName = positionalArgNames[argIndex];
|
||||
}
|
||||
@ -1060,7 +1063,7 @@ function narrowTypeOfClassPatternArgument(
|
||||
let useSelfForPattern = false;
|
||||
let selfForPatternType = matchType;
|
||||
|
||||
if (!arg.name && isClass(matchType) && argIndex === 0) {
|
||||
if (!arg.d.name && isClass(matchType) && argIndex === 0) {
|
||||
if (isClassSpecialCaseForClassPattern(matchType)) {
|
||||
useSelfForPattern = true;
|
||||
} else if (positionalArgNames.length === 0) {
|
||||
@ -1106,7 +1109,7 @@ function narrowTypeOfClassPatternArgument(
|
||||
}
|
||||
}
|
||||
|
||||
return narrowTypeBasedOnPattern(evaluator, argType, arg.pattern, isPositiveTest);
|
||||
return narrowTypeBasedOnPattern(evaluator, argType, arg.d.pattern, isPositiveTest);
|
||||
}
|
||||
|
||||
function narrowTypeBasedOnValuePattern(
|
||||
@ -1115,7 +1118,7 @@ function narrowTypeBasedOnValuePattern(
|
||||
pattern: PatternValueNode,
|
||||
isPositiveTest: boolean
|
||||
): Type {
|
||||
const valueType = evaluator.getTypeOfExpression(pattern.expression).type;
|
||||
const valueType = evaluator.getTypeOfExpression(pattern.d.expression).type;
|
||||
const narrowedSubtypes: Type[] = [];
|
||||
|
||||
evaluator.mapSubtypesExpandTypeVars(
|
||||
@ -1182,12 +1185,12 @@ function narrowTypeBasedOnValuePattern(
|
||||
|
||||
// Determine if assignment is supported for this combination of
|
||||
// value subtype and matching subtype.
|
||||
const returnType = evaluator.useSpeculativeMode(pattern.expression, () =>
|
||||
const returnType = evaluator.useSpeculativeMode(pattern.d.expression, () =>
|
||||
evaluator.getTypeOfMagicMethodCall(
|
||||
valueSubtypeExpanded,
|
||||
'__eq__',
|
||||
[{ type: subjectSubtypeExpanded }],
|
||||
pattern.expression,
|
||||
pattern.d.expression,
|
||||
/* expectedType */ undefined
|
||||
)
|
||||
);
|
||||
@ -1300,8 +1303,8 @@ function getSequencePatternInfo(
|
||||
pattern: PatternSequenceNode,
|
||||
type: Type
|
||||
): SequencePatternInfo[] {
|
||||
const patternEntryCount = pattern.entries.length;
|
||||
const patternStarEntryIndex = pattern.starEntryIndex;
|
||||
const patternEntryCount = pattern.d.entries.length;
|
||||
const patternStarEntryIndex = pattern.d.starEntryIndex;
|
||||
const sequenceInfo: SequencePatternInfo[] = [];
|
||||
|
||||
doForEachSubtype(type, (subtype) => {
|
||||
@ -1397,14 +1400,14 @@ function getSequencePatternInfo(
|
||||
if (
|
||||
patternStarEntryIndex !== undefined &&
|
||||
tupleIndeterminateIndex >= 0 &&
|
||||
pattern.entries.length - 1 === tupleDeterminateEntryCount &&
|
||||
pattern.d.entries.length - 1 === tupleDeterminateEntryCount &&
|
||||
patternStarEntryIndex === tupleIndeterminateIndex
|
||||
) {
|
||||
isPotentialNoMatch = false;
|
||||
}
|
||||
|
||||
for (let i = 0; i < patternEntryCount; i++) {
|
||||
const subPattern = pattern.entries[i];
|
||||
const subPattern = pattern.d.entries[i];
|
||||
const typeArg = typeArgs[i].type;
|
||||
const narrowedType = narrowTypeBasedOnPattern(
|
||||
evaluator,
|
||||
@ -1456,7 +1459,7 @@ function getSequencePatternInfo(
|
||||
continue;
|
||||
}
|
||||
|
||||
const subPattern = pattern.entries[i];
|
||||
const subPattern = pattern.d.entries[i];
|
||||
const typeArg = typeArgs[i].type;
|
||||
const narrowedType = narrowTypeBasedOnPattern(
|
||||
evaluator,
|
||||
@ -1637,7 +1640,7 @@ export function assignTypeToPatternTargets(
|
||||
(seqInfo) => !seqInfo.isDefiniteNoMatch
|
||||
);
|
||||
|
||||
pattern.entries.forEach((entry, index) => {
|
||||
pattern.d.entries.forEach((entry, index) => {
|
||||
const entryType = combineTypes(
|
||||
sequenceInfo.map((info) =>
|
||||
getTypeOfPatternSequenceEntry(
|
||||
@ -1645,8 +1648,8 @@ export function assignTypeToPatternTargets(
|
||||
pattern,
|
||||
info,
|
||||
index,
|
||||
pattern.entries.length,
|
||||
pattern.starEntryIndex,
|
||||
pattern.d.entries.length,
|
||||
pattern.d.starEntryIndex,
|
||||
/* unpackStarEntry */ false
|
||||
)
|
||||
)
|
||||
@ -1658,16 +1661,16 @@ export function assignTypeToPatternTargets(
|
||||
}
|
||||
|
||||
case ParseNodeType.PatternAs: {
|
||||
if (pattern.target) {
|
||||
if (pattern.d.target) {
|
||||
evaluator.assignTypeToExpression(
|
||||
pattern.target,
|
||||
pattern.d.target,
|
||||
{ type: narrowedType, isIncomplete: isTypeIncomplete },
|
||||
pattern.target
|
||||
pattern.d.target
|
||||
);
|
||||
}
|
||||
|
||||
let runningNarrowedType = narrowedType;
|
||||
pattern.orPatterns.forEach((orPattern) => {
|
||||
pattern.d.orPatterns.forEach((orPattern) => {
|
||||
assignTypeToPatternTargets(evaluator, runningNarrowedType, isTypeIncomplete, orPattern);
|
||||
|
||||
// OR patterns are evaluated left to right, so we can narrow
|
||||
@ -1683,13 +1686,13 @@ export function assignTypeToPatternTargets(
|
||||
}
|
||||
|
||||
case ParseNodeType.PatternCapture: {
|
||||
if (pattern.isWildcard) {
|
||||
if (pattern.d.isWildcard) {
|
||||
if (!isTypeIncomplete) {
|
||||
if (isUnknown(narrowedType)) {
|
||||
evaluator.addDiagnostic(
|
||||
DiagnosticRule.reportUnknownVariableType,
|
||||
LocMessage.wildcardPatternTypeUnknown(),
|
||||
pattern.target
|
||||
pattern.d.target
|
||||
);
|
||||
} else if (isPartlyUnknown(narrowedType)) {
|
||||
const diagAddendum = new DiagnosticAddendum();
|
||||
@ -1702,15 +1705,15 @@ export function assignTypeToPatternTargets(
|
||||
evaluator.addDiagnostic(
|
||||
DiagnosticRule.reportUnknownVariableType,
|
||||
LocMessage.wildcardPatternTypePartiallyUnknown() + diagAddendum.getString(),
|
||||
pattern.target
|
||||
pattern.d.target
|
||||
);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
evaluator.assignTypeToExpression(
|
||||
pattern.target,
|
||||
pattern.d.target,
|
||||
{ type: narrowedType, isIncomplete: isTypeIncomplete },
|
||||
pattern.target
|
||||
pattern.d.target
|
||||
);
|
||||
}
|
||||
break;
|
||||
@ -1719,7 +1722,7 @@ export function assignTypeToPatternTargets(
|
||||
case ParseNodeType.PatternMapping: {
|
||||
const mappingInfo = getMappingPatternInfo(evaluator, narrowedType, pattern);
|
||||
|
||||
pattern.entries.forEach((mappingEntry) => {
|
||||
pattern.d.entries.forEach((mappingEntry) => {
|
||||
const keyTypes: Type[] = [];
|
||||
const valueTypes: Type[] = [];
|
||||
|
||||
@ -1729,7 +1732,7 @@ export function assignTypeToPatternTargets(
|
||||
const keyType = narrowTypeBasedOnPattern(
|
||||
evaluator,
|
||||
evaluator.getBuiltInObject(pattern, 'str'),
|
||||
mappingEntry.keyPattern,
|
||||
mappingEntry.d.keyPattern,
|
||||
/* isPositiveTest */ true
|
||||
);
|
||||
keyTypes.push(keyType);
|
||||
@ -1759,7 +1762,7 @@ export function assignTypeToPatternTargets(
|
||||
const keyType = narrowTypeBasedOnPattern(
|
||||
evaluator,
|
||||
mappingSubtypeInfo.dictTypeArgs.key,
|
||||
mappingEntry.keyPattern,
|
||||
mappingEntry.d.keyPattern,
|
||||
/* isPositiveTest */ true
|
||||
);
|
||||
keyTypes.push(keyType);
|
||||
@ -1767,7 +1770,7 @@ export function assignTypeToPatternTargets(
|
||||
narrowTypeBasedOnPattern(
|
||||
evaluator,
|
||||
mappingSubtypeInfo.dictTypeArgs.value,
|
||||
mappingEntry.valuePattern,
|
||||
mappingEntry.d.valuePattern,
|
||||
/* isPositiveTest */ true
|
||||
)
|
||||
);
|
||||
@ -1782,8 +1785,8 @@ export function assignTypeToPatternTargets(
|
||||
const valueType = combineTypes(valueTypes);
|
||||
|
||||
if (mappingEntry.nodeType === ParseNodeType.PatternMappingKeyEntry) {
|
||||
assignTypeToPatternTargets(evaluator, keyType, isTypeIncomplete, mappingEntry.keyPattern);
|
||||
assignTypeToPatternTargets(evaluator, valueType, isTypeIncomplete, mappingEntry.valuePattern);
|
||||
assignTypeToPatternTargets(evaluator, keyType, isTypeIncomplete, mappingEntry.d.keyPattern);
|
||||
assignTypeToPatternTargets(evaluator, valueType, isTypeIncomplete, mappingEntry.d.valuePattern);
|
||||
} else if (mappingEntry.nodeType === ParseNodeType.PatternMappingExpandEntry) {
|
||||
const dictClass = evaluator.getBuiltInType(pattern, 'dict');
|
||||
const strType = evaluator.getBuiltInObject(pattern, 'str');
|
||||
@ -1798,9 +1801,9 @@ export function assignTypeToPatternTargets(
|
||||
)
|
||||
: UnknownType.create();
|
||||
evaluator.assignTypeToExpression(
|
||||
mappingEntry.target,
|
||||
mappingEntry.d.target,
|
||||
{ type: dictType, isIncomplete: isTypeIncomplete },
|
||||
mappingEntry.target
|
||||
mappingEntry.d.target
|
||||
);
|
||||
}
|
||||
});
|
||||
@ -1808,7 +1811,7 @@ export function assignTypeToPatternTargets(
|
||||
}
|
||||
|
||||
case ParseNodeType.PatternClass: {
|
||||
const argTypes: Type[][] = pattern.arguments.map((arg) => []);
|
||||
const argTypes: Type[][] = pattern.d.arguments.map((arg) => []);
|
||||
|
||||
evaluator.mapSubtypesExpandTypeVars(narrowedType, /* options */ undefined, (expandedSubtype) => {
|
||||
if (isClassInstance(expandedSubtype)) {
|
||||
@ -1816,21 +1819,21 @@ export function assignTypeToPatternTargets(
|
||||
const concreteSubtype = evaluator.makeTopLevelTypeVarsConcrete(subjectSubtype);
|
||||
|
||||
if (isAnyOrUnknown(concreteSubtype)) {
|
||||
pattern.arguments.forEach((arg, index) => {
|
||||
pattern.d.arguments.forEach((arg, index) => {
|
||||
argTypes[index].push(concreteSubtype);
|
||||
});
|
||||
} else if (isClassInstance(concreteSubtype)) {
|
||||
// Are there any positional arguments? If so, try to get the mappings for
|
||||
// these arguments by fetching the __match_args__ symbol from the class.
|
||||
let positionalArgNames: string[] = [];
|
||||
if (pattern.arguments.some((arg) => !arg.name)) {
|
||||
if (pattern.d.arguments.some((arg) => !arg.d.name)) {
|
||||
positionalArgNames = getPositionalMatchArgNames(
|
||||
evaluator,
|
||||
ClassType.cloneAsInstantiable(expandedSubtype)
|
||||
);
|
||||
}
|
||||
|
||||
pattern.arguments.forEach((arg, index) => {
|
||||
pattern.d.arguments.forEach((arg, index) => {
|
||||
const narrowedArgType = narrowTypeOfClassPatternArgument(
|
||||
evaluator,
|
||||
arg,
|
||||
@ -1844,7 +1847,7 @@ export function assignTypeToPatternTargets(
|
||||
}
|
||||
});
|
||||
} else {
|
||||
pattern.arguments.forEach((arg, index) => {
|
||||
pattern.d.arguments.forEach((arg, index) => {
|
||||
argTypes[index].push(UnknownType.create());
|
||||
});
|
||||
}
|
||||
@ -1852,8 +1855,8 @@ export function assignTypeToPatternTargets(
|
||||
return undefined;
|
||||
});
|
||||
|
||||
pattern.arguments.forEach((arg, index) => {
|
||||
assignTypeToPatternTargets(evaluator, combineTypes(argTypes[index]), isTypeIncomplete, arg.pattern);
|
||||
pattern.d.arguments.forEach((arg, index) => {
|
||||
assignTypeToPatternTargets(evaluator, combineTypes(argTypes[index]), isTypeIncomplete, arg.d.pattern);
|
||||
});
|
||||
break;
|
||||
}
|
||||
@ -1887,7 +1890,7 @@ function wrapTypeInList(evaluator: TypeEvaluator, node: ParseNode, type: Type):
|
||||
}
|
||||
|
||||
export function validateClassPattern(evaluator: TypeEvaluator, pattern: PatternClassNode) {
|
||||
let exprType = evaluator.getTypeOfExpression(pattern.className, EvalFlags.CallBaseDefaults).type;
|
||||
let exprType = evaluator.getTypeOfExpression(pattern.d.className, EvalFlags.CallBaseDefaults).type;
|
||||
|
||||
// If the expression is a type alias or other special form, treat it
|
||||
// as the special form rather than the class.
|
||||
@ -1909,14 +1912,14 @@ export function validateClassPattern(evaluator: TypeEvaluator, pattern: PatternC
|
||||
evaluator.addDiagnostic(
|
||||
DiagnosticRule.reportGeneralTypeIssues,
|
||||
LocMessage.classPatternTypeAlias().format({ type: evaluator.printType(exprType) }),
|
||||
pattern.className
|
||||
pattern.d.className
|
||||
);
|
||||
} else if (!isInstantiableClass(exprType)) {
|
||||
if (!isNever(exprType)) {
|
||||
evaluator.addDiagnostic(
|
||||
DiagnosticRule.reportGeneralTypeIssues,
|
||||
LocAddendum.typeNotClass().format({ type: evaluator.printType(exprType) }),
|
||||
pattern.className
|
||||
pattern.d.className
|
||||
);
|
||||
}
|
||||
} else {
|
||||
@ -1924,26 +1927,26 @@ export function validateClassPattern(evaluator: TypeEvaluator, pattern: PatternC
|
||||
|
||||
// If it's a special-case builtin class, only positional arguments are allowed.
|
||||
if (isBuiltIn) {
|
||||
if (pattern.arguments.length === 1 && pattern.arguments[0].name) {
|
||||
if (pattern.d.arguments.length === 1 && pattern.d.arguments[0].d.name) {
|
||||
evaluator.addDiagnostic(
|
||||
DiagnosticRule.reportGeneralTypeIssues,
|
||||
LocMessage.classPatternBuiltInArgPositional(),
|
||||
pattern.arguments[0].name
|
||||
pattern.d.arguments[0].d.name
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Emits an error if the supplied number of positional patterns is less than
|
||||
// expected for the given subject type.
|
||||
let positionalPatternCount = pattern.arguments.findIndex((arg) => arg.name !== undefined);
|
||||
let positionalPatternCount = pattern.d.arguments.findIndex((arg) => arg.d.name !== undefined);
|
||||
if (positionalPatternCount < 0) {
|
||||
positionalPatternCount = pattern.arguments.length;
|
||||
positionalPatternCount = pattern.d.arguments.length;
|
||||
}
|
||||
|
||||
let expectedPatternCount = 1;
|
||||
if (!isBuiltIn) {
|
||||
let positionalArgNames: string[] = [];
|
||||
if (pattern.arguments.some((arg) => !arg.name)) {
|
||||
if (pattern.d.arguments.some((arg) => !arg.d.name)) {
|
||||
positionalArgNames = getPositionalMatchArgNames(evaluator, exprType);
|
||||
}
|
||||
|
||||
@ -1958,7 +1961,7 @@ export function validateClassPattern(evaluator: TypeEvaluator, pattern: PatternC
|
||||
expected: expectedPatternCount,
|
||||
received: positionalPatternCount,
|
||||
}),
|
||||
pattern.arguments[expectedPatternCount]
|
||||
pattern.d.arguments[expectedPatternCount]
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -1977,18 +1980,18 @@ export function getPatternSubtypeNarrowingCallback(
|
||||
// (for tuple discrimination).
|
||||
if (
|
||||
subjectExpression.nodeType === ParseNodeType.Index &&
|
||||
subjectExpression.items.length === 1 &&
|
||||
!subjectExpression.trailingComma &&
|
||||
subjectExpression.items[0].argumentCategory === ArgumentCategory.Simple &&
|
||||
isMatchingExpression(reference, subjectExpression.baseExpression)
|
||||
subjectExpression.d.items.length === 1 &&
|
||||
!subjectExpression.d.trailingComma &&
|
||||
subjectExpression.d.items[0].d.argumentCategory === ArgumentCategory.Simple &&
|
||||
isMatchingExpression(reference, subjectExpression.d.baseExpression)
|
||||
) {
|
||||
const indexTypeResult = evaluator.getTypeOfExpression(subjectExpression.items[0].valueExpression);
|
||||
const indexTypeResult = evaluator.getTypeOfExpression(subjectExpression.d.items[0].d.valueExpression);
|
||||
const indexType = indexTypeResult.type;
|
||||
|
||||
if (isClassInstance(indexType) && isLiteralType(indexType)) {
|
||||
if (ClassType.isBuiltIn(indexType, ['int', 'str'])) {
|
||||
const unnarrowedReferenceTypeResult = evaluator.getTypeOfExpression(
|
||||
subjectExpression.baseExpression,
|
||||
subjectExpression.d.baseExpression,
|
||||
EvalFlags.CallBaseDefaults
|
||||
);
|
||||
const unnarrowedReferenceType = unnarrowedReferenceTypeResult.type;
|
||||
@ -2044,11 +2047,11 @@ export function getPatternSubtypeNarrowingCallback(
|
||||
// Look for a subject expression that contains the reference
|
||||
// expression as an entry in a tuple.
|
||||
if (subjectExpression.nodeType === ParseNodeType.Tuple) {
|
||||
const matchingEntryIndex = subjectExpression.expressions.findIndex((expr) =>
|
||||
const matchingEntryIndex = subjectExpression.d.expressions.findIndex((expr) =>
|
||||
isMatchingExpression(reference, expr)
|
||||
);
|
||||
if (matchingEntryIndex >= 0) {
|
||||
const typeResult = evaluator.getTypeOfExpression(subjectExpression.expressions[matchingEntryIndex]);
|
||||
const typeResult = evaluator.getTypeOfExpression(subjectExpression.d.expressions[matchingEntryIndex]);
|
||||
|
||||
return (narrowedSubjectType: Type) => {
|
||||
let canNarrow = true;
|
||||
@ -2081,10 +2084,10 @@ export function getPatternSubtypeNarrowingCallback(
|
||||
// that is annotated with a literal type.
|
||||
if (
|
||||
subjectExpression.nodeType === ParseNodeType.MemberAccess &&
|
||||
isMatchingExpression(reference, subjectExpression.leftExpression)
|
||||
isMatchingExpression(reference, subjectExpression.d.leftExpression)
|
||||
) {
|
||||
const unnarrowedReferenceTypeResult = evaluator.getTypeOfExpression(
|
||||
subjectExpression.leftExpression,
|
||||
subjectExpression.d.leftExpression,
|
||||
EvalFlags.CallBaseDefaults
|
||||
);
|
||||
const unnarrowedReferenceType = unnarrowedReferenceTypeResult.type;
|
||||
@ -2104,7 +2107,7 @@ export function getPatternSubtypeNarrowingCallback(
|
||||
return narrowTypeForDiscriminatedLiteralFieldComparison(
|
||||
evaluator,
|
||||
unnarrowedReferenceType,
|
||||
subjectExpression.memberName.value,
|
||||
subjectExpression.d.memberName.d.value,
|
||||
literalSubtype,
|
||||
/* isPositiveTest */ true
|
||||
);
|
||||
|
@ -1861,7 +1861,7 @@ export class Program {
|
||||
dunderAllNames: dunderAllInfo?.names,
|
||||
usesUnsupportedDunderAllForm: dunderAllInfo?.usesUnsupportedDunderAllForm ?? false,
|
||||
get docString() {
|
||||
return getDocString(moduleNode.statements);
|
||||
return getDocString(moduleNode.d.statements);
|
||||
},
|
||||
isInPyTypedPackage: fileInfo.isInPyTypedPackage,
|
||||
};
|
||||
|
@ -134,7 +134,7 @@ export function clonePropertyWithSetter(
|
||||
// We'll skip this test if the diagnostic rule is disabled because it
|
||||
// can be somewhat expensive, especially in code that is not annotated.
|
||||
const fileInfo = getFileInfo(errorNode);
|
||||
if (errorNode.parameters.length >= 2) {
|
||||
if (errorNode.d.parameters.length >= 2) {
|
||||
const typeAnnotation = getTypeAnnotationForParameter(errorNode, 1);
|
||||
if (typeAnnotation) {
|
||||
// Verify consistency of the type.
|
||||
|
@ -1397,7 +1397,7 @@ export class SourceFile {
|
||||
// Associate the import results with the module import
|
||||
// name node in the parse tree so we can access it later
|
||||
// (for hover and definition support).
|
||||
if (moduleImport.nameParts.length === moduleImport.nameNode.nameParts.length) {
|
||||
if (moduleImport.nameParts.length === moduleImport.nameNode.d.nameParts.length) {
|
||||
AnalyzerNodeInfo.setImportInfo(moduleImport.nameNode, importResult);
|
||||
} else {
|
||||
// For implicit imports of higher-level modules within a multi-part
|
||||
@ -1405,9 +1405,9 @@ export class SourceFile {
|
||||
// of the multi-part name rather than the full multi-part name. In this
|
||||
// case, store the import info on the name part node.
|
||||
assert(moduleImport.nameParts.length > 0);
|
||||
assert(moduleImport.nameParts.length - 1 < moduleImport.nameNode.nameParts.length);
|
||||
assert(moduleImport.nameParts.length - 1 < moduleImport.nameNode.d.nameParts.length);
|
||||
AnalyzerNodeInfo.setImportInfo(
|
||||
moduleImport.nameNode.nameParts[moduleImport.nameParts.length - 1],
|
||||
moduleImport.nameNode.d.nameParts[moduleImport.nameParts.length - 1],
|
||||
importResult
|
||||
);
|
||||
}
|
||||
|
@ -130,8 +130,8 @@ export class SourceMapper {
|
||||
stubDecl: SpecialBuiltInClassDeclaration,
|
||||
recursiveDeclCache = new Set<string>()
|
||||
) {
|
||||
if (stubDecl.node.valueExpression.nodeType === ParseNodeType.Name) {
|
||||
const className = stubDecl.node.valueExpression.value;
|
||||
if (stubDecl.node.d.valueExpression.nodeType === ParseNodeType.Name) {
|
||||
const className = stubDecl.node.d.valueExpression.d.value;
|
||||
const sourceFiles = this._getBoundSourceFilesFromStubFile(stubDecl.uri);
|
||||
|
||||
return sourceFiles.flatMap((sourceFile) =>
|
||||
@ -155,7 +155,7 @@ export class SourceMapper {
|
||||
stubDecl: FunctionDeclaration,
|
||||
recursiveDeclCache = new Set<string>()
|
||||
): ClassOrFunctionOrVariableDeclaration[] {
|
||||
const functionName = stubDecl.node.name.value;
|
||||
const functionName = stubDecl.node.d.name.d.value;
|
||||
const sourceFiles = this._getBoundSourceFilesFromStubFile(stubDecl.uri);
|
||||
|
||||
if (stubDecl.isMethod) {
|
||||
@ -183,7 +183,7 @@ export class SourceMapper {
|
||||
return [];
|
||||
}
|
||||
|
||||
const variableName = stubDecl.node.value;
|
||||
const variableName = stubDecl.node.d.value;
|
||||
const sourceFiles = this._getBoundSourceFilesFromStubFile(stubDecl.uri);
|
||||
const classNode = ParseTreeUtils.getEnclosingClass(stubDecl.node);
|
||||
|
||||
@ -203,7 +203,7 @@ export class SourceMapper {
|
||||
private _findParameterDeclarations(stubDecl: ParameterDeclaration): ParameterDeclaration[] {
|
||||
const result: ParameterDeclaration[] = [];
|
||||
|
||||
if (!stubDecl.node.name) {
|
||||
if (!stubDecl.node.d.name) {
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -212,7 +212,7 @@ export class SourceMapper {
|
||||
return result;
|
||||
}
|
||||
|
||||
const functionStubDecls = this._evaluator.getDeclarationsForNameNode(functionNode.name);
|
||||
const functionStubDecls = this._evaluator.getDeclarationsForNameNode(functionNode.d.name);
|
||||
if (!functionStubDecls) {
|
||||
return result;
|
||||
}
|
||||
@ -225,7 +225,7 @@ export class SourceMapper {
|
||||
)) {
|
||||
appendArray(
|
||||
result,
|
||||
this._lookUpSymbolDeclarations(functionDecl.node, stubDecl.node.name.value)
|
||||
this._lookUpSymbolDeclarations(functionDecl.node, stubDecl.node.d.name.d.value)
|
||||
.filter((d) => isParameterDeclaration(d))
|
||||
.map((d) => d as ParameterDeclaration)
|
||||
);
|
||||
@ -565,7 +565,7 @@ export class SourceMapper {
|
||||
// from runtime if we provide right synthesized stub path.
|
||||
const fakeStubPath = stdLibPath.combinePaths(
|
||||
getModuleName()
|
||||
.nameParts.map((n) => n.value)
|
||||
.d.nameParts.map((n) => n.d.value)
|
||||
.join('.') + '.pyi'
|
||||
);
|
||||
|
||||
@ -582,11 +582,11 @@ export class SourceMapper {
|
||||
function getModuleName() {
|
||||
switch (decl.node.nodeType) {
|
||||
case ParseNodeType.ImportAs:
|
||||
return decl.node.module;
|
||||
return decl.node.d.module;
|
||||
case ParseNodeType.ImportFromAs:
|
||||
return (decl.node.parent as ImportFromNode).module;
|
||||
return (decl.node.parent as ImportFromNode).d.module;
|
||||
case ParseNodeType.ImportFrom:
|
||||
return decl.node.module;
|
||||
return decl.node.d.module;
|
||||
default:
|
||||
return assertNever(decl.node);
|
||||
}
|
||||
@ -650,7 +650,7 @@ export class SourceMapper {
|
||||
!isAliasDeclaration(decl) ||
|
||||
decl.uri.isEmpty() ||
|
||||
decl.node.nodeType !== ParseNodeType.ImportFrom ||
|
||||
!decl.node.isWildcardImport
|
||||
!decl.node.d.isWildcardImport
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
@ -724,7 +724,7 @@ export class SourceMapper {
|
||||
|
||||
let current: ClassNode | undefined = node;
|
||||
while (current !== undefined) {
|
||||
fullName.push(current.name.value);
|
||||
fullName.push(current.d.name.d.value);
|
||||
current = ParseTreeUtils.getEnclosingClass(current);
|
||||
}
|
||||
|
||||
|
@ -24,7 +24,7 @@ export function evaluateStaticBoolExpression(
|
||||
): boolean | undefined {
|
||||
if (node.nodeType === ParseNodeType.AssignmentExpression) {
|
||||
return evaluateStaticBoolExpression(
|
||||
node.rightExpression,
|
||||
node.d.rightExpression,
|
||||
execEnv,
|
||||
definedConstants,
|
||||
typingImportAliases,
|
||||
@ -33,9 +33,9 @@ export function evaluateStaticBoolExpression(
|
||||
}
|
||||
|
||||
if (node.nodeType === ParseNodeType.UnaryOperation) {
|
||||
if (node.operator === OperatorType.Not) {
|
||||
if (node.d.operator === OperatorType.Not) {
|
||||
const value = evaluateStaticBoolLikeExpression(
|
||||
node.expression,
|
||||
node.d.expression,
|
||||
execEnv,
|
||||
definedConstants,
|
||||
typingImportAliases,
|
||||
@ -47,16 +47,16 @@ export function evaluateStaticBoolExpression(
|
||||
}
|
||||
} else if (node.nodeType === ParseNodeType.BinaryOperation) {
|
||||
// Is it an OR or AND expression?
|
||||
if (node.operator === OperatorType.Or || node.operator === OperatorType.And) {
|
||||
if (node.d.operator === OperatorType.Or || node.d.operator === OperatorType.And) {
|
||||
const leftValue = evaluateStaticBoolExpression(
|
||||
node.leftExpression,
|
||||
node.d.leftExpression,
|
||||
execEnv,
|
||||
definedConstants,
|
||||
typingImportAliases,
|
||||
sysImportAliases
|
||||
);
|
||||
const rightValue = evaluateStaticBoolExpression(
|
||||
node.rightExpression,
|
||||
node.d.rightExpression,
|
||||
execEnv,
|
||||
definedConstants,
|
||||
typingImportAliases,
|
||||
@ -67,7 +67,7 @@ export function evaluateStaticBoolExpression(
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (node.operator === OperatorType.Or) {
|
||||
if (node.d.operator === OperatorType.Or) {
|
||||
return leftValue || rightValue;
|
||||
} else {
|
||||
return leftValue && rightValue;
|
||||
@ -75,99 +75,99 @@ export function evaluateStaticBoolExpression(
|
||||
}
|
||||
|
||||
if (
|
||||
_isSysVersionInfoExpression(node.leftExpression, sysImportAliases) &&
|
||||
node.rightExpression.nodeType === ParseNodeType.Tuple
|
||||
_isSysVersionInfoExpression(node.d.leftExpression, sysImportAliases) &&
|
||||
node.d.rightExpression.nodeType === ParseNodeType.Tuple
|
||||
) {
|
||||
// Handle the special case of "sys.version_info >= (3, x)"
|
||||
const comparisonVersion = _convertTupleToVersion(node.rightExpression);
|
||||
return _evaluateVersionBinaryOperation(node.operator, execEnv.pythonVersion, comparisonVersion);
|
||||
const comparisonVersion = _convertTupleToVersion(node.d.rightExpression);
|
||||
return _evaluateVersionBinaryOperation(node.d.operator, execEnv.pythonVersion, comparisonVersion);
|
||||
}
|
||||
|
||||
if (
|
||||
node.leftExpression.nodeType === ParseNodeType.Index &&
|
||||
_isSysVersionInfoExpression(node.leftExpression.baseExpression, sysImportAliases) &&
|
||||
node.leftExpression.items.length === 1 &&
|
||||
!node.leftExpression.trailingComma &&
|
||||
!node.leftExpression.items[0].name &&
|
||||
node.leftExpression.items[0].argumentCategory === ArgumentCategory.Simple &&
|
||||
node.leftExpression.items[0].valueExpression.nodeType === ParseNodeType.Number &&
|
||||
!node.leftExpression.items[0].valueExpression.isImaginary &&
|
||||
node.leftExpression.items[0].valueExpression.value === 0 &&
|
||||
node.rightExpression.nodeType === ParseNodeType.Number &&
|
||||
node.rightExpression.isInteger &&
|
||||
typeof node.rightExpression.value === 'number'
|
||||
node.d.leftExpression.nodeType === ParseNodeType.Index &&
|
||||
_isSysVersionInfoExpression(node.d.leftExpression.d.baseExpression, sysImportAliases) &&
|
||||
node.d.leftExpression.d.items.length === 1 &&
|
||||
!node.d.leftExpression.d.trailingComma &&
|
||||
!node.d.leftExpression.d.items[0].d.name &&
|
||||
node.d.leftExpression.d.items[0].d.argumentCategory === ArgumentCategory.Simple &&
|
||||
node.d.leftExpression.d.items[0].d.valueExpression.nodeType === ParseNodeType.Number &&
|
||||
!node.d.leftExpression.d.items[0].d.valueExpression.d.isImaginary &&
|
||||
node.d.leftExpression.d.items[0].d.valueExpression.d.value === 0 &&
|
||||
node.d.rightExpression.nodeType === ParseNodeType.Number &&
|
||||
node.d.rightExpression.d.isInteger &&
|
||||
typeof node.d.rightExpression.d.value === 'number'
|
||||
) {
|
||||
// Handle the special case of "sys.version_info[0] >= X"
|
||||
return _evaluateVersionBinaryOperation(
|
||||
node.operator,
|
||||
node.d.operator,
|
||||
new PythonVersion(execEnv.pythonVersion.major, 0),
|
||||
new PythonVersion(node.rightExpression.value, 0)
|
||||
new PythonVersion(node.d.rightExpression.d.value, 0)
|
||||
);
|
||||
}
|
||||
|
||||
if (
|
||||
_isSysPlatformInfoExpression(node.leftExpression, sysImportAliases) &&
|
||||
node.rightExpression.nodeType === ParseNodeType.StringList
|
||||
_isSysPlatformInfoExpression(node.d.leftExpression, sysImportAliases) &&
|
||||
node.d.rightExpression.nodeType === ParseNodeType.StringList
|
||||
) {
|
||||
// Handle the special case of "sys.platform != 'X'"
|
||||
const comparisonPlatform = node.rightExpression.strings.map((s) => s.value).join('');
|
||||
const comparisonPlatform = node.d.rightExpression.d.strings.map((s) => s.d.value).join('');
|
||||
const expectedPlatformName = _getExpectedPlatformNameFromPlatform(execEnv);
|
||||
return _evaluateStringBinaryOperation(node.operator, expectedPlatformName, comparisonPlatform);
|
||||
return _evaluateStringBinaryOperation(node.d.operator, expectedPlatformName, comparisonPlatform);
|
||||
}
|
||||
|
||||
if (
|
||||
_isOsNameInfoExpression(node.leftExpression) &&
|
||||
node.rightExpression.nodeType === ParseNodeType.StringList
|
||||
_isOsNameInfoExpression(node.d.leftExpression) &&
|
||||
node.d.rightExpression.nodeType === ParseNodeType.StringList
|
||||
) {
|
||||
// Handle the special case of "os.name == 'X'"
|
||||
const comparisonOsName = node.rightExpression.strings.map((s) => s.value).join('');
|
||||
const comparisonOsName = node.d.rightExpression.d.strings.map((s) => s.d.value).join('');
|
||||
const expectedOsName = _getExpectedOsNameFromPlatform(execEnv);
|
||||
if (expectedOsName !== undefined) {
|
||||
return _evaluateStringBinaryOperation(node.operator, expectedOsName, comparisonOsName);
|
||||
return _evaluateStringBinaryOperation(node.d.operator, expectedOsName, comparisonOsName);
|
||||
}
|
||||
} else {
|
||||
// Handle the special case of <definedConstant> == 'X' or <definedConstant> != 'X'.
|
||||
if (node.rightExpression.nodeType === ParseNodeType.StringList) {
|
||||
if (node.d.rightExpression.nodeType === ParseNodeType.StringList) {
|
||||
let constantValue: string | number | boolean | undefined;
|
||||
|
||||
if (node.leftExpression.nodeType === ParseNodeType.Name) {
|
||||
constantValue = definedConstants.get(node.leftExpression.value);
|
||||
} else if (node.leftExpression.nodeType === ParseNodeType.MemberAccess) {
|
||||
constantValue = definedConstants.get(node.leftExpression.memberName.value);
|
||||
if (node.d.leftExpression.nodeType === ParseNodeType.Name) {
|
||||
constantValue = definedConstants.get(node.d.leftExpression.d.value);
|
||||
} else if (node.d.leftExpression.nodeType === ParseNodeType.MemberAccess) {
|
||||
constantValue = definedConstants.get(node.d.leftExpression.d.memberName.d.value);
|
||||
}
|
||||
|
||||
if (constantValue !== undefined && typeof constantValue === 'string') {
|
||||
const comparisonStringName = node.rightExpression.strings.map((s) => s.value).join('');
|
||||
return _evaluateStringBinaryOperation(node.operator, constantValue, comparisonStringName);
|
||||
const comparisonStringName = node.d.rightExpression.d.strings.map((s) => s.d.value).join('');
|
||||
return _evaluateStringBinaryOperation(node.d.operator, constantValue, comparisonStringName);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (node.nodeType === ParseNodeType.Constant) {
|
||||
if (node.constType === KeywordType.True) {
|
||||
if (node.d.constType === KeywordType.True) {
|
||||
return true;
|
||||
} else if (node.constType === KeywordType.False) {
|
||||
} else if (node.d.constType === KeywordType.False) {
|
||||
return false;
|
||||
}
|
||||
} else if (node.nodeType === ParseNodeType.Name) {
|
||||
if (node.value === 'TYPE_CHECKING') {
|
||||
if (node.d.value === 'TYPE_CHECKING') {
|
||||
return true;
|
||||
}
|
||||
|
||||
const constant = definedConstants.get(node.value);
|
||||
const constant = definedConstants.get(node.d.value);
|
||||
if (constant !== undefined) {
|
||||
return !!constant;
|
||||
}
|
||||
} else if (node.nodeType === ParseNodeType.MemberAccess) {
|
||||
if (
|
||||
typingImportAliases &&
|
||||
node.memberName.value === 'TYPE_CHECKING' &&
|
||||
node.leftExpression.nodeType === ParseNodeType.Name &&
|
||||
typingImportAliases.some((alias) => alias === (node.leftExpression as NameNode).value)
|
||||
node.d.memberName.d.value === 'TYPE_CHECKING' &&
|
||||
node.d.leftExpression.nodeType === ParseNodeType.Name &&
|
||||
typingImportAliases.some((alias) => alias === (node.d.leftExpression as NameNode).d.value)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const constant = definedConstants.get(node.memberName.value);
|
||||
const constant = definedConstants.get(node.d.memberName.d.value);
|
||||
if (constant !== undefined) {
|
||||
return !!constant;
|
||||
}
|
||||
@ -187,7 +187,7 @@ export function evaluateStaticBoolLikeExpression(
|
||||
sysImportAliases?: string[]
|
||||
): boolean | undefined {
|
||||
if (node.nodeType === ParseNodeType.Constant) {
|
||||
if (node.constType === KeywordType.None) {
|
||||
if (node.d.constType === KeywordType.None) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -196,57 +196,57 @@ export function evaluateStaticBoolLikeExpression(
|
||||
}
|
||||
|
||||
function _convertTupleToVersion(node: TupleNode): PythonVersion | undefined {
|
||||
if (node.expressions.length >= 2) {
|
||||
if (node.d.expressions.length >= 2) {
|
||||
if (
|
||||
node.expressions[0].nodeType === ParseNodeType.Number &&
|
||||
!node.expressions[0].isImaginary &&
|
||||
node.expressions[1].nodeType === ParseNodeType.Number &&
|
||||
!node.expressions[1].isImaginary
|
||||
node.d.expressions[0].nodeType === ParseNodeType.Number &&
|
||||
!node.d.expressions[0].d.isImaginary &&
|
||||
node.d.expressions[1].nodeType === ParseNodeType.Number &&
|
||||
!node.d.expressions[1].d.isImaginary
|
||||
) {
|
||||
const majorNode = node.expressions[0];
|
||||
const minorNode = node.expressions[1];
|
||||
if (typeof majorNode.value !== 'number' || typeof minorNode.value !== 'number') {
|
||||
const majorNode = node.d.expressions[0];
|
||||
const minorNode = node.d.expressions[1];
|
||||
if (typeof majorNode.d.value !== 'number' || typeof minorNode.d.value !== 'number') {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const major = majorNode.value;
|
||||
const minor = minorNode.value;
|
||||
const major = majorNode.d.value;
|
||||
const minor = minorNode.d.value;
|
||||
let micro: number | undefined;
|
||||
if (
|
||||
node.expressions.length >= 3 &&
|
||||
node.expressions[2].nodeType === ParseNodeType.Number &&
|
||||
!node.expressions[2].isImaginary &&
|
||||
typeof node.expressions[2].value === 'number'
|
||||
node.d.expressions.length >= 3 &&
|
||||
node.d.expressions[2].nodeType === ParseNodeType.Number &&
|
||||
!node.d.expressions[2].d.isImaginary &&
|
||||
typeof node.d.expressions[2].d.value === 'number'
|
||||
) {
|
||||
micro = node.expressions[2].value;
|
||||
micro = node.d.expressions[2].d.value;
|
||||
}
|
||||
|
||||
let releaseLevel: PythonReleaseLevel | undefined;
|
||||
if (
|
||||
node.expressions.length >= 4 &&
|
||||
node.expressions[3].nodeType === ParseNodeType.StringList &&
|
||||
node.expressions[3].strings.length === 1 &&
|
||||
node.expressions[3].strings[0].nodeType === ParseNodeType.String
|
||||
node.d.expressions.length >= 4 &&
|
||||
node.d.expressions[3].nodeType === ParseNodeType.StringList &&
|
||||
node.d.expressions[3].d.strings.length === 1 &&
|
||||
node.d.expressions[3].d.strings[0].nodeType === ParseNodeType.String
|
||||
) {
|
||||
releaseLevel = node.expressions[3].strings[0].value as PythonReleaseLevel;
|
||||
releaseLevel = node.d.expressions[3].d.strings[0].d.value as PythonReleaseLevel;
|
||||
}
|
||||
|
||||
let serial: number | undefined;
|
||||
if (
|
||||
node.expressions.length >= 5 &&
|
||||
node.expressions[4].nodeType === ParseNodeType.Number &&
|
||||
!node.expressions[4].isImaginary &&
|
||||
typeof node.expressions[4].value === 'number'
|
||||
node.d.expressions.length >= 5 &&
|
||||
node.d.expressions[4].nodeType === ParseNodeType.Number &&
|
||||
!node.d.expressions[4].d.isImaginary &&
|
||||
typeof node.d.expressions[4].d.value === 'number'
|
||||
) {
|
||||
serial = node.expressions[4].value;
|
||||
serial = node.d.expressions[4].d.value;
|
||||
}
|
||||
|
||||
return new PythonVersion(major, minor, micro, releaseLevel, serial);
|
||||
}
|
||||
} else if (node.expressions.length === 1) {
|
||||
const major = node.expressions[0] as NumberNode;
|
||||
if (typeof major.value === 'number') {
|
||||
return new PythonVersion(major.value, 0);
|
||||
} else if (node.d.expressions.length === 1) {
|
||||
const major = node.d.expressions[0] as NumberNode;
|
||||
if (typeof major.d.value === 'number') {
|
||||
return new PythonVersion(major.d.value, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -305,8 +305,8 @@ function _evaluateStringBinaryOperation(
|
||||
|
||||
function _isSysVersionInfoExpression(node: ExpressionNode, sysImportAliases: string[] = ['sys']): boolean {
|
||||
if (node.nodeType === ParseNodeType.MemberAccess) {
|
||||
if (node.leftExpression.nodeType === ParseNodeType.Name && node.memberName.value === 'version_info') {
|
||||
if (sysImportAliases.some((alias) => alias === (node.leftExpression as NameNode).value)) {
|
||||
if (node.d.leftExpression.nodeType === ParseNodeType.Name && node.d.memberName.d.value === 'version_info') {
|
||||
if (sysImportAliases.some((alias) => alias === (node.d.leftExpression as NameNode).d.value)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -317,8 +317,8 @@ function _isSysVersionInfoExpression(node: ExpressionNode, sysImportAliases: str
|
||||
|
||||
function _isSysPlatformInfoExpression(node: ExpressionNode, sysImportAliases: string[] = ['sys']): boolean {
|
||||
if (node.nodeType === ParseNodeType.MemberAccess) {
|
||||
if (node.leftExpression.nodeType === ParseNodeType.Name && node.memberName.value === 'platform') {
|
||||
if (sysImportAliases.some((alias) => alias === (node.leftExpression as NameNode).value)) {
|
||||
if (node.d.leftExpression.nodeType === ParseNodeType.Name && node.d.memberName.d.value === 'platform') {
|
||||
if (sysImportAliases.some((alias) => alias === (node.d.leftExpression as NameNode).d.value)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -330,9 +330,9 @@ function _isSysPlatformInfoExpression(node: ExpressionNode, sysImportAliases: st
|
||||
function _isOsNameInfoExpression(node: ExpressionNode): boolean {
|
||||
if (node.nodeType === ParseNodeType.MemberAccess) {
|
||||
if (
|
||||
node.leftExpression.nodeType === ParseNodeType.Name &&
|
||||
node.leftExpression.value === 'os' &&
|
||||
node.memberName.value === 'name'
|
||||
node.d.leftExpression.nodeType === ParseNodeType.Name &&
|
||||
node.d.leftExpression.d.value === 'os' &&
|
||||
node.d.memberName.d.value === 'name'
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
@ -57,7 +57,7 @@ export class TestWalker extends ParseTreeWalker {
|
||||
case ParseNodeType.Assignment:
|
||||
// There are a few exceptions we need to deal with here. Comment
|
||||
// annotations can occur outside of an assignment node's range.
|
||||
if (child === node.typeAnnotationComment) {
|
||||
if (child === node.d.typeAnnotationComment) {
|
||||
skipCheck = true;
|
||||
}
|
||||
|
||||
@ -69,7 +69,7 @@ export class TestWalker extends ParseTreeWalker {
|
||||
break;
|
||||
|
||||
case ParseNodeType.StringList:
|
||||
if (child === node.typeAnnotation) {
|
||||
if (child === node.d.typeAnnotation) {
|
||||
skipCheck = true;
|
||||
}
|
||||
break;
|
||||
|
@ -186,33 +186,35 @@ export function createTracePrinter(roots: Uri[]): TracePrinter {
|
||||
|
||||
switch (node.nodeType) {
|
||||
case ParseNodeType.ImportAs:
|
||||
return `importAs '${printNode(node.module)}' ${wrap(node.alias ? printNode(node.alias) : '')} ${path}`;
|
||||
return `importAs '${printNode(node.d.module)}' ${wrap(
|
||||
node.d.alias ? printNode(node.d.alias) : ''
|
||||
)} ${path}`;
|
||||
|
||||
case ParseNodeType.ImportFrom:
|
||||
return `importFrom [${node.imports.map((i) => wrap(printNode(i), '"')).join(',')}]`;
|
||||
return `importFrom [${node.d.imports.map((i) => wrap(printNode(i), '"')).join(',')}]`;
|
||||
|
||||
case ParseNodeType.ImportFromAs:
|
||||
return `ImportFromAs '${printNode(node.name)}' ${wrap(
|
||||
node.alias ? printNode(node.alias) : ''
|
||||
return `ImportFromAs '${printNode(node.d.name)}' ${wrap(
|
||||
node.d.alias ? printNode(node.d.alias) : ''
|
||||
)} ${path}`;
|
||||
|
||||
case ParseNodeType.Module:
|
||||
return `module ${path}`;
|
||||
|
||||
case ParseNodeType.Class:
|
||||
return `class '${printNode(node.name)}' ${path}`;
|
||||
return `class '${printNode(node.d.name)}' ${path}`;
|
||||
|
||||
case ParseNodeType.Function:
|
||||
return `function '${printNode(node.name)}' ${path}`;
|
||||
return `function '${printNode(node.d.name)}' ${path}`;
|
||||
|
||||
case ParseNodeType.ModuleName:
|
||||
return `moduleName '${node.nameParts.map((n) => printNode(n)).join('.')}' ${path}`;
|
||||
return `moduleName '${node.d.nameParts.map((n) => printNode(n)).join('.')}' ${path}`;
|
||||
|
||||
case ParseNodeType.Argument:
|
||||
return `argument '${node.name ? printNode(node.name) : 'N/A'}' ${path}`;
|
||||
return `argument '${node.d.name ? printNode(node.d.name) : 'N/A'}' ${path}`;
|
||||
|
||||
case ParseNodeType.Parameter:
|
||||
return `parameter '${node.name ? printNode(node.name) : 'N/A'}' ${path}`;
|
||||
return `parameter '${node.d.name ? printNode(node.d.name) : 'N/A'}' ${path}`;
|
||||
|
||||
default:
|
||||
return `${ParseTreeUtils.printParseNodeType(node.nodeType)} ${path}`;
|
||||
|
@ -152,7 +152,7 @@ export function getPropertyDocStringInherited(
|
||||
sourceMapper: SourceMapper,
|
||||
evaluator: TypeEvaluator
|
||||
) {
|
||||
const enclosingClass = ParseTreeUtils.getEnclosingClass(decl.node.name, /* stopAtFunction */ false);
|
||||
const enclosingClass = ParseTreeUtils.getEnclosingClass(decl.node.d.name, /* stopAtFunction */ false);
|
||||
const classResults = enclosingClass ? evaluator.getTypeOfClass(enclosingClass) : undefined;
|
||||
if (classResults) {
|
||||
return _getPropertyDocStringInherited(decl, sourceMapper, evaluator, classResults.classType);
|
||||
@ -191,8 +191,8 @@ export function isBuiltInModule(uri: Uri | undefined) {
|
||||
|
||||
export function getModuleDocStringFromModuleNodes(modules: ModuleNode[]): string | undefined {
|
||||
for (const module of modules) {
|
||||
if (module.statements) {
|
||||
const docString = ParseTreeUtils.getDocString(module.statements);
|
||||
if (module.d.statements) {
|
||||
const docString = ParseTreeUtils.getDocString(module.d.statements);
|
||||
if (docString) {
|
||||
return docString;
|
||||
}
|
||||
@ -264,7 +264,7 @@ export function getClassDocString(
|
||||
}
|
||||
|
||||
export function getFunctionOrClassDeclDocString(decl: FunctionDeclaration | ClassDeclaration): string | undefined {
|
||||
return ParseTreeUtils.getDocString(decl.node?.suite?.statements ?? []);
|
||||
return ParseTreeUtils.getDocString(decl.node?.d.suite?.d.statements ?? []);
|
||||
}
|
||||
|
||||
export function getVariableDocString(
|
||||
@ -324,7 +324,7 @@ function _getPropertyDocStringInherited(
|
||||
return;
|
||||
}
|
||||
|
||||
const fieldName = decl.node.nodeType === ParseNodeType.Function ? decl.node.name.value : undefined;
|
||||
const fieldName = decl.node.nodeType === ParseNodeType.Function ? decl.node.d.name.d.value : undefined;
|
||||
if (!fieldName) {
|
||||
return;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -132,34 +132,34 @@ export function getTypeNarrowingCallback(
|
||||
|
||||
if (testExpression.nodeType === ParseNodeType.BinaryOperation) {
|
||||
const isOrIsNotOperator =
|
||||
testExpression.operator === OperatorType.Is || testExpression.operator === OperatorType.IsNot;
|
||||
testExpression.d.operator === OperatorType.Is || testExpression.d.operator === OperatorType.IsNot;
|
||||
const equalsOrNotEqualsOperator =
|
||||
testExpression.operator === OperatorType.Equals || testExpression.operator === OperatorType.NotEquals;
|
||||
testExpression.d.operator === OperatorType.Equals || testExpression.d.operator === OperatorType.NotEquals;
|
||||
const comparisonOperator =
|
||||
equalsOrNotEqualsOperator ||
|
||||
testExpression.operator === OperatorType.LessThan ||
|
||||
testExpression.operator === OperatorType.LessThanOrEqual ||
|
||||
testExpression.operator === OperatorType.GreaterThan ||
|
||||
testExpression.operator === OperatorType.GreaterThanOrEqual;
|
||||
testExpression.d.operator === OperatorType.LessThan ||
|
||||
testExpression.d.operator === OperatorType.LessThanOrEqual ||
|
||||
testExpression.d.operator === OperatorType.GreaterThan ||
|
||||
testExpression.d.operator === OperatorType.GreaterThanOrEqual;
|
||||
|
||||
if (isOrIsNotOperator || equalsOrNotEqualsOperator) {
|
||||
// Invert the "isPositiveTest" value if this is an "is not" operation.
|
||||
const adjIsPositiveTest =
|
||||
testExpression.operator === OperatorType.Is || testExpression.operator === OperatorType.Equals
|
||||
testExpression.d.operator === OperatorType.Is || testExpression.d.operator === OperatorType.Equals
|
||||
? isPositiveTest
|
||||
: !isPositiveTest;
|
||||
|
||||
// Look for "X is None", "X is not None", "X == None", and "X != None".
|
||||
// These are commonly-used patterns used in control flow.
|
||||
if (
|
||||
testExpression.rightExpression.nodeType === ParseNodeType.Constant &&
|
||||
testExpression.rightExpression.constType === KeywordType.None
|
||||
testExpression.d.rightExpression.nodeType === ParseNodeType.Constant &&
|
||||
testExpression.d.rightExpression.d.constType === KeywordType.None
|
||||
) {
|
||||
// Allow the LHS to be either a simple expression or an assignment
|
||||
// expression that assigns to a simple name.
|
||||
let leftExpression = testExpression.leftExpression;
|
||||
let leftExpression = testExpression.d.leftExpression;
|
||||
if (leftExpression.nodeType === ParseNodeType.AssignmentExpression) {
|
||||
leftExpression = leftExpression.name;
|
||||
leftExpression = leftExpression.d.name;
|
||||
}
|
||||
|
||||
if (ParseTreeUtils.isMatchingExpression(reference, leftExpression)) {
|
||||
@ -170,16 +170,16 @@ export function getTypeNarrowingCallback(
|
||||
|
||||
if (
|
||||
leftExpression.nodeType === ParseNodeType.Index &&
|
||||
ParseTreeUtils.isMatchingExpression(reference, leftExpression.baseExpression) &&
|
||||
leftExpression.items.length === 1 &&
|
||||
!leftExpression.trailingComma &&
|
||||
leftExpression.items[0].argumentCategory === ArgumentCategory.Simple &&
|
||||
!leftExpression.items[0].name &&
|
||||
leftExpression.items[0].valueExpression.nodeType === ParseNodeType.Number &&
|
||||
leftExpression.items[0].valueExpression.isInteger &&
|
||||
!leftExpression.items[0].valueExpression.isImaginary
|
||||
ParseTreeUtils.isMatchingExpression(reference, leftExpression.d.baseExpression) &&
|
||||
leftExpression.d.items.length === 1 &&
|
||||
!leftExpression.d.trailingComma &&
|
||||
leftExpression.d.items[0].d.argumentCategory === ArgumentCategory.Simple &&
|
||||
!leftExpression.d.items[0].d.name &&
|
||||
leftExpression.d.items[0].d.valueExpression.nodeType === ParseNodeType.Number &&
|
||||
leftExpression.d.items[0].d.valueExpression.d.isInteger &&
|
||||
!leftExpression.d.items[0].d.valueExpression.d.isImaginary
|
||||
) {
|
||||
const indexValue = leftExpression.items[0].valueExpression.value;
|
||||
const indexValue = leftExpression.d.items[0].d.valueExpression.d.value;
|
||||
if (typeof indexValue === 'number') {
|
||||
return (type: Type) => {
|
||||
return {
|
||||
@ -192,12 +192,12 @@ export function getTypeNarrowingCallback(
|
||||
}
|
||||
|
||||
// Look for "X is ...", "X is not ...", "X == ...", and "X != ...".
|
||||
if (testExpression.rightExpression.nodeType === ParseNodeType.Ellipsis) {
|
||||
if (testExpression.d.rightExpression.nodeType === ParseNodeType.Ellipsis) {
|
||||
// Allow the LHS to be either a simple expression or an assignment
|
||||
// expression that assigns to a simple name.
|
||||
let leftExpression = testExpression.leftExpression;
|
||||
let leftExpression = testExpression.d.leftExpression;
|
||||
if (leftExpression.nodeType === ParseNodeType.AssignmentExpression) {
|
||||
leftExpression = leftExpression.name;
|
||||
leftExpression = leftExpression.d.name;
|
||||
}
|
||||
|
||||
if (ParseTreeUtils.isMatchingExpression(reference, leftExpression)) {
|
||||
@ -211,20 +211,20 @@ export function getTypeNarrowingCallback(
|
||||
}
|
||||
|
||||
// Look for "type(X) is Y", "type(X) is not Y", "type(X) == Y" or "type(X) != Y".
|
||||
if (testExpression.leftExpression.nodeType === ParseNodeType.Call) {
|
||||
if (testExpression.d.leftExpression.nodeType === ParseNodeType.Call) {
|
||||
if (
|
||||
testExpression.leftExpression.arguments.length === 1 &&
|
||||
testExpression.leftExpression.arguments[0].argumentCategory === ArgumentCategory.Simple
|
||||
testExpression.d.leftExpression.d.arguments.length === 1 &&
|
||||
testExpression.d.leftExpression.d.arguments[0].d.argumentCategory === ArgumentCategory.Simple
|
||||
) {
|
||||
const arg0Expr = testExpression.leftExpression.arguments[0].valueExpression;
|
||||
const arg0Expr = testExpression.d.leftExpression.d.arguments[0].d.valueExpression;
|
||||
if (ParseTreeUtils.isMatchingExpression(reference, arg0Expr)) {
|
||||
const callType = evaluator.getTypeOfExpression(
|
||||
testExpression.leftExpression.leftExpression,
|
||||
testExpression.d.leftExpression.d.leftExpression,
|
||||
EvalFlags.CallBaseDefaults
|
||||
).type;
|
||||
|
||||
if (isInstantiableClass(callType) && ClassType.isBuiltIn(callType, 'type')) {
|
||||
const classTypeResult = evaluator.getTypeOfExpression(testExpression.rightExpression);
|
||||
const classTypeResult = evaluator.getTypeOfExpression(testExpression.d.rightExpression);
|
||||
const classType = evaluator.makeTopLevelTypeVarsConcrete(classTypeResult.type);
|
||||
|
||||
if (isInstantiableClass(classType)) {
|
||||
@ -241,8 +241,8 @@ export function getTypeNarrowingCallback(
|
||||
}
|
||||
|
||||
if (isOrIsNotOperator) {
|
||||
if (ParseTreeUtils.isMatchingExpression(reference, testExpression.leftExpression)) {
|
||||
const rightTypeResult = evaluator.getTypeOfExpression(testExpression.rightExpression);
|
||||
if (ParseTreeUtils.isMatchingExpression(reference, testExpression.d.leftExpression)) {
|
||||
const rightTypeResult = evaluator.getTypeOfExpression(testExpression.d.rightExpression);
|
||||
const rightType = rightTypeResult.type;
|
||||
|
||||
// Look for "X is Y" or "X is not Y" where Y is a an enum or bool literal.
|
||||
@ -278,20 +278,20 @@ export function getTypeNarrowingCallback(
|
||||
|
||||
// Look for X[<literal>] is <literal> or X[<literal>] is not <literal>.
|
||||
if (
|
||||
testExpression.leftExpression.nodeType === ParseNodeType.Index &&
|
||||
testExpression.leftExpression.items.length === 1 &&
|
||||
!testExpression.leftExpression.trailingComma &&
|
||||
testExpression.leftExpression.items[0].argumentCategory === ArgumentCategory.Simple &&
|
||||
ParseTreeUtils.isMatchingExpression(reference, testExpression.leftExpression.baseExpression)
|
||||
testExpression.d.leftExpression.nodeType === ParseNodeType.Index &&
|
||||
testExpression.d.leftExpression.d.items.length === 1 &&
|
||||
!testExpression.d.leftExpression.d.trailingComma &&
|
||||
testExpression.d.leftExpression.d.items[0].d.argumentCategory === ArgumentCategory.Simple &&
|
||||
ParseTreeUtils.isMatchingExpression(reference, testExpression.d.leftExpression.d.baseExpression)
|
||||
) {
|
||||
const indexTypeResult = evaluator.getTypeOfExpression(
|
||||
testExpression.leftExpression.items[0].valueExpression
|
||||
testExpression.d.leftExpression.d.items[0].d.valueExpression
|
||||
);
|
||||
const indexType = indexTypeResult.type;
|
||||
|
||||
if (isClassInstance(indexType) && isLiteralType(indexType)) {
|
||||
if (ClassType.isBuiltIn(indexType, 'str')) {
|
||||
const rightType = evaluator.getTypeOfExpression(testExpression.rightExpression).type;
|
||||
const rightType = evaluator.getTypeOfExpression(testExpression.d.rightExpression).type;
|
||||
if (isClassInstance(rightType) && rightType.priv.literalValue !== undefined) {
|
||||
return (type: Type) => {
|
||||
return {
|
||||
@ -307,7 +307,7 @@ export function getTypeNarrowingCallback(
|
||||
};
|
||||
}
|
||||
} else if (ClassType.isBuiltIn(indexType, 'int')) {
|
||||
const rightTypeResult = evaluator.getTypeOfExpression(testExpression.rightExpression);
|
||||
const rightTypeResult = evaluator.getTypeOfExpression(testExpression.d.rightExpression);
|
||||
const rightType = rightTypeResult.type;
|
||||
|
||||
if (isClassInstance(rightType) && rightType.priv.literalValue !== undefined) {
|
||||
@ -342,14 +342,14 @@ export function getTypeNarrowingCallback(
|
||||
if (equalsOrNotEqualsOperator) {
|
||||
// Look for X == <literal> or X != <literal>
|
||||
const adjIsPositiveTest =
|
||||
testExpression.operator === OperatorType.Equals ? isPositiveTest : !isPositiveTest;
|
||||
testExpression.d.operator === OperatorType.Equals ? isPositiveTest : !isPositiveTest;
|
||||
|
||||
if (ParseTreeUtils.isMatchingExpression(reference, testExpression.leftExpression)) {
|
||||
if (ParseTreeUtils.isMatchingExpression(reference, testExpression.d.leftExpression)) {
|
||||
// Use speculative mode here to avoid polluting the type cache. This is
|
||||
// important in cases where evaluation of the right expression creates
|
||||
// a false dependency on another variable.
|
||||
const rightTypeResult = evaluator.useSpeculativeMode(testExpression.rightExpression, () => {
|
||||
return evaluator.getTypeOfExpression(testExpression.rightExpression);
|
||||
const rightTypeResult = evaluator.useSpeculativeMode(testExpression.d.rightExpression, () => {
|
||||
return evaluator.getTypeOfExpression(testExpression.d.rightExpression);
|
||||
});
|
||||
|
||||
const rightType = rightTypeResult.type;
|
||||
@ -372,20 +372,20 @@ export function getTypeNarrowingCallback(
|
||||
|
||||
// Look for X[<literal>] == <literal> or X[<literal>] != <literal>
|
||||
if (
|
||||
testExpression.leftExpression.nodeType === ParseNodeType.Index &&
|
||||
testExpression.leftExpression.items.length === 1 &&
|
||||
!testExpression.leftExpression.trailingComma &&
|
||||
testExpression.leftExpression.items[0].argumentCategory === ArgumentCategory.Simple &&
|
||||
ParseTreeUtils.isMatchingExpression(reference, testExpression.leftExpression.baseExpression)
|
||||
testExpression.d.leftExpression.nodeType === ParseNodeType.Index &&
|
||||
testExpression.d.leftExpression.d.items.length === 1 &&
|
||||
!testExpression.d.leftExpression.d.trailingComma &&
|
||||
testExpression.d.leftExpression.d.items[0].d.argumentCategory === ArgumentCategory.Simple &&
|
||||
ParseTreeUtils.isMatchingExpression(reference, testExpression.d.leftExpression.d.baseExpression)
|
||||
) {
|
||||
const indexTypeResult = evaluator.getTypeOfExpression(
|
||||
testExpression.leftExpression.items[0].valueExpression
|
||||
testExpression.d.leftExpression.d.items[0].d.valueExpression
|
||||
);
|
||||
const indexType = indexTypeResult.type;
|
||||
|
||||
if (isClassInstance(indexType) && isLiteralType(indexType)) {
|
||||
if (ClassType.isBuiltIn(indexType, ['str', 'int'])) {
|
||||
const rightTypeResult = evaluator.getTypeOfExpression(testExpression.rightExpression);
|
||||
const rightTypeResult = evaluator.getTypeOfExpression(testExpression.d.rightExpression);
|
||||
const rightType = rightTypeResult.type;
|
||||
|
||||
if (isLiteralTypeOrUnion(rightType)) {
|
||||
@ -424,12 +424,12 @@ export function getTypeNarrowingCallback(
|
||||
// Look for X.Y == <literal> or X.Y != <literal>
|
||||
if (
|
||||
equalsOrNotEqualsOperator &&
|
||||
testExpression.leftExpression.nodeType === ParseNodeType.MemberAccess &&
|
||||
ParseTreeUtils.isMatchingExpression(reference, testExpression.leftExpression.leftExpression)
|
||||
testExpression.d.leftExpression.nodeType === ParseNodeType.MemberAccess &&
|
||||
ParseTreeUtils.isMatchingExpression(reference, testExpression.d.leftExpression.d.leftExpression)
|
||||
) {
|
||||
const rightTypeResult = evaluator.getTypeOfExpression(testExpression.rightExpression);
|
||||
const rightTypeResult = evaluator.getTypeOfExpression(testExpression.d.rightExpression);
|
||||
const rightType = rightTypeResult.type;
|
||||
const memberName = testExpression.leftExpression.memberName;
|
||||
const memberName = testExpression.d.leftExpression.d.memberName;
|
||||
|
||||
if (isClassInstance(rightType)) {
|
||||
if (rightType.priv.literalValue !== undefined || isNoneInstance(rightType)) {
|
||||
@ -438,7 +438,7 @@ export function getTypeNarrowingCallback(
|
||||
type: narrowTypeForDiscriminatedLiteralFieldComparison(
|
||||
evaluator,
|
||||
type,
|
||||
memberName.value,
|
||||
memberName.d.value,
|
||||
rightType,
|
||||
adjIsPositiveTest
|
||||
),
|
||||
@ -452,12 +452,12 @@ export function getTypeNarrowingCallback(
|
||||
// Look for X.Y is <literal> or X.Y is not <literal> where <literal> is
|
||||
// an enum or bool literal
|
||||
if (
|
||||
testExpression.leftExpression.nodeType === ParseNodeType.MemberAccess &&
|
||||
ParseTreeUtils.isMatchingExpression(reference, testExpression.leftExpression.leftExpression)
|
||||
testExpression.d.leftExpression.nodeType === ParseNodeType.MemberAccess &&
|
||||
ParseTreeUtils.isMatchingExpression(reference, testExpression.d.leftExpression.d.leftExpression)
|
||||
) {
|
||||
const rightTypeResult = evaluator.getTypeOfExpression(testExpression.rightExpression);
|
||||
const rightTypeResult = evaluator.getTypeOfExpression(testExpression.d.rightExpression);
|
||||
const rightType = rightTypeResult.type;
|
||||
const memberName = testExpression.leftExpression.memberName;
|
||||
const memberName = testExpression.d.leftExpression.d.memberName;
|
||||
|
||||
if (
|
||||
isClassInstance(rightType) &&
|
||||
@ -469,7 +469,7 @@ export function getTypeNarrowingCallback(
|
||||
type: narrowTypeForDiscriminatedLiteralFieldComparison(
|
||||
evaluator,
|
||||
type,
|
||||
memberName.value,
|
||||
memberName.d.value,
|
||||
rightType,
|
||||
adjIsPositiveTest
|
||||
),
|
||||
@ -482,18 +482,18 @@ export function getTypeNarrowingCallback(
|
||||
// Look for X.Y is None or X.Y is not None
|
||||
// These are commonly-used patterns used in control flow.
|
||||
if (
|
||||
testExpression.leftExpression.nodeType === ParseNodeType.MemberAccess &&
|
||||
ParseTreeUtils.isMatchingExpression(reference, testExpression.leftExpression.leftExpression) &&
|
||||
testExpression.rightExpression.nodeType === ParseNodeType.Constant &&
|
||||
testExpression.rightExpression.constType === KeywordType.None
|
||||
testExpression.d.leftExpression.nodeType === ParseNodeType.MemberAccess &&
|
||||
ParseTreeUtils.isMatchingExpression(reference, testExpression.d.leftExpression.d.leftExpression) &&
|
||||
testExpression.d.rightExpression.nodeType === ParseNodeType.Constant &&
|
||||
testExpression.d.rightExpression.d.constType === KeywordType.None
|
||||
) {
|
||||
const memberName = testExpression.leftExpression.memberName;
|
||||
const memberName = testExpression.d.leftExpression.d.memberName;
|
||||
return (type: Type) => {
|
||||
return {
|
||||
type: narrowTypeForDiscriminatedFieldNoneComparison(
|
||||
evaluator,
|
||||
type,
|
||||
memberName.value,
|
||||
memberName.d.value,
|
||||
adjIsPositiveTest
|
||||
),
|
||||
isIncomplete: false,
|
||||
@ -505,20 +505,20 @@ export function getTypeNarrowingCallback(
|
||||
// Look for len(x) == <literal>, len(x) != <literal>, len(x) < <literal>, etc.
|
||||
if (
|
||||
comparisonOperator &&
|
||||
testExpression.leftExpression.nodeType === ParseNodeType.Call &&
|
||||
testExpression.leftExpression.arguments.length === 1
|
||||
testExpression.d.leftExpression.nodeType === ParseNodeType.Call &&
|
||||
testExpression.d.leftExpression.d.arguments.length === 1
|
||||
) {
|
||||
const arg0Expr = testExpression.leftExpression.arguments[0].valueExpression;
|
||||
const arg0Expr = testExpression.d.leftExpression.d.arguments[0].d.valueExpression;
|
||||
|
||||
if (ParseTreeUtils.isMatchingExpression(reference, arg0Expr)) {
|
||||
const callTypeResult = evaluator.getTypeOfExpression(
|
||||
testExpression.leftExpression.leftExpression,
|
||||
testExpression.d.leftExpression.d.leftExpression,
|
||||
EvalFlags.CallBaseDefaults
|
||||
);
|
||||
const callType = callTypeResult.type;
|
||||
|
||||
if (isFunction(callType) && callType.shared.fullName === 'builtins.len') {
|
||||
const rightTypeResult = evaluator.getTypeOfExpression(testExpression.rightExpression);
|
||||
const rightTypeResult = evaluator.getTypeOfExpression(testExpression.d.rightExpression);
|
||||
const rightType = rightTypeResult.type;
|
||||
|
||||
if (
|
||||
@ -531,23 +531,23 @@ export function getTypeNarrowingCallback(
|
||||
// We'll treat <, <= and == as positive tests with >=, > and != as
|
||||
// their negative counterparts.
|
||||
const isLessOrEqual =
|
||||
testExpression.operator === OperatorType.Equals ||
|
||||
testExpression.operator === OperatorType.LessThan ||
|
||||
testExpression.operator === OperatorType.LessThanOrEqual;
|
||||
testExpression.d.operator === OperatorType.Equals ||
|
||||
testExpression.d.operator === OperatorType.LessThan ||
|
||||
testExpression.d.operator === OperatorType.LessThanOrEqual;
|
||||
|
||||
const adjIsPositiveTest = isLessOrEqual ? isPositiveTest : !isPositiveTest;
|
||||
|
||||
// For <= (or its negative counterpart >), adjust the tuple length by 1.
|
||||
if (
|
||||
testExpression.operator === OperatorType.LessThanOrEqual ||
|
||||
testExpression.operator === OperatorType.GreaterThan
|
||||
testExpression.d.operator === OperatorType.LessThanOrEqual ||
|
||||
testExpression.d.operator === OperatorType.GreaterThan
|
||||
) {
|
||||
tupleLength++;
|
||||
}
|
||||
|
||||
const isEqualityCheck =
|
||||
testExpression.operator === OperatorType.Equals ||
|
||||
testExpression.operator === OperatorType.NotEquals;
|
||||
testExpression.d.operator === OperatorType.Equals ||
|
||||
testExpression.d.operator === OperatorType.NotEquals;
|
||||
|
||||
return (type: Type) => {
|
||||
return {
|
||||
@ -566,13 +566,13 @@ export function getTypeNarrowingCallback(
|
||||
}
|
||||
}
|
||||
|
||||
if (testExpression.operator === OperatorType.In || testExpression.operator === OperatorType.NotIn) {
|
||||
if (testExpression.d.operator === OperatorType.In || testExpression.d.operator === OperatorType.NotIn) {
|
||||
// Look for "x in y" or "x not in y" where y is one of several built-in types.
|
||||
if (ParseTreeUtils.isMatchingExpression(reference, testExpression.leftExpression)) {
|
||||
const rightTypeResult = evaluator.getTypeOfExpression(testExpression.rightExpression);
|
||||
if (ParseTreeUtils.isMatchingExpression(reference, testExpression.d.leftExpression)) {
|
||||
const rightTypeResult = evaluator.getTypeOfExpression(testExpression.d.rightExpression);
|
||||
const rightType = rightTypeResult.type;
|
||||
const adjIsPositiveTest =
|
||||
testExpression.operator === OperatorType.In ? isPositiveTest : !isPositiveTest;
|
||||
testExpression.d.operator === OperatorType.In ? isPositiveTest : !isPositiveTest;
|
||||
|
||||
return (type: Type) => {
|
||||
return {
|
||||
@ -582,15 +582,15 @@ export function getTypeNarrowingCallback(
|
||||
};
|
||||
}
|
||||
|
||||
if (ParseTreeUtils.isMatchingExpression(reference, testExpression.rightExpression)) {
|
||||
if (ParseTreeUtils.isMatchingExpression(reference, testExpression.d.rightExpression)) {
|
||||
// Look for <string literal> in y where y is a union that contains
|
||||
// one or more TypedDicts.
|
||||
const leftTypeResult = evaluator.getTypeOfExpression(testExpression.leftExpression);
|
||||
const leftTypeResult = evaluator.getTypeOfExpression(testExpression.d.leftExpression);
|
||||
const leftType = leftTypeResult.type;
|
||||
|
||||
if (isClassInstance(leftType) && ClassType.isBuiltIn(leftType, 'str') && isLiteralType(leftType)) {
|
||||
const adjIsPositiveTest =
|
||||
testExpression.operator === OperatorType.In ? isPositiveTest : !isPositiveTest;
|
||||
testExpression.d.operator === OperatorType.In ? isPositiveTest : !isPositiveTest;
|
||||
return (type: Type) => {
|
||||
return {
|
||||
type: narrowTypeForTypedDictKey(
|
||||
@ -609,16 +609,16 @@ export function getTypeNarrowingCallback(
|
||||
|
||||
if (testExpression.nodeType === ParseNodeType.Call) {
|
||||
// Look for "isinstance(X, Y)" or "issubclass(X, Y)".
|
||||
if (testExpression.arguments.length === 2) {
|
||||
if (testExpression.d.arguments.length === 2) {
|
||||
// Make sure the first parameter is a supported expression type
|
||||
// and the second parameter is a valid class type or a tuple
|
||||
// of valid class types.
|
||||
const arg0Expr = testExpression.arguments[0].valueExpression;
|
||||
const arg1Expr = testExpression.arguments[1].valueExpression;
|
||||
const arg0Expr = testExpression.d.arguments[0].d.valueExpression;
|
||||
const arg1Expr = testExpression.d.arguments[1].d.valueExpression;
|
||||
|
||||
if (ParseTreeUtils.isMatchingExpression(reference, arg0Expr)) {
|
||||
const callTypeResult = evaluator.getTypeOfExpression(
|
||||
testExpression.leftExpression,
|
||||
testExpression.d.leftExpression,
|
||||
EvalFlags.CallBaseDefaults
|
||||
);
|
||||
const callType = callTypeResult.type;
|
||||
@ -661,11 +661,11 @@ export function getTypeNarrowingCallback(
|
||||
}
|
||||
|
||||
// Look for "callable(X)"
|
||||
if (testExpression.arguments.length === 1) {
|
||||
const arg0Expr = testExpression.arguments[0].valueExpression;
|
||||
if (testExpression.d.arguments.length === 1) {
|
||||
const arg0Expr = testExpression.d.arguments[0].d.valueExpression;
|
||||
if (ParseTreeUtils.isMatchingExpression(reference, arg0Expr)) {
|
||||
const callTypeResult = evaluator.getTypeOfExpression(
|
||||
testExpression.leftExpression,
|
||||
testExpression.d.leftExpression,
|
||||
EvalFlags.CallBaseDefaults
|
||||
);
|
||||
const callType = callTypeResult.type;
|
||||
@ -697,10 +697,10 @@ export function getTypeNarrowingCallback(
|
||||
}
|
||||
|
||||
// Look for "bool(X)"
|
||||
if (testExpression.arguments.length === 1 && !testExpression.arguments[0].name) {
|
||||
if (ParseTreeUtils.isMatchingExpression(reference, testExpression.arguments[0].valueExpression)) {
|
||||
if (testExpression.d.arguments.length === 1 && !testExpression.d.arguments[0].d.name) {
|
||||
if (ParseTreeUtils.isMatchingExpression(reference, testExpression.d.arguments[0].d.valueExpression)) {
|
||||
const callTypeResult = evaluator.getTypeOfExpression(
|
||||
testExpression.leftExpression,
|
||||
testExpression.d.leftExpression,
|
||||
EvalFlags.CallBaseDefaults
|
||||
);
|
||||
const callType = callTypeResult.type;
|
||||
@ -717,8 +717,8 @@ export function getTypeNarrowingCallback(
|
||||
}
|
||||
|
||||
// Look for a TypeGuard function.
|
||||
if (testExpression.arguments.length >= 1) {
|
||||
const arg0Expr = testExpression.arguments[0].valueExpression;
|
||||
if (testExpression.d.arguments.length >= 1) {
|
||||
const arg0Expr = testExpression.d.arguments[0].d.valueExpression;
|
||||
if (ParseTreeUtils.isMatchingExpression(reference, arg0Expr)) {
|
||||
// Does this look like it's a custom type guard function?
|
||||
let isPossiblyTypeGuard = false;
|
||||
@ -732,7 +732,7 @@ export function getTypeNarrowingCallback(
|
||||
};
|
||||
|
||||
const callTypeResult = evaluator.getTypeOfExpression(
|
||||
testExpression.leftExpression,
|
||||
testExpression.d.leftExpression,
|
||||
EvalFlags.CallBaseDefaults
|
||||
);
|
||||
const callType = callTypeResult.type;
|
||||
@ -807,11 +807,14 @@ export function getTypeNarrowingCallback(
|
||||
// by the binder when it creates condition flow nodes, but we can find this
|
||||
// in the case of local variables type narrowing.
|
||||
if (reference.nodeType === ParseNodeType.Name) {
|
||||
if (testExpression.nodeType === ParseNodeType.UnaryOperation && testExpression.operator === OperatorType.Not) {
|
||||
if (
|
||||
testExpression.nodeType === ParseNodeType.UnaryOperation &&
|
||||
testExpression.d.operator === OperatorType.Not
|
||||
) {
|
||||
return getTypeNarrowingCallback(
|
||||
evaluator,
|
||||
reference,
|
||||
testExpression.expression,
|
||||
testExpression.d.expression,
|
||||
!isPositiveTest,
|
||||
recursionCount
|
||||
);
|
||||
@ -901,7 +904,7 @@ function getDeclsForLocalVar(
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const symbol = scope.lookUpSymbol(name.value);
|
||||
const symbol = scope.lookUpSymbol(name.d.value);
|
||||
if (!symbol) {
|
||||
return undefined;
|
||||
}
|
||||
@ -923,7 +926,7 @@ function getDeclsForLocalVar(
|
||||
let prevDeclScope: ParseNode | undefined;
|
||||
if (
|
||||
decls.some((decl) => {
|
||||
const nodeToConsider = decl.type === DeclarationType.Parameter ? decl.node.name! : decl.node;
|
||||
const nodeToConsider = decl.type === DeclarationType.Parameter ? decl.node.d.name! : decl.node;
|
||||
const declScopeNode = ParseTreeUtils.getExecutionScopeNode(nodeToConsider);
|
||||
if (prevDeclScope && declScopeNode !== prevDeclScope) {
|
||||
return true;
|
||||
@ -951,10 +954,10 @@ function getTypeNarrowingCallbackForAssignmentExpression(
|
||||
getTypeNarrowingCallback(
|
||||
evaluator,
|
||||
reference,
|
||||
testExpression.rightExpression,
|
||||
testExpression.d.rightExpression,
|
||||
isPositiveTest,
|
||||
recursionCount
|
||||
) ?? getTypeNarrowingCallback(evaluator, reference, testExpression.name, isPositiveTest, recursionCount)
|
||||
) ?? getTypeNarrowingCallback(evaluator, reference, testExpression.d.name, isPositiveTest, recursionCount)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1228,9 +1228,9 @@ function printFunctionPartsInternal(
|
||||
}
|
||||
|
||||
if (param.defaultType) {
|
||||
const paramNode = functionNode?.parameters.find((p) => p.name?.value === param.name);
|
||||
if (paramNode?.defaultValue) {
|
||||
paramString += defaultValueAssignment + ParseTreeUtils.printExpression(paramNode.defaultValue);
|
||||
const paramNode = functionNode?.d.parameters.find((p) => p.d.name?.d.value === param.name);
|
||||
if (paramNode?.d.defaultValue) {
|
||||
paramString += defaultValueAssignment + ParseTreeUtils.printExpression(paramNode.d.defaultValue);
|
||||
} else {
|
||||
// If the function doesn't originate from a function declaration (e.g. it is
|
||||
// synthesized), we can't get to the default declaration, but we can still indicate
|
||||
|
@ -104,15 +104,15 @@ class ImportSymbolWalker extends ParseTreeWalker {
|
||||
}
|
||||
|
||||
override visitName(node: NameNode) {
|
||||
this._accessedImportedSymbols.add(node.value);
|
||||
this._accessedImportedSymbols.add(node.d.value);
|
||||
return true;
|
||||
}
|
||||
|
||||
override visitMemberAccess(node: MemberAccessNode): boolean {
|
||||
const baseExpression = this._getRecursiveModuleAccessExpression(node.leftExpression);
|
||||
const baseExpression = this._getRecursiveModuleAccessExpression(node.d.leftExpression);
|
||||
|
||||
if (baseExpression) {
|
||||
this._accessedImportedSymbols.add(`${baseExpression}.${node.memberName.value}`);
|
||||
this._accessedImportedSymbols.add(`${baseExpression}.${node.d.memberName.d.value}`);
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -120,7 +120,7 @@ class ImportSymbolWalker extends ParseTreeWalker {
|
||||
|
||||
override visitString(node: StringNode) {
|
||||
if (this._treatStringsAsSymbols) {
|
||||
this._accessedImportedSymbols.add(node.value);
|
||||
this._accessedImportedSymbols.add(node.d.value);
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -128,16 +128,16 @@ class ImportSymbolWalker extends ParseTreeWalker {
|
||||
|
||||
private _getRecursiveModuleAccessExpression(node: ExpressionNode): string | undefined {
|
||||
if (node.nodeType === ParseNodeType.Name) {
|
||||
return node.value;
|
||||
return node.d.value;
|
||||
}
|
||||
|
||||
if (node.nodeType === ParseNodeType.MemberAccess) {
|
||||
const baseExpression = this._getRecursiveModuleAccessExpression(node.leftExpression);
|
||||
const baseExpression = this._getRecursiveModuleAccessExpression(node.d.leftExpression);
|
||||
if (!baseExpression) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return `${baseExpression}.${node.memberName.value}`;
|
||||
return `${baseExpression}.${node.d.memberName.d.value}`;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
@ -187,34 +187,34 @@ export class TypeStubWriter extends ParseTreeWalker {
|
||||
}
|
||||
|
||||
override visitClass(node: ClassNode) {
|
||||
const className = node.name.value;
|
||||
const className = node.d.name.d.value;
|
||||
|
||||
this._emittedSuite = true;
|
||||
this._emitDocString = true;
|
||||
this._emitDecorators(node.decorators);
|
||||
this._emitDecorators(node.d.decorators);
|
||||
let line = `class ${className}`;
|
||||
|
||||
if (node.typeParameters) {
|
||||
line += this._printTypeParameters(node.typeParameters);
|
||||
if (node.d.typeParameters) {
|
||||
line += this._printTypeParameters(node.d.typeParameters);
|
||||
}
|
||||
|
||||
// Remove "object" from the list, since it's implied
|
||||
const args = node.arguments.filter(
|
||||
const args = node.d.arguments.filter(
|
||||
(arg) =>
|
||||
arg.name !== undefined ||
|
||||
arg.argumentCategory !== ArgumentCategory.Simple ||
|
||||
arg.valueExpression.nodeType !== ParseNodeType.Name ||
|
||||
arg.valueExpression.value !== 'object'
|
||||
arg.d.name !== undefined ||
|
||||
arg.d.argumentCategory !== ArgumentCategory.Simple ||
|
||||
arg.d.valueExpression.nodeType !== ParseNodeType.Name ||
|
||||
arg.d.valueExpression.d.value !== 'object'
|
||||
);
|
||||
|
||||
if (args.length > 0) {
|
||||
line += `(${args
|
||||
.map((arg) => {
|
||||
let argString = '';
|
||||
if (arg.name) {
|
||||
argString = arg.name.value + '=';
|
||||
if (arg.d.name) {
|
||||
argString = arg.d.name.d.value + '=';
|
||||
}
|
||||
argString += this._printExpression(arg.valueExpression);
|
||||
argString += this._printExpression(arg.d.valueExpression);
|
||||
return argString;
|
||||
})
|
||||
.join(', ')})`;
|
||||
@ -224,7 +224,7 @@ export class TypeStubWriter extends ParseTreeWalker {
|
||||
|
||||
this._emitSuite(() => {
|
||||
this._classNestCount++;
|
||||
this.walk(node.suite);
|
||||
this.walk(node.d.suite);
|
||||
this._classNestCount--;
|
||||
});
|
||||
|
||||
@ -235,41 +235,41 @@ export class TypeStubWriter extends ParseTreeWalker {
|
||||
}
|
||||
|
||||
override visitFunction(node: FunctionNode) {
|
||||
const functionName = node.name.value;
|
||||
const functionName = node.d.name.d.value;
|
||||
|
||||
// Skip if we're already within a function or if the name is private/protected.
|
||||
if (this._functionNestCount === 0 && !SymbolNameUtils.isPrivateOrProtectedName(functionName)) {
|
||||
this._emittedSuite = true;
|
||||
this._emitDocString = true;
|
||||
this._emitDecorators(node.decorators);
|
||||
let line = node.isAsync ? 'async ' : '';
|
||||
this._emitDecorators(node.d.decorators);
|
||||
let line = node.d.isAsync ? 'async ' : '';
|
||||
line += `def ${functionName}`;
|
||||
|
||||
if (node.typeParameters) {
|
||||
line += this._printTypeParameters(node.typeParameters);
|
||||
if (node.d.typeParameters) {
|
||||
line += this._printTypeParameters(node.d.typeParameters);
|
||||
}
|
||||
|
||||
line += `(${node.parameters.map((param, index) => this._printParameter(param, node, index)).join(', ')})`;
|
||||
line += `(${node.d.parameters.map((param, index) => this._printParameter(param, node, index)).join(', ')})`;
|
||||
|
||||
let returnAnnotation: string | undefined;
|
||||
if (node.returnTypeAnnotation) {
|
||||
returnAnnotation = this._printExpression(node.returnTypeAnnotation, /* treatStringsAsSymbols */ true);
|
||||
} else if (node.functionAnnotationComment) {
|
||||
if (node.d.returnTypeAnnotation) {
|
||||
returnAnnotation = this._printExpression(node.d.returnTypeAnnotation, /* treatStringsAsSymbols */ true);
|
||||
} else if (node.d.functionAnnotationComment) {
|
||||
returnAnnotation = this._printExpression(
|
||||
node.functionAnnotationComment.returnTypeAnnotation,
|
||||
node.d.functionAnnotationComment.d.returnTypeAnnotation,
|
||||
/* treatStringsAsSymbols */ true
|
||||
);
|
||||
} else {
|
||||
// Handle a few common cases where we always know the answer.
|
||||
if (node.name.value === '__init__') {
|
||||
if (node.d.name.d.value === '__init__') {
|
||||
returnAnnotation = 'None';
|
||||
} else if (node.name.value === '__str__') {
|
||||
} else if (node.d.name.d.value === '__str__') {
|
||||
returnAnnotation = 'str';
|
||||
} else if (['__int__', '__hash__'].some((name) => name === node.name.value)) {
|
||||
} else if (['__int__', '__hash__'].some((name) => name === node.d.name.d.value)) {
|
||||
returnAnnotation = 'int';
|
||||
} else if (
|
||||
['__eq__', '__ne__', '__gt__', '__lt__', '__ge__', '__le__'].some(
|
||||
(name) => name === node.name.value
|
||||
(name) => name === node.d.name.d.value
|
||||
)
|
||||
) {
|
||||
returnAnnotation = 'bool';
|
||||
@ -300,7 +300,7 @@ export class TypeStubWriter extends ParseTreeWalker {
|
||||
this._emitSuite(() => {
|
||||
// Don't emit any nested functions.
|
||||
this._functionNestCount++;
|
||||
this.walk(node.suite);
|
||||
this.walk(node.d.suite);
|
||||
this._functionNestCount--;
|
||||
});
|
||||
|
||||
@ -327,7 +327,7 @@ export class TypeStubWriter extends ParseTreeWalker {
|
||||
this._emitDocString = false;
|
||||
|
||||
// Only walk a single branch of the try/catch to for imports.
|
||||
this.walk(node.trySuite);
|
||||
this.walk(node.d.trySuite);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -346,19 +346,19 @@ export class TypeStubWriter extends ParseTreeWalker {
|
||||
if (this._functionNestCount === 0 && this._ifNestCount === 0) {
|
||||
this._ifNestCount++;
|
||||
this._emittedSuite = true;
|
||||
this._emitLine('if ' + this._printExpression(node.testExpression) + ':');
|
||||
this._emitLine('if ' + this._printExpression(node.d.testExpression) + ':');
|
||||
this._emitSuite(() => {
|
||||
this.walkMultiple(node.ifSuite.statements);
|
||||
this.walkMultiple(node.d.ifSuite.d.statements);
|
||||
});
|
||||
|
||||
const elseSuite = node.elseSuite;
|
||||
const elseSuite = node.d.elseSuite;
|
||||
if (elseSuite) {
|
||||
this._emitLine('else:');
|
||||
this._emitSuite(() => {
|
||||
if (elseSuite.nodeType === ParseNodeType.If) {
|
||||
this.walkMultiple([elseSuite.testExpression, elseSuite.ifSuite, elseSuite.elseSuite]);
|
||||
this.walkMultiple([elseSuite.d.testExpression, elseSuite.d.ifSuite, elseSuite.d.elseSuite]);
|
||||
} else {
|
||||
this.walkMultiple(elseSuite.statements);
|
||||
this.walkMultiple(elseSuite.d.statements);
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -370,14 +370,14 @@ export class TypeStubWriter extends ParseTreeWalker {
|
||||
|
||||
override visitTypeAlias(node: TypeAliasNode): boolean {
|
||||
let line = '';
|
||||
line = this._printExpression(node.name);
|
||||
line = this._printExpression(node.d.name);
|
||||
|
||||
if (node.typeParameters) {
|
||||
line += this._printTypeParameters(node.typeParameters);
|
||||
if (node.d.typeParameters) {
|
||||
line += this._printTypeParameters(node.d.typeParameters);
|
||||
}
|
||||
|
||||
line += ' = ';
|
||||
line += this._printExpression(node.expression);
|
||||
line += this._printExpression(node.d.expression);
|
||||
this._emitLine(line);
|
||||
|
||||
return false;
|
||||
@ -387,15 +387,15 @@ export class TypeStubWriter extends ParseTreeWalker {
|
||||
let isTypeAlias = false;
|
||||
let line = '';
|
||||
|
||||
if (node.leftExpression.nodeType === ParseNodeType.Name) {
|
||||
if (node.d.leftExpression.nodeType === ParseNodeType.Name) {
|
||||
// Handle "__all__" as a special case.
|
||||
if (node.leftExpression.value === '__all__') {
|
||||
if (node.d.leftExpression.d.value === '__all__') {
|
||||
if (this._functionNestCount === 0 && this._ifNestCount === 0) {
|
||||
this._emittedSuite = true;
|
||||
|
||||
line = this._printExpression(node.leftExpression);
|
||||
line = this._printExpression(node.d.leftExpression);
|
||||
line += ' = ';
|
||||
line += this._printExpression(node.rightExpression);
|
||||
line += this._printExpression(node.d.rightExpression);
|
||||
this._emitLine(line);
|
||||
}
|
||||
|
||||
@ -403,18 +403,19 @@ export class TypeStubWriter extends ParseTreeWalker {
|
||||
}
|
||||
|
||||
if (this._functionNestCount === 0) {
|
||||
line = this._printExpression(node.leftExpression);
|
||||
if (node.typeAnnotationComment) {
|
||||
line += ': ' + this._printExpression(node.typeAnnotationComment, /* treatStringsAsSymbols */ true);
|
||||
line = this._printExpression(node.d.leftExpression);
|
||||
if (node.d.typeAnnotationComment) {
|
||||
line +=
|
||||
': ' + this._printExpression(node.d.typeAnnotationComment, /* treatStringsAsSymbols */ true);
|
||||
}
|
||||
|
||||
const valueType = this._evaluator.getType(node.leftExpression);
|
||||
const valueType = this._evaluator.getType(node.d.leftExpression);
|
||||
if (valueType?.props?.typeAliasInfo) {
|
||||
isTypeAlias = true;
|
||||
} else if (node.rightExpression.nodeType === ParseNodeType.Call) {
|
||||
} else if (node.d.rightExpression.nodeType === ParseNodeType.Call) {
|
||||
// Special-case TypeVar, TypeVarTuple, ParamSpec and NewType calls. Treat
|
||||
// them like type aliases.
|
||||
const callBaseType = this._evaluator.getType(node.rightExpression.leftExpression);
|
||||
const callBaseType = this._evaluator.getType(node.d.rightExpression.d.leftExpression);
|
||||
if (
|
||||
callBaseType &&
|
||||
isInstantiableClass(callBaseType) &&
|
||||
@ -424,13 +425,13 @@ export class TypeStubWriter extends ParseTreeWalker {
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (node.leftExpression.nodeType === ParseNodeType.TypeAnnotation) {
|
||||
const valueExpr = node.leftExpression.valueExpression;
|
||||
} else if (node.d.leftExpression.nodeType === ParseNodeType.TypeAnnotation) {
|
||||
const valueExpr = node.d.leftExpression.d.valueExpression;
|
||||
|
||||
if (valueExpr.nodeType === ParseNodeType.Name) {
|
||||
if (this._functionNestCount === 0) {
|
||||
line = `${this._printExpression(valueExpr)}: ${this._printExpression(
|
||||
node.leftExpression.typeAnnotation,
|
||||
node.d.leftExpression.d.typeAnnotation,
|
||||
/* treatStringsAsSymbols */ true
|
||||
)}`;
|
||||
}
|
||||
@ -443,7 +444,7 @@ export class TypeStubWriter extends ParseTreeWalker {
|
||||
line += ' = ';
|
||||
|
||||
if (isTypeAlias) {
|
||||
line += this._printExpression(node.rightExpression);
|
||||
line += this._printExpression(node.d.rightExpression);
|
||||
} else {
|
||||
line += '...';
|
||||
}
|
||||
@ -454,13 +455,13 @@ export class TypeStubWriter extends ParseTreeWalker {
|
||||
}
|
||||
|
||||
override visitAugmentedAssignment(node: AugmentedAssignmentNode) {
|
||||
if (node.leftExpression.nodeType === ParseNodeType.Name) {
|
||||
if (node.d.leftExpression.nodeType === ParseNodeType.Name) {
|
||||
// Handle "__all__ +=" as a special case.
|
||||
if (node.leftExpression.value === '__all__' && node.operator === OperatorType.AddEqual) {
|
||||
if (node.d.leftExpression.d.value === '__all__' && node.d.operator === OperatorType.AddEqual) {
|
||||
if (this._functionNestCount === 0 && this._ifNestCount === 0) {
|
||||
let line = this._printExpression(node.leftExpression);
|
||||
let line = this._printExpression(node.d.leftExpression);
|
||||
line += ' += ';
|
||||
line += this._printExpression(node.rightExpression);
|
||||
line += this._printExpression(node.d.rightExpression);
|
||||
this._emitLine(line);
|
||||
}
|
||||
}
|
||||
@ -472,22 +473,22 @@ export class TypeStubWriter extends ParseTreeWalker {
|
||||
override visitTypeAnnotation(node: TypeAnnotationNode) {
|
||||
if (this._functionNestCount === 0) {
|
||||
let line = '';
|
||||
if (node.valueExpression.nodeType === ParseNodeType.Name) {
|
||||
line = this._printExpression(node.valueExpression);
|
||||
} else if (node.valueExpression.nodeType === ParseNodeType.MemberAccess) {
|
||||
const baseExpression = node.valueExpression.leftExpression;
|
||||
if (node.d.valueExpression.nodeType === ParseNodeType.Name) {
|
||||
line = this._printExpression(node.d.valueExpression);
|
||||
} else if (node.d.valueExpression.nodeType === ParseNodeType.MemberAccess) {
|
||||
const baseExpression = node.d.valueExpression.d.leftExpression;
|
||||
if (baseExpression.nodeType === ParseNodeType.Name) {
|
||||
if (baseExpression.value === 'self') {
|
||||
const memberName = node.valueExpression.memberName.value;
|
||||
if (baseExpression.d.value === 'self') {
|
||||
const memberName = node.d.valueExpression.d.memberName.d.value;
|
||||
if (!SymbolNameUtils.isPrivateOrProtectedName(memberName)) {
|
||||
line = this._printExpression(node.valueExpression);
|
||||
line = this._printExpression(node.d.valueExpression);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (line) {
|
||||
line += ': ' + this._printExpression(node.typeAnnotation, /* treatStringsAsSymbols */ true);
|
||||
line += ': ' + this._printExpression(node.d.typeAnnotation, /* treatStringsAsSymbols */ true);
|
||||
this._emitLine(line);
|
||||
}
|
||||
}
|
||||
@ -503,19 +504,19 @@ export class TypeStubWriter extends ParseTreeWalker {
|
||||
const currentScope = getScopeForNode(node);
|
||||
if (currentScope) {
|
||||
// Record the input for later.
|
||||
node.list.forEach((imp) => {
|
||||
const moduleName = this._printModuleName(imp.module);
|
||||
node.d.list.forEach((imp) => {
|
||||
const moduleName = this._printModuleName(imp.d.module);
|
||||
if (!this._trackedImportAs.has(moduleName)) {
|
||||
const symbolName = imp.alias
|
||||
? imp.alias.value
|
||||
: imp.module.nameParts.length > 0
|
||||
? imp.module.nameParts[0].value
|
||||
const symbolName = imp.d.alias
|
||||
? imp.d.alias.d.value
|
||||
: imp.d.module.d.nameParts.length > 0
|
||||
? imp.d.module.d.nameParts[0].d.value
|
||||
: '';
|
||||
const symbolInfo = currentScope.lookUpSymbolRecursive(symbolName);
|
||||
if (symbolInfo) {
|
||||
const trackedImportAs = new TrackedImportAs(
|
||||
moduleName,
|
||||
imp.alias ? imp.alias.value : undefined,
|
||||
imp.d.alias ? imp.d.alias.d.value : undefined,
|
||||
symbolInfo.symbol
|
||||
);
|
||||
this._trackedImportAs.set(moduleName, trackedImportAs);
|
||||
@ -535,21 +536,21 @@ export class TypeStubWriter extends ParseTreeWalker {
|
||||
const currentScope = getScopeForNode(node);
|
||||
if (currentScope) {
|
||||
// Record the input for later.
|
||||
const moduleName = this._printModuleName(node.module);
|
||||
const moduleName = this._printModuleName(node.d.module);
|
||||
let trackedImportFrom = this._trackedImportFrom.get(moduleName);
|
||||
if (!trackedImportFrom) {
|
||||
trackedImportFrom = new TrackedImportFrom(moduleName, node.isWildcardImport, node);
|
||||
trackedImportFrom = new TrackedImportFrom(moduleName, node.d.isWildcardImport, node);
|
||||
this._trackedImportFrom.set(moduleName, trackedImportFrom);
|
||||
}
|
||||
|
||||
node.imports.forEach((imp) => {
|
||||
const symbolName = imp.alias ? imp.alias.value : imp.name.value;
|
||||
node.d.imports.forEach((imp) => {
|
||||
const symbolName = imp.d.alias ? imp.d.alias.d.value : imp.d.name.d.value;
|
||||
const symbolInfo = currentScope.lookUpSymbolRecursive(symbolName);
|
||||
if (symbolInfo) {
|
||||
trackedImportFrom!.addSymbol(
|
||||
symbolInfo.symbol,
|
||||
imp.name.value,
|
||||
imp.alias ? imp.alias.value : undefined,
|
||||
imp.d.name.d.value,
|
||||
imp.d.alias ? imp.d.alias.d.value : undefined,
|
||||
false
|
||||
);
|
||||
}
|
||||
@ -560,18 +561,18 @@ export class TypeStubWriter extends ParseTreeWalker {
|
||||
}
|
||||
|
||||
override visitStatementList(node: StatementListNode) {
|
||||
if (node.statements.length > 0 && node.statements[0].nodeType === ParseNodeType.StringList) {
|
||||
if (node.d.statements.length > 0 && node.d.statements[0].nodeType === ParseNodeType.StringList) {
|
||||
// Is this the first statement in a suite? If it's a string
|
||||
// literal, assume it's a doc string and emit it.
|
||||
if (!this._emittedSuite && this._emitDocString) {
|
||||
this._emitLine(this._printExpression(node.statements[0]));
|
||||
this._emitLine(this._printExpression(node.d.statements[0]));
|
||||
}
|
||||
}
|
||||
|
||||
// Don't emit a doc string after the first statement.
|
||||
this._emitDocString = false;
|
||||
|
||||
this.walkMultiple(node.statements);
|
||||
this.walkMultiple(node.d.statements);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -598,7 +599,7 @@ export class TypeStubWriter extends ParseTreeWalker {
|
||||
|
||||
private _emitDecorators(decorators: DecoratorNode[]) {
|
||||
decorators.forEach((decorator) => {
|
||||
this._emitLine('@' + this._printExpression(decorator.expression));
|
||||
this._emitLine('@' + this._printExpression(decorator.d.expression));
|
||||
});
|
||||
}
|
||||
|
||||
@ -623,28 +624,28 @@ export class TypeStubWriter extends ParseTreeWalker {
|
||||
}
|
||||
|
||||
private _printTypeParameters(node: TypeParameterListNode): string {
|
||||
return `[${node.parameters.map((typeParam) => this._printTypeParameter(typeParam)).join(',')}]`;
|
||||
return `[${node.d.parameters.map((typeParam) => this._printTypeParameter(typeParam)).join(',')}]`;
|
||||
}
|
||||
|
||||
private _printTypeParameter(node: TypeParameterNode): string {
|
||||
let line = '';
|
||||
|
||||
if (node.typeParamCategory === TypeParameterCategory.TypeVarTuple) {
|
||||
if (node.d.typeParamCategory === TypeParameterCategory.TypeVarTuple) {
|
||||
line += '*';
|
||||
} else if (node.typeParamCategory === TypeParameterCategory.ParamSpec) {
|
||||
} else if (node.d.typeParamCategory === TypeParameterCategory.ParamSpec) {
|
||||
line += '**';
|
||||
}
|
||||
|
||||
line += node.name.value;
|
||||
line += node.d.name.d.value;
|
||||
|
||||
if (node.boundExpression) {
|
||||
if (node.d.boundExpression) {
|
||||
line += ': ';
|
||||
line += this._printExpression(node.boundExpression);
|
||||
line += this._printExpression(node.d.boundExpression);
|
||||
}
|
||||
|
||||
if (node.defaultExpression) {
|
||||
if (node.d.defaultExpression) {
|
||||
line += ' = ';
|
||||
line += this._printExpression(node.defaultExpression);
|
||||
line += this._printExpression(node.d.defaultExpression);
|
||||
}
|
||||
|
||||
return line;
|
||||
@ -652,24 +653,24 @@ export class TypeStubWriter extends ParseTreeWalker {
|
||||
|
||||
private _printModuleName(node: ModuleNameNode): string {
|
||||
let line = '';
|
||||
for (let i = 0; i < node.leadingDots; i++) {
|
||||
for (let i = 0; i < node.d.leadingDots; i++) {
|
||||
line += '.';
|
||||
}
|
||||
line += node.nameParts.map((part) => part.value).join('.');
|
||||
line += node.d.nameParts.map((part) => part.d.value).join('.');
|
||||
return line;
|
||||
}
|
||||
|
||||
private _printParameter(paramNode: ParameterNode, functionNode: FunctionNode, paramIndex: number): string {
|
||||
let line = '';
|
||||
if (paramNode.category === ParameterCategory.ArgsList) {
|
||||
if (paramNode.d.category === ParameterCategory.ArgsList) {
|
||||
line += '*';
|
||||
} else if (paramNode.category === ParameterCategory.KwargsDict) {
|
||||
} else if (paramNode.d.category === ParameterCategory.KwargsDict) {
|
||||
line += '**';
|
||||
}
|
||||
|
||||
if (paramNode.name) {
|
||||
line += paramNode.name.value;
|
||||
} else if (paramNode.category === ParameterCategory.Simple) {
|
||||
if (paramNode.d.name) {
|
||||
line += paramNode.d.name.d.value;
|
||||
} else if (paramNode.d.category === ParameterCategory.Simple) {
|
||||
line += '/';
|
||||
}
|
||||
|
||||
@ -683,7 +684,7 @@ export class TypeStubWriter extends ParseTreeWalker {
|
||||
line += ': ' + paramType;
|
||||
}
|
||||
|
||||
if (paramNode.defaultValue) {
|
||||
if (paramNode.d.defaultValue) {
|
||||
// Follow PEP8 spacing rules. Include spaces if type
|
||||
// annotation is present, no space otherwise.
|
||||
if (paramType) {
|
||||
|
@ -9,10 +9,11 @@
|
||||
|
||||
import { appendArray } from '../common/collectionUtils';
|
||||
import { assert } from '../common/debug';
|
||||
import { ParameterCategory } from '../parser/parseNodes';
|
||||
import { ArgumentNode, ParameterCategory } from '../parser/parseNodes';
|
||||
import { DeclarationType } from './declaration';
|
||||
import { Symbol, SymbolFlags, SymbolTable } from './symbol';
|
||||
import { isEffectivelyClassVar, isTypedDictMemberAccessedThroughIndex } from './symbolUtils';
|
||||
import { FunctionArgumentWithExpression } from './typeEvaluatorTypes';
|
||||
import {
|
||||
AnyType,
|
||||
ClassType,
|
||||
@ -3327,6 +3328,14 @@ export function getDeclaringModulesForType(type: Type): string[] {
|
||||
return moduleList;
|
||||
}
|
||||
|
||||
export function convertArgumentNodeToFunctionArgument(node: ArgumentNode): FunctionArgumentWithExpression {
|
||||
return {
|
||||
argumentCategory: node.d.argumentCategory,
|
||||
name: node.d.name,
|
||||
valueExpression: node.d.valueExpression,
|
||||
};
|
||||
}
|
||||
|
||||
function addDeclaringModuleNamesForType(type: Type, moduleList: string[], recursionCount = 0) {
|
||||
if (recursionCount > maxTypeRecursionCount) {
|
||||
return;
|
||||
|
@ -96,7 +96,7 @@ export function createTypedDictType(
|
||||
argList[0].valueExpression || errorNode
|
||||
);
|
||||
} else {
|
||||
className = nameArg.valueExpression.strings.map((s) => s.value).join('');
|
||||
className = nameArg.valueExpression.d.strings.map((s) => s.d.value).join('');
|
||||
}
|
||||
}
|
||||
|
||||
@ -142,7 +142,7 @@ export function createTypedDictType(
|
||||
continue;
|
||||
}
|
||||
|
||||
if (entrySet.has(entry.name.value)) {
|
||||
if (entrySet.has(entry.name.d.value)) {
|
||||
evaluator.addDiagnostic(
|
||||
DiagnosticRule.reportGeneralTypeIssues,
|
||||
LocMessage.typedDictEntryUnique(),
|
||||
@ -152,7 +152,7 @@ export function createTypedDictType(
|
||||
}
|
||||
|
||||
// Record names in a map to detect duplicates.
|
||||
entrySet.add(entry.name.value);
|
||||
entrySet.add(entry.name.d.value);
|
||||
|
||||
const newSymbol = new Symbol(SymbolFlags.InstanceMember);
|
||||
const declaration: VariableDeclaration = {
|
||||
@ -171,7 +171,7 @@ export function createTypedDictType(
|
||||
};
|
||||
newSymbol.addDeclaration(declaration);
|
||||
|
||||
classFields.set(entry.name.value, newSymbol);
|
||||
classFields.set(entry.name.d.value, newSymbol);
|
||||
}
|
||||
} else {
|
||||
evaluator.addDiagnostic(DiagnosticRule.reportArgumentType, LocMessage.typedDictSecondArgDict(), errorNode);
|
||||
@ -180,23 +180,23 @@ export function createTypedDictType(
|
||||
|
||||
if (usingDictSyntax) {
|
||||
for (const arg of argList.slice(2)) {
|
||||
if (arg.name?.value === 'total' || arg.name?.value === 'closed') {
|
||||
if (arg.name?.d.value === 'total' || arg.name?.d.value === 'closed') {
|
||||
if (
|
||||
!arg.valueExpression ||
|
||||
arg.valueExpression.nodeType !== ParseNodeType.Constant ||
|
||||
!(
|
||||
arg.valueExpression.constType === KeywordType.False ||
|
||||
arg.valueExpression.constType === KeywordType.True
|
||||
arg.valueExpression.d.constType === KeywordType.False ||
|
||||
arg.valueExpression.d.constType === KeywordType.True
|
||||
)
|
||||
) {
|
||||
evaluator.addDiagnostic(
|
||||
DiagnosticRule.reportGeneralTypeIssues,
|
||||
LocMessage.typedDictBoolParam().format({ name: arg.name.value }),
|
||||
LocMessage.typedDictBoolParam().format({ name: arg.name.d.value }),
|
||||
arg.valueExpression || errorNode
|
||||
);
|
||||
} else if (arg.name.value === 'total' && arg.valueExpression.constType === KeywordType.False) {
|
||||
} else if (arg.name.d.value === 'total' && arg.valueExpression.d.constType === KeywordType.False) {
|
||||
classType.shared.flags |= ClassTypeFlags.CanOmitDictValues;
|
||||
} else if (arg.name.value === 'closed' && arg.valueExpression.constType === KeywordType.True) {
|
||||
} else if (arg.name.d.value === 'closed' && arg.valueExpression.d.constType === KeywordType.True) {
|
||||
// This is an experimental feature because PEP 728 hasn't been accepted yet.
|
||||
if (AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.enableExperimentalFeatures) {
|
||||
classType.shared.flags |=
|
||||
@ -217,11 +217,11 @@ export function createTypedDictType(
|
||||
|
||||
// Validate that the assigned variable name is consistent with the provided name.
|
||||
if (errorNode.parent?.nodeType === ParseNodeType.Assignment && className) {
|
||||
const target = errorNode.parent.leftExpression;
|
||||
const typedDictTarget = target.nodeType === ParseNodeType.TypeAnnotation ? target.valueExpression : target;
|
||||
const target = errorNode.parent.d.leftExpression;
|
||||
const typedDictTarget = target.nodeType === ParseNodeType.TypeAnnotation ? target.d.valueExpression : target;
|
||||
|
||||
if (typedDictTarget.nodeType === ParseNodeType.Name) {
|
||||
if (typedDictTarget.value !== className) {
|
||||
if (typedDictTarget.d.value !== className) {
|
||||
evaluator.addDiagnostic(
|
||||
DiagnosticRule.reportGeneralTypeIssues,
|
||||
LocMessage.typedDictAssignedName().format({
|
||||
@ -898,7 +898,7 @@ function getTypedDictFieldsFromDictSyntax(
|
||||
const entrySet = new Set<string>();
|
||||
const fileInfo = AnalyzerNodeInfo.getFileInfo(entryDict);
|
||||
|
||||
entryDict.entries.forEach((entry) => {
|
||||
entryDict.d.entries.forEach((entry) => {
|
||||
if (entry.nodeType !== ParseNodeType.DictionaryKeyEntry) {
|
||||
evaluator.addDiagnostic(
|
||||
DiagnosticRule.reportGeneralTypeIssues,
|
||||
@ -908,21 +908,21 @@ function getTypedDictFieldsFromDictSyntax(
|
||||
return;
|
||||
}
|
||||
|
||||
if (entry.keyExpression.nodeType !== ParseNodeType.StringList) {
|
||||
if (entry.d.keyExpression.nodeType !== ParseNodeType.StringList) {
|
||||
evaluator.addDiagnostic(
|
||||
DiagnosticRule.reportGeneralTypeIssues,
|
||||
LocMessage.typedDictEntryName(),
|
||||
entry.keyExpression
|
||||
entry.d.keyExpression
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
const entryName = entry.keyExpression.strings.map((s) => s.value).join('');
|
||||
const entryName = entry.d.keyExpression.d.strings.map((s) => s.d.value).join('');
|
||||
if (!entryName) {
|
||||
evaluator.addDiagnostic(
|
||||
DiagnosticRule.reportGeneralTypeIssues,
|
||||
LocMessage.typedDictEmptyName(),
|
||||
entry.keyExpression
|
||||
entry.d.keyExpression
|
||||
);
|
||||
return;
|
||||
}
|
||||
@ -931,7 +931,7 @@ function getTypedDictFieldsFromDictSyntax(
|
||||
evaluator.addDiagnostic(
|
||||
DiagnosticRule.reportGeneralTypeIssues,
|
||||
LocMessage.typedDictEntryUnique(),
|
||||
entry.keyExpression
|
||||
entry.d.keyExpression
|
||||
);
|
||||
return;
|
||||
}
|
||||
@ -942,13 +942,13 @@ function getTypedDictFieldsFromDictSyntax(
|
||||
const newSymbol = new Symbol(SymbolFlags.InstanceMember);
|
||||
const declaration: VariableDeclaration = {
|
||||
type: DeclarationType.Variable,
|
||||
node: entry.keyExpression,
|
||||
node: entry.d.keyExpression,
|
||||
uri: fileInfo.fileUri,
|
||||
typeAnnotationNode: entry.valueExpression,
|
||||
typeAnnotationNode: entry.d.valueExpression,
|
||||
isRuntimeTypeExpression: !isInline,
|
||||
range: convertOffsetsToRange(
|
||||
entry.keyExpression.start,
|
||||
TextRange.getEnd(entry.keyExpression),
|
||||
entry.d.keyExpression.start,
|
||||
TextRange.getEnd(entry.d.keyExpression),
|
||||
fileInfo.lines
|
||||
),
|
||||
moduleName: fileInfo.moduleName,
|
||||
@ -1416,23 +1416,27 @@ export function getTypeOfIndexedTypedDict(
|
||||
baseType: ClassType,
|
||||
usage: EvaluatorUsage
|
||||
): TypeResult | undefined {
|
||||
if (node.items.length !== 1) {
|
||||
if (node.d.items.length !== 1) {
|
||||
evaluator.addDiagnostic(
|
||||
DiagnosticRule.reportGeneralTypeIssues,
|
||||
LocMessage.typeArgsMismatchOne().format({ received: node.items.length }),
|
||||
LocMessage.typeArgsMismatchOne().format({ received: node.d.items.length }),
|
||||
node
|
||||
);
|
||||
return { type: UnknownType.create() };
|
||||
}
|
||||
|
||||
// Look for subscript types that are not supported by TypedDict.
|
||||
if (node.trailingComma || node.items[0].name || node.items[0].argumentCategory !== ArgumentCategory.Simple) {
|
||||
if (
|
||||
node.d.trailingComma ||
|
||||
node.d.items[0].d.name ||
|
||||
node.d.items[0].d.argumentCategory !== ArgumentCategory.Simple
|
||||
) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const entries = getTypedDictMembersForClass(evaluator, baseType, /* allowNarrowed */ usage.method === 'get');
|
||||
|
||||
const indexTypeResult = evaluator.getTypeOfExpression(node.items[0].valueExpression);
|
||||
const indexTypeResult = evaluator.getTypeOfExpression(node.d.items[0].d.valueExpression);
|
||||
const indexType = indexTypeResult.type;
|
||||
let diag = new DiagnosticAddendum();
|
||||
let allDiagsInvolveNotRequiredKeys = true;
|
||||
|
@ -272,7 +272,7 @@ function getTypeEvaluatorString(
|
||||
switch (node.parent?.nodeType) {
|
||||
case ParseNodeType.Class: {
|
||||
const result = cacheOnly
|
||||
? evaluator.getCachedType(node.parent.name)
|
||||
? evaluator.getCachedType(node.parent.d.name)
|
||||
: evaluator.getTypeOfClass(node.parent as ClassNode);
|
||||
if (!result) {
|
||||
return 'N/A';
|
||||
@ -282,7 +282,7 @@ function getTypeEvaluatorString(
|
||||
}
|
||||
case ParseNodeType.Function: {
|
||||
const result = cacheOnly
|
||||
? evaluator.getCachedType(node.parent.name)
|
||||
? evaluator.getCachedType(node.parent.d.name)
|
||||
: evaluator.getTypeOfFunction(node.parent as FunctionNode);
|
||||
if (!result) {
|
||||
return 'N/A';
|
||||
@ -578,7 +578,7 @@ class TreeDumper extends ParseTreeWalker {
|
||||
}
|
||||
|
||||
override visitArgument(node: ArgumentNode) {
|
||||
this._log(`${this._getPrefix(node)} ${getArgumentCategoryString(node.argumentCategory)}`);
|
||||
this._log(`${this._getPrefix(node)} ${getArgumentCategoryString(node.d.argumentCategory)}`);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -598,7 +598,7 @@ class TreeDumper extends ParseTreeWalker {
|
||||
}
|
||||
|
||||
override visitAugmentedAssignment(node: AugmentedAssignmentNode) {
|
||||
this._log(`${this._getPrefix(node)} ${getOperatorTypeString(node.operator)}`);
|
||||
this._log(`${this._getPrefix(node)} ${getOperatorTypeString(node.d.operator)}`);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -611,9 +611,9 @@ class TreeDumper extends ParseTreeWalker {
|
||||
this._log(
|
||||
`${this._getPrefix(node)} ${getTokenString(
|
||||
this._uri,
|
||||
node.operatorToken,
|
||||
node.d.operatorToken,
|
||||
this._lines
|
||||
)} ${getOperatorTypeString(node.operator)}} parenthesized:(${node.isParenthesized})`
|
||||
)} ${getOperatorTypeString(node.d.operator)}} parenthesized:(${node.d.isParenthesized})`
|
||||
);
|
||||
return true;
|
||||
}
|
||||
@ -639,7 +639,7 @@ class TreeDumper extends ParseTreeWalker {
|
||||
}
|
||||
|
||||
override visitComprehensionFor(node: ComprehensionForNode) {
|
||||
this._log(`${this._getPrefix(node)} async:(${node.isAsync})`);
|
||||
this._log(`${this._getPrefix(node)} async:(${node.d.isAsync})`);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -654,7 +654,7 @@ class TreeDumper extends ParseTreeWalker {
|
||||
}
|
||||
|
||||
override visitConstant(node: ConstantNode) {
|
||||
this._log(`${this._getPrefix(node)} ${getKeywordTypeString(node.constType)}`);
|
||||
this._log(`${this._getPrefix(node)} ${getKeywordTypeString(node.d.constType)}`);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -684,7 +684,7 @@ class TreeDumper extends ParseTreeWalker {
|
||||
}
|
||||
|
||||
override visitError(node: ErrorNode) {
|
||||
this._log(`${this._getPrefix(node)} ${getErrorExpressionCategoryString(node.category)}`);
|
||||
this._log(`${this._getPrefix(node)} ${getErrorExpressionCategoryString(node.d.category)}`);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -710,11 +710,11 @@ class TreeDumper extends ParseTreeWalker {
|
||||
|
||||
override visitImportFrom(node: ImportFromNode) {
|
||||
this._log(
|
||||
`${this._getPrefix(node)} wildcard import:(${node.isWildcardImport}) paren:(${
|
||||
node.usesParens
|
||||
`${this._getPrefix(node)} wildcard import:(${node.d.isWildcardImport}) paren:(${
|
||||
node.d.usesParens
|
||||
}) wildcard token:(${
|
||||
node.wildcardToken ? getTokenString(this._uri, node.wildcardToken, this._lines) : 'N/A'
|
||||
}) missing import keyword:(${node.missingImportKeyword})`
|
||||
node.d.wildcardToken ? getTokenString(this._uri, node.d.wildcardToken, this._lines) : 'N/A'
|
||||
}) missing import keyword:(${node.d.missingImportKeyword})`
|
||||
);
|
||||
return true;
|
||||
}
|
||||
@ -735,7 +735,7 @@ class TreeDumper extends ParseTreeWalker {
|
||||
}
|
||||
|
||||
override visitFor(node: ForNode) {
|
||||
this._log(`${this._getPrefix(node)} async:(${node.isAsync})`);
|
||||
this._log(`${this._getPrefix(node)} async:(${node.d.isAsync})`);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -745,12 +745,12 @@ class TreeDumper extends ParseTreeWalker {
|
||||
}
|
||||
|
||||
override visitFunction(node: FunctionNode) {
|
||||
this._log(`${this._getPrefix(node)} async:(${node.isAsync})`);
|
||||
this._log(`${this._getPrefix(node)} async:(${node.d.isAsync})`);
|
||||
return true;
|
||||
}
|
||||
|
||||
override visitFunctionAnnotation(node: FunctionAnnotationNode) {
|
||||
this._log(`${this._getPrefix(node)} ellipsis:(${node.isParamListEllipsis})`);
|
||||
this._log(`${this._getPrefix(node)} ellipsis:(${node.d.isParamListEllipsis})`);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -780,12 +780,14 @@ class TreeDumper extends ParseTreeWalker {
|
||||
}
|
||||
|
||||
override visitModuleName(node: ModuleNameNode) {
|
||||
this._log(`${this._getPrefix(node)} leading dots:(${node.leadingDots}) trailing dot:(${node.hasTrailingDot})`);
|
||||
this._log(
|
||||
`${this._getPrefix(node)} leading dots:(${node.d.leadingDots}) trailing dot:(${node.d.hasTrailingDot})`
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
||||
override visitName(node: NameNode) {
|
||||
this._log(`${this._getPrefix(node)} ${getTokenString(this._uri, node.token, this._lines)} ${node.value}`);
|
||||
this._log(`${this._getPrefix(node)} ${getTokenString(this._uri, node.d.token, this._lines)} ${node.d.value}`);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -795,12 +797,14 @@ class TreeDumper extends ParseTreeWalker {
|
||||
}
|
||||
|
||||
override visitNumber(node: NumberNode) {
|
||||
this._log(`${this._getPrefix(node)} ${node.value} int:(${node.isInteger}) imaginary:(${node.isImaginary})`);
|
||||
this._log(
|
||||
`${this._getPrefix(node)} ${node.d.value} int:(${node.d.isInteger}) imaginary:(${node.d.isImaginary})`
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
||||
override visitParameter(node: ParameterNode) {
|
||||
this._log(`${this._getPrefix(node)} ${getParameterCategoryString(node.category)}`);
|
||||
this._log(`${this._getPrefix(node)} ${getParameterCategoryString(node.d.category)}`);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -835,7 +839,7 @@ class TreeDumper extends ParseTreeWalker {
|
||||
}
|
||||
|
||||
override visitString(node: StringNode) {
|
||||
this._log(`${this._getPrefix(node)} ${getTokenString(this._uri, node.token, this._lines)} ${node.value}`);
|
||||
this._log(`${this._getPrefix(node)} ${getTokenString(this._uri, node.d.token, this._lines)} ${node.d.value}`);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -855,7 +859,7 @@ class TreeDumper extends ParseTreeWalker {
|
||||
}
|
||||
|
||||
override visitTuple(node: TupleNode) {
|
||||
this._log(`${this._getPrefix(node)} paren:(${node.enclosedInParens})`);
|
||||
this._log(`${this._getPrefix(node)} paren:(${node.d.isParenthesized})`);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -873,9 +877,9 @@ class TreeDumper extends ParseTreeWalker {
|
||||
this._log(
|
||||
`${this._getPrefix(node)} ${getTokenString(
|
||||
this._uri,
|
||||
node.operatorToken,
|
||||
node.d.operatorToken,
|
||||
this._lines
|
||||
)} ${getOperatorTypeString(node.operator)}`
|
||||
)} ${getOperatorTypeString(node.d.operator)}`
|
||||
);
|
||||
return true;
|
||||
}
|
||||
@ -891,7 +895,7 @@ class TreeDumper extends ParseTreeWalker {
|
||||
}
|
||||
|
||||
override visitWith(node: WithNode) {
|
||||
this._log(`${this._getPrefix(node)} async:(${node.isAsync})`);
|
||||
this._log(`${this._getPrefix(node)} async:(${node.d.isAsync})`);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -911,7 +915,7 @@ class TreeDumper extends ParseTreeWalker {
|
||||
}
|
||||
|
||||
override visitCase(node: CaseNode): boolean {
|
||||
this._log(`${this._getPrefix(node)} isIrrefutable: ${node.isIrrefutable}`);
|
||||
this._log(`${this._getPrefix(node)} isIrrefutable: ${node.d.isIrrefutable}`);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -926,7 +930,7 @@ class TreeDumper extends ParseTreeWalker {
|
||||
}
|
||||
|
||||
override visitPatternCapture(node: PatternCaptureNode): boolean {
|
||||
this._log(`${this._getPrefix(node)} isStar:${node.isStar} isWildcard:${node.isWildcard}`);
|
||||
this._log(`${this._getPrefix(node)} isStar:${node.d.isStar} isWildcard:${node.d.isWildcard}`);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -961,7 +965,7 @@ class TreeDumper extends ParseTreeWalker {
|
||||
}
|
||||
|
||||
override visitPatternSequence(node: PatternSequenceNode): boolean {
|
||||
this._log(`${this._getPrefix(node)} starEntryIndex: ${node.starEntryIndex}`);
|
||||
this._log(`${this._getPrefix(node)} starEntryIndex: ${node.d.starEntryIndex}`);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -977,7 +981,7 @@ class TreeDumper extends ParseTreeWalker {
|
||||
|
||||
override visitTypeParameter(node: TypeParameterNode): boolean {
|
||||
this._log(
|
||||
`${this._getPrefix(node)} typeParamCategory:${getTypeParameterCategoryString(node.typeParamCategory)}`
|
||||
`${this._getPrefix(node)} typeParamCategory:${getTypeParameterCategoryString(node.d.typeParamCategory)}`
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
@ -90,8 +90,8 @@ export class TextEditTracker {
|
||||
// used by remove unused imports.
|
||||
const imports: ImportFromAsNode[] | ImportAsNode[] =
|
||||
importToDelete.nodeType === ParseNodeType.ImportAs
|
||||
? (importToDelete.parent as ImportNode).list
|
||||
: (importToDelete.parent as ImportFromNode).imports;
|
||||
? (importToDelete.parent as ImportNode).d.list
|
||||
: (importToDelete.parent as ImportFromNode).d.imports;
|
||||
|
||||
const filePath = getFileInfo(parseFileResults.parserOutput.parseTree).fileUri;
|
||||
const ranges = getTextRangeForImportNameDeletion(
|
||||
@ -219,7 +219,7 @@ export class TextEditTracker {
|
||||
(i.moduleName === moduleNameInfo.nameForImportFrom || i.moduleName === moduleNameInfo.name)
|
||||
);
|
||||
|
||||
if (!imported || imported.node.nodeType !== ParseNodeType.ImportFrom || imported.node.isWildcardImport) {
|
||||
if (!imported || imported.node.nodeType !== ParseNodeType.ImportFrom || imported.node.d.isWildcardImport) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -260,8 +260,8 @@ export class TextEditTracker {
|
||||
const newLastModuleName = newModuleNames[newModuleNames.length - 1];
|
||||
|
||||
const alias = importNameInfo[0].alias === newLastModuleName ? lastModuleName : importNameInfo[0].alias;
|
||||
const importName = updateOptions.currentFromImport.imports.find(
|
||||
(i) => i.name.value === lastModuleName && i.alias?.value === alias
|
||||
const importName = updateOptions.currentFromImport.d.imports.find(
|
||||
(i) => i.d.name.d.value === lastModuleName && i.d.alias?.d.value === alias
|
||||
);
|
||||
|
||||
if (!importName) {
|
||||
@ -269,13 +269,13 @@ export class TextEditTracker {
|
||||
}
|
||||
|
||||
this._removeEdits(fileUri, deletions);
|
||||
if (importName.alias) {
|
||||
this._nodesRemoved.delete(importName.alias);
|
||||
if (importName.d.alias) {
|
||||
this._nodesRemoved.delete(importName.d.alias);
|
||||
}
|
||||
|
||||
this.addEdit(
|
||||
fileUri,
|
||||
convertTextRangeToRange(importName.name, parseFileResults.tokenizerOutput.lines),
|
||||
convertTextRangeToRange(importName.d.name, parseFileResults.tokenizerOutput.lines),
|
||||
newLastModuleName
|
||||
);
|
||||
|
||||
@ -415,15 +415,15 @@ export class TextEditTracker {
|
||||
// Mark that we don't need to process these node again later.
|
||||
this._nodesRemoved.set(nodeToDelete, parseFileResults);
|
||||
if (nodeToDelete.nodeType === ParseNodeType.ImportAs) {
|
||||
this._nodesRemoved.set(nodeToDelete.module, parseFileResults);
|
||||
nodeToDelete.module.nameParts.forEach((n) => this._nodesRemoved.set(n, parseFileResults));
|
||||
if (nodeToDelete.alias) {
|
||||
this._nodesRemoved.set(nodeToDelete.alias, parseFileResults);
|
||||
this._nodesRemoved.set(nodeToDelete.d.module, parseFileResults);
|
||||
nodeToDelete.d.module.d.nameParts.forEach((n) => this._nodesRemoved.set(n, parseFileResults));
|
||||
if (nodeToDelete.d.alias) {
|
||||
this._nodesRemoved.set(nodeToDelete.d.alias, parseFileResults);
|
||||
}
|
||||
} else if (nodeToDelete.nodeType === ParseNodeType.ImportFromAs) {
|
||||
this._nodesRemoved.set(nodeToDelete.name, parseFileResults);
|
||||
if (nodeToDelete.alias) {
|
||||
this._nodesRemoved.set(nodeToDelete.alias, parseFileResults);
|
||||
this._nodesRemoved.set(nodeToDelete.d.name, parseFileResults);
|
||||
if (nodeToDelete.d.alias) {
|
||||
this._nodesRemoved.set(nodeToDelete.d.alias, parseFileResults);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -266,7 +266,9 @@ export class AutoImporter {
|
||||
if (
|
||||
imported &&
|
||||
imported.node.nodeType === ParseNodeType.ImportFrom &&
|
||||
imported.node.imports.some((i) => i.name.value === importAliasData.importParts.symbolName)
|
||||
imported.node.d.imports.some(
|
||||
(i) => i.d.name.d.value === importAliasData.importParts.symbolName
|
||||
)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
@ -633,7 +635,7 @@ export class AutoImporter {
|
||||
if (importStatement.node.nodeType === ParseNodeType.Import) {
|
||||
// For now, we don't check whether alias or moduleName got overwritten at
|
||||
// given position
|
||||
const importAlias = importStatement.subnode?.alias?.value;
|
||||
const importAlias = importStatement.subnode?.d.alias?.d.value;
|
||||
if (importNameInfo.name) {
|
||||
// ex) import module
|
||||
// method | <= auto-import
|
||||
@ -655,14 +657,14 @@ export class AutoImporter {
|
||||
if (
|
||||
importNameInfo.name &&
|
||||
importStatement.node.nodeType === ParseNodeType.ImportFrom &&
|
||||
!importStatement.node.isWildcardImport
|
||||
!importStatement.node.d.isWildcardImport
|
||||
) {
|
||||
// If so, see whether what we want already exist.
|
||||
const importNode = importStatement.node.imports.find((i) => i.name.value === importNameInfo.name);
|
||||
const importNode = importStatement.node.d.imports.find((i) => i.d.name.d.value === importNameInfo.name);
|
||||
if (importNode) {
|
||||
// For now, we don't check whether alias or moduleName got overwritten at
|
||||
// given position
|
||||
const importAlias = importNode.alias?.value;
|
||||
const importAlias = importNode.d.alias?.d.value;
|
||||
return {
|
||||
insertionText: `${importAlias ?? importNameInfo.name}`,
|
||||
edits: [],
|
||||
@ -689,12 +691,12 @@ export class AutoImporter {
|
||||
// If it is the module itself that got imported, make sure we don't import it again.
|
||||
// ex) from module import submodule
|
||||
const imported = this._importStatements.orderedImports.find((i) => i.moduleName === moduleNameInfo.name);
|
||||
if (imported && imported.node.nodeType === ParseNodeType.ImportFrom && !imported.node.isWildcardImport) {
|
||||
const importFrom = imported.node.imports.find((i) => i.name.value === importNameInfo.name);
|
||||
if (imported && imported.node.nodeType === ParseNodeType.ImportFrom && !imported.node.d.isWildcardImport) {
|
||||
const importFrom = imported.node.d.imports.find((i) => i.d.name.d.value === importNameInfo.name);
|
||||
if (importFrom) {
|
||||
// For now, we don't check whether alias or moduleName got overwritten at
|
||||
// given position. only move to alias, but not the other way around
|
||||
const importAlias = importFrom.alias?.value;
|
||||
const importAlias = importFrom.d.alias?.d.value;
|
||||
if (importAlias) {
|
||||
return {
|
||||
insertionText: `${importAlias}`,
|
||||
@ -717,9 +719,9 @@ export class AutoImporter {
|
||||
if (importFrom) {
|
||||
// For now, we don't check whether alias or moduleName got overwritten at
|
||||
// given position
|
||||
const importAlias = importFrom.alias?.value;
|
||||
const importAlias = importFrom.d.alias?.d.value;
|
||||
return {
|
||||
insertionText: `${importAlias ?? importFrom.name.value}.${importNameInfo.name}`,
|
||||
insertionText: `${importAlias ?? importFrom.d.name.d.value}.${importNameInfo.name}`,
|
||||
edits: [],
|
||||
};
|
||||
}
|
||||
|
@ -250,7 +250,7 @@ export class CallHierarchyProvider {
|
||||
// This simplifies our code and ensures compatibility with the LSP specification.
|
||||
let callItemUri: Uri;
|
||||
if (targetDecl.type === DeclarationType.Alias) {
|
||||
symbolName = (referencesResult.nodeAtOffset as NameNode).value;
|
||||
symbolName = (referencesResult.nodeAtOffset as NameNode).d.value;
|
||||
callItemUri = this._fileUri;
|
||||
} else {
|
||||
symbolName = DeclarationUtils.getNameFromDeclaration(targetDecl) || referencesResult.symbolNames[0];
|
||||
@ -308,10 +308,10 @@ class FindOutgoingCallTreeWalker extends ParseTreeWalker {
|
||||
|
||||
let nameNode: NameNode | undefined;
|
||||
|
||||
if (node.leftExpression.nodeType === ParseNodeType.Name) {
|
||||
nameNode = node.leftExpression;
|
||||
} else if (node.leftExpression.nodeType === ParseNodeType.MemberAccess) {
|
||||
nameNode = node.leftExpression.memberName;
|
||||
if (node.d.leftExpression.nodeType === ParseNodeType.Name) {
|
||||
nameNode = node.d.leftExpression;
|
||||
} else if (node.d.leftExpression.nodeType === ParseNodeType.MemberAccess) {
|
||||
nameNode = node.d.leftExpression.d.memberName;
|
||||
}
|
||||
|
||||
if (nameNode) {
|
||||
@ -336,7 +336,7 @@ class FindOutgoingCallTreeWalker extends ParseTreeWalker {
|
||||
// Determine whether the member corresponds to a property.
|
||||
// If so, we'll treat it as a function call for purposes of
|
||||
// finding outgoing calls.
|
||||
const leftHandType = this._evaluator.getType(node.leftExpression);
|
||||
const leftHandType = this._evaluator.getType(node.d.leftExpression);
|
||||
if (leftHandType) {
|
||||
doForEachSubtype(leftHandType, (subtype) => {
|
||||
let baseType = subtype;
|
||||
@ -348,7 +348,7 @@ class FindOutgoingCallTreeWalker extends ParseTreeWalker {
|
||||
return;
|
||||
}
|
||||
|
||||
const memberInfo = lookUpObjectMember(baseType, node.memberName.value);
|
||||
const memberInfo = lookUpObjectMember(baseType, node.d.memberName.d.value);
|
||||
if (!memberInfo) {
|
||||
return;
|
||||
}
|
||||
@ -362,7 +362,7 @@ class FindOutgoingCallTreeWalker extends ParseTreeWalker {
|
||||
|
||||
if (isClassInstance(memberType) && ClassType.isPropertyClass(memberType)) {
|
||||
propertyDecls.forEach((decl) => {
|
||||
this._addOutgoingCallForDeclaration(node.memberName, decl);
|
||||
this._addOutgoingCallForDeclaration(node.d.memberName, decl);
|
||||
});
|
||||
}
|
||||
});
|
||||
@ -382,8 +382,8 @@ class FindOutgoingCallTreeWalker extends ParseTreeWalker {
|
||||
}
|
||||
|
||||
const callDest: CallHierarchyItem = {
|
||||
name: nameNode.value,
|
||||
kind: getSymbolKind(resolvedDecl, this._evaluator, nameNode.value) ?? SymbolKind.Module,
|
||||
name: nameNode.d.value,
|
||||
kind: getSymbolKind(resolvedDecl, this._evaluator, nameNode.d.value) ?? SymbolKind.Module,
|
||||
uri: convertUriToLspUriString(this._fs, resolvedDecl.uri),
|
||||
range: resolvedDecl.range,
|
||||
selectionRange: resolvedDecl.range,
|
||||
@ -403,10 +403,10 @@ class FindOutgoingCallTreeWalker extends ParseTreeWalker {
|
||||
this._outgoingCalls.push(outgoingCall);
|
||||
}
|
||||
|
||||
if (outgoingCall && outgoingCall.to.name !== nameNode.value) {
|
||||
if (outgoingCall && outgoingCall.to.name !== nameNode.d.value) {
|
||||
// If both the function and its alias are called in the same function,
|
||||
// the name of the call item will be the resolved declaration name, not the alias.
|
||||
outgoingCall.to.name = DeclarationUtils.getNameFromDeclaration(resolvedDecl) ?? nameNode.value;
|
||||
outgoingCall.to.name = DeclarationUtils.getNameFromDeclaration(resolvedDecl) ?? nameNode.d.value;
|
||||
}
|
||||
|
||||
const fromRange: Range = convertOffsetsToRange(
|
||||
@ -454,14 +454,14 @@ class FindIncomingCallTreeWalker extends ParseTreeWalker {
|
||||
throwIfCancellationRequested(this._cancellationToken);
|
||||
|
||||
let nameNode: NameNode | undefined;
|
||||
if (node.leftExpression.nodeType === ParseNodeType.Name) {
|
||||
nameNode = node.leftExpression;
|
||||
} else if (node.leftExpression.nodeType === ParseNodeType.MemberAccess) {
|
||||
nameNode = node.leftExpression.memberName;
|
||||
if (node.d.leftExpression.nodeType === ParseNodeType.Name) {
|
||||
nameNode = node.d.leftExpression;
|
||||
} else if (node.d.leftExpression.nodeType === ParseNodeType.MemberAccess) {
|
||||
nameNode = node.d.leftExpression.d.memberName;
|
||||
}
|
||||
|
||||
// Don't bother doing any more work if the name doesn't match.
|
||||
if (nameNode && nameNode.value === this._symbolName) {
|
||||
if (nameNode && nameNode.d.value === this._symbolName) {
|
||||
const declarations = this._getDeclarations(nameNode);
|
||||
if (declarations) {
|
||||
if (this._targetDeclaration.type === DeclarationType.Alias) {
|
||||
@ -491,11 +491,11 @@ class FindIncomingCallTreeWalker extends ParseTreeWalker {
|
||||
override visitMemberAccess(node: MemberAccessNode): boolean {
|
||||
throwIfCancellationRequested(this._cancellationToken);
|
||||
|
||||
if (node.memberName.value === this._symbolName) {
|
||||
if (node.d.memberName.d.value === this._symbolName) {
|
||||
// Determine whether the member corresponds to a property.
|
||||
// If so, we'll treat it as a function call for purposes of
|
||||
// finding outgoing calls.
|
||||
const leftHandType = this._evaluator.getType(node.leftExpression);
|
||||
const leftHandType = this._evaluator.getType(node.d.leftExpression);
|
||||
if (leftHandType) {
|
||||
doForEachSubtype(leftHandType, (subtype) => {
|
||||
let baseType = subtype;
|
||||
@ -507,7 +507,7 @@ class FindIncomingCallTreeWalker extends ParseTreeWalker {
|
||||
return;
|
||||
}
|
||||
|
||||
const memberInfo = lookUpObjectMember(baseType, node.memberName.value);
|
||||
const memberInfo = lookUpObjectMember(baseType, node.d.memberName.d.value);
|
||||
if (!memberInfo) {
|
||||
return;
|
||||
}
|
||||
@ -524,7 +524,7 @@ class FindIncomingCallTreeWalker extends ParseTreeWalker {
|
||||
DeclarationUtils.areDeclarationsSame(decl!, this._targetDeclaration)
|
||||
)
|
||||
) {
|
||||
this._addIncomingCallForDeclaration(node.memberName);
|
||||
this._addIncomingCallForDeclaration(node.d.memberName);
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -589,13 +589,13 @@ class FindIncomingCallTreeWalker extends ParseTreeWalker {
|
||||
};
|
||||
} else {
|
||||
const functionRange = convertOffsetsToRange(
|
||||
executionNode.name.start,
|
||||
executionNode.name.start + executionNode.name.length,
|
||||
executionNode.d.name.start,
|
||||
executionNode.d.name.start + executionNode.d.name.length,
|
||||
this._parseResults.tokenizerOutput.lines
|
||||
);
|
||||
|
||||
callSource = {
|
||||
name: executionNode.name.value,
|
||||
name: executionNode.d.name.d.value,
|
||||
kind: SymbolKind.Function,
|
||||
uri: convertUriToLspUriString(this._program.fileSystem, this._fileUri),
|
||||
range: functionRange,
|
||||
|
@ -440,7 +440,7 @@ export class CompletionProvider {
|
||||
symbolTable.forEach((symbol, name) => {
|
||||
let decl = getLastTypedDeclarationForSymbol(symbol);
|
||||
if (decl && decl.type === DeclarationType.Function) {
|
||||
if (StringUtils.isPatternInSymbol(partialName.value, name)) {
|
||||
if (StringUtils.isPatternInSymbol(partialName.d.value, name)) {
|
||||
const declaredType = this.evaluator.getTypeForDeclaration(decl)?.type;
|
||||
if (!declaredType) {
|
||||
return;
|
||||
@ -491,14 +491,14 @@ export class CompletionProvider {
|
||||
isDeclaredStaticMethod,
|
||||
isProperty,
|
||||
decl,
|
||||
decl.node.isAsync
|
||||
decl.node.d.isAsync
|
||||
);
|
||||
text = `${methodSignature}:\n${methodBody}`;
|
||||
}
|
||||
|
||||
const textEdit = this.createReplaceEdits(priorWord, partialName, text);
|
||||
|
||||
this.addSymbol(name, symbol, partialName.value, completionMap, {
|
||||
this.addSymbol(name, symbol, partialName.d.value, completionMap, {
|
||||
// method signature already contains ()
|
||||
funcParensDisabled: true,
|
||||
edits: {
|
||||
@ -531,13 +531,13 @@ export class CompletionProvider {
|
||||
return sb;
|
||||
}
|
||||
|
||||
if (decl.node.parameters.length === 0) {
|
||||
if (decl.node.d.parameters.length === 0) {
|
||||
sb += this.options.snippet ? '${0:pass}' : 'pass';
|
||||
return sb;
|
||||
}
|
||||
|
||||
const parameters = getParameters(isStaticMethod ? decl.node.parameters : decl.node.parameters.slice(1));
|
||||
if (decl.node.name.value !== '__init__') {
|
||||
const parameters = getParameters(isStaticMethod ? decl.node.d.parameters : decl.node.d.parameters.slice(1));
|
||||
if (decl.node.d.name.d.value !== '__init__') {
|
||||
sb += 'return ';
|
||||
}
|
||||
|
||||
@ -546,26 +546,28 @@ export class CompletionProvider {
|
||||
}
|
||||
|
||||
if (isProperty) {
|
||||
return sb + `super().${decl.node.name.value}`;
|
||||
return sb + `super().${decl.node.d.name.d.value}`;
|
||||
}
|
||||
|
||||
return sb + `super().${decl.node.name.value}(${parameters.map(convertToString).join(', ')})`;
|
||||
return sb + `super().${decl.node.d.name.d.value}(${parameters.map(convertToString).join(', ')})`;
|
||||
|
||||
function getParameters(parameters: ParameterNode[]) {
|
||||
const results: [node: ParameterNode, keywordOnly: boolean][] = [];
|
||||
|
||||
let sawKeywordOnlySeparator = false;
|
||||
for (const parameter of parameters) {
|
||||
if (parameter.name) {
|
||||
if (parameter.d.name) {
|
||||
results.push([
|
||||
parameter,
|
||||
parameter.category === ParameterCategory.Simple && !!parameter.name && sawKeywordOnlySeparator,
|
||||
parameter.d.category === ParameterCategory.Simple &&
|
||||
!!parameter.d.name &&
|
||||
sawKeywordOnlySeparator,
|
||||
]);
|
||||
}
|
||||
|
||||
// All simple parameters after a `*` or `*args` parameter
|
||||
// are considered keyword only.
|
||||
if (parameter.category === ParameterCategory.ArgsList) {
|
||||
if (parameter.d.category === ParameterCategory.ArgsList) {
|
||||
sawKeywordOnlySeparator = true;
|
||||
}
|
||||
}
|
||||
@ -574,12 +576,12 @@ export class CompletionProvider {
|
||||
}
|
||||
|
||||
function convertToString(parameter: [node: ParameterNode, keywordOnly: boolean]) {
|
||||
const name = parameter[0].name?.value;
|
||||
if (parameter[0].category === ParameterCategory.ArgsList) {
|
||||
const name = parameter[0].d.name?.d.value;
|
||||
if (parameter[0].d.category === ParameterCategory.ArgsList) {
|
||||
return `*${name}`;
|
||||
}
|
||||
|
||||
if (parameter[0].category === ParameterCategory.KwargsDict) {
|
||||
if (parameter[0].d.category === ParameterCategory.KwargsDict) {
|
||||
return `**${name}`;
|
||||
}
|
||||
|
||||
@ -590,7 +592,7 @@ export class CompletionProvider {
|
||||
protected createReplaceEdits(priorWord: string, node: ParseNode | undefined, text: string) {
|
||||
const replaceOrInsertEndChar =
|
||||
node?.nodeType === ParseNodeType.Name
|
||||
? this.position.character - priorWord.length + node.value.length
|
||||
? this.position.character - priorWord.length + node.d.value.length
|
||||
: this.position.character;
|
||||
|
||||
const range: Range = {
|
||||
@ -1078,7 +1080,7 @@ export class CompletionProvider {
|
||||
ParseNodeType.FormatString
|
||||
);
|
||||
if (fStringContainer) {
|
||||
this._stringLiteralContainer = fStringContainer.token;
|
||||
this._stringLiteralContainer = fStringContainer.d.token;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1171,7 +1173,7 @@ export class CompletionProvider {
|
||||
}
|
||||
|
||||
if (curNode.nodeType === ParseNodeType.MemberAccess) {
|
||||
return this.getMemberAccessCompletions(curNode.leftExpression, priorWord);
|
||||
return this.getMemberAccessCompletions(curNode.d.leftExpression, priorWord);
|
||||
}
|
||||
|
||||
if (curNode.nodeType === ParseNodeType.Dictionary) {
|
||||
@ -1197,7 +1199,7 @@ export class CompletionProvider {
|
||||
if (dictionaryEntry) {
|
||||
if (dictionaryEntry.parent?.nodeType === ParseNodeType.Dictionary) {
|
||||
const dictionaryNode = dictionaryEntry.parent;
|
||||
if (dictionaryNode.trailingCommaToken && dictionaryNode.trailingCommaToken.start < offset) {
|
||||
if (dictionaryNode.d.trailingCommaToken && dictionaryNode.d.trailingCommaToken.start < offset) {
|
||||
const completionMap = new CompletionMap();
|
||||
if (
|
||||
this._tryAddTypedDictKeysFromDictionary(
|
||||
@ -1242,10 +1244,10 @@ export class CompletionProvider {
|
||||
if (
|
||||
curNode.parent &&
|
||||
curNode.parent.nodeType === ParseNodeType.Except &&
|
||||
!curNode.parent.name &&
|
||||
curNode.parent.typeExpression &&
|
||||
TextRange.getEnd(curNode.parent.typeExpression) < offset &&
|
||||
offset <= curNode.parent.exceptSuite.start
|
||||
!curNode.parent.d.name &&
|
||||
curNode.parent.d.typeExpression &&
|
||||
TextRange.getEnd(curNode.parent.d.typeExpression) < offset &&
|
||||
offset <= curNode.parent.d.exceptSuite.start
|
||||
) {
|
||||
// except Exception as [<empty>]
|
||||
return undefined;
|
||||
@ -1254,9 +1256,9 @@ export class CompletionProvider {
|
||||
if (
|
||||
curNode.parent &&
|
||||
curNode.parent.nodeType === ParseNodeType.Class &&
|
||||
(!curNode.parent.name || !curNode.parent.name.value) &&
|
||||
curNode.parent.arguments.length === 0 &&
|
||||
offset <= curNode.parent.suite.start
|
||||
(!curNode.parent.d.name || !curNode.parent.d.name.d.value) &&
|
||||
curNode.parent.d.arguments.length === 0 &&
|
||||
offset <= curNode.parent.d.suite.start
|
||||
) {
|
||||
// class [<empty>]
|
||||
return undefined;
|
||||
@ -1303,7 +1305,7 @@ export class CompletionProvider {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (curNode.parent.nodeType === ParseNodeType.ImportAs && curNode.parent.alias === curNode) {
|
||||
if (curNode.parent.nodeType === ParseNodeType.ImportAs && curNode.parent.d.alias === curNode) {
|
||||
// Are we within a "import Y as [Z]"?
|
||||
return undefined;
|
||||
}
|
||||
@ -1313,7 +1315,7 @@ export class CompletionProvider {
|
||||
if (
|
||||
curNode.parent.parent &&
|
||||
curNode.parent.parent.nodeType === ParseNodeType.ImportAs &&
|
||||
!curNode.parent.parent.alias &&
|
||||
!curNode.parent.parent.d.alias &&
|
||||
TextRange.getEnd(curNode.parent.parent) < offset
|
||||
) {
|
||||
return undefined;
|
||||
@ -1325,7 +1327,7 @@ export class CompletionProvider {
|
||||
}
|
||||
|
||||
if (curNode.parent.nodeType === ParseNodeType.ImportFromAs) {
|
||||
if (curNode.parent.alias === curNode) {
|
||||
if (curNode.parent.d.alias === curNode) {
|
||||
// Are we within a "from X import Y as [Z]"?
|
||||
return undefined;
|
||||
}
|
||||
@ -1333,11 +1335,11 @@ export class CompletionProvider {
|
||||
const parentNode = curNode.parent.parent;
|
||||
if (parentNode && parentNode.nodeType === ParseNodeType.ImportFrom) {
|
||||
// Are we within a "from X import Y as [<empty>]"?
|
||||
if (!curNode.parent.alias && TextRange.getEnd(curNode.parent) < offset) {
|
||||
if (!curNode.parent.d.alias && TextRange.getEnd(curNode.parent) < offset) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (curNode.parent.name === curNode) {
|
||||
if (curNode.parent.d.name === curNode) {
|
||||
return this._getImportFromCompletions(parentNode, offset, priorWord);
|
||||
}
|
||||
|
||||
@ -1347,40 +1349,40 @@ export class CompletionProvider {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (curNode.parent.nodeType === ParseNodeType.MemberAccess && curNode === curNode.parent.memberName) {
|
||||
return this.getMemberAccessCompletions(curNode.parent.leftExpression, priorWord);
|
||||
if (curNode.parent.nodeType === ParseNodeType.MemberAccess && curNode === curNode.parent.d.memberName) {
|
||||
return this.getMemberAccessCompletions(curNode.parent.d.leftExpression, priorWord);
|
||||
}
|
||||
|
||||
if (curNode.parent.nodeType === ParseNodeType.Except && curNode === curNode.parent.name) {
|
||||
if (curNode.parent.nodeType === ParseNodeType.Except && curNode === curNode.parent.d.name) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (curNode.parent.nodeType === ParseNodeType.Function && curNode === curNode.parent.name) {
|
||||
if (curNode.parent.decorators?.some((d) => this._isOverload(d))) {
|
||||
if (curNode.parent.nodeType === ParseNodeType.Function && curNode === curNode.parent.d.name) {
|
||||
if (curNode.parent.d.decorators?.some((d) => this._isOverload(d))) {
|
||||
return this._getMethodOverloadsCompletions(priorWord, curNode);
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (curNode.parent.nodeType === ParseNodeType.Parameter && curNode === curNode.parent.name) {
|
||||
if (curNode.parent.nodeType === ParseNodeType.Parameter && curNode === curNode.parent.d.name) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (curNode.parent.nodeType === ParseNodeType.Class && curNode === curNode.parent.name) {
|
||||
if (curNode.parent.nodeType === ParseNodeType.Class && curNode === curNode.parent.d.name) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (
|
||||
curNode.parent.nodeType === ParseNodeType.For &&
|
||||
TextRange.contains(curNode.parent.targetExpression, curNode.start)
|
||||
TextRange.contains(curNode.parent.d.targetExpression, curNode.start)
|
||||
) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (
|
||||
curNode.parent.nodeType === ParseNodeType.ComprehensionFor &&
|
||||
TextRange.contains(curNode.parent.targetExpression, curNode.start)
|
||||
TextRange.contains(curNode.parent.d.targetExpression, curNode.start)
|
||||
) {
|
||||
return undefined;
|
||||
}
|
||||
@ -1392,8 +1394,8 @@ export class CompletionProvider {
|
||||
) {
|
||||
const leftNode =
|
||||
curNode.parent.nodeType === ParseNodeType.AssignmentExpression
|
||||
? curNode.parent.name
|
||||
: curNode.parent.leftExpression;
|
||||
? curNode.parent.d.name
|
||||
: curNode.parent.d.leftExpression;
|
||||
|
||||
if (leftNode !== curNode || priorWord.length === 0) {
|
||||
return false;
|
||||
@ -1406,7 +1408,7 @@ export class CompletionProvider {
|
||||
|
||||
const completionMap = this._getExpressionCompletions(curNode, priorWord, priorText, postText);
|
||||
if (completionMap) {
|
||||
completionMap.delete(curNode.value);
|
||||
completionMap.delete(curNode.d.value);
|
||||
}
|
||||
|
||||
return completionMap;
|
||||
@ -1483,7 +1485,7 @@ export class CompletionProvider {
|
||||
// Is the error due to a missing member access name? If so,
|
||||
// we can evaluate the left side of the member access expression
|
||||
// to determine its type and offer suggestions based on it.
|
||||
switch (node.category) {
|
||||
switch (node.d.category) {
|
||||
case ErrorExpressionCategory.MissingIn: {
|
||||
return this._createSingleKeywordCompletion('in');
|
||||
}
|
||||
@ -1501,7 +1503,7 @@ export class CompletionProvider {
|
||||
const token = ParseTreeUtils.getTokenAtIndex(tokenizerOutput.tokens, index);
|
||||
const prevToken = ParseTreeUtils.getTokenAtIndex(tokenizerOutput.tokens, index - 1);
|
||||
|
||||
if (node.category === ErrorExpressionCategory.MissingExpression) {
|
||||
if (node.d.category === ErrorExpressionCategory.MissingExpression) {
|
||||
// Skip dots on expressions.
|
||||
if (token?.type === TokenType.Dot || token?.type === TokenType.Ellipsis) {
|
||||
break;
|
||||
@ -1531,14 +1533,14 @@ export class CompletionProvider {
|
||||
);
|
||||
if (
|
||||
previousNode?.nodeType !== ParseNodeType.Error ||
|
||||
previousNode.category !== ErrorExpressionCategory.MissingMemberAccessName
|
||||
previousNode.d.category !== ErrorExpressionCategory.MissingMemberAccessName
|
||||
) {
|
||||
return this._getExpressionCompletions(node, priorWord, priorText, postText);
|
||||
} else {
|
||||
// Update node to previous node so we get the member access completions.
|
||||
node = previousNode;
|
||||
}
|
||||
} else if (node.category === ErrorExpressionCategory.MissingMemberAccessName) {
|
||||
} else if (node.d.category === ErrorExpressionCategory.MissingMemberAccessName) {
|
||||
// Skip double dots on member access.
|
||||
if (
|
||||
(token?.type === TokenType.Dot || token?.type === TokenType.Ellipsis) &&
|
||||
@ -1567,14 +1569,14 @@ export class CompletionProvider {
|
||||
}
|
||||
|
||||
case ErrorExpressionCategory.MissingFunctionParameterList: {
|
||||
if (node.child && node.child.nodeType === ParseNodeType.Name) {
|
||||
if (node.decorators?.some((d) => this._isOverload(d))) {
|
||||
return this._getMethodOverloadsCompletions(priorWord, node.child);
|
||||
if (node.d.child && node.d.child.nodeType === ParseNodeType.Name) {
|
||||
if (node.d.decorators?.some((d) => this._isOverload(d))) {
|
||||
return this._getMethodOverloadsCompletions(priorWord, node.d.child);
|
||||
}
|
||||
|
||||
// Determine if the partial name is a method that's overriding
|
||||
// a method in a base class.
|
||||
return this.getMethodOverrideCompletions(priorWord, node.child, node.decorators);
|
||||
return this.getMethodOverrideCompletions(priorWord, node.d.child, node.d.decorators);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -1584,11 +1586,11 @@ export class CompletionProvider {
|
||||
}
|
||||
|
||||
private _getMissingMemberAccessNameCompletions(node: ErrorNode, priorWord: string) {
|
||||
if (!node.child || !isExpressionNode(node.child)) {
|
||||
if (!node.d.child || !isExpressionNode(node.d.child)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return this.getMemberAccessCompletions(node.child, priorWord);
|
||||
return this.getMemberAccessCompletions(node.d.child, priorWord);
|
||||
}
|
||||
|
||||
private _isOverload(node: DecoratorNode): boolean {
|
||||
@ -1613,8 +1615,8 @@ export class CompletionProvider {
|
||||
// f: |<= here
|
||||
const isTypeAnnotationOfClassVariable =
|
||||
parseNode.parent?.nodeType === ParseNodeType.TypeAnnotation &&
|
||||
parseNode.parent.valueExpression.nodeType === ParseNodeType.Name &&
|
||||
parseNode.parent.typeAnnotation === parseNode &&
|
||||
parseNode.parent.d.valueExpression.nodeType === ParseNodeType.Name &&
|
||||
parseNode.parent.d.typeAnnotation === parseNode &&
|
||||
parseNode.parent.parent?.nodeType === ParseNodeType.StatementList &&
|
||||
parseNode.parent.parent.parent?.nodeType === ParseNodeType.Suite &&
|
||||
parseNode.parent.parent.parent.parent?.nodeType === ParseNodeType.Class;
|
||||
@ -1633,7 +1635,7 @@ export class CompletionProvider {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const classVariableName = ((parseNode.parent as TypeAnnotationNode).valueExpression as NameNode).value;
|
||||
const classVariableName = ((parseNode.parent as TypeAnnotationNode).d.valueExpression as NameNode).d.value;
|
||||
const classMember = lookUpClassMember(
|
||||
classResults.classType,
|
||||
classVariableName,
|
||||
@ -1729,7 +1731,7 @@ export class CompletionProvider {
|
||||
SymbolNameUtils.isPrivateName(name) ||
|
||||
symbol.isPrivateMember() ||
|
||||
symbol.isExternallyHidden() ||
|
||||
!StringUtils.isPatternInSymbol(partialName.value, name)
|
||||
!StringUtils.isPatternInSymbol(partialName.d.value, name)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
@ -1746,7 +1748,7 @@ export class CompletionProvider {
|
||||
return;
|
||||
}
|
||||
|
||||
this.addSymbol(name, symbol, partialName.value, completionMap, {});
|
||||
this.addSymbol(name, symbol, partialName.d.value, completionMap, {});
|
||||
});
|
||||
|
||||
return completionMap.size > 0 ? completionMap : undefined;
|
||||
@ -1768,7 +1770,7 @@ export class CompletionProvider {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!decl.node.decorators.some((d) => this._isOverload(d))) {
|
||||
if (!decl.node.d.decorators.some((d) => this._isOverload(d))) {
|
||||
// Only consider ones that have overload decorator.
|
||||
return;
|
||||
}
|
||||
@ -1779,9 +1781,9 @@ export class CompletionProvider {
|
||||
return;
|
||||
}
|
||||
|
||||
if (StringUtils.isPatternInSymbol(partialName.value, name)) {
|
||||
const textEdit = this.createReplaceEdits(priorWord, partialName, decl.node.name.value);
|
||||
this.addSymbol(name, symbol, partialName.value, completionMap, {
|
||||
if (StringUtils.isPatternInSymbol(partialName.d.value, name)) {
|
||||
const textEdit = this.createReplaceEdits(priorWord, partialName, decl.node.d.name.d.value);
|
||||
this.addSymbol(name, symbol, partialName.d.value, completionMap, {
|
||||
funcParensDisabled,
|
||||
edits: { textEdit },
|
||||
});
|
||||
@ -1836,17 +1838,17 @@ export class CompletionProvider {
|
||||
ParseTreeUtils.PrintExpressionFlags.DoNotLimitStringLength
|
||||
: ParseTreeUtils.PrintExpressionFlags.DoNotLimitStringLength;
|
||||
|
||||
const paramList = node.parameters
|
||||
const paramList = node.d.parameters
|
||||
.map((param, index) => {
|
||||
let paramString = '';
|
||||
if (param.category === ParameterCategory.ArgsList) {
|
||||
if (param.d.category === ParameterCategory.ArgsList) {
|
||||
paramString += '*';
|
||||
} else if (param.category === ParameterCategory.KwargsDict) {
|
||||
} else if (param.d.category === ParameterCategory.KwargsDict) {
|
||||
paramString += '**';
|
||||
}
|
||||
|
||||
if (param.name) {
|
||||
paramString += param.name.value;
|
||||
if (param.d.name) {
|
||||
paramString += param.d.name.d.value;
|
||||
}
|
||||
|
||||
// Currently, we don't automatically add import if the type used in the annotation is not imported
|
||||
@ -1856,14 +1858,16 @@ export class CompletionProvider {
|
||||
paramString += ': ' + ParseTreeUtils.printExpression(paramTypeAnnotation, printFlags);
|
||||
}
|
||||
|
||||
if (param.defaultValue) {
|
||||
if (param.d.defaultValue) {
|
||||
paramString += paramTypeAnnotation ? ' = ' : '=';
|
||||
|
||||
const useEllipsis = ellipsisForDefault ?? !ParseTreeUtils.isSimpleDefault(param.defaultValue);
|
||||
paramString += useEllipsis ? '...' : ParseTreeUtils.printExpression(param.defaultValue, printFlags);
|
||||
const useEllipsis = ellipsisForDefault ?? !ParseTreeUtils.isSimpleDefault(param.d.defaultValue);
|
||||
paramString += useEllipsis
|
||||
? '...'
|
||||
: ParseTreeUtils.printExpression(param.d.defaultValue, printFlags);
|
||||
}
|
||||
|
||||
if (!paramString && !param.name && param.category === ParameterCategory.Simple) {
|
||||
if (!paramString && !param.d.name && param.d.category === ParameterCategory.Simple) {
|
||||
return '/';
|
||||
}
|
||||
|
||||
@ -1871,14 +1875,14 @@ export class CompletionProvider {
|
||||
})
|
||||
.join(', ');
|
||||
|
||||
let methodSignature = node.name.value + '(' + paramList + ')';
|
||||
let methodSignature = node.d.name.d.value + '(' + paramList + ')';
|
||||
|
||||
if (node.returnTypeAnnotation) {
|
||||
methodSignature += ' -> ' + ParseTreeUtils.printExpression(node.returnTypeAnnotation, printFlags);
|
||||
} else if (node.functionAnnotationComment) {
|
||||
if (node.d.returnTypeAnnotation) {
|
||||
methodSignature += ' -> ' + ParseTreeUtils.printExpression(node.d.returnTypeAnnotation, printFlags);
|
||||
} else if (node.d.functionAnnotationComment) {
|
||||
methodSignature +=
|
||||
' -> ' +
|
||||
ParseTreeUtils.printExpression(node.functionAnnotationComment.returnTypeAnnotation, printFlags);
|
||||
ParseTreeUtils.printExpression(node.d.functionAnnotationComment.d.returnTypeAnnotation, printFlags);
|
||||
}
|
||||
|
||||
return methodSignature;
|
||||
@ -1912,7 +1916,7 @@ export class CompletionProvider {
|
||||
// Don't add any completion options.
|
||||
if (
|
||||
parseNode.parent?.nodeType === ParseNodeType.WithItem &&
|
||||
parseNode.parent === parseNode.parent.target?.parent
|
||||
parseNode.parent === parseNode.parent.d.target?.parent
|
||||
) {
|
||||
return undefined;
|
||||
}
|
||||
@ -1970,11 +1974,11 @@ export class CompletionProvider {
|
||||
return (
|
||||
currentNode &&
|
||||
currentNode.nodeType === ParseNodeType.Argument &&
|
||||
currentNode.argumentCategory === ArgumentCategory.Simple &&
|
||||
currentNode.d.argumentCategory === ArgumentCategory.Simple &&
|
||||
currentNode.parent &&
|
||||
currentNode.parent.nodeType === ParseNodeType.Index &&
|
||||
currentNode.parent.baseExpression &&
|
||||
currentNode.parent.baseExpression.nodeType === ParseNodeType.Name
|
||||
currentNode.parent.d.baseExpression &&
|
||||
currentNode.parent.d.baseExpression.nodeType === ParseNodeType.Name
|
||||
);
|
||||
}
|
||||
|
||||
@ -2007,7 +2011,7 @@ export class CompletionProvider {
|
||||
if (signatureInfo) {
|
||||
// Are we past the call expression and within the argument list?
|
||||
const callNameEnd = convertOffsetToPosition(
|
||||
signatureInfo.callNode.leftExpression.start + signatureInfo.callNode.leftExpression.length,
|
||||
signatureInfo.callNode.d.leftExpression.start + signatureInfo.callNode.d.leftExpression.length,
|
||||
this.parseResults.tokenizerOutput.lines
|
||||
);
|
||||
|
||||
@ -2080,13 +2084,13 @@ export class CompletionProvider {
|
||||
return [];
|
||||
}
|
||||
|
||||
return node.entries.flatMap((entry) => {
|
||||
if (entry.nodeType !== ParseNodeType.DictionaryKeyEntry || excludeIds?.has(entry.keyExpression.id)) {
|
||||
return node.d.entries.flatMap((entry) => {
|
||||
if (entry.nodeType !== ParseNodeType.DictionaryKeyEntry || excludeIds?.has(entry.d.keyExpression.id)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
if (entry.keyExpression.nodeType === ParseNodeType.StringList) {
|
||||
return [entry.keyExpression.strings.map((s) => s.value).join('')];
|
||||
if (entry.d.keyExpression.nodeType === ParseNodeType.StringList) {
|
||||
return [entry.d.keyExpression.d.strings.map((s) => s.d.value).join('')];
|
||||
}
|
||||
|
||||
return [];
|
||||
@ -2147,7 +2151,7 @@ export class CompletionProvider {
|
||||
}
|
||||
|
||||
private _getIndexKeys(indexNode: IndexNode, invocationNode: ParseNode) {
|
||||
const baseType = this.evaluator.getType(indexNode.baseExpression);
|
||||
const baseType = this.evaluator.getType(indexNode.d.baseExpression);
|
||||
if (!baseType || !isClassInstance(baseType)) {
|
||||
return [];
|
||||
}
|
||||
@ -2176,13 +2180,13 @@ export class CompletionProvider {
|
||||
}
|
||||
}
|
||||
|
||||
if (indexNode.baseExpression.nodeType !== ParseNodeType.Name) {
|
||||
if (indexNode.d.baseExpression.nodeType !== ParseNodeType.Name) {
|
||||
// This completion only supports simple name case
|
||||
return [];
|
||||
}
|
||||
|
||||
// Must be local variable/parameter
|
||||
const declarations = this.evaluator.getDeclarationsForNameNode(indexNode.baseExpression) ?? [];
|
||||
const declarations = this.evaluator.getDeclarationsForNameNode(indexNode.d.baseExpression) ?? [];
|
||||
const declaration = declarations.length > 0 ? declarations[0] : undefined;
|
||||
if (
|
||||
!declaration ||
|
||||
@ -2195,7 +2199,7 @@ export class CompletionProvider {
|
||||
return [];
|
||||
}
|
||||
|
||||
let startingNode: ParseNode = indexNode.baseExpression;
|
||||
let startingNode: ParseNode = indexNode.d.baseExpression;
|
||||
if (declaration.node) {
|
||||
const scopeRoot = ParseTreeUtils.getEvaluationScopeNode(declaration.node).node;
|
||||
|
||||
@ -2211,7 +2215,7 @@ export class CompletionProvider {
|
||||
|
||||
const results = DocumentSymbolCollector.collectFromNode(
|
||||
this.program,
|
||||
indexNode.baseExpression,
|
||||
indexNode.d.baseExpression,
|
||||
this.cancellationToken,
|
||||
startingNode
|
||||
);
|
||||
@ -2225,27 +2229,27 @@ export class CompletionProvider {
|
||||
node.parent?.nodeType === ParseNodeType.Assignment ||
|
||||
node.parent?.nodeType === ParseNodeType.AssignmentExpression
|
||||
) {
|
||||
if (node.parent.rightExpression.nodeType === ParseNodeType.Dictionary) {
|
||||
const dictionary = node.parent.rightExpression;
|
||||
for (const entry of dictionary.entries.filter(
|
||||
if (node.parent.d.rightExpression.nodeType === ParseNodeType.Dictionary) {
|
||||
const dictionary = node.parent.d.rightExpression;
|
||||
for (const entry of dictionary.d.entries.filter(
|
||||
(e) => e.nodeType === ParseNodeType.DictionaryKeyEntry
|
||||
) as DictionaryKeyEntryNode[]) {
|
||||
const key = this.parseResults.text
|
||||
.substr(entry.keyExpression.start, entry.keyExpression.length)
|
||||
.substr(entry.d.keyExpression.start, entry.d.keyExpression.length)
|
||||
.trim();
|
||||
if (key.length > 0) keys.add(key);
|
||||
}
|
||||
}
|
||||
|
||||
if (node.parent.rightExpression.nodeType === ParseNodeType.Call) {
|
||||
const call = node.parent.rightExpression;
|
||||
const type = this.evaluator.getType(call.leftExpression);
|
||||
if (node.parent.d.rightExpression.nodeType === ParseNodeType.Call) {
|
||||
const call = node.parent.d.rightExpression;
|
||||
const type = this.evaluator.getType(call.d.leftExpression);
|
||||
if (!type || !isInstantiableClass(type) || !ClassType.isBuiltIn(type, 'dict')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (const arg of call.arguments) {
|
||||
const key = arg.name?.value.trim() ?? '';
|
||||
for (const arg of call.d.arguments) {
|
||||
const key = arg.d.name?.d.value.trim() ?? '';
|
||||
const quote = this.parseResults.tokenizerOutput.predominantSingleQuoteCharacter;
|
||||
if (key.length > 0) {
|
||||
keys.add(`${quote}${key}${quote}`);
|
||||
@ -2256,13 +2260,13 @@ export class CompletionProvider {
|
||||
|
||||
if (
|
||||
node.parent?.nodeType === ParseNodeType.Index &&
|
||||
node.parent.items.length === 1 &&
|
||||
node.parent.items[0].valueExpression.nodeType !== ParseNodeType.Error &&
|
||||
node.parent.d.items.length === 1 &&
|
||||
node.parent.d.items[0].d.valueExpression.nodeType !== ParseNodeType.Error &&
|
||||
!TextRange.containsRange(node.parent, invocationNode)
|
||||
) {
|
||||
const indexArgument = node.parent.items[0];
|
||||
const indexArgument = node.parent.d.items[0];
|
||||
const key = this.parseResults.text
|
||||
.substr(indexArgument.valueExpression.start, indexArgument.valueExpression.length)
|
||||
.substr(indexArgument.d.valueExpression.start, indexArgument.d.valueExpression.length)
|
||||
.trim();
|
||||
if (key.length > 0) keys.add(key);
|
||||
}
|
||||
@ -2310,7 +2314,7 @@ export class CompletionProvider {
|
||||
// ex) a: Literal["str"] = /* here */
|
||||
const nodeForExpectedType =
|
||||
parentAndChild.parent.nodeType === ParseNodeType.Assignment
|
||||
? parentAndChild.parent.rightExpression === parentAndChild.child
|
||||
? parentAndChild.parent.d.rightExpression === parentAndChild.child
|
||||
? parentAndChild.child
|
||||
: undefined
|
||||
: isExpressionNode(parentAndChild.child)
|
||||
@ -2340,7 +2344,7 @@ export class CompletionProvider {
|
||||
|
||||
if (
|
||||
nodeForKey.nodeType === ParseNodeType.DictionaryKeyEntry &&
|
||||
nodeForKey.keyExpression === parentAndChild.child &&
|
||||
nodeForKey.d.keyExpression === parentAndChild.child &&
|
||||
nodeForKey.parent?.nodeType === ParseNodeType.Dictionary
|
||||
) {
|
||||
dictOrSet = nodeForKey.parent;
|
||||
@ -2426,8 +2430,11 @@ export class CompletionProvider {
|
||||
// if c == "/* here */"
|
||||
const comparison = parentAndChild.parent;
|
||||
const supportedOperators = [OperatorType.Assign, OperatorType.Equals, OperatorType.NotEquals];
|
||||
if (comparison.nodeType === ParseNodeType.BinaryOperation && supportedOperators.includes(comparison.operator)) {
|
||||
const type = this.evaluator.getType(comparison.leftExpression);
|
||||
if (
|
||||
comparison.nodeType === ParseNodeType.BinaryOperation &&
|
||||
supportedOperators.includes(comparison.d.operator)
|
||||
) {
|
||||
const type = this.evaluator.getType(comparison.d.leftExpression);
|
||||
if (type && containsLiteralType(type)) {
|
||||
this._addLiteralValuesForTargetType(type, priorWord, priorText, postText, completionMap);
|
||||
return true;
|
||||
@ -2438,9 +2445,9 @@ export class CompletionProvider {
|
||||
const assignmentExpression = parentAndChild.parent;
|
||||
if (
|
||||
assignmentExpression.nodeType === ParseNodeType.AssignmentExpression &&
|
||||
assignmentExpression.rightExpression === parentAndChild.child
|
||||
assignmentExpression.d.rightExpression === parentAndChild.child
|
||||
) {
|
||||
const type = this.evaluator.getType(assignmentExpression.name);
|
||||
const type = this.evaluator.getType(assignmentExpression.d.name);
|
||||
if (type && containsLiteralType(type)) {
|
||||
this._addLiteralValuesForTargetType(type, priorWord, priorText, postText, completionMap);
|
||||
return true;
|
||||
@ -2453,12 +2460,12 @@ export class CompletionProvider {
|
||||
const caseNode = parentAndChild.parent;
|
||||
if (
|
||||
caseNode.nodeType === ParseNodeType.Case &&
|
||||
caseNode.pattern.nodeType === ParseNodeType.Error &&
|
||||
caseNode.pattern.category === ErrorExpressionCategory.MissingPattern &&
|
||||
caseNode.suite === parentAndChild.child &&
|
||||
caseNode.d.pattern.nodeType === ParseNodeType.Error &&
|
||||
caseNode.d.pattern.d.category === ErrorExpressionCategory.MissingPattern &&
|
||||
caseNode.d.suite === parentAndChild.child &&
|
||||
caseNode.parent?.nodeType === ParseNodeType.Match
|
||||
) {
|
||||
const type = this.evaluator.getType(caseNode.parent.subjectExpression);
|
||||
const type = this.evaluator.getType(caseNode.parent.d.subjectExpression);
|
||||
if (type && containsLiteralType(type)) {
|
||||
this._addLiteralValuesForTargetType(type, priorWord, priorText, postText, completionMap);
|
||||
return true;
|
||||
@ -2476,7 +2483,7 @@ export class CompletionProvider {
|
||||
patternLiteral.parent.parent?.nodeType === ParseNodeType.Case &&
|
||||
patternLiteral.parent.parent.parent?.nodeType === ParseNodeType.Match
|
||||
) {
|
||||
const type = this.evaluator.getType(patternLiteral.parent.parent.parent.subjectExpression);
|
||||
const type = this.evaluator.getType(patternLiteral.parent.parent.parent.d.subjectExpression);
|
||||
if (type && containsLiteralType(type)) {
|
||||
this._addLiteralValuesForTargetType(type, priorWord, priorText, postText, completionMap);
|
||||
return true;
|
||||
@ -2505,7 +2512,7 @@ export class CompletionProvider {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (node.parent?.nodeType !== ParseNodeType.StringList || node.parent.strings.length > 1) {
|
||||
if (node.parent?.nodeType !== ParseNodeType.StringList || node.parent.d.strings.length > 1) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@ -2666,7 +2673,7 @@ export class CompletionProvider {
|
||||
return false;
|
||||
}
|
||||
|
||||
const baseType = this.evaluator.getType(indexNode.baseExpression);
|
||||
const baseType = this.evaluator.getType(indexNode.d.baseExpression);
|
||||
if (!baseType) {
|
||||
return false;
|
||||
}
|
||||
@ -2726,13 +2733,13 @@ export class CompletionProvider {
|
||||
priorWord: string
|
||||
): CompletionMap | undefined {
|
||||
// Don't attempt to provide completions for "from X import *".
|
||||
if (importFromNode.isWildcardImport) {
|
||||
if (importFromNode.d.isWildcardImport) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// Access the imported module information, which is hanging
|
||||
// off the ImportFromNode.
|
||||
const importInfo = AnalyzerNodeInfo.getImportInfo(importFromNode.module);
|
||||
const importInfo = AnalyzerNodeInfo.getImportInfo(importFromNode.d.module);
|
||||
if (!importInfo) {
|
||||
return undefined;
|
||||
}
|
||||
@ -2763,9 +2770,9 @@ export class CompletionProvider {
|
||||
symbol.getDeclarations().some((d) => !isIntrinsicDeclaration(d)) &&
|
||||
// Don't suggest symbols that have already been imported elsewhere
|
||||
// in this import statement.
|
||||
!importFromNode.imports.find(
|
||||
!importFromNode.d.imports.find(
|
||||
(imp) =>
|
||||
imp.name.value === name &&
|
||||
imp.d.name.d.value === name &&
|
||||
!(TextRange.contains(imp, offset) || TextRange.getEnd(imp) === offset)
|
||||
)
|
||||
);
|
||||
@ -2789,7 +2796,7 @@ export class CompletionProvider {
|
||||
completionMap: CompletionMap
|
||||
) {
|
||||
importInfo.implicitImports.forEach((implImport) => {
|
||||
if (!importFromNode.imports.find((imp) => imp.name.value === implImport.name)) {
|
||||
if (!importFromNode.d.imports.find((imp) => imp.d.name.d.value === implImport.name)) {
|
||||
this.addNameToCompletions(implImport.name, CompletionItemKind.Module, priorWord, completionMap, {
|
||||
moduleUri: implImport.uri,
|
||||
});
|
||||
@ -2825,9 +2832,9 @@ export class CompletionProvider {
|
||||
});
|
||||
|
||||
// Remove any named parameters that are already provided.
|
||||
signatureInfo.callNode.arguments!.forEach((arg) => {
|
||||
if (arg.name) {
|
||||
argNameSet.delete(arg.name.value);
|
||||
signatureInfo.callNode.d.arguments!.forEach((arg) => {
|
||||
if (arg.d.name) {
|
||||
argNameSet.delete(arg.d.name.d.value);
|
||||
}
|
||||
});
|
||||
|
||||
@ -3098,9 +3105,9 @@ export class CompletionProvider {
|
||||
|
||||
private _getImportModuleCompletions(node: ModuleNameNode): CompletionMap {
|
||||
const moduleDescriptor: ImportedModuleDescriptor = {
|
||||
leadingDots: node.leadingDots,
|
||||
hasTrailingDot: node.hasTrailingDot || false,
|
||||
nameParts: node.nameParts.map((part) => part.value),
|
||||
leadingDots: node.d.leadingDots,
|
||||
hasTrailingDot: node.d.hasTrailingDot || false,
|
||||
nameParts: node.d.nameParts.map((part) => part.d.value),
|
||||
importedSymbols: new Set<string>(),
|
||||
};
|
||||
|
||||
@ -3111,10 +3118,10 @@ export class CompletionProvider {
|
||||
// If we're in the middle of a "from X import Y" statement, offer
|
||||
// the "import" keyword as a completion.
|
||||
if (
|
||||
!node.hasTrailingDot &&
|
||||
!node.d.hasTrailingDot &&
|
||||
node.parent &&
|
||||
node.parent.nodeType === ParseNodeType.ImportFrom &&
|
||||
node.parent.missingImportKeyword
|
||||
node.parent.d.missingImportKeyword
|
||||
) {
|
||||
const keyword = 'import';
|
||||
const completionItem = CompletionItem.create(keyword);
|
||||
@ -3136,7 +3143,7 @@ export class CompletionProvider {
|
||||
private _isPossiblePropertyDeclaration(decl: FunctionDeclaration) {
|
||||
// Do cheap check using only nodes that will cover 99.9% cases
|
||||
// before doing more expensive type evaluation.
|
||||
return decl.isMethod && decl.node.decorators.length > 0;
|
||||
return decl.isMethod && decl.node.d.decorators.length > 0;
|
||||
}
|
||||
|
||||
private _isEnumMember(containingType: ClassType | undefined, name: string) {
|
||||
|
@ -159,7 +159,7 @@ export class DocumentSymbolCollector extends ParseTreeWalker {
|
||||
|
||||
const collector = new DocumentSymbolCollector(
|
||||
program,
|
||||
[node.value],
|
||||
[node.d.value],
|
||||
declarations,
|
||||
startingNode,
|
||||
cancellationToken,
|
||||
@ -208,7 +208,7 @@ export class DocumentSymbolCollector extends ParseTreeWalker {
|
||||
// Add declarations from chained source files
|
||||
let builtinsScope = fileInfo.builtinsScope;
|
||||
while (builtinsScope && builtinsScope.type === ScopeType.Module) {
|
||||
const symbol = builtinsScope?.lookUpSymbol(node.value);
|
||||
const symbol = builtinsScope?.lookUpSymbol(node.d.value);
|
||||
appendSymbolDeclarations(symbol, resolvedDeclarations);
|
||||
builtinsScope = builtinsScope?.parent;
|
||||
}
|
||||
@ -219,7 +219,7 @@ export class DocumentSymbolCollector extends ParseTreeWalker {
|
||||
const parseTree = program.getParseResults(implicitImport.sourceFile.getUri())?.parserOutput.parseTree;
|
||||
if (parseTree) {
|
||||
const scope = AnalyzerNodeInfo.getScope(parseTree);
|
||||
const symbol = scope?.lookUpSymbol(node.value);
|
||||
const symbol = scope?.lookUpSymbol(node.d.value);
|
||||
appendSymbolDeclarations(symbol, resolvedDeclarations);
|
||||
}
|
||||
});
|
||||
@ -255,7 +255,7 @@ export class DocumentSymbolCollector extends ParseTreeWalker {
|
||||
throwIfCancellationRequested(this._cancellationToken);
|
||||
|
||||
// No need to do any more work if the symbol name doesn't match.
|
||||
if (!this._symbolNames.has(node.value)) {
|
||||
if (!this._symbolNames.has(node.d.value)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -279,7 +279,7 @@ export class DocumentSymbolCollector extends ParseTreeWalker {
|
||||
// See if we have reference that matches this node.
|
||||
if (this._declarations.some((d) => d.node?.id === node.id)) {
|
||||
// Then the matching string should be included
|
||||
const matching = node.strings.find((s) => this._symbolNames.has(s.value));
|
||||
const matching = node.d.strings.find((s) => this._symbolNames.has(s.d.value));
|
||||
if (matching && matching.nodeType === ParseNodeType.String) {
|
||||
this._addResult(matching);
|
||||
}
|
||||
@ -303,7 +303,7 @@ export class DocumentSymbolCollector extends ParseTreeWalker {
|
||||
}
|
||||
|
||||
private _addResult(node: NameNode | StringNode) {
|
||||
const range: TextRange = node.nodeType === ParseNodeType.Name ? node.token : getStringNodeValueRange(node);
|
||||
const range: TextRange = node.nodeType === ParseNodeType.Name ? node.d.token : getStringNodeValueRange(node);
|
||||
this._results.push({ node, range });
|
||||
}
|
||||
|
||||
@ -386,11 +386,11 @@ export class DocumentSymbolCollector extends ParseTreeWalker {
|
||||
}
|
||||
|
||||
dunderAllInfo.stringNodes.forEach((stringNode) => {
|
||||
if (!this._symbolNames.has(stringNode.value)) {
|
||||
if (!this._symbolNames.has(stringNode.d.value)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const symbolInScope = moduleScope.lookUpSymbolRecursive(stringNode.value);
|
||||
const symbolInScope = moduleScope.lookUpSymbolRecursive(stringNode.d.value);
|
||||
if (!symbolInScope) {
|
||||
return;
|
||||
}
|
||||
@ -465,7 +465,10 @@ function _getDeclarationsForNonModuleNameNode(
|
||||
continue;
|
||||
}
|
||||
|
||||
appendArray(decls, evaluator.getDeclarationsForNameNode(node.module.nameParts[0], skipUnreachableCode) || []);
|
||||
appendArray(
|
||||
decls,
|
||||
evaluator.getDeclarationsForNameNode(node.d.module.d.nameParts[0], skipUnreachableCode) || []
|
||||
);
|
||||
}
|
||||
|
||||
return decls;
|
||||
@ -483,7 +486,7 @@ function _getDeclarationsForModuleNameNode(evaluator: TypeEvaluator, node: NameN
|
||||
moduleName.parent?.nodeType === ParseNodeType.ImportAs ||
|
||||
moduleName.parent?.nodeType === ParseNodeType.ImportFrom
|
||||
) {
|
||||
const index = moduleName.nameParts.findIndex((n) => n === node);
|
||||
const index = moduleName.d.nameParts.findIndex((n) => n === node);
|
||||
|
||||
// Special case, first module name part.
|
||||
if (index === 0) {
|
||||
@ -494,7 +497,7 @@ function _getDeclarationsForModuleNameNode(evaluator: TypeEvaluator, node: NameN
|
||||
// we can match both "import X" and "from X import ..."
|
||||
appendArray(
|
||||
decls,
|
||||
evaluator.getDeclarationsForNameNode(moduleName.nameParts[0])?.filter((d) => isAliasDeclaration(d)) ||
|
||||
evaluator.getDeclarationsForNameNode(moduleName.d.nameParts[0])?.filter((d) => isAliasDeclaration(d)) ||
|
||||
[]
|
||||
);
|
||||
|
||||
@ -507,20 +510,20 @@ function _getDeclarationsForModuleNameNode(evaluator: TypeEvaluator, node: NameN
|
||||
// from symbol as well.
|
||||
// ex, import X as x
|
||||
const isImportAsWithAlias =
|
||||
moduleName.nameParts.length === 1 &&
|
||||
moduleName.d.nameParts.length === 1 &&
|
||||
moduleName.parent.nodeType === ParseNodeType.ImportAs &&
|
||||
!!moduleName.parent.alias;
|
||||
!!moduleName.parent.d.alias;
|
||||
|
||||
// if "import" has alias, symbol is assigned to alias, not the module.
|
||||
const importName = isImportAsWithAlias
|
||||
? (moduleName.parent as ImportAsNode).alias!.value
|
||||
: moduleName.nameParts[0].value;
|
||||
? (moduleName.parent as ImportAsNode).d.alias!.d.value
|
||||
: moduleName.d.nameParts[0].d.value;
|
||||
|
||||
// And we also need to re-use "decls for X" binder has created
|
||||
// so that it matches with decls type evaluator returns for "references for X".
|
||||
// ex) import X or from .X import ... in init file and etc.
|
||||
const symbolWithScope = ScopeUtils.getScopeForNode(node)?.lookUpSymbolRecursive(importName);
|
||||
if (symbolWithScope && moduleName.nameParts.length === 1) {
|
||||
if (symbolWithScope && moduleName.d.nameParts.length === 1) {
|
||||
let declsFromSymbol: Declaration[] = [];
|
||||
|
||||
appendArray(
|
||||
@ -538,7 +541,7 @@ function _getDeclarationsForModuleNameNode(evaluator: TypeEvaluator, node: NameN
|
||||
// ex) import X.Y and import X.Z or from .X import ... in init file.
|
||||
// Decls for X will be reused for both import statements, and node will point
|
||||
// to first import statement. For those case, use firstNamePart instead to check.
|
||||
return d.firstNamePart === moduleName.nameParts[0].value;
|
||||
return d.firstNamePart === moduleName.d.nameParts[0].d.value;
|
||||
}
|
||||
|
||||
return d.node === moduleName.parent;
|
||||
@ -564,7 +567,7 @@ function _getDeclarationsForModuleNameNode(evaluator: TypeEvaluator, node: NameN
|
||||
// "import X.Y" hold onto synthesized module type (without any decl).
|
||||
// And "from X.Y import ..." doesn't have any symbol associated module names.
|
||||
// they can't be referenced in the module.
|
||||
return evaluator.getDeclarationsForNameNode(moduleName.nameParts[index]) || [];
|
||||
return evaluator.getDeclarationsForNameNode(moduleName.d.nameParts[index]) || [];
|
||||
}
|
||||
|
||||
return [];
|
||||
|
@ -139,7 +139,7 @@ export function getVariableTypeText(
|
||||
|
||||
if (type.props?.typeAliasInfo && typeNode.nodeType === ParseNodeType.Name) {
|
||||
const typeAliasInfo = getTypeAliasInfo(type);
|
||||
if (typeAliasInfo?.name === typeNode.value) {
|
||||
if (typeAliasInfo?.name === typeNode.d.value) {
|
||||
if (isTypeVar(type)) {
|
||||
label = type.shared.isParamSpec ? 'param spec' : 'type variable';
|
||||
typeVarName = type.shared.name;
|
||||
@ -258,7 +258,7 @@ export class HoverProvider {
|
||||
// Handle modules specially because submodules aren't associated with
|
||||
// declarations, but we want them to be presented in the same way as
|
||||
// the top-level module, which does have a declaration.
|
||||
typeText = '(module) ' + node.value;
|
||||
typeText = '(module) ' + node.d.value;
|
||||
} else {
|
||||
let label = 'function';
|
||||
let isProperty = false;
|
||||
@ -271,7 +271,7 @@ export class HoverProvider {
|
||||
typeText = getToolTipForType(
|
||||
type,
|
||||
label,
|
||||
node.value,
|
||||
node.d.value,
|
||||
this._evaluator,
|
||||
isProperty,
|
||||
this._functionSignatureDisplay
|
||||
@ -295,13 +295,13 @@ export class HoverProvider {
|
||||
private _addResultsForDeclaration(parts: HoverTextPart[], declaration: Declaration, node: NameNode): void {
|
||||
const resolvedDecl = this._evaluator.resolveAliasDeclaration(declaration, /* resolveLocalNames */ true);
|
||||
if (!resolvedDecl || isUnresolvedAliasDeclaration(resolvedDecl)) {
|
||||
this._addResultsPart(parts, `(import) ` + node.value + this._getTypeText(node), /* python */ true);
|
||||
this._addResultsPart(parts, `(import) ` + node.d.value + this._getTypeText(node), /* python */ true);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (resolvedDecl.type) {
|
||||
case DeclarationType.Intrinsic: {
|
||||
this._addResultsPart(parts, node.value + this._getTypeText(node), /* python */ true);
|
||||
this._addResultsPart(parts, node.d.value + this._getTypeText(node), /* python */ true);
|
||||
this._addDocumentationPart(parts, node, resolvedDecl);
|
||||
break;
|
||||
}
|
||||
@ -315,12 +315,12 @@ export class HoverProvider {
|
||||
declaration.node.nodeType === ParseNodeType.ImportAs ||
|
||||
declaration.node.nodeType === ParseNodeType.ImportFromAs
|
||||
) {
|
||||
if (declaration.node.alias && node !== declaration.node.alias) {
|
||||
if (declaration.node.d.alias && node !== declaration.node.d.alias) {
|
||||
if (resolvedDecl.node.nodeType === ParseNodeType.Name) {
|
||||
typeNode = resolvedDecl.node;
|
||||
}
|
||||
}
|
||||
} else if (node.parent?.nodeType === ParseNodeType.Argument && node.parent.name === node) {
|
||||
} else if (node.parent?.nodeType === ParseNodeType.Argument && node.parent.d.name === node) {
|
||||
// If this is a named argument, we would normally have received a Parameter declaration
|
||||
// rather than a variable declaration, but we can get here in the case of a dataclass.
|
||||
// Replace the typeNode with the node of the variable declaration.
|
||||
@ -335,7 +335,7 @@ export class HoverProvider {
|
||||
const typeText = getVariableTypeText(
|
||||
this._evaluator,
|
||||
resolvedDecl,
|
||||
node.value,
|
||||
node.d.value,
|
||||
type,
|
||||
typeNode,
|
||||
this._functionSignatureDisplay
|
||||
@ -347,7 +347,7 @@ export class HoverProvider {
|
||||
}
|
||||
|
||||
case DeclarationType.Parameter: {
|
||||
this._addResultsPart(parts, '(parameter) ' + node.value + this._getTypeText(node), /* python */ true);
|
||||
this._addResultsPart(parts, '(parameter) ' + node.d.value + this._getTypeText(node), /* python */ true);
|
||||
|
||||
if (resolvedDecl.docString) {
|
||||
this._addResultsPart(parts, resolvedDecl.docString);
|
||||
@ -364,7 +364,7 @@ export class HoverProvider {
|
||||
|
||||
this._addResultsPart(
|
||||
parts,
|
||||
'(type parameter) ' + node.value + this._getTypeText(node, { printTypeVarVariance }),
|
||||
'(type parameter) ' + node.d.value + this._getTypeText(node, { printTypeVarVariance }),
|
||||
/* python */ true
|
||||
);
|
||||
this._addDocumentationPart(parts, node, resolvedDecl);
|
||||
@ -377,8 +377,8 @@ export class HoverProvider {
|
||||
return;
|
||||
}
|
||||
|
||||
const nameNode = resolvedDecl.type === DeclarationType.Class ? resolvedDecl.node.name : node;
|
||||
this._addResultsPart(parts, '(class) ' + nameNode.value, /* python */ true);
|
||||
const nameNode = resolvedDecl.type === DeclarationType.Class ? resolvedDecl.node.d.name : node;
|
||||
this._addResultsPart(parts, '(class) ' + nameNode.d.value, /* python */ true);
|
||||
this._addDocumentationPart(parts, node, resolvedDecl);
|
||||
break;
|
||||
}
|
||||
@ -393,12 +393,12 @@ export class HoverProvider {
|
||||
}
|
||||
|
||||
let type = this._getType(node);
|
||||
const resolvedType = this._getType(resolvedDecl.node.name);
|
||||
const resolvedType = this._getType(resolvedDecl.node.d.name);
|
||||
type = isAnyOrUnknown(type) ? resolvedType : type;
|
||||
const signatureString = getToolTipForType(
|
||||
type,
|
||||
label,
|
||||
node.value,
|
||||
node.d.value,
|
||||
this._evaluator,
|
||||
isProperty,
|
||||
this._functionSignatureDisplay
|
||||
@ -411,7 +411,7 @@ export class HoverProvider {
|
||||
|
||||
case DeclarationType.Alias: {
|
||||
// First the 'module' header.
|
||||
this._addResultsPart(parts, '(module) ' + node.value, /* python */ true);
|
||||
this._addResultsPart(parts, '(module) ' + node.d.value, /* python */ true);
|
||||
this._addDocumentationPart(parts, node, resolvedDecl);
|
||||
break;
|
||||
}
|
||||
@ -419,7 +419,7 @@ export class HoverProvider {
|
||||
case DeclarationType.TypeAlias: {
|
||||
const type = convertToInstance(this._getType(node));
|
||||
const typeText = this._evaluator.printType(type, { expandTypeAlias: true });
|
||||
this._addResultsPart(parts, `(type) ${node.value} = ${typeText}`, /* python */ true);
|
||||
this._addResultsPart(parts, `(type) ${node.d.value} = ${typeText}`, /* python */ true);
|
||||
this._addDocumentationPart(parts, node, resolvedDecl);
|
||||
break;
|
||||
}
|
||||
@ -434,7 +434,7 @@ export class HoverProvider {
|
||||
// with the type of the TypedDict key and its docstring, if available.
|
||||
doForEachSubtype(type, (subtype) => {
|
||||
if (isClassInstance(subtype) && ClassType.isTypedDictClass(subtype)) {
|
||||
const entry = subtype.shared.typedDictEntries?.knownItems.get(node.value);
|
||||
const entry = subtype.shared.typedDictEntries?.knownItems.get(node.d.value);
|
||||
if (entry) {
|
||||
// If we have already added parts for another declaration (e.g. for a union of TypedDicts that share the same key)
|
||||
// then we need to add a separator to prevent a visual bug.
|
||||
@ -443,10 +443,10 @@ export class HoverProvider {
|
||||
}
|
||||
|
||||
// e.g. (key) name: str
|
||||
const text = '(key) ' + node.value + ': ' + this._evaluator.printType(entry.valueType);
|
||||
const text = '(key) ' + node.d.value + ': ' + this._evaluator.printType(entry.valueType);
|
||||
this._addResultsPart(parts, text, /* python */ true);
|
||||
|
||||
const declarations = ClassType.getSymbolTable(subtype).get(node.value)?.getDeclarations();
|
||||
const declarations = ClassType.getSymbolTable(subtype).get(node.d.value)?.getDeclarations();
|
||||
if (declarations !== undefined && declarations?.length !== 0) {
|
||||
// As we are just interested in the docString we don't have to worry about
|
||||
// anything other than the first declaration. There also shouldn't be more
|
||||
@ -470,7 +470,7 @@ export class HoverProvider {
|
||||
if (result.methodType && (isFunction(result.methodType) || isOverloadedFunction(result.methodType))) {
|
||||
this._addResultsPart(
|
||||
parts,
|
||||
getConstructorTooltip(node.value, result.methodType, this._evaluator, this._functionSignatureDisplay),
|
||||
getConstructorTooltip(node.d.value, result.methodType, this._evaluator, this._functionSignatureDisplay),
|
||||
/* python */ true
|
||||
);
|
||||
|
||||
@ -497,7 +497,7 @@ export class HoverProvider {
|
||||
|
||||
private _addDocumentationPart(parts: HoverTextPart[], node: NameNode, resolvedDecl: Declaration | undefined) {
|
||||
const type = this._getType(node);
|
||||
this._addDocumentationPartForType(parts, type, resolvedDecl, node.value);
|
||||
this._addDocumentationPartForType(parts, type, resolvedDecl, node.d.value);
|
||||
}
|
||||
|
||||
private _addDocumentationPartForType(
|
||||
|
@ -144,27 +144,27 @@ export class ImportSorter {
|
||||
|
||||
private _formatImportNode(subnode: ImportAsNode, moduleName: string): string {
|
||||
let importText = `import ${moduleName}`;
|
||||
if (subnode.alias) {
|
||||
importText += ` as ${subnode.alias.value}`;
|
||||
if (subnode.d.alias) {
|
||||
importText += ` as ${subnode.d.alias.d.value}`;
|
||||
}
|
||||
|
||||
return importText;
|
||||
}
|
||||
|
||||
private _formatImportFromNode(node: ImportFromNode, moduleName: string): string {
|
||||
const symbols = node.imports
|
||||
const symbols = node.d.imports
|
||||
.sort((a, b) => this._compareSymbols(a, b))
|
||||
.map((symbol) => {
|
||||
let symbolText = symbol.name.value;
|
||||
if (symbol.alias) {
|
||||
symbolText += ` as ${symbol.alias.value}`;
|
||||
let symbolText = symbol.d.name.d.value;
|
||||
if (symbol.d.alias) {
|
||||
symbolText += ` as ${symbol.d.alias.d.value}`;
|
||||
}
|
||||
|
||||
return symbolText;
|
||||
});
|
||||
|
||||
let cumulativeText = `from ${moduleName} import `;
|
||||
if (node.isWildcardImport) {
|
||||
if (node.d.isWildcardImport) {
|
||||
return cumulativeText + '*';
|
||||
}
|
||||
|
||||
@ -190,6 +190,6 @@ export class ImportSorter {
|
||||
}
|
||||
|
||||
private _compareSymbols(a: ImportFromAsNode, b: ImportFromAsNode) {
|
||||
return a.name.value < b.name.value ? -1 : 1;
|
||||
return a.d.name.d.value < b.d.name.d.value ? -1 : 1;
|
||||
}
|
||||
}
|
||||
|
@ -67,7 +67,7 @@ export class ReferencesResult {
|
||||
}
|
||||
|
||||
// Extract alias for comparison (symbolNames.some can't know d is for an Alias).
|
||||
const alias = d.node.alias?.value;
|
||||
const alias = d.node.d.alias?.d.value;
|
||||
|
||||
// Check alias and what we are renaming is same thing.
|
||||
if (!symbolNames.some((s) => s === alias)) {
|
||||
@ -332,7 +332,7 @@ export class ReferencesProvider {
|
||||
|
||||
const requiresGlobalSearch = isVisibleOutside(program.evaluator!, fileUri, node, declarations);
|
||||
const symbolNames = new Set<string>(declarations.map((d) => getNameFromDeclaration(d)!).filter((n) => !!n));
|
||||
symbolNames.add(node.value);
|
||||
symbolNames.add(node.d.value);
|
||||
|
||||
const providers = (program.serviceProvider.tryGet(ServiceKeys.symbolUsageProviderFactory) ?? [])
|
||||
.map((f) => f.tryCreateProvider(useCase, declarations, token))
|
||||
@ -389,7 +389,7 @@ export class ReferencesProvider {
|
||||
}
|
||||
|
||||
function isVisibleOutside(evaluator: TypeEvaluator, currentUri: Uri, node: NameNode, declarations: Declaration[]) {
|
||||
const result = evaluator.lookUpSymbolRecursive(node, node.value, /* honorCodeFlow */ false);
|
||||
const result = evaluator.lookUpSymbolRecursive(node, node.d.value, /* honorCodeFlow */ false);
|
||||
if (result && !isExternallyVisible(result.symbol)) {
|
||||
return false;
|
||||
}
|
||||
@ -414,7 +414,7 @@ function isVisibleOutside(evaluator: TypeEvaluator, currentUri: Uri, node: NameN
|
||||
}
|
||||
|
||||
// If the name node is a member variable, we need to do a global search.
|
||||
if (decl.node?.parent?.nodeType === ParseNodeType.MemberAccess && decl.node === decl.node.parent.memberName) {
|
||||
if (decl.node?.parent?.nodeType === ParseNodeType.MemberAccess && decl.node === decl.node.parent.d.memberName) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -446,10 +446,10 @@ function isVisibleOutside(evaluator: TypeEvaluator, currentUri: Uri, node: NameN
|
||||
|
||||
case DeclarationType.Class:
|
||||
case DeclarationType.Function:
|
||||
return isVisible && isContainerExternallyVisible(decl.node.name, recursionCount);
|
||||
return isVisible && isContainerExternallyVisible(decl.node.d.name, recursionCount);
|
||||
|
||||
case DeclarationType.Parameter:
|
||||
return isVisible && isContainerExternallyVisible(decl.node.name!, recursionCount);
|
||||
return isVisible && isContainerExternallyVisible(decl.node.d.name!, recursionCount);
|
||||
|
||||
case DeclarationType.TypeParameter:
|
||||
return false;
|
||||
@ -478,8 +478,8 @@ function isVisibleOutside(evaluator: TypeEvaluator, currentUri: Uri, node: NameN
|
||||
switch (scopingNode.nodeType) {
|
||||
case ParseNodeType.Class:
|
||||
case ParseNodeType.Function: {
|
||||
const name = scopingNode.name;
|
||||
const result = evaluator.lookUpSymbolRecursive(name, name.value, /* honorCodeFlow */ false);
|
||||
const name = scopingNode.d.name;
|
||||
const result = evaluator.lookUpSymbolRecursive(name, name.d.value, /* honorCodeFlow */ false);
|
||||
return result ? isExternallyVisible(result.symbol, recursionCount) : true;
|
||||
}
|
||||
|
||||
|
@ -125,7 +125,7 @@ export class SignatureHelpProvider {
|
||||
this._makeSignature(callSignatureInfo.callNode, sig)
|
||||
);
|
||||
|
||||
const callHasParameters = !!callSignatureInfo.callNode.arguments?.length;
|
||||
const callHasParameters = !!callSignatureInfo.callNode.d.arguments?.length;
|
||||
return {
|
||||
signatures,
|
||||
callHasParameters,
|
||||
@ -315,11 +315,11 @@ export class SignatureHelpProvider {
|
||||
// from call node when all other methods failed.
|
||||
// It only works if call is off a name node.
|
||||
let name: NameNode | undefined;
|
||||
const expr = callNode.leftExpression;
|
||||
const expr = callNode.d.leftExpression;
|
||||
if (expr.nodeType === ParseNodeType.Name) {
|
||||
name = expr;
|
||||
} else if (expr.nodeType === ParseNodeType.MemberAccess) {
|
||||
name = expr.memberName;
|
||||
name = expr.d.memberName;
|
||||
}
|
||||
|
||||
if (!name) {
|
||||
|
@ -159,9 +159,9 @@ function collectSymbolIndexDataForName(
|
||||
|
||||
// The default range for a module alias is the first character of the module's file.
|
||||
// Replace that with the range of the alias token.
|
||||
if (declaration.node.nodeType === ParseNodeType.ImportAs && declaration.node.alias) {
|
||||
if (declaration.node.nodeType === ParseNodeType.ImportAs && declaration.node.d.alias) {
|
||||
selectionRange = range = convertTextRangeToRange(
|
||||
declaration.node.alias.token,
|
||||
declaration.node.d.alias.d.token,
|
||||
parseResults.tokenizerOutput.lines
|
||||
);
|
||||
}
|
||||
@ -192,6 +192,6 @@ function shouldAliasBeIndexed(declaration: AliasDeclaration, indexOptions: Index
|
||||
return (
|
||||
(declaration.node.nodeType === ParseNodeType.ImportAs ||
|
||||
declaration.node.nodeType === ParseNodeType.ImportFromAs) &&
|
||||
declaration.node.alias !== undefined
|
||||
declaration.node.d.alias !== undefined
|
||||
);
|
||||
}
|
||||
|
@ -314,9 +314,9 @@ export function getDocumentationPartsForTypeAndDecl(
|
||||
resolvedDecl.node &&
|
||||
resolvedDecl.node.nodeType === ParseNodeType.ImportAs &&
|
||||
!!optional?.name &&
|
||||
!resolvedDecl.node.alias
|
||||
!resolvedDecl.node.d.alias
|
||||
) {
|
||||
const name = resolvedDecl.node.module.nameParts.find((n) => n.value === optional.name);
|
||||
const name = resolvedDecl.node.d.module.d.nameParts.find((n) => n.d.value === optional.name);
|
||||
if (name) {
|
||||
const aliasDecls = evaluator.getDeclarationsForNameNode(name) ?? [resolvedDecl];
|
||||
resolvedDecl = aliasDecls.length > 0 ? aliasDecls[0] : resolvedDecl;
|
||||
@ -382,7 +382,7 @@ export function getClassAndConstructorTypes(node: NameNode, evaluator: TypeEvalu
|
||||
|
||||
// Allow the left to be a member access chain (e.g. a.b.c) if the
|
||||
// node in question is the last item in the chain.
|
||||
if (callLeftNode?.parent?.nodeType === ParseNodeType.MemberAccess && node === callLeftNode.parent.memberName) {
|
||||
if (callLeftNode?.parent?.nodeType === ParseNodeType.MemberAccess && node === callLeftNode.parent.d.memberName) {
|
||||
callLeftNode = node.parent;
|
||||
// Allow the left to be a generic class constructor (e.g. foo[int]())
|
||||
} else if (callLeftNode?.parent?.nodeType === ParseNodeType.Index) {
|
||||
@ -393,7 +393,7 @@ export function getClassAndConstructorTypes(node: NameNode, evaluator: TypeEvalu
|
||||
!callLeftNode ||
|
||||
!callLeftNode.parent ||
|
||||
callLeftNode.parent.nodeType !== ParseNodeType.Call ||
|
||||
callLeftNode.parent.leftExpression !== callLeftNode
|
||||
callLeftNode.parent.d.leftExpression !== callLeftNode
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -141,7 +141,7 @@ test('property', () => {
|
||||
assert(isClassDeclaration(result.decoratedType.shared.declaration));
|
||||
|
||||
assert(result.decoratedType.shared.declaration.moduleName === 'builtins');
|
||||
assert(result.decoratedType.shared.declaration.node.name.value === 'property');
|
||||
assert(result.decoratedType.shared.declaration.node.d.name.d.value === 'property');
|
||||
});
|
||||
});
|
||||
|
||||
@ -154,7 +154,7 @@ function checkSpecialBuiltInClassDetail(code: string) {
|
||||
const type = state.program.evaluator!.getType(node);
|
||||
assert(type?.category === TypeCategory.Class);
|
||||
|
||||
assert.strictEqual(node.value, type.priv.aliasName ?? type.shared.name);
|
||||
assert.strictEqual(node.d.value, type.priv.aliasName ?? type.shared.name);
|
||||
|
||||
assert(type.shared.declaration);
|
||||
if (type.priv.aliasName) {
|
||||
@ -181,7 +181,7 @@ function _checkClassDetail(state: TestState, range: Range | undefined, name?: st
|
||||
const type = state.program.evaluator!.getType(node);
|
||||
assert(type?.category === TypeCategory.Class);
|
||||
|
||||
assert.strictEqual(name ?? node.value, type.priv.aliasName ?? type.shared.name);
|
||||
assert.strictEqual(name ?? node.d.value, type.priv.aliasName ?? type.shared.name);
|
||||
|
||||
if (range) {
|
||||
assert(type.shared.declaration);
|
||||
|
@ -133,7 +133,7 @@ test('getDottedName', () => {
|
||||
function getDottedNameString(marker: string) {
|
||||
const node = getNodeForRange(state, marker);
|
||||
return getDottedName(node as NameNode | MemberAccessNode)
|
||||
?.map((n) => n.value)
|
||||
?.map((n) => n.d.value)
|
||||
.join('.');
|
||||
}
|
||||
});
|
||||
@ -157,7 +157,7 @@ test('getFirstNameOfDottedName', () => {
|
||||
|
||||
function getDottedNameString(marker: string) {
|
||||
const node = getNodeForRange(state, marker);
|
||||
return getFirstNameOfDottedName(node as NameNode | MemberAccessNode)?.value ?? '';
|
||||
return getFirstNameOfDottedName(node as NameNode | MemberAccessNode)?.d.value ?? '';
|
||||
}
|
||||
});
|
||||
|
||||
@ -336,7 +336,7 @@ test('findNodeByOffset', () => {
|
||||
|
||||
const node = findNodeByOffset(sourceFile.getParseResults()!.parserOutput.parseTree, range.pos);
|
||||
assert.strictEqual(node?.nodeType, ParseNodeType.Name);
|
||||
assert.strictEqual((node as NameNode).value, 'r');
|
||||
assert.strictEqual((node as NameNode).d.value, 'r');
|
||||
});
|
||||
|
||||
test('findNodeByOffset with binary search', () => {
|
||||
@ -374,7 +374,7 @@ test('findNodeByOffset with binary search', () => {
|
||||
|
||||
const node = findNodeByOffset(sourceFile.getParseResults()!.parserOutput.parseTree, range.pos);
|
||||
assert.strictEqual(node?.nodeType, ParseNodeType.Name);
|
||||
assert.strictEqual((node as NameNode).value, 'r');
|
||||
assert.strictEqual((node as NameNode).d.value, 'r');
|
||||
});
|
||||
|
||||
test('findNodeByOffset with binary search choose earliest match', () => {
|
||||
@ -414,7 +414,7 @@ test('findNodeByOffset with binary search choose earliest match', () => {
|
||||
|
||||
const node = findNodeByOffset(sourceFile.getParseResults()!.parserOutput.parseTree, range.pos);
|
||||
assert.strictEqual(node?.nodeType, ParseNodeType.Name);
|
||||
assert.strictEqual((node as NameNode).value, 'r');
|
||||
assert.strictEqual((node as NameNode).d.value, 'r');
|
||||
});
|
||||
|
||||
function testNodeRange(state: TestState, markerName: string, type: ParseNodeType, includeTrailingBlankLines = false) {
|
||||
|
@ -22,7 +22,7 @@ test('Empty', () => {
|
||||
const parserOutput = TestUtils.parseText('', diagSink).parserOutput;
|
||||
|
||||
assert.equal(diagSink.fetchAndClear().length, 0);
|
||||
assert.equal(parserOutput.parseTree.statements.length, 0);
|
||||
assert.equal(parserOutput.parseTree.d.statements.length, 0);
|
||||
});
|
||||
|
||||
test('Parser1', () => {
|
||||
@ -30,7 +30,7 @@ test('Parser1', () => {
|
||||
const parserOutput = TestUtils.parseSampleFile('parser1.py', diagSink).parserOutput;
|
||||
|
||||
assert.equal(diagSink.fetchAndClear().length, 0);
|
||||
assert.equal(parserOutput.parseTree.statements.length, 4);
|
||||
assert.equal(parserOutput.parseTree.d.statements.length, 4);
|
||||
});
|
||||
|
||||
test('Parser2', () => {
|
||||
@ -69,15 +69,15 @@ test('ExpressionWrappedInParens', () => {
|
||||
const parserOutput = TestUtils.parseText('(str)', diagSink).parserOutput;
|
||||
|
||||
assert.equal(diagSink.fetchAndClear().length, 0);
|
||||
assert.equal(parserOutput.parseTree.statements.length, 1);
|
||||
assert.equal(parserOutput.parseTree.statements[0].nodeType, ParseNodeType.StatementList);
|
||||
assert.equal(parserOutput.parseTree.d.statements.length, 1);
|
||||
assert.equal(parserOutput.parseTree.d.statements[0].nodeType, ParseNodeType.StatementList);
|
||||
|
||||
const statementList = parserOutput.parseTree.statements[0] as StatementListNode;
|
||||
assert.equal(statementList.statements.length, 1);
|
||||
const statementList = parserOutput.parseTree.d.statements[0] as StatementListNode;
|
||||
assert.equal(statementList.d.statements.length, 1);
|
||||
|
||||
// length of node should include parens
|
||||
assert.equal(statementList.statements[0].nodeType, ParseNodeType.Name);
|
||||
assert.equal(statementList.statements[0].length, 5);
|
||||
assert.equal(statementList.d.statements[0].nodeType, ParseNodeType.Name);
|
||||
assert.equal(statementList.d.statements[0].length, 5);
|
||||
});
|
||||
|
||||
test('MaxParseDepth1', () => {
|
||||
|
@ -232,7 +232,7 @@ function assertTypeAlias(code: string) {
|
||||
const range = state.getRangeByMarkerName('decl')!;
|
||||
const decls = mapper.findDeclarationsByType(markerUri, type, /* userTypeAlias */ true);
|
||||
|
||||
const decl = decls.find((d) => isVariableDeclaration(d) && d.typeAliasName && d.typeAliasName.value === 'M') as
|
||||
const decl = decls.find((d) => isVariableDeclaration(d) && d.typeAliasName && d.typeAliasName.d.value === 'M') as
|
||||
| VariableDeclaration
|
||||
| undefined;
|
||||
assert(decl);
|
||||
|
Loading…
Reference in New Issue
Block a user