Replace docparse with a tree-sitter based parser - #30
Merged
Merged
Conversation
The SourcePawn docparse tool is deprecated and its C++ build no longer works with current toolchains. It also can't parse several current SourceMod includes (handles.inc, float.inc, entitylump.inc, tf2_stocks.inc), and its Rust post-processing panics on sourcemod.inc (`typedef Address = int64`), so the core bundle can't be regenerated. libalternator now parses includes itself: - a small preprocessor evaluates #if/#elseif/#else, records #defines and honours #endinput, blanking inactive code without shifting offsets - function bodies are blanked before parsing, since documentation never needs statements and unusual statement syntax could otherwise derail the parser - tree-sitter-sourcepawn parses declarations - doc comments attach to declarations by the same front/tail comment rules docparse used, and are parsed with spdcp - types, defaults and enum values are rendered in docparse's format so existing bundles don't churn Syntax errors inside declarations fail the file, like before, so history walks don't mistake a failed parse for removed symbols. spdcp is pinned to the commit from rumblefrog/sp-dcp#1, which upstreams the doc comment fixes (e.g. `@note` on its own line). Switch to the 0.5 release once published. Upstream SourceMod and third-party sources are vendored as a snapshot regression corpus (221 files). On the 189 of them docparse could handle, the output matches docparse apart from intended doc comment fixes. CI no longer builds SourcePawn; it tests the parser and builds chumbucket. Refs #29 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011dNCUV71HWmyb9MwBD4xhC
spdcp 0.5.0 carries the doc comment fixes from rumblefrog/sp-dcp#1, so drop the git pin. The Windows build failed compiling ntapi 0.3.6 (pulled in by mio 0.7 through tokio 1.15), which current Rust rejects for unaligned references to packed fields. Updating tokio within 1.x moves to mio 1.x, which no longer depends on ntapi. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011dNCUV71HWmyb9MwBD4xhC
This was referenced Sep 25, 2026
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
The upstream SourcePawn
docparsetool thatlibalternatorbound to over FFI is deprecated. It is also failing in practice:handles.inc,float.inc,entitylump.incandtf2_stocks.inc. Their pages on sourcemod.dev are stale.sourcemod.inc(typedef Address = int64inparse_type_signature), so the core bundle can't be regenerated at all.What
libalternatornow parses includes in Rust. The public API (alternator::consume) is unchanged, sochumbucketneeds no changes.preprocess.rs): evaluates#if/#elseif/#else/#endif(withdefined, macro values and arithmetic), records#defines and honours#endinput. Inactive code, directive lines and function bodies are blanked with spaces, so byte offsets and line numbers stay identical to the source.extract.rs): natives, forwards and stocks; methodmaps (including properties, constructors, destructors and aliases); enums and constants; enum structs and legacystructs; typedefs and typesets (including legacyfunctag/funcenum); and defines.comments.rs): comments attach to declarations using the same front/tail rules as the SourcePawn lexer docparse relied on, quirks included.expr.rs): types, defaults, dimensions and enum values are rendered in docparse's exact format. That meansint&vsHandle &h,1 << 0with parentheses dropped, decimal integers,%ffloats, and same-file macro expansion. Existing bundles therefore don't churn.Doc comments are still parsed by
spdcp, now 0.5.0, which includes the fixes from rumblefrog/sp-dcp#1.parse_type_signaturenow returnsOptioninstead of panicking.Tests
libalternator/tests/corpus: 221 upstream.inc/.spfiles from SourceMod, sm-json, ripext, SourceBans++, TTT, the IncludeLibrary collection and others. They're pinned and fetched bytests/update-corpus.sh, with licenses listed inSOURCES.md. Three sources from the manifests are left out because they have no license.tests/corpus.rs: snapshot test againsttests/expected/*.json. Update the snapshots withALTERNATOR_BLESS=1.tests/extract.rsand unit tests cover the preprocessor, comment attachment, expressions and each declaration kind.Parity with docparse
I built the old docparse locally and compared outputs on the 189 corpus files it (and its post-processing) could handle. Every symbol, kind, type,
decl, default, value and comment location matches. The only differences are intentional doc comment fixes:**/: 34 tags*/, e.g./** Ungag*/becameUnga: 6// Sectionlabel: 3 symbols@ paramtypos incURL.inc: previously dropped entirelyFiles the old pipeline couldn't handle now parse. Of the 221 files, only
cURL_header.incstill fails: it uses function-like macros inside an enum, which docparse couldn't handle either. That failure is recorded as a snapshot.End to end
I ran
chumbucket generateto continue the publishedcore.bundlefrom its recorded commit to current SourceMod master, which took 7 seconds. Every change traces to a real upstream edit:Handlemethodmap andWriteFileAsyncIsValidHandle@notes such as onOnMapStartCI
cargo test -p alternator -p schemaand buildschumbucketon Linux and Windows, on current action versions.tokiois updated within 1.x (1.15 → 1.53). The Windows build failed compilingntapi 0.3.6, pulled in bymio 0.7, which current Rust rejects.mio 1.xno longer uses it.edge_workeris no longer built: its pinnedwasm-bindgendoesn't compile on current Rust, and that is unrelated to this change.#29 (
@note)@noteforCloseHandle(116 of the 119 notes in SourceMod). The notes are missing from the site because the frontend only rendersbrief,param:*,returnanderror. That is fixed in sourcemod-dev/sourcemod-dev#20, which is merged.@noteon its own line (text on the following lines) used to be dropped and its text merged into the previous tag. That is fixed in spdcp 0.5.Fixes #29
🤖 Generated with Claude Code
https://claude.ai/code/session_011dNCUV71HWmyb9MwBD4xhC