diff --git a/shared/test/tools/lexicon_check.gleam b/shared/test/tools/lexicon_check.gleam index 5aa4f77..d2d986a 100644 --- a/shared/test/tools/lexicon_check.gleam +++ b/shared/test/tools/lexicon_check.gleam @@ -14,7 +14,6 @@ import gleam/int import gleam/io import gleam/list import gleam/result -import gleam/set.{type Set} import gleam/string import simplifile @@ -78,6 +77,17 @@ fn in_scope(doc: LexiconDoc) -> Bool { string.starts_with(doc.id, dev_mokkenstorm_prefix) } +// A batch compile (`atproto_sdl.parse_all`), not one `parse_in_tree` call +// per file: `parse_in_tree`'s `known_docs` only disambiguates dotted +// reference *syntax*, and its lowering pass builds an empty cross-file +// registry regardless (see atproto_sdl/lower's own doc comment on +// `lower_in_tree`), so a cross-file `@known` values-set reference (e.g. +// getFeedSkeleton's `dev.mokkenstorm.crate.defs#OwnershipStatus`) can never +// resolve through it even when the target document exists in the tree. +// `parse_all` builds one real registry from the whole batch up front, +// mirroring how `make gen`'s `atproto_sdl` CLI resolves the same kind of +// cross-file reference (its own hand-rolled registry, not `parse_all` +// itself, but the same shared-registry idea). fn load_tree(dir: String) -> Result(List(LexiconDoc), String) { use paths <- result.try( simplifile.get_files(dir) @@ -89,21 +99,22 @@ fn load_tree(dir: String) -> Result(List(LexiconDoc), String) { paths |> list.filter(string.ends_with(_, ".sdl")) |> list.map(fn(path) { #(nsid_of(dir, path), path) }) - let known_docs = sdl_paths |> list.map(fn(pair) { pair.0 }) |> set.from_list - list.try_map(sdl_paths, fn(pair) { parse_one(pair.0, pair.1, known_docs) }) -} - -fn parse_one( - nsid: String, - path: String, - known_docs: Set(String), -) -> Result(LexiconDoc, String) { - use source <- result.try( - simplifile.read(path) - |> result.map_error(fn(e) { path <> ": read failed: " <> string.inspect(e) }), + use sources <- result.try( + list.try_map(sdl_paths, fn(pair) { + let #(nsid, path) = pair + simplifile.read(path) + |> result.map(fn(source) { #(nsid, source) }) + |> result.map_error(fn(e) { + path <> ": read failed: " <> string.inspect(e) + }) + }), ) - atproto_sdl.parse_in_tree(source, nsid, known_docs) - |> result.map_error(fn(e) { path <> ": " <> error.describe(e) }) + atproto_sdl.parse_all(sources, []) + |> list.zip(sdl_paths) + |> list.try_map(fn(pair) { + let #(#(_nsid, parsed), #(_nsid_again, path)) = pair + parsed |> result.map_error(fn(e) { path <> ": " <> error.describe(e) }) + }) } fn nsid_of(dir: String, path: String) -> String {