Skip to content

Commit e224b9c

Browse files
authored
Merge pull request #1877 from jakubfijalkowski/huge-project-limit-conf
Allow to change huge project file limit
2 parents be0ec9a + 1460622 commit e224b9c

File tree

10 files changed

+140
-27
lines changed

10 files changed

+140
-27
lines changed

CHANGELOG.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
* 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))
2121
* 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))
2222
* 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))
23+
* 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))
2324

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

4344
* 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))
4445

45-
* 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))
46+
* 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))
4647

4748
* 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))_
4849

@@ -61,7 +62,7 @@
6162
#### Testing
6263

6364
* 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))
64-
* 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))
65+
* 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))
6566

6667
#### Options
6768

package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -566,6 +566,11 @@
566566
"default": true,
567567
"description": "Specifies whether the run and debug test CodeLens should be show be shown."
568568
},
569+
"csharp.maxProjectFileCountForDiagnosticAnalysis": {
570+
"type": "number",
571+
"default": 1000,
572+
"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."
573+
},
569574
"omnisharp.path": {
570575
"type": [
571576
"string",

src/CSharpExtensionExports.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@
33
* Licensed under the MIT License. See License.txt in the project root for license information.
44
*--------------------------------------------------------------------------------------------*/
55

6+
import { Advisor } from "./features/diagnosticsProvider";
7+
68
export default interface CSharpExtensionExports {
79
initializationFinished: () => Promise<void>;
10+
11+
getAdvisor: () => Promise<Advisor>;
812
}

src/features/diagnosticsProvider.ts

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import CompositeDisposable from '../CompositeDisposable';
1313
import { IDisposable } from '../Disposable';
1414
import { isVirtualCSharpDocument } from './virtualDocumentTracker';
1515
import { TextDocument } from '../vscodeAdapter';
16+
import OptionProvider from '../observers/OptionProvider';
1617

1718
export class Advisor {
1819

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

24-
constructor(server: OmniSharpServer) {
25+
constructor(server: OmniSharpServer, private optionProvider: OptionProvider) {
2526
this._server = server;
2627

2728
let d1 = server.onProjectChange(this._onProjectChange, this);
@@ -44,7 +45,7 @@ export class Advisor {
4445
public shouldValidateProject(): boolean {
4546
return this._isServerStarted()
4647
&& !this._isRestoringPackages()
47-
&& !this._isHugeProject();
48+
&& !this._isOverFileLimit();
4849
}
4950

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

102-
private _isHugeProject(): boolean {
103-
let sourceFileCount = 0;
104-
for (let key in this._projectSourceFileCounts) {
105-
sourceFileCount += this._projectSourceFileCounts[key];
106-
if (sourceFileCount > 1000) {
107-
return true;
103+
private _isOverFileLimit(): boolean {
104+
let opts = this.optionProvider.GetLatestOptions();
105+
let fileLimit = opts.maxProjectFileCountForDiagnosticAnalysis;
106+
if (fileLimit > 0) {
107+
let sourceFileCount = 0;
108+
for (let key in this._projectSourceFileCounts) {
109+
sourceFileCount += this._projectSourceFileCounts[key];
110+
if (sourceFileCount > fileLimit) {
111+
return true;
112+
}
108113
}
109114
}
110-
111115
return false;
112116
}
113117
}

src/main.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ import { ProjectStatusBarObserver } from './observers/ProjectStatusBarObserver';
3030
import CSharpExtensionExports from './CSharpExtensionExports';
3131
import { vscodeNetworkSettingsProvider, NetworkSettingsProvider } from './NetworkSettings';
3232
import { ErrorMessageObserver } from './observers/ErrorMessageObserver';
33-
import OptionProvider from './observers/OptionProvider';
33+
import OptionProvider from './observers/OptionProvider';
3434
import DotNetTestChannelObserver from './observers/DotnetTestChannelObserver';
3535
import DotNetTestLoggerObserver from './observers/DotnetTestLoggerObserver';
3636
import { ShowOmniSharpConfigChangePrompt } from './observers/OptionChangeObserver';
@@ -65,7 +65,7 @@ export async function activate(context: vscode.ExtensionContext): Promise<CSharp
6565
let dotnetTestLoggerObserver = new DotNetTestLoggerObserver(dotnetTestChannel);
6666
eventStream.subscribe(dotnetTestChannelObserver.post);
6767
eventStream.subscribe(dotnetTestLoggerObserver.post);
68-
68+
6969
let csharpChannel = vscode.window.createOutputChannel('C#');
7070
let csharpchannelObserver = new CsharpChannelObserver(csharpChannel);
7171
let csharpLogObserver = new CsharpLoggerObserver(csharpChannel);
@@ -119,7 +119,7 @@ export async function activate(context: vscode.ExtensionContext): Promise<CSharp
119119
let runtimeDependenciesExist = await ensureRuntimeDependencies(extension, eventStream, platformInfo, networkSettingsProvider);
120120

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

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

148148
return {
149149
initializationFinished: async () => {
150-
let omniSharp = await omniSharpPromise;
151-
await omniSharp.waitForEmptyEventQueue();
150+
let langService = await langServicePromise;
151+
await langService.server.waitForEmptyEventQueue();
152152
await coreClrDebugPromise;
153+
},
154+
getAdvisor: async () => {
155+
let langService = await langServicePromise;
156+
return langService.advisor;
153157
}
154158
};
155159
}

src/omnisharp/extension.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,10 @@ import { StructureProvider } from '../features/structureProvider';
3939
import { OmniSharpMonoResolver } from './OmniSharpMonoResolver';
4040
import { getMonoVersion } from '../utils/getMonoVersion';
4141

42-
export let omnisharp: OmniSharpServer;
42+
export interface ActivationResult {
43+
readonly server: OmniSharpServer;
44+
readonly advisor: Advisor;
45+
}
4346

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

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

177179
context.subscriptions.push(disposables);
178180

179-
return new Promise<OmniSharpServer>(resolve =>
181+
return new Promise<ActivationResult>(resolve =>
180182
server.onServerStart(e =>
181-
resolve(server)));
183+
resolve({ server, advisor })));
182184
}

src/omnisharp/options.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ export class Options {
2626
public razorDevMode: boolean,
2727
public razorPluginPath?: string,
2828
public defaultLaunchSolution?: string,
29-
public monoPath?: string) { }
29+
public monoPath?: string,
30+
public maxProjectFileCountForDiagnosticAnalysis?: number | null) { }
3031

3132

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

80+
const maxProjectFileCountForDiagnosticAnalysis = csharpConfig.get<number | null>('maxProjectFileCountForDiagnosticAnalysis', 1000);
81+
7982
return new Options(
80-
path,
81-
useGlobalMono,
83+
path,
84+
useGlobalMono,
8285
waitForDebugger,
8386
loggingLevel,
8487
autoStart,
@@ -97,6 +100,7 @@ export class Options {
97100
razorPluginPath,
98101
defaultLaunchSolution,
99102
monoPath,
103+
maxProjectFileCountForDiagnosticAnalysis,
100104
);
101105
}
102106

@@ -130,7 +134,7 @@ export class Options {
130134
return toUseGlobalMonoValue(omnisharpConfig.get<boolean>('useMono'));
131135
}
132136
else if (csharpConfig.has('omnisharpUsesMono')) {
133-
// BACKCOMPAT: If 'csharp.omnisharpUsesMono' setting was found, true maps to "always" and false maps to "auto"
137+
// BACKCOMPAT: If 'csharp.omnisharpUsesMono' setting was found, true maps to "always" and false maps to "auto"
134138
return toUseGlobalMonoValue(csharpConfig.get<boolean>('omnisharpUsesMono'));
135139
}
136140
else {
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
import * as vscode from 'vscode';
7+
8+
import { expect } from 'chai';
9+
import * as path from 'path';
10+
import { activateCSharpExtension } from './integrationHelpers';
11+
import testAssetWorkspace from './testAssets/testAssetWorkspace';
12+
13+
import { Advisor } from '../../src/features/diagnosticsProvider';
14+
15+
const chai = require('chai');
16+
chai.use(require('chai-arrays'));
17+
chai.use(require('chai-fs'));
18+
19+
function setLimit(to: number | null) {
20+
let csharpConfig = vscode.workspace.getConfiguration('csharp');
21+
return csharpConfig.update('maxProjectFileCountForDiagnosticAnalysis', to);
22+
}
23+
24+
suite(`Advisor ${testAssetWorkspace.description}`, function () {
25+
let advisor: Advisor;
26+
27+
suiteSetup(async function () {
28+
await testAssetWorkspace.restore();
29+
let activationResult = await activateCSharpExtension();
30+
if (!activationResult) {
31+
throw new Error('Cannot activate extension.');
32+
} else {
33+
advisor = activationResult.advisor;
34+
}
35+
36+
let fileName = 'completion.cs';
37+
let dir = testAssetWorkspace.projects[0].projectDirectoryPath;
38+
let fileUri = vscode.Uri.file(path.join(dir, fileName));
39+
await vscode.commands.executeCommand('vscode.open', fileUri);
40+
});
41+
42+
suiteTeardown(async () => {
43+
await testAssetWorkspace.cleanupWorkspace();
44+
});
45+
46+
test('Advisor.shouldValidateProject returns true when maxProjectFileCountForDiagnosticAnalysis is higher than the file count', async () => {
47+
await setLimit(1000);
48+
49+
expect(advisor.shouldValidateProject()).to.be.true;
50+
});
51+
52+
test('Advisor.shouldValidateFiles returns true when maxProjectFileCountForDiagnosticAnalysis is higher than the file count', async () => {
53+
await setLimit(1000);
54+
55+
expect(advisor.shouldValidateFiles()).to.be.true;
56+
});
57+
58+
test('Advisor.shouldValidateProject returns false when maxProjectFileCountForDiagnosticAnalysis is lower than the file count', async () => {
59+
await setLimit(1);
60+
61+
expect(advisor.shouldValidateProject()).to.be.false;
62+
});
63+
64+
test('Advisor.shouldValidateFiles returns true when maxProjectFileCountForDiagnosticAnalysis is lower than the file count', async () => {
65+
await setLimit(1);
66+
67+
expect(advisor.shouldValidateFiles()).to.be.true;
68+
});
69+
70+
test('Advisor.shouldValidateProject returns true when maxProjectFileCountForDiagnosticAnalysis is null', async () => {
71+
await setLimit(null);
72+
73+
expect(advisor.shouldValidateProject()).to.be.true;
74+
});
75+
76+
test('Advisor.shouldValidateFiles returns true when maxProjectFileCountForDiagnosticAnalysis is null', async () => {
77+
await setLimit(null);
78+
79+
expect(advisor.shouldValidateFiles()).to.be.true;
80+
});
81+
});

test/integrationTests/integrationHelpers.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,13 @@
55

66
import * as vscode from 'vscode';
77
import CSharpExtensionExports from '../../src/CSharpExtensionExports';
8+
import { Advisor } from '../../src/features/diagnosticsProvider';
89

9-
export async function activateCSharpExtension(): Promise<void> {
10+
export interface ActivationResult {
11+
readonly advisor: Advisor;
12+
}
13+
14+
export async function activateCSharpExtension(): Promise<ActivationResult | undefined> {
1015
const csharpExtension = vscode.extensions.getExtension<CSharpExtensionExports>("ms-vscode.csharp");
1116

1217
if (!csharpExtension.isActive) {
@@ -16,8 +21,10 @@ export async function activateCSharpExtension(): Promise<void> {
1621
try {
1722
await csharpExtension.exports.initializationFinished();
1823
console.log("ms-vscode.csharp activated");
24+
return { advisor: await csharpExtension.exports.getAdvisor() };
1925
}
2026
catch (err) {
2127
console.log(JSON.stringify(err));
28+
return undefined;
2229
}
23-
}
30+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
{
22
"omnisharp.defaultLaunchSolution": "b_SecondInOrder_SlnFile.sln",
33
"omnisharp.path": "latest",
4+
"csharp.maxProjectFileCountForDiagnosticAnalysis": 1000,
45
}

0 commit comments

Comments
 (0)