Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions vscode/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,23 @@
"show types of `var` variables"
]
}
},
"netbeans.autoScanWorkspace": {
"type": "boolean",
"default": false,
"description": "Automatically scan the entire workspace for diagnostics (warnings/errors) upon load"
},
"netbeans.scanExclude": {
"type": "array",
"default": [
"**/node_modules/**",
Comment thread
Moataz-Aldawood marked this conversation as resolved.
"**/target/**",
"**/build/**"
],
"description": "Glob patterns of files and directories to exclude when scanning the workspace for diagnostics",
"items": {
"type": "string"
}
}
}
},
Expand Down Expand Up @@ -514,6 +531,14 @@
}
],
"commands": [
{
"command": "nbls.workspace.scan",
"title": "Java: Scan Workspace for Diagnostics"
},
{
"command": "nbls.workspace.scan.clear",
"title": "Java: Clear Workspace Diagnostics"
},
{
"command": "nbls.node.properties.edit",
"title": "Properties"
Expand Down Expand Up @@ -857,6 +882,14 @@
}
],
"commandPalette": [
{
"command": "nbls.workspace.scan",
"when": "nbJavaLSReady && config.netbeans.javaSupport.enabled"
},
{
"command": "nbls.workspace.scan.clear",
"when": "nbJavaLSReady && config.netbeans.javaSupport.enabled"
},
{
"command": "nbls.workspace.new",
"when": "nbJavaLSReady"
Expand Down
90 changes: 89 additions & 1 deletion vscode/src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ export const COMMAND_PREFIX : string = "nbls";
const DATABASE: string = 'Database';
export const listeners = new Map<string, string[]>();
export let client: Promise<NbLanguageClient>;
export let projectDiagnosticCollection: vscode.DiagnosticCollection;
export let clientRuntimeJDK : string | null = null;
export const MINIMAL_JDK_VERSION = 17;
export const TEST_PROGRESS_EVENT: string = "testProgress";
Expand Down Expand Up @@ -499,7 +500,10 @@ class LineBufferingPseudoterminal implements vscode.Pseudoterminal {
}
}

export function activate(context: ExtensionContext): VSNetBeansAPI {
export function activate(context: ExtensionContext): VSNetBeansAPI {
projectDiagnosticCollection = vscode.languages.createDiagnosticCollection('java-workspace');
context.subscriptions.push(projectDiagnosticCollection);

const provider = new StringContentProvider();
const scheme = 'in-memory';
const providerRegistration = vscode.workspace.registerTextDocumentContentProvider(scheme, provider);
Expand Down Expand Up @@ -815,6 +819,13 @@ export function activate(context: ExtensionContext): VSNetBeansAPI {
context.subscriptions.push(commands.registerCommand(COMMAND_PREFIX + '.workspace.compile', () =>
wrapCommandWithProgress(COMMAND_PREFIX + '.build.workspace', 'Compiling workspace...', log, true)
));
context.subscriptions.push(commands.registerCommand(COMMAND_PREFIX + '.workspace.scan', () => {
doWorkspaceScan();
}));
context.subscriptions.push(commands.registerCommand(COMMAND_PREFIX + '.workspace.scan.clear', () => {
projectDiagnosticCollection.clear();
vscode.window.showInformationMessage('Workspace diagnostics cleared.');
}));
context.subscriptions.push(commands.registerCommand(COMMAND_PREFIX + '.workspace.clean', () =>
wrapCommandWithProgress(COMMAND_PREFIX + '.clean.workspace', 'Cleaning workspace...', log, true)
));
Expand Down Expand Up @@ -1140,6 +1151,13 @@ export function activate(context: ExtensionContext): VSNetBeansAPI {

// register completions:
launchConfigurations.registerCompletion(context);
client.then(() => {
const config = vscode.workspace.getConfiguration('netbeans');
if (config.get<boolean>('autoScanWorkspace', false)) {
vscode.commands.executeCommand(COMMAND_PREFIX + '.workspace.scan');
}
}).catch(() => {});

return Object.freeze({
version : API_VERSION,
apiVersion : API_VERSION
Expand Down Expand Up @@ -2148,3 +2166,73 @@ class StringContentProvider implements vscode.TextDocumentContentProvider {

}

async function doWorkspaceScan() {
const config = vscode.workspace.getConfiguration('netbeans');
const excludes = config.get<string[]>('scanExclude', ["**/node_modules/**", "**/target/**", "**/build/**"]);
const excludePattern = excludes.join(',');

await vscode.window.withProgress({
location: vscode.ProgressLocation.Window,
title: "Scanning workspace for diagnostics...",
cancellable: true
}, async (progress, token) => {
try {
const files = await vscode.workspace.findFiles('**/*.java', `{${excludePattern}}`);
const total = files.length;
let current = 0;

projectDiagnosticCollection.clear();

// Process in small chunks to avoid overloading the LSP server
const chunkSize = 5;
for (let i = 0; i < files.length; i += chunkSize) {
if (token.isCancellationRequested) {
break;
}
const chunk = files.slice(i, i + chunkSize);

await Promise.all(chunk.map(async (file) => {
try {
const diags: any[] = await vscode.commands.executeCommand('nbls.get.diagnostics', file.toString()) as any[];
if (diags && diags.length > 0) {
const vsDiags = diags
.filter(d => {
// Filter out noisy annotation processor initialization errors (like Lombok on newer JDKs)
return !d.message.includes("Can't initialize javac processor") && !d.message.includes("lombok");
})
.map(d => {
const range = new vscode.Range(
new vscode.Position(d.range.start.line, d.range.start.character),
new vscode.Position(d.range.end.line, d.range.end.character)
);
let severity = vscode.DiagnosticSeverity.Error;
if (d.severity === 2) severity = vscode.DiagnosticSeverity.Warning;
else if (d.severity === 3) severity = vscode.DiagnosticSeverity.Information;
else if (d.severity === 4) severity = vscode.DiagnosticSeverity.Hint;

const diagnostic = new vscode.Diagnostic(range, d.message, severity);
if (d.source) {
diagnostic.source = d.source;
}
if (d.code) {
diagnostic.code = d.code;
}
return diagnostic;
});
projectDiagnosticCollection.set(file, vsDiags);
}
} catch (err) {
// Ignore errors for individual files
} finally {
current++;
progress.report({ message: `Scanned ${current}/${total} files`, increment: (1 / total) * 100 });
}
}));
}
} catch (err) {
vscode.window.showErrorMessage(`Failed to scan workspace: ${err}`);
}
});
}