mirror of
https://github.com/microsoft/pyright.git
synced 2024-09-20 04:37:57 +03:00
Fixed crashing bug in type stub writer.
This commit is contained in:
parent
940acae881
commit
69980ab8dd
@ -13,7 +13,7 @@
|
||||
import { ClassNode, FunctionNode, LambdaNode, ListComprehensionNode, ModuleNode,
|
||||
ParseNode } from '../parser/parseNodes';
|
||||
import { AnalyzerFileInfo } from './analyzerFileInfo';
|
||||
import { FlowNode } from './codeFlow';
|
||||
import { FlowFlags, FlowNode } from './codeFlow';
|
||||
import { Declaration } from './declaration';
|
||||
import { ImportResult } from './importResult';
|
||||
import { Scope } from './scope';
|
||||
@ -119,3 +119,19 @@ export function setFileInfo(node: ModuleNode, fileInfo: AnalyzerFileInfo) {
|
||||
const analyzerNode = node as AnalyzerNodeInfo;
|
||||
analyzerNode.fileInfo = fileInfo;
|
||||
}
|
||||
|
||||
export function isCodeUnreachable(node: ParseNode): boolean {
|
||||
let curNode: ParseNode | undefined = node;
|
||||
|
||||
// Walk up the parse tree until we find a node with
|
||||
// an associated flow node.
|
||||
while (curNode) {
|
||||
const flowNode = getFlowNode(curNode);
|
||||
if (flowNode) {
|
||||
return !!(flowNode.flags & FlowFlags.Unreachable);
|
||||
}
|
||||
curNode = curNode.parent;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -70,7 +70,7 @@ export class Checker extends ParseTreeWalker {
|
||||
}
|
||||
|
||||
walk(node: ParseNode) {
|
||||
if (!this._isCodeUnreachable(node)) {
|
||||
if (!AnalyzerNodeInfo.isCodeUnreachable(node)) {
|
||||
super.walk(node);
|
||||
}
|
||||
}
|
||||
@ -991,7 +991,7 @@ export class Checker extends ParseTreeWalker {
|
||||
};
|
||||
|
||||
suiteNode.statements.forEach(statement => {
|
||||
if (!this._isCodeUnreachable(statement)) {
|
||||
if (!AnalyzerNodeInfo.isCodeUnreachable(statement)) {
|
||||
if (statement.nodeType === ParseNodeType.StatementList) {
|
||||
for (const substatement of statement.statements) {
|
||||
if (substatement.nodeType !== ParseNodeType.TypeAnnotation &&
|
||||
@ -1009,22 +1009,6 @@ export class Checker extends ParseTreeWalker {
|
||||
});
|
||||
}
|
||||
|
||||
private _isCodeUnreachable(node: ParseNode): boolean {
|
||||
let curNode: ParseNode | undefined = node;
|
||||
|
||||
// Walk up the parse tree until we find a node with
|
||||
// an associated flow node.
|
||||
while (curNode) {
|
||||
const flowNode = AnalyzerNodeInfo.getFlowNode(curNode);
|
||||
if (flowNode) {
|
||||
return !!(flowNode.flags & FlowFlags.Unreachable);
|
||||
}
|
||||
curNode = curNode.parent;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private _validateFunctionReturn(node: FunctionNode, functionType: FunctionType) {
|
||||
// Stub files are allowed not to return an actual value,
|
||||
// so skip this if it's a stub file.
|
||||
|
@ -571,9 +571,23 @@ export class AnalyzerService {
|
||||
// don't include those.
|
||||
const resolvedPath = importResult.resolvedPaths[
|
||||
importResult.resolvedPaths.length - 1];
|
||||
this._typeStubTargetPath = importResult.resolvedPaths[0];
|
||||
if (isFile(this._typeStubTargetPath)) {
|
||||
this._typeStubTargetPath = getDirectoryPath(this._typeStubTargetPath);
|
||||
|
||||
// Get the directory that contains the root package.
|
||||
let targetPath = getDirectoryPath(resolvedPath);
|
||||
for (let i = importResult.resolvedPaths.length - 2; i >= 0; i--) {
|
||||
const resolvedPath = importResult.resolvedPaths[i];
|
||||
if (resolvedPath) {
|
||||
targetPath = getDirectoryPath(resolvedPath);
|
||||
} else {
|
||||
// If there was no file corresponding to this portion
|
||||
// of the name path, assume that it's contained
|
||||
// within its parent directory.
|
||||
targetPath = getDirectoryPath(targetPath);
|
||||
}
|
||||
}
|
||||
|
||||
if (isDirectory(targetPath)) {
|
||||
this._typeStubTargetPath = targetPath;
|
||||
}
|
||||
|
||||
if (!resolvedPath) {
|
||||
|
@ -13,8 +13,9 @@ import * as fs from 'fs';
|
||||
import { ArgumentCategory, ArgumentNode, AssignmentNode, AugmentedAssignmentNode,
|
||||
ClassNode, DecoratorNode, ExpressionNode, ForNode, FunctionNode, IfNode,
|
||||
ImportFromNode, ImportNode, ModuleNameNode, NameNode, ParameterCategory, ParameterNode,
|
||||
ParseNodeType, StatementListNode, StringNode, TryNode, TypeAnnotationNode,
|
||||
WhileNode, WithNode } from '../parser/parseNodes';
|
||||
ParseNode, ParseNodeType, StatementListNode, StringNode, TryNode,
|
||||
TypeAnnotationNode, WhileNode, WithNode } from '../parser/parseNodes';
|
||||
import * as AnalyzerNodeInfo from './analyzerNodeInfo';
|
||||
import * as ParseTreeUtils from './parseTreeUtils';
|
||||
import { ParseTreeWalker } from './parseTreeWalker';
|
||||
import { getScopeForNode } from './scopeUtils';
|
||||
@ -47,10 +48,11 @@ interface TrackedImportSymbol {
|
||||
}
|
||||
|
||||
class TrackedImportFrom extends TrackedImport {
|
||||
symbols: TrackedImportSymbol[] = [];
|
||||
|
||||
constructor(importName: string, public isWildcardImport: boolean, public node?: ImportFromNode) {
|
||||
super(importName);
|
||||
}
|
||||
symbols: TrackedImportSymbol[] = [];
|
||||
|
||||
addSymbol(symbol: Symbol | undefined, name: string,
|
||||
alias: string | undefined, isAccessed = false) {
|
||||
@ -78,6 +80,12 @@ class ImportSymbolWalker extends ParseTreeWalker {
|
||||
this.walk(node);
|
||||
}
|
||||
|
||||
walk(node: ParseNode) {
|
||||
if (!AnalyzerNodeInfo.isCodeUnreachable(node)) {
|
||||
super.walk(node);
|
||||
}
|
||||
}
|
||||
|
||||
visitName(node: NameNode) {
|
||||
this._accessedImportedSymbols.set(node.value, true);
|
||||
return true;
|
||||
@ -129,6 +137,12 @@ export class TypeStubWriter extends ParseTreeWalker {
|
||||
this._writeFile();
|
||||
}
|
||||
|
||||
walk(node: ParseNode) {
|
||||
if (!AnalyzerNodeInfo.isCodeUnreachable(node)) {
|
||||
super.walk(node);
|
||||
}
|
||||
}
|
||||
|
||||
visitClass(node: ClassNode) {
|
||||
const className = node.name.value;
|
||||
|
||||
|
@ -52,7 +52,7 @@ class FindReferencesTreeWalker extends ParseTreeWalker {
|
||||
}
|
||||
|
||||
walk(node: ParseNode) {
|
||||
if (!this._isCodeUnreachable(node)) {
|
||||
if (!AnalyzerNodeInfo.isCodeUnreachable(node)) {
|
||||
super.walk(node);
|
||||
}
|
||||
}
|
||||
@ -90,22 +90,6 @@ class FindReferencesTreeWalker extends ParseTreeWalker {
|
||||
return this._referencesResult.declarations.some(decl =>
|
||||
DeclarationUtils.areDeclarationsSame(decl, resolvedDecl));
|
||||
}
|
||||
|
||||
private _isCodeUnreachable(node: ParseNode): boolean {
|
||||
let curNode: ParseNode | undefined = node;
|
||||
|
||||
// Walk up the parse tree until we find a node with
|
||||
// an associated flow node.
|
||||
while (curNode) {
|
||||
const flowNode = AnalyzerNodeInfo.getFlowNode(curNode);
|
||||
if (flowNode) {
|
||||
return !!(flowNode.flags & FlowFlags.Unreachable);
|
||||
}
|
||||
curNode = curNode.parent;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export class ReferencesProvider {
|
||||
|
Loading…
Reference in New Issue
Block a user