@suss/adapter-python 0.5.2 → 0.5.4
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/index.cjs +125 -46
- package/dist/index.d.cts +6 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +125 -46
- package/package.json +4 -4
package/dist/index.cjs
CHANGED
|
@@ -564,6 +564,18 @@ function readArg(node) {
|
|
|
564
564
|
if (node.type === "identifier") {
|
|
565
565
|
return { kind: "identifier", name: node.text };
|
|
566
566
|
}
|
|
567
|
+
if (node.type === "attribute") {
|
|
568
|
+
const object2 = field(node, "object");
|
|
569
|
+
const attribute = field(node, "attribute");
|
|
570
|
+
if (object2?.type === "identifier" && attribute?.type === "identifier") {
|
|
571
|
+
return {
|
|
572
|
+
kind: "attribute",
|
|
573
|
+
objectName: object2.text,
|
|
574
|
+
attributeName: attribute.text
|
|
575
|
+
};
|
|
576
|
+
}
|
|
577
|
+
return { kind: "other" };
|
|
578
|
+
}
|
|
567
579
|
if (node.type === "list") {
|
|
568
580
|
return {
|
|
569
581
|
kind: "list",
|
|
@@ -17248,45 +17260,64 @@ function directStorageEffects(calls, options) {
|
|
|
17248
17260
|
function discoverUnits(root, module2, options) {
|
|
17249
17261
|
const units = [];
|
|
17250
17262
|
for (const stmt of bodyStatements(root)) {
|
|
17251
|
-
if (stmt.type
|
|
17263
|
+
if (stmt.type === "decorated_definition") {
|
|
17264
|
+
units.push(...decoratedUnits(stmt, module2.moduleScope, module2, options));
|
|
17252
17265
|
continue;
|
|
17253
17266
|
}
|
|
17254
|
-
const { definition
|
|
17255
|
-
|
|
17256
|
-
|
|
17257
|
-
|
|
17258
|
-
|
|
17259
|
-
|
|
17260
|
-
|
|
17261
|
-
|
|
17262
|
-
|
|
17263
|
-
|
|
17264
|
-
|
|
17265
|
-
|
|
17266
|
-
|
|
17267
|
-
|
|
17268
|
-
|
|
17269
|
-
|
|
17270
|
-
|
|
17271
|
-
|
|
17272
|
-
|
|
17273
|
-
|
|
17274
|
-
|
|
17275
|
-
|
|
17276
|
-
|
|
17277
|
-
|
|
17278
|
-
|
|
17279
|
-
|
|
17280
|
-
|
|
17281
|
-
|
|
17282
|
-
|
|
17283
|
-
|
|
17284
|
-
|
|
17285
|
-
|
|
17286
|
-
|
|
17287
|
-
|
|
17288
|
-
|
|
17289
|
-
|
|
17267
|
+
const { definition } = stripDecorators(stmt);
|
|
17268
|
+
if (definition.type !== "function_definition") {
|
|
17269
|
+
continue;
|
|
17270
|
+
}
|
|
17271
|
+
const body = field(definition, "body");
|
|
17272
|
+
const scope = module2.scopeFor.get(definition.id);
|
|
17273
|
+
if (body === null || scope === void 0) {
|
|
17274
|
+
continue;
|
|
17275
|
+
}
|
|
17276
|
+
for (const inner of bodyStatements(body)) {
|
|
17277
|
+
if (inner.type === "decorated_definition") {
|
|
17278
|
+
units.push(...decoratedUnits(inner, scope, module2, options));
|
|
17279
|
+
}
|
|
17280
|
+
}
|
|
17281
|
+
}
|
|
17282
|
+
return units;
|
|
17283
|
+
}
|
|
17284
|
+
function decoratedUnits(stmt, scope, module2, options) {
|
|
17285
|
+
const units = [];
|
|
17286
|
+
const { definition, decorators } = stripDecorators(stmt);
|
|
17287
|
+
for (const decoratorNode of decorators) {
|
|
17288
|
+
const direct = classifyDecorator(decoratorNode, scope);
|
|
17289
|
+
const classifications = direct.module !== null && acceptedByAnyPattern(direct.module, options) ? [direct] : [
|
|
17290
|
+
unwrapDecorator(
|
|
17291
|
+
decoratorNode,
|
|
17292
|
+
scope,
|
|
17293
|
+
module2,
|
|
17294
|
+
(spec, name) => options.routerIndex?.moduleDef(
|
|
17295
|
+
options.absoluteFile ?? options.filePath,
|
|
17296
|
+
spec,
|
|
17297
|
+
name
|
|
17298
|
+
) ?? null
|
|
17299
|
+
)
|
|
17300
|
+
].filter(
|
|
17301
|
+
(candidate) => candidate !== null
|
|
17302
|
+
);
|
|
17303
|
+
for (const classification of classifications) {
|
|
17304
|
+
if (classification.module === null) {
|
|
17305
|
+
continue;
|
|
17306
|
+
}
|
|
17307
|
+
const decoratorModule = classification.module;
|
|
17308
|
+
for (const pack of options.packs) {
|
|
17309
|
+
for (const pattern of pack.discovery) {
|
|
17310
|
+
units.push(
|
|
17311
|
+
...unitsFor(
|
|
17312
|
+
pattern,
|
|
17313
|
+
pack,
|
|
17314
|
+
decoratorModule,
|
|
17315
|
+
classification,
|
|
17316
|
+
definition,
|
|
17317
|
+
module2,
|
|
17318
|
+
options
|
|
17319
|
+
)
|
|
17320
|
+
);
|
|
17290
17321
|
}
|
|
17291
17322
|
}
|
|
17292
17323
|
}
|
|
@@ -18221,8 +18252,10 @@ function buildRouterIndex(files, packs, resolverOptions) {
|
|
|
18221
18252
|
}
|
|
18222
18253
|
}
|
|
18223
18254
|
const byFile = /* @__PURE__ */ new Map();
|
|
18255
|
+
const displayPaths = /* @__PURE__ */ new Map();
|
|
18224
18256
|
for (const file2 of files) {
|
|
18225
18257
|
byFile.set(file2.file, file2);
|
|
18258
|
+
displayPaths.set(file2.module, file2.displayPath);
|
|
18226
18259
|
}
|
|
18227
18260
|
return {
|
|
18228
18261
|
moduleDef(fromFile, spec, name) {
|
|
@@ -18262,14 +18295,15 @@ function buildRouterIndex(files, packs, resolverOptions) {
|
|
|
18262
18295
|
if (ownPrefix.kind === "abstain") {
|
|
18263
18296
|
return ownPrefix;
|
|
18264
18297
|
}
|
|
18298
|
+
const routerPath = displayPaths.get(module2);
|
|
18265
18299
|
const mount = index.mounts.get(construction);
|
|
18266
18300
|
if (mount === void 0) {
|
|
18267
|
-
return { kind: "abstain", reason: unmountedReason(index) };
|
|
18301
|
+
return { kind: "abstain", reason: unmountedReason(index, routerPath) };
|
|
18268
18302
|
}
|
|
18269
18303
|
if (mount.kind === "abstain") {
|
|
18270
18304
|
return { kind: "abstain", reason: mount.reason };
|
|
18271
18305
|
}
|
|
18272
|
-
const rivalled = rivalRegistration(index, mount.site);
|
|
18306
|
+
const rivalled = rivalRegistration(index, mount.site, routerPath);
|
|
18273
18307
|
if (rivalled !== null) {
|
|
18274
18308
|
return { kind: "abstain", reason: rivalled };
|
|
18275
18309
|
}
|
|
@@ -18303,24 +18337,32 @@ function loopsClause(loops, verb) {
|
|
|
18303
18337
|
}
|
|
18304
18338
|
return `loops at ${locations.join(", ")} ${verb}`;
|
|
18305
18339
|
}
|
|
18306
|
-
function
|
|
18307
|
-
|
|
18308
|
-
|
|
18309
|
-
return "is never mounted through a single variable binding in the files read";
|
|
18340
|
+
function couldReach(loop, routerPath) {
|
|
18341
|
+
if (routerPath === void 0) {
|
|
18342
|
+
return true;
|
|
18310
18343
|
}
|
|
18344
|
+
const directory = loop.file.slice(0, loop.file.lastIndexOf("/") + 1);
|
|
18345
|
+
return routerPath.startsWith(directory);
|
|
18346
|
+
}
|
|
18347
|
+
function unmountedReason(index, routerPath) {
|
|
18348
|
+
const loops = [...index.unenumerableLoops.values()];
|
|
18311
18349
|
const stopped = loops.find((loop) => loop.unmatched !== void 0);
|
|
18312
18350
|
if (stopped?.unmatched !== void 0) {
|
|
18313
18351
|
const { name, resolvedTo, matched, of } = stopped.unmatched;
|
|
18314
18352
|
return `is not mounted by name in the files read, and a loop at ${stopped.location} mounts a list this reading resolved, where ${matched} of ${of} entries matched a router and ${name} did not (it resolved to ${resolvedTo}), so the whole list is declined rather than most of it mounted`;
|
|
18315
18353
|
}
|
|
18316
|
-
|
|
18354
|
+
const reachable = loops.filter((loop) => couldReach(loop, routerPath));
|
|
18355
|
+
if (reachable.length === 0) {
|
|
18356
|
+
return "is never mounted through a single variable binding in the files read";
|
|
18357
|
+
}
|
|
18358
|
+
return `is not mounted by name in the files read, and ${loopsClause(reachable, "mount")} routers read out of a call this reading does not follow`;
|
|
18317
18359
|
}
|
|
18318
|
-
function rivalRegistration(index, site) {
|
|
18360
|
+
function rivalRegistration(index, site, routerPath) {
|
|
18319
18361
|
if (site.kind === "module") {
|
|
18320
18362
|
return null;
|
|
18321
18363
|
}
|
|
18322
18364
|
const rivals = [...index.unenumerableLoops.values()].filter(
|
|
18323
|
-
(loop) => !sameSite(loop.site, site)
|
|
18365
|
+
(loop) => !sameSite(loop.site, site) && couldReach(loop, routerPath)
|
|
18324
18366
|
);
|
|
18325
18367
|
if (rivals.length === 0) {
|
|
18326
18368
|
return null;
|
|
@@ -18772,6 +18814,10 @@ function resolvedValueKey(facts, value) {
|
|
|
18772
18814
|
return row === void 0 ? value : String(row[1]);
|
|
18773
18815
|
}
|
|
18774
18816
|
function mountedConstructions(arg, position, scan) {
|
|
18817
|
+
if (arg?.kind === "attribute") {
|
|
18818
|
+
const construction = constructionThroughModule(arg, position.scope, scan);
|
|
18819
|
+
return construction === null ? [] : [construction];
|
|
18820
|
+
}
|
|
18775
18821
|
if (arg?.kind !== "identifier") {
|
|
18776
18822
|
return [];
|
|
18777
18823
|
}
|
|
@@ -18793,6 +18839,7 @@ function mountedConstructions(arg, position, scan) {
|
|
|
18793
18839
|
}
|
|
18794
18840
|
scan.index.unenumerableLoops.set(target.location, {
|
|
18795
18841
|
site: position.site,
|
|
18842
|
+
file: scan.bound.displayPath,
|
|
18796
18843
|
location: target.location,
|
|
18797
18844
|
...returned.kind === "unmatched" ? { unmatched: returned } : {}
|
|
18798
18845
|
});
|
|
@@ -18800,10 +18847,42 @@ function mountedConstructions(arg, position, scan) {
|
|
|
18800
18847
|
}
|
|
18801
18848
|
scan.index.unenumerableLoops.set(target.location, {
|
|
18802
18849
|
site: position.site,
|
|
18850
|
+
file: scan.bound.displayPath,
|
|
18803
18851
|
location: target.location
|
|
18804
18852
|
});
|
|
18805
18853
|
return [];
|
|
18806
18854
|
}
|
|
18855
|
+
function constructionThroughModule(arg, scope, scan) {
|
|
18856
|
+
const binding = resolveName(scope, arg.objectName);
|
|
18857
|
+
if (binding === null) {
|
|
18858
|
+
return null;
|
|
18859
|
+
}
|
|
18860
|
+
const spec = importedModuleSpec(binding);
|
|
18861
|
+
if (spec === null) {
|
|
18862
|
+
return null;
|
|
18863
|
+
}
|
|
18864
|
+
const resolution = resolveModule(scan.bound.file, spec, scan.resolverOptions);
|
|
18865
|
+
if (resolution.status !== "resolved") {
|
|
18866
|
+
return null;
|
|
18867
|
+
}
|
|
18868
|
+
const target = scan.byFile.get(resolution.file);
|
|
18869
|
+
if (target === void 0) {
|
|
18870
|
+
return null;
|
|
18871
|
+
}
|
|
18872
|
+
return scan.index.constructions.get(target.module)?.get(arg.attributeName) ?? null;
|
|
18873
|
+
}
|
|
18874
|
+
function importedModuleSpec(binding) {
|
|
18875
|
+
if (binding.kind === "import") {
|
|
18876
|
+
return { module: binding.module, relativeLevel: binding.relativeLevel };
|
|
18877
|
+
}
|
|
18878
|
+
if (binding.kind === "importFrom") {
|
|
18879
|
+
return {
|
|
18880
|
+
module: binding.module === "" ? binding.importedName : `${binding.module}.${binding.importedName}`,
|
|
18881
|
+
relativeLevel: binding.relativeLevel
|
|
18882
|
+
};
|
|
18883
|
+
}
|
|
18884
|
+
return null;
|
|
18885
|
+
}
|
|
18807
18886
|
function recordMountStatement(stmt, position, scan) {
|
|
18808
18887
|
const mountCall = mountCallOf(stmt, position.scope, scan);
|
|
18809
18888
|
if (mountCall === null) {
|
package/dist/index.d.cts
CHANGED
|
@@ -128,6 +128,12 @@ type DecoratorArg = {
|
|
|
128
128
|
| {
|
|
129
129
|
kind: "identifier";
|
|
130
130
|
name: string;
|
|
131
|
+
}
|
|
132
|
+
/** One dotted hop, `routers.orders`. The caller decides what the object is. */
|
|
133
|
+
| {
|
|
134
|
+
kind: "attribute";
|
|
135
|
+
objectName: string;
|
|
136
|
+
attributeName: string;
|
|
131
137
|
} | {
|
|
132
138
|
kind: "list";
|
|
133
139
|
items: DecoratorArg[];
|
package/dist/index.d.ts
CHANGED
|
@@ -128,6 +128,12 @@ type DecoratorArg = {
|
|
|
128
128
|
| {
|
|
129
129
|
kind: "identifier";
|
|
130
130
|
name: string;
|
|
131
|
+
}
|
|
132
|
+
/** One dotted hop, `routers.orders`. The caller decides what the object is. */
|
|
133
|
+
| {
|
|
134
|
+
kind: "attribute";
|
|
135
|
+
objectName: string;
|
|
136
|
+
attributeName: string;
|
|
131
137
|
} | {
|
|
132
138
|
kind: "list";
|
|
133
139
|
items: DecoratorArg[];
|
package/dist/index.js
CHANGED
|
@@ -510,6 +510,18 @@ function readArg(node) {
|
|
|
510
510
|
if (node.type === "identifier") {
|
|
511
511
|
return { kind: "identifier", name: node.text };
|
|
512
512
|
}
|
|
513
|
+
if (node.type === "attribute") {
|
|
514
|
+
const object2 = field(node, "object");
|
|
515
|
+
const attribute = field(node, "attribute");
|
|
516
|
+
if (object2?.type === "identifier" && attribute?.type === "identifier") {
|
|
517
|
+
return {
|
|
518
|
+
kind: "attribute",
|
|
519
|
+
objectName: object2.text,
|
|
520
|
+
attributeName: attribute.text
|
|
521
|
+
};
|
|
522
|
+
}
|
|
523
|
+
return { kind: "other" };
|
|
524
|
+
}
|
|
513
525
|
if (node.type === "list") {
|
|
514
526
|
return {
|
|
515
527
|
kind: "list",
|
|
@@ -17204,45 +17216,64 @@ function directStorageEffects(calls, options) {
|
|
|
17204
17216
|
function discoverUnits(root, module, options) {
|
|
17205
17217
|
const units = [];
|
|
17206
17218
|
for (const stmt of bodyStatements(root)) {
|
|
17207
|
-
if (stmt.type
|
|
17219
|
+
if (stmt.type === "decorated_definition") {
|
|
17220
|
+
units.push(...decoratedUnits(stmt, module.moduleScope, module, options));
|
|
17208
17221
|
continue;
|
|
17209
17222
|
}
|
|
17210
|
-
const { definition
|
|
17211
|
-
|
|
17212
|
-
|
|
17213
|
-
|
|
17214
|
-
|
|
17215
|
-
|
|
17216
|
-
|
|
17217
|
-
|
|
17218
|
-
|
|
17219
|
-
|
|
17220
|
-
|
|
17221
|
-
|
|
17222
|
-
|
|
17223
|
-
|
|
17224
|
-
|
|
17225
|
-
|
|
17226
|
-
|
|
17227
|
-
|
|
17228
|
-
|
|
17229
|
-
|
|
17230
|
-
|
|
17231
|
-
|
|
17232
|
-
|
|
17233
|
-
|
|
17234
|
-
|
|
17235
|
-
|
|
17236
|
-
|
|
17237
|
-
|
|
17238
|
-
|
|
17239
|
-
|
|
17240
|
-
|
|
17241
|
-
|
|
17242
|
-
|
|
17243
|
-
|
|
17244
|
-
|
|
17245
|
-
|
|
17223
|
+
const { definition } = stripDecorators(stmt);
|
|
17224
|
+
if (definition.type !== "function_definition") {
|
|
17225
|
+
continue;
|
|
17226
|
+
}
|
|
17227
|
+
const body = field(definition, "body");
|
|
17228
|
+
const scope = module.scopeFor.get(definition.id);
|
|
17229
|
+
if (body === null || scope === void 0) {
|
|
17230
|
+
continue;
|
|
17231
|
+
}
|
|
17232
|
+
for (const inner of bodyStatements(body)) {
|
|
17233
|
+
if (inner.type === "decorated_definition") {
|
|
17234
|
+
units.push(...decoratedUnits(inner, scope, module, options));
|
|
17235
|
+
}
|
|
17236
|
+
}
|
|
17237
|
+
}
|
|
17238
|
+
return units;
|
|
17239
|
+
}
|
|
17240
|
+
function decoratedUnits(stmt, scope, module, options) {
|
|
17241
|
+
const units = [];
|
|
17242
|
+
const { definition, decorators } = stripDecorators(stmt);
|
|
17243
|
+
for (const decoratorNode of decorators) {
|
|
17244
|
+
const direct = classifyDecorator(decoratorNode, scope);
|
|
17245
|
+
const classifications = direct.module !== null && acceptedByAnyPattern(direct.module, options) ? [direct] : [
|
|
17246
|
+
unwrapDecorator(
|
|
17247
|
+
decoratorNode,
|
|
17248
|
+
scope,
|
|
17249
|
+
module,
|
|
17250
|
+
(spec, name) => options.routerIndex?.moduleDef(
|
|
17251
|
+
options.absoluteFile ?? options.filePath,
|
|
17252
|
+
spec,
|
|
17253
|
+
name
|
|
17254
|
+
) ?? null
|
|
17255
|
+
)
|
|
17256
|
+
].filter(
|
|
17257
|
+
(candidate) => candidate !== null
|
|
17258
|
+
);
|
|
17259
|
+
for (const classification of classifications) {
|
|
17260
|
+
if (classification.module === null) {
|
|
17261
|
+
continue;
|
|
17262
|
+
}
|
|
17263
|
+
const decoratorModule = classification.module;
|
|
17264
|
+
for (const pack of options.packs) {
|
|
17265
|
+
for (const pattern of pack.discovery) {
|
|
17266
|
+
units.push(
|
|
17267
|
+
...unitsFor(
|
|
17268
|
+
pattern,
|
|
17269
|
+
pack,
|
|
17270
|
+
decoratorModule,
|
|
17271
|
+
classification,
|
|
17272
|
+
definition,
|
|
17273
|
+
module,
|
|
17274
|
+
options
|
|
17275
|
+
)
|
|
17276
|
+
);
|
|
17246
17277
|
}
|
|
17247
17278
|
}
|
|
17248
17279
|
}
|
|
@@ -18177,8 +18208,10 @@ function buildRouterIndex(files, packs, resolverOptions) {
|
|
|
18177
18208
|
}
|
|
18178
18209
|
}
|
|
18179
18210
|
const byFile = /* @__PURE__ */ new Map();
|
|
18211
|
+
const displayPaths = /* @__PURE__ */ new Map();
|
|
18180
18212
|
for (const file2 of files) {
|
|
18181
18213
|
byFile.set(file2.file, file2);
|
|
18214
|
+
displayPaths.set(file2.module, file2.displayPath);
|
|
18182
18215
|
}
|
|
18183
18216
|
return {
|
|
18184
18217
|
moduleDef(fromFile, spec, name) {
|
|
@@ -18218,14 +18251,15 @@ function buildRouterIndex(files, packs, resolverOptions) {
|
|
|
18218
18251
|
if (ownPrefix.kind === "abstain") {
|
|
18219
18252
|
return ownPrefix;
|
|
18220
18253
|
}
|
|
18254
|
+
const routerPath = displayPaths.get(module);
|
|
18221
18255
|
const mount = index.mounts.get(construction);
|
|
18222
18256
|
if (mount === void 0) {
|
|
18223
|
-
return { kind: "abstain", reason: unmountedReason(index) };
|
|
18257
|
+
return { kind: "abstain", reason: unmountedReason(index, routerPath) };
|
|
18224
18258
|
}
|
|
18225
18259
|
if (mount.kind === "abstain") {
|
|
18226
18260
|
return { kind: "abstain", reason: mount.reason };
|
|
18227
18261
|
}
|
|
18228
|
-
const rivalled = rivalRegistration(index, mount.site);
|
|
18262
|
+
const rivalled = rivalRegistration(index, mount.site, routerPath);
|
|
18229
18263
|
if (rivalled !== null) {
|
|
18230
18264
|
return { kind: "abstain", reason: rivalled };
|
|
18231
18265
|
}
|
|
@@ -18259,24 +18293,32 @@ function loopsClause(loops, verb) {
|
|
|
18259
18293
|
}
|
|
18260
18294
|
return `loops at ${locations.join(", ")} ${verb}`;
|
|
18261
18295
|
}
|
|
18262
|
-
function
|
|
18263
|
-
|
|
18264
|
-
|
|
18265
|
-
return "is never mounted through a single variable binding in the files read";
|
|
18296
|
+
function couldReach(loop, routerPath) {
|
|
18297
|
+
if (routerPath === void 0) {
|
|
18298
|
+
return true;
|
|
18266
18299
|
}
|
|
18300
|
+
const directory = loop.file.slice(0, loop.file.lastIndexOf("/") + 1);
|
|
18301
|
+
return routerPath.startsWith(directory);
|
|
18302
|
+
}
|
|
18303
|
+
function unmountedReason(index, routerPath) {
|
|
18304
|
+
const loops = [...index.unenumerableLoops.values()];
|
|
18267
18305
|
const stopped = loops.find((loop) => loop.unmatched !== void 0);
|
|
18268
18306
|
if (stopped?.unmatched !== void 0) {
|
|
18269
18307
|
const { name, resolvedTo, matched, of } = stopped.unmatched;
|
|
18270
18308
|
return `is not mounted by name in the files read, and a loop at ${stopped.location} mounts a list this reading resolved, where ${matched} of ${of} entries matched a router and ${name} did not (it resolved to ${resolvedTo}), so the whole list is declined rather than most of it mounted`;
|
|
18271
18309
|
}
|
|
18272
|
-
|
|
18310
|
+
const reachable = loops.filter((loop) => couldReach(loop, routerPath));
|
|
18311
|
+
if (reachable.length === 0) {
|
|
18312
|
+
return "is never mounted through a single variable binding in the files read";
|
|
18313
|
+
}
|
|
18314
|
+
return `is not mounted by name in the files read, and ${loopsClause(reachable, "mount")} routers read out of a call this reading does not follow`;
|
|
18273
18315
|
}
|
|
18274
|
-
function rivalRegistration(index, site) {
|
|
18316
|
+
function rivalRegistration(index, site, routerPath) {
|
|
18275
18317
|
if (site.kind === "module") {
|
|
18276
18318
|
return null;
|
|
18277
18319
|
}
|
|
18278
18320
|
const rivals = [...index.unenumerableLoops.values()].filter(
|
|
18279
|
-
(loop) => !sameSite(loop.site, site)
|
|
18321
|
+
(loop) => !sameSite(loop.site, site) && couldReach(loop, routerPath)
|
|
18280
18322
|
);
|
|
18281
18323
|
if (rivals.length === 0) {
|
|
18282
18324
|
return null;
|
|
@@ -18728,6 +18770,10 @@ function resolvedValueKey(facts, value) {
|
|
|
18728
18770
|
return row === void 0 ? value : String(row[1]);
|
|
18729
18771
|
}
|
|
18730
18772
|
function mountedConstructions(arg, position, scan) {
|
|
18773
|
+
if (arg?.kind === "attribute") {
|
|
18774
|
+
const construction = constructionThroughModule(arg, position.scope, scan);
|
|
18775
|
+
return construction === null ? [] : [construction];
|
|
18776
|
+
}
|
|
18731
18777
|
if (arg?.kind !== "identifier") {
|
|
18732
18778
|
return [];
|
|
18733
18779
|
}
|
|
@@ -18749,6 +18795,7 @@ function mountedConstructions(arg, position, scan) {
|
|
|
18749
18795
|
}
|
|
18750
18796
|
scan.index.unenumerableLoops.set(target.location, {
|
|
18751
18797
|
site: position.site,
|
|
18798
|
+
file: scan.bound.displayPath,
|
|
18752
18799
|
location: target.location,
|
|
18753
18800
|
...returned.kind === "unmatched" ? { unmatched: returned } : {}
|
|
18754
18801
|
});
|
|
@@ -18756,10 +18803,42 @@ function mountedConstructions(arg, position, scan) {
|
|
|
18756
18803
|
}
|
|
18757
18804
|
scan.index.unenumerableLoops.set(target.location, {
|
|
18758
18805
|
site: position.site,
|
|
18806
|
+
file: scan.bound.displayPath,
|
|
18759
18807
|
location: target.location
|
|
18760
18808
|
});
|
|
18761
18809
|
return [];
|
|
18762
18810
|
}
|
|
18811
|
+
function constructionThroughModule(arg, scope, scan) {
|
|
18812
|
+
const binding = resolveName(scope, arg.objectName);
|
|
18813
|
+
if (binding === null) {
|
|
18814
|
+
return null;
|
|
18815
|
+
}
|
|
18816
|
+
const spec = importedModuleSpec(binding);
|
|
18817
|
+
if (spec === null) {
|
|
18818
|
+
return null;
|
|
18819
|
+
}
|
|
18820
|
+
const resolution = resolveModule(scan.bound.file, spec, scan.resolverOptions);
|
|
18821
|
+
if (resolution.status !== "resolved") {
|
|
18822
|
+
return null;
|
|
18823
|
+
}
|
|
18824
|
+
const target = scan.byFile.get(resolution.file);
|
|
18825
|
+
if (target === void 0) {
|
|
18826
|
+
return null;
|
|
18827
|
+
}
|
|
18828
|
+
return scan.index.constructions.get(target.module)?.get(arg.attributeName) ?? null;
|
|
18829
|
+
}
|
|
18830
|
+
function importedModuleSpec(binding) {
|
|
18831
|
+
if (binding.kind === "import") {
|
|
18832
|
+
return { module: binding.module, relativeLevel: binding.relativeLevel };
|
|
18833
|
+
}
|
|
18834
|
+
if (binding.kind === "importFrom") {
|
|
18835
|
+
return {
|
|
18836
|
+
module: binding.module === "" ? binding.importedName : `${binding.module}.${binding.importedName}`,
|
|
18837
|
+
relativeLevel: binding.relativeLevel
|
|
18838
|
+
};
|
|
18839
|
+
}
|
|
18840
|
+
return null;
|
|
18841
|
+
}
|
|
18763
18842
|
function recordMountStatement(stmt, position, scan) {
|
|
18764
18843
|
const mountCall = mountCallOf(stmt, position.scope, scan);
|
|
18765
18844
|
if (mountCall === null) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@suss/adapter-python",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.4",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Python language adapter for suss — parses source with tree-sitter (WASM), resolves names with a lexical binder, and emits raw extractions for the suss pipeline.",
|
|
6
6
|
"keywords": [
|
|
@@ -47,9 +47,9 @@
|
|
|
47
47
|
"typecheck": "tsc --noEmit"
|
|
48
48
|
},
|
|
49
49
|
"dependencies": {
|
|
50
|
-
"@suss/behavioral-ir": "0.5.
|
|
51
|
-
"@suss/datalog": "0.5.
|
|
52
|
-
"@suss/extractor": "0.5.
|
|
50
|
+
"@suss/behavioral-ir": "0.5.4",
|
|
51
|
+
"@suss/datalog": "0.5.4",
|
|
52
|
+
"@suss/extractor": "0.5.4",
|
|
53
53
|
"web-tree-sitter": "^0.26.11"
|
|
54
54
|
},
|
|
55
55
|
"devDependencies": {
|