Expand description
Re-implementation of IntelliJ’s PsiBuilderImpl (platform 251.27812.49, the one bundled with
Kotlin 2.4.20) and the Kotlin builder wrappers on top of it.
Semantics kept exactly:
- Whitespace/comments (
WHITE_SPACE,EOL/BLOCK/SHEBANG_COMMENT,DOC_COMMENT) are skipped lazily: byeof()/get_token_type()and bymark()(except for the very first marker), never byadvance_lexer(),error()ordone(). Positions are fixed up afterwards bybalanceWhiteSpacesusing each edge’sEdgeBinder(defaults: start markers skip leading trivia, done markers and error items exclude trailing trivia; an empty marker of a left-bound type —ERROR_ELEMENT,CONSTRUCTOR_DELEGATION_*— binds to the left). builder.error()adds an empty error item at the current raw lexeme, ignored if the last production entry is an error item at the same lexeme; when building, only the first error item per lexeme (in production order) survives.- Collapsed markers become one leaf; leaves of lazy-parseable kinds are reparsed with a fresh
builder into the same
TreeSink(seetree.rs), so the tree equals the compiler’s fully expanded PSI. - Token remaps survive
rollback_to.
Deviations: offsets are UTF-8 byte offsets (IntelliJ: UTF-16 units) — only compared with each
other, so behaviour is identical. No debug-mode checks, no ITokenTypeRemapper,
WhitespaceSkippedCallback, incremental reparse or recursive binders (Kotlin uses none).
Tokens outside the root marker are dropped (upstream logs an error).
Performance (none of it observable): builders take their vectors from a per-thread pool
(pool.rs), chameleons reuse the outer builder’s lexemes instead of re-lexing (LazyLeaf), and
a caller re-parsing similar text can reuse expanded chameleons (ChameleonCache). Measure with
cargo run -p ktrs-parser --release --example bench.
Structs§
- Chameleon
Cache - Lazy
Leaf - A leaf about to be built, with the outer builder’s (unremapped) lexemes covering it.
- Marker
- PsiBuilder
- Constructed (from recycled buffers) in
pool.rs. - Semantic
Whitespace Aware PsiBuilder - Tree
Sink
Enums§
- Edge
Binder - Decides where an element edge lands inside a run of whitespace/comment tokens:
the result is an index into
tokens(0 = before all of them,tokens.len()= after all). - Layer
Constants§
Traits§
- Lazy
Reparse - Reparses a lazy-parseable leaf into
sink;falseif its kind isn’t lazy (nothing emitted). Generic rather thandynso the per-leaf kind check inlines intocreate_leaf. - Marker
Host - Anything that owns the underlying
PsiBuilder(the builder itself, the Kotlin semantic-whitespace wrapper, theParser).