gitnexus 1.6.5-rc.37 → 1.6.5-rc.38

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * C++ argument-dependent lookup (ADL / Koenig lookup) — V1.
2
+ * C++ argument-dependent lookup (ADL / Koenig lookup).
3
3
  *
4
4
  * When ordinary unqualified lookup fails for a free-call site, ADL also
5
5
  * considers candidates declared in the **associated namespaces** of the
@@ -13,17 +13,18 @@
13
13
  * `using` anything. With V1 ADL: `audit::record` is discovered via
14
14
  * `audit::Event`'s associated namespace.
15
15
  *
16
- * ## V1 boundary
16
+ * ## Current boundary
17
17
  *
18
- * V1 covers ONE associated-entity rule: an argument that's a directly-named
18
+ * The current implementation covers ONE associated-entity rule: an argument that's a directly-named
19
19
  * class type (`audit::Event e`) contributes its **direct enclosing
20
- * namespace** to the candidate set. Anything else — pointer/reference
20
+ * namespace** to the candidate set. V2 extends that one step to
21
+ * pointer-typed class args (`audit::Event* p`, `audit::Event** pp`):
22
+ * they contribute the pointee class's enclosing namespace too. Reference
21
23
  * arguments, function-pointer arguments, template specializations,
22
- * base-class associated namespaces — is V2 closure work and is
23
- * deliberately excluded. The `cpp-adl-pointer-arg-boundary` fixture
24
- * locks the exclusion in CI.
24
+ * base-class associated namespaces, and the rest of the full closure are
25
+ * still deliberately excluded.
25
26
  *
26
- * V1 also short-circuits to ADL only when ordinary lookup is empty
27
+ * The current implementation also short-circuits to ADL only when ordinary lookup is empty
27
28
  * (`findCallableBindingInScope` returned undefined). ISO C++ would
28
29
  * normally merge ADL candidates with ordinary-lookup candidates and
29
30
  * run overload resolution over the union; V1 defers that merge to V2.
@@ -54,16 +55,16 @@
54
55
  import type { ParsedFile, SymbolDefinition } from '../../../../_shared/index.js';
55
56
  import type { ScopeResolutionIndexes } from '../../model/scope-resolution-indexes.js';
56
57
  /**
57
- * Per-argument shape information collected at capture time. ADL only
58
- * fires for arguments where `simpleClassName !== ''` AND `!isPointer`
59
- * AND `!isReference` — i.e., directly-named class-type values.
58
+ * Per-argument shape information collected at capture time. ADL fires for
59
+ * arguments where `simpleClassName !== ''` AND `!isReference`, including
60
+ * class pointers whose declarator chain resolves to a named class type.
60
61
  */
