blob: c3a6db2c7a68612a4dc64356a0bf17467eb1a8d8 [file] [log] [blame] [edit]
// Copyright 2025 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import path from 'path';
import * as vscode from 'vscode';
const buildSeverity: Record<string, vscode.DiagnosticSeverity> = {
'error': vscode.DiagnosticSeverity.Error,
'warn': vscode.DiagnosticSeverity.Warning,
'note': vscode.DiagnosticSeverity.Information
};
/**
* Diagnostic Collection Class
* Checks for C++ and Rust build syntax errors from Fuchsia builds and routes
* to the extension's problem matcher.
*
* Python and GN are not included since the recommended language server extensions
* handle these cases.
*/
export class FuchsiaDiagnostics {
private collection = vscode.languages.createDiagnosticCollection('fuchsia');
private entries: Array<[vscode.Uri, vscode.Diagnostic[]]> = [];
private fileSet: Set<string> = new Set();
private fuchsiaProblemMatcher: any;
constructor(packageJSON: any) {
this.fuchsiaProblemMatcher = packageJSON.contributes.problemMatchers;
}
/**
* Matches message and adds to diagnostics collection
* @param msg Message to match to problem matcher
*/
match(msg: string) {
const matcher = this.fuchsiaProblemMatcher.find(
(item: { name: string; }) => item.name === 'cpp-rust-build');
const pattern = new RegExp(matcher!.pattern.regexp, 'g');
const matches = msg.matchAll(pattern);
// Assumes in fuchsia directory
const workspaceFolder = vscode.workspace.workspaceFolders;
if (!workspaceFolder) {
return;
}
const workspacePath = workspaceFolder[0].uri.fsPath;
// Prevent duplicates of matches
for (const match of matches) {
if (this.fileSet.has(match[0])) {
continue;
}
this.fileSet.add(match[0]);
const fullPath = path.join(workspacePath, match[matcher!.pattern.file]);
this.entries.push([vscode.Uri.file(fullPath), [{
message: match[matcher!.pattern.message],
range: new vscode.Range(
new vscode.Position(parseInt(match[matcher!.pattern.line]) - 1,
parseInt(match[matcher!.pattern.column]) - 1),
new vscode.Position(parseInt(match[matcher!.pattern.line]) - 1,
parseInt(match[matcher!.pattern.column]) - 1)),
severity: buildSeverity[match[matcher!.pattern.severity]]
}]]);
}
this.collection.set(this.entries);
}
/**
* Clear the collection
*/
clear() {
this.entries = [];
this.fileSet.clear();
this.collection.clear();
}
/**
* Returns current list of matches for a uri resource
* @returns
*/
get(): Array<[vscode.Uri, vscode.Diagnostic[]]> {
let collection: Array<[vscode.Uri, vscode.Diagnostic[]]> = [];
this.entries.forEach((entry) => {
console.log(entry[0]);
let uri = entry[0];
let getDiagnostics = this.collection.get(uri);
if (getDiagnostics) {
collection.push([uri, [...getDiagnostics]]);
}
});
return collection;
}
}