fix(vscode): repair WRN language diagnostics and activation

This commit is contained in:
2026-07-19 14:02:17 +05:30
parent df4c1d3e7d
commit 646d16f83d
16 changed files with 425 additions and 171 deletions
+39 -96
View File
@@ -284,95 +284,37 @@ function registerCompilerDiagnostics(context) {
* @param {vscode.ExtensionContext} context
*/
function registerSemanticTokens(context) {
const semanticTokenLegend = new vscode.SemanticTokensLegend(
["variable"],
["declaration", "modification"],
context.subscriptions.push(
vscode.languages.registerDocumentSemanticTokensProvider(
{
language: WRN_LANGUAGE_ID,
},
wrnSemanticTokensProvider,
semanticTokenLegend,
),
);
}
const escapeRegExp = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
/**
* Recover files affected by older workspace settings that associated `*.wrn`
* with the obsolete `wire` language id. Normal language contribution matching
* happens before activation; this fallback is intentionally limited to Plain
* Text and the legacy id so explicit third-party associations are respected.
*
* @param {vscode.TextDocument} document
*/
async function recoverWrnLanguage(document) {
if (!document.fileName.toLowerCase().endsWith(".wrn")) return;
if (!["plaintext", "wire"].includes(document.languageId)) return;
const collectStateVariables = (text) => {
const states = new Map();
const pattern = /\bstate\s+([A-Za-z_$][A-Za-z0-9_$]*)\s*(?==|;|\r?$)/gm;
let match;
while ((match = pattern.exec(text)) !== null) {
const name = match[1];
if (!name) {
continue;
}
const offset = match.index + match[0].lastIndexOf(name);
const declarations = states.get(name) ?? new Set();
declarations.add(offset);
states.set(name, declarations);
}
return states;
};
const isModification = (text, offset, length) => {
const after = text.slice(offset + length).match(/^\s*(=|\+=|-=|\*=|\/=|%=|\+\+|--)/);
if (after) {
return true;
}
const before = text.slice(Math.max(0, offset - 8), offset).match(/(\+\+|--)\s*$/);
return Boolean(before);
};
const provider = {
provideDocumentSemanticTokens(document, token) {
const builder = new vscode.SemanticTokensBuilder(semanticTokenLegend);
const text = document.getText();
const states = collectStateVariables(text);
for (const [name, declarationOffsets] of states) {
if (token.isCancellationRequested) {
return builder.build();
}
const pattern = new RegExp(`(?<![A-Za-z0-9_$])${escapeRegExp(name)}(?![A-Za-z0-9_$])`, "g");
let match;
while ((match = pattern.exec(text)) !== null) {
const offset = match.index;
const position = document.positionAt(offset);
let modifiers = [];
if (declarationOffsets.has(offset)) {
modifiers = ["declaration"];
} else if (isModification(text, offset, name.length)) {
modifiers = ["modification"];
}
builder.push(position.line, position.character, name.length, "variable", modifiers);
}
}
return builder.build();
},
};
const registration = vscode.languages.registerDocumentSemanticTokensProvider(
{
language: WRN_LANGUAGE_ID,
},
provider,
semanticTokenLegend,
);
context.subscriptions.push(registration);
try {
await vscode.languages.setTextDocumentLanguage(document, WRN_LANGUAGE_ID);
} catch (error) {
console.warn(
"[wrnexus] unable to recover .wrn language association:",
error instanceof Error ? error.message : String(error),
);
}
}
/**
@@ -381,22 +323,22 @@ function registerSemanticTokens(context) {
* @param {vscode.ExtensionContext} context
*/
function activate(context) {
for (const document of vscode.workspace.textDocuments) {
void recoverWrnLanguage(document);
}
context.subscriptions.push(
vscode.workspace.onDidOpenTextDocument((document) => {
void recoverWrnLanguage(document);
}),
);
registerDiagnostics(context);
registerCompilerDiagnostics(context);
registerCompletionProvider(context);
registerDefinitionProvider(context);
registerFormatter(context);
registerSemanticTokens(context);
context.subscriptions.push(
vscode.languages.registerDocumentSemanticTokensProvider(
{
language: "wrn",
},
wrnSemanticTokensProvider,
semanticTokenLegend,
),
);
}
function deactivate() {}
@@ -614,5 +556,6 @@ module.exports = {
registerCompilerDiagnostics,
registerFormatter,
registerSemanticTokens,
recoverWrnLanguage,
toCompilerDiagnostic,
};