@@ -499,7 +499,7 @@ function extractConstDeclarators(declNode: TreeSitterNode, definitions: Definiti
499499 } ) ;
500500 // Phase 8.3f: extract function/arrow properties from object literals.
501501 if ( valueN . type === 'object' ) {
502- extractObjectLiteralFunctions ( valueN , definitions ) ;
502+ extractObjectLiteralFunctions ( valueN , nameN . text , definitions ) ;
503503 }
504504 }
505505 }
@@ -841,7 +841,7 @@ function handleVariableDecl(node: TreeSitterNode, ctx: ExtractorOutput): void {
841841 // Phase 8.3f: extract function/arrow properties from object literals so that
842842 // this.method() calls inside Object.defineProperty accessors can resolve them.
843843 if ( valueN . type === 'object' ) {
844- extractObjectLiteralFunctions ( valueN , ctx . definitions ) ;
844+ extractObjectLiteralFunctions ( valueN , nameN . text , ctx . definitions ) ;
845845 }
846846 } else if ( isConst && nameN . type === 'object_pattern' && ! hasFunctionScopeAncestor ( node ) ) {
847847 // Destructured bindings: const { handleToken, checkPermissions } = initAuth(...)
@@ -866,11 +866,20 @@ function handleVariableDecl(node: TreeSitterNode, ctx: ExtractorOutput): void {
866866/**
867867 * Phase 8.3f: extract function/arrow function properties from an object literal as standalone
868868 * definitions so that `this.method()` calls inside Object.defineProperty accessor functions can
869- * resolve them via the normal same-file definition lookup.
869+ * resolve them via the same-file definition lookup.
870870 *
871- * `const obj = { baz: () => {} }` → emits Definition { name: 'baz', kind: 'function' }
871+ * Definitions are emitted as qualified names (`obj.baz` rather than bare `baz`) to avoid
872+ * polluting the global definition index with common property names like `init`, `run`, or
873+ * `render`. The typeMap value stored by the caller also uses the qualified name so the resolver
874+ * looks up `lookup.byName('obj.baz')` rather than `lookup.byName('baz')`.
875+ *
876+ * `const obj = { baz: () => {} }` → emits Definition { name: 'obj.baz', kind: 'function' }
872877 */
873- function extractObjectLiteralFunctions ( objNode : TreeSitterNode , definitions : Definition [ ] ) : void {
878+ function extractObjectLiteralFunctions (
879+ objNode : TreeSitterNode ,
880+ varName : string ,
881+ definitions : Definition [ ] ,
882+ ) : void {
874883 for ( let i = 0 ; i < objNode . childCount ; i ++ ) {
875884 const child = objNode . child ( i ) ;
876885 if ( ! child ) continue ;
@@ -887,7 +896,7 @@ function extractObjectLiteralFunctions(objNode: TreeSitterNode, definitions: Def
887896 valueNode . type === 'function'
888897 ) {
889898 definitions . push ( {
890- name : keyName ,
899+ name : ` ${ varName } . ${ keyName } ` ,
891900 kind : 'function' ,
892901 line : nodeStartLine ( child ) ,
893902 endLine : nodeEndLine ( valueNode ) ,
@@ -897,7 +906,7 @@ function extractObjectLiteralFunctions(objNode: TreeSitterNode, definitions: Def
897906 const nameNode = child . childForFieldName ( 'name' ) ;
898907 if ( nameNode ) {
899908 definitions . push ( {
900- name : nameNode . text ,
909+ name : ` ${ varName } . ${ nameNode . text } ` ,
901910 kind : 'function' ,
902911 line : nodeStartLine ( child ) ,
903912 endLine : nodeEndLine ( child ) ,
@@ -1637,10 +1646,15 @@ function handleVarDeclaratorTypeMap(
16371646 }
16381647
16391648 // Phase 8.3f: seed composite pts keys for object literal properties.
1640- // `const obj = { baz: () => {} }` → typeMap['obj.baz'] = 'baz'
1641- // `const obj = { baz }` (shorthand) → typeMap['obj.baz'] = 'baz'
1649+ // `const obj = { baz: () => {} }` → typeMap['obj.baz'] = 'obj.baz'
1650+ // `const obj = { baz }` (shorthand) → typeMap['obj.baz'] = 'baz' (bare identifier target)
1651+ // `const obj = { baz: otherFn }` → typeMap['obj.baz'] = 'otherFn' (identifier alias)
1652+ //
1653+ // For function/arrow values, the value is the qualified name ('obj.baz') because
1654+ // extractObjectLiteralFunctions now registers definitions under that qualified name to avoid
1655+ // polluting the global index with bare property names like 'init', 'run', or 'render'.
16421656 // Enables accessor this-dispatch: when typeMap['getter:this'] = 'obj',
1643- // resolving this.baz() inside getter → typeMap['obj.baz'] → 'baz'.
1657+ // resolving this.baz() inside getter → typeMap['obj.baz'] → 'obj. baz' → lookup.byName('obj.baz') .
16441658 if ( valueN . type === 'object' ) {
16451659 for ( let i = 0 ; i < valueN . childCount ; i ++ ) {
16461660 const child = valueN . child ( i ) ;
@@ -1654,14 +1668,16 @@ function handleVarDeclaratorTypeMap(
16541668 const keyName =
16551669 keyNode . type === 'string' ? keyNode . text . replace ( / ^ [ ' " ] | [ ' " ] $ / g, '' ) : keyNode . text ;
16561670 if ( ! keyName ) continue ;
1671+ const qualifiedKey = `${ nameN . text } .${ keyName } ` ;
16571672 if (
16581673 valNode . type === 'arrow_function' ||
16591674 valNode . type === 'function_expression' ||
16601675 valNode . type === 'function'
16611676 ) {
1662- setTypeMapEntry ( typeMap , `${ nameN . text } .${ keyName } ` , keyName , 0.85 ) ;
1677+ // Store the qualified name so the resolver finds the qualified definition.
1678+ setTypeMapEntry ( typeMap , qualifiedKey , qualifiedKey , 0.85 ) ;
16631679 } else if ( valNode . type === 'identifier' ) {
1664- setTypeMapEntry ( typeMap , ` ${ nameN . text } . ${ keyName } ` , valNode . text , 0.85 ) ;
1680+ setTypeMapEntry ( typeMap , qualifiedKey , valNode . text , 0.85 ) ;
16651681 }
16661682 }
16671683 }
@@ -1759,9 +1775,8 @@ function handleDefinePropertyTypeMap(
17591775 if ( target ) {
17601776 setTypeMapEntry ( typeMap , `${ arg0 . text } .${ key } ` , target , 0.85 ) ;
17611777 }
1762- // Phase 8.3f: { get: getter } or { set: setter } → this inside getter/setter is arg0 (obj)
1763- const accessor = findDescriptorAccessor ( arg2 ) ;
1764- if ( accessor ) {
1778+ // Phase 8.3f: { get: getter } and/or { set: setter } → this inside each accessor is arg0 (obj)
1779+ for ( const accessor of findDescriptorAccessors ( arg2 ) ) {
17651780 setTypeMapEntry ( typeMap , `${ accessor } :this` , arg0 . text , 0.85 ) ;
17661781 }
17671782 } else {
@@ -1799,19 +1814,23 @@ function findDescriptorValue(desc: TreeSitterNode): string | undefined {
17991814}
18001815
18011816/**
1802- * Phase 8.3f: return the identifier text of a `get` or `set` accessor in a property descriptor.
1803- * `{ get: getter }` → 'getter'; `{ set: setter }` → 'setter'.
1817+ * Phase 8.3f: return the identifier texts of all `get` and `set` accessors in a property
1818+ * descriptor. `{ get: getter, set: setter }` → ['getter', 'setter'].
1819+ * Returns all accessors so that each one gets a `callerName:this = obj` typeMap entry.
18041820 */
1805- function findDescriptorAccessor ( desc : TreeSitterNode ) : string | undefined {
1806- if ( desc . type !== 'object' ) return undefined ;
1821+ function findDescriptorAccessors ( desc : TreeSitterNode ) : string [ ] {
1822+ if ( desc . type !== 'object' ) return [ ] ;
1823+ const result : string [ ] = [ ] ;
18071824 for ( let i = 0 ; i < desc . childCount ; i ++ ) {
18081825 const pair = desc . child ( i ) ;
18091826 if ( pair ?. type !== 'pair' ) continue ;
18101827 const key = pair . childForFieldName ( 'key' ) ;
18111828 const val = pair . childForFieldName ( 'value' ) ;
1812- if ( ( key ?. text === 'get' || key ?. text === 'set' ) && val ?. type === 'identifier' ) return val . text ;
1829+ if ( ( key ?. text === 'get' || key ?. text === 'set' ) && val ?. type === 'identifier' ) {
1830+ result . push ( val . text ) ;
1831+ }
18131832 }
1814- return undefined ;
1833+ return result ;
18151834}
18161835
18171836/** Seed composite pts keys for each property in a prototype object literal. */
0 commit comments