gitnexus 1.6.13-rc.65 → 1.6.13-rc.66
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/core/ingestion/languages/swift/callable-visibility.d.ts +9 -0
- package/dist/core/ingestion/languages/swift/callable-visibility.js +57 -0
- package/dist/core/ingestion/languages/swift/scope-resolver.js +2 -0
- package/dist/core/ingestion/scope-resolution/contract/scope-resolver.d.ts +3 -0
- package/dist/core/ingestion/scope-resolution/passes/free-call-fallback.d.ts +1 -6
- package/dist/core/ingestion/scope-resolution/passes/free-call-fallback.js +2 -0
- package/package.json +1 -1
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ParsedFile, ScopeId, SymbolDefinition } from '../../../../_shared/index.js';
|
|
2
|
+
import type { ScopeResolutionIndexes } from '../../model/scope-resolution-indexes.js';
|
|
3
|
+
export declare function swiftIsCallableVisibleFromCaller(ctx: {
|
|
4
|
+
readonly candidate: SymbolDefinition;
|
|
5
|
+
readonly callerParsed?: ParsedFile;
|
|
6
|
+
readonly callArity?: number;
|
|
7
|
+
readonly callerScope?: ScopeId;
|
|
8
|
+
readonly scopes?: ScopeResolutionIndexes;
|
|
9
|
+
}): boolean;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { findClassBindingInScope } from '../../scope-resolution/scope/walkers.js';
|
|
2
|
+
export function swiftIsCallableVisibleFromCaller(ctx) {
|
|
3
|
+
const indexes = ctx.scopes;
|
|
4
|
+
if (ctx.callerScope === undefined || indexes === undefined || ctx.callArity !== 0)
|
|
5
|
+
return true;
|
|
6
|
+
const name = ctx.candidate.qualifiedName?.split('.').at(-1);
|
|
7
|
+
if (name === undefined)
|
|
8
|
+
return true;
|
|
9
|
+
let scopeId = ctx.callerScope;
|
|
10
|
+
let selfType;
|
|
11
|
+
while (scopeId !== null) {
|
|
12
|
+
const scope = indexes.scopeTree.getScope(scopeId);
|
|
13
|
+
if (scope === undefined)
|
|
14
|
+
break;
|
|
15
|
+
// A local function selected inside the caller wins before member lookup.
|
|
16
|
+
if (scope.kind !== 'Class' &&
|
|
17
|
+
scope.ownedDefs.some((def) => def.nodeId === ctx.candidate.nodeId))
|
|
18
|
+
return true;
|
|
19
|
+
selfType ??= scope.typeBindings.get('self');
|
|
20
|
+
if (scope.kind === 'Class') {
|
|
21
|
+
const classDef = scope.ownedDefs.find((def) => def.type === 'Class') ??
|
|
22
|
+
(selfType === undefined
|
|
23
|
+
? undefined
|
|
24
|
+
: findClassBindingInScope(ctx.callerScope, selfType.rawName, indexes, undefined, {
|
|
25
|
+
uniqueQualifiedNameFallback: false,
|
|
26
|
+
}));
|
|
27
|
+
const propertyOnOwner = (ownerId, ownerName) => indexes.qualifiedNames.get(`${ownerName}.${name}`).some((defId) => {
|
|
28
|
+
const def = indexes.defs.get(defId);
|
|
29
|
+
return def?.type === 'Property' && def.ownerId === ownerId;
|
|
30
|
+
});
|
|
31
|
+
const ownProperty = scope.ownedDefs.some((def) => def.type === 'Property' && def.qualifiedName?.split('.').at(-1) === name) ||
|
|
32
|
+
(classDef !== undefined &&
|
|
33
|
+
classDef.qualifiedName !== undefined &&
|
|
34
|
+
propertyOnOwner(classDef.nodeId, classDef.qualifiedName));
|
|
35
|
+
const inheritedProperty = classDef !== undefined &&
|
|
36
|
+
indexes.methodDispatch.mroFor(classDef.nodeId).some((ownerId) => {
|
|
37
|
+
const ownerName = indexes.defs.get(ownerId)?.qualifiedName;
|
|
38
|
+
return ownerName !== undefined && propertyOnOwner(ownerId, ownerName);
|
|
39
|
+
});
|
|
40
|
+
if (!ownProperty && !inheritedProperty)
|
|
41
|
+
return true;
|
|
42
|
+
// Swift's nested function is owned by its own Function scope. A
|
|
43
|
+
// same-file sibling must not count as a nearer lexical binding.
|
|
44
|
+
const declarationScope = ctx.callerParsed?.scopes.find((candidateScope) => candidateScope.ownedDefs.some((def) => def.nodeId === ctx.candidate.nodeId));
|
|
45
|
+
if (declarationScope !== undefined &&
|
|
46
|
+
declarationScope.kind === 'Function' &&
|
|
47
|
+
(declarationScope.id === ctx.callerScope ||
|
|
48
|
+
indexes.scopeTree.getAncestors(declarationScope.id).includes(ctx.callerScope)))
|
|
49
|
+
return true;
|
|
50
|
+
// Scope defs do not carry Swift access modifiers. A method positively
|
|
51
|
+
// selected on this type must not be vetoed by an uncertain ancestor.
|
|
52
|
+
return classDef !== undefined && ctx.candidate.ownerId === classDef.nodeId;
|
|
53
|
+
}
|
|
54
|
+
scopeId = scope.parent;
|
|
55
|
+
}
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
@@ -56,6 +56,7 @@ import { swiftArityCompatibility, swiftMergeBindings, interpretSwiftImport, reso
|
|
|
56
56
|
import { stripSwiftTypePreservingDecoration } from './interpret.js';
|
|
57
57
|
import { groupSwiftFilesByModule } from './target-grouping.js';
|
|
58
58
|
import { swiftIsGlobalNameFallbackPlausible } from './name-fallback-visibility.js';
|
|
59
|
+
import { swiftIsCallableVisibleFromCaller } from './callable-visibility.js';
|
|
59
60
|
const ZERO_RANGE = { startLine: 0, startCol: 0, endLine: 0, endCol: 0 };
|
|
60
61
|
const swiftScopeResolver = {
|
|
61
62
|
language: SupportedLanguages.Swift,
|
|
@@ -123,6 +124,7 @@ const swiftScopeResolver = {
|
|
|
123
124
|
// no-`new` constructor + cross-file free-call shape).
|
|
124
125
|
allowGlobalFreeCallFallback: true,
|
|
125
126
|
isGlobalNameFallbackPlausible: swiftIsGlobalNameFallbackPlausible,
|
|
127
|
+
isCallableVisibleFromCaller: swiftIsCallableVisibleFromCaller,
|
|
126
128
|
// Swift's call graph models `Type(...)` as a reference to the type
|
|
127
129
|
// itself, not its `init` — both the legacy DAG and this test suite link
|
|
128
130
|
// `Foo()` to the Class node even when an explicit `init` exists.
|
|
@@ -1112,6 +1112,9 @@ export interface ScopeResolver {
|
|
|
1112
1112
|
readonly isCallableVisibleFromCaller?: (ctx: {
|
|
1113
1113
|
readonly callerParsed: ParsedFile;
|
|
1114
1114
|
readonly candidate: SymbolDefinition;
|
|
1115
|
+
/** Arity of the actual call, when known. A visibility veto must not
|
|
1116
|
+
* infer applicability from a name match alone. */
|
|
1117
|
+
readonly callArity?: number;
|
|
1115
1118
|
/** Caller's enclosing scope id. Languages that gate visibility on
|
|
1116
1119
|
* caller scope (e.g. C++ two-phase template lookup) consult it;
|
|
1117
1120
|
* others ignore. Optional so existing implementations stay valid. */
|
|
@@ -47,12 +47,7 @@ export declare function emitFreeCallFallback(graph: KnowledgeGraph, scopes: Scop
|
|
|
47
47
|
* appended to its reason. See `ScopeResolver.markConstructionSites`. */
|
|
48
48
|
readonly markConstructionSites?: boolean;
|
|
49
49
|
readonly isFileLocalDef?: (def: SymbolDefinition) => boolean;
|
|
50
|
-
readonly isCallableVisibleFromCaller?:
|
|
51
|
-
readonly callerParsed: ParsedFile;
|
|
52
|
-
readonly candidate: SymbolDefinition;
|
|
53
|
-
readonly callerScope?: ScopeId;
|
|
54
|
-
readonly scopes?: ScopeResolutionIndexes;
|
|
55
|
-
}) => boolean;
|
|
50
|
+
readonly isCallableVisibleFromCaller?: ScopeResolver['isCallableVisibleFromCaller'];
|
|
56
51
|
readonly resolveAdlCandidates?: (site: {
|
|
57
52
|
readonly name: string;
|
|
58
53
|
readonly arity?: number;
|
|
@@ -447,6 +447,7 @@ export function emitFreeCallFallback(graph, scopes, parsedFiles, nodeLookup, _re
|
|
|
447
447
|
? (candidate) => options.isCallableVisibleFromCaller({
|
|
448
448
|
callerParsed: parsed,
|
|
449
449
|
candidate,
|
|
450
|
+
callArity: site.arity,
|
|
450
451
|
callerScope: site.inScope,
|
|
451
452
|
scopes,
|
|
452
453
|
})
|
|
@@ -514,6 +515,7 @@ export function emitFreeCallFallback(graph, scopes, parsedFiles, nodeLookup, _re
|
|
|
514
515
|
!options.isCallableVisibleFromCaller({
|
|
515
516
|
callerParsed: parsed,
|
|
516
517
|
candidate: fnDef,
|
|
518
|
+
callArity: site.arity,
|
|
517
519
|
callerScope: site.inScope,
|
|
518
520
|
scopes,
|
|
519
521
|
})) {
|
package/package.json
CHANGED