From d9ede2eca4f46c80b94fe744f25b9b1efa1cab91 Mon Sep 17 00:00:00 2001 From: Savpek Date: Sat, 25 May 2019 11:50:03 +0300 Subject: [PATCH 01/57] Initial harsh version of analyze commands that can re-analyze full solution. --- package-lock.json | 2 +- package.json | 32 ++++++++++++------- src/features/commands.ts | 13 ++++++++ src/features/diagnosticsProvider.ts | 18 ++++++----- src/omnisharp/protocol.ts | 1 + src/omnisharp/server.ts | 8 ++++- src/omnisharp/utils.ts | 4 +++ .../slnWithCsproj/.vscode/settings.json | 4 ++- 8 files changed, 60 insertions(+), 22 deletions(-) diff --git a/package-lock.json b/package-lock.json index b7f2b5817..35559a697 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "csharp", - "version": "1.19.1-beta1", + "version": "1.20.0-beta1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 2d0a61290..2c3c23fb0 100644 --- a/package.json +++ b/package.json @@ -481,12 +481,12 @@ "items": { "type": "string" }, - "description": "Array of symbol server URLs (example: http\u200b://MyExampleSymbolServer) or directories (example: /build/symbols) to search for .pdb files. These directories will be searched in addition to the default locations -- next to the module and the path where the pdb was originally dropped to.", + "description": "Array of symbol server URLs (example: http​://MyExampleSymbolServer) or directories (example: /build/symbols) to search for .pdb files. These directories will be searched in addition to the default locations -- next to the module and the path where the pdb was originally dropped to.", "default": [] }, "searchMicrosoftSymbolServer": { "type": "boolean", - "description": "If 'true' the Microsoft Symbol server (https\u200b://msdl.microsoft.com\u200b/download/symbols) is added to the symbols search path. If unspecified, this option defaults to 'false'.", + "description": "If 'true' the Microsoft Symbol server (https​://msdl.microsoft.com​/download/symbols) is added to the symbols search path. If unspecified, this option defaults to 'false'.", "default": false }, "cachePath": { @@ -778,6 +778,16 @@ "title": "Select Project", "category": "OmniSharp" }, + { + "command": "o.reanalyze.allProjects", + "title": "Analyze all projects", + "category": "OmniSharp" + }, + { + "command": "o.reanalyze.currentProject", + "title": "Analyze current project", + "category": "OmniSharp" + }, { "command": "dotnet.generateAssets", "title": "Generate Assets for Build and Debug", @@ -1330,12 +1340,12 @@ "items": { "type": "string" }, - "description": "Array of symbol server URLs (example: http\u200b://MyExampleSymbolServer) or directories (example: /build/symbols) to search for .pdb files. These directories will be searched in addition to the default locations -- next to the module and the path where the pdb was originally dropped to.", + "description": "Array of symbol server URLs (example: http​://MyExampleSymbolServer) or directories (example: /build/symbols) to search for .pdb files. These directories will be searched in addition to the default locations -- next to the module and the path where the pdb was originally dropped to.", "default": [] }, "searchMicrosoftSymbolServer": { "type": "boolean", - "description": "If 'true' the Microsoft Symbol server (https\u200b://msdl.microsoft.com\u200b/download/symbols) is added to the symbols search path. If unspecified, this option defaults to 'false'.", + "description": "If 'true' the Microsoft Symbol server (https​://msdl.microsoft.com​/download/symbols) is added to the symbols search path. If unspecified, this option defaults to 'false'.", "default": false }, "cachePath": { @@ -1731,12 +1741,12 @@ "items": { "type": "string" }, - "description": "Array of symbol server URLs (example: http\u200b://MyExampleSymbolServer) or directories (example: /build/symbols) to search for .pdb files. These directories will be searched in addition to the default locations -- next to the module and the path where the pdb was originally dropped to.", + "description": "Array of symbol server URLs (example: http​://MyExampleSymbolServer) or directories (example: /build/symbols) to search for .pdb files. These directories will be searched in addition to the default locations -- next to the module and the path where the pdb was originally dropped to.", "default": [] }, "searchMicrosoftSymbolServer": { "type": "boolean", - "description": "If 'true' the Microsoft Symbol server (https\u200b://msdl.microsoft.com\u200b/download/symbols) is added to the symbols search path. If unspecified, this option defaults to 'false'.", + "description": "If 'true' the Microsoft Symbol server (https​://msdl.microsoft.com​/download/symbols) is added to the symbols search path. If unspecified, this option defaults to 'false'.", "default": false }, "cachePath": { @@ -2378,12 +2388,12 @@ "items": { "type": "string" }, - "description": "Array of symbol server URLs (example: http\u200b://MyExampleSymbolServer) or directories (example: /build/symbols) to search for .pdb files. These directories will be searched in addition to the default locations -- next to the module and the path where the pdb was originally dropped to.", + "description": "Array of symbol server URLs (example: http​://MyExampleSymbolServer) or directories (example: /build/symbols) to search for .pdb files. These directories will be searched in addition to the default locations -- next to the module and the path where the pdb was originally dropped to.", "default": [] }, "searchMicrosoftSymbolServer": { "type": "boolean", - "description": "If 'true' the Microsoft Symbol server (https\u200b://msdl.microsoft.com\u200b/download/symbols) is added to the symbols search path. If unspecified, this option defaults to 'false'.", + "description": "If 'true' the Microsoft Symbol server (https​://msdl.microsoft.com​/download/symbols) is added to the symbols search path. If unspecified, this option defaults to 'false'.", "default": false }, "cachePath": { @@ -2779,12 +2789,12 @@ "items": { "type": "string" }, - "description": "Array of symbol server URLs (example: http\u200b://MyExampleSymbolServer) or directories (example: /build/symbols) to search for .pdb files. These directories will be searched in addition to the default locations -- next to the module and the path where the pdb was originally dropped to.", + "description": "Array of symbol server URLs (example: http​://MyExampleSymbolServer) or directories (example: /build/symbols) to search for .pdb files. These directories will be searched in addition to the default locations -- next to the module and the path where the pdb was originally dropped to.", "default": [] }, "searchMicrosoftSymbolServer": { "type": "boolean", - "description": "If 'true' the Microsoft Symbol server (https\u200b://msdl.microsoft.com\u200b/download/symbols) is added to the symbols search path. If unspecified, this option defaults to 'false'.", + "description": "If 'true' the Microsoft Symbol server (https​://msdl.microsoft.com​/download/symbols) is added to the symbols search path. If unspecified, this option defaults to 'false'.", "default": false }, "cachePath": { @@ -2914,4 +2924,4 @@ ] } } -} \ No newline at end of file +} diff --git a/src/features/commands.ts b/src/features/commands.ts index 2d8802e93..13f05a667 100644 --- a/src/features/commands.ts +++ b/src/features/commands.ts @@ -32,6 +32,9 @@ export default function registerCommands(server: OmniSharpServer, platformInfo: disposable.add(vscode.commands.registerCommand('dotnet.restore.project', async () => pickProjectAndDotnetRestore(server, eventStream))); disposable.add(vscode.commands.registerCommand('dotnet.restore.all', async () => dotnetRestoreAllProjects(server, eventStream))); + disposable.add(vscode.commands.registerCommand('o.reanalyze.allProjects', async () => reAnalyzeAllProjects(server, eventStream))); + disposable.add(vscode.commands.registerCommand('o.reanalyze.currentProject', async () => reAnalyzeCurrentProject(server, eventStream))); + // register empty handler for csharp.installDebugger // running the command activates the extension, which is all we need for installation to kickoff disposable.add(vscode.commands.registerCommand('csharp.downloadDebugger', () => { })); @@ -132,6 +135,16 @@ async function pickProjectAndDotnetRestore(server: OmniSharpServer, eventStream: } } +async function reAnalyzeAllProjects(server: OmniSharpServer, eventStream: EventStream): Promise { + await serverUtils.reAnalyze(server, {}); +} + +async function reAnalyzeCurrentProject(server: OmniSharpServer, eventStream: EventStream): Promise { + await serverUtils.reAnalyze(server, { + currentOpenFilePathAsContext: vscode.window.activeTextEditor.document.uri.fsPath + }); +} + async function dotnetRestoreAllProjects(server: OmniSharpServer, eventStream: EventStream): Promise { let descriptors = await getProjectDescriptors(server); eventStream.post(new CommandDotNetRestoreStart()); diff --git a/src/features/diagnosticsProvider.ts b/src/features/diagnosticsProvider.ts index 54d4b5c63..b7c8602de 100644 --- a/src/features/diagnosticsProvider.ts +++ b/src/features/diagnosticsProvider.ts @@ -134,14 +134,16 @@ class DiagnosticsProvider extends AbstractSupport { this._validationAdvisor = validationAdvisor; this._diagnostics = vscode.languages.createDiagnosticCollection('csharp'); - let d1 = this._server.onPackageRestore(this._validateProject, this); - let d2 = this._server.onProjectChange(this._validateProject, this); - let d4 = vscode.workspace.onDidOpenTextDocument(event => this._onDocumentAddOrChange(event), this); - let d3 = vscode.workspace.onDidChangeTextDocument(event => this._onDocumentAddOrChange(event.document), this); - let d5 = vscode.workspace.onDidCloseTextDocument(this._onDocumentRemove, this); - let d6 = vscode.window.onDidChangeActiveTextEditor(event => this._onDidChangeActiveTextEditor(event), this); - let d7 = vscode.window.onDidChangeWindowState(event => this._OnDidChangeWindowState(event), this); - this._disposable = new CompositeDisposable(this._diagnostics, d1, d2, d3, d4, d5, d6, d7); + this._disposable = new CompositeDisposable(this._diagnostics, + this._server.onPackageRestore(this._validateProject, this), + this._server.onProjectChange(this._validateProject, this), + this._server.onProjectAnalyzed(this._validateProject, this), + vscode.workspace.onDidOpenTextDocument(event => this._onDocumentAddOrChange(event), this), + vscode.workspace.onDidChangeTextDocument(event => this._onDocumentAddOrChange(event.document), this), + vscode.workspace.onDidCloseTextDocument(this._onDocumentRemove, this), + vscode.window.onDidChangeActiveTextEditor(event => this._onDidChangeActiveTextEditor(event), this), + vscode.window.onDidChangeWindowState(event => this._OnDidChangeWindowState(event), this), + ); // Go ahead and check for diagnostics in the currently visible editors. for (let editor of vscode.window.visibleTextEditors) { diff --git a/src/omnisharp/protocol.ts b/src/omnisharp/protocol.ts index 4e968a3e3..81f08ee32 100644 --- a/src/omnisharp/protocol.ts +++ b/src/omnisharp/protocol.ts @@ -28,6 +28,7 @@ export module Requests { export const TypeLookup = '/typelookup'; export const UpdateBuffer = '/updatebuffer'; export const Metadata = '/metadata'; + export const ReAnalyze = '/reanalyze'; } export namespace WireProtocol { diff --git a/src/omnisharp/server.ts b/src/omnisharp/server.ts index 042f6287a..af16a2268 100644 --- a/src/omnisharp/server.ts +++ b/src/omnisharp/server.ts @@ -56,6 +56,8 @@ module Events { export const ProjectAdded = 'ProjectAdded'; export const ProjectRemoved = 'ProjectRemoved'; + export const ProjectAnalyzed = 'ProjectAnalyzed'; + export const MsBuildProjectDiagnostics = 'MsBuildProjectDiagnostics'; export const TestMessage = 'TestMessage'; @@ -194,6 +196,10 @@ export class OmniSharpServer { return this._addListener(Events.ProjectRemoved, listener, thisArg); } + public onProjectAnalyzed(listener: () => any, thisArg?: any) { + return this._addListener(Events.ProjectAnalyzed, listener, thisArg); + } + public onMsBuildProjectDiagnostics(listener: (e: protocol.MSBuildProjectDiagnostics) => any, thisArg?: any) { return this._addListener(Events.MsBuildProjectDiagnostics, listener, thisArg); } @@ -370,7 +376,7 @@ export class OmniSharpServer { return this.stop(); } } - + private onProjectConfigurationReceived(listener: (e: protocol.ProjectConfigurationMessage) => void){ return this._addListener(Events.ProjectConfiguration, listener); } diff --git a/src/omnisharp/utils.ts b/src/omnisharp/utils.ts index a488083dd..541fa580e 100644 --- a/src/omnisharp/utils.ts +++ b/src/omnisharp/utils.ts @@ -87,6 +87,10 @@ export async function getMetadata(server: OmniSharpServer, request: protocol.Met return server.makeRequest(protocol.Requests.Metadata, request); } +export async function reAnalyze(server: OmniSharpServer, request: any) { + return server.makeRequest(protocol.Requests.ReAnalyze, request); +} + export async function getTestStartInfo(server: OmniSharpServer, request: protocol.V2.GetTestStartInfoRequest) { return server.makeRequest(protocol.V2.Requests.GetTestStartInfo, request); } diff --git a/test/integrationTests/testAssets/slnWithCsproj/.vscode/settings.json b/test/integrationTests/testAssets/slnWithCsproj/.vscode/settings.json index c80abf42f..300576c07 100644 --- a/test/integrationTests/testAssets/slnWithCsproj/.vscode/settings.json +++ b/test/integrationTests/testAssets/slnWithCsproj/.vscode/settings.json @@ -1,5 +1,7 @@ { "omnisharp.defaultLaunchSolution": "b_SecondInOrder_SlnFile.sln", - "omnisharp.path": "latest", + "omnisharp.path": "C:\\Github\\omnisharp-roslyn\\bin\\Debug\\OmniSharp.Stdio.Driver\\net472\\Omnisharp.exe", "csharp.maxProjectFileCountForDiagnosticAnalysis": 1000, + "csharp.referencesCodeLens.enabled": false, + "csharp.testsCodeLens.enabled": false, } \ No newline at end of file From 14baae36c4564d022643cbccca1ec99a9de4e301 Mon Sep 17 00:00:00 2001 From: Savpek Date: Sun, 26 May 2019 08:59:14 +0300 Subject: [PATCH 02/57] Reverted invalid changes from settings.json. --- .../testAssets/slnWithCsproj/.vscode/settings.json | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/test/integrationTests/testAssets/slnWithCsproj/.vscode/settings.json b/test/integrationTests/testAssets/slnWithCsproj/.vscode/settings.json index 300576c07..c80abf42f 100644 --- a/test/integrationTests/testAssets/slnWithCsproj/.vscode/settings.json +++ b/test/integrationTests/testAssets/slnWithCsproj/.vscode/settings.json @@ -1,7 +1,5 @@ { "omnisharp.defaultLaunchSolution": "b_SecondInOrder_SlnFile.sln", - "omnisharp.path": "C:\\Github\\omnisharp-roslyn\\bin\\Debug\\OmniSharp.Stdio.Driver\\net472\\Omnisharp.exe", + "omnisharp.path": "latest", "csharp.maxProjectFileCountForDiagnosticAnalysis": 1000, - "csharp.referencesCodeLens.enabled": false, - "csharp.testsCodeLens.enabled": false, } \ No newline at end of file From 170d18f2a67072677f10e08b19c73675ef059b21 Mon Sep 17 00:00:00 2001 From: Savpek Date: Sun, 26 May 2019 16:35:25 +0300 Subject: [PATCH 03/57] Updated to match new events. --- src/features/diagnosticsProvider.ts | 2 +- src/omnisharp/protocol.ts | 6 ++++++ src/omnisharp/server.ts | 6 +++--- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/features/diagnosticsProvider.ts b/src/features/diagnosticsProvider.ts index b7c8602de..8435b57a6 100644 --- a/src/features/diagnosticsProvider.ts +++ b/src/features/diagnosticsProvider.ts @@ -137,7 +137,7 @@ class DiagnosticsProvider extends AbstractSupport { this._disposable = new CompositeDisposable(this._diagnostics, this._server.onPackageRestore(this._validateProject, this), this._server.onProjectChange(this._validateProject, this), - this._server.onProjectAnalyzed(this._validateProject, this), + this._server.onProjectDiagnosticStatus(e => e.ProjectDiagnosticStatus === 1 ? this._validateProject() : undefined, this), vscode.workspace.onDidOpenTextDocument(event => this._onDocumentAddOrChange(event), this), vscode.workspace.onDidChangeTextDocument(event => this._onDocumentAddOrChange(event.document), this), vscode.workspace.onDidCloseTextDocument(this._onDocumentRemove, this), diff --git a/src/omnisharp/protocol.ts b/src/omnisharp/protocol.ts index 81f08ee32..51d4c0e4b 100644 --- a/src/omnisharp/protocol.ts +++ b/src/omnisharp/protocol.ts @@ -285,6 +285,12 @@ export interface ProjectInformationResponse { DotNetProject: DotNetProject; } +export interface ProjectDiagnosticStatus { + ProjectDiagnosticStatus: 0 | 1; + ProjectFilePath: string; + Type: "background"; +} + export interface WorkspaceInformationResponse { MsBuild?: MsBuildWorkspaceInformation; DotNet?: DotNetWorkspaceInformation; diff --git a/src/omnisharp/server.ts b/src/omnisharp/server.ts index af16a2268..28c6f5ae8 100644 --- a/src/omnisharp/server.ts +++ b/src/omnisharp/server.ts @@ -56,7 +56,7 @@ module Events { export const ProjectAdded = 'ProjectAdded'; export const ProjectRemoved = 'ProjectRemoved'; - export const ProjectAnalyzed = 'ProjectAnalyzed'; + export const ProjectDiagnosticStatus = 'ProjectDiagnosticStatus'; export const MsBuildProjectDiagnostics = 'MsBuildProjectDiagnostics'; @@ -196,8 +196,8 @@ export class OmniSharpServer { return this._addListener(Events.ProjectRemoved, listener, thisArg); } - public onProjectAnalyzed(listener: () => any, thisArg?: any) { - return this._addListener(Events.ProjectAnalyzed, listener, thisArg); + public onProjectDiagnosticStatus(listener: (e: protocol.ProjectDiagnosticStatus) => any, thisArg?: any) { + return this._addListener(Events.ProjectDiagnosticStatus, listener, thisArg); } public onMsBuildProjectDiagnostics(listener: (e: protocol.MSBuildProjectDiagnostics) => any, thisArg?: any) { From d6163a8d1b5ba2fa3a2de232945f094c33c6b6cf Mon Sep 17 00:00:00 2001 From: Savpek Date: Sun, 26 May 2019 17:50:48 +0300 Subject: [PATCH 04/57] Fixes to work with newer eventing. --- src/features/diagnosticsProvider.ts | 16 ++++++++++++---- src/omnisharp/protocol.ts | 2 +- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/features/diagnosticsProvider.ts b/src/features/diagnosticsProvider.ts index 8435b57a6..8b78ebe7a 100644 --- a/src/features/diagnosticsProvider.ts +++ b/src/features/diagnosticsProvider.ts @@ -137,7 +137,7 @@ class DiagnosticsProvider extends AbstractSupport { this._disposable = new CompositeDisposable(this._diagnostics, this._server.onPackageRestore(this._validateProject, this), this._server.onProjectChange(this._validateProject, this), - this._server.onProjectDiagnosticStatus(e => e.ProjectDiagnosticStatus === 1 ? this._validateProject() : undefined, this), + this._server.onProjectDiagnosticStatus(this.onProjectAnalysis, this), vscode.workspace.onDidOpenTextDocument(event => this._onDocumentAddOrChange(event), this), vscode.workspace.onDidChangeTextDocument(event => this._onDocumentAddOrChange(event.document), this), vscode.workspace.onDidCloseTextDocument(this._onDocumentRemove, this), @@ -203,6 +203,14 @@ class DiagnosticsProvider extends AbstractSupport { this._validateProject(); } + private onProjectAnalysis(event: protocol.ProjectDiagnosticStatus) + { + if(event.Status == 1) + { + this._validateProject(); + } + } + private _onDocumentRemove(document: vscode.TextDocument): void { let key = document.uri; let didChange = false; @@ -263,9 +271,9 @@ class DiagnosticsProvider extends AbstractSupport { private _validateProject(): void { // If we've already started computing for this project, cancel that work. - if (this._projectValidation) { - this._projectValidation.cancel(); - } + // if (this._projectValidation) { + // this._projectValidation.cancel(); + // } if (!this._validationAdvisor.shouldValidateProject()) { return; diff --git a/src/omnisharp/protocol.ts b/src/omnisharp/protocol.ts index 51d4c0e4b..a16192f15 100644 --- a/src/omnisharp/protocol.ts +++ b/src/omnisharp/protocol.ts @@ -286,7 +286,7 @@ export interface ProjectInformationResponse { } export interface ProjectDiagnosticStatus { - ProjectDiagnosticStatus: 0 | 1; + Status: 0 | 1; ProjectFilePath: string; Type: "background"; } From bf70916fa2c3a768922141d5377a28e84fb29cd0 Mon Sep 17 00:00:00 2001 From: Savpek Date: Tue, 28 May 2019 07:11:48 +0300 Subject: [PATCH 05/57] Temporary ignore of validate project. --- src/features/diagnosticsProvider.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/features/diagnosticsProvider.ts b/src/features/diagnosticsProvider.ts index 8b78ebe7a..9855d82bc 100644 --- a/src/features/diagnosticsProvider.ts +++ b/src/features/diagnosticsProvider.ts @@ -200,7 +200,7 @@ class DiagnosticsProvider extends AbstractSupport { } this._validateDocument(document); - this._validateProject(); + //this._validateProject(); } private onProjectAnalysis(event: protocol.ProjectDiagnosticStatus) From f31c723cace1262e2b10df59e58f5c1a13994b3b Mon Sep 17 00:00:00 2001 From: Savpek Date: Fri, 31 May 2019 08:30:24 +0300 Subject: [PATCH 06/57] Added dummy statusbar for analyze progress. --- src/main.ts | 9 +++++++-- src/observers/BackgroundWorkObserver.ts | 19 +++++++++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) create mode 100644 src/observers/BackgroundWorkObserver.ts diff --git a/src/main.ts b/src/main.ts index 77e96992a..c9e593b80 100644 --- a/src/main.ts +++ b/src/main.ts @@ -43,6 +43,7 @@ import { downloadAndInstallPackages } from './packageManager/downloadAndInstallP import IInstallDependencies from './packageManager/IInstallDependencies'; import { installRuntimeDependencies } from './InstallRuntimeDependencies'; import { isValidDownload } from './packageManager/isValidDownload'; +import { BackgroundWorkObserver } from './observers/BackgroundWorkObserver'; export async function activate(context: vscode.ExtensionContext): Promise { @@ -91,14 +92,18 @@ export async function activate(context: vscode.ExtensionContext): Promise { + this.SetAndShowStatusBar('$(sync~spin) Analyzing project.foo.csproj', 'o.showOutput', null, 'Analyzing project.foo.csproj...'); + } +} + From 97e16d0f4f92bf80f70fac1d6143d19039d921cd Mon Sep 17 00:00:00 2001 From: Savpek Date: Fri, 31 May 2019 09:12:26 +0300 Subject: [PATCH 07/57] Status bar works as expected. --- src/features/diagnosticsProvider.ts | 4 ++-- src/observers/BackgroundWorkObserver.ts | 26 +++++++++++++++++-------- src/omnisharp/EventType.ts | 1 + src/omnisharp/loggingEvents.ts | 5 +++++ src/omnisharp/protocol.ts | 8 +++++++- src/omnisharp/server.ts | 4 ++++ 6 files changed, 37 insertions(+), 11 deletions(-) diff --git a/src/features/diagnosticsProvider.ts b/src/features/diagnosticsProvider.ts index 9855d82bc..40b96241e 100644 --- a/src/features/diagnosticsProvider.ts +++ b/src/features/diagnosticsProvider.ts @@ -137,7 +137,7 @@ class DiagnosticsProvider extends AbstractSupport { this._disposable = new CompositeDisposable(this._diagnostics, this._server.onPackageRestore(this._validateProject, this), this._server.onProjectChange(this._validateProject, this), - this._server.onProjectDiagnosticStatus(this.onProjectAnalysis, this), + this._server.onProjectDiagnosticStatus(this._onProjectAnalysis, this), vscode.workspace.onDidOpenTextDocument(event => this._onDocumentAddOrChange(event), this), vscode.workspace.onDidChangeTextDocument(event => this._onDocumentAddOrChange(event.document), this), vscode.workspace.onDidCloseTextDocument(this._onDocumentRemove, this), @@ -203,7 +203,7 @@ class DiagnosticsProvider extends AbstractSupport { //this._validateProject(); } - private onProjectAnalysis(event: protocol.ProjectDiagnosticStatus) + private _onProjectAnalysis(event: protocol.ProjectDiagnosticStatus) { if(event.Status == 1) { diff --git a/src/observers/BackgroundWorkObserver.ts b/src/observers/BackgroundWorkObserver.ts index d12f16572..650f713b3 100644 --- a/src/observers/BackgroundWorkObserver.ts +++ b/src/observers/BackgroundWorkObserver.ts @@ -4,16 +4,26 @@ *--------------------------------------------------------------------------------------------*/ import { BaseStatusBarItemObserver } from './BaseStatusBarItemObserver'; - -export enum StatusBarColors{ - Red = 'rgb(218,0,0)', - Green = 'rgb(0,218,0)', - Yellow = 'rgb(218,218,0)' -} +import { BaseEvent, OmnisharpProjectDiagnosticStatus } from '../omnisharp/loggingEvents'; +import { EventType } from '../omnisharp/EventType'; +import { DiagnosticStatus } from '../omnisharp/protocol'; export class BackgroundWorkObserver extends BaseStatusBarItemObserver { - public post = () => { - this.SetAndShowStatusBar('$(sync~spin) Analyzing project.foo.csproj', 'o.showOutput', null, 'Analyzing project.foo.csproj...'); + public post = (event: BaseEvent) => { + if(event.type == EventType.ProjectDiagnosticStatus) + { + let asProjectEvent = event; + + if(asProjectEvent.message.Status === DiagnosticStatus.Processing) + { + let projectFile = asProjectEvent.message.ProjectFilePath.replace(/^.*[\\\/]/, ''); + this.SetAndShowStatusBar(`$(sync~spin) Analyzing ${projectFile}`, 'o.showOutput', null, `Analyzing ${projectFile}`); + } + else + { + this.ResetAndHideStatusBar(); + } + } } } diff --git a/src/omnisharp/EventType.ts b/src/omnisharp/EventType.ts index 1c114fc69..db1a32965 100644 --- a/src/omnisharp/EventType.ts +++ b/src/omnisharp/EventType.ts @@ -79,6 +79,7 @@ export enum EventType { OmnisharpServerOnStart = 72, OmnisharpOnBeforeServerInstall = 73, ProjectConfigurationReceived = 74, + ProjectDiagnosticStatus = 75 } //Note that the EventType protocol is shared with Razor.VSCode and the numbers here should not be altered diff --git a/src/omnisharp/loggingEvents.ts b/src/omnisharp/loggingEvents.ts index a4f7d6ed5..63f63dde9 100644 --- a/src/omnisharp/loggingEvents.ts +++ b/src/omnisharp/loggingEvents.ts @@ -92,6 +92,11 @@ export class OmnisharpServerOnError implements BaseEvent { constructor(public errorMessage: protocol.ErrorMessage) { } } +export class OmnisharpProjectDiagnosticStatus implements BaseEvent { + type=EventType.ProjectDiagnosticStatus; + constructor(public message: protocol.ProjectDiagnosticStatus) { } +} + export class OmnisharpServerMsBuildProjectDiagnostics implements BaseEvent { type=EventType.OmnisharpServerMsBuildProjectDiagnostics; constructor(public diagnostics: protocol.MSBuildProjectDiagnostics) { } diff --git a/src/omnisharp/protocol.ts b/src/omnisharp/protocol.ts index a16192f15..bdaefc5bb 100644 --- a/src/omnisharp/protocol.ts +++ b/src/omnisharp/protocol.ts @@ -285,8 +285,14 @@ export interface ProjectInformationResponse { DotNetProject: DotNetProject; } +export enum DiagnosticStatus +{ + Processing = 0, + Ready = 1 +} + export interface ProjectDiagnosticStatus { - Status: 0 | 1; + Status: DiagnosticStatus; ProjectFilePath: string; Type: "background"; } diff --git a/src/omnisharp/server.ts b/src/omnisharp/server.ts index 28c6f5ae8..f5d8f08dd 100644 --- a/src/omnisharp/server.ts +++ b/src/omnisharp/server.ts @@ -288,6 +288,10 @@ export class OmniSharpServer { this.eventStream.post(new ObservableEvents.OmnisharpServerOnStart()); })); + disposables.add(this.onProjectDiagnosticStatus((message: protocol.ProjectDiagnosticStatus) => + this.eventStream.post(new ObservableEvents.OmnisharpProjectDiagnosticStatus(message)) + )); + disposables.add(this.onProjectConfigurationReceived((message: protocol.ProjectConfigurationMessage) => { this.eventStream.post(new ObservableEvents.ProjectConfiguration(message)); })); From 08ae6bea38c76a5a2cf725b48171800922ce5337 Mon Sep 17 00:00:00 2001 From: Savpek Date: Fri, 31 May 2019 11:58:33 +0300 Subject: [PATCH 08/57] Implemented diagnostic provider in to of rxjs. --- src/features/diagnosticsProvider.ts | 83 ++++++++++--------- .../advisor.integration.test.ts | 6 +- 2 files changed, 45 insertions(+), 44 deletions(-) diff --git a/src/features/diagnosticsProvider.ts b/src/features/diagnosticsProvider.ts index 40b96241e..a1185ad3b 100644 --- a/src/features/diagnosticsProvider.ts +++ b/src/features/diagnosticsProvider.ts @@ -14,6 +14,9 @@ import { IDisposable } from '../Disposable'; import { isVirtualCSharpDocument } from './virtualDocumentTracker'; import { TextDocument } from '../vscodeAdapter'; import OptionProvider from '../observers/OptionProvider'; +import { Subject } from 'rxjs'; +import { throttleTime } from 'rxjs/operators'; +import { DiagnosticStatus } from '../omnisharp/protocol'; export class Advisor { @@ -42,7 +45,7 @@ export class Advisor { && !this._isRestoringPackages(); } - public shouldValidateProject(): boolean { + public shouldValidateAll(): boolean { return this._isServerStarted() && !this._isRestoringPackages() && !this._isOverFileLimit(); @@ -127,16 +130,20 @@ class DiagnosticsProvider extends AbstractSupport { private _documentValidations: { [uri: string]: vscode.CancellationTokenSource } = Object.create(null); private _projectValidation: vscode.CancellationTokenSource; private _diagnostics: vscode.DiagnosticCollection; + private _validateDocumentStream = new Subject(); + private _validateAllStream = new Subject(); + private _analyzersEnabled: boolean; constructor(server: OmniSharpServer, validationAdvisor: Advisor) { super(server); + this._analyzersEnabled = vscode.workspace.getConfiguration('omnisharp').get('enableRoslynAnalyzers', false); this._validationAdvisor = validationAdvisor; this._diagnostics = vscode.languages.createDiagnosticCollection('csharp'); this._disposable = new CompositeDisposable(this._diagnostics, - this._server.onPackageRestore(this._validateProject, this), - this._server.onProjectChange(this._validateProject, this), + this._server.onPackageRestore(this._validateAllStream.next, this), + this._server.onProjectChange(this._validateAllStream.next, this), this._server.onProjectDiagnosticStatus(this._onProjectAnalysis, this), vscode.workspace.onDidOpenTextDocument(event => this._onDocumentAddOrChange(event), this), vscode.workspace.onDidChangeTextDocument(event => this._onDocumentAddOrChange(event.document), this), @@ -145,6 +152,16 @@ class DiagnosticsProvider extends AbstractSupport { vscode.window.onDidChangeWindowState(event => this._OnDidChangeWindowState(event), this), ); + this._validateDocumentStream + .pipe(throttleTime(750)) + .subscribe(async x => await this._validateDocument(x)); + + this._validateAllStream + .pipe(throttleTime(3000)) + .subscribe(async () => await this._validateAll()); + + this._validateAllStream.next(); + // Go ahead and check for diagnostics in the currently visible editors. for (let editor of vscode.window.visibleTextEditors) { let document = editor.document; @@ -152,7 +169,7 @@ class DiagnosticsProvider extends AbstractSupport { continue; } - this._validateDocument(document); + this._validateDocumentStream.next(document); } } @@ -199,15 +216,19 @@ class DiagnosticsProvider extends AbstractSupport { return; } - this._validateDocument(document); - //this._validateProject(); - } + this._validateDocumentStream.next(document); - private _onProjectAnalysis(event: protocol.ProjectDiagnosticStatus) - { - if(event.Status == 1) + // This check is just small perf optimization to reduce queries + // for omnisharp with analyzers (which have enents to notify updates.) + if(!this._analyzersEnabled) { - this._validateProject(); + this._validateAllStream.next(); + } + } + + private _onProjectAnalysis(event: protocol.ProjectDiagnosticStatus) { + if (event.Status == DiagnosticStatus.Ready) { + this._validateAllStream.next(); } } @@ -227,23 +248,17 @@ class DiagnosticsProvider extends AbstractSupport { delete this._documentValidations[keyString]; } if (didChange) { - this._validateProject(); + this._validateAllStream.next(); } } - private _validateDocument(document: vscode.TextDocument): void { - // If we've already started computing for this document, cancel that work. - let key = document.uri.toString(); - if (this._documentValidations[key]) { - this._documentValidations[key].cancel(); - } - + private async _validateDocument(document: vscode.TextDocument): Promise { if (!this._validationAdvisor.shouldValidateFiles()) { return; } - let source = new vscode.CancellationTokenSource(); - let handle = setTimeout(async () => { + await setTimeout(async () => { + let source = new vscode.CancellationTokenSource(); try { let value = await serverUtils.codeCheck(this._server, { FileName: document.fileName }, source.token); let quickFixes = value.QuickFixes.filter(DiagnosticsProvider._shouldInclude); @@ -263,26 +278,17 @@ class DiagnosticsProvider extends AbstractSupport { catch (error) { return; } - }, 750); - - source.token.onCancellationRequested(() => clearTimeout(handle)); - this._documentValidations[key] = source; + }, 2000); } - private _validateProject(): void { - // If we've already started computing for this project, cancel that work. - // if (this._projectValidation) { - // this._projectValidation.cancel(); - // } - - if (!this._validationAdvisor.shouldValidateProject()) { + private async _validateAll(): Promise { + if (!this._validationAdvisor.shouldValidateAll()) { return; } - this._projectValidation = new vscode.CancellationTokenSource(); - let handle = setTimeout(async () => { + await setTimeout(async() => { try { - let value = await serverUtils.codeCheck(this._server, { FileName: null }, this._projectValidation.token); + let value = await serverUtils.codeCheck(this._server, { FileName: null }, new vscode.CancellationTokenSource().token); let quickFixes = value.QuickFixes .filter(DiagnosticsProvider._shouldInclude) @@ -309,7 +315,7 @@ class DiagnosticsProvider extends AbstractSupport { } // Clear diagnostics for files that no longer have any diagnostics. - this._diagnostics.forEach((uri, diagnostics) => { + this._diagnostics.forEach((uri) => { if (!entries.find(tuple => tuple[0].toString() === uri.toString())) { this._diagnostics.delete(uri); } @@ -322,11 +328,6 @@ class DiagnosticsProvider extends AbstractSupport { return; } }, 3000); - - // clear timeout on cancellation - this._projectValidation.token.onCancellationRequested(() => { - clearTimeout(handle); - }); } private static _shouldInclude(quickFix: protocol.QuickFix): boolean { diff --git a/test/integrationTests/advisor.integration.test.ts b/test/integrationTests/advisor.integration.test.ts index 02633495a..eea40059a 100644 --- a/test/integrationTests/advisor.integration.test.ts +++ b/test/integrationTests/advisor.integration.test.ts @@ -46,7 +46,7 @@ suite(`Advisor ${testAssetWorkspace.description}`, function () { test('Advisor.shouldValidateProject returns true when maxProjectFileCountForDiagnosticAnalysis is higher than the file count', async () => { await setLimit(1000); - expect(advisor.shouldValidateProject()).to.be.true; + expect(advisor.shouldValidateAll()).to.be.true; }); test('Advisor.shouldValidateFiles returns true when maxProjectFileCountForDiagnosticAnalysis is higher than the file count', async () => { @@ -58,7 +58,7 @@ suite(`Advisor ${testAssetWorkspace.description}`, function () { test('Advisor.shouldValidateProject returns false when maxProjectFileCountForDiagnosticAnalysis is lower than the file count', async () => { await setLimit(1); - expect(advisor.shouldValidateProject()).to.be.false; + expect(advisor.shouldValidateAll()).to.be.false; }); test('Advisor.shouldValidateFiles returns true when maxProjectFileCountForDiagnosticAnalysis is lower than the file count', async () => { @@ -70,7 +70,7 @@ suite(`Advisor ${testAssetWorkspace.description}`, function () { test('Advisor.shouldValidateProject returns true when maxProjectFileCountForDiagnosticAnalysis is null', async () => { await setLimit(null); - expect(advisor.shouldValidateProject()).to.be.true; + expect(advisor.shouldValidateAll()).to.be.true; }); test('Advisor.shouldValidateFiles returns true when maxProjectFileCountForDiagnosticAnalysis is null', async () => { From b6d6965db8f9e04f63dfb37c0fa41698f844ca45 Mon Sep 17 00:00:00 2001 From: Savpek Date: Fri, 31 May 2019 14:19:03 +0300 Subject: [PATCH 09/57] Testing tests against local build. --- src/features/diagnosticsProvider.ts | 19 +++++++++---------- .../advisor.integration.test.ts | 6 +++--- .../singleCsproj/.vscode/settings.json | 2 +- .../slnWithCsproj/.vscode/settings.json | 2 +- 4 files changed, 14 insertions(+), 15 deletions(-) diff --git a/src/features/diagnosticsProvider.ts b/src/features/diagnosticsProvider.ts index a1185ad3b..c36c4456b 100644 --- a/src/features/diagnosticsProvider.ts +++ b/src/features/diagnosticsProvider.ts @@ -141,6 +141,15 @@ class DiagnosticsProvider extends AbstractSupport { this._validationAdvisor = validationAdvisor; this._diagnostics = vscode.languages.createDiagnosticCollection('csharp'); + + this._validateDocumentStream + .pipe(throttleTime(750)) + .subscribe(async x => await this._validateDocument(x)); + + this._validateAllStream + .pipe(throttleTime(3000)) + .subscribe(async () => await this._validateAll()); + this._disposable = new CompositeDisposable(this._diagnostics, this._server.onPackageRestore(this._validateAllStream.next, this), this._server.onProjectChange(this._validateAllStream.next, this), @@ -152,16 +161,6 @@ class DiagnosticsProvider extends AbstractSupport { vscode.window.onDidChangeWindowState(event => this._OnDidChangeWindowState(event), this), ); - this._validateDocumentStream - .pipe(throttleTime(750)) - .subscribe(async x => await this._validateDocument(x)); - - this._validateAllStream - .pipe(throttleTime(3000)) - .subscribe(async () => await this._validateAll()); - - this._validateAllStream.next(); - // Go ahead and check for diagnostics in the currently visible editors. for (let editor of vscode.window.visibleTextEditors) { let document = editor.document; diff --git a/test/integrationTests/advisor.integration.test.ts b/test/integrationTests/advisor.integration.test.ts index eea40059a..c899872ee 100644 --- a/test/integrationTests/advisor.integration.test.ts +++ b/test/integrationTests/advisor.integration.test.ts @@ -43,7 +43,7 @@ suite(`Advisor ${testAssetWorkspace.description}`, function () { await testAssetWorkspace.cleanupWorkspace(); }); - test('Advisor.shouldValidateProject returns true when maxProjectFileCountForDiagnosticAnalysis is higher than the file count', async () => { + test('Advisor.shouldValidateAll returns true when maxProjectFileCountForDiagnosticAnalysis is higher than the file count', async () => { await setLimit(1000); expect(advisor.shouldValidateAll()).to.be.true; @@ -55,7 +55,7 @@ suite(`Advisor ${testAssetWorkspace.description}`, function () { expect(advisor.shouldValidateFiles()).to.be.true; }); - test('Advisor.shouldValidateProject returns false when maxProjectFileCountForDiagnosticAnalysis is lower than the file count', async () => { + test('Advisor.shouldValidateAll returns false when maxProjectFileCountForDiagnosticAnalysis is lower than the file count', async () => { await setLimit(1); expect(advisor.shouldValidateAll()).to.be.false; @@ -67,7 +67,7 @@ suite(`Advisor ${testAssetWorkspace.description}`, function () { expect(advisor.shouldValidateFiles()).to.be.true; }); - test('Advisor.shouldValidateProject returns true when maxProjectFileCountForDiagnosticAnalysis is null', async () => { + test('Advisor.shouldValidateAll returns true when maxProjectFileCountForDiagnosticAnalysis is null', async () => { await setLimit(null); expect(advisor.shouldValidateAll()).to.be.true; diff --git a/test/integrationTests/testAssets/singleCsproj/.vscode/settings.json b/test/integrationTests/testAssets/singleCsproj/.vscode/settings.json index 15054e359..56a56c43c 100644 --- a/test/integrationTests/testAssets/singleCsproj/.vscode/settings.json +++ b/test/integrationTests/testAssets/singleCsproj/.vscode/settings.json @@ -1,3 +1,3 @@ { - "omnisharp.path": "latest" + "omnisharp.path": "C:\\tmp\\Omnisharp-combined0\\Omnisharp.exe" } \ No newline at end of file diff --git a/test/integrationTests/testAssets/slnWithCsproj/.vscode/settings.json b/test/integrationTests/testAssets/slnWithCsproj/.vscode/settings.json index c80abf42f..dce380ba4 100644 --- a/test/integrationTests/testAssets/slnWithCsproj/.vscode/settings.json +++ b/test/integrationTests/testAssets/slnWithCsproj/.vscode/settings.json @@ -1,5 +1,5 @@ { "omnisharp.defaultLaunchSolution": "b_SecondInOrder_SlnFile.sln", - "omnisharp.path": "latest", + "omnisharp.path": "C:\\tmp\\Omnisharp-combined0\\Omnisharp.exe", "csharp.maxProjectFileCountForDiagnosticAnalysis": 1000, } \ No newline at end of file From 42779b5bcd2c12e27a0504c46f3d6fa7bb3df9cb Mon Sep 17 00:00:00 2001 From: Savpek Date: Fri, 31 May 2019 17:36:57 +0300 Subject: [PATCH 10/57] Tweaks for provider. --- src/features/diagnosticsProvider.ts | 65 ++++++++++------------------- 1 file changed, 22 insertions(+), 43 deletions(-) diff --git a/src/features/diagnosticsProvider.ts b/src/features/diagnosticsProvider.ts index c36c4456b..ab5c8cf25 100644 --- a/src/features/diagnosticsProvider.ts +++ b/src/features/diagnosticsProvider.ts @@ -14,7 +14,7 @@ import { IDisposable } from '../Disposable'; import { isVirtualCSharpDocument } from './virtualDocumentTracker'; import { TextDocument } from '../vscodeAdapter'; import OptionProvider from '../observers/OptionProvider'; -import { Subject } from 'rxjs'; +import { Subject, Subscription } from 'rxjs'; import { throttleTime } from 'rxjs/operators'; import { DiagnosticStatus } from '../omnisharp/protocol'; @@ -127,12 +127,11 @@ class DiagnosticsProvider extends AbstractSupport { private _validationAdvisor: Advisor; private _disposable: CompositeDisposable; - private _documentValidations: { [uri: string]: vscode.CancellationTokenSource } = Object.create(null); - private _projectValidation: vscode.CancellationTokenSource; private _diagnostics: vscode.DiagnosticCollection; private _validateDocumentStream = new Subject(); private _validateAllStream = new Subject(); private _analyzersEnabled: boolean; + private _subscriptions: Subscription[] = []; constructor(server: OmniSharpServer, validationAdvisor: Advisor) { super(server); @@ -141,18 +140,19 @@ class DiagnosticsProvider extends AbstractSupport { this._validationAdvisor = validationAdvisor; this._diagnostics = vscode.languages.createDiagnosticCollection('csharp'); - - this._validateDocumentStream + this._subscriptions.push(this._validateDocumentStream + .asObservable() .pipe(throttleTime(750)) - .subscribe(async x => await this._validateDocument(x)); + .subscribe(async x => await this._validateDocument(x))); - this._validateAllStream + this._subscriptions.push(this._validateAllStream + .asObservable() .pipe(throttleTime(3000)) - .subscribe(async () => await this._validateAll()); + .subscribe(async () => await this._validateAll())); this._disposable = new CompositeDisposable(this._diagnostics, - this._server.onPackageRestore(this._validateAllStream.next, this), - this._server.onProjectChange(this._validateAllStream.next, this), + this._server.onPackageRestore(() => this._validateAllStream.next(), this), + this._server.onProjectChange(() => this._validateAllStream.next(), this), this._server.onProjectDiagnosticStatus(this._onProjectAnalysis, this), vscode.workspace.onDidOpenTextDocument(event => this._onDocumentAddOrChange(event), this), vscode.workspace.onDidChangeTextDocument(event => this._onDocumentAddOrChange(event.document), this), @@ -161,26 +161,21 @@ class DiagnosticsProvider extends AbstractSupport { vscode.window.onDidChangeWindowState(event => this._OnDidChangeWindowState(event), this), ); - // Go ahead and check for diagnostics in the currently visible editors. - for (let editor of vscode.window.visibleTextEditors) { - let document = editor.document; - if (this.shouldIgnoreDocument(document)) { - continue; - } + // // Go ahead and check for diagnostics in the currently visible editors. + // for (let editor of vscode.window.visibleTextEditors) { + // let document = editor.document; + // if (this.shouldIgnoreDocument(document)) { + // continue; + // } - this._validateDocumentStream.next(document); - } + // this._validateDocumentStream.next(document); + // } } public dispose = () => { - if (this._projectValidation) { - this._projectValidation.dispose(); - } - - for (let key in this._documentValidations) { - this._documentValidations[key].dispose(); - } - + this._validateAllStream.complete(); + this._validateDocumentStream.complete(); + this._subscriptions.forEach(x => x.unsubscribe()); this._disposable.dispose(); } @@ -232,23 +227,7 @@ class DiagnosticsProvider extends AbstractSupport { } private _onDocumentRemove(document: vscode.TextDocument): void { - let key = document.uri; - let didChange = false; - if (this._diagnostics.get(key)) { - didChange = true; - this._diagnostics.delete(key); - } - - let keyString = key.toString(); - - if (this._documentValidations[keyString]) { - didChange = true; - this._documentValidations[keyString].cancel(); - delete this._documentValidations[keyString]; - } - if (didChange) { - this._validateAllStream.next(); - } + this._validateAllStream.next(); } private async _validateDocument(document: vscode.TextDocument): Promise { From 53420cb821824fc6a08bfd180df4afcf6f38f9d3 Mon Sep 17 00:00:00 2001 From: Savpek Date: Fri, 31 May 2019 18:54:13 +0300 Subject: [PATCH 11/57] Streamlined large vs small workspace analysis. --- src/features/diagnosticsProvider.ts | 126 ++++++++++++++-------------- 1 file changed, 64 insertions(+), 62 deletions(-) diff --git a/src/features/diagnosticsProvider.ts b/src/features/diagnosticsProvider.ts index ab5c8cf25..e7d6fb77b 100644 --- a/src/features/diagnosticsProvider.ts +++ b/src/features/diagnosticsProvider.ts @@ -128,8 +128,8 @@ class DiagnosticsProvider extends AbstractSupport { private _validationAdvisor: Advisor; private _disposable: CompositeDisposable; private _diagnostics: vscode.DiagnosticCollection; - private _validateDocumentStream = new Subject(); - private _validateAllStream = new Subject(); + private _validateCurrentDocumentPipe = new Subject(); + private _validateAllPipe = new Subject(); private _analyzersEnabled: boolean; private _subscriptions: Subscription[] = []; @@ -140,19 +140,28 @@ class DiagnosticsProvider extends AbstractSupport { this._validationAdvisor = validationAdvisor; this._diagnostics = vscode.languages.createDiagnosticCollection('csharp'); - this._subscriptions.push(this._validateDocumentStream + this._subscriptions.push(this._validateCurrentDocumentPipe .asObservable() .pipe(throttleTime(750)) .subscribe(async x => await this._validateDocument(x))); - this._subscriptions.push(this._validateAllStream + this._subscriptions.push(this._validateAllPipe .asObservable() .pipe(throttleTime(3000)) - .subscribe(async () => await this._validateAll())); + .subscribe(async () => { + try { + if (this._validationAdvisor.shouldValidateAll()) { + await this._validateSmallWorkspace(); + } + else if (this._validationAdvisor.shouldValidateFiles()) { + await this._validateLargeWorkspace(); + } + } catch { } + })); this._disposable = new CompositeDisposable(this._diagnostics, - this._server.onPackageRestore(() => this._validateAllStream.next(), this), - this._server.onProjectChange(() => this._validateAllStream.next(), this), + this._server.onPackageRestore(() => this._validateAllPipe.next(), this), + this._server.onProjectChange(() => this._validateAllPipe.next(), this), this._server.onProjectDiagnosticStatus(this._onProjectAnalysis, this), vscode.workspace.onDidOpenTextDocument(event => this._onDocumentAddOrChange(event), this), vscode.workspace.onDidChangeTextDocument(event => this._onDocumentAddOrChange(event.document), this), @@ -160,21 +169,11 @@ class DiagnosticsProvider extends AbstractSupport { vscode.window.onDidChangeActiveTextEditor(event => this._onDidChangeActiveTextEditor(event), this), vscode.window.onDidChangeWindowState(event => this._OnDidChangeWindowState(event), this), ); - - // // Go ahead and check for diagnostics in the currently visible editors. - // for (let editor of vscode.window.visibleTextEditors) { - // let document = editor.document; - // if (this.shouldIgnoreDocument(document)) { - // continue; - // } - - // this._validateDocumentStream.next(document); - // } } public dispose = () => { - this._validateAllStream.complete(); - this._validateDocumentStream.complete(); + this._validateAllPipe.complete(); + this._validateCurrentDocumentPipe.complete(); this._subscriptions.forEach(x => x.unsubscribe()); this._disposable.dispose(); } @@ -210,24 +209,23 @@ class DiagnosticsProvider extends AbstractSupport { return; } - this._validateDocumentStream.next(document); + this._validateCurrentDocumentPipe.next(document); // This check is just small perf optimization to reduce queries // for omnisharp with analyzers (which have enents to notify updates.) - if(!this._analyzersEnabled) - { - this._validateAllStream.next(); + if (!this._analyzersEnabled) { + this._validateAllPipe.next(); } } private _onProjectAnalysis(event: protocol.ProjectDiagnosticStatus) { if (event.Status == DiagnosticStatus.Ready) { - this._validateAllStream.next(); + this._validateAllPipe.next(); } } private _onDocumentRemove(document: vscode.TextDocument): void { - this._validateAllStream.next(); + this._validateAllPipe.next(); } private async _validateDocument(document: vscode.TextDocument): Promise { @@ -259,52 +257,56 @@ class DiagnosticsProvider extends AbstractSupport { }, 2000); } - private async _validateAll(): Promise { - if (!this._validationAdvisor.shouldValidateAll()) { - return; - } + private async _validateLargeWorkspace(): Promise { + await setTimeout(async () => { + for (let editor of vscode.window.visibleTextEditors) { + let document = editor.document; + if (this.shouldIgnoreDocument(document)) { + continue; + } - await setTimeout(async() => { - try { - let value = await serverUtils.codeCheck(this._server, { FileName: null }, new vscode.CancellationTokenSource().token); + await this._validateDocument(document); + } + }, 3000); + } - let quickFixes = value.QuickFixes - .filter(DiagnosticsProvider._shouldInclude) - .sort((a, b) => a.FileName.localeCompare(b.FileName)); + private async _validateSmallWorkspace(): Promise { + await setTimeout(async () => { + let value = await serverUtils.codeCheck(this._server, { FileName: null }, new vscode.CancellationTokenSource().token); - let entries: [vscode.Uri, vscode.Diagnostic[]][] = []; - let lastEntry: [vscode.Uri, vscode.Diagnostic[]]; + let quickFixes = value.QuickFixes + .filter(DiagnosticsProvider._shouldInclude) + .sort((a, b) => a.FileName.localeCompare(b.FileName)); - for (let quickFix of quickFixes) { + let entries: [vscode.Uri, vscode.Diagnostic[]][] = []; + let lastEntry: [vscode.Uri, vscode.Diagnostic[]]; - let diag = DiagnosticsProvider._asDiagnostic(quickFix); - let uri = vscode.Uri.file(quickFix.FileName); + for (let quickFix of quickFixes) { - 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); - } + let diag = DiagnosticsProvider._asDiagnostic(quickFix); + let uri = vscode.Uri.file(quickFix.FileName); + + 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) => { - if (!entries.find(tuple => tuple[0].toString() === uri.toString())) { - this._diagnostics.delete(uri); - } - }); + // Clear diagnostics for files that no longer have any diagnostics. + this._diagnostics.forEach((uri) => { + if (!entries.find(tuple => tuple[0].toString() === uri.toString())) { + this._diagnostics.delete(uri); + } + }); - // replace all entries - this._diagnostics.set(entries); - } - catch (error) { - return; - } + // replace all entries + this._diagnostics.set(entries); }, 3000); } From 204e7de4a0ab1bb9af5008f7e9d409331eaf50a6 Mon Sep 17 00:00:00 2001 From: Savpek Date: Fri, 31 May 2019 19:11:33 +0300 Subject: [PATCH 12/57] Restored latest as version. --- .../testAssets/singleCsproj/.vscode/settings.json | 4 +++- .../testAssets/slnWithCsproj/.vscode/settings.json | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/test/integrationTests/testAssets/singleCsproj/.vscode/settings.json b/test/integrationTests/testAssets/singleCsproj/.vscode/settings.json index 56a56c43c..83f9c5b60 100644 --- a/test/integrationTests/testAssets/singleCsproj/.vscode/settings.json +++ b/test/integrationTests/testAssets/singleCsproj/.vscode/settings.json @@ -1,3 +1,5 @@ { - "omnisharp.path": "C:\\tmp\\Omnisharp-combined0\\Omnisharp.exe" + "omnisharp.path": "latest", + "csharp.referencesCodeLens.enabled": true, + "csharp.testsCodeLens.enabled": true } \ No newline at end of file diff --git a/test/integrationTests/testAssets/slnWithCsproj/.vscode/settings.json b/test/integrationTests/testAssets/slnWithCsproj/.vscode/settings.json index dce380ba4..c80abf42f 100644 --- a/test/integrationTests/testAssets/slnWithCsproj/.vscode/settings.json +++ b/test/integrationTests/testAssets/slnWithCsproj/.vscode/settings.json @@ -1,5 +1,5 @@ { "omnisharp.defaultLaunchSolution": "b_SecondInOrder_SlnFile.sln", - "omnisharp.path": "C:\\tmp\\Omnisharp-combined0\\Omnisharp.exe", + "omnisharp.path": "latest", "csharp.maxProjectFileCountForDiagnosticAnalysis": 1000, } \ No newline at end of file From b46d8d1ea4addc303aa1833307155f4e68c8cff2 Mon Sep 17 00:00:00 2001 From: Savpek Date: Fri, 31 May 2019 19:13:17 +0300 Subject: [PATCH 13/57] Fix for test settings.json. --- .../testAssets/singleCsproj/.vscode/settings.json | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/test/integrationTests/testAssets/singleCsproj/.vscode/settings.json b/test/integrationTests/testAssets/singleCsproj/.vscode/settings.json index 83f9c5b60..15054e359 100644 --- a/test/integrationTests/testAssets/singleCsproj/.vscode/settings.json +++ b/test/integrationTests/testAssets/singleCsproj/.vscode/settings.json @@ -1,5 +1,3 @@ { - "omnisharp.path": "latest", - "csharp.referencesCodeLens.enabled": true, - "csharp.testsCodeLens.enabled": true + "omnisharp.path": "latest" } \ No newline at end of file From 060560c2944763c6d95e35ca405ad588663e44ba Mon Sep 17 00:00:00 2001 From: Savpek Date: Fri, 31 May 2019 20:58:56 +0300 Subject: [PATCH 14/57] Comment tweaks. --- src/features/diagnosticsProvider.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/features/diagnosticsProvider.ts b/src/features/diagnosticsProvider.ts index e7d6fb77b..49d033490 100644 --- a/src/features/diagnosticsProvider.ts +++ b/src/features/diagnosticsProvider.ts @@ -212,7 +212,7 @@ class DiagnosticsProvider extends AbstractSupport { this._validateCurrentDocumentPipe.next(document); // This check is just small perf optimization to reduce queries - // for omnisharp with analyzers (which have enents to notify updates.) + // for omnisharp with analyzers (which has event to notify about updates.) if (!this._analyzersEnabled) { this._validateAllPipe.next(); } @@ -257,6 +257,8 @@ class DiagnosticsProvider extends AbstractSupport { }, 2000); } + // On large workspaces (if maxProjectFileCountForDiagnosticAnalysis) is less than workspace size, + // diagnostic fallback to mode where only open documents are analyzed. private async _validateLargeWorkspace(): Promise { await setTimeout(async () => { for (let editor of vscode.window.visibleTextEditors) { From 640b4ccf4c55a1141b24787e0eea06e27a63107e Mon Sep 17 00:00:00 2001 From: Savpek Date: Sun, 7 Jul 2019 12:31:24 +0300 Subject: [PATCH 15/57] npm fix. --- package-lock.json | 45 +++++++++++---------------------------------- package.json | 2 +- 2 files changed, 12 insertions(+), 35 deletions(-) diff --git a/package-lock.json b/package-lock.json index e13db3d90..6c1814de5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,10 +1,6 @@ { "name": "csharp", -<<<<<<< HEAD - "version": "1.20.0-beta1", -======= "version": "1.21.0-beta1", ->>>>>>> upstream/master "lockfileVersion": 1, "requires": true, "dependencies": { @@ -3612,8 +3608,7 @@ "ansi-regex": { "version": "2.1.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "aproba": { "version": "1.2.0", @@ -3634,14 +3629,12 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, - "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -3656,20 +3649,17 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "core-util-is": { "version": "1.0.2", @@ -3786,8 +3776,7 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "ini": { "version": "1.3.5", @@ -3799,7 +3788,6 @@ "version": "1.0.0", "bundled": true, "dev": true, - "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -3814,7 +3802,6 @@ "version": "3.0.4", "bundled": true, "dev": true, - "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -3822,14 +3809,12 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "minipass": { "version": "2.2.4", "bundled": true, "dev": true, - "optional": true, "requires": { "safe-buffer": "^5.1.1", "yallist": "^3.0.0" @@ -3848,7 +3833,6 @@ "version": "0.5.1", "bundled": true, "dev": true, - "optional": true, "requires": { "minimist": "0.0.8" } @@ -3929,8 +3913,7 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "object-assign": { "version": "4.1.1", @@ -3942,7 +3925,6 @@ "version": "1.4.0", "bundled": true, "dev": true, - "optional": true, "requires": { "wrappy": "1" } @@ -4028,8 +4010,7 @@ "safe-buffer": { "version": "5.1.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "safer-buffer": { "version": "2.1.2", @@ -4065,7 +4046,6 @@ "version": "1.0.2", "bundled": true, "dev": true, - "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -4085,7 +4065,6 @@ "version": "3.0.1", "bundled": true, "dev": true, - "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -4129,14 +4108,12 @@ "wrappy": { "version": "1.0.2", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "yallist": { "version": "3.0.2", "bundled": true, - "dev": true, - "optional": true + "dev": true } } }, diff --git a/package.json b/package.json index 09a9e29e9..ff89bbb03 100644 --- a/package.json +++ b/package.json @@ -2979,4 +2979,4 @@ ] } } -} \ No newline at end of file +} From 158b4c06f27fe4ee0aede1113e6f01ee0bc3fa97 Mon Sep 17 00:00:00 2001 From: Savpek Date: Sun, 7 Jul 2019 16:55:46 +0300 Subject: [PATCH 16/57] Enabled skipped test. --- test/integrationTests/diagnostics.integration.test.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/integrationTests/diagnostics.integration.test.ts b/test/integrationTests/diagnostics.integration.test.ts index a7baf46fa..77d077445 100644 --- a/test/integrationTests/diagnostics.integration.test.ts +++ b/test/integrationTests/diagnostics.integration.test.ts @@ -50,11 +50,10 @@ suite(`DiagnosticProvider: ${testAssetWorkspace.description}`, function () { }); test("Return fadeout diagnostics like unused usings based on roslyn analyzers", async function () { - this.skip(); // Remove this once https://github.com/OmniSharp/omnisharp-roslyn/issues/1458 is resolved. let result = await poll(() => vscode.languages.getDiagnostics(fileUri), 15*1000, 500); let ide0005 = result.find(x => x.message.includes("IDE0005")); - expect(ide0005).to.not.be(undefined); + expect(ide0005).to.not.be.undefined; expect(ide0005.tags).to.include(vscode.DiagnosticTag.Unnecessary); }); }); From 975e61083319ac07c7e9e9c3089dd782b5aabda0 Mon Sep 17 00:00:00 2001 From: Savpek Date: Sun, 7 Jul 2019 17:14:55 +0300 Subject: [PATCH 17/57] Test tweak. --- .../diagnostics.integration.test.ts | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/test/integrationTests/diagnostics.integration.test.ts b/test/integrationTests/diagnostics.integration.test.ts index 77d077445..749d466df 100644 --- a/test/integrationTests/diagnostics.integration.test.ts +++ b/test/integrationTests/diagnostics.integration.test.ts @@ -49,11 +49,19 @@ suite(`DiagnosticProvider: ${testAssetWorkspace.description}`, function () { expect(cs8019.tags).to.include(vscode.DiagnosticTag.Unnecessary); }); - test("Return fadeout diagnostics like unused usings based on roslyn analyzers", async function () { + test("Return fadeout diagnostics like unused variables based on roslyn analyzers", async function () { let result = await poll(() => vscode.languages.getDiagnostics(fileUri), 15*1000, 500); - let ide0005 = result.find(x => x.message.includes("IDE0005")); - expect(ide0005).to.not.be.undefined; - expect(ide0005.tags).to.include(vscode.DiagnosticTag.Unnecessary); + let ide0059 = result.find(x => x.message.includes("IDE0059")); + expect(ide0059).to.not.be.undefined; + expect(ide0059.tags).to.include(vscode.DiagnosticTag.Unnecessary); + }); + + test("When re-analyze for project is executed then eventually get correct result", async function () { + // let result = await poll(() => vscode.languages.getDiagnostics(fileUri), 15*1000, 500); + + // let ide0005 = result.find(x => x.message.includes("IDE0059")); + // expect(ide0005).to.not.be.undefined; + // expect(ide0005.tags).to.include(vscode.DiagnosticTag.Unnecessary); }); }); From c22f6bd1226343fe48527c92e55b9f23cfc13713 Mon Sep 17 00:00:00 2001 From: Savpek Date: Sun, 7 Jul 2019 17:43:32 +0300 Subject: [PATCH 18/57] Tweaked test poll routine. --- test/integrationTests/diagnostics.integration.test.ts | 3 +-- test/integrationTests/poll.ts | 6 +++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/test/integrationTests/diagnostics.integration.test.ts b/test/integrationTests/diagnostics.integration.test.ts index 749d466df..0c5f18f63 100644 --- a/test/integrationTests/diagnostics.integration.test.ts +++ b/test/integrationTests/diagnostics.integration.test.ts @@ -50,10 +50,9 @@ suite(`DiagnosticProvider: ${testAssetWorkspace.description}`, function () { }); test("Return fadeout diagnostics like unused variables based on roslyn analyzers", async function () { - let result = await poll(() => vscode.languages.getDiagnostics(fileUri), 15*1000, 500); + let result = await poll(() => vscode.languages.getDiagnostics(fileUri), 15*1000, 500, result => result.find(x => x.message.includes("IDE0059")) != undefined); let ide0059 = result.find(x => x.message.includes("IDE0059")); - expect(ide0059).to.not.be.undefined; expect(ide0059.tags).to.include(vscode.DiagnosticTag.Unnecessary); }); diff --git a/test/integrationTests/poll.ts b/test/integrationTests/poll.ts index 0f0b2ace4..8c2616bc1 100644 --- a/test/integrationTests/poll.ts +++ b/test/integrationTests/poll.ts @@ -3,15 +3,15 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -export default async function poll(getValue: () => T, duration: number, step: number): Promise { +export default async function poll(getValue: () => T, duration: number, step: number, expression: (input: T) => boolean = _ => true): Promise { while (duration > 0) { let value = await getValue(); - if(Array.isArray(value) && value.length > 0) { + if(Array.isArray(value) && value.length > 0 && expression(value)) { return value; } - if (!Array.isArray(value) && value) { + if (!Array.isArray(value) && value && expression(value)) { return value; } From 2a0e0e53fcc0ecc8cfab0cde40e9ac75d9932286 Mon Sep 17 00:00:00 2001 From: Savpek Date: Sun, 7 Jul 2019 18:02:36 +0300 Subject: [PATCH 19/57] Enable roslyn analyzers for diag tests. --- .../testAssets/singleCsproj/.vscode/settings.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/integrationTests/testAssets/singleCsproj/.vscode/settings.json b/test/integrationTests/testAssets/singleCsproj/.vscode/settings.json index 15054e359..2dae17035 100644 --- a/test/integrationTests/testAssets/singleCsproj/.vscode/settings.json +++ b/test/integrationTests/testAssets/singleCsproj/.vscode/settings.json @@ -1,3 +1,4 @@ { - "omnisharp.path": "latest" + "omnisharp.path": "latest", + "omnisharp.enableRoslynAnalyzers": true } \ No newline at end of file From 0fc52b0244c7984129aa7ab4c029b5665ce6cb96 Mon Sep 17 00:00:00 2001 From: Savpek Date: Sun, 7 Jul 2019 18:23:03 +0300 Subject: [PATCH 20/57] Enabled analyzers with sln. --- package-lock.json | 28 ++++++++++++++----- .../slnWithCsproj/.vscode/settings.json | 1 + 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6c1814de5..f118a7dd6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3629,12 +3629,14 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, + "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -3649,17 +3651,20 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "core-util-is": { "version": "1.0.2", @@ -3776,7 +3781,8 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "ini": { "version": "1.3.5", @@ -3788,6 +3794,7 @@ "version": "1.0.0", "bundled": true, "dev": true, + "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -3802,6 +3809,7 @@ "version": "3.0.4", "bundled": true, "dev": true, + "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -3809,12 +3817,14 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "minipass": { "version": "2.2.4", "bundled": true, "dev": true, + "optional": true, "requires": { "safe-buffer": "^5.1.1", "yallist": "^3.0.0" @@ -3833,6 +3843,7 @@ "version": "0.5.1", "bundled": true, "dev": true, + "optional": true, "requires": { "minimist": "0.0.8" } @@ -3913,7 +3924,8 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "object-assign": { "version": "4.1.1", @@ -3925,6 +3937,7 @@ "version": "1.4.0", "bundled": true, "dev": true, + "optional": true, "requires": { "wrappy": "1" } @@ -4046,6 +4059,7 @@ "version": "1.0.2", "bundled": true, "dev": true, + "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", diff --git a/test/integrationTests/testAssets/slnWithCsproj/.vscode/settings.json b/test/integrationTests/testAssets/slnWithCsproj/.vscode/settings.json index 0f37721a6..21cecb392 100644 --- a/test/integrationTests/testAssets/slnWithCsproj/.vscode/settings.json +++ b/test/integrationTests/testAssets/slnWithCsproj/.vscode/settings.json @@ -1,5 +1,6 @@ { "omnisharp.defaultLaunchSolution": "b_SecondInOrder_SlnFile.sln", "omnisharp.path": "latest", + "omnisharp.enableRoslynAnalyzers": true, "csharp.maxProjectFileCountForDiagnosticAnalysis": 1000 } \ No newline at end of file From 5cd74d066c4b37dcb8a2034b8578164a2e858ca2 Mon Sep 17 00:00:00 2001 From: Savpek Date: Sun, 7 Jul 2019 18:40:40 +0300 Subject: [PATCH 21/57] Updated request to match latest version of o-roslyn side. --- src/features/commands.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/features/commands.ts b/src/features/commands.ts index 13f05a667..9dbf69a71 100644 --- a/src/features/commands.ts +++ b/src/features/commands.ts @@ -141,7 +141,7 @@ async function reAnalyzeAllProjects(server: OmniSharpServer, eventStream: EventS async function reAnalyzeCurrentProject(server: OmniSharpServer, eventStream: EventStream): Promise { await serverUtils.reAnalyze(server, { - currentOpenFilePathAsContext: vscode.window.activeTextEditor.document.uri.fsPath + fileName: vscode.window.activeTextEditor.document.uri.fsPath }); } From 9c1bb317f306133d50109f6cb374ecfafe20d6d5 Mon Sep 17 00:00:00 2001 From: Savpek Date: Sun, 7 Jul 2019 19:46:33 +0300 Subject: [PATCH 22/57] First dummy version of re-analysis test. --- .../diagnostics.integration.test.ts | 8 ---- .../reAnalyze.integration.test.ts | 45 +++++++++++++++++++ .../testAssets/singleCsproj/ISomeInterface.cs | 6 +++ .../singleCsproj/SomeInterfaceImpl.cs | 6 +++ 4 files changed, 57 insertions(+), 8 deletions(-) create mode 100644 test/integrationTests/reAnalyze.integration.test.ts create mode 100644 test/integrationTests/testAssets/singleCsproj/ISomeInterface.cs create mode 100644 test/integrationTests/testAssets/singleCsproj/SomeInterfaceImpl.cs diff --git a/test/integrationTests/diagnostics.integration.test.ts b/test/integrationTests/diagnostics.integration.test.ts index 0c5f18f63..20f07edc0 100644 --- a/test/integrationTests/diagnostics.integration.test.ts +++ b/test/integrationTests/diagnostics.integration.test.ts @@ -55,12 +55,4 @@ suite(`DiagnosticProvider: ${testAssetWorkspace.description}`, function () { let ide0059 = result.find(x => x.message.includes("IDE0059")); expect(ide0059.tags).to.include(vscode.DiagnosticTag.Unnecessary); }); - - test("When re-analyze for project is executed then eventually get correct result", async function () { - // let result = await poll(() => vscode.languages.getDiagnostics(fileUri), 15*1000, 500); - - // let ide0005 = result.find(x => x.message.includes("IDE0059")); - // expect(ide0005).to.not.be.undefined; - // expect(ide0005.tags).to.include(vscode.DiagnosticTag.Unnecessary); - }); }); diff --git a/test/integrationTests/reAnalyze.integration.test.ts b/test/integrationTests/reAnalyze.integration.test.ts new file mode 100644 index 000000000..eb3ed25d1 --- /dev/null +++ b/test/integrationTests/reAnalyze.integration.test.ts @@ -0,0 +1,45 @@ +/*--------------------------------------------------------------------------------------------- +* Copyright (c) Microsoft Corporation. All rights reserved. +* Licensed under the MIT License. See License.txt in the project root for license information. +*--------------------------------------------------------------------------------------------*/ + +import * as vscode from 'vscode'; +import * as path from 'path'; + +import { should } from 'chai'; +import { activateCSharpExtension } from './integrationHelpers'; +import testAssetWorkspace from './testAssets/testAssetWorkspace'; + +const chai = require('chai'); +chai.use(require('chai-arrays')); +chai.use(require('chai-fs')); + +suite(`ReAnalyze: ${testAssetWorkspace.description}`, function () { + let interfaceUri: vscode.Uri; + let interfaceImplUri: vscode.Uri; + + suiteSetup(async function () { + should(); + + await testAssetWorkspace.restore(); + await activateCSharpExtension(); + + let projectDirectory = testAssetWorkspace.projects[0].projectDirectoryPath; + interfaceUri = vscode.Uri.file(path.join(projectDirectory, 'ISomeInterface.cs')); + interfaceImplUri = vscode.Uri.file(path.join(projectDirectory, 'SomeInterfaceImpl.cs')); + + await vscode.commands.executeCommand("vscode.open", interfaceImplUri); + await vscode.commands.executeCommand("vscode.open", interfaceUri); + }); + + suiteTeardown(async () => { + await testAssetWorkspace.cleanupWorkspace(); + }); + + test("When interface is manually renamed, then return correct analysis after re-analysis of project", async function () { + vscode.TextEdit.replace(new vscode.Range(1, 0, 1, 100), 'foo'); + await vscode.commands.executeCommand('o.reanalyze.currentProject', interfaceUri); + // let result = await poll(() => vscode.languages.getDiagnostics(interfaceImplUri), 10*1000, 500); + // let cs8019 = result.find(x => x.message.includes("CS8019")); + }); +}); diff --git a/test/integrationTests/testAssets/singleCsproj/ISomeInterface.cs b/test/integrationTests/testAssets/singleCsproj/ISomeInterface.cs new file mode 100644 index 000000000..4c2da47f4 --- /dev/null +++ b/test/integrationTests/testAssets/singleCsproj/ISomeInterface.cs @@ -0,0 +1,6 @@ +namespace ReAnalyze +{ + public interface ISomeInterface + { + } +} \ No newline at end of file diff --git a/test/integrationTests/testAssets/singleCsproj/SomeInterfaceImpl.cs b/test/integrationTests/testAssets/singleCsproj/SomeInterfaceImpl.cs new file mode 100644 index 000000000..ce6b9fa31 --- /dev/null +++ b/test/integrationTests/testAssets/singleCsproj/SomeInterfaceImpl.cs @@ -0,0 +1,6 @@ +namespace ReAnalyze +{ + public class SomeInterfaceImpl: ISomeInterface + { + } +} \ No newline at end of file From 50bf6e2a46af605a90e3f2190aa18d8f362c73d1 Mon Sep 17 00:00:00 2001 From: Savpek Date: Sun, 7 Jul 2019 20:05:51 +0300 Subject: [PATCH 23/57] Temporary local omnisharp.exe. --- .../codeActionRename.integration.test.ts | 2 +- .../reAnalyze.integration.test.ts | 19 ++++++++++++++----- .../singleCsproj/.vscode/settings.json | 3 ++- .../testAssets/singleCsproj/ISomeInterface.cs | 2 +- .../slnWithCsproj/.vscode/settings.json | 3 ++- 5 files changed, 20 insertions(+), 9 deletions(-) diff --git a/test/integrationTests/codeActionRename.integration.test.ts b/test/integrationTests/codeActionRename.integration.test.ts index 7685f3dfd..ef3d1437f 100644 --- a/test/integrationTests/codeActionRename.integration.test.ts +++ b/test/integrationTests/codeActionRename.integration.test.ts @@ -25,7 +25,7 @@ suite(`Code Action Rename ${testAssetWorkspace.description}`, function () { let fileName = 'A.cs'; let projectDirectory = testAssetWorkspace.projects[0].projectDirectoryPath; let filePath = path.join(projectDirectory, fileName); - fileUri = vscode.Uri.file(filePath) + fileUri = vscode.Uri.file(filePath); }); suiteTeardown(async () => { diff --git a/test/integrationTests/reAnalyze.integration.test.ts b/test/integrationTests/reAnalyze.integration.test.ts index eb3ed25d1..6f8ad61de 100644 --- a/test/integrationTests/reAnalyze.integration.test.ts +++ b/test/integrationTests/reAnalyze.integration.test.ts @@ -6,9 +6,10 @@ import * as vscode from 'vscode'; import * as path from 'path'; -import { should } from 'chai'; +import { should, expect } from 'chai'; import { activateCSharpExtension } from './integrationHelpers'; import testAssetWorkspace from './testAssets/testAssetWorkspace'; +import poll from './poll'; const chai = require('chai'); chai.use(require('chai-arrays')); @@ -37,9 +38,17 @@ suite(`ReAnalyze: ${testAssetWorkspace.description}`, function () { }); test("When interface is manually renamed, then return correct analysis after re-analysis of project", async function () { - vscode.TextEdit.replace(new vscode.Range(1, 0, 1, 100), 'foo'); - await vscode.commands.executeCommand('o.reanalyze.currentProject', interfaceUri); - // let result = await poll(() => vscode.languages.getDiagnostics(interfaceImplUri), 10*1000, 500); - // let cs8019 = result.find(x => x.message.includes("CS8019")); + await vscode.commands.executeCommand("vscode.open", interfaceUri); + + let editor = vscode.window.activeTextEditor; + + await editor.edit(editorBuilder => editorBuilder.replace(new vscode.Range(2, 0, 2, 50), 'public interface ISomeInterfaceRenamedNow')); + + await vscode.commands.executeCommand('o.reanalyze.currentProject', interfaceImplUri); + + let result = await poll(() => vscode.languages.getDiagnostics(interfaceImplUri), 10*1000, 500); + + let cs8019 = result.find(x => x.message.includes("CS8019")); + expect(cs8019).to.not.be.undefined; }); }); diff --git a/test/integrationTests/testAssets/singleCsproj/.vscode/settings.json b/test/integrationTests/testAssets/singleCsproj/.vscode/settings.json index 2dae17035..4e83a835f 100644 --- a/test/integrationTests/testAssets/singleCsproj/.vscode/settings.json +++ b/test/integrationTests/testAssets/singleCsproj/.vscode/settings.json @@ -1,4 +1,5 @@ { - "omnisharp.path": "latest", + "omnisharp.path": "C:\\Github\\omnisharp-roslyn\\bin\\Debug\\OmniSharp.Stdio.Driver\\net472\\Omnisharp.exe", + //"omnisharp.path": "latest", "omnisharp.enableRoslynAnalyzers": true } \ No newline at end of file diff --git a/test/integrationTests/testAssets/singleCsproj/ISomeInterface.cs b/test/integrationTests/testAssets/singleCsproj/ISomeInterface.cs index 4c2da47f4..0908c4ada 100644 --- a/test/integrationTests/testAssets/singleCsproj/ISomeInterface.cs +++ b/test/integrationTests/testAssets/singleCsproj/ISomeInterface.cs @@ -1,6 +1,6 @@ namespace ReAnalyze { - public interface ISomeInterface +public interface ISomeInterfaceRenamedNow { } } \ No newline at end of file diff --git a/test/integrationTests/testAssets/slnWithCsproj/.vscode/settings.json b/test/integrationTests/testAssets/slnWithCsproj/.vscode/settings.json index 21cecb392..9026ce64b 100644 --- a/test/integrationTests/testAssets/slnWithCsproj/.vscode/settings.json +++ b/test/integrationTests/testAssets/slnWithCsproj/.vscode/settings.json @@ -1,6 +1,7 @@ { "omnisharp.defaultLaunchSolution": "b_SecondInOrder_SlnFile.sln", - "omnisharp.path": "latest", + "omnisharp.path": "C:\\Github\\omnisharp-roslyn\\bin\\Debug\\OmniSharp.Stdio.Driver\\net472\\Omnisharp.exe", + //"omnisharp.path": "latest", "omnisharp.enableRoslynAnalyzers": true, "csharp.maxProjectFileCountForDiagnosticAnalysis": 1000 } \ No newline at end of file From 77ebd2fbfd8b0c1412b1afd2175d83a92dea2c45 Mon Sep 17 00:00:00 2001 From: Savpek Date: Mon, 8 Jul 2019 08:42:23 +0300 Subject: [PATCH 24/57] ISomeInterface in correct form. --- test/integrationTests/reAnalyze.integration.test.ts | 8 +++----- .../testAssets/singleCsproj/ISomeInterface.cs | 2 +- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/test/integrationTests/reAnalyze.integration.test.ts b/test/integrationTests/reAnalyze.integration.test.ts index 6f8ad61de..8e39fefa4 100644 --- a/test/integrationTests/reAnalyze.integration.test.ts +++ b/test/integrationTests/reAnalyze.integration.test.ts @@ -6,7 +6,7 @@ import * as vscode from 'vscode'; import * as path from 'path'; -import { should, expect } from 'chai'; +import { should } from 'chai'; import { activateCSharpExtension } from './integrationHelpers'; import testAssetWorkspace from './testAssets/testAssetWorkspace'; import poll from './poll'; @@ -46,9 +46,7 @@ suite(`ReAnalyze: ${testAssetWorkspace.description}`, function () { await vscode.commands.executeCommand('o.reanalyze.currentProject', interfaceImplUri); - let result = await poll(() => vscode.languages.getDiagnostics(interfaceImplUri), 10*1000, 500); - - let cs8019 = result.find(x => x.message.includes("CS8019")); - expect(cs8019).to.not.be.undefined; + await poll(() => vscode.languages.getDiagnostics(interfaceImplUri), 10*1000, 500, + r => r.find(x => x.message.includes("CS0246")) != undefined); }); }); diff --git a/test/integrationTests/testAssets/singleCsproj/ISomeInterface.cs b/test/integrationTests/testAssets/singleCsproj/ISomeInterface.cs index 0908c4ada..4c2da47f4 100644 --- a/test/integrationTests/testAssets/singleCsproj/ISomeInterface.cs +++ b/test/integrationTests/testAssets/singleCsproj/ISomeInterface.cs @@ -1,6 +1,6 @@ namespace ReAnalyze { -public interface ISomeInterfaceRenamedNow + public interface ISomeInterface { } } \ No newline at end of file From 8e39cfe89fd3c69a5ee529b9248650d41629e520 Mon Sep 17 00:00:00 2001 From: Savpek Date: Mon, 8 Jul 2019 10:17:02 +0300 Subject: [PATCH 25/57] Implemented tests based on events from analyzers. --- src/main.ts | 4 +- ....ts => BackgroundWorkStatusBarObserver.ts} | 2 +- .../reAnalyze.integration.test.ts | 49 +++++++++++++++++-- 3 files changed, 48 insertions(+), 7 deletions(-) rename src/observers/{BackgroundWorkObserver.ts => BackgroundWorkStatusBarObserver.ts} (93%) diff --git a/src/main.ts b/src/main.ts index c9e593b80..24215760c 100644 --- a/src/main.ts +++ b/src/main.ts @@ -43,7 +43,7 @@ import { downloadAndInstallPackages } from './packageManager/downloadAndInstallP import IInstallDependencies from './packageManager/IInstallDependencies'; import { installRuntimeDependencies } from './InstallRuntimeDependencies'; import { isValidDownload } from './packageManager/isValidDownload'; -import { BackgroundWorkObserver } from './observers/BackgroundWorkObserver'; +import { BackgroundWorkStatusBarObserver } from './observers/BackgroundWorkStatusBarObserver'; export async function activate(context: vscode.ExtensionContext): Promise { @@ -101,7 +101,7 @@ export async function activate(context: vscode.ExtensionContext): Promise { if(event.type == EventType.ProjectDiagnosticStatus) { diff --git a/test/integrationTests/reAnalyze.integration.test.ts b/test/integrationTests/reAnalyze.integration.test.ts index 8e39fefa4..3b206ff69 100644 --- a/test/integrationTests/reAnalyze.integration.test.ts +++ b/test/integrationTests/reAnalyze.integration.test.ts @@ -6,24 +6,43 @@ import * as vscode from 'vscode'; import * as path from 'path'; -import { should } from 'chai'; +import { should, expect } from 'chai'; import { activateCSharpExtension } from './integrationHelpers'; import testAssetWorkspace from './testAssets/testAssetWorkspace'; import poll from './poll'; +import { EventStream } from '../../src/EventStream'; +import { EventType } from '../../src/omnisharp/EventType'; +import { BaseEvent, OmnisharpProjectDiagnosticStatus } from '../../src/omnisharp/loggingEvents'; +import { DiagnosticStatus } from '../../src/omnisharp/protocol'; const chai = require('chai'); chai.use(require('chai-arrays')); chai.use(require('chai-fs')); +function listenEvents(stream: EventStream, type: EventType): T[] +{ + let results: T[] = []; + + stream.subscribe((event: BaseEvent) => { + if(event.type === type) + { + results.push(event); + } + }); + + return results; +} + suite(`ReAnalyze: ${testAssetWorkspace.description}`, function () { let interfaceUri: vscode.Uri; let interfaceImplUri: vscode.Uri; + let eventStream: EventStream; suiteSetup(async function () { should(); await testAssetWorkspace.restore(); - await activateCSharpExtension(); + eventStream = (await activateCSharpExtension()).eventStream; let projectDirectory = testAssetWorkspace.projects[0].projectDirectoryPath; interfaceUri = vscode.Uri.file(path.join(projectDirectory, 'ISomeInterface.cs')); @@ -38,6 +57,8 @@ suite(`ReAnalyze: ${testAssetWorkspace.description}`, function () { }); test("When interface is manually renamed, then return correct analysis after re-analysis of project", async function () { + let diagnosticStatusEvents = listenEvents(eventStream, EventType.ProjectDiagnosticStatus); + await vscode.commands.executeCommand("vscode.open", interfaceUri); let editor = vscode.window.activeTextEditor; @@ -46,7 +67,27 @@ suite(`ReAnalyze: ${testAssetWorkspace.description}`, function () { await vscode.commands.executeCommand('o.reanalyze.currentProject', interfaceImplUri); - await poll(() => vscode.languages.getDiagnostics(interfaceImplUri), 10*1000, 500, - r => r.find(x => x.message.includes("CS0246")) != undefined); + await poll(() => diagnosticStatusEvents, 10*1000, 500, r => r.find(x => x.message.Status === DiagnosticStatus.Ready) != undefined); + + let typeNotFoundCs = vscode.languages.getDiagnostics(interfaceImplUri).find(x => x.message.includes("CS0246")); + expect(typeNotFoundCs).to.not.be.undefined; + }); + + test("When re-analyze of project is executed then eventually get notified about them.", async function () { + let diagnosticStatusEvents = listenEvents(eventStream, EventType.ProjectDiagnosticStatus); + + await vscode.commands.executeCommand('o.reanalyze.currentProject', interfaceImplUri); + + await poll(() => diagnosticStatusEvents, 10*1000, 500, r => r.find(x => x.message.Status === DiagnosticStatus.Processing) != undefined); + await poll(() => diagnosticStatusEvents, 10*1000, 500, r => r.find(x => x.message.Status === DiagnosticStatus.Ready) != undefined); + }); + + test("When re-analyze of all projects is executed then eventually get notified about them.", async function () { + let diagnosticStatusEvents = listenEvents(eventStream, EventType.ProjectDiagnosticStatus); + + await vscode.commands.executeCommand('o.reanalyze.allProjects', interfaceImplUri); + + await poll(() => diagnosticStatusEvents, 10*1000, 500, r => r.find(x => x.message.Status === DiagnosticStatus.Processing) != undefined); + await poll(() => diagnosticStatusEvents, 10*1000, 500, r => r.find(x => x.message.Status === DiagnosticStatus.Ready) != undefined); }); }); From ddb92f4bcc57198643cf9500bb51effa22447a16 Mon Sep 17 00:00:00 2001 From: Savpek Date: Mon, 8 Jul 2019 10:19:43 +0300 Subject: [PATCH 26/57] Restored non local build for testing. --- test/integrationTests/reAnalyze.integration.test.ts | 3 +++ .../testAssets/singleCsproj/.vscode/settings.json | 3 +-- .../testAssets/slnWithCsproj/.vscode/settings.json | 3 +-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/test/integrationTests/reAnalyze.integration.test.ts b/test/integrationTests/reAnalyze.integration.test.ts index 3b206ff69..8c038938d 100644 --- a/test/integrationTests/reAnalyze.integration.test.ts +++ b/test/integrationTests/reAnalyze.integration.test.ts @@ -57,6 +57,7 @@ suite(`ReAnalyze: ${testAssetWorkspace.description}`, function () { }); test("When interface is manually renamed, then return correct analysis after re-analysis of project", async function () { + this.skip(); // Enable once background analysis is merged on omnisharp-roslyn side. let diagnosticStatusEvents = listenEvents(eventStream, EventType.ProjectDiagnosticStatus); await vscode.commands.executeCommand("vscode.open", interfaceUri); @@ -74,6 +75,7 @@ suite(`ReAnalyze: ${testAssetWorkspace.description}`, function () { }); test("When re-analyze of project is executed then eventually get notified about them.", async function () { + this.skip(); // Enable once background analysis is merged on omnisharp-roslyn side. let diagnosticStatusEvents = listenEvents(eventStream, EventType.ProjectDiagnosticStatus); await vscode.commands.executeCommand('o.reanalyze.currentProject', interfaceImplUri); @@ -83,6 +85,7 @@ suite(`ReAnalyze: ${testAssetWorkspace.description}`, function () { }); test("When re-analyze of all projects is executed then eventually get notified about them.", async function () { + this.skip(); // Enable once background analysis is merged on omnisharp-roslyn side. let diagnosticStatusEvents = listenEvents(eventStream, EventType.ProjectDiagnosticStatus); await vscode.commands.executeCommand('o.reanalyze.allProjects', interfaceImplUri); diff --git a/test/integrationTests/testAssets/singleCsproj/.vscode/settings.json b/test/integrationTests/testAssets/singleCsproj/.vscode/settings.json index 4e83a835f..2dae17035 100644 --- a/test/integrationTests/testAssets/singleCsproj/.vscode/settings.json +++ b/test/integrationTests/testAssets/singleCsproj/.vscode/settings.json @@ -1,5 +1,4 @@ { - "omnisharp.path": "C:\\Github\\omnisharp-roslyn\\bin\\Debug\\OmniSharp.Stdio.Driver\\net472\\Omnisharp.exe", - //"omnisharp.path": "latest", + "omnisharp.path": "latest", "omnisharp.enableRoslynAnalyzers": true } \ No newline at end of file diff --git a/test/integrationTests/testAssets/slnWithCsproj/.vscode/settings.json b/test/integrationTests/testAssets/slnWithCsproj/.vscode/settings.json index 9026ce64b..21cecb392 100644 --- a/test/integrationTests/testAssets/slnWithCsproj/.vscode/settings.json +++ b/test/integrationTests/testAssets/slnWithCsproj/.vscode/settings.json @@ -1,7 +1,6 @@ { "omnisharp.defaultLaunchSolution": "b_SecondInOrder_SlnFile.sln", - "omnisharp.path": "C:\\Github\\omnisharp-roslyn\\bin\\Debug\\OmniSharp.Stdio.Driver\\net472\\Omnisharp.exe", - //"omnisharp.path": "latest", + "omnisharp.path": "latest", "omnisharp.enableRoslynAnalyzers": true, "csharp.maxProjectFileCountForDiagnosticAnalysis": 1000 } \ No newline at end of file From dd0438f9bf113ae367bae60f6449546efa85b426 Mon Sep 17 00:00:00 2001 From: Savpek Date: Mon, 8 Jul 2019 10:41:34 +0300 Subject: [PATCH 27/57] Added unit tests for background work observer. --- .../BackgroundWorkStatusBarObserver.test.ts | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 test/unitTests/logging/BackgroundWorkStatusBarObserver.test.ts diff --git a/test/unitTests/logging/BackgroundWorkStatusBarObserver.test.ts b/test/unitTests/logging/BackgroundWorkStatusBarObserver.test.ts new file mode 100644 index 000000000..6e0503a58 --- /dev/null +++ b/test/unitTests/logging/BackgroundWorkStatusBarObserver.test.ts @@ -0,0 +1,43 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { expect, should } from 'chai'; +import { StatusBarItem } from '../../../src/vscodeAdapter'; +import { OmnisharpProjectDiagnosticStatus } from '../../../src/omnisharp/loggingEvents'; +import { BackgroundWorkStatusBarObserver } from '../../../src/observers/BackgroundWorkStatusBarObserver'; +import { DiagnosticStatus } from '../../../src/omnisharp/protocol'; + +suite('BackgroundWorkStatusBarObserver', () => { + suiteSetup(() => should()); + + let showCalled: boolean; + let hideCalled: boolean; + let statusBarItem = { + show: () => { showCalled = true; }, + hide: () => { hideCalled = true; } + }; + let observer = new BackgroundWorkStatusBarObserver(statusBarItem); + + setup(() => { + showCalled = false; + hideCalled = false; + }); + + test('OmnisharpProjectDiagnosticStatus.Processing: Show processing message', () => { + let event = new OmnisharpProjectDiagnosticStatus({ Status: DiagnosticStatus.Processing, ProjectFilePath: "foo.csproj", Type: "background" }); + observer.post(event); + expect(hideCalled).to.be.false; + expect(showCalled).to.be.true; + expect(statusBarItem.text).to.contain('Analyzing'); + }); + + test('OmnisharpProjectDiagnosticStatus.Ready: Hide processing message', () => { + let event = new OmnisharpProjectDiagnosticStatus({ Status: DiagnosticStatus.Ready, ProjectFilePath: "foo.csproj", Type: "background" }); + observer.post(event); + expect(hideCalled).to.be.true; + expect(showCalled).to.be.false; + expect(statusBarItem.text).to.be.undefined; + }); +}); \ No newline at end of file From 0cdec6c917bcf18d527c19fa181e78dfb207112c Mon Sep 17 00:00:00 2001 From: Savpek Date: Wed, 10 Jul 2019 09:56:01 +0300 Subject: [PATCH 28/57] Review fixes. --- src/features/diagnosticsProvider.ts | 26 +++++++++---------- .../BackgroundWorkStatusBarObserver.ts | 2 +- 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/src/features/diagnosticsProvider.ts b/src/features/diagnosticsProvider.ts index 727db04cf..0a2587930 100644 --- a/src/features/diagnosticsProvider.ts +++ b/src/features/diagnosticsProvider.ts @@ -151,14 +151,12 @@ class DiagnosticsProvider extends AbstractSupport { .asObservable() .pipe(throttleTime(3000)) .subscribe(async () => { - try { - if (this._validationAdvisor.shouldValidateAll()) { - await this._validateSmallWorkspace(); - } - else if (this._validationAdvisor.shouldValidateFiles()) { - await this._validateLargeWorkspace(); - } - } catch { } + if (this._validationAdvisor.shouldValidateAll()) { + await this._validateSmallWorkspace(); + } + else if (this._validationAdvisor.shouldValidateFiles()) { + await this._validateLargeWorkspace(); + } })); this._disposable = new CompositeDisposable(this._diagnostics, @@ -230,12 +228,12 @@ class DiagnosticsProvider extends AbstractSupport { this._validateAllPipe.next(); } - private async _validateDocument(document: vscode.TextDocument): Promise { + private _validateDocument(document: vscode.TextDocument): NodeJS.Timeout { if (!this._validationAdvisor.shouldValidateFiles()) { return; } - await setTimeout(async () => { + return setTimeout(async () => { let source = new vscode.CancellationTokenSource(); try { let value = await serverUtils.codeCheck(this._server, { FileName: document.fileName }, source.token); @@ -262,8 +260,8 @@ class DiagnosticsProvider extends AbstractSupport { // On large workspaces (if maxProjectFileCountForDiagnosticAnalysis) is less than workspace size, // diagnostic fallback to mode where only open documents are analyzed. - private async _validateLargeWorkspace(): Promise { - await setTimeout(async () => { + private _validateLargeWorkspace(): NodeJS.Timeout { + return setTimeout(async () => { for (let editor of vscode.window.visibleTextEditors) { let document = editor.document; if (this.shouldIgnoreDocument(document)) { @@ -281,8 +279,8 @@ class DiagnosticsProvider extends AbstractSupport { .filter(diagnosticInFile => diagnosticInFile !== undefined); } - private async _validateSmallWorkspace(): Promise { - await setTimeout(async () => { + private _validateSmallWorkspace(): NodeJS.Timeout { + return setTimeout(async () => { let value = await serverUtils.codeCheck(this._server, { FileName: null }, new vscode.CancellationTokenSource().token); let quickFixes = value.QuickFixes diff --git a/src/observers/BackgroundWorkStatusBarObserver.ts b/src/observers/BackgroundWorkStatusBarObserver.ts index 889405907..36be52813 100644 --- a/src/observers/BackgroundWorkStatusBarObserver.ts +++ b/src/observers/BackgroundWorkStatusBarObserver.ts @@ -10,7 +10,7 @@ import { DiagnosticStatus } from '../omnisharp/protocol'; export class BackgroundWorkStatusBarObserver extends BaseStatusBarItemObserver { public post = (event: BaseEvent) => { - if(event.type == EventType.ProjectDiagnosticStatus) + if(event.type === EventType.ProjectDiagnosticStatus) { let asProjectEvent = event; From 8c873c6163d530fd4ab95dca740d878d1408902f Mon Sep 17 00:00:00 2001 From: Savpek Date: Wed, 10 Jul 2019 10:39:07 +0300 Subject: [PATCH 29/57] Temporary enable of local build. --- .../diagnostics.integration.test.ts | 16 ++++++++++++++-- .../singleCsproj/.vscode/settings.json | 3 ++- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/test/integrationTests/diagnostics.integration.test.ts b/test/integrationTests/diagnostics.integration.test.ts index 20f07edc0..06b7b5f05 100644 --- a/test/integrationTests/diagnostics.integration.test.ts +++ b/test/integrationTests/diagnostics.integration.test.ts @@ -17,6 +17,7 @@ chai.use(require('chai-fs')); suite(`DiagnosticProvider: ${testAssetWorkspace.description}`, function () { let fileUri: vscode.Uri; + let secondaryFileUri: vscode.Uri; suiteSetup(async function () { should(); @@ -25,9 +26,11 @@ suite(`DiagnosticProvider: ${testAssetWorkspace.description}`, function () { await activateCSharpExtension(); let fileName = 'diagnostics.cs'; + let secondaryFileName = 'secondaryFileDiagnostics.cs'; let projectDirectory = testAssetWorkspace.projects[0].projectDirectoryPath; - let filePath = path.join(projectDirectory, fileName); - fileUri = vscode.Uri.file(filePath); + + fileUri = vscode.Uri.file(path.join(projectDirectory, fileName)); + secondaryFileUri = vscode.Uri.file(path.join(projectDirectory, secondaryFileName)); await vscode.commands.executeCommand("vscode.open", fileUri); }); @@ -55,4 +58,13 @@ suite(`DiagnosticProvider: ${testAssetWorkspace.description}`, function () { let ide0059 = result.find(x => x.message.includes("IDE0059")); expect(ide0059.tags).to.include(vscode.DiagnosticTag.Unnecessary); }); + + test("When workspace is count as 'large', then only return diagnostics from open documents", async function () { + let openFileDiagnostics = await poll(() => vscode.languages.getDiagnostics(fileUri), 15*1000, 500); + //let secondaryNonOpenFileDiagnostics = await vscode.languages.getDiagnostics(secondaryFileUri); + let secondaryNonOpenFileDiagnostics = await poll(() => vscode.languages.getDiagnostics(secondaryFileUri), 15*1000, 500); + + expect(openFileDiagnostics.length).to.be.greaterThan(0); + expect(secondaryNonOpenFileDiagnostics.length).to.be.eq(0); + }); }); diff --git a/test/integrationTests/testAssets/singleCsproj/.vscode/settings.json b/test/integrationTests/testAssets/singleCsproj/.vscode/settings.json index 2dae17035..adcf78f71 100644 --- a/test/integrationTests/testAssets/singleCsproj/.vscode/settings.json +++ b/test/integrationTests/testAssets/singleCsproj/.vscode/settings.json @@ -1,4 +1,5 @@ { - "omnisharp.path": "latest", + //"omnisharp.path": "latest", + "omnisharp.path": "C:\\Github\\omnisharp-roslyn\\bin\\Debug\\OmniSharp.Stdio.Driver\\net472\\Omnisharp.exe", "omnisharp.enableRoslynAnalyzers": true } \ No newline at end of file From b65fbfd6d4fb678b0ba86e305f25516f4ae92520 Mon Sep 17 00:00:00 2001 From: Savpek Date: Wed, 10 Jul 2019 11:00:38 +0300 Subject: [PATCH 30/57] Added missing file for tests. --- .../integrationTests/diagnostics.integration.test.ts | 2 +- .../testAssets/singleCsproj/secondaryDiagnostics.cs | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 test/integrationTests/testAssets/singleCsproj/secondaryDiagnostics.cs diff --git a/test/integrationTests/diagnostics.integration.test.ts b/test/integrationTests/diagnostics.integration.test.ts index 06b7b5f05..bea115091 100644 --- a/test/integrationTests/diagnostics.integration.test.ts +++ b/test/integrationTests/diagnostics.integration.test.ts @@ -26,7 +26,7 @@ suite(`DiagnosticProvider: ${testAssetWorkspace.description}`, function () { await activateCSharpExtension(); let fileName = 'diagnostics.cs'; - let secondaryFileName = 'secondaryFileDiagnostics.cs'; + let secondaryFileName = 'secondaryDiagnostics.cs'; let projectDirectory = testAssetWorkspace.projects[0].projectDirectoryPath; fileUri = vscode.Uri.file(path.join(projectDirectory, fileName)); diff --git a/test/integrationTests/testAssets/singleCsproj/secondaryDiagnostics.cs b/test/integrationTests/testAssets/singleCsproj/secondaryDiagnostics.cs new file mode 100644 index 000000000..1a866d573 --- /dev/null +++ b/test/integrationTests/testAssets/singleCsproj/secondaryDiagnostics.cs @@ -0,0 +1,12 @@ +using System.IO; + +namespace Foo +{ + public class SecondaryDiagnostics + { + public void FooBarBar() + { + var notUsed = 3; + } + } +} \ No newline at end of file From cadd127c66271449ebb95ae63dad8484ad21a17b Mon Sep 17 00:00:00 2001 From: Savpek Date: Wed, 10 Jul 2019 19:02:07 +0300 Subject: [PATCH 31/57] Added tests for small and large workspace. --- src/features/diagnosticsProvider.ts | 19 ++-- .../diagnostics.integration.test.ts | 89 +++++++++++++------ 2 files changed, 72 insertions(+), 36 deletions(-) diff --git a/src/features/diagnosticsProvider.ts b/src/features/diagnosticsProvider.ts index 0a2587930..6f5a8394d 100644 --- a/src/features/diagnosticsProvider.ts +++ b/src/features/diagnosticsProvider.ts @@ -159,15 +159,16 @@ class DiagnosticsProvider extends AbstractSupport { } })); + this._disposable = new CompositeDisposable(this._diagnostics, this._server.onPackageRestore(() => this._validateAllPipe.next(), this), this._server.onProjectChange(() => this._validateAllPipe.next(), this), this._server.onProjectDiagnosticStatus(this._onProjectAnalysis, this), - vscode.workspace.onDidOpenTextDocument(event => this._onDocumentAddOrChange(event), this), - vscode.workspace.onDidChangeTextDocument(event => this._onDocumentAddOrChange(event.document), this), - vscode.workspace.onDidCloseTextDocument(this._onDocumentRemove, this), + vscode.workspace.onDidOpenTextDocument(event => this._onDocumentOpenOrChange(event), this), + vscode.workspace.onDidChangeTextDocument(event => this._onDocumentOpenOrChange(event.document), this), + vscode.workspace.onDidCloseTextDocument(this._onDocumentClose, this), vscode.window.onDidChangeActiveTextEditor(event => this._onDidChangeActiveTextEditor(event), this), - vscode.window.onDidChangeWindowState(event => this._OnDidChangeWindowState(event), this), + vscode.window.onDidChangeWindowState(event => this._OnDidChangeWindowState(event), this,), ); } @@ -200,11 +201,11 @@ class DiagnosticsProvider extends AbstractSupport { private _onDidChangeActiveTextEditor(textEditor: vscode.TextEditor): void { // active text editor can be undefined. if (textEditor != undefined && textEditor.document != null) { - this._onDocumentAddOrChange(textEditor.document); + this._onDocumentOpenOrChange(textEditor.document); } } - private _onDocumentAddOrChange(document: vscode.TextDocument): void { + private _onDocumentOpenOrChange(document: vscode.TextDocument): void { if (this.shouldIgnoreDocument(document)) { return; } @@ -224,8 +225,10 @@ class DiagnosticsProvider extends AbstractSupport { } } - private _onDocumentRemove(document: vscode.TextDocument): void { - this._validateAllPipe.next(); + private _onDocumentClose(document: vscode.TextDocument): void { + if (this._diagnostics.has(document.uri) && !this._validationAdvisor.shouldValidateAll()) { + this._diagnostics.delete(document.uri); + } } private _validateDocument(document: vscode.TextDocument): NodeJS.Timeout { diff --git a/test/integrationTests/diagnostics.integration.test.ts b/test/integrationTests/diagnostics.integration.test.ts index bea115091..4978fbff2 100644 --- a/test/integrationTests/diagnostics.integration.test.ts +++ b/test/integrationTests/diagnostics.integration.test.ts @@ -15,6 +15,11 @@ const chai = require('chai'); chai.use(require('chai-arrays')); chai.use(require('chai-fs')); +function setDiagnosticWorkspaceLimit(to: number | null) { + let csharpConfig = vscode.workspace.getConfiguration('csharp'); + return csharpConfig.update('maxProjectFileCountForDiagnosticAnalysis', to); +} + suite(`DiagnosticProvider: ${testAssetWorkspace.description}`, function () { let fileUri: vscode.Uri; let secondaryFileUri: vscode.Uri; @@ -22,49 +27,77 @@ suite(`DiagnosticProvider: ${testAssetWorkspace.description}`, function () { suiteSetup(async function () { should(); - await testAssetWorkspace.restore(); - await activateCSharpExtension(); - let fileName = 'diagnostics.cs'; let secondaryFileName = 'secondaryDiagnostics.cs'; let projectDirectory = testAssetWorkspace.projects[0].projectDirectoryPath; fileUri = vscode.Uri.file(path.join(projectDirectory, fileName)); secondaryFileUri = vscode.Uri.file(path.join(projectDirectory, secondaryFileName)); - - await vscode.commands.executeCommand("vscode.open", fileUri); }); - suiteTeardown(async () => { - await testAssetWorkspace.cleanupWorkspace(); - }); + suite("small workspace (based on maxProjectFileCountForDiagnosticAnalysis setting)", () => { + suiteSetup(async function () { + should(); + await testAssetWorkspace.restore(); + await activateCSharpExtension(); + await vscode.commands.executeCommand("vscode.open", fileUri); + }); - test("Returns any diagnostics from file", async function () { - let result = await poll(() => vscode.languages.getDiagnostics(fileUri), 10*1000, 500); - expect(result.length).to.be.greaterThan(0); - }); + test("Returns any diagnostics from file", async function () { + let result = await poll(() => vscode.languages.getDiagnostics(fileUri), 10 * 1000, 500); + expect(result.length).to.be.greaterThan(0); + }); - test("Return unnecessary tag in case of unnesessary using", async function () { - let result = await poll(() => vscode.languages.getDiagnostics(fileUri), 15*1000, 500); + test("Return unnecessary tag in case of unnesessary using", async function () { + let result = await poll(() => vscode.languages.getDiagnostics(fileUri), 15 * 1000, 500); - let cs8019 = result.find(x => x.message.includes("CS8019")); - expect(cs8019).to.not.be.undefined; - expect(cs8019.tags).to.include(vscode.DiagnosticTag.Unnecessary); - }); + let cs8019 = result.find(x => x.message.includes("CS8019")); + expect(cs8019).to.not.be.undefined; + expect(cs8019.tags).to.include(vscode.DiagnosticTag.Unnecessary); + }); + + test("Return fadeout diagnostics like unused variables based on roslyn analyzers", async function () { + let result = await poll(() => vscode.languages.getDiagnostics(fileUri), 15 * 1000, 500, result => result.find(x => x.message.includes("IDE0059")) != undefined); - test("Return fadeout diagnostics like unused variables based on roslyn analyzers", async function () { - let result = await poll(() => vscode.languages.getDiagnostics(fileUri), 15*1000, 500, result => result.find(x => x.message.includes("IDE0059")) != undefined); + let ide0059 = result.find(x => x.message.includes("IDE0059")); + expect(ide0059.tags).to.include(vscode.DiagnosticTag.Unnecessary); + }); - let ide0059 = result.find(x => x.message.includes("IDE0059")); - expect(ide0059.tags).to.include(vscode.DiagnosticTag.Unnecessary); + test("On small workspaces also show/fetch closed document analysis results", async function () { + let result = await poll(() => vscode.languages.getDiagnostics(secondaryFileUri), 15 * 1000, 500); + + expect(result.length).to.not.greaterThan(0); + }); + + suiteTeardown(async () => { + await testAssetWorkspace.cleanupWorkspace(); + }); }); - test("When workspace is count as 'large', then only return diagnostics from open documents", async function () { - let openFileDiagnostics = await poll(() => vscode.languages.getDiagnostics(fileUri), 15*1000, 500); - //let secondaryNonOpenFileDiagnostics = await vscode.languages.getDiagnostics(secondaryFileUri); - let secondaryNonOpenFileDiagnostics = await poll(() => vscode.languages.getDiagnostics(secondaryFileUri), 15*1000, 500); + suite("large workspace (based on maxProjectFileCountForDiagnosticAnalysis setting)", () => { + suiteSetup(async function () { + should(); + await setDiagnosticWorkspaceLimit(1); + await testAssetWorkspace.restore(); + await activateCSharpExtension(); + }); + + test("When workspace is count as 'large', then only show/fetch diagnostics from open documents", async function () { + // This is to trigger manual cleanup for diagnostics before test because we modify max project file count on fly. + await vscode.commands.executeCommand("vscode.open", secondaryFileUri); + await vscode.commands.executeCommand("workbench.action.closeAllEditors"); + + await vscode.commands.executeCommand("vscode.open", fileUri); + + let openFileDiagnostics = await poll(() => vscode.languages.getDiagnostics(fileUri), 15 * 1000, 500); + let secondaryDiagnostic = await vscode.languages.getDiagnostics(secondaryFileUri); + + expect(openFileDiagnostics.length).to.be.greaterThan(0); + expect(secondaryDiagnostic.length).to.be.eq(0); + }); - expect(openFileDiagnostics.length).to.be.greaterThan(0); - expect(secondaryNonOpenFileDiagnostics.length).to.be.eq(0); + suiteTeardown(async () => { + await testAssetWorkspace.cleanupWorkspace(); + }); }); }); From 2a5c7648a567c3d8b785fc298fe32184c22e563c Mon Sep 17 00:00:00 2001 From: Savpek Date: Wed, 10 Jul 2019 19:02:49 +0300 Subject: [PATCH 32/57] Enable default build instead of local one. --- .../testAssets/singleCsproj/.vscode/settings.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/integrationTests/testAssets/singleCsproj/.vscode/settings.json b/test/integrationTests/testAssets/singleCsproj/.vscode/settings.json index adcf78f71..2dae17035 100644 --- a/test/integrationTests/testAssets/singleCsproj/.vscode/settings.json +++ b/test/integrationTests/testAssets/singleCsproj/.vscode/settings.json @@ -1,5 +1,4 @@ { - //"omnisharp.path": "latest", - "omnisharp.path": "C:\\Github\\omnisharp-roslyn\\bin\\Debug\\OmniSharp.Stdio.Driver\\net472\\Omnisharp.exe", + "omnisharp.path": "latest", "omnisharp.enableRoslynAnalyzers": true } \ No newline at end of file From 9843d19c1bf48c72ba36caa05cb064c818d130d3 Mon Sep 17 00:00:00 2001 From: Savpek Date: Wed, 10 Jul 2019 19:09:41 +0300 Subject: [PATCH 33/57] Test tweaks. --- test/integrationTests/diagnostics.integration.test.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/test/integrationTests/diagnostics.integration.test.ts b/test/integrationTests/diagnostics.integration.test.ts index 4978fbff2..ebadc5c00 100644 --- a/test/integrationTests/diagnostics.integration.test.ts +++ b/test/integrationTests/diagnostics.integration.test.ts @@ -64,6 +64,7 @@ suite(`DiagnosticProvider: ${testAssetWorkspace.description}`, function () { }); test("On small workspaces also show/fetch closed document analysis results", async function () { + this.skip(); // Enable once background analysis support is merged to omnisharp-roslyn. let result = await poll(() => vscode.languages.getDiagnostics(secondaryFileUri), 15 * 1000, 500); expect(result.length).to.not.greaterThan(0); From 77156bd7523b73bec79b3645ebebfdec5a73ad6f Mon Sep 17 00:00:00 2001 From: Savpek Date: Wed, 10 Jul 2019 19:44:39 +0300 Subject: [PATCH 34/57] Added missing test assets to sln tests. --- .../testAssets/slnWithCsproj/.vscode/settings.json | 5 ++++- .../slnWithCsproj/src/app/ISomeInterface.cs | 6 ++++++ .../slnWithCsproj/src/app/SomeInterfaceImpl.cs | 6 ++++++ .../slnWithCsproj/src/app/secondaryDiagnostics.cs | 12 ++++++++++++ 4 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 test/integrationTests/testAssets/slnWithCsproj/src/app/ISomeInterface.cs create mode 100644 test/integrationTests/testAssets/slnWithCsproj/src/app/SomeInterfaceImpl.cs create mode 100644 test/integrationTests/testAssets/slnWithCsproj/src/app/secondaryDiagnostics.cs diff --git a/test/integrationTests/testAssets/slnWithCsproj/.vscode/settings.json b/test/integrationTests/testAssets/slnWithCsproj/.vscode/settings.json index 21cecb392..397277207 100644 --- a/test/integrationTests/testAssets/slnWithCsproj/.vscode/settings.json +++ b/test/integrationTests/testAssets/slnWithCsproj/.vscode/settings.json @@ -2,5 +2,8 @@ "omnisharp.defaultLaunchSolution": "b_SecondInOrder_SlnFile.sln", "omnisharp.path": "latest", "omnisharp.enableRoslynAnalyzers": true, - "csharp.maxProjectFileCountForDiagnosticAnalysis": 1000 + "csharp.maxProjectFileCountForDiagnosticAnalysis": 1, + "csharp.referencesCodeLens.enabled": false, + "csharp.testsCodeLens.enabled": false, + "omnisharp.minFindSymbolsFilterLength": 2 } \ No newline at end of file diff --git a/test/integrationTests/testAssets/slnWithCsproj/src/app/ISomeInterface.cs b/test/integrationTests/testAssets/slnWithCsproj/src/app/ISomeInterface.cs new file mode 100644 index 000000000..4c2da47f4 --- /dev/null +++ b/test/integrationTests/testAssets/slnWithCsproj/src/app/ISomeInterface.cs @@ -0,0 +1,6 @@ +namespace ReAnalyze +{ + public interface ISomeInterface + { + } +} \ No newline at end of file diff --git a/test/integrationTests/testAssets/slnWithCsproj/src/app/SomeInterfaceImpl.cs b/test/integrationTests/testAssets/slnWithCsproj/src/app/SomeInterfaceImpl.cs new file mode 100644 index 000000000..ce6b9fa31 --- /dev/null +++ b/test/integrationTests/testAssets/slnWithCsproj/src/app/SomeInterfaceImpl.cs @@ -0,0 +1,6 @@ +namespace ReAnalyze +{ + public class SomeInterfaceImpl: ISomeInterface + { + } +} \ No newline at end of file diff --git a/test/integrationTests/testAssets/slnWithCsproj/src/app/secondaryDiagnostics.cs b/test/integrationTests/testAssets/slnWithCsproj/src/app/secondaryDiagnostics.cs new file mode 100644 index 000000000..1a866d573 --- /dev/null +++ b/test/integrationTests/testAssets/slnWithCsproj/src/app/secondaryDiagnostics.cs @@ -0,0 +1,12 @@ +using System.IO; + +namespace Foo +{ + public class SecondaryDiagnostics + { + public void FooBarBar() + { + var notUsed = 3; + } + } +} \ No newline at end of file From 87e9b3568b206354d3983f1e5834c70b357fd643 Mon Sep 17 00:00:00 2001 From: Savpek Date: Wed, 10 Jul 2019 20:01:01 +0300 Subject: [PATCH 35/57] Removed accidently added configurations. --- .../testAssets/slnWithCsproj/.vscode/settings.json | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/test/integrationTests/testAssets/slnWithCsproj/.vscode/settings.json b/test/integrationTests/testAssets/slnWithCsproj/.vscode/settings.json index 397277207..c449ec467 100644 --- a/test/integrationTests/testAssets/slnWithCsproj/.vscode/settings.json +++ b/test/integrationTests/testAssets/slnWithCsproj/.vscode/settings.json @@ -1,9 +1,5 @@ { "omnisharp.defaultLaunchSolution": "b_SecondInOrder_SlnFile.sln", "omnisharp.path": "latest", - "omnisharp.enableRoslynAnalyzers": true, - "csharp.maxProjectFileCountForDiagnosticAnalysis": 1, - "csharp.referencesCodeLens.enabled": false, - "csharp.testsCodeLens.enabled": false, - "omnisharp.minFindSymbolsFilterLength": 2 + "omnisharp.enableRoslynAnalyzers": true } \ No newline at end of file From e797bec56b1be38d84ad381a04d5beda1015f425 Mon Sep 17 00:00:00 2001 From: Savpek Date: Thu, 11 Jul 2019 07:46:04 +0300 Subject: [PATCH 36/57] Enabled skipped tests because re-analyze is merged in omnisharp-roslyn. --- package-lock.json | 13 +++++++++---- .../diagnostics.integration.test.ts | 1 - test/integrationTests/reAnalyze.integration.test.ts | 3 --- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index f118a7dd6..b1c9213c1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3608,7 +3608,8 @@ "ansi-regex": { "version": "2.1.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "aproba": { "version": "1.2.0", @@ -4023,7 +4024,8 @@ "safe-buffer": { "version": "5.1.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "safer-buffer": { "version": "2.1.2", @@ -4079,6 +4081,7 @@ "version": "3.0.1", "bundled": true, "dev": true, + "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -4122,12 +4125,14 @@ "wrappy": { "version": "1.0.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "yallist": { "version": "3.0.2", "bundled": true, - "dev": true + "dev": true, + "optional": true } } }, diff --git a/test/integrationTests/diagnostics.integration.test.ts b/test/integrationTests/diagnostics.integration.test.ts index ebadc5c00..4978fbff2 100644 --- a/test/integrationTests/diagnostics.integration.test.ts +++ b/test/integrationTests/diagnostics.integration.test.ts @@ -64,7 +64,6 @@ suite(`DiagnosticProvider: ${testAssetWorkspace.description}`, function () { }); test("On small workspaces also show/fetch closed document analysis results", async function () { - this.skip(); // Enable once background analysis support is merged to omnisharp-roslyn. let result = await poll(() => vscode.languages.getDiagnostics(secondaryFileUri), 15 * 1000, 500); expect(result.length).to.not.greaterThan(0); diff --git a/test/integrationTests/reAnalyze.integration.test.ts b/test/integrationTests/reAnalyze.integration.test.ts index 8c038938d..3b206ff69 100644 --- a/test/integrationTests/reAnalyze.integration.test.ts +++ b/test/integrationTests/reAnalyze.integration.test.ts @@ -57,7 +57,6 @@ suite(`ReAnalyze: ${testAssetWorkspace.description}`, function () { }); test("When interface is manually renamed, then return correct analysis after re-analysis of project", async function () { - this.skip(); // Enable once background analysis is merged on omnisharp-roslyn side. let diagnosticStatusEvents = listenEvents(eventStream, EventType.ProjectDiagnosticStatus); await vscode.commands.executeCommand("vscode.open", interfaceUri); @@ -75,7 +74,6 @@ suite(`ReAnalyze: ${testAssetWorkspace.description}`, function () { }); test("When re-analyze of project is executed then eventually get notified about them.", async function () { - this.skip(); // Enable once background analysis is merged on omnisharp-roslyn side. let diagnosticStatusEvents = listenEvents(eventStream, EventType.ProjectDiagnosticStatus); await vscode.commands.executeCommand('o.reanalyze.currentProject', interfaceImplUri); @@ -85,7 +83,6 @@ suite(`ReAnalyze: ${testAssetWorkspace.description}`, function () { }); test("When re-analyze of all projects is executed then eventually get notified about them.", async function () { - this.skip(); // Enable once background analysis is merged on omnisharp-roslyn side. let diagnosticStatusEvents = listenEvents(eventStream, EventType.ProjectDiagnosticStatus); await vscode.commands.executeCommand('o.reanalyze.allProjects', interfaceImplUri); From 884fa3090d5c32027ae71b41c05e946bf37ee830 Mon Sep 17 00:00:00 2001 From: Savpek Date: Thu, 11 Jul 2019 07:54:57 +0300 Subject: [PATCH 37/57] Fix for test. --- test/integrationTests/diagnostics.integration.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integrationTests/diagnostics.integration.test.ts b/test/integrationTests/diagnostics.integration.test.ts index 4978fbff2..deadfc805 100644 --- a/test/integrationTests/diagnostics.integration.test.ts +++ b/test/integrationTests/diagnostics.integration.test.ts @@ -66,7 +66,7 @@ suite(`DiagnosticProvider: ${testAssetWorkspace.description}`, function () { test("On small workspaces also show/fetch closed document analysis results", async function () { let result = await poll(() => vscode.languages.getDiagnostics(secondaryFileUri), 15 * 1000, 500); - expect(result.length).to.not.greaterThan(0); + expect(result.length).to.be.greaterThan(0); }); suiteTeardown(async () => { From 0cf278d49f844bc0fee82c66454c141efc190184 Mon Sep 17 00:00:00 2001 From: Savpek Date: Thu, 11 Jul 2019 09:33:01 +0300 Subject: [PATCH 38/57] Attempt to make tests more robust. --- .../integrationTests/diagnostics.integration.test.ts | 9 ++++++--- test/integrationTests/poll.ts | 12 ++++++------ test/integrationTests/reAnalyze.integration.test.ts | 2 +- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/test/integrationTests/diagnostics.integration.test.ts b/test/integrationTests/diagnostics.integration.test.ts index deadfc805..2a09f428b 100644 --- a/test/integrationTests/diagnostics.integration.test.ts +++ b/test/integrationTests/diagnostics.integration.test.ts @@ -79,7 +79,10 @@ suite(`DiagnosticProvider: ${testAssetWorkspace.description}`, function () { should(); await setDiagnosticWorkspaceLimit(1); await testAssetWorkspace.restore(); - await activateCSharpExtension(); + let activationResult = await activateCSharpExtension(); + + + expect(activationResult.advisor.shouldValidateAll()).to.be.false; }); test("When workspace is count as 'large', then only show/fetch diagnostics from open documents", async function () { @@ -89,8 +92,8 @@ suite(`DiagnosticProvider: ${testAssetWorkspace.description}`, function () { await vscode.commands.executeCommand("vscode.open", fileUri); - let openFileDiagnostics = await poll(() => vscode.languages.getDiagnostics(fileUri), 15 * 1000, 500); - let secondaryDiagnostic = await vscode.languages.getDiagnostics(secondaryFileUri); + let openFileDiagnostics = await poll(() => vscode.languages.getDiagnostics(fileUri), 10 * 1000, 500); + let secondaryDiagnostic = await poll(() => vscode.languages.getDiagnostics(secondaryFileUri), 10 * 1000, 500, x => x.length === 0); expect(openFileDiagnostics.length).to.be.greaterThan(0); expect(secondaryDiagnostic.length).to.be.eq(0); diff --git a/test/integrationTests/poll.ts b/test/integrationTests/poll.ts index 8c2616bc1..25e865134 100644 --- a/test/integrationTests/poll.ts +++ b/test/integrationTests/poll.ts @@ -3,15 +3,15 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -export default async function poll(getValue: () => T, duration: number, step: number, expression: (input: T) => boolean = _ => true): Promise { +export default async function poll( + getValue: () => T, + duration: number, + step: number, + expression: (input: T) => boolean = x => x !== undefined && ((Array.isArray(x) && x.length > 0) || !Array.isArray(x))): Promise { while (duration > 0) { let value = await getValue(); - if(Array.isArray(value) && value.length > 0 && expression(value)) { - return value; - } - - if (!Array.isArray(value) && value && expression(value)) { + if(expression(value)) { return value; } diff --git a/test/integrationTests/reAnalyze.integration.test.ts b/test/integrationTests/reAnalyze.integration.test.ts index 3b206ff69..6a47e91fd 100644 --- a/test/integrationTests/reAnalyze.integration.test.ts +++ b/test/integrationTests/reAnalyze.integration.test.ts @@ -67,7 +67,7 @@ suite(`ReAnalyze: ${testAssetWorkspace.description}`, function () { await vscode.commands.executeCommand('o.reanalyze.currentProject', interfaceImplUri); - await poll(() => diagnosticStatusEvents, 10*1000, 500, r => r.find(x => x.message.Status === DiagnosticStatus.Ready) != undefined); + await poll(() => diagnosticStatusEvents, 10*1000, 500, r => r.find(x => x.message.Status === DiagnosticStatus.Ready) !== undefined); let typeNotFoundCs = vscode.languages.getDiagnostics(interfaceImplUri).find(x => x.message.includes("CS0246")); expect(typeNotFoundCs).to.not.be.undefined; From 4d6e2ac0854c42e052ccdf81b4b7c4d69f34ef10 Mon Sep 17 00:00:00 2001 From: Savpek Date: Thu, 11 Jul 2019 10:43:30 +0300 Subject: [PATCH 39/57] Added poll with better messages and improved cleanup robustness. --- .vscode/settings.json | 3 +- .../diagnostics.integration.test.ts | 14 ++--- .../launchConfiguration.integration.test.ts | 5 +- test/integrationTests/poll.ts | 59 ++++++++++++++++--- .../reAnalyze.integration.test.ts | 2 + .../integrationTests/testAssets/testAssets.ts | 21 +++++-- 6 files changed, 81 insertions(+), 23 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index bf86be1b4..f32fb78fb 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -18,5 +18,6 @@ "tslint.rulesDirectory": "node_modules/tslint-microsoft-contrib", "typescript.tsdk": "./node_modules/typescript/lib", - "mocha.enabled": true + "mocha.enabled": true, + "omnisharp.autoStart": false } \ No newline at end of file diff --git a/test/integrationTests/diagnostics.integration.test.ts b/test/integrationTests/diagnostics.integration.test.ts index 2a09f428b..1d3813010 100644 --- a/test/integrationTests/diagnostics.integration.test.ts +++ b/test/integrationTests/diagnostics.integration.test.ts @@ -9,7 +9,7 @@ import * as path from 'path'; import { should, expect } from 'chai'; import { activateCSharpExtension } from './integrationHelpers'; import testAssetWorkspace from './testAssets/testAssetWorkspace'; -import poll from './poll'; +import poll, { assertWithPoll } from './poll'; const chai = require('chai'); chai.use(require('chai-arrays')); @@ -44,8 +44,8 @@ suite(`DiagnosticProvider: ${testAssetWorkspace.description}`, function () { }); test("Returns any diagnostics from file", async function () { - let result = await poll(() => vscode.languages.getDiagnostics(fileUri), 10 * 1000, 500); - expect(result.length).to.be.greaterThan(0); + await assertWithPoll(() => vscode.languages.getDiagnostics(fileUri), 10 * 1000, 500, + res => expect(res.length).to.be.greaterThan(0)); }); test("Return unnecessary tag in case of unnesessary using", async function () { @@ -64,9 +64,7 @@ suite(`DiagnosticProvider: ${testAssetWorkspace.description}`, function () { }); test("On small workspaces also show/fetch closed document analysis results", async function () { - let result = await poll(() => vscode.languages.getDiagnostics(secondaryFileUri), 15 * 1000, 500); - - expect(result.length).to.be.greaterThan(0); + await assertWithPoll(() => vscode.languages.getDiagnostics(secondaryFileUri), 15 * 1000, 500, res => expect(res.length).to.be.greaterThan(0)); }); suiteTeardown(async () => { @@ -77,6 +75,7 @@ suite(`DiagnosticProvider: ${testAssetWorkspace.description}`, function () { suite("large workspace (based on maxProjectFileCountForDiagnosticAnalysis setting)", () => { suiteSetup(async function () { should(); + await testAssetWorkspace.cleanupWorkspace(); await setDiagnosticWorkspaceLimit(1); await testAssetWorkspace.restore(); let activationResult = await activateCSharpExtension(); @@ -93,10 +92,9 @@ suite(`DiagnosticProvider: ${testAssetWorkspace.description}`, function () { await vscode.commands.executeCommand("vscode.open", fileUri); let openFileDiagnostics = await poll(() => vscode.languages.getDiagnostics(fileUri), 10 * 1000, 500); - let secondaryDiagnostic = await poll(() => vscode.languages.getDiagnostics(secondaryFileUri), 10 * 1000, 500, x => x.length === 0); + await assertWithPoll(() => vscode.languages.getDiagnostics(secondaryFileUri), 10 * 1000, 500, secondaryDiag => expect(secondaryDiag.length).to.be.eq(0)); expect(openFileDiagnostics.length).to.be.greaterThan(0); - expect(secondaryDiagnostic.length).to.be.eq(0); }); suiteTeardown(async () => { diff --git a/test/integrationTests/launchConfiguration.integration.test.ts b/test/integrationTests/launchConfiguration.integration.test.ts index ad7e59fb5..7a60d24fa 100644 --- a/test/integrationTests/launchConfiguration.integration.test.ts +++ b/test/integrationTests/launchConfiguration.integration.test.ts @@ -31,15 +31,14 @@ suite(`Tasks generation: ${testAssetWorkspace.description}`, function () { }); test("Starting .NET Core Launch (console) from the workspace root should create an Active Debug Session", async () => { - vscode.debug.onDidChangeActiveDebugSession((e) => { expect(vscode.debug.activeDebugSession).not.to.be.undefined; expect(vscode.debug.activeDebugSession.type).to.equal("coreclr"); }); - + let result = await vscode.debug.startDebugging(vscode.workspace.workspaceFolders[0], ".NET Core Launch (console)"); expect(result, "Debugger could not be started."); - + let debugSessionTerminated = new Promise(resolve => { vscode.debug.onDidTerminateDebugSession((e) => resolve()); }); diff --git a/test/integrationTests/poll.ts b/test/integrationTests/poll.ts index 25e865134..1cbb66a24 100644 --- a/test/integrationTests/poll.ts +++ b/test/integrationTests/poll.ts @@ -1,17 +1,62 @@ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ + *--------------------------------------------------------------------------------------------*/ + +function defaultAssertion(value: T): void { + if (value === undefined) { + throw "Default assertion of poll: Excepted value not to be undefined."; + } + + if (Array.isArray(value) && value.length === 0) { + throw "Default assertion of poll: Value was array but it got length of '0'."; + } +} + +export async function assertWithPoll( + getValue: () => T, + duration: number, + step: number, + assertForValue: (input: T) => void = defaultAssertion): Promise { + + let assertResult: Error = undefined; + + while (duration > 0) { + let value = await getValue(); + + try { + assertResult = undefined; + assertForValue(value); + } catch (error) { + assertResult = error; + } + + if (assertResult === undefined) { + return; + } + + await sleep(step); + + duration -= step; + } + + throw assertResult; +} + +function defaultPollExpression(value: T): boolean +{ + return value !== undefined && ((Array.isArray(value) && value.length > 0) || !Array.isArray(value)); +} export default async function poll( - getValue: () => T, - duration: number, - step: number, - expression: (input: T) => boolean = x => x !== undefined && ((Array.isArray(x) && x.length > 0) || !Array.isArray(x))): Promise { + getValue: () => T, + duration: number, + step: number, + expression: (input: T) => boolean = defaultPollExpression): Promise { while (duration > 0) { let value = await getValue(); - if(expression(value)) { + if (expression(value)) { return value; } @@ -23,6 +68,6 @@ export default async function poll( throw new Error("Polling did not succeed within the alotted duration."); } -async function sleep(ms = 0) { +function sleep(ms = 0) { return new Promise(r => setTimeout(r, ms)); } \ No newline at end of file diff --git a/test/integrationTests/reAnalyze.integration.test.ts b/test/integrationTests/reAnalyze.integration.test.ts index 6a47e91fd..6616f0108 100644 --- a/test/integrationTests/reAnalyze.integration.test.ts +++ b/test/integrationTests/reAnalyze.integration.test.ts @@ -41,6 +41,8 @@ suite(`ReAnalyze: ${testAssetWorkspace.description}`, function () { suiteSetup(async function () { should(); + await testAssetWorkspace.cleanupWorkspace(); + await testAssetWorkspace.restore(); eventStream = (await activateCSharpExtension()).eventStream; diff --git a/test/integrationTests/testAssets/testAssets.ts b/test/integrationTests/testAssets/testAssets.ts index bec85518e..83129f62a 100644 --- a/test/integrationTests/testAssets/testAssets.ts +++ b/test/integrationTests/testAssets/testAssets.ts @@ -77,10 +77,23 @@ export class TestAssetWorkspace { } async cleanupWorkspace(): Promise { - for (let project of this.projects) { - let wd = project.projectDirectoryPath; - await spawnGit(["clean", "-xdf", "."], { cwd: wd }); - await spawnGit(["checkout", "--", "."], { cwd: wd }); + let cleanUpRoutine = async () => + { + for (let project of this.projects) { + let wd = project.projectDirectoryPath; + await spawnGit(["clean", "-xdf", "."], { cwd: wd }); + await spawnGit(["checkout", "--", "."], { cwd: wd }); + } + }; + + let sleep = () => new Promise((resolve) => setTimeout(resolve, 2*1000)); + + try { + await cleanUpRoutine(); + } catch (error) { + // Its possible that cleanup fails for locked files etc, for this reason retry is added. + await sleep(); + await cleanUpRoutine(); } } From 674273f44571e1ac74fc694bf892044900495cb4 Mon Sep 17 00:00:00 2001 From: Savpek Date: Thu, 11 Jul 2019 11:27:51 +0300 Subject: [PATCH 40/57] Made robuster version of restore routine during testing. --- test/integrationTests/advisor.integration.test.ts | 2 +- .../codeActionRename.integration.test.ts | 2 +- .../codeLensProvider.integration.test.ts | 4 ++-- .../completionItemProvider.integration.test.ts | 2 +- .../diagnostics.integration.test.ts | 14 +++----------- .../documentSymbolProvider.integration.test.ts | 2 +- .../hoverProvider.integration.test.ts | 2 +- .../implementationProvider.test.ts | 2 +- .../launchConfiguration.integration.test.ts | 4 ++-- .../integrationTests/reAnalyze.integration.test.ts | 5 +---- test/integrationTests/referenceProvider.test.ts | 2 +- .../signatureHelp.integration.test.ts | 2 +- test/integrationTests/testAssets/testAssets.ts | 10 +++------- .../virtualDocumentTracker.integration.test.ts | 2 +- .../workspaceSymbolProvider.integration.test.ts | 2 +- 15 files changed, 21 insertions(+), 36 deletions(-) diff --git a/test/integrationTests/advisor.integration.test.ts b/test/integrationTests/advisor.integration.test.ts index c899872ee..6ace0fdaf 100644 --- a/test/integrationTests/advisor.integration.test.ts +++ b/test/integrationTests/advisor.integration.test.ts @@ -25,8 +25,8 @@ suite(`Advisor ${testAssetWorkspace.description}`, function () { let advisor: Advisor; suiteSetup(async function () { - await testAssetWorkspace.restore(); let activationResult = await activateCSharpExtension(); + await testAssetWorkspace.restore(); if (!activationResult) { throw new Error('Cannot activate extension.'); } else { diff --git a/test/integrationTests/codeActionRename.integration.test.ts b/test/integrationTests/codeActionRename.integration.test.ts index ef3d1437f..b834805ab 100644 --- a/test/integrationTests/codeActionRename.integration.test.ts +++ b/test/integrationTests/codeActionRename.integration.test.ts @@ -19,8 +19,8 @@ suite(`Code Action Rename ${testAssetWorkspace.description}`, function () { suiteSetup(async function () { should(); - await testAssetWorkspace.restore(); await activateCSharpExtension(); + await testAssetWorkspace.restore(); let fileName = 'A.cs'; let projectDirectory = testAssetWorkspace.projects[0].projectDirectoryPath; diff --git a/test/integrationTests/codeLensProvider.integration.test.ts b/test/integrationTests/codeLensProvider.integration.test.ts index 30ed9b476..0a1fd1dee 100644 --- a/test/integrationTests/codeLensProvider.integration.test.ts +++ b/test/integrationTests/codeLensProvider.integration.test.ts @@ -19,8 +19,8 @@ suite(`CodeLensProvider: ${testAssetWorkspace.description}`, function () { suiteSetup(async function () { should(); - await testAssetWorkspace.restore(); await activateCSharpExtension(); + await testAssetWorkspace.restore(); let fileName = 'Program.cs'; let projectDirectory = testAssetWorkspace.projects[0].projectDirectoryPath; @@ -72,8 +72,8 @@ suite(`CodeLensProvider options: ${testAssetWorkspace.description}`, function() } else { - await testAssetWorkspace.restore(); await activateCSharpExtension(); + await testAssetWorkspace.restore(); let fileName = 'UnitTest1.cs'; let projectDirectory = testAssetWorkspace.projects[2].projectDirectoryPath; diff --git a/test/integrationTests/completionItemProvider.integration.test.ts b/test/integrationTests/completionItemProvider.integration.test.ts index 34a9189b6..1b142c3d3 100644 --- a/test/integrationTests/completionItemProvider.integration.test.ts +++ b/test/integrationTests/completionItemProvider.integration.test.ts @@ -14,8 +14,8 @@ suite(`${OmniSharpCompletionItemProvider.name}: Returns the completion items`, ( let fileUri: vscode.Uri; suiteSetup(async () => { - await testAssetWorkspace.restore(); await activateCSharpExtension(); + await testAssetWorkspace.restore(); let fileName = 'completion.cs'; let dir = testAssetWorkspace.projects[0].projectDirectoryPath; diff --git a/test/integrationTests/diagnostics.integration.test.ts b/test/integrationTests/diagnostics.integration.test.ts index 1d3813010..df78bddb5 100644 --- a/test/integrationTests/diagnostics.integration.test.ts +++ b/test/integrationTests/diagnostics.integration.test.ts @@ -38,8 +38,8 @@ suite(`DiagnosticProvider: ${testAssetWorkspace.description}`, function () { suite("small workspace (based on maxProjectFileCountForDiagnosticAnalysis setting)", () => { suiteSetup(async function () { should(); - await testAssetWorkspace.restore(); await activateCSharpExtension(); + await testAssetWorkspace.restore(); await vscode.commands.executeCommand("vscode.open", fileUri); }); @@ -75,26 +75,18 @@ suite(`DiagnosticProvider: ${testAssetWorkspace.description}`, function () { suite("large workspace (based on maxProjectFileCountForDiagnosticAnalysis setting)", () => { suiteSetup(async function () { should(); - await testAssetWorkspace.cleanupWorkspace(); await setDiagnosticWorkspaceLimit(1); await testAssetWorkspace.restore(); - let activationResult = await activateCSharpExtension(); - - - expect(activationResult.advisor.shouldValidateAll()).to.be.false; + await activateCSharpExtension(); }); test("When workspace is count as 'large', then only show/fetch diagnostics from open documents", async function () { // This is to trigger manual cleanup for diagnostics before test because we modify max project file count on fly. await vscode.commands.executeCommand("vscode.open", secondaryFileUri); - await vscode.commands.executeCommand("workbench.action.closeAllEditors"); - await vscode.commands.executeCommand("vscode.open", fileUri); - let openFileDiagnostics = await poll(() => vscode.languages.getDiagnostics(fileUri), 10 * 1000, 500); + await assertWithPoll(() => vscode.languages.getDiagnostics(fileUri), 10 * 1000, 500, openFileDiag => expect(openFileDiag.length).to.be.greaterThan(0)); await assertWithPoll(() => vscode.languages.getDiagnostics(secondaryFileUri), 10 * 1000, 500, secondaryDiag => expect(secondaryDiag.length).to.be.eq(0)); - - expect(openFileDiagnostics.length).to.be.greaterThan(0); }); suiteTeardown(async () => { diff --git a/test/integrationTests/documentSymbolProvider.integration.test.ts b/test/integrationTests/documentSymbolProvider.integration.test.ts index 2abd2c4e5..9552aecb5 100644 --- a/test/integrationTests/documentSymbolProvider.integration.test.ts +++ b/test/integrationTests/documentSymbolProvider.integration.test.ts @@ -19,8 +19,8 @@ suite(`DocumentSymbolProvider: ${testAssetWorkspace.description}`, function () { suiteSetup(async function () { should(); - await testAssetWorkspace.restore(); await activateCSharpExtension(); + await testAssetWorkspace.restore(); let fileName = 'documentSymbols.cs'; let projectDirectory = testAssetWorkspace.projects[0].projectDirectoryPath; diff --git a/test/integrationTests/hoverProvider.integration.test.ts b/test/integrationTests/hoverProvider.integration.test.ts index c1bd5b739..bac3d85d0 100644 --- a/test/integrationTests/hoverProvider.integration.test.ts +++ b/test/integrationTests/hoverProvider.integration.test.ts @@ -17,8 +17,8 @@ chai.use(require('chai-fs')); suite(`Hover Provider: ${testAssetWorkspace.description}`, function () { suiteSetup(async function () { should(); - await testAssetWorkspace.restore(); await activateCSharpExtension(); + await testAssetWorkspace.restore(); }); suiteTeardown(async () => { diff --git a/test/integrationTests/implementationProvider.test.ts b/test/integrationTests/implementationProvider.test.ts index d7074d983..4f09a08b4 100644 --- a/test/integrationTests/implementationProvider.test.ts +++ b/test/integrationTests/implementationProvider.test.ts @@ -14,8 +14,8 @@ suite(`${CSharpImplementationProvider.name}: ${testAssetWorkspace.description}`, let fileUri: vscode.Uri; suiteSetup(async () => { - await testAssetWorkspace.restore(); await activateCSharpExtension(); + await testAssetWorkspace.restore(); let fileName = 'implementation.cs'; let projectDirectory = testAssetWorkspace.projects[0].projectDirectoryPath; diff --git a/test/integrationTests/launchConfiguration.integration.test.ts b/test/integrationTests/launchConfiguration.integration.test.ts index 7a60d24fa..ecf8e2d34 100644 --- a/test/integrationTests/launchConfiguration.integration.test.ts +++ b/test/integrationTests/launchConfiguration.integration.test.ts @@ -18,12 +18,12 @@ chai.use(require('chai-fs')); suite(`Tasks generation: ${testAssetWorkspace.description}`, function () { suiteSetup(async function () { should(); - await testAssetWorkspace.restore(); await activateCSharpExtension(); + await testAssetWorkspace.restore(); await vscode.commands.executeCommand("dotnet.generateAssets", 0); - await poll(async () => await fs.exists(testAssetWorkspace.launchJsonPath), 10000, 100); + await poll(() => fs.exists(testAssetWorkspace.launchJsonPath), 10000, 100); }); suiteTeardown(async () => { diff --git a/test/integrationTests/reAnalyze.integration.test.ts b/test/integrationTests/reAnalyze.integration.test.ts index 6616f0108..29d475a2a 100644 --- a/test/integrationTests/reAnalyze.integration.test.ts +++ b/test/integrationTests/reAnalyze.integration.test.ts @@ -40,11 +40,8 @@ suite(`ReAnalyze: ${testAssetWorkspace.description}`, function () { suiteSetup(async function () { should(); - - await testAssetWorkspace.cleanupWorkspace(); - - await testAssetWorkspace.restore(); eventStream = (await activateCSharpExtension()).eventStream; + await testAssetWorkspace.restore(); let projectDirectory = testAssetWorkspace.projects[0].projectDirectoryPath; interfaceUri = vscode.Uri.file(path.join(projectDirectory, 'ISomeInterface.cs')); diff --git a/test/integrationTests/referenceProvider.test.ts b/test/integrationTests/referenceProvider.test.ts index 387272303..a64bfd7cd 100644 --- a/test/integrationTests/referenceProvider.test.ts +++ b/test/integrationTests/referenceProvider.test.ts @@ -14,8 +14,8 @@ suite(`${OmnisharpReferenceProvider.name}: ${testAssetWorkspace.description}`, ( let fileUri: vscode.Uri; suiteSetup(async () => { - await testAssetWorkspace.restore(); await activateCSharpExtension(); + await testAssetWorkspace.restore(); let fileName = 'reference.cs'; let projectDirectory = testAssetWorkspace.projects[0].projectDirectoryPath; diff --git a/test/integrationTests/signatureHelp.integration.test.ts b/test/integrationTests/signatureHelp.integration.test.ts index 48b3a8ef4..bab386e6b 100644 --- a/test/integrationTests/signatureHelp.integration.test.ts +++ b/test/integrationTests/signatureHelp.integration.test.ts @@ -18,8 +18,8 @@ suite(`SignatureHelp: ${testAssetWorkspace.description}`, function () { let fileUri: vscode.Uri; suiteSetup(async function () { - await testAssetWorkspace.restore(); await activateCSharpExtension(); + await testAssetWorkspace.restore(); let fileName = 'sigHelp.cs'; let dir = testAssetWorkspace.projects[0].projectDirectoryPath; diff --git a/test/integrationTests/testAssets/testAssets.ts b/test/integrationTests/testAssets/testAssets.ts index 83129f62a..c505ef310 100644 --- a/test/integrationTests/testAssets/testAssets.ts +++ b/test/integrationTests/testAssets/testAssets.ts @@ -7,8 +7,6 @@ import * as fs from 'async-file'; import * as path from 'path'; import * as vscode from 'vscode'; import spawnGit from './spawnGit'; -import { dotnetRestore } from '../../../src/features/commands'; -import { EventStream } from '../../../src/EventStream'; export class TestAssetProject { constructor(project: ITestAssetProject) { @@ -35,10 +33,6 @@ export class TestAssetProject { await fs.rimraf(this.objDirectoryPath); } - async restore(): Promise { - await dotnetRestore(this.projectDirectoryPath, new EventStream()); - } - async addFileWithContents(fileName: string, contents: string): Promise { let dir = this.projectDirectoryPath; let loc = path.join(dir, fileName); @@ -61,7 +55,7 @@ export class TestAssetWorkspace { } async restore(): Promise { - this.projects.forEach(async p => await p.restore()); + await vscode.commands.executeCommand("dotnet.restore.all"); } get vsCodeDirectoryPath(): string { @@ -79,6 +73,8 @@ export class TestAssetWorkspace { async cleanupWorkspace(): Promise { let cleanUpRoutine = async () => { + await vscode.commands.executeCommand("workbench.action.closeAllEditors"); + for (let project of this.projects) { let wd = project.projectDirectoryPath; await spawnGit(["clean", "-xdf", "."], { cwd: wd }); diff --git a/test/integrationTests/virtualDocumentTracker.integration.test.ts b/test/integrationTests/virtualDocumentTracker.integration.test.ts index 6a467d405..1afc8d5d3 100644 --- a/test/integrationTests/virtualDocumentTracker.integration.test.ts +++ b/test/integrationTests/virtualDocumentTracker.integration.test.ts @@ -20,8 +20,8 @@ suite(`Virtual Document Tracking ${testAssetWorkspace.description}`, function () suiteSetup(async function () { should(); - await testAssetWorkspace.restore(); await activateCSharpExtension(); + await testAssetWorkspace.restore(); let virtualCSharpDocumentProvider = new VirtualCSharpDocumentProvider(); virtualDocumentRegistration = vscode.workspace.registerTextDocumentContentProvider(virtualScheme, virtualCSharpDocumentProvider); diff --git a/test/integrationTests/workspaceSymbolProvider.integration.test.ts b/test/integrationTests/workspaceSymbolProvider.integration.test.ts index e522968fe..4b1508ca2 100644 --- a/test/integrationTests/workspaceSymbolProvider.integration.test.ts +++ b/test/integrationTests/workspaceSymbolProvider.integration.test.ts @@ -14,8 +14,8 @@ chai.use(require('chai-fs')); suite(`WorkspaceSymbolProvider: ${testAssetWorkspace.description}`, function () { suiteSetup(async function () { - await testAssetWorkspace.restore(); await activateCSharpExtension(); + await testAssetWorkspace.restore(); let projectDirectory = vscode.Uri.file(testAssetWorkspace.projects[0].projectDirectoryPath); await vscode.commands.executeCommand("vscode.open", projectDirectory); }); From e03e2807ea6f637f7e92a5bb7221e629c88eaca3 Mon Sep 17 00:00:00 2001 From: Savpek Date: Thu, 11 Jul 2019 11:56:44 +0300 Subject: [PATCH 41/57] Fixes for git cleanup. --- test/integrationTests/testAssets/spawnGit.ts | 8 +++--- .../integrationTests/testAssets/testAssets.ts | 25 ++----------------- 2 files changed, 6 insertions(+), 27 deletions(-) diff --git a/test/integrationTests/testAssets/spawnGit.ts b/test/integrationTests/testAssets/spawnGit.ts index f407e6e18..8944baaac 100644 --- a/test/integrationTests/testAssets/spawnGit.ts +++ b/test/integrationTests/testAssets/spawnGit.ts @@ -14,7 +14,7 @@ export default async function spawnGit(args?: string[], options?: SpawnOptions): env: {} }; } - + let optionsWithFullEnvironment = { ...options, env: { @@ -22,11 +22,11 @@ export default async function spawnGit(args?: string[], options?: SpawnOptions): ...options.env } }; - + let spawned = spawn('git', args, optionsWithFullEnvironment); - //spawned.stdout.on('data', (data) => console.log(data.toString())); - //spawned.stderr.on('data', (data) => console.log(data.toString())); + spawned.stdout.on('data', (data) => console.log(data.toString())); + spawned.stderr.on('data', (data) => console.log(data.toString())); return join(spawned); } \ No newline at end of file diff --git a/test/integrationTests/testAssets/testAssets.ts b/test/integrationTests/testAssets/testAssets.ts index c505ef310..2d4af87eb 100644 --- a/test/integrationTests/testAssets/testAssets.ts +++ b/test/integrationTests/testAssets/testAssets.ts @@ -20,19 +20,6 @@ export class TestAssetProject { path.dirname(this.relativeFilePath)); } - get binDirectoryPath(): string { - return path.join(this.projectDirectoryPath, 'bin'); - } - - get objDirectoryPath(): string { - return path.join(this.projectDirectoryPath, 'obj'); - } - - async deleteBuildArtifacts(): Promise { - await fs.rimraf(this.binDirectoryPath); - await fs.rimraf(this.objDirectoryPath); - } - async addFileWithContents(fileName: string, contents: string): Promise { let dir = this.projectDirectoryPath; let loc = path.join(dir, fileName); @@ -50,10 +37,6 @@ export class TestAssetWorkspace { this.description = workspace.description; } - async deleteBuildArtifacts(): Promise { - this.projects.forEach(async p => await p.deleteBuildArtifacts()); - } - async restore(): Promise { await vscode.commands.executeCommand("dotnet.restore.all"); } @@ -74,12 +57,8 @@ export class TestAssetWorkspace { let cleanUpRoutine = async () => { await vscode.commands.executeCommand("workbench.action.closeAllEditors"); - - for (let project of this.projects) { - let wd = project.projectDirectoryPath; - await spawnGit(["clean", "-xdf", "."], { cwd: wd }); - await spawnGit(["checkout", "--", "."], { cwd: wd }); - } + await spawnGit(["clean", "-xdf", "."], { cwd: vscode.workspace.rootPath }); + await spawnGit(["checkout", "--", "."], { cwd: vscode.workspace.rootPath }); }; let sleep = () => new Promise((resolve) => setTimeout(resolve, 2*1000)); From 0148843166c79ed8ca7addca7d331294964e3c2e Mon Sep 17 00:00:00 2001 From: Savpek Date: Thu, 11 Jul 2019 12:27:31 +0300 Subject: [PATCH 42/57] Testing if travis is just slow during tests. --- test/integrationTests/reAnalyze.integration.test.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test/integrationTests/reAnalyze.integration.test.ts b/test/integrationTests/reAnalyze.integration.test.ts index 29d475a2a..afef9b083 100644 --- a/test/integrationTests/reAnalyze.integration.test.ts +++ b/test/integrationTests/reAnalyze.integration.test.ts @@ -66,7 +66,7 @@ suite(`ReAnalyze: ${testAssetWorkspace.description}`, function () { await vscode.commands.executeCommand('o.reanalyze.currentProject', interfaceImplUri); - await poll(() => diagnosticStatusEvents, 10*1000, 500, r => r.find(x => x.message.Status === DiagnosticStatus.Ready) !== undefined); + await poll(() => diagnosticStatusEvents, 15*1000, 500, r => r.find(x => x.message.Status === DiagnosticStatus.Ready) !== undefined); let typeNotFoundCs = vscode.languages.getDiagnostics(interfaceImplUri).find(x => x.message.includes("CS0246")); expect(typeNotFoundCs).to.not.be.undefined; @@ -77,8 +77,8 @@ suite(`ReAnalyze: ${testAssetWorkspace.description}`, function () { await vscode.commands.executeCommand('o.reanalyze.currentProject', interfaceImplUri); - await poll(() => diagnosticStatusEvents, 10*1000, 500, r => r.find(x => x.message.Status === DiagnosticStatus.Processing) != undefined); - await poll(() => diagnosticStatusEvents, 10*1000, 500, r => r.find(x => x.message.Status === DiagnosticStatus.Ready) != undefined); + await poll(() => diagnosticStatusEvents, 15*1000, 500, r => r.find(x => x.message.Status === DiagnosticStatus.Processing) != undefined); + await poll(() => diagnosticStatusEvents, 15*1000, 500, r => r.find(x => x.message.Status === DiagnosticStatus.Ready) != undefined); }); test("When re-analyze of all projects is executed then eventually get notified about them.", async function () { @@ -86,7 +86,7 @@ suite(`ReAnalyze: ${testAssetWorkspace.description}`, function () { await vscode.commands.executeCommand('o.reanalyze.allProjects', interfaceImplUri); - await poll(() => diagnosticStatusEvents, 10*1000, 500, r => r.find(x => x.message.Status === DiagnosticStatus.Processing) != undefined); - await poll(() => diagnosticStatusEvents, 10*1000, 500, r => r.find(x => x.message.Status === DiagnosticStatus.Ready) != undefined); + await poll(() => diagnosticStatusEvents, 15*1000, 500, r => r.find(x => x.message.Status === DiagnosticStatus.Processing) != undefined); + await poll(() => diagnosticStatusEvents, 15*1000, 500, r => r.find(x => x.message.Status === DiagnosticStatus.Ready) != undefined); }); }); From d8b9d4f04af2b7597fecf737b6df96fe3592891e Mon Sep 17 00:00:00 2001 From: Savpek Date: Thu, 11 Jul 2019 12:28:14 +0300 Subject: [PATCH 43/57] Disabled git logging. --- test/integrationTests/testAssets/spawnGit.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/integrationTests/testAssets/spawnGit.ts b/test/integrationTests/testAssets/spawnGit.ts index 8944baaac..65ba73994 100644 --- a/test/integrationTests/testAssets/spawnGit.ts +++ b/test/integrationTests/testAssets/spawnGit.ts @@ -25,8 +25,8 @@ export default async function spawnGit(args?: string[], options?: SpawnOptions): let spawned = spawn('git', args, optionsWithFullEnvironment); - spawned.stdout.on('data', (data) => console.log(data.toString())); - spawned.stderr.on('data', (data) => console.log(data.toString())); + //spawned.stdout.on('data', (data) => console.log(data.toString())); + //spawned.stderr.on('data', (data) => console.log(data.toString())); return join(spawned); } \ No newline at end of file From 9c20469f25fa08a1c7b97ff1ccbc84feb8283cb2 Mon Sep 17 00:00:00 2001 From: Savpek Date: Thu, 11 Jul 2019 12:46:54 +0300 Subject: [PATCH 44/57] Expect that after diagnostic event there may be throttling before diagnostics are available. --- test/integrationTests/reAnalyze.integration.test.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/test/integrationTests/reAnalyze.integration.test.ts b/test/integrationTests/reAnalyze.integration.test.ts index afef9b083..473893f41 100644 --- a/test/integrationTests/reAnalyze.integration.test.ts +++ b/test/integrationTests/reAnalyze.integration.test.ts @@ -9,7 +9,7 @@ import * as path from 'path'; import { should, expect } from 'chai'; import { activateCSharpExtension } from './integrationHelpers'; import testAssetWorkspace from './testAssets/testAssetWorkspace'; -import poll from './poll'; +import poll, { assertWithPoll } from './poll'; import { EventStream } from '../../src/EventStream'; import { EventType } from '../../src/omnisharp/EventType'; import { BaseEvent, OmnisharpProjectDiagnosticStatus } from '../../src/omnisharp/loggingEvents'; @@ -68,8 +68,11 @@ suite(`ReAnalyze: ${testAssetWorkspace.description}`, function () { await poll(() => diagnosticStatusEvents, 15*1000, 500, r => r.find(x => x.message.Status === DiagnosticStatus.Ready) !== undefined); - let typeNotFoundCs = vscode.languages.getDiagnostics(interfaceImplUri).find(x => x.message.includes("CS0246")); - expect(typeNotFoundCs).to.not.be.undefined; + await assertWithPoll( + () => vscode.languages.getDiagnostics(interfaceImplUri), + 15*1000, + 500, + res => expect(res.find(x => x.message.includes("CS0246")))); }); test("When re-analyze of project is executed then eventually get notified about them.", async function () { From 9b51e58b64e32edb11e350735be4e87c51e76d55 Mon Sep 17 00:00:00 2001 From: Savpek Date: Thu, 11 Jul 2019 12:58:07 +0300 Subject: [PATCH 45/57] Testing build robustnes. From d4a8a6be4d0695a4091501d974c843ea76cb7e91 Mon Sep 17 00:00:00 2001 From: Savpek Date: Sat, 13 Jul 2019 20:41:19 +0300 Subject: [PATCH 46/57] Attempt to make test more robust. --- test/integrationTests/codeActionRename.integration.test.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/integrationTests/codeActionRename.integration.test.ts b/test/integrationTests/codeActionRename.integration.test.ts index b834805ab..dd423cc49 100644 --- a/test/integrationTests/codeActionRename.integration.test.ts +++ b/test/integrationTests/codeActionRename.integration.test.ts @@ -9,6 +9,7 @@ import { should, expect } from 'chai'; import { activateCSharpExtension } from './integrationHelpers'; import testAssetWorkspace from './testAssets/testAssetWorkspace'; import * as path from 'path'; +import { assertWithPoll } from './poll'; const chai = require('chai'); chai.use(require('chai-arrays')); @@ -40,6 +41,7 @@ suite(`Code Action Rename ${testAssetWorkspace.description}`, function () { ); expect(command, "Didn't find rename class command"); await vscode.commands.executeCommand(command.command, ...command.arguments); - expect(vscode.window.activeTextEditor.document.fileName).contains("C.cs"); + + assertWithPoll(await vscode.commands.executeCommand(command.command, ...command.arguments), 15*1000, 500, expect(vscode.window.activeTextEditor.document.fileName).contains("C.cs")); }); }); \ No newline at end of file From 05526315d0a7f1de97f82c541048fa13769a43e8 Mon Sep 17 00:00:00 2001 From: Savpek Date: Sat, 13 Jul 2019 21:01:28 +0300 Subject: [PATCH 47/57] Testing test robustnes. From 131c4c5802f8357d2773c4aaa358163efa254150 Mon Sep 17 00:00:00 2001 From: Savpek Date: Sat, 13 Jul 2019 21:20:25 +0300 Subject: [PATCH 48/57] Testing test robustnes. From 2e75ec727b5682d3577a364c399582373e421bc7 Mon Sep 17 00:00:00 2001 From: Savpek Date: Sun, 14 Jul 2019 12:12:53 +0300 Subject: [PATCH 49/57] Added missing await. --- test/integrationTests/codeActionRename.integration.test.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/integrationTests/codeActionRename.integration.test.ts b/test/integrationTests/codeActionRename.integration.test.ts index dd423cc49..6993d7045 100644 --- a/test/integrationTests/codeActionRename.integration.test.ts +++ b/test/integrationTests/codeActionRename.integration.test.ts @@ -40,8 +40,9 @@ suite(`Code Action Rename ${testAssetWorkspace.description}`, function () { (s) => { return s.title == "Rename file to C.cs"; } ); expect(command, "Didn't find rename class command"); + await vscode.commands.executeCommand(command.command, ...command.arguments); - assertWithPoll(await vscode.commands.executeCommand(command.command, ...command.arguments), 15*1000, 500, expect(vscode.window.activeTextEditor.document.fileName).contains("C.cs")); + await assertWithPoll(() => {}, 15*1000, 500, _ => expect(vscode.window.activeTextEditor.document.fileName).contains("C.cs")); }); }); \ No newline at end of file From 074bf66ea368d7c78e2cd4e1d7e7bfc36a86bf6c Mon Sep 17 00:00:00 2001 From: Savpek Date: Sun, 29 Sep 2019 13:16:10 +0300 Subject: [PATCH 50/57] Rebuild From 3f1c9a1026367a7528fa3ac682179e23aece526d Mon Sep 17 00:00:00 2001 From: Savpek Date: Sat, 12 Oct 2019 12:42:45 +0300 Subject: [PATCH 51/57] Testing stability From 76536afaee947a8f86249ede273adde89eef039a Mon Sep 17 00:00:00 2001 From: Savpek Date: Sat, 12 Oct 2019 12:53:23 +0300 Subject: [PATCH 52/57] Testing stability From 482878f86f98ef8b46c1f2e48e1fb856f64b38ad Mon Sep 17 00:00:00 2001 From: Savpek Date: Sun, 1 Dec 2019 18:38:26 +0200 Subject: [PATCH 53/57] Fix for invalid json at tsconfig.json --- tsconfig.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tsconfig.json b/tsconfig.json index 58caa9bb2..402904926 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -13,7 +13,7 @@ "skipLibCheck": true, "noImplicitThis": true, "noUnusedLocals": true, - "noFallthroughCasesInSwitch": true, + "noFallthroughCasesInSwitch": true }, "exclude": [ "syntaxes", From 0f75a9cd6a0ddf7e01b09bfb68815d11190d20c2 Mon Sep 17 00:00:00 2001 From: Savpek Date: Sun, 1 Dec 2019 19:03:50 +0200 Subject: [PATCH 54/57] Mergefixes --- test/integrationTests/diagnostics.integration.test.ts | 3 --- test/integrationTests/poll.ts | 5 ----- 2 files changed, 8 deletions(-) diff --git a/test/integrationTests/diagnostics.integration.test.ts b/test/integrationTests/diagnostics.integration.test.ts index 02629ef19..65597da6e 100644 --- a/test/integrationTests/diagnostics.integration.test.ts +++ b/test/integrationTests/diagnostics.integration.test.ts @@ -95,8 +95,5 @@ suite(`DiagnosticProvider: ${testAssetWorkspace.description}`, function () { suiteTeardown(async () => { await testAssetWorkspace.cleanupWorkspace(); }); - let cs8019 = result.find(x => x.source == "csharp" && x.code == "CS8019"); - expect(cs8019).to.not.be.undefined; - expect(cs8019.tags).to.include(vscode.DiagnosticTag.Unnecessary); }); }); diff --git a/test/integrationTests/poll.ts b/test/integrationTests/poll.ts index 7fd8e55cf..27397f28e 100644 --- a/test/integrationTests/poll.ts +++ b/test/integrationTests/poll.ts @@ -43,12 +43,7 @@ export async function assertWithPoll( throw assertResult; } -<<<<<<< HEAD -function defaultPollExpression(value: T): boolean -{ -======= function defaultPollExpression(value: T): boolean { ->>>>>>> upstream/master return value !== undefined && ((Array.isArray(value) && value.length > 0) || !Array.isArray(value)); } From c6e097661061553408afb73cdfa6a6ad470c768b Mon Sep 17 00:00:00 2001 From: Savpek Date: Thu, 5 Dec 2019 09:02:08 +0200 Subject: [PATCH 55/57] Fixes to make linter happy --- test/integrationTests/diagnostics.integration.test.ts | 2 +- .../integrationTests/launchConfiguration.integration.test.ts | 5 +++-- test/integrationTests/poll.ts | 4 ++-- test/integrationTests/reAnalyze.integration.test.ts | 2 +- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/test/integrationTests/diagnostics.integration.test.ts b/test/integrationTests/diagnostics.integration.test.ts index 65597da6e..e35a27f92 100644 --- a/test/integrationTests/diagnostics.integration.test.ts +++ b/test/integrationTests/diagnostics.integration.test.ts @@ -9,7 +9,7 @@ import * as path from 'path'; import { should, expect } from 'chai'; import { activateCSharpExtension } from './integrationHelpers'; import testAssetWorkspace from './testAssets/testAssetWorkspace'; -import poll, { assertWithPoll } from './poll'; +import { poll, assertWithPoll } from './poll'; const chai = require('chai'); chai.use(require('chai-arrays')); diff --git a/test/integrationTests/launchConfiguration.integration.test.ts b/test/integrationTests/launchConfiguration.integration.test.ts index ecf8e2d34..c3e373212 100644 --- a/test/integrationTests/launchConfiguration.integration.test.ts +++ b/test/integrationTests/launchConfiguration.integration.test.ts @@ -6,10 +6,10 @@ import * as fs from 'async-file'; import * as vscode from 'vscode'; -import poll from './poll'; import { should, expect } from 'chai'; import { activateCSharpExtension } from './integrationHelpers'; import testAssetWorkspace from './testAssets/testAssetWorkspace'; +import { poll } from './poll'; const chai = require('chai'); chai.use(require('chai-arrays')); @@ -23,7 +23,7 @@ suite(`Tasks generation: ${testAssetWorkspace.description}`, function () { await vscode.commands.executeCommand("dotnet.generateAssets", 0); - await poll(() => fs.exists(testAssetWorkspace.launchJsonPath), 10000, 100); + await poll(async () => await fs.exists(testAssetWorkspace.launchJsonPath), 10000, 100); }); suiteTeardown(async () => { @@ -31,6 +31,7 @@ suite(`Tasks generation: ${testAssetWorkspace.description}`, function () { }); test("Starting .NET Core Launch (console) from the workspace root should create an Active Debug Session", async () => { + vscode.debug.onDidChangeActiveDebugSession((e) => { expect(vscode.debug.activeDebugSession).not.to.be.undefined; expect(vscode.debug.activeDebugSession.type).to.equal("coreclr"); diff --git a/test/integrationTests/poll.ts b/test/integrationTests/poll.ts index 27397f28e..b0d428d87 100644 --- a/test/integrationTests/poll.ts +++ b/test/integrationTests/poll.ts @@ -47,7 +47,7 @@ function defaultPollExpression(value: T): boolean { return value !== undefined && ((Array.isArray(value) && value.length > 0) || !Array.isArray(value)); } -export default async function poll( +export async function poll( getValue: () => T, duration: number, step: number, @@ -67,6 +67,6 @@ export default async function poll( throw new Error("Polling did not succeed within the alotted duration."); } -function sleep(ms = 0) { +async function sleep(ms = 0) { return new Promise(r => setTimeout(r, ms)); } \ No newline at end of file diff --git a/test/integrationTests/reAnalyze.integration.test.ts b/test/integrationTests/reAnalyze.integration.test.ts index 473893f41..be694ce16 100644 --- a/test/integrationTests/reAnalyze.integration.test.ts +++ b/test/integrationTests/reAnalyze.integration.test.ts @@ -9,7 +9,7 @@ import * as path from 'path'; import { should, expect } from 'chai'; import { activateCSharpExtension } from './integrationHelpers'; import testAssetWorkspace from './testAssets/testAssetWorkspace'; -import poll, { assertWithPoll } from './poll'; +import { poll, assertWithPoll } from './poll'; import { EventStream } from '../../src/EventStream'; import { EventType } from '../../src/omnisharp/EventType'; import { BaseEvent, OmnisharpProjectDiagnosticStatus } from '../../src/omnisharp/loggingEvents'; From 180be7051b1def2a3f853f427d623621bc1b6680 Mon Sep 17 00:00:00 2001 From: Savpek Date: Thu, 5 Dec 2019 09:22:02 +0200 Subject: [PATCH 56/57] Testfixes --- test/integrationTests/diagnostics.integration.test.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/integrationTests/diagnostics.integration.test.ts b/test/integrationTests/diagnostics.integration.test.ts index e35a27f92..f72965c92 100644 --- a/test/integrationTests/diagnostics.integration.test.ts +++ b/test/integrationTests/diagnostics.integration.test.ts @@ -54,15 +54,15 @@ suite(`DiagnosticProvider: ${testAssetWorkspace.description}`, function () { test("Return unnecessary tag in case of unnesessary using", async function () { let result = await poll(() => vscode.languages.getDiagnostics(fileUri), 15 * 1000, 500); - let cs8019 = result.find(x => x.message.includes("CS8019")); + let cs8019 = result.find(x => x.code === "CS8019"); expect(cs8019).to.not.be.undefined; expect(cs8019.tags).to.include(vscode.DiagnosticTag.Unnecessary); }); test("Return fadeout diagnostics like unused variables based on roslyn analyzers", async function () { - let result = await poll(() => vscode.languages.getDiagnostics(fileUri), 15 * 1000, 500, result => result.find(x => x.message.includes("IDE0059")) != undefined); + let result = await poll(() => vscode.languages.getDiagnostics(fileUri), 15 * 1000, 500, result => result.find(x => x.code === "IDE0059") != undefined); - let ide0059 = result.find(x => x.message.includes("IDE0059")); + let ide0059 = result.find(x => x.code === "IDE0059"); expect(ide0059.tags).to.include(vscode.DiagnosticTag.Unnecessary); }); From 69a7bc38fd39e84da586da6227f0f08a92020042 Mon Sep 17 00:00:00 2001 From: Savpek Date: Thu, 5 Dec 2019 09:28:33 +0200 Subject: [PATCH 57/57] Review fixes for naming --- src/features/diagnosticsProvider.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/features/diagnosticsProvider.ts b/src/features/diagnosticsProvider.ts index 2cbd21ac7..55c624ad9 100644 --- a/src/features/diagnosticsProvider.ts +++ b/src/features/diagnosticsProvider.ts @@ -152,10 +152,10 @@ class DiagnosticsProvider extends AbstractSupport { .pipe(throttleTime(3000)) .subscribe(async () => { if (this._validationAdvisor.shouldValidateAll()) { - await this._validateSmallWorkspace(); + await this._validateEntireWorkspace(); } else if (this._validationAdvisor.shouldValidateFiles()) { - await this._validateLargeWorkspace(); + await this._validateOpenDocuments(); } })); @@ -263,7 +263,7 @@ class DiagnosticsProvider extends AbstractSupport { // On large workspaces (if maxProjectFileCountForDiagnosticAnalysis) is less than workspace size, // diagnostic fallback to mode where only open documents are analyzed. - private _validateLargeWorkspace(): NodeJS.Timeout { + private _validateOpenDocuments(): NodeJS.Timeout { return setTimeout(async () => { for (let editor of vscode.window.visibleTextEditors) { let document = editor.document; @@ -282,7 +282,7 @@ class DiagnosticsProvider extends AbstractSupport { .filter(diagnosticInFile => diagnosticInFile !== undefined); } - private _validateSmallWorkspace(): NodeJS.Timeout { + private _validateEntireWorkspace(): NodeJS.Timeout { return setTimeout(async () => { let value = await serverUtils.codeCheck(this._server, { FileName: null }, new vscode.CancellationTokenSource().token);