@suss/adapter-python 0.5.3 → 0.5.5

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 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 !== "decorated_definition") {
17263
+ if (stmt.type === "decorated_definition") {
17264
+ units.push(...decoratedUnits(stmt, module2.moduleScope, module2, options));
17252
17265
  continue;
17253
17266
  }
17254
- const { definition, decorators } = stripDecorators(stmt);
17255
- for (const decoratorNode of decorators) {
17256
- const direct = classifyDecorator(decoratorNode, module2.moduleScope);
17257
- const classifications = direct.module !== null && acceptedByAnyPattern(direct.module, options) ? [direct] : [
17258
- unwrapDecorator(
17259
- decoratorNode,
17260
- module2.moduleScope,
17261
- module2,
17262
- (spec, name) => options.routerIndex?.moduleDef(
17263
- options.absoluteFile ?? options.filePath,
17264
- spec,
17265
- name
17266
- ) ?? null
17267
- )
17268
- ].filter(
17269
- (candidate) => candidate !== null
17270
- );
17271
- for (const classification of classifications) {
17272
- if (classification.module === null) {
17273
- continue;
17274
- }
17275
- const decoratorModule = classification.module;
17276
- for (const pack of options.packs) {
17277
- for (const pattern of pack.discovery) {
17278
- units.push(
17279
- ...unitsFor(
17280
- pattern,
17281
- pack,
17282
- decoratorModule,
17283
- classification,
17284
- definition,
17285
- module2,
17286
- options
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
  }
@@ -18783,6 +18814,10 @@ function resolvedValueKey(facts, value) {
18783
18814
  return row === void 0 ? value : String(row[1]);
18784
18815
  }
18785
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
+ }
18786
18821
  if (arg?.kind !== "identifier") {
18787
18822
  return [];
18788
18823
  }
@@ -18817,6 +18852,37 @@ function mountedConstructions(arg, position, scan) {
18817
18852
  });
18818
18853
  return [];
18819
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
+ }
18820
18886
  function recordMountStatement(stmt, position, scan) {
18821
18887
  const mountCall = mountCallOf(stmt, position.scope, scan);
18822
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 !== "decorated_definition") {
17219
+ if (stmt.type === "decorated_definition") {
17220
+ units.push(...decoratedUnits(stmt, module.moduleScope, module, options));
17208
17221
  continue;
17209
17222
  }
17210
- const { definition, decorators } = stripDecorators(stmt);
17211
- for (const decoratorNode of decorators) {
17212
- const direct = classifyDecorator(decoratorNode, module.moduleScope);
17213
- const classifications = direct.module !== null && acceptedByAnyPattern(direct.module, options) ? [direct] : [
17214
- unwrapDecorator(
17215
- decoratorNode,
17216
- module.moduleScope,
17217
- module,
17218
- (spec, name) => options.routerIndex?.moduleDef(
17219
- options.absoluteFile ?? options.filePath,
17220
- spec,
17221
- name
17222
- ) ?? null
17223
- )
17224
- ].filter(
17225
- (candidate) => candidate !== null
17226
- );
17227
- for (const classification of classifications) {
17228
- if (classification.module === null) {
17229
- continue;
17230
- }
17231
- const decoratorModule = classification.module;
17232
- for (const pack of options.packs) {
17233
- for (const pattern of pack.discovery) {
17234
- units.push(
17235
- ...unitsFor(
17236
- pattern,
17237
- pack,
17238
- decoratorModule,
17239
- classification,
17240
- definition,
17241
- module,
17242
- options
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
  }
@@ -18739,6 +18770,10 @@ function resolvedValueKey(facts, value) {
18739
18770
  return row === void 0 ? value : String(row[1]);
18740
18771
  }
18741
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
+ }
18742
18777
  if (arg?.kind !== "identifier") {
18743
18778
  return [];
18744
18779
  }
@@ -18773,6 +18808,37 @@ function mountedConstructions(arg, position, scan) {
18773
18808
  });
18774
18809
  return [];
18775
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
+ }
18776
18842
  function recordMountStatement(stmt, position, scan) {
18777
18843
  const mountCall = mountCallOf(stmt, position.scope, scan);
18778
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",
3
+ "version": "0.5.5",
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.3",
51
- "@suss/datalog": "0.5.3",
52
- "@suss/extractor": "0.5.3",
50
+ "@suss/behavioral-ir": "0.5.5",
51
+ "@suss/datalog": "0.5.5",
52
+ "@suss/extractor": "0.5.5",
53
53
  "web-tree-sitter": "^0.26.11"
54
54
  },
55
55
  "devDependencies": {