fix compiler authoring traps and showcase generation order

This commit is contained in:
2026-08-09 14:22:12 +05:30
parent 2e5c0cc953
commit 09ebd44b6c
29 changed files with 1437 additions and 5101 deletions
+15 -1
View File
@@ -439,7 +439,14 @@ export function parse(source: string): PageAst {
// props { name: Type = <default>; @event name = function }
lx.next();
expect("lbrace");
while (lx.peek().type !== "rbrace") {
while (true) {
if (lx.startsWithBlockComment()) {
throw new ParseError(
"Block comments are not allowed inside props {}; use // line comments instead",
"WRN-PROPS-BLOCK-COMMENT",
);
}
if (lx.peek().type === "rbrace") break;
const t = lx.peek();
if (t.type === "eof") throw new ParseError("Unexpected end of input inside props");
if (t.type === "at") {
@@ -829,6 +836,13 @@ export function parse(source: string): PageAst {
const declaredStates = new Set(states.map((state) => state.name));
if (declaredStates.has("page")) {
throw new ParseError(
"State name 'page' collides with the WRN 'page' keyword; choose another state name",
"WRN-STATE-RESERVED-NAME",
);
}
for (const watcher of watches) {
if (!declaredStates.has(watcher.state)) {
throw new ParseError(`Cannot watch undeclared state '${watcher.state}'`);
+6
View File
@@ -55,6 +55,12 @@ export class Lexer {
}
}
/** True when the next non-trivia characters open a block comment. */
startsWithBlockComment(): boolean {
this.skipTrivia();
return this.src[this.pos] === "/" && this.src[this.pos + 1] === "*";
}
/** Read and consume the next structural token. */
next(): Token {
this.skipTrivia();