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: 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,
}