import type { Expression, Parameter, Program, Statement, TypeParameterDeclaration, TypeReference, TypeSyntax } from "./ast.ts"; import type { AdvisorySuppression } from "./advisory-suppression.ts"; import { type Advisory, type Diagnostic } from "./diagnostic.ts"; import type { CompilerLexicalExtension } from "./extension.ts"; import { type Span } from "./source.ts"; import { type Token, type TokenKind } from "./token.ts"; export declare function isParserComplexityFailure(value: unknown): boolean; export interface ParseResult { readonly program: Program; readonly diagnostics: readonly Diagnostic[]; /** D89: the advisory channel, accumulated beside the diagnostics and never merged into them. */ readonly advisories: readonly Advisory[]; /** * D103: the `velar-allow` suppressions carried by comments the module lexer * never saw, because they sit inside a region an extension scanner claimed * whole — a `look:` block, a `keyframes:` block, an f-string interpolation. * Those regions are lexed again by `parseNestedExpression`, and its lexer's * suppressions used to be dropped on the floor: a `velar-allow` written on a * Look entry silenced nothing and a stale one was never reported, so a * suppression could rot in place there — the exact failure the charter's * third suppression rule exists to prevent. */ readonly suppressions: readonly AdvisorySuppression[]; } export interface ExpressionParseResult { readonly expression: Expression; readonly diagnostics: readonly Diagnostic[]; readonly advisories: readonly Advisory[]; readonly suppressions: readonly AdvisorySuppression[]; } export declare class Parser { private readonly tokens; protected readonly lexicalExtensions: readonly CompilerLexicalExtension[]; protected readonly diagnostics: Diagnostic[]; protected readonly refusedTypeParameterNames: Set; protected readonly advisories: Advisory[]; protected readonly suppressions: AdvisorySuppression[]; private readonly genericCallableNames; private readonly contextMarkers; /** Extension-owned contextual keywords: names until a shape claims them. */ protected readonly contextualKeywords: ReadonlySet; private index; private parseDepth; private statementBlockDepth; private recoveredImportDelimiterBoundary; /** * D65 rule 170: non-zero while `parseParameters` is reading an arrow's * parameter list — the one list a contextual function type can still type. * It is a field rather than an argument because `packages/web` overrides * `parseParameters()` and forwards to `super.parseParameters()`, so an added * argument would be silently dropped for every arrow inside a web module. */ private contextualParameterDepth; private readonly typeSyntax; private readonly patterns; private readonly declarations; private readonly classSyntax; private readonly controlFlow; private readonly modules; private readonly operators; private readonly postfix; private readonly primary; /** * The one object every collaborator is handed. Its properties are live reads * of the parser: the token cursor moves under the collaborators, so `index`, * `current()` and the diagnostics array must be the parser's own and not a * snapshot taken when the collaborator was built. */ private parserHost; constructor(tokens: readonly Token[], lexicalExtensions?: readonly CompilerLexicalExtension[]); parse(): ParseResult; parseExpressionFragment(): ExpressionParseResult; private recoverExpressionAssignment; protected parseStatement(): Statement | null; /** * The statement dispatcher. Each phase below answers for one family of * statement heads and returns `undefined` when it did not claim the * statement, so the order the phases run in is the order the grammar reads * them — the same order this method read them as one 402-line chain. */ private parseStatementBody; /** * The four statement heads that are decided before any modifier: the * `@context(...)` marker, `import`, `extern`, and `unsafe`. `undefined` means * no rule here claimed the statement and the next phase gets it. */ private parseModuleStatement; /** * What `export` can be followed by that is not an ordinary declaration: the * re-export forms, the JavaScript `export default` habit, a `readonly type`, * and the compiler-owned `@main` region, which is refused an export. */ private parseExportedStatement; /** * The declarations the `abstract` / `async` modifiers reach, and the two * statements that are spelled with a modifier word — `detach` and the retired * bare `async`. An installed extension is offered the statement first. */ private parseModifiedStatement; /** * The three contextual keywords whose statement shape no expression can have: * `match value:` above an indented `case`, `test "name":`, and `using x = …`. * Every other spelling of those words stays an ordinary name. */ private parseContextualKeywordStatement; /** * The shapes that are a removed statement or another language's habit: the * `invert x` toggle, Python's `raise`, and a declaration written with the * wrong keyword. Each is claimed only by the exact shape it had, so * `invert(...)`, `raise.field` and `value name` keep their own meanings. */ private parseRetiredStatementSpelling; /** * The statements that carry a value or a block and take no modifier: `return`, * `throw`, `assert`, `if`, `for`, `while`, `break`, `continue`, `try`, `pass`, * and the refusal for a clause with no block above it. */ private parseControlStatement; protected parseExtensionStatement(_start: number, _modifiers: { readonly exported: boolean; readonly abstract: boolean; readonly asynchronous: boolean; }): Statement | null | undefined; /** Lets an extension claim its own `unsafe ` before Core requires `js`. */ protected parseUnsafeExtensionStatement(_start: number): Statement | null | undefined; protected parseExtensionImport(_start: number): Statement | null | undefined; protected parseTypeParameters(): readonly TypeParameterDeclaration[] | null; /** * D55 rule 120 layer two: the `<...>` that follows a name in a *type* * position — `extends Stack` is the one place a type application is * written outside `parseTypeReference`, and it reads the arguments through * the same `checkTypeGreater`/`expectTypeGreater` pair so a nested * `Stack>` closes the way every annotation does. */ protected parseTypeArgumentList(): readonly TypeSyntax[]; protected parseParameters(): readonly Parameter[]; protected parseBlock(): readonly Statement[]; protected parseTypeReference(allowTrailingOptional?: boolean, initialized?: boolean): TypeReference; protected validateExtensionTypeArguments(_name: string, _arguments: readonly TypeSyntax[], _nameSpan: Span): boolean; protected parseExpression(minimumPrecedence?: number): Expression; protected parseExtensionExpression(_token: Token): Expression | undefined; protected parseExtensionNumericLiteral(token: Token, value: number, unit: string): Expression | undefined; protected parseNestedExpression(fragment: string, offset: number, bracketFragment?: boolean, sourceOffsets?: readonly number[]): Expression; protected createNestedParser(tokens: readonly Token[]): Parser; /** * An interpolation is parsed by a nested parser, so the nest continues the * budget rather than restarting it: without this, `MAX_PARSE_DEPTH` resets * at every level and only a JavaScript stack overflow ends a deeply nested * f-string, after the superlinear work is already paid. It is a method * rather than a constructor argument because `packages/web` and * `packages/node` override `createNestedParser`, so an added argument would * be silently dropped for exactly the modules that build one. */ protected inheritParseBudget(parent: Parser): void; private withParseDepth; private atStatementEnd; protected expectStatementEnd(): void; protected expectStatementBoundary(): void; private finishStatementBoundary; private statementBoundaryMessage; private describeInvertTarget; private synchronize; /** * D38 rule 47 (BRG-D2): an extern signature is the entire contract — there * is no body to infer from — so a parameter without a type used to degrade * to `unknown` and accept every argument silently. The escape hatch may * never lose air quietly: the missing type is reported at the parameter * itself, and the member keeps its place in the module contract so the use * site is not blamed for a declaration defect. */ protected reportUntypedExternParameters(parameters: readonly Parameter[]): void; /** * D38 rule 47, second half: the rejection of a body on an extern declaration * lands in the right place already, but "Expected the end of a statement" * never said why a body cannot be there. */ protected reportExternDeclarationBody(): boolean; /** * CLS-I5: `readonly` marks a data type, never a class member. A field's * read-only spelling is `const`; a method, getter, or constructor is * executable, so there is no read-only contract for the modifier to state * and pointing the author at `const` was advice they cannot take. */ protected reportClassMemberReadonly(modifier: Token | null, member: "field" | "executable", code: string): void; /** * The name slot of a `type`, `class`, or `enum` declaration. Answers the * token that names the declaration, or `null` when the slot held a word that * cannot name one — the declaration is skipped in that case, so the refusal * is the only report the mistake earns. * * Charter §5 puts a reserved-name refusal at the declaration, "rather than at * the uses that would lose to it". Three spellings reached this slot without * it. A reserved word never reached a declaration at all: `type null:` read * as an expression and answered with the statement-layout recovery, and * `class null:` and `enum null:` answered "Expected a class name" and six * cascading messages after it — none of them naming the rule. `readonly`, the * read-only view modifier, declared a type that every annotation then * answered with "Expected a type name". A guided spelling — `type Array:`, * `type str:` — declared a name every annotation rewrites to the type it is * guided to, so `const value: Array` reported "Unknown type 'List'". All * three are the same mistake, a name a type position cannot spell as itself, * and all three now say so here, once. */ private parseDeclarationName; protected skipMistypedDeclaration(): void; protected consumeNewlines(): void; protected expect(kind: TokenKind, message: string): Token; private checkTypeGreater; /** Consume one `>` from a generic close without changing shift lexing. */ private expectTypeGreater; private expectMemberName; protected match(kind: TokenKind): boolean; protected matchExtensionKeyword(value: string): boolean; /** * D30 item 16: a contextual keyword is an ordinary identifier token whose * spelling matches. `checkWord` asks the question without consuming; the * declaration shape decides at each statement head, and every other position * keeps the identifier reading. */ /** * D30 item 16: the words that stay hard-reserved now say so. A bare * "Expected a binding name" never told the reader that the spelling itself * was the problem, which is exactly the question a reserved word raises. */ protected reservedWordMessage(noun: string): string | null; private reservedWordMessageFor; protected expectBindingName(message: string, noun: string): Token; protected checkWord(value: string): boolean; protected matchWord(value: string): boolean; /** * Consumes a contextual keyword that a production requires — `from` in an * import, `as` in a namespace import — and reports it in the same voice as a * missing hard keyword when it is absent. */ protected expectWord(value: string, message: string): Token; protected check(kind: TokenKind): boolean; protected peekKind(distance: number): TokenKind; protected peekValue(distance: number): string; protected advance(): Token; /** * D54 rule 118 keeps prefix `!` a teaching diagnostic rather than a second * spelling of `not`; D86 rule 212 moved the report here because only the * parser knows the `!` stood before its operand. The rewrite carries the * spacing the word form needs, exactly as the lexer's own word-operator * fixes do: `!ready` becomes `not ready`, `and!ready` becomes `and not ready`. */ /** * D86 rule 212: `value! = next` names the unwrap on the left of a write. The * unwrap reads a value and proves it present; a write has neither a result * to unwrap nor a fact to prove, and assigning `null` back into an optional * is legitimate — so the target is the location itself. */ protected reportInvalidAssignmentTarget(expression: Expression): void; protected reportPrefixBang(bang: Token): void; protected current(): Token; protected previous(): Token; } //# sourceMappingURL=parser.d.ts.map