feat: add typed WRN declarations
This commit is contained in:
@@ -9,7 +9,17 @@
|
||||
*/
|
||||
|
||||
export type TokenType =
|
||||
"ident" | "string" | "lbrace" | "rbrace" | "lparen" | "rparen" | "at" | "eq" | "comma" | "eof";
|
||||
| "ident"
|
||||
| "string"
|
||||
| "lbrace"
|
||||
| "rbrace"
|
||||
| "lparen"
|
||||
| "rparen"
|
||||
| "at"
|
||||
| "eq"
|
||||
| "colon"
|
||||
| "comma"
|
||||
| "eof";
|
||||
|
||||
export interface Token {
|
||||
type: TokenType;
|
||||
@@ -71,6 +81,9 @@ export class Lexer {
|
||||
case "=":
|
||||
this.pos++;
|
||||
return { type: "eq", value: c, pos };
|
||||
case ":":
|
||||
this.pos++;
|
||||
return { type: "colon", value: c, pos };
|
||||
case ",":
|
||||
this.pos++;
|
||||
return { type: "comma", value: c, pos };
|
||||
@@ -133,6 +146,62 @@ export class Lexer {
|
||||
return v.trim();
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a TypeScript-style type annotation after `:`. Reading stops at a
|
||||
* top-level `=` or line ending, while nested object/tuple/generic syntax is
|
||||
* preserved. The optional `=` is consumed for the caller.
|
||||
*/
|
||||
readTypeAnnotation(): { type: string; hasDefault: boolean } {
|
||||
const { src } = this;
|
||||
let value = "";
|
||||
let angle = 0;
|
||||
let square = 0;
|
||||
let brace = 0;
|
||||
let paren = 0;
|
||||
let quote: string | null = null;
|
||||
|
||||
while (this.pos < src.length) {
|
||||
const c = src[this.pos]!;
|
||||
if (quote) {
|
||||
value += c;
|
||||
this.pos++;
|
||||
if (c === "\\" && this.pos < src.length) value += src[this.pos++]!;
|
||||
else if (c === quote) quote = null;
|
||||
continue;
|
||||
}
|
||||
if (c === '"' || c === "'" || c === "`") {
|
||||
quote = c;
|
||||
value += c;
|
||||
this.pos++;
|
||||
continue;
|
||||
}
|
||||
if (c === "<") angle++;
|
||||
else if (c === ">" && angle > 0) angle--;
|
||||
else if (c === "[") square++;
|
||||
else if (c === "]" && square > 0) square--;
|
||||
else if (c === "{") brace++;
|
||||
else if (c === "}" && brace > 0) brace--;
|
||||
else if (c === "(") paren++;
|
||||
else if (c === ")" && paren > 0) paren--;
|
||||
|
||||
if (angle === 0 && square === 0 && brace === 0 && paren === 0) {
|
||||
if (c === "=") {
|
||||
this.pos++;
|
||||
const type = value.trim();
|
||||
if (!type) throw new LexError(`Expected a type annotation at offset ${this.pos}`);
|
||||
return { type, hasDefault: true };
|
||||
}
|
||||
if (c === "\n" || c === "\r") break;
|
||||
}
|
||||
value += c;
|
||||
this.pos++;
|
||||
}
|
||||
|
||||
const type = value.trim();
|
||||
if (!type) throw new LexError(`Expected a type annotation at offset ${this.pos}`);
|
||||
return { type, hasDefault: false };
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a `{ ... }` block and return its INNER text (no outer braces), with
|
||||
* brace counting that respects string and template literals so a `}` inside a
|
||||
|
||||
Reference in New Issue
Block a user