release: prepare WRNexusJS 0.8.8
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env node
|
||||
// WRN editor language server source hash: eb2126d09754a516bf6846aea69409578879532f74759f66ae37cf60c961b3bf
|
||||
// WRN editor language server source hash: da83a5e1dbf90523ee0fe9a0d232182b0a78d025f3be8d07c324728d1cdcc17c
|
||||
// WRN editor language server generator hash: f593a44aaf05495b789ce7a3086bee1eebb951b884d41c0e017bbcfe5f547e72
|
||||
// @bun @bun-cjs
|
||||
(function(exports, require, module, __filename, __dirname) {var __create = Object.create;
|
||||
@@ -171925,6 +171925,7 @@ function virtualTypeScriptModule(source, filePath = "component.wrn", appRoot = f
|
||||
append(ast.types.join(`
|
||||
|
||||
`), ast.types[0]?.trim());
|
||||
append('declare const ctx: import("@wrnexus/core").Context;');
|
||||
for (const prop of ast.props) {
|
||||
if (!safeBindingName(prop.name))
|
||||
continue;
|
||||
@@ -172370,7 +172371,7 @@ var SKIPPED_DIRECTORIES = new Set([
|
||||
]);
|
||||
var MAX_INDEX_FILES = 5000;
|
||||
var MAX_SOURCE_BYTES = 1048576;
|
||||
var INDEX_TTL_MS = 5000;
|
||||
var INDEX_TTL_MS = 5 * 60000;
|
||||
var MAX_CACHED_ROOTS = 8;
|
||||
var workspaceIndexCache = new Map;
|
||||
function walk3(root, test) {
|
||||
@@ -172494,6 +172495,36 @@ function workspaceCompletionItems(root) {
|
||||
}
|
||||
return items;
|
||||
}
|
||||
function clearWorkspaceIndexCache(root) {
|
||||
if (root)
|
||||
workspaceIndexCache.delete(import_node_path3.resolve(root));
|
||||
else
|
||||
workspaceIndexCache.clear();
|
||||
}
|
||||
function workspaceSymbolLocations(root, name, limit = 1000) {
|
||||
if (!/^[A-Za-z_$][\w$]*$/.test(name))
|
||||
return [];
|
||||
const escaped = name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
||||
const pattern = new RegExp(`(?<![A-Za-z0-9_$])${escaped}(?![A-Za-z0-9_$])`, "g");
|
||||
const locations = [];
|
||||
for (const file of walk3(import_node_path3.resolve(root), (path) => import_node_path3.extname(path) === ".wrn").slice(0, limit)) {
|
||||
let source;
|
||||
try {
|
||||
source = import_node_fs3.readFileSync(file, "utf8");
|
||||
} catch {
|
||||
continue;
|
||||
}
|
||||
for (const match of source.matchAll(pattern)) {
|
||||
const before = source.slice(0, match.index).split(/\r?\n/);
|
||||
const start = { line: before.length - 1, character: before.at(-1)?.length ?? 0 };
|
||||
locations.push({
|
||||
uri: `file:///${file.replace(/\\/g, "/")}`,
|
||||
range: { start, end: { line: start.line, character: start.character + name.length } }
|
||||
});
|
||||
}
|
||||
}
|
||||
return locations;
|
||||
}
|
||||
function extractComponentRefactor(document, range, name) {
|
||||
if (!/^[A-Z][A-Za-z0-9_$]*$/.test(name))
|
||||
throw new Error("Component name must use PascalCase");
|
||||
@@ -172599,7 +172630,7 @@ function diagnosticRange(diagnostic) {
|
||||
}
|
||||
};
|
||||
}
|
||||
function documentDiagnostics(document) {
|
||||
function documentDiagnostics(document, options = {}) {
|
||||
if (Buffer.byteLength(document.text, "utf8") > 1048576) {
|
||||
return [
|
||||
{
|
||||
@@ -172618,7 +172649,7 @@ function documentDiagnostics(document) {
|
||||
source: "wrnexus",
|
||||
message: diagnostic.message
|
||||
}));
|
||||
if (syntax.some((diagnostic) => diagnostic.severity === 1))
|
||||
if (syntax.some((diagnostic) => diagnostic.severity === 1) || options.includeTypes === false)
|
||||
return syntax;
|
||||
const types = checkWrnSource(document.text, { filePath: documentPath(document.uri) }).map((diagnostic) => ({
|
||||
range: {
|
||||
@@ -172688,19 +172719,6 @@ function documentSymbols(document) {
|
||||
};
|
||||
});
|
||||
}
|
||||
function symbolLocations(document, position) {
|
||||
const selected = wordAt(document.text, position);
|
||||
if (!selected)
|
||||
return [];
|
||||
const pattern = new RegExp(`(?<![A-Za-z0-9_$])${selected.word.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}(?![A-Za-z0-9_$])`, "g");
|
||||
return [...document.text.matchAll(pattern)].map((match) => ({
|
||||
uri: document.uri,
|
||||
range: {
|
||||
start: positionAt2(document.text, match.index),
|
||||
end: positionAt2(document.text, match.index + selected.word.length)
|
||||
}
|
||||
}));
|
||||
}
|
||||
function definitionLocation(document, position) {
|
||||
const selected = wordAt(document.text, position);
|
||||
if (!selected)
|
||||
@@ -172734,6 +172752,55 @@ ${declaration[0]}
|
||||
function completionItems() {
|
||||
return WRN_COMPLETIONS.map((label) => ({ label, kind: 14, detail: "WRNexus language keyword" }));
|
||||
}
|
||||
var semanticTokenTypes = ["variable"];
|
||||
var semanticTokenModifiers = ["declaration", "modification"];
|
||||
var semanticTokensLegend = {
|
||||
tokenTypes: [...semanticTokenTypes],
|
||||
tokenModifiers: [...semanticTokenModifiers]
|
||||
};
|
||||
function semanticTokens(document) {
|
||||
const declarations = new Map;
|
||||
for (const match of document.text.matchAll(/\bstate\s+([A-Za-z_$][A-Za-z0-9_$]*)\s*(?==|;|\r?$)/gm)) {
|
||||
const name = match[1];
|
||||
const offset = match.index + match[0].lastIndexOf(name);
|
||||
const offsets = declarations.get(name) ?? new Set;
|
||||
offsets.add(offset);
|
||||
declarations.set(name, offsets);
|
||||
}
|
||||
const comments = [...document.text.matchAll(/\/\/[^\n]*|\/\*[\s\S]*?\*\//g)].map((match) => ({
|
||||
start: match.index,
|
||||
end: match.index + match[0].length
|
||||
}));
|
||||
const tokens = [];
|
||||
for (const [name, offsets] of declarations) {
|
||||
const escaped = name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
||||
for (const match of document.text.matchAll(new RegExp(`(?<![A-Za-z0-9_$])${escaped}(?![A-Za-z0-9_$])`, "g"))) {
|
||||
const offset = match.index;
|
||||
if (comments.some((range) => offset >= range.start && offset < range.end))
|
||||
continue;
|
||||
const position = positionAt2(document.text, offset);
|
||||
const after = document.text.slice(offset + name.length).match(/^\s*(?:=|\+=|-=|\*=|\/=|%=|\+\+|--)/);
|
||||
const before = document.text.slice(Math.max(0, offset - 8), offset).match(/(?:\+\+|--)\s*$/);
|
||||
tokens.push({
|
||||
...position,
|
||||
length: name.length,
|
||||
modifiers: offsets.has(offset) ? 1 : after || before ? 2 : 0
|
||||
});
|
||||
}
|
||||
}
|
||||
tokens.sort((a, b) => a.line - b.line || a.character - b.character);
|
||||
const data = [];
|
||||
let previousLine = 0;
|
||||
let previousCharacter = 0;
|
||||
for (const token of tokens) {
|
||||
const deltaLine = token.line - previousLine;
|
||||
const deltaCharacter = deltaLine === 0 ? token.character - previousCharacter : token.character;
|
||||
data.push(deltaLine, deltaCharacter, token.length, 0, token.modifiers);
|
||||
previousLine = token.line;
|
||||
previousCharacter = token.character;
|
||||
}
|
||||
return { data };
|
||||
}
|
||||
|
||||
// packages/language-server/src/server.ts
|
||||
var documents = new Map;
|
||||
@@ -172767,20 +172834,20 @@ function internalDiagnostic(document, error) {
|
||||
message: `WRNexus language analysis failed safely: ${message}`
|
||||
};
|
||||
}
|
||||
function safeDocumentDiagnostics(document) {
|
||||
function safeDocumentDiagnostics(document, includeTypes = true) {
|
||||
try {
|
||||
return documentDiagnostics(document);
|
||||
return documentDiagnostics(document, { includeTypes });
|
||||
} catch (error) {
|
||||
process.stderr.write(`[wrnexus-lsp] diagnostics failed for ${document.uri}: ${error instanceof Error ? error.stack ?? error.message : String(error)}
|
||||
`);
|
||||
return [internalDiagnostic(document, error)];
|
||||
}
|
||||
}
|
||||
function publish(document) {
|
||||
function publish(document, includeTypes = true) {
|
||||
send({
|
||||
jsonrpc: "2.0",
|
||||
method: "textDocument/publishDiagnostics",
|
||||
params: { uri: document.uri, diagnostics: safeDocumentDiagnostics(document) }
|
||||
params: { uri: document.uri, diagnostics: safeDocumentDiagnostics(document, includeTypes) }
|
||||
});
|
||||
}
|
||||
function clearDiagnosticTimer(uri) {
|
||||
@@ -172796,7 +172863,7 @@ function schedulePublish(document) {
|
||||
diagnosticTimers.delete(document.uri);
|
||||
const current = documents.get(document.uri);
|
||||
if (current && current.version === expectedVersion)
|
||||
publish(current);
|
||||
publish(current, false);
|
||||
}, DIAGNOSTIC_DEBOUNCE_MS));
|
||||
}
|
||||
function rememberDocument(document) {
|
||||
@@ -172818,7 +172885,7 @@ async function handle(message) {
|
||||
result(message.id, {
|
||||
serverInfo: { name: "WRNexus Language Server", version: "0.8.3" },
|
||||
capabilities: {
|
||||
textDocumentSync: 1,
|
||||
textDocumentSync: { openClose: true, change: 1, save: true },
|
||||
documentFormattingProvider: true,
|
||||
completionProvider: { triggerCharacters: ["<", "@", ":", "."] },
|
||||
hoverProvider: true,
|
||||
@@ -172826,8 +172893,14 @@ async function handle(message) {
|
||||
referencesProvider: true,
|
||||
renameProvider: { prepareProvider: true },
|
||||
documentSymbolProvider: true,
|
||||
semanticTokensProvider: { legend: semanticTokensLegend, full: true },
|
||||
codeActionProvider: {
|
||||
codeActionKinds: ["quickfix", "refactor.extract", "refactor.rewrite"]
|
||||
codeActionKinds: [
|
||||
"quickfix",
|
||||
"refactor.extract",
|
||||
"refactor.rewrite",
|
||||
"source.organizeImports"
|
||||
]
|
||||
},
|
||||
experimental: { wrnexusVirtualTypeScript: true }
|
||||
}
|
||||
@@ -172842,6 +172915,10 @@ async function handle(message) {
|
||||
result(message.id, null);
|
||||
break;
|
||||
case "exit":
|
||||
for (const timer of diagnosticTimers.values())
|
||||
clearTimeout(timer);
|
||||
diagnosticTimers.clear();
|
||||
documents.clear();
|
||||
process.exit(0);
|
||||
break;
|
||||
case "textDocument/didOpen": {
|
||||
@@ -172861,6 +172938,15 @@ async function handle(message) {
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "textDocument/didSave": {
|
||||
const document = documents.get(params.textDocument.uri);
|
||||
if (document) {
|
||||
clearDiagnosticTimer(document.uri);
|
||||
clearWorkspaceIndexCache(workspaceRoot);
|
||||
publish(document, true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "textDocument/didClose":
|
||||
clearDiagnosticTimer(params.textDocument.uri);
|
||||
documents.delete(params.textDocument.uri);
|
||||
@@ -172890,6 +172976,11 @@ async function handle(message) {
|
||||
result(message.id, document ? documentSymbols(document) : []);
|
||||
break;
|
||||
}
|
||||
case "textDocument/semanticTokens/full": {
|
||||
const document = documents.get(params.textDocument.uri);
|
||||
result(message.id, document ? semanticTokens(document) : { data: [] });
|
||||
break;
|
||||
}
|
||||
case "textDocument/hover": {
|
||||
const document = documents.get(params.textDocument.uri);
|
||||
result(message.id, document ? hover(document, params.position) : null);
|
||||
@@ -172902,7 +172993,8 @@ async function handle(message) {
|
||||
}
|
||||
case "textDocument/references": {
|
||||
const document = documents.get(params.textDocument.uri);
|
||||
result(message.id, document ? symbolLocations(document, params.position) : []);
|
||||
const selected = document ? wordAt(document.text, params.position) : null;
|
||||
result(message.id, selected ? workspaceSymbolLocations(workspaceRoot, selected.word) : []);
|
||||
break;
|
||||
}
|
||||
case "textDocument/prepareRename": {
|
||||
@@ -172912,11 +173004,16 @@ async function handle(message) {
|
||||
}
|
||||
case "textDocument/rename": {
|
||||
const document = documents.get(params.textDocument.uri);
|
||||
const edits = document ? symbolLocations(document, params.position).map(({ range }) => ({
|
||||
range,
|
||||
newText: params.newName
|
||||
})) : [];
|
||||
result(message.id, document ? { changes: { [document.uri]: edits } } : null);
|
||||
const selected = document ? wordAt(document.text, params.position) : null;
|
||||
if (!selected || !/^[A-Za-z_$][\w$]*$/.test(params.newName)) {
|
||||
result(message.id, null);
|
||||
break;
|
||||
}
|
||||
const changes = {};
|
||||
for (const location of workspaceSymbolLocations(workspaceRoot, selected.word)) {
|
||||
(changes[location.uri] ??= []).push({ range: location.range, newText: params.newName });
|
||||
}
|
||||
result(message.id, { changes });
|
||||
break;
|
||||
}
|
||||
case "textDocument/codeAction": {
|
||||
@@ -172937,6 +173034,70 @@ async function handle(message) {
|
||||
}
|
||||
}
|
||||
}));
|
||||
const imports = [
|
||||
...document.text.matchAll(/^import(?:\s+type)?[\s\S]*?(?:;\s*|\n(?=import|\s*(?:page|component|layout|global\s+store|page\s+store)\b))/gm)
|
||||
].map((match) => ({
|
||||
start: match.index,
|
||||
end: match.index + match[0].length,
|
||||
text: match[0].trim()
|
||||
}));
|
||||
if (imports.length > 1) {
|
||||
const ordered = [...imports].sort((a, b) => {
|
||||
const aType = /^import\s+type\b/.test(a.text) ? 0 : 1;
|
||||
const bType = /^import\s+type\b/.test(b.text) ? 0 : 1;
|
||||
return aType - bType || a.text.localeCompare(b.text);
|
||||
});
|
||||
const replacement = ordered.map((entry) => entry.text.replace(/;$/, "")).join(`
|
||||
`) + `
|
||||
`;
|
||||
const start = imports[0].start;
|
||||
const end = imports.at(-1).end;
|
||||
if (document.text.slice(start, end) !== replacement) {
|
||||
actions.push({
|
||||
title: "Organize WRN imports",
|
||||
kind: "source.organizeImports",
|
||||
edit: {
|
||||
changes: {
|
||||
[document.uri]: [
|
||||
{
|
||||
range: {
|
||||
start: positionAt2(document.text, start),
|
||||
end: positionAt2(document.text, end)
|
||||
},
|
||||
newText: replacement
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
for (const diagnostic of params.context?.diagnostics ?? []) {
|
||||
if (diagnostic.code !== "WRN-OUTPUT-LEGACY-EMIT")
|
||||
continue;
|
||||
const start = offsetAt(document.text, diagnostic.range.start);
|
||||
const end = offsetAt(document.text, diagnostic.range.end);
|
||||
const source = document.text.slice(start, end);
|
||||
const match = /\$emit\(\s*["']([A-Za-z_$][\w$]*)["']\s*,?/.exec(source);
|
||||
if (!match)
|
||||
continue;
|
||||
actions.push({
|
||||
title: `Convert $emit to output.${match[1]}`,
|
||||
kind: "quickfix",
|
||||
diagnostics: [diagnostic],
|
||||
isPreferred: true,
|
||||
edit: {
|
||||
changes: {
|
||||
[document.uri]: [
|
||||
{
|
||||
range: diagnostic.range,
|
||||
newText: source.replace(/\$emit\(\s*["'][A-Za-z_$][\w$]*["']\s*,?\s*/, `output.${match[1]}(`)
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
const selected = document.text.slice(document.text.split(/\r?\n/).slice(0, params.range.start.line).reduce((n, line) => n + line.length + 1, 0) + params.range.start.character, document.text.split(/\r?\n/).slice(0, params.range.end.line).reduce((n, line) => n + line.length + 1, 0) + params.range.end.character);
|
||||
if (selected.trim().startsWith("<")) {
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user