Added new VS Code setting "pyright.openFilesOnly", which is set to true.

This commit is contained in:
Eric Traut 2019-11-15 18:37:14 -08:00
parent 460239e7d5
commit 894cdbd52b
8 changed files with 73 additions and 50 deletions

View File

@ -87,6 +87,12 @@
"default": false,
"description": "Disables type completion, definitions, and references.",
"scope": "resource"
},
"pyright.openFilesOnly": {
"type": "boolean",
"default": true,
"description": "Report errors for all files in the workspace or only currently-open files?",
"scope": "resource"
}
}
},

View File

@ -4,6 +4,8 @@ The Pyright VS Code extension honors the following settings.
**pyright.disableLanguageServices** [boolean]: Disables all language services except for “hover”. This includes type completion, signature completion, find definition, find references, and find symbols in file. This option is useful if you want to use pyright only as a type checker but want to run another Python language server for langue service features.
**pyright.openFilesOnly** [boolean]: Determines whether pyright analyzes (and reports errors for) all files in the workspace, as indicated by the config file. If this option is set to true, pyright analyzes only open files.
**python.analysis.typeshedPaths** [array of paths]: Paths to look for typeshed modules. Pyright currently honors only the first path in the array.
**python.pythonPath** [path]: Path to Python interpreter.

View File

