pull-pylance-with-pyright-1.1.273 (#3991)

Co-authored-by: Bill Schnurr <bschnurr@microsoft.com>
Co-authored-by: HeeJae Chang <hechang@microsoft.com>
Co-authored-by: Erik De Bonte <erikd@microsoft.com>
Co-authored-by: Rich Chiodo <rchiodo@microsoft.com>
This commit is contained in:
PylanceBot 2022-09-28 10:03:38 -07:00 committed by GitHub
parent f04730ce92
commit 4047554222
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 1440 additions and 3 deletions

View File

@ -11,6 +11,7 @@
* TypeScript compiler. * TypeScript compiler.
*/ */
import { ConsoleInterface } from '../common/console';
import { assert, fail } from '../common/debug'; import { assert, fail } from '../common/debug';
import { convertOffsetToPosition } from '../common/positionUtils'; import { convertOffsetToPosition } from '../common/positionUtils';
import { ArgumentCategory, ExpressionNode, ParseNode, ParseNodeType } from '../parser/parseNodes'; import { ArgumentCategory, ExpressionNode, ParseNode, ParseNodeType } from '../parser/parseNodes';
@ -99,6 +100,12 @@ export interface CodeFlowEngine {
createCodeFlowAnalyzer: () => CodeFlowAnalyzer; createCodeFlowAnalyzer: () => CodeFlowAnalyzer;
isFlowNodeReachable: (flowNode: FlowNode, sourceFlowNode?: FlowNode, ignoreNoReturn?: boolean) => boolean; isFlowNodeReachable: (flowNode: FlowNode, sourceFlowNode?: FlowNode, ignoreNoReturn?: boolean) => boolean;
narrowConstrainedTypeVar: (flowNode: FlowNode, typeVar: TypeVarType) => Type | undefined; narrowConstrainedTypeVar: (flowNode: FlowNode, typeVar: TypeVarType) => Type | undefined;
printControlFlowGraph: (
flowNode: FlowNode,
reference: CodeFlowReferenceExpressionNode | undefined,
callName: string,
logger: ConsoleInterface
) => void;
} }
interface CodeFlowTypeCache { interface CodeFlowTypeCache {
@ -1557,7 +1564,8 @@ export function getCodeFlowEngine(
function printControlFlowGraph( function printControlFlowGraph(
flowNode: FlowNode, flowNode: FlowNode,
reference: CodeFlowReferenceExpressionNode | undefined, reference: CodeFlowReferenceExpressionNode | undefined,
callName: string callName: string,
logger: ConsoleInterface = console
) { ) {
let referenceText = ''; let referenceText = '';
if (reference) { if (reference) {
@ -1566,13 +1574,14 @@ export function getCodeFlowEngine(
referenceText = `${printExpression(reference)}[${pos.line + 1}:${pos.character + 1}]`; referenceText = `${printExpression(reference)}[${pos.line + 1}:${pos.character + 1}]`;
} }
console.log(`${callName}@${flowNode.id}: ${referenceText || '(none)'}`); logger.log(`${callName}@${flowNode.id}: ${referenceText || '(none)'}`);
console.log(formatControlFlowGraph(flowNode)); logger.log(formatControlFlowGraph(flowNode));
} }
return { return {
createCodeFlowAnalyzer, createCodeFlowAnalyzer,
isFlowNodeReachable, isFlowNodeReachable,
narrowConstrainedTypeVar, narrowConstrainedTypeVar,
printControlFlowGraph,
}; };
} }

View File

@ -20,6 +20,7 @@ import { Commands } from '../commands/commands';
import { throwIfCancellationRequested } from '../common/cancellationUtils'; import { throwIfCancellationRequested } from '../common/cancellationUtils';
import { appendArray } from '../common/collectionUtils'; import { appendArray } from '../common/collectionUtils';
import { DiagnosticLevel } from '../common/configOptions'; import { DiagnosticLevel } from '../common/configOptions';
import { ConsoleInterface } from '../common/console';
import { assert, assertNever, fail } from '../common/debug'; import { assert, assertNever, fail } from '../common/debug';
import { AddMissingOptionalToParamAction, DiagnosticAddendum } from '../common/diagnostic'; import { AddMissingOptionalToParamAction, DiagnosticAddendum } from '../common/diagnostic';
import { DiagnosticRule } from '../common/diagnosticRules'; import { DiagnosticRule } from '../common/diagnosticRules';
@ -832,6 +833,11 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions
})?.type; })?.type;
} }
// Reads the type of the node from the cache.
function getCachedType(node: ExpressionNode): Type | undefined {
return readTypeCache(node, EvaluatorFlags.None);
}
// Determines the expected type of a specified node based on surrounding // Determines the expected type of a specified node based on surrounding
// context. For example, if it's a subexpression of an argument expression, // context. For example, if it's a subexpression of an argument expression,
// the associated parameter type might inform the expected type. // the associated parameter type might inform the expected type.
@ -24051,9 +24057,19 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions
return (range.start.line + 1).toString(); return (range.start.line + 1).toString();
} }
function printControlFlowGraph(
flowNode: FlowNode,
reference: CodeFlowReferenceExpressionNode | undefined,
callName: string,
logger: ConsoleInterface
) {
return codeFlowEngine.printControlFlowGraph(flowNode, reference, callName, logger);
}
const evaluatorInterface: TypeEvaluator = { const evaluatorInterface: TypeEvaluator = {
runWithCancellationToken, runWithCancellationToken,
getType, getType,
getCachedType,
getTypeOfExpression, getTypeOfExpression,
getTypeOfAnnotation, getTypeOfAnnotation,
getTypeOfClass, getTypeOfClass,
@ -24135,6 +24151,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions
useSpeculativeMode, useSpeculativeMode,
setTypeForNode, setTypeForNode,
checkForCancellation, checkForCancellation,
printControlFlowGraph,
}; };
const codeFlowEngine = getCodeFlowEngine(evaluatorInterface, speculativeTypeTracker); const codeFlowEngine = getCodeFlowEngine(evaluatorInterface, speculativeTypeTracker);

