@@ -10,25 +10,31 @@ Lexer (logos) + parser (rowan) are resilient: collect errors, don't fail-fast.
1010crates/
1111 plotnik-lib/ # Core library
1212 src/
13+ diagnostics/ # Diagnostic infrastructure
14+ mod.rs # Diagnostics struct, DiagnosticBuilder
15+ message.rs # DiagnosticMessage, Severity, Fix
16+ printer.rs # DiagnosticsPrinter for rendering
1317 parser/ # Syntax infrastructure
1418 lexer.rs # Token definitions (logos)
1519 cst.rs # SyntaxKind enum
1620 ast.rs # Typed AST wrappers over CST
1721 core.rs # Parser infrastructure
1822 grammar.rs # Grammar rules
19- error.rs # Parse errors
2023 invariants.rs # Parser invariant checks
2124 mod.rs # Re-exports, Parse struct, parse()
2225 tests/ # Parser tests (snapshots)
26+ *_tests.rs # Test files (lexer_tests, ast_tests, cst_tests)
2327 query/ # Query processing
2428 mod.rs # Query struct, new(), pipeline
25- dump.rs # dump_* debug output methods
26- errors.rs # Error access methods
29+ dump.rs # dump_* debug output methods (test-only)
30+ printer.rs # QueryPrinter for AST output
31+ invariants.rs # Query invariant checks
2732 alt_kind.rs # Alternation validation
2833 named_defs.rs # Name resolution, symbol table
2934 ref_cycles.rs # Escape analysis (recursion validation)
3035 shape_cardinalities.rs # Shape inference
31- lib.rs # Re-exports Query
36+ *_tests.rs # Test files per module
37+ lib.rs # Re-exports Query, Diagnostics, Error
3238 plotnik-cli/ # CLI tool
3339 src/commands/ # Subcommands (debug, docs, langs)
3440 plotnik-langs/ # Tree-sitter language bindings
@@ -43,8 +49,7 @@ parser::parse() // Parse → CST
4349alt_kind :: validate () // Validate alternation kinds
4450named_defs :: resolve () // Resolve names → SymbolTable
4551ref_cycles :: validate () // Validate recursion termination
46- shape_cardinalities :: infer () // Infer shape cardinalities
47- shape_cardinalities :: validate () // Validate field constraints
52+ shape_cardinalities :: analyze () // Infer and validate shape cardinalities
4853```
4954
5055Module = "what", function = "action".
@@ -61,14 +66,14 @@ Run: `cargo run -p plotnik-cli -- <command>`
6166
6267Inputs: ` -q/--query <Q> ` , ` --query-file <F> ` , ` --source <S> ` , ` -s/--source-file <F> ` , ` -l/--lang <L> `
6368
64- Output: ` --show- query ` , ` --show -source ` , ` --only-symbols ` , ` --cst ` , ` --raw ` , ` --spans ` , ` --cardinalities `
69+ Output: ` --query ` , ` --source ` , ` --only-symbols ` , ` --cst ` , ` --raw ` , ` --spans ` , ` --cardinalities `
6570
6671``` sh
67- cargo run -p plotnik-cli -- debug -q ' (identifier) @id' --show- query
72+ cargo run -p plotnik-cli -- debug -q ' (identifier) @id' --query
6873cargo run -p plotnik-cli -- debug -q ' (identifier) @id' --only-symbols
69- cargo run -p plotnik-cli -- debug -s app.ts --show- source
70- cargo run -p plotnik-cli -- debug -s app.ts --show- source --raw
71- cargo run -p plotnik-cli -- debug -q ' (function_declaration) @fn' -s app.ts -l typescript --show- query
74+ cargo run -p plotnik-cli -- debug -s app.ts --source
75+ cargo run -p plotnik-cli -- debug -s app.ts --source --raw
76+ cargo run -p plotnik-cli -- debug -q ' (function_declaration) @fn' -s app.ts -l typescript --query
7277```
7378
7479## Syntax
@@ -79,9 +84,23 @@ SyntaxKind: `Root`, `Tree`, `Ref`, `Str`, `Field`, `Capture`, `Type`, `Quantifie
7984
8085Expr = ` Tree | Ref | Str | Alt | Seq | Capture | Quantifier | Field | NegatedField | Wildcard | Anchor ` . Quantifier/Capture wrap their target.
8186
82- ## Errors
87+ ## Diagnostics
8388
84- Stages: ` Parse ` → ` Validate ` → ` Resolve ` → ` Escape ` . Use ` Query::errors_for_stage() ` .
89+ ` Diagnostics ` struct collects errors/warnings across passes. Access per-pass or combined:
90+
91+ ``` rust
92+ query . parse_diagnostics () // Parse errors
93+ query . alt_kind_diagnostics () // Alternation validation
94+ query . resolve_diagnostics () // Name resolution
95+ query . ref_cycle_diagnostics () // Recursion validation
96+ query . shape_diagnostics () // Shape cardinality validation
97+ query . all_diagnostics () // All combined
98+ query . diagnostics () // Alias for all_diagnostics()
99+ ```
100+
101+ Render: ` query.render_diagnostics() ` or ` query.render_diagnostics_colored(bool) ` .
102+
103+ Check validity: ` query.is_valid() ` returns false if any pass has errors (warnings allowed).
85104
86105## Constraints
87106
@@ -120,7 +139,7 @@ fn my_test() {
120139 name: (identifier) @name)
121140 " # };
122141
123- let query = Query :: new (input );
142+ let query = Query :: new (input ). unwrap () ;
124143 assert! (query . is_valid ());
125144 insta :: assert_snapshot! (query . dump_ast (), @ "" ); // <-- empty string, always
126145}
@@ -138,7 +157,7 @@ Never write snapshot content manually. Let insta generate it.
138157** Test patterns:**
139158
140159- Valid parsing: ` assert!(query.is_valid()) ` + snapshot ` dump_*() ` output
141- - Error recovery: ` assert!(!query.is_valid()) ` + snapshot ` dump_errors ()` only
160+ - Error recovery: ` assert!(!query.is_valid()) ` + snapshot ` dump_diagnostics ()` only
142161
143162## Coverage
144163
@@ -162,9 +181,10 @@ They are excluded from test coverage because they're unreachable.
162181They usually wrap a specific assert.
163182It was done due to limitation of inline coverage exclusion in Rust.
164183But it seems to be useful to extract such invariant check helpers anyways:
184+
165185- if it just performs assertion and doesn't return value, it starts with ` assert_ `
166186- if it returns value, it's name consists of' ` ensure_ ` and some statement about return value
167- Find any of such files for more examples.
187+ Find any of such files for more examples.
168188
169189## Not implemented
170190
0 commit comments