Skip to content

Commit

Permalink
feat: improve astToString, add tests for astToString (#873)
Browse files Browse the repository at this point in the history
  • Loading branch information
Hsiwe authored Nov 5, 2023
1 parent 6b443b3 commit 7827474
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 8 deletions.
7 changes: 7 additions & 0 deletions dev/configs/.changeset/pretty-dogs-film.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"arktype": patch
---

Improve static parse error contextual summaries

Thanks @Hsiwe! https://github.com/arktypeio/arktype/pull/873
20 changes: 20 additions & 0 deletions dev/test/astUtils.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { describe, it } from "mocha"
import type { astToString } from "../../src/parse/ast/utils.js"
import { attest } from "../attest/main.js"

describe("astToString", () => {
it("no parentheses if nested ast is an array", () => {
const t = {} as unknown as astToString<
[["number", "[]"], "|", "number"]
>
attest(t).typed as "'number[]|number'"
})
it("parentheses if nested ast is an infix expression", () => {
const t = {} as unknown as astToString<[["0", "|", "1"], "|", "string"]>
attest(t).typed as "'(0|1)|string'"
})
it('defaults to "..." if input is bad', () => {
const t = {} as unknown as astToString<["0", "///", "1"]>
attest(t).typed as "'...'"
})
})
30 changes: 22 additions & 8 deletions src/parse/ast/utils.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,26 @@
import type { Literalable } from "../../utils/generics.js"
import type { List, Literalable } from "../../utils/generics.js"
import type { Scanner } from "../string/shift/scanner.js"
import type { InfixExpression, PostfixExpression } from "./ast.js"

export type astToString<ast> = `'${astToStringRecurse<ast, "">}'`
export type astToString<ast> = `'${astToStringRecurse<ast>}'`

type astToStringRecurse<ast, result extends string> = ast extends [
infer head,
...infer tail
]
? astToStringRecurse<tail, `${result}${astToStringRecurse<head, "">}`>
type astToStringRecurse<ast> = ast extends PostfixExpression<
infer operator,
infer operand
>
? operator extends "[]"
? `${groupAst<operand>}[]`
: never
: ast extends InfixExpression<infer operator, infer l, infer r>
? operator extends "&" | "|" | "%" | Scanner.Comparator
? `${groupAst<l>}${operator}${groupAst<r>}`
: never
: ast extends Literalable
? `${result}${ast extends bigint ? `${ast}n` : ast}`
? `${ast extends bigint ? `${ast}n` : ast}`
: "..."

type groupAst<ast> = ast extends List
? ast[1] extends "[]"
? astToStringRecurse<ast>
: `(${astToStringRecurse<ast>})`
: astToStringRecurse<ast>

0 comments on commit 7827474

Please sign in to comment.