View File

@ -11,6 +11,7 @@
import { CancellationToken } from 'vscode-languageserver-protocol'; import { CancellationToken } from 'vscode-languageserver-protocol';
import { DiagnosticLevel } from '../common/configOptions'; import { DiagnosticLevel } from '../common/configOptions';
import { ConsoleInterface } from '../common/console';
import { Diagnostic, DiagnosticAddendum } from '../common/diagnostic'; import { Diagnostic, DiagnosticAddendum } from '../common/diagnostic';
import { TextRange } from '../common/textRange'; import { TextRange } from '../common/textRange';
import { import {
@ -31,6 +32,7 @@ import {
} from '../parser/parseNodes'; } from '../parser/parseNodes';
import * as DeclarationUtils from './aliasDeclarationUtils'; import * as DeclarationUtils from './aliasDeclarationUtils';
import { AnalyzerFileInfo } from './analyzerFileInfo'; import { AnalyzerFileInfo } from './analyzerFileInfo';
import { CodeFlowReferenceExpressionNode, FlowNode } from './codeFlowTypes';
import { Declaration } from './declaration'; import { Declaration } from './declaration';
import { SymbolWithScope } from './scope'; import { SymbolWithScope } from './scope';
import { Symbol } from './symbol'; import { Symbol } from './symbol';
@ -312,6 +314,7 @@ export interface TypeEvaluator {
runWithCancellationToken<T>(token: CancellationToken, callback: () => T): T; runWithCancellationToken<T>(token: CancellationToken, callback: () => T): T;
getType: (node: ExpressionNode) => Type | undefined; getType: (node: ExpressionNode) => Type | undefined;
getCachedType: (node: ExpressionNode) => Type | undefined;
getTypeOfExpression: (node: ExpressionNode, flags?: EvaluatorFlags, expectedType?: Type) => TypeResult; getTypeOfExpression: (node: ExpressionNode, flags?: EvaluatorFlags, expectedType?: Type) => TypeResult;
getTypeOfAnnotation: (node: ExpressionNode, options?: AnnotationTypeOptions) => Type; getTypeOfAnnotation: (node: ExpressionNode, options?: AnnotationTypeOptions) => Type;
getTypeOfClass: (node: ClassNode) => ClassTypeResult | undefined; getTypeOfClass: (node: ClassNode) => ClassTypeResult | undefined;
@ -489,4 +492,10 @@ export interface TypeEvaluator {
setTypeForNode: (node: ParseNode, type?: Type, flags?: EvaluatorFlags) => void; setTypeForNode: (node: ParseNode, type?: Type, flags?: EvaluatorFlags) => void;
checkForCancellation: () => void; checkForCancellation: () => void;
printControlFlowGraph: (
flowNode: FlowNode,
reference: CodeFlowReferenceExpressionNode | undefined,
callName: string,
logger: ConsoleInterface
) => void;
} }

View File

@ -11,6 +11,7 @@ import { CancellationToken, ExecuteCommandParams, ResponseError } from 'vscode-l
import { LanguageServerInterface } from '../languageServerBase'; import { LanguageServerInterface } from '../languageServerBase';
import { Commands } from './commands'; import { Commands } from './commands';
import { CreateTypeStubCommand } from './createTypeStub'; import { CreateTypeStubCommand } from './createTypeStub';
import { DumpFileDebugInfoCommand } from './dumpFileDebugInfoCommand';
import { QuickActionCommand } from './quickActionCommand'; import { QuickActionCommand } from './quickActionCommand';
import { RestartServerCommand } from './restartServer'; import { RestartServerCommand } from './restartServer';
@ -22,11 +23,13 @@ export class CommandController implements ServerCommand {
private _createStub: CreateTypeStubCommand; private _createStub: CreateTypeStubCommand;
private _restartServer: RestartServerCommand; private _restartServer: RestartServerCommand;
private _quickAction: QuickActionCommand; private _quickAction: QuickActionCommand;
private _dumpFileDebugInfo: DumpFileDebugInfoCommand;
constructor(ls: LanguageServerInterface) { constructor(ls: LanguageServerInterface) {
this._createStub = new CreateTypeStubCommand(ls); this._createStub = new CreateTypeStubCommand(ls);
this._restartServer = new RestartServerCommand(ls); this._restartServer = new RestartServerCommand(ls);
this._quickAction = new QuickActionCommand(ls); this._quickAction = new QuickActionCommand(ls);
this._dumpFileDebugInfo = new DumpFileDebugInfoCommand(ls);
} }
async execute(cmdParams: ExecuteCommandParams, token: CancellationToken): Promise<any> { async execute(cmdParams: ExecuteCommandParams, token: CancellationToken): Promise<any> {
@ -44,6 +47,10 @@ export class CommandController implements ServerCommand {
return this._restartServer.execute(cmdParams); return this._restartServer.execute(cmdParams);
} }
case Commands.dumpFileDebugInfo: {
return this._dumpFileDebugInfo.execute(cmdParams, token);
}
default: { default: {
return new ResponseError<string>(1, 'Unsupported command'); return new ResponseError<string>(1, 'Unsupported command');
} }

View File

@ -13,4 +13,10 @@ export const enum Commands {
orderImports = 'pyright.organizeimports', orderImports = 'pyright.organizeimports',
addMissingOptionalToParam = 'pyright.addoptionalforparam', addMissingOptionalToParam = 'pyright.addoptionalforparam',
unusedImport = 'pyright.unusedImport', unusedImport = 'pyright.unusedImport',
dumpFileDebugInfo = 'pyright.dumpFileDebugInfo',
dumpTokens = 'pyright.dumpTokens',
dumpNodes = 'pyright.dumpNodes',
dumpTypes = 'pyright.dumpTypes',
dumpCachedTypes = 'pyright.dumpCachedTypes',
dumpCodeFlowGraph = 'pyright.dumpCodeFlowGraph',
} }

File diff suppressed because it is too large Load Diff

View File

@ -51,7 +51,38 @@
"command": "pyright.restartserver", "command": "pyright.restartserver",
"title": "Restart Server", "title": "Restart Server",
"category": "Pyright" "category": "Pyright"
},
{
"command": "pyright.dumpTokens",
"title": "Dump token streams ...",
"category": "Pyright",
"enablement": "editorLangId == python && pyright.development"
},
{
"command": "pyright.dumpNodes",
"title": "Dump parse tree ...",
"category": "Pyright",
"enablement": "editorLangId == python && pyright.development"
},
{
"command": "pyright.dumpTypes",
"title": "Dump type info ...",
"category": "Pyright",
"enablement": "editorLangId == python && pyright.development"
},
{
"command": "pyright.dumpCachedTypes",
"title": "Dump cached type info ...",
"category": "Pyright",
"enablement": "editorLangId == python && pyright.development"
},
{
"command": "pyright.dumpCodeFlowGraph",
"title": "Dump code flow graph for node ...",
"category": "Pyright",
"enablement": "editorLangId == python && pyright.development"
} }
], ],
"menus": { "menus": {
"editor/context": [ "editor/context": [
@ -61,7 +92,30 @@
"group": "Pyright", "group": "Pyright",
"when": "editorLangId == python" "when": "editorLangId == python"
} }
],
"commandPalette": [
{
"command": "pyright.dumpTokens",
"when": "editorLangId == python && pyright.development"
},
{
"command": "pyright.dumpNodes",
"when": "editorLangId == python && pyright.development"
},
{
"command": "pyright.dumpTypes",
"when": "editorLangId == python && pyright.development"
},
{
"command": "pyright.dumpCachedTypes",
"when": "editorLangId == python && pyright.development"
},
{
"command": "pyright.dumpCodeFlowGraph",
"when": "editorLangId == python && pyright.development"
}
] ]
}, },
"configuration": { "configuration": {
"type": "object", "type": "object",

View File

@ -13,6 +13,7 @@ import * as path from 'path';
import { import {
commands, commands,
ExtensionContext, ExtensionContext,
ExtensionMode,
extensions, extensions,
OutputChannel, OutputChannel,
Position, Position,
@ -210,6 +211,81 @@ export async function activate(context: ExtensionContext) {
); );
}); });
// Register the debug only commands when running under the debugger.
if (context.extensionMode === ExtensionMode.Development) {
// Create a 'when' context for development.
commands.executeCommand('setContext', 'pyright.development', true);
// Register the commands that only work when in development mode.
context.subscriptions.push(
commands.registerCommand(Commands.dumpTokens, () => {
const fileName = window.activeTextEditor?.document.fileName;
if (fileName) {
client.sendRequest('workspace/executeCommand', {
command: Commands.dumpFileDebugInfo,
arguments: [fileName, 'tokens'],
});
}
})
);
context.subscriptions.push(
commands.registerCommand(Commands.dumpNodes, () => {
const fileName = window.activeTextEditor?.document.fileName;
if (fileName) {
client.sendRequest('workspace/executeCommand', {
command: Commands.dumpFileDebugInfo,
arguments: [fileName, 'nodes'],
});
}
})
);
context.subscriptions.push(
commands.registerCommand(Commands.dumpTypes, () => {
const fileName = window.activeTextEditor?.document.fileName;
if (fileName) {
const start = window.activeTextEditor!.selection.start;
const end = window.activeTextEditor!.selection.end;
const startOffset = window.activeTextEditor!.document.offsetAt(start);
const endOffset = window.activeTextEditor!.document.offsetAt(end);
client.sendRequest('workspace/executeCommand', {
command: Commands.dumpFileDebugInfo,
arguments: [fileName, 'types', startOffset, endOffset],
});
}
})
);
context.subscriptions.push(
commands.registerCommand(Commands.dumpCachedTypes, () => {
const fileName = window.activeTextEditor?.document.fileName;
if (fileName) {
const start = window.activeTextEditor!.selection.start;
const end = window.activeTextEditor!.selection.end;
const startOffset = window.activeTextEditor!.document.offsetAt(start);
const endOffset = window.activeTextEditor!.document.offsetAt(end);
client.sendRequest('workspace/executeCommand', {
command: Commands.dumpFileDebugInfo,
arguments: [fileName, 'cachedtypes', startOffset, endOffset],
});
}
})
);
context.subscriptions.push(
commands.registerCommand(Commands.dumpCodeFlowGraph, () => {
const fileName = window.activeTextEditor?.document.fileName;
if (fileName) {
const start = window.activeTextEditor!.selection.start;
const startOffset = window.activeTextEditor!.document.offsetAt(start);
client.sendRequest('workspace/executeCommand', {
command: Commands.dumpFileDebugInfo,
arguments: [fileName, 'codeflowgraph', startOffset],
});
}
})
);
}
await client.start(); await client.start();
} }