Modified parser data structures to make parse nodes monomorphic and improve performance. (#8416)

This commit is contained in:
Eric Traut 2024-07-13 17:45:13 -07:00 committed by GitHub
parent 5ac7f49a3f
commit 210bb144d7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
48 changed files with 4299 additions and 3707 deletions

View File

@ -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

View File

@ -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);

View File

@ -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),
];
}

View File

@ -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
);
}

View File

@ -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
);
}

View File

@ -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;

View File

@ -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);
}

View File

@ -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;

View File

@ -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 {

View File

@ -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
);

View File

@ -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

View File

@ -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}`);

View File

@ -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
);

View File

@ -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,
};

View File

@ -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.

View File

@ -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
);
}

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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}`;

View File

@ -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

View File

@ -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)
);
}

View File

@ -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

View File

@ -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) {

View File

@ -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;

View File

@ -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;

View File

@ -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;
}

View File

@ -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);
}
}
}

View File

@ -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: [],
};
}

View File

@ -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,

View File

@ -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) {

View File

@ -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 [];

View File

@ -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(

View File

@ -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;
}
}

View File

@ -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;
}

View File

@ -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) {

View File

@ -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
);
}

View File

@ -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

View File

@ -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);

View File

@ -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) {

View File

@ -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', () => {

View File

@ -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);