release: WRNexusJS 0.6.0
This commit is contained in:
@@ -5,9 +5,16 @@ const vscode = require("vscode");
|
||||
const COLLECTION_NAME = "wrnexus";
|
||||
const WRN_LANGUAGE_ID = "wrn";
|
||||
|
||||
const TOP_LEVEL_PATTERN = /^\s*(page|component|layout)\s+([A-Za-z_$][\w$]*)\s*\{/;
|
||||
const TOP_LEVEL_PATTERN =
|
||||
/^\s*((?:global|page)\s+store|page|component|layout)\s+([A-Za-z_$][\w$]*)\s*\{/;
|
||||
|
||||
const VALID_TOP_LEVEL_KINDS = new Set(["page", "component", "layout"]);
|
||||
const VALID_TOP_LEVEL_KINDS = new Set([
|
||||
"page",
|
||||
"component",
|
||||
"layout",
|
||||
"global store",
|
||||
"page store",
|
||||
]);
|
||||
|
||||
const VALID_LIFECYCLE_HOOKS = new Set(["mount", "update", "unmount"]);
|
||||
|
||||
@@ -18,7 +25,9 @@ const ROOT_MEMBER_NAMES = [
|
||||
"client",
|
||||
"types",
|
||||
"props",
|
||||
"outputs",
|
||||
"state",
|
||||
"persist",
|
||||
"computed",
|
||||
"effect",
|
||||
"watch",
|
||||
@@ -39,6 +48,8 @@ const VALID_MEMBERS = {
|
||||
page: new Set(ROOT_MEMBER_NAMES),
|
||||
component: new Set(ROOT_MEMBER_NAMES),
|
||||
layout: new Set(ROOT_MEMBER_NAMES),
|
||||
"global store": new Set(ROOT_MEMBER_NAMES),
|
||||
"page store": new Set(ROOT_MEMBER_NAMES),
|
||||
};
|
||||
|
||||
function createDiagnostic(
|
||||
@@ -1181,6 +1192,68 @@ function validateLayoutUsage(document, source, rootKind, rootMatch) {
|
||||
return diagnostics;
|
||||
}
|
||||
|
||||
function validateV060Features(document, source) {
|
||||
const diagnostics = [];
|
||||
const duplicateRuntimeFunctions = new Map();
|
||||
for (const match of source.matchAll(
|
||||
/\b(client|server|shared)\s+(?:async\s+)?function\s+([A-Za-z_$][\w$]*)/g,
|
||||
)) {
|
||||
const key = `${match[1]}:${match[2]}`;
|
||||
if (duplicateRuntimeFunctions.has(key)) {
|
||||
diagnostics.push(
|
||||
createDiagnostic(
|
||||
document,
|
||||
match.index,
|
||||
match.index + match[0].length,
|
||||
`Duplicate ${match[1]} function '${match[2]}'.`,
|
||||
vscode.DiagnosticSeverity.Error,
|
||||
"WRN-FUNCTION-DUPLICATE",
|
||||
),
|
||||
);
|
||||
} else duplicateRuntimeFunctions.set(key, match.index);
|
||||
}
|
||||
for (const match of source.matchAll(/\$emit\s*\(/g)) {
|
||||
diagnostics.push(
|
||||
createDiagnostic(
|
||||
document,
|
||||
match.index,
|
||||
match.index + match[0].length,
|
||||
"Use typed output.name(payload) instead of deprecated $emit().",
|
||||
vscode.DiagnosticSeverity.Warning,
|
||||
"WRN-OUTPUT-LEGACY-EMIT",
|
||||
),
|
||||
);
|
||||
}
|
||||
for (const match of source.matchAll(/\bevent\.detail\b/g)) {
|
||||
diagnostics.push(
|
||||
createDiagnostic(
|
||||
document,
|
||||
match.index,
|
||||
match.index + match[0].length,
|
||||
"Component output handlers receive payload directly.",
|
||||
vscode.DiagnosticSeverity.Warning,
|
||||
"WRN-OUTPUT-LEGACY-DETAIL",
|
||||
),
|
||||
);
|
||||
}
|
||||
for (const match of source.matchAll(
|
||||
/\bserver\s+(?:async\s+)?function\b[\s\S]*?\b(window|document|localStorage|navigator)\b/g,
|
||||
)) {
|
||||
const offset = match.index + match[0].lastIndexOf(match[1]);
|
||||
diagnostics.push(
|
||||
createDiagnostic(
|
||||
document,
|
||||
offset,
|
||||
offset + match[1].length,
|
||||
`Browser API '${match[1]}' is unavailable in a server function.`,
|
||||
vscode.DiagnosticSeverity.Error,
|
||||
"WRN-SERVER-BROWSER-API",
|
||||
),
|
||||
);
|
||||
}
|
||||
return diagnostics;
|
||||
}
|
||||
|
||||
function validateDocument(document) {
|
||||
if (document.languageId !== WRN_LANGUAGE_ID) {
|
||||
return [];
|
||||
@@ -1234,6 +1307,8 @@ function validateDocument(document) {
|
||||
|
||||
diagnostics.push(...validateLayoutUsage(document, source, declaration.kind, declaration.match));
|
||||
|
||||
diagnostics.push(...validateV060Features(document, source));
|
||||
|
||||
return diagnostics;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user