Skip to content

Commit

Permalink
Merge pull request #437 from markw65/visitor-types
Browse files Browse the repository at this point in the history
Better type checking for visitor
  • Loading branch information
hildjj authored Dec 9, 2023
2 parents 55e8b6e + 484d322 commit fe34d94
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 9 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ Released: TBD

### Minor Changes

- [#437](https://github.com/peggyjs/peggy/pull/437) Better type checking for visitor
- [#435](https://github.com/peggyjs/peggy/pull/435) Setup tsconfig to detect use of library functions from es6 or later
- [#438](https://github.com/peggyjs/peggy/pull/438) Make test build deterministic
- [#436](https://github.com/peggyjs/peggy/pull/436) Get rid of tsd
Expand Down
9 changes: 9 additions & 0 deletions lib/peg.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,15 @@ declare namespace ast {
| GrammarCharacterClass & { type: "class" }
;

type AllNodes =
| Expression
| Grammar
| Initializer
| Named
| Rule
| TopLevelInitializer
;

/** The main Peggy AST class returned by the parser. */
interface Grammar extends Node<"grammar"> {
/** Initializer that run once when importing generated parser module. */
Expand Down
25 changes: 16 additions & 9 deletions test/types/peg.test-d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -184,13 +184,11 @@ describe("peg.d.ts", () => {
it("creates an AST", () => {
const grammar = peggy.parser.parse(src);
expectExact<peggy.ast.Grammar>()(grammar)();
const visited: { [typ: string]: number } = {};
function add(typ: string): void {
if (!visited[typ]) {
visited[typ] = 1;
} else {
visited[typ]++;
}
type AstTypes = peggy.ast.AllNodes["type"];
const visited: { [typ in AstTypes]?: number } = {};
function add(typ: AstTypes): void {
const v = visited[typ] || 0;
visited[typ] = v + 1;
}

const visit = peggy.compiler.visitor.build({
Expand Down Expand Up @@ -444,9 +442,14 @@ describe("peg.d.ts", () => {
},
});

// Extract the keys from the visitor object
type DefinedKeys
= typeof visit extends peggy.compiler.visitor.Visitor<infer U>
? keyof U : never;

visit(grammar);

expect(Object.keys(visited).sort()).toStrictEqual([
const astKeys = [
"action",
"any",
"choice",
Expand All @@ -470,7 +473,11 @@ describe("peg.d.ts", () => {
"text",
"top_level_initializer",
"zero_or_more",
]);
] satisfies AstTypes[] satisfies DefinedKeys[];

expect(Object.keys(visited).sort()).toStrictEqual(astKeys);
expectExact<AstTypes[]>()(astKeys)();
expectExact<DefinedKeys[]>()(astKeys)();
});

it("compiles", () => {
Expand Down

0 comments on commit fe34d94

Please sign in to comment.