From cdcd4046b520816ea07a8de88e4777b1fd7448a6 Mon Sep 17 00:00:00 2001 From: Eric Traut Date: Sun, 14 Jan 2024 21:11:13 -0800 Subject: [PATCH] Added new language server setting `pyright.disableTaggedHints` to disable the use of diagnostics hints with tags. Some language server clients do not display these tagged hints in the intended manner and instead treat them as regular diagnostics. --- docs/settings.md | 2 ++ .../pyright-internal/src/analyzer/program.ts | 17 ++++++++++++----- .../pyright-internal/src/analyzer/service.ts | 2 ++ .../src/common/commandLineOptions.ts | 3 +++ .../src/common/configOptions.ts | 3 +++ .../pyright-internal/src/languageServerBase.ts | 2 ++ .../languageService/analyzerServiceExecutor.ts | 2 ++ packages/pyright-internal/src/server.ts | 2 ++ .../harness/fourslash/testLanguageService.ts | 2 ++ .../src/tests/harness/fourslash/testState.ts | 1 + .../pyright-internal/src/workspaceFactory.ts | 2 ++ packages/vscode-pyright/package.json | 6 ++++++ 12 files changed, 39 insertions(+), 5 deletions(-) diff --git a/docs/settings.md b/docs/settings.md index 2a0ded9115..eb7f805bf2 100644 --- a/docs/settings.md +++ b/docs/settings.md @@ -6,6 +6,8 @@ The Pyright language server honors the following settings. **pyright.disableOrganizeImports** [boolean]: Disables the “Organize Imports” command. This is useful if you are using another extension that provides similar functionality and you don’t want the two extensions to fight each other. +**pyright.disableTaggedHints** [boolean]: Disables the use of hint diagnostics with special tags to tell the client to display text ranges in a "grayed out" manner (to indicate unreachable code or unreferenced symbols) or in a "strike through" manner (to indicate use of a deprecated feature). + **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. This setting is deprecated in favor of python.analysis.diagnosticMode. It will be removed at a future time. **pyright.useLibraryCodeForTypes** [boolean]: This setting is deprecated in favor of python.analysis.useLibraryCodeForTypes. It will be removed at a future time. diff --git a/packages/pyright-internal/src/analyzer/program.ts b/packages/pyright-internal/src/analyzer/program.ts index bf3a054616..2bf4ce82ed 100644 --- a/packages/pyright-internal/src/analyzer/program.ts +++ b/packages/pyright-internal/src/analyzer/program.ts @@ -16,7 +16,7 @@ import { ConfigOptions, ExecutionEnvironment, matchFileSpecs } from '../common/c import { ConsoleInterface, StandardConsole } from '../common/console'; import * as debug from '../common/debug'; import { assert } from '../common/debug'; -import { Diagnostic } from '../common/diagnostic'; +import { Diagnostic, DiagnosticCategory } from '../common/diagnostic'; import { FileDiagnostics } from '../common/diagnosticSink'; import { FileEditAction } from '../common/editAction'; import { EditableProgram, ProgramView } from '../common/extensibility'; @@ -889,11 +889,18 @@ export class Program { this._sourceFileList.forEach((sourceFileInfo) => { if (this._shouldCheckFile(sourceFileInfo)) { - const diagnostics = sourceFileInfo.sourceFile.getDiagnostics( - options, - sourceFileInfo.diagnosticsVersion - ); + let diagnostics = sourceFileInfo.sourceFile.getDiagnostics(options, sourceFileInfo.diagnosticsVersion); if (diagnostics !== undefined) { + // Filter out all categories that are translated to tagged hints? + if (options.disableTaggedHints) { + diagnostics = diagnostics.filter( + (diag) => + diag.category !== DiagnosticCategory.UnreachableCode && + diag.category !== DiagnosticCategory.UnusedCode && + diag.category !== DiagnosticCategory.Deprecated + ); + } + fileDiagnostics.push({ fileUri: sourceFileInfo.sourceFile.getUri(), version: sourceFileInfo.sourceFile.getClientVersion(), diff --git a/packages/pyright-internal/src/analyzer/service.ts b/packages/pyright-internal/src/analyzer/service.ts index 1e02379249..d399991c2d 100644 --- a/packages/pyright-internal/src/analyzer/service.ts +++ b/packages/pyright-internal/src/analyzer/service.ts @@ -641,6 +641,8 @@ export class AnalyzerService { this._configFileUri = configFilePath || pyprojectFilePath; + configOptions.disableTaggedHints = !!commandLineOptions.disableTaggedHints; + // If we found a config file, parse it to compute the effective options. let configJsonObj: object | undefined; if (configFilePath) { diff --git a/packages/pyright-internal/src/common/commandLineOptions.ts b/packages/pyright-internal/src/common/commandLineOptions.ts index 89c5e84195..6ca23e990b 100644 --- a/packages/pyright-internal/src/common/commandLineOptions.ts +++ b/packages/pyright-internal/src/common/commandLineOptions.ts @@ -147,6 +147,9 @@ export class CommandLineOptions { // Analyze functions and methods that have no type annotations? analyzeUnannotatedFunctions?: boolean; + // Disable reporting of hint diagnostics with tags? + disableTaggedHints?: boolean; + constructor(executionRoot: string, fromVsCodeExtension: boolean) { this.executionRoot = executionRoot; this.fromVsCodeExtension = fromVsCodeExtension; diff --git a/packages/pyright-internal/src/common/configOptions.ts b/packages/pyright-internal/src/common/configOptions.ts index 25a9cfaf0f..6878ebd652 100644 --- a/packages/pyright-internal/src/common/configOptions.ts +++ b/packages/pyright-internal/src/common/configOptions.ts @@ -857,6 +857,9 @@ export class ConfigOptions { // Was this config initialized from JSON (pyrightconfig/pyproject)? initializedFromJson = false; + // Filter out any hint diagnostics with tags? + disableTaggedHints = false; + //--------------------------------------------------------------- // Diagnostics Rule Set diff --git a/packages/pyright-internal/src/languageServerBase.ts b/packages/pyright-internal/src/languageServerBase.ts index f39e5e8e78..89750620b0 100644 --- a/packages/pyright-internal/src/languageServerBase.ts +++ b/packages/pyright-internal/src/languageServerBase.ts @@ -138,6 +138,7 @@ export interface ServerSettings { typeCheckingMode?: string | undefined; useLibraryCodeForTypes?: boolean | undefined; disableLanguageServices?: boolean | undefined; + disableTaggedHints?: boolean | undefined; disableOrganizeImports?: boolean | undefined; autoSearchPaths?: boolean | undefined; extraPaths?: Uri[] | undefined; @@ -509,6 +510,7 @@ export abstract class LanguageServerBase implements LanguageServerInterface, Dis this.updateOptionsAndRestartService(workspace, serverSettings); workspace.disableLanguageServices = !!serverSettings.disableLanguageServices; + workspace.disableTaggedHints = !!serverSettings.disableTaggedHints; workspace.disableOrganizeImports = !!serverSettings.disableOrganizeImports; // Don't use workspace.isInitialized directly since it might have been diff --git a/packages/pyright-internal/src/languageService/analyzerServiceExecutor.ts b/packages/pyright-internal/src/languageService/analyzerServiceExecutor.ts index ef5b4f7383..c8fe51e80c 100644 --- a/packages/pyright-internal/src/languageService/analyzerServiceExecutor.ts +++ b/packages/pyright-internal/src/languageService/analyzerServiceExecutor.ts @@ -67,6 +67,7 @@ export class AnalyzerServiceExecutor { options.fileSystem ), disableLanguageServices: true, + disableTaggedHints: true, disableOrganizeImports: true, disableWorkspaceSymbol: true, isInitialized: createInitStatus(), @@ -103,6 +104,7 @@ function getEffectiveCommandLineOptions( commandLineOptions.typeEvaluationTimeThreshold = serverSettings.typeEvaluationTimeThreshold ?? 50; commandLineOptions.enableAmbientAnalysis = trackFiles; commandLineOptions.pythonEnvironmentName = pythonEnvironmentName; + commandLineOptions.disableTaggedHints = serverSettings.disableTaggedHints; if (!trackFiles) { commandLineOptions.watchForSourceChanges = false; diff --git a/packages/pyright-internal/src/server.ts b/packages/pyright-internal/src/server.ts index 61f16397e9..65867262e9 100644 --- a/packages/pyright-internal/src/server.ts +++ b/packages/pyright-internal/src/server.ts @@ -91,6 +91,7 @@ export class PyrightServer extends LanguageServerBase { openFilesOnly: true, useLibraryCodeForTypes: true, disableLanguageServices: false, + disableTaggedHints: false, disableOrganizeImports: false, typeCheckingMode: 'standard', diagnosticSeverityOverrides: {}, @@ -205,6 +206,7 @@ export class PyrightServer extends LanguageServerBase { } serverSettings.disableLanguageServices = !!pyrightSection.disableLanguageServices; + serverSettings.disableTaggedHints = !!pyrightSection.disableTaggedHints; serverSettings.disableOrganizeImports = !!pyrightSection.disableOrganizeImports; const typeCheckingMode = pyrightSection.typeCheckingMode; diff --git a/packages/pyright-internal/src/tests/harness/fourslash/testLanguageService.ts b/packages/pyright-internal/src/tests/harness/fourslash/testLanguageService.ts index 73cc2b5783..7e75d4f21a 100644 --- a/packages/pyright-internal/src/tests/harness/fourslash/testLanguageService.ts +++ b/packages/pyright-internal/src/tests/harness/fourslash/testLanguageService.ts @@ -97,6 +97,7 @@ export class TestLanguageService implements LanguageServerInterface { fileSystem: this.fs, }), disableLanguageServices: false, + disableTaggedHints: false, disableOrganizeImports: false, disableWorkspaceSymbol: false, isInitialized: createInitStatus(), @@ -125,6 +126,7 @@ export class TestLanguageService implements LanguageServerInterface { openFilesOnly: this._workspace.service.getConfigOptions().checkOnlyOpenFiles, useLibraryCodeForTypes: this._workspace.service.getConfigOptions().useLibraryCodeForTypes, disableLanguageServices: this._workspace.disableLanguageServices, + disableTaggedHints: this._workspace.disableTaggedHints, autoImportCompletions: this._workspace.service.getConfigOptions().autoImportCompletions, functionSignatureDisplay: this._workspace.service.getConfigOptions().functionSignatureDisplay, }; diff --git a/packages/pyright-internal/src/tests/harness/fourslash/testState.ts b/packages/pyright-internal/src/tests/harness/fourslash/testState.ts index a5eb79559b..8ed42f70f5 100644 --- a/packages/pyright-internal/src/tests/harness/fourslash/testState.ts +++ b/packages/pyright-internal/src/tests/harness/fourslash/testState.ts @@ -197,6 +197,7 @@ export class TestState { kinds: [WellKnownWorkspaceKinds.Test], service: service, disableLanguageServices: false, + disableTaggedHints: false, disableOrganizeImports: false, disableWorkspaceSymbol: false, isInitialized: createInitStatus(), diff --git a/packages/pyright-internal/src/workspaceFactory.ts b/packages/pyright-internal/src/workspaceFactory.ts index 39993a7a57..a5b3f40934 100644 --- a/packages/pyright-internal/src/workspaceFactory.ts +++ b/packages/pyright-internal/src/workspaceFactory.ts @@ -79,6 +79,7 @@ export interface Workspace { kinds: string[]; service: AnalyzerService; disableLanguageServices: boolean; + disableTaggedHints: boolean; disableOrganizeImports: boolean; disableWorkspaceSymbol: boolean; isInitialized: InitStatus; @@ -383,6 +384,7 @@ export class WorkspaceFactory { pythonPathKind, service: this._createService(name, rootUri, kinds), disableLanguageServices: false, + disableTaggedHints: false, disableOrganizeImports: false, disableWorkspaceSymbol: false, isInitialized: createInitStatus(), diff --git a/packages/vscode-pyright/package.json b/packages/vscode-pyright/package.json index c6ddf6eb53..d442b01c2a 100644 --- a/packages/vscode-pyright/package.json +++ b/packages/vscode-pyright/package.json @@ -1261,6 +1261,12 @@ "description": "Disables type completion, definitions, and references.", "scope": "resource" }, + "pyright.disableTaggedHints": { + "type": "boolean", + "default": false, + "description": "Disable hint diagnostics with special hints for grayed-out or strike-through text.", + "scope": "resource" + }, "pyright.disableOrganizeImports": { "type": "boolean", "default": false,