@ -35,8 +35,6 @@ import { createTypeEvaluator, TypeEvaluator } from './typeEvaluator';
import { TypeStubWriter } from './typeStubWriter';
const _maxImportDepth = 256;
const _maxAnalysisTimeForCompletions = 500;
const _analyzeOnlyOpenFiles = false;
const _allowAllThirdPartyImports = true;
export interface SourceFileInfo {
@ -146,7 +144,7 @@ export class Program {
fileInfo.sourceFile.isBindingRequired() ||
fileInfo.sourceFile.isCheckingRequired()) {
if ((!_analyzeOnlyOpenFiles && fileInfo.isTracked) || fileInfo.isOpenByClient) {
if ((!this._configOptions.checkOnlyOpenFiles && fileInfo.isTracked) || fileInfo.isOpenByClient) {
sourceFileCount++;
}
}
@ -155,6 +153,10 @@ export class Program {
return sourceFileCount;
}
isCheckingOnlyOpenFiles() {
return this._configOptions.checkOnlyOpenFiles;
}
addTrackedFiles(filePaths: string[]) {
filePaths.forEach(filePath => {
this.addTrackedFile(filePath);
@ -295,7 +297,7 @@ export class Program {
}
}
if (!_analyzeOnlyOpenFiles) {
if (!this._configOptions.checkOnlyOpenFiles) {
// Do type analysis of remaining files.
const allFiles = this._sourceFileList;
@ -700,7 +702,7 @@ export class Program {
const fileDiagnostics: FileDiagnostics[] = this._removeUnneededFiles();
this._sourceFileList.forEach(sourceFileInfo => {
if ((!_analyzeOnlyOpenFiles && sourceFileInfo.isTracked) || sourceFileInfo.isOpenByClient) {
if ((!options.checkOnlyOpenFiles && sourceFileInfo.isTracked) || sourceFileInfo.isOpenByClient) {
const diagnostics = sourceFileInfo.sourceFile.getDiagnostics(
options, sourceFileInfo.diagnosticsVersion);
if (diagnostics !== undefined) {
@ -954,7 +956,7 @@ export class Program {
} else {
// If we're showing the user errors only for open files, clear
// out the errors for the now-closed file.
if (_analyzeOnlyOpenFiles && !fileInfo.isOpenByClient) {
if (this._configOptions.checkOnlyOpenFiles && !fileInfo.isOpenByClient) {
fileDiagnostics.push({
filePath: fileInfo.sourceFile.getFilePath(),
diagnostics: []

View File

@ -37,6 +37,7 @@ export { MaxAnalysisTime } from './program';
export interface AnalysisResults {
diagnostics: FileDiagnostics[];
filesInProgram: number;
checkingOnlyOpenFiles: boolean;
filesRequiringAnalysis: number;
fatalErrorOccurred: boolean;
configParseErrorOccurred: boolean;
@ -325,9 +326,8 @@ export class AnalyzerService {
}
}
if (commandLineOptions.verboseOutput) {
configOptions.verboseOutput = true;
}
configOptions.verboseOutput = !!commandLineOptions.verboseOutput;
configOptions.checkOnlyOpenFiles = !!commandLineOptions.checkOnlyOpenFiles;
// Do some sanity checks on the specified settings and report missing
// or inconsistent information.
@ -809,7 +809,7 @@ export class AnalyzerService {
// How long has it been since the user interacted with the service?
// If the user is actively typing, back off to let him or her finish.
const timeSinceLastUserInteractionInMs = Date.now() - this._lastUserInteractionTime;
const minBackoffTimeInMs = 3000;
const minBackoffTimeInMs = 1500;
// We choose a small non-zero value here. If this value
// is too small (like zero), the VS Code extension becomes
@ -866,6 +866,7 @@ export class AnalyzerService {
diagnostics: this._program.getDiagnostics(this._configOptions),
filesInProgram: this._program.getFileCount(),
filesRequiringAnalysis: filesLeftToAnalyze,
checkingOnlyOpenFiles: this._program.isCheckingOnlyOpenFiles(),
fatalErrorOccurred: false,
configParseErrorOccurred: false,
elapsedTime: duration.getDurationInSeconds()
@ -890,6 +891,7 @@ export class AnalyzerService {
diagnostics: [],
filesInProgram: 0,
filesRequiringAnalysis: 0,
checkingOnlyOpenFiles: true,
fatalErrorOccurred: true,
configParseErrorOccurred: false,
elapsedTime: 0
@ -907,6 +909,7 @@ export class AnalyzerService {
diagnostics: fileDiags,
filesInProgram: this._program.getFileCount(),
filesRequiringAnalysis: this._program.getFilesToAnalyzeCount(),
checkingOnlyOpenFiles: this._program.isCheckingOnlyOpenFiles(),
fatalErrorOccurred: false,
configParseErrorOccurred: false,
elapsedTime: 0
@ -921,6 +924,7 @@ export class AnalyzerService {
diagnostics: [],
filesInProgram: 0,
filesRequiringAnalysis: 0,
checkingOnlyOpenFiles: true,
fatalErrorOccurred: false,
configParseErrorOccurred: true,
elapsedTime: 0

View File

@ -46,6 +46,9 @@ export class CommandLineOptions {
// Emit verbose information to console?
verboseOutput?: boolean;
// Indicates that only open files should be checked.
checkOnlyOpenFiles?: boolean;
// Indicates that the settings came from VS Code rather than
// from the command-line. Useful for providing clearer error
// messages.

View File

@ -323,6 +323,9 @@ export class ConfigOptions {
// Emit verbose information to console?
verboseOutput: boolean;
// Perform type checking and report diagnostics only for open files?
checkOnlyOpenFiles: boolean;
//---------------------------------------------------------------
// Diagnostics Settings

View File

@ -109,6 +109,7 @@ function processArgs() {
}
options.verboseOutput = !!args.verbose;
options.checkOnlyOpenFiles = false;
const watch = args.watch !== undefined;
options.watch = watch;

View File

@ -32,6 +32,7 @@ interface PythonSettings {
interface PyrightSettings {
disableLanguageServices?: boolean;
openFilesOnly?: boolean;
}
interface WorkspaceServiceInstance {
@ -92,7 +93,8 @@ function _createAnalyzerService(name: string): AnalyzerService {
});
if (results.filesRequiringAnalysis > 0) {
if (!_isDisplayingProgress) {
// Display a progress spinner if we're checking the entire program.
if (!_isDisplayingProgress && !results.checkingOnlyOpenFiles) {
_isDisplayingProgress = true;
_connection.sendNotification('pyright/beginProgress');
}
@ -573,68 +575,72 @@ _connection.onDidCloseTextDocument(params => {
service.setFileClosed(filePath);
});
function getConfiguration(workspace: WorkspaceServiceInstance, section: string) {
if (workspace.rootUri) {
return _connection.workspace.getConfiguration({
scopeUri: workspace.rootUri || undefined,
section
});
} else {
return _connection.workspace.getConfiguration(section);
}
function getConfiguration(workspace: WorkspaceServiceInstance, sections: string[]) {
const scopeUri = workspace.rootUri ? workspace.rootUri : undefined;
return _connection.workspace.getConfiguration(
sections.map(section => {
return {
scopeUri,
section
};
})
);
}
function fetchSettingsForWorkspace(workspace: WorkspaceServiceInstance,
callback: (pythonSettings: PythonSettings, pyrightSettings: PyrightSettings) => void) {
const pythonSettingsPromise = getConfiguration(workspace, ['python', 'pyright']);
pythonSettingsPromise.then((settings: [PythonSettings, PyrightSettings]) => {
callback(settings[0], settings[1]);
}, () => {
// An error occurred trying to read the settings
// for this workspace, so ignore.
});
}
function updateSettingsForAllWorkspaces() {
_workspaceMap.forEach(workspace => {
const pythonSettingsPromise = getConfiguration(workspace, 'python');
pythonSettingsPromise.then((settings: PythonSettings) => {
updateOptionsAndRestartService(workspace, settings);
}, () => {
// An error occurred trying to read the settings
// for this workspace, so ignore.
});
fetchSettingsForWorkspace(workspace, (pythonSettings, pyrightSettings) => {
updateOptionsAndRestartService(workspace, pythonSettings, pyrightSettings);
const pyrightSettingsPromise = getConfiguration(workspace, 'pyright');
pyrightSettingsPromise.then((settings?: PyrightSettings) => {
workspace.disableLanguageServices = settings !== undefined &&
!!settings.disableLanguageServices;
}, () => {
// An error occurred trying to read the settings
// for this workspace, so ignore.
workspace.disableLanguageServices = !!pyrightSettings.disableLanguageServices;
});
});
}
function updateOptionsAndRestartService(workspace: WorkspaceServiceInstance,
settings: PythonSettings, typeStubTargetImportName?: string) {
pythonSettings: PythonSettings, pyrightSettings?: PyrightSettings,
typeStubTargetImportName?: string) {
const commandLineOptions = new CommandLineOptions(workspace.rootPath, true);
commandLineOptions.watch = true;
commandLineOptions.checkOnlyOpenFiles = pyrightSettings ?
!!pyrightSettings.openFilesOnly : true;
if (settings.venvPath) {
if (pythonSettings.venvPath) {
commandLineOptions.venvPath = combinePaths(workspace.rootPath || _rootPath,
normalizePath(_expandPathVariables(settings.venvPath)));
normalizePath(_expandPathVariables(pythonSettings.venvPath)));
}
if (settings.pythonPath) {
if (pythonSettings.pythonPath) {
// The Python VS Code extension treats the value "python" specially. This means
// the local python interpreter should be used rather than interpreting the
// setting value as a path to the interpreter. We'll simply ignore it in this case.
if (settings.pythonPath.trim() !== 'python') {
if (pythonSettings.pythonPath.trim() !== 'python') {
commandLineOptions.pythonPath = combinePaths(workspace.rootPath || _rootPath,
normalizePath(_expandPathVariables(settings.pythonPath)));
normalizePath(_expandPathVariables(pythonSettings.pythonPath)));
}
}
if (settings.analysis &&
settings.analysis.typeshedPaths &&
settings.analysis.typeshedPaths.length > 0) {
if (pythonSettings.analysis &&
pythonSettings.analysis.typeshedPaths &&
pythonSettings.analysis.typeshedPaths.length > 0) {
// Pyright supports only one typeshed path currently, whereas the
// official VS Code Python extension supports multiple typeshed paths.
// We'll use the first one specified and ignore the rest.
commandLineOptions.typeshedPath =
_expandPathVariables(settings.analysis.typeshedPaths[0]);
_expandPathVariables(pythonSettings.analysis.typeshedPaths[0]);
}
if (typeStubTargetImportName) {
@ -712,12 +718,8 @@ _connection.onExecuteCommand((cmdParams: ExecuteCommandParams) => {
disableLanguageServices: true
};
const pythonSettingsPromise = getConfiguration(workspace, 'python');
pythonSettingsPromise.then((settings: PythonSettings) => {
updateOptionsAndRestartService(workspace, settings, importName);
}, () => {
// An error occurred trying to read the settings
// for this workspace, so ignore.
fetchSettingsForWorkspace(workspace, (pythonSettings, pyrightSettings) => {
updateOptionsAndRestartService(workspace, pythonSettings, pyrightSettings, importName);
});
});