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.
This commit is contained in:
Dustin Campbell 2016-07-20 09:50:20 -07:00
Родитель ff2d0b4c11
Коммит 4d205e0aee
3 изменённых файлов: 30 добавлений и 34 удалений

Просмотреть файл

@ -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;
}

Просмотреть файл

@ -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);
}

Просмотреть файл

@ -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;