gitnexus 1.6.6-rc.71 → 1.6.6-rc.73
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.
- package/dist/_shared/scope-resolution/symbol-definition.d.ts +4 -0
- package/dist/_shared/scope-resolution/symbol-definition.d.ts.map +1 -1
- package/dist/core/ingestion/languages/cpp/captures.js +17 -0
- package/dist/core/ingestion/languages/cpp/conversion-rank.d.ts +4 -2
- package/dist/core/ingestion/languages/cpp/conversion-rank.js +8 -3
- package/dist/core/ingestion/languages/cpp/query.js +6 -0
- package/dist/core/ingestion/languages/cpp/scope-resolver.js +6 -0
- package/dist/core/ingestion/languages/cpp/user-defined-conversions.d.ts +5 -0
- package/dist/core/ingestion/languages/cpp/user-defined-conversions.js +122 -0
- package/dist/core/ingestion/languages/typescript/import-target.d.ts +3 -0
- package/dist/core/ingestion/languages/typescript/import-target.js +1 -1
- package/dist/core/ingestion/languages/typescript/scope-resolver.js +5 -1
- package/dist/core/ingestion/scope-extractor.js +12 -0
- package/package.json +1 -1
- package/web/assets/{agent-BNViyptx.js → agent-ztCmSzAP.js} +55 -55
- package/web/assets/{architectureDiagram-UL44E2DR-DO5inHmm.js → architectureDiagram-UL44E2DR-UbBGKtKc.js} +1 -1
- package/web/assets/{chunk-LCXTWHL2-DhdrdQ7D.js → chunk-LCXTWHL2-CNag8uwS.js} +1 -1
- package/web/assets/{chunk-RG4AUYOV-DBj3-_VI.js → chunk-RG4AUYOV-BsPxAzSB.js} +1 -1
- package/web/assets/{classDiagram-KGZ6W3CR-BTB1tQAy.js → classDiagram-KGZ6W3CR-hyXalbgI.js} +1 -1
- package/web/assets/{classDiagram-v2-72OJOZXJ-V77T4eMR.js → classDiagram-v2-72OJOZXJ-BZvBt1Jw.js} +1 -1
- package/web/assets/{diagram-3NCE3AQN-4wwT76SR.js → diagram-3NCE3AQN-BPy1qvxM.js} +1 -1
- package/web/assets/{diagram-GF46GFSD-1KA4CdVb.js → diagram-GF46GFSD-DHZvmDr6.js} +1 -1
- package/web/assets/{diagram-QXG6HAR7-DyJXA8oH.js → diagram-QXG6HAR7-h2JaRLwM.js} +1 -1
- package/web/assets/{diagram-WEQXMOUZ-SaMOxwEm.js → diagram-WEQXMOUZ-BQasYj8c.js} +1 -1
- package/web/assets/{erDiagram-L5TCEMPS-CQrHY5G4.js → erDiagram-L5TCEMPS-CKNmoGli.js} +1 -1
- package/web/assets/{flowDiagram-H6V6AXG4-D76sobt4.js → flowDiagram-H6V6AXG4-BUtBrFuB.js} +1 -1
- package/web/assets/{index-C0tkkul6.js → index-BTynj0rU.js} +6 -6
- package/web/assets/{infoDiagram-3YFTVSEB-DSjuC3eN.js → infoDiagram-3YFTVSEB-FmBeKKHR.js} +1 -1
- package/web/assets/{ishikawaDiagram-BNXS4ZKH-BRvPjFcQ.js → ishikawaDiagram-BNXS4ZKH-CBIehaQ8.js} +1 -1
- package/web/assets/{kanban-definition-75IXJCU3-CvhjvMdi.js → kanban-definition-75IXJCU3-BkQHGPDZ.js} +1 -1
- package/web/assets/{mindmap-definition-2TDM6QVE-DAt0LLtT.js → mindmap-definition-2TDM6QVE-CtjovahQ.js} +1 -1
- package/web/assets/{pieDiagram-CU6KROY3-wcL42rsj.js → pieDiagram-CU6KROY3-DJ7mL2OO.js} +1 -1
- package/web/assets/{requirementDiagram-JXO7QTGE-6rMJxIMd.js → requirementDiagram-JXO7QTGE-BQ-a2UHa.js} +1 -1
- package/web/assets/{sequenceDiagram-VS2MUI6T-Qxw2CKq9.js → sequenceDiagram-VS2MUI6T-Dq-E41TD.js} +1 -1
- package/web/assets/{stateDiagram-7D4R322I-59Ejn7s2.js → stateDiagram-7D4R322I-DyXkAThk.js} +1 -1
- package/web/assets/{stateDiagram-v2-36443NZ5-DuJ-XKAm.js → stateDiagram-v2-36443NZ5-x6kVl63Y.js} +1 -1
- package/web/assets/{timeline-definition-O6YCAMPW-31ZPtVTp.js → timeline-definition-O6YCAMPW-CnIsqFeF.js} +1 -1
- package/web/assets/{vennDiagram-MWXL3ELB-DF2g9kQO.js → vennDiagram-MWXL3ELB-Ce24QI5i.js} +1 -1
- package/web/assets/{wardleyDiagram-CUQ6CDDI-DEhL8j4N.js → wardleyDiagram-CUQ6CDDI-BFmc79Jd.js} +1 -1
- package/web/assets/{xychartDiagram-N2JHSOCM-BhcF9p43.js → xychartDiagram-N2JHSOCM-CIcd2MDJ.js} +1 -1
- package/web/index.html +1 -1
|
@@ -50,6 +50,10 @@ export interface SymbolDefinition {
|
|
|
50
50
|
* `ScopeResolver.constraintCompatibility` hook during overload narrowing.
|
|
51
51
|
* Absent for symbols that have no constraints (the common case). */
|
|
52
52
|
templateConstraints?: unknown;
|
|
53
|
+
/** True when the producing language marked this callable as explicit.
|
|
54
|
+
* Currently used by C++ overload ranking to exclude explicit constructors
|
|
55
|
+
* from implicit user-defined conversion candidates. */
|
|
56
|
+
isExplicit?: boolean;
|
|
53
57
|
/** Links Method/Constructor/Property to owning Class/Struct/Trait nodeId */
|
|
54
58
|
ownerId?: string;
|
|
55
59
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"symbol-definition.d.ts","sourceRoot":"","sources":["../../src/scope-resolution/symbol-definition.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAEnD,MAAM,WAAW,kBAAkB;IACjC,wFAAwF;IACxF,IAAI,EAAE,MAAM,CAAC;IACb,8EAA8E;IAC9E,EAAE,EAAE,MAAM,GAAG,OAAO,GAAG,UAAU,GAAG,gBAAgB,GAAG,SAAS,CAAC;IACjE,4CAA4C;IAC5C,WAAW,EAAE,OAAO,GAAG,YAAY,GAAG,YAAY,GAAG,SAAS,GAAG,SAAS,CAAC;IAC3E,4EAA4E;IAC5E,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,SAAS,CAAC;IAChB;;+FAE2F;IAC3F,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;iHAC6G;IAC7G,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC;uFACmF;IACnF,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B;4FACwF;IACxF,oBAAoB,CAAC,EAAE,kBAAkB,EAAE,CAAC;IAC5C,6EAA6E;IAC7E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gGAAgG;IAChG,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gGAAgG;IAChG,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B;;;;;yEAKqE;IACrE,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,4EAA4E;IAC5E,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB"}
|
|
1
|
+
{"version":3,"file":"symbol-definition.d.ts","sourceRoot":"","sources":["../../src/scope-resolution/symbol-definition.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAEnD,MAAM,WAAW,kBAAkB;IACjC,wFAAwF;IACxF,IAAI,EAAE,MAAM,CAAC;IACb,8EAA8E;IAC9E,EAAE,EAAE,MAAM,GAAG,OAAO,GAAG,UAAU,GAAG,gBAAgB,GAAG,SAAS,CAAC;IACjE,4CAA4C;IAC5C,WAAW,EAAE,OAAO,GAAG,YAAY,GAAG,YAAY,GAAG,SAAS,GAAG,SAAS,CAAC;IAC3E,4EAA4E;IAC5E,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,SAAS,CAAC;IAChB;;+FAE2F;IAC3F,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;iHAC6G;IAC7G,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC;uFACmF;IACnF,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B;4FACwF;IACxF,oBAAoB,CAAC,EAAE,kBAAkB,EAAE,CAAC;IAC5C,6EAA6E;IAC7E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gGAAgG;IAChG,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gGAAgG;IAChG,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B;;;;;yEAKqE;IACrE,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B;;4DAEwD;IACxD,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,4EAA4E;IAC5E,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB"}
|
|
@@ -89,6 +89,9 @@ export function emitCppScopeCaptures(sourceText, filePath, cachedTree) {
|
|
|
89
89
|
if (arity.parameterTypeClasses !== undefined) {
|
|
90
90
|
grouped['@declaration.parameter-type-classes'] = syntheticCapture('@declaration.parameter-type-classes', fnNode, JSON.stringify(arity.parameterTypeClasses));
|
|
91
91
|
}
|
|
92
|
+
if (hasExplicitSpecifier(fnNode)) {
|
|
93
|
+
grouped['@declaration.is-explicit'] = syntheticCapture('@declaration.is-explicit', fnNode, 'true');
|
|
94
|
+
}
|
|
92
95
|
// Detect static storage class (file-local linkage)
|
|
93
96
|
if (hasStaticStorageClass(fnNode)) {
|
|
94
97
|
const nameText = grouped['@declaration.name']?.text;
|
|
@@ -1433,6 +1436,20 @@ function extractDeclaratorLeafName(node) {
|
|
|
1433
1436
|
}
|
|
1434
1437
|
return null;
|
|
1435
1438
|
}
|
|
1439
|
+
/**
|
|
1440
|
+
* Check if a C++ declaration has an `explicit` specifier. Tree-sitter-cpp
|
|
1441
|
+
* exposes `explicit` as a direct keyword child on constructor declarations in
|
|
1442
|
+
* current grammar builds; the bounded text prefix keeps this resilient across
|
|
1443
|
+
* small grammar shape differences without scanning whole function bodies.
|
|
1444
|
+
*/
|
|
1445
|
+
function hasExplicitSpecifier(node) {
|
|
1446
|
+
for (let i = 0; i < node.childCount; i++) {
|
|
1447
|
+
const child = node.child(i);
|
|
1448
|
+
if (child !== null && child.text === 'explicit')
|
|
1449
|
+
return true;
|
|
1450
|
+
}
|
|
1451
|
+
return /\bexplicit\b/.test(node.text.slice(0, 128));
|
|
1452
|
+
}
|
|
1436
1453
|
/**
|
|
1437
1454
|
* Check if a C++ function_definition or declaration has `static` storage class.
|
|
1438
1455
|
*/
|
|
@@ -12,7 +12,8 @@
|
|
|
12
12
|
* - rank 2: standard conversion (arithmetic, nullptr -> T*, T* -> bool,
|
|
13
13
|
* T* -> void*)
|
|
14
14
|
* - rank 3: nullptr -> bool (kept worse than nullptr -> T*)
|
|
15
|
-
* - rank 4:
|
|
15
|
+
* - rank 4: user-defined conversion (one-step, conservative)
|
|
16
|
+
* - rank 5: ellipsis conversion (worst viable)
|
|
16
17
|
* - Infinity: mismatch (string -> int, user types, unsupported shapes)
|
|
17
18
|
*
|
|
18
19
|
* This function is intentionally C++-specific. Other languages may define
|
|
@@ -23,7 +24,8 @@ import type { ParameterTypeClass } from '../../../../_shared/index.js';
|
|
|
23
24
|
* Return the conversion rank from `argType` to `paramType`.
|
|
24
25
|
*
|
|
25
26
|
* @returns 0 for exact match, 1 for integral promotion, 2 for standard
|
|
26
|
-
* conversion, 3 for nullptr -> bool, 4 for
|
|
27
|
+
* conversion, 3 for nullptr -> bool, 4 for user-defined conversion,
|
|
28
|
+
* 5 for ellipsis, Infinity
|
|
27
29
|
* for mismatch.
|
|
28
30
|
*/
|
|
29
31
|
export declare function cppConversionRank(argType: string, paramType: string, argTypeClass?: ParameterTypeClass, paramTypeClass?: ParameterTypeClass): number;
|
|
@@ -12,12 +12,14 @@
|
|
|
12
12
|
* - rank 2: standard conversion (arithmetic, nullptr -> T*, T* -> bool,
|
|
13
13
|
* T* -> void*)
|
|
14
14
|
* - rank 3: nullptr -> bool (kept worse than nullptr -> T*)
|
|
15
|
-
* - rank 4:
|
|
15
|
+
* - rank 4: user-defined conversion (one-step, conservative)
|
|
16
|
+
* - rank 5: ellipsis conversion (worst viable)
|
|
16
17
|
* - Infinity: mismatch (string -> int, user types, unsupported shapes)
|
|
17
18
|
*
|
|
18
19
|
* This function is intentionally C++-specific. Other languages may define
|
|
19
20
|
* their own `ConversionRankFn` in the future.
|
|
20
21
|
*/
|
|
22
|
+
import { hasCppUserDefinedConversion } from './user-defined-conversions.js';
|
|
21
23
|
/** Set of normalized arithmetic types that support implicit conversion. */
|
|
22
24
|
const ARITHMETIC = new Set(['int', 'double', 'char', 'bool']);
|
|
23
25
|
/** Integral promotion targets: char -> int and bool -> int are rank 1. */
|
|
@@ -29,7 +31,8 @@ const INTEGRAL_PROMOTION = new Map([
|
|
|
29
31
|
* Return the conversion rank from `argType` to `paramType`.
|
|
30
32
|
*
|
|
31
33
|
* @returns 0 for exact match, 1 for integral promotion, 2 for standard
|
|
32
|
-
* conversion, 3 for nullptr -> bool, 4 for
|
|
34
|
+
* conversion, 3 for nullptr -> bool, 4 for user-defined conversion,
|
|
35
|
+
* 5 for ellipsis, Infinity
|
|
33
36
|
* for mismatch.
|
|
34
37
|
*/
|
|
35
38
|
export function cppConversionRank(argType, paramType, argTypeClass, paramTypeClass) {
|
|
@@ -37,7 +40,7 @@ export function cppConversionRank(argType, paramType, argTypeClass, paramTypeCla
|
|
|
37
40
|
return exactShapeCompatible(argTypeClass, paramTypeClass) ? 0 : Infinity;
|
|
38
41
|
}
|
|
39
42
|
if (paramType === '...')
|
|
40
|
-
return
|
|
43
|
+
return 5;
|
|
41
44
|
if (INTEGRAL_PROMOTION.get(argType) === paramType)
|
|
42
45
|
return 1;
|
|
43
46
|
if (ARITHMETIC.has(argType) && ARITHMETIC.has(paramType))
|
|
@@ -50,6 +53,8 @@ export function cppConversionRank(argType, paramType, argTypeClass, paramTypeCla
|
|
|
50
53
|
return 2;
|
|
51
54
|
if (isPointer(argTypeClass) && isPointer(paramTypeClass) && paramType === 'void')
|
|
52
55
|
return 2;
|
|
56
|
+
if (hasCppUserDefinedConversion(argType, paramType))
|
|
57
|
+
return 4;
|
|
53
58
|
return Infinity;
|
|
54
59
|
}
|
|
55
60
|
function isPointer(typeClass) {
|
|
@@ -224,6 +224,12 @@ const CPP_SCOPE_QUERY = `
|
|
|
224
224
|
declarator: (function_declarator
|
|
225
225
|
declarator: (field_identifier) @declaration.name))) @declaration.method
|
|
226
226
|
|
|
227
|
+
;; Constructor prototype in class body: User(int id);
|
|
228
|
+
(field_declaration_list
|
|
229
|
+
(declaration
|
|
230
|
+
declarator: (function_declarator
|
|
231
|
+
declarator: (identifier) @declaration.name)) @declaration.method)
|
|
232
|
+
|
|
227
233
|
;; Method prototype with reference return: User& getRef();
|
|
228
234
|
(field_declaration
|
|
229
235
|
declarator: (reference_declarator
|
|
@@ -14,6 +14,7 @@ import { populateCppAssociatedNamespaces, clearCppAdlState, pickCppAdlCandidates
|
|
|
14
14
|
import { clearCppInlineNamespaces, populateCppInlineNamespaceScopes, resolveCppQualifiedNamespaceMember, } from './inline-namespaces.js';
|
|
15
15
|
import { populateCppRangeBindings } from './range-bindings.js';
|
|
16
16
|
import { cppConstraintCompatibility } from './constraint-filter.js';
|
|
17
|
+
import { clearCppUserDefinedConversions, populateCppUserDefinedConversions, } from './user-defined-conversions.js';
|
|
17
18
|
/**
|
|
18
19
|
* C++ `ScopeResolver` registered in `SCOPE_RESOLVERS` and consumed by
|
|
19
20
|
* the generic `runScopeResolution` orchestrator (RFC #909 Ring 3).
|
|
@@ -39,6 +40,7 @@ export const cppScopeResolver = {
|
|
|
39
40
|
clearCppDependentBases();
|
|
40
41
|
clearCppAdlState();
|
|
41
42
|
clearCppInlineNamespaces();
|
|
43
|
+
clearCppUserDefinedConversions();
|
|
42
44
|
return scanCppHeaderFiles(repoPath);
|
|
43
45
|
},
|
|
44
46
|
resolveImportTarget: (targetRaw, fromFile, allFilePaths, resolutionConfig) => {
|
|
@@ -80,6 +82,10 @@ export const cppScopeResolver = {
|
|
|
80
82
|
// by ADL (U2 of plan 2026-05-13-001) to identify each argument type's
|
|
81
83
|
// associated namespace for Koenig lookup.
|
|
82
84
|
populateCppAssociatedNamespaces(parsed);
|
|
85
|
+
// Build conservative one-step user-defined conversion facts for
|
|
86
|
+
// overload ranking (#1631): implicit converting constructors only,
|
|
87
|
+
// with no chaining or conversion-operator handling.
|
|
88
|
+
populateCppUserDefinedConversions(parsed);
|
|
83
89
|
},
|
|
84
90
|
// Resolve recorded template-class → dependent-base simple names to
|
|
85
91
|
// class nodeIds for two-phase template lookup (U3 of plan
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { ParsedFile } from '../../../../_shared/index.js';
|
|
2
|
+
export declare function clearCppUserDefinedConversions(): void;
|
|
3
|
+
export declare function hasCppUserDefinedConversion(argType: string, paramType: string): boolean;
|
|
4
|
+
export declare function populateCppUserDefinedConversions(parsed: ParsedFile): void;
|
|
5
|
+
export declare function registerCppUserDefinedConversion(argType: string, paramType: string): void;
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { normalizeCppParamType } from './arity-metadata.js';
|
|
2
|
+
const userDefinedConversions = new Set();
|
|
3
|
+
const pendingUserDefinedConversions = [];
|
|
4
|
+
const classIdentitiesBySimpleName = new Map();
|
|
5
|
+
export function clearCppUserDefinedConversions() {
|
|
6
|
+
userDefinedConversions.clear();
|
|
7
|
+
pendingUserDefinedConversions.length = 0;
|
|
8
|
+
classIdentitiesBySimpleName.clear();
|
|
9
|
+
}
|
|
10
|
+
export function hasCppUserDefinedConversion(argType, paramType) {
|
|
11
|
+
return userDefinedConversions.has(conversionKey(argType, paramType));
|
|
12
|
+
}
|
|
13
|
+
export function populateCppUserDefinedConversions(parsed) {
|
|
14
|
+
const scopesById = new Map();
|
|
15
|
+
for (const scope of parsed.scopes)
|
|
16
|
+
scopesById.set(scope.id, scope);
|
|
17
|
+
for (const classScope of parsed.scopes) {
|
|
18
|
+
if (classScope.kind !== 'Class')
|
|
19
|
+
continue;
|
|
20
|
+
const classDef = classScope.ownedDefs.find(isClassLike);
|
|
21
|
+
if (classDef !== undefined)
|
|
22
|
+
recordClassIdentity(classDef);
|
|
23
|
+
}
|
|
24
|
+
for (const classScope of parsed.scopes) {
|
|
25
|
+
if (classScope.kind !== 'Class')
|
|
26
|
+
continue;
|
|
27
|
+
const classDef = classScope.ownedDefs.find(isClassLike);
|
|
28
|
+
if (classDef === undefined)
|
|
29
|
+
continue;
|
|
30
|
+
const className = normalizedSimpleName(classDef);
|
|
31
|
+
if (className === '')
|
|
32
|
+
continue;
|
|
33
|
+
const methodDefs = collectClassMethodDefs(classScope.id, parsed, scopesById);
|
|
34
|
+
for (const def of methodDefs) {
|
|
35
|
+
const simpleName = simpleNameOf(def);
|
|
36
|
+
if (simpleName === className && def.parameterTypes?.length === 1) {
|
|
37
|
+
if (def.isExplicit === true)
|
|
38
|
+
continue;
|
|
39
|
+
registerPendingCppUserDefinedConversion(def.parameterTypes[0], className, className);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
rebuildCppUserDefinedConversions();
|
|
44
|
+
}
|
|
45
|
+
export function registerCppUserDefinedConversion(argType, paramType) {
|
|
46
|
+
if (argType === '' || paramType === '')
|
|
47
|
+
return;
|
|
48
|
+
if (argType === paramType)
|
|
49
|
+
return;
|
|
50
|
+
userDefinedConversions.add(conversionKey(argType, paramType));
|
|
51
|
+
}
|
|
52
|
+
function collectClassMethodDefs(classScopeId, parsed, scopesById) {
|
|
53
|
+
const methods = [];
|
|
54
|
+
const classScope = scopesById.get(classScopeId);
|
|
55
|
+
if (classScope === undefined)
|
|
56
|
+
return methods;
|
|
57
|
+
for (const def of classScope.ownedDefs) {
|
|
58
|
+
if (isCallableMember(def))
|
|
59
|
+
methods.push(def);
|
|
60
|
+
}
|
|
61
|
+
for (const scope of parsed.scopes) {
|
|
62
|
+
if (scope.parent !== classScopeId)
|
|
63
|
+
continue;
|
|
64
|
+
if (scope.kind === 'Class')
|
|
65
|
+
continue;
|
|
66
|
+
for (const def of scope.ownedDefs) {
|
|
67
|
+
if (isCallableMember(def))
|
|
68
|
+
methods.push(def);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return methods;
|
|
72
|
+
}
|
|
73
|
+
function conversionKey(argType, paramType) {
|
|
74
|
+
return `${argType}\0${paramType}`;
|
|
75
|
+
}
|
|
76
|
+
function registerPendingCppUserDefinedConversion(argType, paramType, ownerClassName) {
|
|
77
|
+
if (argType === '' || paramType === '')
|
|
78
|
+
return;
|
|
79
|
+
if (argType === paramType)
|
|
80
|
+
return;
|
|
81
|
+
pendingUserDefinedConversions.push({ argType, paramType, ownerClassName });
|
|
82
|
+
}
|
|
83
|
+
function rebuildCppUserDefinedConversions() {
|
|
84
|
+
userDefinedConversions.clear();
|
|
85
|
+
for (const conversion of pendingUserDefinedConversions) {
|
|
86
|
+
if (isAmbiguousClassName(conversion.ownerClassName))
|
|
87
|
+
continue;
|
|
88
|
+
userDefinedConversions.add(conversionKey(conversion.argType, conversion.paramType));
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
function recordClassIdentity(def) {
|
|
92
|
+
const simpleName = normalizedSimpleName(def);
|
|
93
|
+
if (simpleName === '')
|
|
94
|
+
return;
|
|
95
|
+
const identities = classIdentitiesBySimpleName.get(simpleName) ?? new Set();
|
|
96
|
+
identities.add(normalizedQualifiedClassName(def));
|
|
97
|
+
classIdentitiesBySimpleName.set(simpleName, identities);
|
|
98
|
+
}
|
|
99
|
+
function isAmbiguousClassName(simpleName) {
|
|
100
|
+
return (classIdentitiesBySimpleName.get(simpleName)?.size ?? 0) > 1;
|
|
101
|
+
}
|
|
102
|
+
function normalizedQualifiedClassName(def) {
|
|
103
|
+
const qualifiedName = def.qualifiedName ?? simpleNameOf(def);
|
|
104
|
+
if (qualifiedName === '' || !qualifiedName.includes('.'))
|
|
105
|
+
return `${def.filePath}:${def.nodeId}`;
|
|
106
|
+
return qualifiedName
|
|
107
|
+
.split('.')
|
|
108
|
+
.map((part) => normalizeCppParamType(part))
|
|
109
|
+
.join('.');
|
|
110
|
+
}
|
|
111
|
+
function normalizedSimpleName(def) {
|
|
112
|
+
return normalizeCppParamType(simpleNameOf(def));
|
|
113
|
+
}
|
|
114
|
+
function simpleNameOf(def) {
|
|
115
|
+
return def.qualifiedName?.split('.').pop() ?? def.qualifiedName ?? '';
|
|
116
|
+
}
|
|
117
|
+
function isClassLike(def) {
|
|
118
|
+
return def.type === 'Class' || def.type === 'Struct' || def.type === 'Interface';
|
|
119
|
+
}
|
|
120
|
+
function isCallableMember(def) {
|
|
121
|
+
return def.type === 'Method' || def.type === 'Constructor';
|
|
122
|
+
}
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
*/
|
|
16
16
|
import type { ParsedImport, WorkspaceIndex } from '../../../../_shared/index.js';
|
|
17
17
|
import { SupportedLanguages } from '../../../../_shared/index.js';
|
|
18
|
+
import type { SuffixIndex } from '../../import-resolvers/utils.js';
|
|
18
19
|
import type { TsconfigPaths } from '../../language-config.js';
|
|
19
20
|
export interface TsResolveContext {
|
|
20
21
|
readonly fromFile: string;
|
|
@@ -28,6 +29,8 @@ export interface TsResolveContext {
|
|
|
28
29
|
readonly normalizedFileList?: readonly string[];
|
|
29
30
|
/** Per-call resolution cache to dedupe repeated lookups. */
|
|
30
31
|
readonly resolveCache?: Map<string, string | null>;
|
|
32
|
+
/** Prebuilt suffix index for O(1)-style package/absolute import matching. */
|
|
33
|
+
readonly index?: SuffixIndex;
|
|
31
34
|
/** Parsed tsconfig path-aliases. `null` = no aliases configured. */
|
|
32
35
|
readonly tsconfigPaths?: TsconfigPaths | null;
|
|
33
36
|
/** JavaScript vs TypeScript switch — affects the extensions the
|
|
@@ -48,7 +48,7 @@ export function resolveTsTarget(targetRaw, ctx) {
|
|
|
48
48
|
const allFileList = ctx.allFileList ?? Array.from(ctx.allFilePaths);
|
|
49
49
|
const normalizedFileList = ctx.normalizedFileList ?? allFileList.map((f) => f.toLowerCase());
|
|
50
50
|
const resolveCache = ctx.resolveCache ?? new Map();
|
|
51
|
-
return resolveImportPath(ctx.fromFile, targetRaw, ctx.allFilePaths, allFileList, normalizedFileList, resolveCache, language, ctx.tsconfigPaths ?? null);
|
|
51
|
+
return resolveImportPath(ctx.fromFile, targetRaw, ctx.allFilePaths, allFileList, normalizedFileList, resolveCache, language, ctx.tsconfigPaths ?? null, ctx.index);
|
|
52
52
|
}
|
|
53
53
|
function narrowTsContext(workspaceIndex) {
|
|
54
54
|
const ctx = workspaceIndex;
|
|
@@ -16,6 +16,7 @@ import { buildMro, defaultLinearize } from '../../scope-resolution/passes/mro.js
|
|
|
16
16
|
import { populateClassOwnedMembers } from '../../scope-resolution/scope/walkers.js';
|
|
17
17
|
import { typescriptProvider } from '../typescript.js';
|
|
18
18
|
import { loadTsconfigPaths } from '../../language-config.js';
|
|
19
|
+
import { buildSuffixIndex } from '../../import-resolvers/utils.js';
|
|
19
20
|
import { typescriptArityCompatibility, typescriptMergeBindings, resolveTsTarget, } from './index.js';
|
|
20
21
|
/**
|
|
21
22
|
* Build a `resolveImportTarget` adapter that memoizes the workspace
|
|
@@ -35,11 +36,13 @@ function makeTsResolveImportTarget() {
|
|
|
35
36
|
return (targetRaw, fromFile, allFilePaths, resolutionConfig) => {
|
|
36
37
|
if (cached === null || cached.key !== allFilePaths) {
|
|
37
38
|
const allFileList = Array.from(allFilePaths);
|
|
39
|
+
const normalizedFileList = allFileList.map((f) => f.toLowerCase());
|
|
38
40
|
cached = {
|
|
39
41
|
key: allFilePaths,
|
|
40
42
|
allFilePaths: new Set(allFilePaths),
|
|
41
43
|
allFileList,
|
|
42
|
-
normalizedFileList
|
|
44
|
+
normalizedFileList,
|
|
45
|
+
index: buildSuffixIndex(normalizedFileList, allFileList),
|
|
43
46
|
resolveCache: new Map(),
|
|
44
47
|
};
|
|
45
48
|
}
|
|
@@ -49,6 +52,7 @@ function makeTsResolveImportTarget() {
|
|
|
49
52
|
allFilePaths: cached.allFilePaths,
|
|
50
53
|
allFileList: cached.allFileList,
|
|
51
54
|
normalizedFileList: cached.normalizedFileList,
|
|
55
|
+
index: cached.index,
|
|
52
56
|
resolveCache: cached.resolveCache,
|
|
53
57
|
tsconfigPaths: cfg?.tsconfigPaths ?? null,
|
|
54
58
|
};
|
|
@@ -398,6 +398,7 @@ function buildDefFromDeclarationMatch(match, anchor, filePath) {
|
|
|
398
398
|
const declaredType = match['@declaration.field-type']?.text;
|
|
399
399
|
const returnType = match['@declaration.return-type']?.text;
|
|
400
400
|
const templateConstraints = parseJsonCapture(match['@declaration.template-constraints']);
|
|
401
|
+
const isExplicit = parseBooleanCapture(match['@declaration.is-explicit']);
|
|
401
402
|
return {
|
|
402
403
|
nodeId: makeDefId(filePath, anchor.range, type, nameCap.text),
|
|
403
404
|
filePath,
|
|
@@ -411,6 +412,7 @@ function buildDefFromDeclarationMatch(match, anchor, filePath) {
|
|
|
411
412
|
...(returnType !== undefined ? { returnType } : {}),
|
|
412
413
|
...(templateArguments !== undefined ? { templateArguments } : {}),
|
|
413
414
|
...(templateConstraints !== undefined ? { templateConstraints } : {}),
|
|
415
|
+
...(isExplicit === true ? { isExplicit: true } : {}),
|
|
414
416
|
};
|
|
415
417
|
}
|
|
416
418
|
/** Parse an opaque JSON payload synthesized by per-language captures
|
|
@@ -433,6 +435,15 @@ function parseIntCapture(cap) {
|
|
|
433
435
|
const n = Number.parseInt(cap.text, 10);
|
|
434
436
|
return Number.isFinite(n) ? n : undefined;
|
|
435
437
|
}
|
|
438
|
+
function parseBooleanCapture(cap) {
|
|
439
|
+
if (cap === undefined)
|
|
440
|
+
return undefined;
|
|
441
|
+
if (cap.text === 'true')
|
|
442
|
+
return true;
|
|
443
|
+
if (cap.text === 'false')
|
|
444
|
+
return false;
|
|
445
|
+
return undefined;
|
|
446
|
+
}
|
|
436
447
|
function parseJsonParameterTypeClassesCapture(cap) {
|
|
437
448
|
if (cap === undefined)
|
|
438
449
|
return undefined;
|
|
@@ -843,6 +854,7 @@ const KNOWN_SUB_TAGS = new Set([
|
|
|
843
854
|
'@declaration.parameter-types',
|
|
844
855
|
'@declaration.parameter-type-classes',
|
|
845
856
|
'@declaration.template-constraints',
|
|
857
|
+
'@declaration.is-explicit',
|
|
846
858
|
]);
|
|
847
859
|
/**
|
|
848
860
|
* Return the anchor capture for a match — the one whose name begins with
|
package/package.json
CHANGED