mirror of
https://github.com/microsoft/pyright.git
synced 2024-09-20 04:37:57 +03:00
Avoid creating code flow nodes for expressions that are not supported.
This commit is contained in:
parent
676a4b4b76
commit
f95ed3c705
@ -37,7 +37,8 @@ import { KeywordType, OperatorType } from '../parser/tokenizerTypes';
|
||||
import { AnalyzerFileInfo } from './analyzerFileInfo';
|
||||
import * as AnalyzerNodeInfo from './analyzerNodeInfo';
|
||||
import { FlowAssignment, FlowAssignmentAlias, FlowCall, FlowCondition, FlowFlags, FlowLabel,
|
||||
FlowNode, FlowPostFinally, FlowPreFinallyGate, FlowWildcardImport, getUniqueFlowNodeId } from './codeFlow';
|
||||
FlowNode, FlowPostFinally, FlowPreFinallyGate, FlowWildcardImport, getUniqueFlowNodeId,
|
||||
isCodeFlowSupportedForReference } from './codeFlow';
|
||||
import { AliasDeclaration, ClassDeclaration, DeclarationType, FunctionDeclaration,
|
||||
IntrinsicType, ModuleLoaderActions, VariableDeclaration } from './declaration';
|
||||
import { ImplicitImport, ImportResult, ImportType } from './importResult';
|
||||
@ -1480,7 +1481,7 @@ export class Binder extends ParseTreeWalker {
|
||||
switch (expression.nodeType) {
|
||||
case ParseNodeType.Name:
|
||||
case ParseNodeType.MemberAccess: {
|
||||
return true;
|
||||
return isCodeFlowSupportedForReference(expression);
|
||||
}
|
||||
|
||||
case ParseNodeType.BinaryOperation: {
|
||||
@ -1599,7 +1600,7 @@ export class Binder extends ParseTreeWalker {
|
||||
}
|
||||
|
||||
const prevFlowNode = this._currentFlowNode;
|
||||
if (!this._isCodeUnreachable()) {
|
||||
if (!this._isCodeUnreachable() && isCodeFlowSupportedForReference(node)) {
|
||||
const flowNode: FlowAssignment = {
|
||||
flags: FlowFlags.Assignment,
|
||||
id: getUniqueFlowNodeId(),
|
||||
|
@ -13,7 +13,10 @@
|
||||
* TypeScript compiler.
|
||||
*/
|
||||
|
||||
import { CallNode, ExpressionNode, ImportFromNode, MemberAccessNode, NameNode } from '../parser/parseNodes';
|
||||
import * as assert from 'assert';
|
||||
|
||||
import { CallNode, ExpressionNode, ImportFromNode, MemberAccessNode, NameNode,
|
||||
ParseNodeType } from '../parser/parseNodes';
|
||||
|
||||
export enum FlowFlags {
|
||||
Unreachable = 1 << 0, // Unreachable code
|
||||
@ -100,3 +103,35 @@ export interface FlowPostFinally extends FlowNode {
|
||||
antecedent: FlowNode;
|
||||
preFinallyGate: FlowPreFinallyGate;
|
||||
}
|
||||
|
||||
export function isCodeFlowSupportedForReference(reference: ExpressionNode): boolean {
|
||||
if (reference.nodeType === ParseNodeType.Name) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (reference.nodeType === ParseNodeType.MemberAccess) {
|
||||
return isCodeFlowSupportedForReference(reference.leftExpression);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
export function createKeyForReference(reference: NameNode | MemberAccessNode,
|
||||
targetSymbolId: number): string {
|
||||
|
||||
let key;
|
||||
if (reference.nodeType === ParseNodeType.Name) {
|
||||
key = reference.nameToken.value;
|
||||
} else {
|
||||
key = reference.memberName.nameToken.value;
|
||||
let leftNode = reference.leftExpression;
|
||||
while (leftNode.nodeType === ParseNodeType.MemberAccess) {
|
||||
key = leftNode.memberName.nameToken.value + '.' + key;
|
||||
leftNode = leftNode.leftExpression;
|
||||
}
|
||||
assert(leftNode.nodeType === ParseNodeType.Name);
|
||||
key = (leftNode as NameNode).nameToken.value + '.' + key;
|
||||
}
|
||||
|
||||
return key + '.' + targetSymbolId.toString();
|
||||
}
|
||||
|
@ -33,8 +33,9 @@ import { ArgumentCategory, AssignmentNode, AugmentedAssignmentNode, BinaryOperat
|
||||
import { KeywordType, OperatorType, StringTokenFlags, TokenType } from '../parser/tokenizerTypes';
|
||||
import { AnalyzerFileInfo, ImportLookup, ImportLookupResult } from './analyzerFileInfo';
|
||||
import * as AnalyzerNodeInfo from './analyzerNodeInfo';
|
||||
import { FlowAssignment, FlowAssignmentAlias, FlowCall, FlowCondition, FlowFlags, FlowLabel,
|
||||
FlowNode, FlowPostFinally, FlowPreFinallyGate, FlowWildcardImport } from './codeFlow';
|
||||
import { createKeyForReference, FlowAssignment, FlowAssignmentAlias, FlowCall, FlowCondition, FlowFlags,
|
||||
FlowLabel, FlowNode, FlowPostFinally, FlowPreFinallyGate, FlowWildcardImport,
|
||||
isCodeFlowSupportedForReference } from './codeFlow';
|
||||
import { AliasDeclaration, Declaration, DeclarationType, FunctionDeclaration,
|
||||
ModuleLoaderActions, VariableDeclaration } from './declaration';
|
||||
import * as ParseTreeUtils from './parseTreeUtils';
|
||||
@ -6537,18 +6538,6 @@ export function createTypeEvaluator(importLookup: ImportLookup): TypeEvaluator {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function isCodeFlowSupportedForReference(reference: ExpressionNode): boolean {
|
||||
if (reference.nodeType === ParseNodeType.Name) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (reference.nodeType === ParseNodeType.MemberAccess) {
|
||||
return isCodeFlowSupportedForReference(reference.leftExpression);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function getTypeFromWildcardImport(flowNode: FlowWildcardImport, name: string): Type {
|
||||
const importInfo = AnalyzerNodeInfo.getImportInfo(flowNode.node.module);
|
||||
assert(importInfo && importInfo.isImportFound);
|
||||
@ -6627,24 +6616,6 @@ export function createTypeEvaluator(importLookup: ImportLookup): TypeEvaluator {
|
||||
return analyzer.getFlowType(reference, targetSymbolId, initialType);
|
||||
}
|
||||
|
||||
function createKeyForReference(reference: NameNode | MemberAccessNode, targetSymbolId: number): string {
|
||||
let key;
|
||||
if (reference.nodeType === ParseNodeType.Name) {
|
||||
key = reference.nameToken.value;
|
||||
} else {
|
||||
key = reference.memberName.nameToken.value;
|
||||
let leftNode = reference.leftExpression;
|
||||
while (leftNode.nodeType === ParseNodeType.MemberAccess) {
|
||||
key = leftNode.memberName.nameToken.value + '.' + key;
|
||||
leftNode = leftNode.leftExpression;
|
||||
}
|
||||
assert(leftNode.nodeType === ParseNodeType.Name);
|
||||
key = (leftNode as NameNode).nameToken.value + '.' + key;
|
||||
}
|
||||
|
||||
return key + '.' + targetSymbolId.toString();
|
||||
}
|
||||
|
||||
// Creates a new code flow analyzer that can be used to narrow the types
|
||||
// of the expressions within an execution context. Each code flow analyzer
|
||||
// instance maintains a cache of types it has already determined.
|
||||
|
Loading…
Reference in New Issue
Block a user