@suss/adapter-typescript 0.16.0 → 0.17.0

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
@@ -12484,19 +12484,35 @@ function resolveCallee(call, calleeName, scan) {
12484
12484
  }
12485
12485
  };
12486
12486
  }
12487
+ function resolveJsxReference(node) {
12488
+ if (!import_ts_morph56.Node.isJsxOpeningElement(node) && !import_ts_morph56.Node.isJsxSelfClosingElement(node)) {
12489
+ return null;
12490
+ }
12491
+ const tag = node.getTagNameNode();
12492
+ if (!import_ts_morph56.Node.isIdentifier(tag) || !/^[A-Z]/.test(tag.getText())) {
12493
+ return null;
12494
+ }
12495
+ const name = tag.getText();
12496
+ const declarations = declarationsBehind(tag.getSymbol());
12497
+ for (const decl of declarations) {
12498
+ const resolved = resolveDecl(decl, name);
12499
+ if (resolved !== null) {
12500
+ return { tag: name, outcome: { kind: "followed", candidate: resolved } };
12501
+ }
12502
+ }
12503
+ return {
12504
+ tag: name,
12505
+ outcome: {
12506
+ kind: "stopped",
12507
+ stop: { callee: name, reason: classifyStop(declarations) }
12508
+ }
12509
+ };
12510
+ }
12487
12511
  function collectReachable(func, scan) {
12488
12512
  const candidates = [];
12489
12513
  const stops = [];
12490
12514
  const seen = /* @__PURE__ */ new Set();
12491
- func.forEachDescendant((node) => {
12492
- if (!import_ts_morph56.Node.isCallExpression(node)) {
12493
- return;
12494
- }
12495
- const calleeText = normalizeCallee(node.getExpression().getText());
12496
- const outcome = resolveCallee(node, calleeText, scan);
12497
- if (outcome === null) {
12498
- return;
12499
- }
12515
+ const record = (outcome) => {
12500
12516
  if (outcome.kind === "stopped") {
12501
12517
  const stopKey = `${outcome.stop.reason}:${outcome.stop.callee}`;
12502
12518
  if (!seen.has(stopKey) && worthRecording(outcome.stop.reason)) {
@@ -12511,6 +12527,22 @@ function collectReachable(func, scan) {
12511
12527
  }
12512
12528
  seen.add(key);
12513
12529
  candidates.push(outcome.candidate);
12530
+ };
12531
+ func.forEachDescendant((node) => {
12532
+ const jsx = resolveJsxReference(node);
12533
+ if (jsx !== null) {
12534
+ record(jsx.outcome);
12535
+ return;
12536
+ }
12537
+ if (!import_ts_morph56.Node.isCallExpression(node)) {
12538
+ return;
12539
+ }
12540
+ const calleeText = normalizeCallee(node.getExpression().getText());
12541
+ const outcome = resolveCallee(node, calleeText, scan);
12542
+ if (outcome === null) {
12543
+ return;
12544
+ }
12545
+ record(outcome);
12514
12546
  });
12515
12547
  return { candidates, stops };
12516
12548
  }
@@ -14386,8 +14418,8 @@ function collectAccessRecognizers(frameworks, tallies) {
14386
14418
  }
14387
14419
  return out;
14388
14420
  }
14389
- function computeSubUnitBarriers(unit, pack, ctx, tally, file) {
14390
- if (pack.subUnits === void 0 || unit.func === null) {
14421
+ function computeSubUnitBarriers(unit, packs, ctx, tallies, file) {
14422
+ if (unit.func === null) {
14391
14423
  return NO_BARRIERS;
14392
14424
  }
14393
14425
  const parentHandle = {
@@ -14395,27 +14427,27 @@ function computeSubUnitBarriers(unit, pack, ctx, tally, file) {
14395
14427
  name: unit.name,
14396
14428
  kind: unit.kind
14397
14429
  };
14398
- try {
14399
- const subUnits = pack.subUnits(parentHandle, ctx);
14400
- if (subUnits.length === 0) {
14401
- return NO_BARRIERS;
14430
+ const barriers = /* @__PURE__ */ new Set();
14431
+ for (const pack of packs) {
14432
+ if (pack.subUnits === void 0) {
14433
+ continue;
14402
14434
  }
14403
- const barriers = /* @__PURE__ */ new Set();
14404
- for (const su of subUnits) {
14405
- barriers.add(su.func);
14435
+ try {
14436
+ for (const su of pack.subUnits(parentHandle, ctx)) {
14437
+ barriers.add(su.func);
14438
+ }
14439
+ } catch (err) {
14440
+ process.stderr.write(
14441
+ recordPackFailure(tallies?.get(pack.name), {
14442
+ pack: pack.name,
14443
+ hook: "subUnits",
14444
+ file,
14445
+ error: err
14446
+ })
14447
+ );
14406
14448
  }
14407
- return barriers;
14408
- } catch (err) {
14409
- process.stderr.write(
14410
- recordPackFailure(tally, {
14411
- pack: pack.name,
14412
- hook: "subUnits",
14413
- file,
14414
- error: err
14415
- })
14416
- );
14417
- return NO_BARRIERS;
14418
14449
  }
14450
+ return barriers.size === 0 ? NO_BARRIERS : barriers;
14419
14451
  }
14420
14452
  function extractFromSourceFile(sourceFile, frameworks, claimedUnits, options, tallies, resolution, mountPrefixes) {
14421
14453
  const summaries = [];
@@ -14497,9 +14529,9 @@ function extractFromSourceFile(sourceFile, frameworks, claimedUnits, options, ta
14497
14529
  }
14498
14530
  const barriers = computeSubUnitBarriers(
14499
14531
  unit,
14500
- pack,
14532
+ frameworks,
14501
14533
  subUnitCtx,
14502
- tally,
14534
+ tallies,
14503
14535
  sourceFile.getFilePath()
14504
14536
  );
14505
14537
  const raw = extractCodeStructure(
@@ -15268,6 +15300,7 @@ function createTypeScriptAdapter(suppliedConfig) {
15268
15300
  pipeline,
15269
15301
  project,
15270
15302
  config.frameworks,
15303
+ packsByFile,
15271
15304
  config.extractorOptions,
15272
15305
  tallies,
15273
15306
  (created, parent) => {
@@ -15608,11 +15641,15 @@ function buildCacheAttribution(args) {
15608
15641
  ];
15609
15642
  return { roots, owners };
15610
15643
  }
15611
- function synthesizeSubUnits(summaries, project, frameworks, options, tallies, onCreated) {
15644
+ function synthesizeSubUnits(summaries, project, frameworks, packsByFile, options, tallies, onCreated) {
15612
15645
  const packByRecognition = /* @__PURE__ */ new Map();
15613
15646
  for (const pack of frameworks) {
15614
15647
  packByRecognition.set(pack.name, pack);
15615
15648
  }
15649
+ const packsByPath = /* @__PURE__ */ new Map();
15650
+ for (const [sf, packs] of packsByFile) {
15651
+ packsByPath.set(sf.getFilePath(), packs);
15652
+ }
15616
15653
  const allInvocationRecognizers = collectInvocationRecognizers(
15617
15654
  frameworks,
15618
15655
  tallies
@@ -15626,8 +15663,15 @@ function synthesizeSubUnits(summaries, project, frameworks, options, tallies, on
15626
15663
  if (binding === null) {
15627
15664
  continue;
15628
15665
  }
15629
- const pack = packByRecognition.get(binding.recognition);
15630
- if (pack?.subUnits === void 0) {
15666
+ const discovering = packByRecognition.get(binding.recognition);
15667
+ const applicable = packsByPath.get(parent.location.file) ?? (discovering !== void 0 ? [discovering] : []);
15668
+ const hooked = [
15669
+ ...discovering?.subUnits !== void 0 ? [discovering] : [],
15670
+ ...applicable.filter(
15671
+ (one) => one.subUnits !== void 0 && one !== discovering
15672
+ )
15673
+ ];
15674
+ if (hooked.length === 0) {
15631
15675
  continue;
15632
15676
  }
15633
15677
  lookup ??= createSourceFileLookup(project);
@@ -15640,7 +15684,17 @@ function synthesizeSubUnits(summaries, project, frameworks, options, tallies, on
15640
15684
  name: parent.identity.name,
15641
15685
  kind: parent.kind
15642
15686
  };
15643
- const subUnits = pack.subUnits(parentHandle, subUnitCtx);
15687
+ const claimedFuncs = /* @__PURE__ */ new Set();
15688
+ const subUnits = [];
15689
+ for (const pack of hooked) {
15690
+ for (const subUnit of pack.subUnits?.(parentHandle, subUnitCtx) ?? []) {
15691
+ if (claimedFuncs.has(subUnit.func)) {
15692
+ continue;
15693
+ }
15694
+ claimedFuncs.add(subUnit.func);
15695
+ subUnits.push(subUnit);
15696
+ }
15697
+ }
15644
15698
  for (const subUnit of subUnits) {
15645
15699
  const summary = buildSubUnitSummary(
15646
15700
  subUnit,
package/dist/index.js CHANGED
@@ -12490,19 +12490,35 @@ function resolveCallee(call, calleeName, scan) {
12490
12490
  }
12491
12491
  };
12492
12492
  }
12493
+ function resolveJsxReference(node) {
12494
+ if (!Node54.isJsxOpeningElement(node) && !Node54.isJsxSelfClosingElement(node)) {
12495
+ return null;
12496
+ }
12497
+ const tag = node.getTagNameNode();
12498
+ if (!Node54.isIdentifier(tag) || !/^[A-Z]/.test(tag.getText())) {
12499
+ return null;
12500
+ }
12501
+ const name = tag.getText();
12502
+ const declarations = declarationsBehind(tag.getSymbol());
12503
+ for (const decl of declarations) {
12504
+ const resolved = resolveDecl(decl, name);
12505
+ if (resolved !== null) {
12506
+ return { tag: name, outcome: { kind: "followed", candidate: resolved } };
12507
+ }
12508
+ }
12509
+ return {
12510
+ tag: name,
12511
+ outcome: {
12512
+ kind: "stopped",
12513
+ stop: { callee: name, reason: classifyStop(declarations) }
12514
+ }
12515
+ };
12516
+ }
12493
12517
  function collectReachable(func, scan) {
12494
12518
  const candidates = [];
12495
12519
  const stops = [];
12496
12520
  const seen = /* @__PURE__ */ new Set();
12497
- func.forEachDescendant((node) => {
12498
- if (!Node54.isCallExpression(node)) {
12499
- return;
12500
- }
12501
- const calleeText = normalizeCallee(node.getExpression().getText());
12502
- const outcome = resolveCallee(node, calleeText, scan);
12503
- if (outcome === null) {
12504
- return;
12505
- }
12521
+ const record = (outcome) => {
12506
12522
  if (outcome.kind === "stopped") {
12507
12523
  const stopKey = `${outcome.stop.reason}:${outcome.stop.callee}`;
12508
12524
  if (!seen.has(stopKey) && worthRecording(outcome.stop.reason)) {
@@ -12517,6 +12533,22 @@ function collectReachable(func, scan) {
12517
12533
  }
12518
12534
  seen.add(key);
12519
12535
  candidates.push(outcome.candidate);
12536
+ };
12537
+ func.forEachDescendant((node) => {
12538
+ const jsx = resolveJsxReference(node);
12539
+ if (jsx !== null) {
12540
+ record(jsx.outcome);
12541
+ return;
12542
+ }
12543
+ if (!Node54.isCallExpression(node)) {
12544
+ return;
12545
+ }
12546
+ const calleeText = normalizeCallee(node.getExpression().getText());
12547
+ const outcome = resolveCallee(node, calleeText, scan);
12548
+ if (outcome === null) {
12549
+ return;
12550
+ }
12551
+ record(outcome);
12520
12552
  });
12521
12553
  return { candidates, stops };
12522
12554
  }
@@ -14398,8 +14430,8 @@ function collectAccessRecognizers(frameworks, tallies) {
14398
14430
  }
14399
14431
  return out;
14400
14432
  }
14401
- function computeSubUnitBarriers(unit, pack, ctx, tally, file) {
14402
- if (pack.subUnits === void 0 || unit.func === null) {
14433
+ function computeSubUnitBarriers(unit, packs, ctx, tallies, file) {
14434
+ if (unit.func === null) {
14403
14435
  return NO_BARRIERS;
14404
14436
  }
14405
14437
  const parentHandle = {
@@ -14407,27 +14439,27 @@ function computeSubUnitBarriers(unit, pack, ctx, tally, file) {
14407
14439
  name: unit.name,
14408
14440
  kind: unit.kind
14409
14441
  };
14410
- try {
14411
- const subUnits = pack.subUnits(parentHandle, ctx);
14412
- if (subUnits.length === 0) {
14413
- return NO_BARRIERS;
14442
+ const barriers = /* @__PURE__ */ new Set();
14443
+ for (const pack of packs) {
14444
+ if (pack.subUnits === void 0) {
14445
+ continue;
14414
14446
  }
14415
- const barriers = /* @__PURE__ */ new Set();
14416
- for (const su of subUnits) {
14417
- barriers.add(su.func);
14447
+ try {
14448
+ for (const su of pack.subUnits(parentHandle, ctx)) {
14449
+ barriers.add(su.func);
14450
+ }
14451
+ } catch (err) {
14452
+ process.stderr.write(
14453
+ recordPackFailure(tallies?.get(pack.name), {
14454
+ pack: pack.name,
14455
+ hook: "subUnits",
14456
+ file,
14457
+ error: err
14458
+ })
14459
+ );
14418
14460
  }
14419
- return barriers;
14420
- } catch (err) {
14421
- process.stderr.write(
14422
- recordPackFailure(tally, {
14423
- pack: pack.name,
14424
- hook: "subUnits",
14425
- file,
14426
- error: err
14427
- })
14428
- );
14429
- return NO_BARRIERS;
14430
14461
  }
14462
+ return barriers.size === 0 ? NO_BARRIERS : barriers;
14431
14463
  }
14432
14464
  function extractFromSourceFile(sourceFile, frameworks, claimedUnits, options, tallies, resolution, mountPrefixes) {
14433
14465
  const summaries = [];
@@ -14509,9 +14541,9 @@ function extractFromSourceFile(sourceFile, frameworks, claimedUnits, options, ta
14509
14541
  }
14510
14542
  const barriers = computeSubUnitBarriers(
14511
14543
  unit,
14512
- pack,
14544
+ frameworks,
14513
14545
  subUnitCtx,
14514
- tally,
14546
+ tallies,
14515
14547
  sourceFile.getFilePath()
14516
14548
  );
14517
14549
  const raw = extractCodeStructure(
@@ -15280,6 +15312,7 @@ function createTypeScriptAdapter(suppliedConfig) {
15280
15312
  pipeline,
15281
15313
  project,
15282
15314
  config.frameworks,
15315
+ packsByFile,
15283
15316
  config.extractorOptions,
15284
15317
  tallies,
15285
15318
  (created, parent) => {
@@ -15620,11 +15653,15 @@ function buildCacheAttribution(args) {
15620
15653
  ];
15621
15654
  return { roots, owners };
15622
15655
  }
15623
- function synthesizeSubUnits(summaries, project, frameworks, options, tallies, onCreated) {
15656
+ function synthesizeSubUnits(summaries, project, frameworks, packsByFile, options, tallies, onCreated) {
15624
15657
  const packByRecognition = /* @__PURE__ */ new Map();
15625
15658
  for (const pack of frameworks) {
15626
15659
  packByRecognition.set(pack.name, pack);
15627
15660
  }
15661
+ const packsByPath = /* @__PURE__ */ new Map();
15662
+ for (const [sf, packs] of packsByFile) {
15663
+ packsByPath.set(sf.getFilePath(), packs);
15664
+ }
15628
15665
  const allInvocationRecognizers = collectInvocationRecognizers(
15629
15666
  frameworks,
15630
15667
  tallies
@@ -15638,8 +15675,15 @@ function synthesizeSubUnits(summaries, project, frameworks, options, tallies, on
15638
15675
  if (binding === null) {
15639
15676
  continue;
15640
15677
  }
15641
- const pack = packByRecognition.get(binding.recognition);
15642
- if (pack?.subUnits === void 0) {
15678
+ const discovering = packByRecognition.get(binding.recognition);
15679
+ const applicable = packsByPath.get(parent.location.file) ?? (discovering !== void 0 ? [discovering] : []);
15680
+ const hooked = [
15681
+ ...discovering?.subUnits !== void 0 ? [discovering] : [],
15682
+ ...applicable.filter(
15683
+ (one) => one.subUnits !== void 0 && one !== discovering
15684
+ )
15685
+ ];
15686
+ if (hooked.length === 0) {
15643
15687
  continue;
15644
15688
  }
15645
15689
  lookup ??= createSourceFileLookup(project);
@@ -15652,7 +15696,17 @@ function synthesizeSubUnits(summaries, project, frameworks, options, tallies, on
15652
15696
  name: parent.identity.name,
15653
15697
  kind: parent.kind
15654
15698
  };
15655
- const subUnits = pack.subUnits(parentHandle, subUnitCtx);
15699
+ const claimedFuncs = /* @__PURE__ */ new Set();
15700
+ const subUnits = [];
15701
+ for (const pack of hooked) {
15702
+ for (const subUnit of pack.subUnits?.(parentHandle, subUnitCtx) ?? []) {
15703
+ if (claimedFuncs.has(subUnit.func)) {
15704
+ continue;
15705
+ }
15706
+ claimedFuncs.add(subUnit.func);
15707
+ subUnits.push(subUnit);
15708
+ }
15709
+ }
15656
15710
  for (const subUnit of subUnits) {
15657
15711
  const summary = buildSubUnitSummary(
15658
15712
  subUnit,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@suss/adapter-typescript",
3
- "version": "0.16.0",
3
+ "version": "0.17.0",
4
4
  "type": "module",
5
5
  "description": "TypeScript adapter for suss — walks source files with ts-morph and emits raw extractions for the suss pipeline.",
6
6
  "keywords": [
@@ -46,10 +46,10 @@
46
46
  "typecheck": "tsc --noEmit"
47
47
  },
48
48
  "dependencies": {
49
- "@suss/behavioral-ir": "0.16.0",
50
- "@suss/datalog": "0.16.0",
51
- "@suss/extractor": "0.16.0",
52
- "@suss/resolution": "0.16.0",
49
+ "@suss/behavioral-ir": "0.17.0",
50
+ "@suss/datalog": "0.17.0",
51
+ "@suss/extractor": "0.17.0",
52
+ "@suss/resolution": "0.17.0",
53
53
  "graphql": "^16.8.0",
54
54
  "picomatch": "^4.0.4",
55
55
  "ts-morph": "^23.0.0"