Last active
October 24, 2025 19:38
-
-
Save mkatychev/f205b30697927ee329ac9b5a64f1508d to your computer and use it in GitHub Desktop.
To run: `cargo +nightly -Zscript ./wit_doc_comment.rs`
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
| ---cargo | |
| [dependencies] | |
| tree-sitter-wit = { git = "https://github.com/bytecodealliance/tree-sitter-wit", version = "1.2.0" } | |
| tree-sitter = "0.25.10" | |
| --- | |
| use tree_sitter::{Parser, Point, Query, QueryCursor, StreamingIterator}; | |
| const WIT_FILE: &str = " | |
| /// DOC COMMENT `wasmcloud` | |
| package wasmcloud:bus@1.0.0; | |
| // NOT a doc comment! | |
| interface lattice { | |
| /// NO MATCH doc comment, it does not immediately precede an object | |
| no-match: func() -> bool; | |
| /// DOC COMMENT `call-target-interface` | |
| resource call-target-interface { | |
| constructor(namespace: string, %package: string, %interface: string); | |
| } | |
| /// DOC COMMENT for call-target-interface | |
| set-link-name: func(name: string, interfaces: list<call-target-interface>); | |
| } | |
| "; | |
| // match a doc comment string that is immediately followed by a node without the | |
| // `doc` field (!doc) | |
| const QUERY_STR: &str = "((_ (doc_comment)) @obj_comment . (_ !doc) @obj)"; | |
| fn main() { | |
| let mut parser = Parser::new(); | |
| parser | |
| .set_language(&tree_sitter_wit::LANGUAGE.into()) | |
| .expect("Error loading WIT grammar"); | |
| let tree = parser.parse(WIT_FILE, None).unwrap(); | |
| let root_node = tree.root_node(); | |
| let query = Query::new(&tree_sitter_wit::LANGUAGE.into(), QUERY_STR).unwrap(); | |
| let mut cursor = QueryCursor::new(); | |
| let mut matches = cursor.matches(&query, root_node, WIT_FILE.as_bytes()); | |
| while let Some(mat) = matches.next() { | |
| let [end, obj] = mat.captures.try_into().unwrap(); | |
| // https://docs.rs/tree-sitter/latest/tree_sitter/struct.Node.html#method.is_named | |
| if !obj.node.is_named() { | |
| continue; | |
| } | |
| // struct Point { row, column } | |
| let comment_start: Point = end.node.start_position(); | |
| let obj_start: Point = obj.node.start_position(); | |
| // this means our obj is not immediately preceded by doc comment | |
| if comment_start.row + 1 != obj_start.row { | |
| continue; | |
| } | |
| let doc_comment_str = &WIT_FILE[end.node.byte_range()].trim(); | |
| let obj_str = &WIT_FILE[obj.node.byte_range()].trim(); | |
| println!("<\n doc_comment[{comment_start}]: {doc_comment_str}"); | |
| println!(" obj[{obj_start}]: {obj_str}\n>"); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment