MCPcopy Create free account
hub / github.com/colbymchenry/codegraph / effectLink

Function effectLink

src/ui-server/api/steps.ts:897–980  ·  view source on GitHub ↗
(
    step: StepRecord,
    fold: Fold,
    ref: { referenceName: string; referenceKind: 'calls' | 'instantiates'; line: number; column?: number },
    trigger: WireStepTrigger | null,
    fallbackArgs: string | null = null,
    requireReceiver = false,
    /** A site that is no call — a handler's `return "redirect:/x"` — arrives already classified. */
    preset: { effect: Effect; status: number | null } | null = null
  )

Source from the content-addressed store, hash-verified

895
896 /** One effect site: the call as written, what it passes, when, what fires it, and — for a response — the status. */
897 const effectLink = async (
898 step: StepRecord,
899 fold: Fold,
900 ref: { referenceName: string; referenceKind: 'calls' | 'instantiates'; line: number; column?: number },
901 trigger: WireStepTrigger | null,
902 fallbackArgs: string | null = null,
903 requireReceiver = false,
904 /** A site that is no call — a handler's `return "redirect:/x"` — arrives already classified. */
905 preset: { effect: Effect; status: number | null } | null = null
906 ): Promise<boolean> => {
907 const at = { line: ref.line, column: ref.column };
908 const site = preset ? null : await callAt(fold.node, { ...at, callee: ref.referenceName });
909 // The site read must be THIS call: its last segment is the reference's.
910 const last = (n: string) => n.replace(/\([^()]*\)/g, '').split(/[.:]/).pop() ?? n;
911 const usable = !!site && site.callee !== '' && last(site.callee) === last(ref.referenceName);
912 const text = usable ? site.callee : ref.referenceName;
913 if (requireReceiver && !/[.:>]/.test(text)) return false;
914 const args = usable ? site.args : fallbackArgs;
915 // The receiver's declared type counts only when the call leaves the
916 // index through it: a library's `Repository<Cat>`, or the project's own
917 // `OwnerRepository` interface whose `save` comes from Spring Data — never
918 // a project class that declares the method, which is a place to walk into.
919 let effect: Effect | null = preset?.effect ?? null;
920 if (!preset) {
921 const declared = await receiverTypeFor(fold.node, text);
922 const receiverType = declared && (await resolveByReceiver(fold.node, text)) === null ? declared : null;
923 effect = classifyEffect({
924 text,
925 kind: ref.referenceKind,
926 language: fold.node.language,
927 project,
928 receiverType,
929 args,
930 projectType: fold.node.language === 'swift' && (await declaresSwiftType(text)),
931 });
932 }
933 if (effect === null) return false;
934 // A reply's status, read before its box exists — the box is per outcome.
935 // `NextResponse.json(user, { status: 201 })`: the code sits in an object
936 // the abbreviation reduced to its keys; the site reader kept it. And a
937 // body-sending reply that sets none is a 200, so a success has a box of
938 // its own beside the 401's.
939 const status = preset
940 ? preset.status
941 : effect.category === 'response'
942 ? (responseStatus(text, args, ref.referenceKind) ?? (usable && typeof site.status === 'number' ? site.status : null) ?? implicitResponseStatus(text))
943 : null;
944 // What fires this call, read before its box is made: a call bound inside
945 // ANOTHER effect's arguments — the axios.delete in a confirm dialog's
946 // button — hangs off that box, one step deeper, not off the screen.
947 const fired = trigger ?? (await triggerAt(fold.node, at));
948 const from = fired?.of ? (firedByEffect(fold.node.id, at, fired.of) ?? step) : step;
949 const target = effectStep(fold.node, { referenceName: text, line: ref.line }, effect, from.depth + 1, status);
950 if (target === null) return true;
951 const guards = await guardsAt(fold.node, at);
952 const when = guardLabel(guards);
953 const wireSite: WireStepSite = { file: posix(fold.node.filePath), line: ref.line, text, when: '' };
954 if (args !== null) wireSite.args = args;

Callers 1

buildStepsFunction · 0.85

Calls 15

classifyEffectFunction · 0.90
responseStatusFunction · 0.90
implicitResponseStatusFunction · 0.90
guardLabelFunction · 0.90
lastFunction · 0.85
receiverTypeForFunction · 0.85
resolveByReceiverFunction · 0.85
declaresSwiftTypeFunction · 0.85
firedByEffectFunction · 0.85
effectStepFunction · 0.85
posixFunction · 0.85
decisionOfFunction · 0.85

Tested by

no test coverage detected