Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow to change huge project file limit #1877

Merged
merged 11 commits into from
Nov 20, 2018
Merged
5 changes: 3 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
* Added preview Razor (cshtml) language service with support for C# completions and diagnostics in ASP.NET Core projects. Please report issues with the preview Razor tooling on the [aspnet/Razor.VSCode](https://github.com/aspnet/Razor.VSCode/issues) repo. To disable the preview Razor tooling set the "razor.disabled" setting to `true`. (PR: [2554](https://github.com/OmniSharp/omnisharp-vscode/pull/2554))
* Added omnisharp.minFindSymbolsFilterLength setting to configure the number of characters a user must type in for "Go to Symbol in Workspace" command to return any results (default is 0 to preserve existing behavior). Additionally added omnisharp.maxFindSymbolsItems for configuring maximum number of items returned by "Go to Symbol in Workspace" command. The default is 1000. (PR: [#2487](https://github.com/OmniSharp/omnisharp-vscode/pull/2487))
* Added a command - "CSharp: Start authoring a new issue on GitHub" to enable the users to file issues on github from within the extension with helpful config information from their system.(PR: [#2503](https://github.com/OmniSharp/omnisharp-vscode/pull/2503))
* Added a `csharp.maxProjectFileCountForDiagnosticAnalysis` setting to configure the file limit when the extension stops reporting errors for whole workspace. When this threshold is reached, the diagnostics are reported for currently opened files only. This mechanism was available in previous versions, but now can be configured. The default is 1000. (PR: [#1877](https://github.com/OmniSharp/omnisharp-vscode/pull/1877))

#### Debugger
* Fixed crash at the end of debug sessions on Linux ([#2439](https://github.com/OmniSharp/omnisharp-vscode/issues/2439))
Expand All @@ -42,7 +43,7 @@

* Modified the "Unresolved dependencies" prompt to restore the all the projects in the currently selected solution or workspace. (PR: [#2323](https://github.com/OmniSharp/omnisharp-vscode/pull/2323))

* Added support to configure the default *.sln file loaded when opening a project with multiple *.sln files in the root. _(Contributed by [@janaka](https://github.com/janaka))_ (PR: [#2053](https://github.com/OmniSharp/omnisharp-vscode/pull/2053))
* Added support to configure the default *.sln file loaded when opening a project with multiple *.sln files in the root. _(Contributed by [@janaka](https://github.com/janaka))_ (PR: [#2053](https://github.com/OmniSharp/omnisharp-vscode/pull/2053))

* Added support for tracking opening, closing and changing of virtual documents that don't exist on disk. (PR: [#2436](https://github.com/OmniSharp/omnisharp-vscode/pull/2436)) _(Contributed by [@NTaylorMullen](https://github.com/NTaylorMullen))_

Expand All @@ -61,7 +62,7 @@
#### Testing

* Added test execution output to the output of the Run/Debug Test CodeLens. (PR: [#2337](https://github.com/OmniSharp/omnisharp-vscode/pull/2337), [#2343](https://github.com/OmniSharp/omnisharp-vscode/pull/2343), [omnisharp-roslyn#1203](https://github.com/OmniSharp/omnisharp-roslyn/pull/1203))
* Fixed a bug where a debug session could not be started and duplicate logs were displayed after a previous one failed due to build failure. (PR: [#2405](https://github.com/OmniSharp/omnisharp-vscode/pull/2405), [omnisharp-roslyn#1239](https://github.com/OmniSharp/omnisharp-roslyn/pull/1239))
* Fixed a bug where a debug session could not be started and duplicate logs were displayed after a previous one failed due to build failure. (PR: [#2405](https://github.com/OmniSharp/omnisharp-vscode/pull/2405), [omnisharp-roslyn#1239](https://github.com/OmniSharp/omnisharp-roslyn/pull/1239))

#### Options

Expand Down
5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -566,6 +566,11 @@
"default": true,
"description": "Specifies whether the run and debug test CodeLens should be show be shown."
},
"csharp.maxProjectFileCountForDiagnosticAnalysis": {
"type": "number",
"default": 1000,
"description": "Specifies the maximum number of files for which diagnostics are reported for the whole workspace. If this limit is exceeded, diagnostics will be shown for currently opened files only. Specify 0 or less to disable the limit completely."
},
"omnisharp.path": {
"type": [
"string",
Expand Down
4 changes: 4 additions & 0 deletions src/CSharpExtensionExports.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { Advisor } from "./features/diagnosticsProvider";

export default interface CSharpExtensionExports {
initializationFinished: () => Promise<void>;

getAdvisor: () => Promise<Advisor>;
}
22 changes: 13 additions & 9 deletions src/features/diagnosticsProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import CompositeDisposable from '../CompositeDisposable';
import { IDisposable } from '../Disposable';
import { isVirtualCSharpDocument } from './virtualDocumentTracker';
import { TextDocument } from '../vscodeAdapter';
import OptionProvider from '../observers/OptionProvider';

export class Advisor {

Expand All @@ -21,7 +22,7 @@ export class Advisor {
private _packageRestoreCounter: number = 0;
private _projectSourceFileCounts: { [path: string]: number } = Object.create(null);

constructor(server: OmniSharpServer) {
constructor(server: OmniSharpServer, private optionProvider: OptionProvider) {
this._server = server;

let d1 = server.onProjectChange(this._onProjectChange, this);
Expand All @@ -44,7 +45,7 @@ export class Advisor {
public shouldValidateProject(): boolean {
return this._isServerStarted()
&& !this._isRestoringPackages()
&& !this._isHugeProject();
&& !this._isOverFileLimit();
}

private _updateProjectFileCount(path: string, fileCount: number): void {
Expand Down Expand Up @@ -99,15 +100,18 @@ export class Advisor {
return this._server.isRunning();
}

private _isHugeProject(): boolean {
let sourceFileCount = 0;
for (let key in this._projectSourceFileCounts) {
sourceFileCount += this._projectSourceFileCounts[key];
if (sourceFileCount > 1000) {
return true;
private _isOverFileLimit(): boolean {
let opts = this.optionProvider.GetLatestOptions();
let fileLimit = opts.maxProjectFileCountForDiagnosticAnalysis;
if (fileLimit > 0) {
let sourceFileCount = 0;
for (let key in this._projectSourceFileCounts) {
sourceFileCount += this._projectSourceFileCounts[key];
if (sourceFileCount > fileLimit) {
return true;
}
}
}

return false;
}
}
Expand Down
14 changes: 9 additions & 5 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import { ProjectStatusBarObserver } from './observers/ProjectStatusBarObserver';
import CSharpExtensionExports from './CSharpExtensionExports';
import { vscodeNetworkSettingsProvider, NetworkSettingsProvider } from './NetworkSettings';
import { ErrorMessageObserver } from './observers/ErrorMessageObserver';
import OptionProvider from './observers/OptionProvider';
import OptionProvider from './observers/OptionProvider';
import DotNetTestChannelObserver from './observers/DotnetTestChannelObserver';
import DotNetTestLoggerObserver from './observers/DotnetTestLoggerObserver';
import { ShowOmniSharpConfigChangePrompt } from './observers/OptionChangeObserver';
Expand Down Expand Up @@ -65,7 +65,7 @@ export async function activate(context: vscode.ExtensionContext): Promise<CSharp
let dotnetTestLoggerObserver = new DotNetTestLoggerObserver(dotnetTestChannel);
eventStream.subscribe(dotnetTestChannelObserver.post);
eventStream.subscribe(dotnetTestLoggerObserver.post);

let csharpChannel = vscode.window.createOutputChannel('C#');
let csharpchannelObserver = new CsharpChannelObserver(csharpChannel);
let csharpLogObserver = new CsharpLoggerObserver(csharpChannel);
Expand Down Expand Up @@ -119,7 +119,7 @@ export async function activate(context: vscode.ExtensionContext): Promise<CSharp
let runtimeDependenciesExist = await ensureRuntimeDependencies(extension, eventStream, platformInfo, networkSettingsProvider);

// activate language services
let omniSharpPromise = OmniSharp.activate(context, extension.packageJSON, platformInfo, networkSettingsProvider, eventStream, optionProvider, extension.extensionPath);
let langServicePromise = OmniSharp.activate(context, extension.packageJSON, platformInfo, networkSettingsProvider, eventStream, optionProvider, extension.extensionPath);

// register JSON completion & hover providers for project.json
context.subscriptions.push(addJSONProviders());
Expand Down Expand Up @@ -147,9 +147,13 @@ export async function activate(context: vscode.ExtensionContext): Promise<CSharp

return {
initializationFinished: async () => {
let omniSharp = await omniSharpPromise;
await omniSharp.waitForEmptyEventQueue();
let langService = await langServicePromise;
await langService.server.waitForEmptyEventQueue();
await coreClrDebugPromise;
},
getAdvisor: async () => {
let langService = await langServicePromise;
return langService.advisor;
}
};
}
Expand Down
12 changes: 7 additions & 5 deletions src/omnisharp/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,10 @@ import { StructureProvider } from '../features/structureProvider';
import { OmniSharpMonoResolver } from './OmniSharpMonoResolver';
import { getMonoVersion } from '../utils/getMonoVersion';

export let omnisharp: OmniSharpServer;
export interface ActivationResult {
readonly server: OmniSharpServer;
readonly advisor: Advisor;
}

export async function activate(context: vscode.ExtensionContext, packageJSON: any, platformInfo: PlatformInformation, provider: NetworkSettingsProvider, eventStream: EventStream, optionProvider: OptionProvider, extensionPath: string) {
const documentSelector: vscode.DocumentSelector = {
Expand All @@ -49,8 +52,7 @@ export async function activate(context: vscode.ExtensionContext, packageJSON: an
const options = optionProvider.GetLatestOptions();
let omnisharpMonoResolver = new OmniSharpMonoResolver(getMonoVersion);
const server = new OmniSharpServer(vscode, provider, packageJSON, platformInfo, eventStream, optionProvider, extensionPath, omnisharpMonoResolver);
omnisharp = server;
const advisor = new Advisor(server); // create before server is started
const advisor = new Advisor(server, optionProvider); // create before server is started
const disposables = new CompositeDisposable();
let localDisposables: CompositeDisposable;

Expand Down Expand Up @@ -176,7 +178,7 @@ export async function activate(context: vscode.ExtensionContext, packageJSON: an

context.subscriptions.push(disposables);

return new Promise<OmniSharpServer>(resolve =>
return new Promise<ActivationResult>(resolve =>
server.onServerStart(e =>
resolve(server)));
resolve({ server, advisor })));
}
12 changes: 8 additions & 4 deletions src/omnisharp/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ export class Options {
public razorDevMode: boolean,
public razorPluginPath?: string,
public defaultLaunchSolution?: string,
public monoPath?: string) { }
public monoPath?: string,
public maxProjectFileCountForDiagnosticAnalysis?: number | null) { }


public static Read(vscode: vscode): Options {
Expand Down Expand Up @@ -76,9 +77,11 @@ export class Options {
const razorDevMode = !!razorConfig && razorConfig.get<boolean>('devmode', false);
const razorPluginPath = razorConfig ? razorConfig.get<string>('plugin.path', undefined) : undefined;

const maxProjectFileCountForDiagnosticAnalysis = csharpConfig.get<number | null>('maxProjectFileCountForDiagnosticAnalysis', 1000);

return new Options(
path,
useGlobalMono,
path,
useGlobalMono,
waitForDebugger,
loggingLevel,
autoStart,
Expand All @@ -97,6 +100,7 @@ export class Options {
razorPluginPath,
defaultLaunchSolution,
monoPath,
maxProjectFileCountForDiagnosticAnalysis,
);
}

Expand Down Expand Up @@ -130,7 +134,7 @@ export class Options {
return toUseGlobalMonoValue(omnisharpConfig.get<boolean>('useMono'));
}
else if (csharpConfig.has('omnisharpUsesMono')) {
// BACKCOMPAT: If 'csharp.omnisharpUsesMono' setting was found, true maps to "always" and false maps to "auto"
// BACKCOMPAT: If 'csharp.omnisharpUsesMono' setting was found, true maps to "always" and false maps to "auto"
return toUseGlobalMonoValue(csharpConfig.get<boolean>('omnisharpUsesMono'));
}
else {
Expand Down
81 changes: 81 additions & 0 deletions test/integrationTests/advisor.integration.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*---------------------------------------------------------------------------------------------
* 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 { expect } from 'chai';
import * as path from 'path';
import { activateCSharpExtension } from './integrationHelpers';
import testAssetWorkspace from './testAssets/testAssetWorkspace';

import { Advisor } from '../../src/features/diagnosticsProvider';

const chai = require('chai');
chai.use(require('chai-arrays'));
chai.use(require('chai-fs'));

function setLimit(to: number | null) {
let csharpConfig = vscode.workspace.getConfiguration('csharp');
return csharpConfig.update('maxProjectFileCountForDiagnosticAnalysis', to);
}

suite(`Advisor ${testAssetWorkspace.description}`, function () {
let advisor: Advisor;

suiteSetup(async function () {
await testAssetWorkspace.restore();
let activationResult = await activateCSharpExtension();
if (!activationResult) {
throw new Error('Cannot activate extension.');
} else {
advisor = activationResult.advisor;
}

let fileName = 'completion.cs';
let dir = testAssetWorkspace.projects[0].projectDirectoryPath;
let fileUri = vscode.Uri.file(path.join(dir, fileName));
await vscode.commands.executeCommand('vscode.open', fileUri);
});

suiteTeardown(async () => {
await testAssetWorkspace.cleanupWorkspace();
});

test('Advisor.shouldValidateProject returns true when maxProjectFileCountForDiagnosticAnalysis is higher than the file count', async () => {
await setLimit(1000);

expect(advisor.shouldValidateProject()).to.be.true;
});

test('Advisor.shouldValidateFiles returns true when maxProjectFileCountForDiagnosticAnalysis is higher than the file count', async () => {
await setLimit(1000);

expect(advisor.shouldValidateFiles()).to.be.true;
});

test('Advisor.shouldValidateProject returns false when maxProjectFileCountForDiagnosticAnalysis is lower than the file count', async () => {
await setLimit(1);

expect(advisor.shouldValidateProject()).to.be.false;
});

test('Advisor.shouldValidateFiles returns true when maxProjectFileCountForDiagnosticAnalysis is lower than the file count', async () => {
await setLimit(1);

expect(advisor.shouldValidateFiles()).to.be.true;
});

test('Advisor.shouldValidateProject returns true when maxProjectFileCountForDiagnosticAnalysis is null', async () => {
await setLimit(null);

expect(advisor.shouldValidateProject()).to.be.true;
});

test('Advisor.shouldValidateFiles returns true when maxProjectFileCountForDiagnosticAnalysis is null', async () => {
await setLimit(null);

expect(advisor.shouldValidateFiles()).to.be.true;
});
});
11 changes: 9 additions & 2 deletions test/integrationTests/integrationHelpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,13 @@

import * as vscode from 'vscode';
import CSharpExtensionExports from '../../src/CSharpExtensionExports';
import { Advisor } from '../../src/features/diagnosticsProvider';

export async function activateCSharpExtension(): Promise<void> {
export interface ActivationResult {
readonly advisor: Advisor;
}

export async function activateCSharpExtension(): Promise<ActivationResult | undefined> {
const csharpExtension = vscode.extensions.getExtension<CSharpExtensionExports>("ms-vscode.csharp");

if (!csharpExtension.isActive) {
Expand All @@ -16,8 +21,10 @@ export async function activateCSharpExtension(): Promise<void> {
try {
await csharpExtension.exports.initializationFinished();
console.log("ms-vscode.csharp activated");
return { advisor: await csharpExtension.exports.getAdvisor() };
}
catch (err) {
console.log(JSON.stringify(err));
return undefined;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"omnisharp.defaultLaunchSolution": "b_SecondInOrder_SlnFile.sln",
"omnisharp.path": "latest",
"csharp.maxProjectFileCountForDiagnosticAnalysis": 1000,
}