61
62
  export interface CppAdlArgInfo {
62
63
  /** Simple class-like type name (last segment of qualified name); empty
63
64
  * for primitives, literals, function pointers, template specs, etc. */
64
65
  readonly simpleClassName: string;
65
- /** True when the variable's declarator was a `pointer_declarator`. V1
66
- * excludes pointer-typed args (closure rules deferred to V2). */
66
+ /** True when the variable's declarator contained one or more
67
+ * `pointer_declarator` wrappers. */
67
68
  readonly isPointer: boolean;
68
69
  /** True when the variable's declarator was a `reference_declarator`. */
69
70
  readonly isReference: boolean;
@@ -105,8 +106,8 @@ export declare function populateCppAssociatedNamespaces(parsed: ParsedFile): voi
105
106
  *
106
107
  * Fires only when:
107
108
  * - the call site is not in `noAdlSites` (parenthesized form), AND
108
- * - at least one argument is a directly-named class type (not pointer,
109
- * not reference, not literal/primitive).
109
+ * - at least one argument resolves to a named class type (value or
110
+ * pointer, but not reference, function pointer, literal, or primitive).
110
111
  */
111
112
  export declare function pickCppAdlCandidates(site: {
112
113
  readonly name: string;
@@ -1,5 +1,5 @@
1
1
  /**
2
- * C++ argument-dependent lookup (ADL / Koenig lookup) — V1.
2
+ * C++ argument-dependent lookup (ADL / Koenig lookup).
3
3
  *
4
4
  * When ordinary unqualified lookup fails for a free-call site, ADL also
5
5
  * considers candidates declared in the **associated namespaces** of the
@@ -13,17 +13,18 @@
13
13
  * `using` anything. With V1 ADL: `audit::record` is discovered via
14
14
  * `audit::Event`'s associated namespace.
15
15
  *
16
- * ## V1 boundary
16
+ * ## Current boundary
17
17
  *
18
- * V1 covers ONE associated-entity rule: an argument that's a directly-named
18
+ * The current implementation covers ONE associated-entity rule: an argument that's a directly-named
19
19
  * class type (`audit::Event e`) contributes its **direct enclosing
20
- * namespace** to the candidate set. Anything else — pointer/reference
20
+ * namespace** to the candidate set. V2 extends that one step to
21
+ * pointer-typed class args (`audit::Event* p`, `audit::Event** pp`):
22
+ * they contribute the pointee class's enclosing namespace too. Reference
21
23
  * arguments, function-pointer arguments, template specializations,
22
- * base-class associated namespaces — is V2 closure work and is
23
- * deliberately excluded. The `cpp-adl-pointer-arg-boundary` fixture
24
- * locks the exclusion in CI.
24
+ * base-class associated namespaces, and the rest of the full closure are
25
+ * still deliberately excluded.
25
26
  *
26
- * V1 also short-circuits to ADL only when ordinary lookup is empty
27
+ * The current implementation also short-circuits to ADL only when ordinary lookup is empty
27
28
  * (`findCallableBindingInScope` returned undefined). ISO C++ would
28
29
  * normally merge ADL candidates with ordinary-lookup candidates and
29
30
  * run overload resolution over the union; V1 defers that merge to V2.
@@ -118,8 +119,8 @@ export function populateCppAssociatedNamespaces(parsed) {
118
119
  *
119
120
  * Fires only when:
120
121
  * - the call site is not in `noAdlSites` (parenthesized form), AND
121
- * - at least one argument is a directly-named class type (not pointer,
122
- * not reference, not literal/primitive).
122
+ * - at least one argument resolves to a named class type (value or
123
+ * pointer, but not reference, function pointer, literal, or primitive).
123
124
  */
124
125
  export function pickCppAdlCandidates(site, callerParsed, scopes, parsedFiles) {
125
126
  const key = siteKey(callerParsed.filePath, site.atRange.startLine, site.atRange.startCol);
@@ -128,12 +129,12 @@ export function pickCppAdlCandidates(site, callerParsed, scopes, parsedFiles) {
128
129
  const args = argInfoBySite.get(key);
129
130
  if (args === undefined || args.length === 0)
130
131
  return undefined;
131
- // Collect associated namespace QNames from every value-class-typed arg.
132
+ // Collect associated namespace QNames from every participating class-typed arg.
132
133
  const associatedNamespaces = new Set();
133
134
  for (const arg of args) {
134
135
  if (arg.simpleClassName === '')
135
136
  continue;
136
- if (arg.isPointer || arg.isReference)
137
+ if (arg.isReference)
137
138
  continue;
138
139
  const classDef = findCppClassDefBySimpleName(arg.simpleClassName, scopes);
139
140
  if (classDef === undefined)
@@ -657,14 +657,15 @@ function isParenthesizedFunctionCall(callNode) {
657
657
  }
658
658
  /**
659
659
  * Per-argument ADL classification: walk each argument of a free call and
660
- * decide whether it's a directly-named class type (V1 ADL fires) or
661
- * something V1 excludes (pointer, reference, primitive, literal, function
662
- * pointer, template specialization).
660
+ * decide whether it resolves to a directly-named class or class-pointer
661
+ * type (ADL fires) or to an excluded shape such as a reference, function
662
+ * pointer, primitive, literal, or template specialization.
663
663
  *
664
- * V1 only fires for value class-typed args: `void f(N::S); N::S s; f(s);`.
665
- * Pointer args (`N::S* p; f(p);`) intentionally return `simpleClassName=''`
666
- * to lock the V1 boundary — the `cpp-adl-pointer-arg-boundary` fixture
667
- * regression-tests this.
664
+ * Class-typed values and class pointers (`N::S`, `N::S*`, `N::S**`) all
665
+ * preserve the pointee class name for associated-namespace lookup.
666
+ * Function pointers remain excluded even when their return type names a
667
+ * class, because the associated entity is the pointed-to function type,
668
+ * not the return type.
668
669
  */
669
670
  function inferCppCallAdlArgs(callNode) {
670
671
  const argList = callNode.childForFieldName('arguments');
@@ -727,15 +728,23 @@ function lookupAdlIdentifierType(identNode) {
727
728
  continue;
728
729
  // Unwrap declarator chain to find pointer/reference markers and the
729
730
  // variable name. `init_declarator > pointer_declarator > identifier`
730
- // means pointer-typed; `init_declarator > reference_declarator > ...`
731
- // means reference-typed; bare `init_declarator > identifier` is value.
731
+ // means pointer-typed; repeated pointer wrappers still count as pointer
732
+ // typed; `init_declarator > reference_declarator > ...` means
733
+ // reference-typed; bare `init_declarator > identifier` is value.
734
+ // Function-pointer wrappers (`pointer_declarator > function_declarator`)
735
+ // must not contribute ADL associated namespaces.
732
736
  let isPointer = false;
733
737
  let isReference = false;
738
+ let isFunctionPointer = false;
734
739
  let inner = declarator;
735
740
  let nameText = null;
736
741
  let safety = 16; // bound walk depth defensively
737
742
  while (safety-- > 0) {
738
743
  if (inner.type === 'pointer_declarator') {
744
+ if (findFirstDescendantOfType(inner, 'function_declarator') !== null) {
745
+ isFunctionPointer = true;
746
+ break;
747
+ }
739
748
  isPointer = true;
740
749
  const next = inner.childForFieldName('declarator');
741
750
  if (next === null)
@@ -766,11 +775,15 @@ function lookupAdlIdentifierType(identNode) {
766
775
  inner = next;
767
776
  continue;
768
777
  }
778
+ if (inner.type === 'function_declarator') {
779
+ isFunctionPointer = true;
780
+ break;
781
+ }
769
782
  // Reached the leaf — usually `identifier`. Take its text.
770
783
  nameText = inner.text;
771
784
  break;
772
785
  }
773
- if (nameText !== varName)
786
+ if (isFunctionPointer || nameText !== varName)
774
787
  continue;
775
788
  const simpleClassName = extractAdlSimpleTypeName(typeNode);
776
789
  return { simpleClassName, isPointer, isReference };
@@ -778,9 +791,9 @@ function lookupAdlIdentifierType(identNode) {
778
791
  return EMPTY_ADL_ARG;
779
792
  }
780
793
  /** Extract the simple class-like type name from a `type:` field node.
781
- * Returns '' for primitives, template specializations, function pointers,
782
- * and any other shape V1 ADL doesn't support — those args are excluded
783
- * from associated-namespace closure. */
794
+ * Returns '' for primitives, template specializations, and any other
795
+ * unsupported type-only shape. Function pointers are filtered at the
796
+ * declarator level in `lookupAdlIdentifierType`. */
784
797
  function extractAdlSimpleTypeName(typeNode) {
785
798
  if (typeNode.type === 'primitive_type')
786
799
  return '';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gitnexus",
3
- "version": "1.6.5-rc.37",
3
+ "version": "1.6.5-rc.38",
4
4
  "description": "Graph-powered code intelligence for AI agents. Index any codebase, query via MCP or CLI.",
5
5
  "author": "Abhigyan Patwari",
6
6
  "license": "PolyForm-Noncommercial-1.0.0",