File tree Expand file tree Collapse file tree
packages/core/src/scanner Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -60,3 +60,25 @@ pub fn read_server_host(s: &Server) -> String {
6060 let _host = s. host . clone ( ) ;
6161 s. host . to_uppercase ( )
6262}
63+
64+ // Tests mod block support — functions inside mod blocks must be captured
65+ mod handlers {
66+ pub fn handle_request ( data : & str ) -> String {
67+ data. to_uppercase ( )
68+ }
69+
70+ fn internal_helper ( ) -> bool {
71+ true
72+ }
73+ }
74+
75+ // Tests nested generic stripping
76+ pub struct Wrapper < T > {
77+ inner : Option < T > ,
78+ }
79+
80+ impl < T : fmt:: Display > Wrapper < Option < T > > {
81+ pub fn unwrap_display ( & self ) -> String {
82+ format ! ( "{:?}" , self . inner)
83+ }
84+ }
Original file line number Diff line number Diff line change @@ -379,6 +379,27 @@ describe('RustScanner', () => {
379379 expect ( calleeNames . some ( ( n ) => n . includes ( 'transform' ) ) ) . toBe ( true ) ;
380380 } ) ;
381381
382+ it ( 'should extract functions inside mod blocks' , ( ) => {
383+ const handleReq = docs . find (
384+ ( d ) => d . metadata . name === 'handle_request' && d . type === 'function'
385+ ) ;
386+ expect ( handleReq ) . toBeDefined ( ) ;
387+ expect ( handleReq ! . metadata . exported ) . toBe ( true ) ;
388+
389+ const helper = docs . find ( ( d ) => d . metadata . name === 'internal_helper' ) ;
390+ expect ( helper ) . toBeDefined ( ) ;
391+ expect ( helper ! . metadata . exported ) . toBe ( false ) ;
392+ } ) ;
393+
394+ it ( 'should strip nested generic type params from impl' , ( ) => {
395+ // impl<T: Display> Wrapper<Option<T>> → Wrapper, not Wrapper<Option<T>> or Wrapper>
396+ const method = docs . find ( ( d ) => d . metadata . name === 'Wrapper.unwrap_display' ) ;
397+ expect ( method ) . toBeDefined ( ) ;
398+ expect ( method ! . metadata . name ) . toBe ( 'Wrapper.unwrap_display' ) ;
399+ expect ( method ! . metadata . name ) . not . toContain ( '<' ) ;
400+ expect ( method ! . metadata . name ) . not . toContain ( '>' ) ;
401+ } ) ;
402+
382403 it ( 'should NOT include macros in callees' , ( ) => {
383404 // process_request calls format!() — should NOT be in callees
384405 const processReq = docs . find ( ( d ) => d . metadata . name === 'Server.process_request' ) ;
Original file line number Diff line number Diff line change 77 */
88
99export const RUST_QUERIES = {
10- // Free functions (top-level, not inside impl blocks)
10+ // All function_item nodes at any depth (including inside mod blocks).
11+ // Methods inside impl blocks are filtered out in the scanner code
12+ // by checking if the parent is a declaration_list (impl body).
1113 functions : `
12- (source_file
13- (function_item
14- name: (identifier) @name) @definition)
14+ (function_item
15+ name: (identifier) @name) @definition
1516 ` ,
1617
1718 // Struct definitions
Original file line number Diff line number Diff line change @@ -170,6 +170,11 @@ export class RustScanner implements Scanner {
170170 const defCapture = match . captures . find ( ( c ) => c . name === 'definition' ) ;
171171 if ( ! nameCapture || ! defCapture ) continue ;
172172
173+ // Skip functions inside impl blocks — those are captured by extractMethods.
174+ // Functions inside mod blocks (mod_item > declaration_list) should be kept.
175+ const parent = defCapture . node . parent ;
176+ if ( parent ?. type === 'declaration_list' && parent . parent ?. type === 'impl_item' ) continue ;
177+
173178 const name = nameCapture . node . text ;
174179 const node = defCapture . node ;
175180 const startLine = node . startPosition . row + 1 ;
@@ -327,8 +332,8 @@ export class RustScanner implements Scanner {
327332 const defCapture = match . captures . find ( ( c ) => c . name === 'definition' ) ;
328333 if ( ! receiverCapture || ! nameCapture || ! defCapture ) continue ;
329334
330- // Strip generic type params: Container<T> → Container
331- const receiverType = receiverCapture . node . text . replace ( / < . * > / , '' ) ;
335+ // Strip generic type params: Container<T> → Container, HashMap<String, Vec<u8>> → HashMap
336+ const receiverType = receiverCapture . node . text . split ( '<' ) [ 0 ] ;
332337 const methodName = nameCapture . node . text ;
333338 const qualifiedName = `${ receiverType } .${ methodName } ` ;
334339 const node = defCapture . node ;
You can’t perform that action at this time.
0 commit comments