release: prepare WRNexusJS 0.8.8
This commit is contained in:
@@ -75,7 +75,10 @@ function diagnosticRange(diagnostic: WrnDiagnostic): Range {
|
||||
};
|
||||
}
|
||||
|
||||
export function documentDiagnostics(document: TextDocument) {
|
||||
export function documentDiagnostics(
|
||||
document: TextDocument,
|
||||
options: { includeTypes?: boolean } = {},
|
||||
) {
|
||||
if (Buffer.byteLength(document.text, "utf8") > 1_048_576) {
|
||||
return [
|
||||
{
|
||||
@@ -96,7 +99,8 @@ export function documentDiagnostics(document: TextDocument) {
|
||||
message: diagnostic.message,
|
||||
}),
|
||||
);
|
||||
if (syntax.some((diagnostic) => diagnostic.severity === 1)) return syntax;
|
||||
if (syntax.some((diagnostic) => diagnostic.severity === 1) || options.includeTypes === false)
|
||||
return syntax;
|
||||
const types = checkWrnSource(document.text, { filePath: documentPath(document.uri) }).map(
|
||||
(diagnostic) => ({
|
||||
range: {
|
||||
@@ -235,4 +239,61 @@ export function hover(document: TextDocument, position: Position) {
|
||||
export function completionItems() {
|
||||
return WRN_COMPLETIONS.map((label) => ({ label, kind: 14, detail: "WRNexus language keyword" }));
|
||||
}
|
||||
|
||||
const semanticTokenTypes = ["variable"] as const;
|
||||
const semanticTokenModifiers = ["declaration", "modification"] as const;
|
||||
export const semanticTokensLegend = {
|
||||
tokenTypes: [...semanticTokenTypes],
|
||||
tokenModifiers: [...semanticTokenModifiers],
|
||||
};
|
||||
|
||||
/** Encode state declarations, reads, and writes using the LSP relative token format. */
|
||||
export function semanticTokens(document: TextDocument): { data: number[] } {
|
||||
const declarations = new Map<string, Set<number>>();
|
||||
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<number>();
|
||||
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: Array<{ line: number; character: number; length: number; modifiers: number }> = [];
|
||||
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 = positionAt(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: number[] = [];
|
||||
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 };
|
||||
}
|
||||
export * from "./workspace.ts";
|
||||
|
||||
Reference in New Issue
Block a user