From 4d205e0aeeadc5acef954b03486a9cdb1743b8d7 Mon Sep 17 00:00:00 2001 From: Dustin Campbell Date: Wed, 20 Jul 2016 09:50:20 -0700 Subject: [PATCH] Fix several issues with diagnostics 1. The diagnostics provider won't refresh diagnostics while the OmniSharp server is restoring packages. Instead, it waits until it receives an event from OmniSharp afterward. However, that event was only expecting the old DNX protocol, so the diagnostics provider never automatically updated after packages were restored. This change gets rid of the DNX protocol and changes the diagnostic provider to look for .NET Core projects. 2. Hidden diagnostics should have DiagnosticSeverity.Info rather DiagnosticSeverity.Warning. 3. When the processing *all* of the diagnostics (not just those for the current file), the previous diagnostics were not cleared out first. This resulted in new diagnostics being merged with old diagnostics, creating duplicates diagnostics. Now we clear the diagnostics for a file before adding new ones. --- src/features/diagnosticsProvider.ts | 31 +++++++++++++++++++++++++---- src/features/status.ts | 7 ++----- src/omnisharp/protocol.ts | 26 +----------------------- 3 files changed, 30 insertions(+), 34 deletions(-) diff --git a/src/features/diagnosticsProvider.ts b/src/features/diagnosticsProvider.ts index 6a664e39a2..a0f59589c4 100644 --- a/src/features/diagnosticsProvider.ts +++ b/src/features/diagnosticsProvider.ts @@ -43,8 +43,8 @@ export class Advisor { } private _onProjectChange(info: protocol.ProjectInformationResponse): void { - if (info.DnxProject && info.DnxProject.SourceFiles) { - this._projectSourceFileCounts[info.DnxProject.Path] = info.DnxProject.SourceFiles.length; + if (info.DotNetProject && info.DotNetProject.SourceFiles) { + this._projectSourceFileCounts[info.DotNetProject.Path] = info.DotNetProject.SourceFiles.length; } if (info.MsBuildProject && info.MsBuildProject.SourceFiles) { this._projectSourceFileCounts[info.MsBuildProject.Path] = info.MsBuildProject.SourceFiles.length; @@ -94,7 +94,7 @@ class DiagnosticsProvider extends AbstractSupport { constructor(server: OmnisharpServer, validationAdvisor: Advisor) { super(server); this._validationAdvisor = validationAdvisor; - this._diagnostics = languages.createDiagnosticCollection('omnisharp'); + this._diagnostics = languages.createDiagnosticCollection('csharp'); let d1 = this._server.onPackageRestore(this._validateProject, this); let d2 = this._server.onProjectChange(this._validateProject, this); @@ -108,9 +108,11 @@ class DiagnosticsProvider extends AbstractSupport { if (this._projectValidation) { this._projectValidation.dispose(); } + for (let key in this._documentValidations) { this._documentValidations[key].dispose(); } + this._disposable.dispose(); } @@ -153,9 +155,18 @@ class DiagnosticsProvider extends AbstractSupport { let source = new CancellationTokenSource(); let handle = setTimeout(() => { serverUtils.codeCheck(this._server, { Filename: document.fileName }, source.token).then(value => { + // Easy case: If there are no diagnostics in the file, we can clear it quickly. + if (value.QuickFixes.length === 0) { + if (this._diagnostics.has(document.uri)) { + this._diagnostics.delete(document.uri); + } + return; + } + // (re)set new diagnostics for this document let diagnostics = value.QuickFixes.map(DiagnosticsProvider._asDiagnostic); + this._diagnostics.set(document.uri, diagnostics); }); }, 750); @@ -190,11 +201,22 @@ class DiagnosticsProvider extends AbstractSupport { if (lastEntry && lastEntry[0].toString() === uri.toString()) { lastEntry[1].push(diag); } else { + // We're replacing all diagnostics in this file. Pushing an entry with undefined for + // the diagnostics first ensures that the previous diagnostics for this file are + // cleared. Otherwise, new entries will be merged with the old ones. + entries.push([uri, undefined]); lastEntry = [uri, [diag]]; entries.push(lastEntry); } } + // Clear diagnostics for files that no longer have any diagnostics. + this._diagnostics.forEach((uri, diagnostics) => { + if (!entries.find(tuple => tuple[0] === uri)) { + this._diagnostics.delete(uri); + } + }); + // replace all entries this._diagnostics.set(entries); }); @@ -216,10 +238,11 @@ class DiagnosticsProvider extends AbstractSupport { private static _asDiagnosticSeverity(logLevel: string): DiagnosticSeverity { switch (logLevel.toLowerCase()) { - case 'hidden': case 'warning': case 'warn': return DiagnosticSeverity.Warning; + case 'hidden': + return DiagnosticSeverity.Information; default: return DiagnosticSeverity.Error; } diff --git a/src/features/status.ts b/src/features/status.ts index 0a48c0e0eb..22b3615f11 100644 --- a/src/features/status.ts +++ b/src/features/status.ts @@ -165,11 +165,8 @@ export function reportDocumentStatus(server: OmnisharpServer): vscode.Disposable } } - // show dnx projects if applicable - if ('Dnx' in info) { - addDnxOrDotNetProjects(info.Dnx.Projects); - } - else if ('DotNet' in info) { + // show .NET Core projects if applicable + if ('DotNet' in info) { addDnxOrDotNetProjects(info.DotNet.Projects); } diff --git a/src/omnisharp/protocol.ts b/src/omnisharp/protocol.ts index 76bb72bd18..0562798194 100644 --- a/src/omnisharp/protocol.ts +++ b/src/omnisharp/protocol.ts @@ -212,12 +212,11 @@ export interface AutoCompleteResponse { export interface ProjectInformationResponse { MsBuildProject: MSBuildProject; - DnxProject: DnxProject; + DotNetProject: DotNetProject; } export interface WorkspaceInformationResponse { MsBuild: MsBuildWorkspaceInformation; - Dnx: DnxWorkspaceInformation; DotNet: DotNetWorkspaceInformation; ScriptCs: ScriptCsContext; } @@ -244,29 +243,6 @@ export interface MSBuildProject { SourceFiles: string[]; } -export interface DnxWorkspaceInformation { - RuntimePath: string; - DesignTimeHostPort: number; - Projects: DnxProject[]; -} - -export interface DnxProject { - Path: string; - Name: string; - Commands: { [name: string]: string; }; - Configurations: string[]; - ProjectSearchPaths: string[]; - Frameworks: DnxFramework[]; - GlobalJsonPath: string; - SourceFiles: string[]; -} - -export interface DnxFramework { - Name: string; - FriendlyName: string; - ShortName: string; -} - export interface DotNetWorkspaceInformation { Projects: DotNetProject[]; RuntimePath: string;