release: WRNexusJS 0.2.39
This commit is contained in:
+139
-22
@@ -40,41 +40,60 @@ const COMPILER_DIAGNOSTIC_COLLECTION = "wrnexus-compiler";
|
||||
* @param {vscode.ExtensionContext} context
|
||||
*/
|
||||
function registerFormatter(context) {
|
||||
const provider = vscode.languages.registerDocumentFormattingEditProvider(
|
||||
{
|
||||
language: WRN_LANGUAGE_ID,
|
||||
scheme: "file",
|
||||
},
|
||||
{
|
||||
provideDocumentFormattingEdits(document, options) {
|
||||
const configuration = vscode.workspace.getConfiguration("wrnexus", document.uri);
|
||||
const selector = {
|
||||
language: WRN_LANGUAGE_ID,
|
||||
};
|
||||
|
||||
const enabled = configuration.get("format.enable", true);
|
||||
const provider = vscode.languages.registerDocumentFormattingEditProvider(selector, {
|
||||
provideDocumentFormattingEdits(document, options, token) {
|
||||
if (token.isCancellationRequested) {
|
||||
return [];
|
||||
}
|
||||
|
||||
if (!enabled) {
|
||||
return [];
|
||||
}
|
||||
const configuration = vscode.workspace.getConfiguration("wrnexus", document.uri);
|
||||
|
||||
const source = document.getText();
|
||||
const enabled = configuration.get("format.enable", true);
|
||||
|
||||
const printWidth = configuration.get("formatting.printWidth", 100);
|
||||
if (!enabled) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const source = document.getText();
|
||||
|
||||
if (!source.trim()) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const printWidth = configuration.get("formatting.printWidth", 100);
|
||||
|
||||
try {
|
||||
const formatted = formatWrn(source, {
|
||||
tabSize: options.tabSize,
|
||||
insertSpaces: options.insertSpaces,
|
||||
tabSize: options.tabSize || 2,
|
||||
insertSpaces: options.insertSpaces !== false,
|
||||
printWidth,
|
||||
});
|
||||
|
||||
if (formatted === source) {
|
||||
if (typeof formatted !== "string" || formatted === source) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const range = new vscode.Range(document.positionAt(0), document.positionAt(source.length));
|
||||
const fullRange = new vscode.Range(
|
||||
document.positionAt(0),
|
||||
document.positionAt(source.length),
|
||||
);
|
||||
|
||||
return [vscode.TextEdit.replace(range, formatted)];
|
||||
},
|
||||
return [vscode.TextEdit.replace(fullRange, formatted)];
|
||||
} catch (error) {
|
||||
const message = error instanceof Error ? error.message : String(error);
|
||||
|
||||
console.error("[wrnexus] formatting failed:", message);
|
||||
|
||||
vscode.window.showErrorMessage(`WRNexus formatting failed: ${message}`);
|
||||
|
||||
return [];
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
context.subscriptions.push(provider);
|
||||
}
|
||||
@@ -259,6 +278,103 @@ function registerCompilerDiagnostics(context) {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register semantic highlighting for WRN state declarations and references.
|
||||
*
|
||||
* @param {vscode.ExtensionContext} context
|
||||
*/
|
||||
function registerSemanticTokens(context) {
|
||||
const semanticTokenLegend = new vscode.SemanticTokensLegend(
|
||||
["variable"],
|
||||
["declaration", "modification"],
|
||||
);
|
||||
|
||||
const escapeRegExp = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Activate the WRNexus VS Code extension.
|
||||
*
|
||||
@@ -267,10 +383,10 @@ function registerCompilerDiagnostics(context) {
|
||||
function activate(context) {
|
||||
registerDiagnostics(context);
|
||||
registerCompilerDiagnostics(context);
|
||||
|
||||
registerCompletionProvider(context);
|
||||
registerDefinitionProvider(context);
|
||||
registerFormatter(context);
|
||||
registerSemanticTokens(context);
|
||||
|
||||
context.subscriptions.push(
|
||||
vscode.languages.registerDocumentSemanticTokensProvider(
|
||||
@@ -497,5 +613,6 @@ module.exports = {
|
||||
deactivate,
|
||||
registerCompilerDiagnostics,
|
||||
registerFormatter,
|
||||
registerSemanticTokens,
|
||||
toCompilerDiagnostic,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user