@mnemonica/tactica 0.1.15 → 0.3.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.
@@ -0,0 +1,131 @@
1
+ import * as ts from 'typescript';
2
+ import { LocalScopeWalker } from './scopes';
3
+ import { CreationGraph, ModuleGraph, ScopeAnalysis, UsageInfo } from './types';
4
+ /**
5
+ * Inside-out creation walker (instrumentation walker plan, Phase 3).
6
+ *
7
+ * Starts at the certain points — instantiation usages carrying a
8
+ * holderScopeId — then walks OUTWARD: who invokes or references the holder,
9
+ * crossing files through the module graph (barrels chased the same way
10
+ * ModuleGraphBuilder.resolveOrigin does), until no callers remain. Terminals
11
+ * are the starters (application entry points). The walk never assumes a
12
+ * linear Trie (decision 1: strictChain:false permits cycles/out-of-order
13
+ * construction), so traversal is cycle-guarded DFS, and every anchor records
14
+ * which constructor expression was actually used.
15
+ *
16
+ * Deliberate approximations (no getTypeChecker(), name-based only):
17
+ * - Namespace imports (`import * as ns`): when the namespace's source module
18
+ * exposes the holder's export, ANY reference to the alias counts as a
19
+ * caller reference.
20
+ * - Method scopes bind to their CLASS name (callers reference the class);
21
+ * instance-method call sites (`obj.method()`) are not distinguishable
22
+ * without the checker.
23
+ * - Any non-declaration identifier counts as a reference (invocations,
24
+ * pass-as-arg, rebinding); type-position references are not filtered.
25
+ * - Module scopes end the invocation walk, but a terminal module still
26
+ * gains its IMPORTERS as callers: entry modules hand classes to the
27
+ * framework as values (a bootstrap call receiving the root module),
28
+ * which no call-walk can see — the import relation bridges them to
29
+ * the center.
30
+ */
31
+ export declare class CreationGraphBuilder {
32
+ private moduleGraph;
33
+ private scopeAnalysis;
34
+ private scopeWalker;
35
+ /** Keyed by path.resolve(sourceFile.fileName), matching scopeIds */
36
+ private sourceFiles;
37
+ /** filePath -> (identifier text -> reference locations), built lazily per file */
38
+ private referencesByFile;
39
+ constructor(moduleGraph: ModuleGraph, scopeAnalysis: ScopeAnalysis, scopeWalker: LocalScopeWalker, sourceFiles: Map<string, ts.SourceFile>);
40
+ /**
41
+ * Build the creation graph from the analyzer's usages (holderScopeId
42
+ * already attached). Always returns a graph, empty arrays when nothing
43
+ * creates mnemonica instances.
44
+ */
45
+ build(usages: Map<string, UsageInfo[]>): CreationGraph;
46
+ /**
47
+ * One anchor per instantiation usage with a known holder scope.
48
+ */
49
+ private collectAnchors;
50
+ /**
51
+ * Same-line heuristic for the anchor's variable: the variable declared in
52
+ * the holder scope on the same line as the creation, whose typePath (when
53
+ * known) matches the created type.
54
+ */
55
+ private matchAnchorVariable;
56
+ /**
57
+ * Parse the 1-based line out of a file.ts:Line:Col location string.
58
+ */
59
+ private static lineOf;
60
+ private static nodeOf;
61
+ /**
62
+ * The name a scope is reachable by: functions/arrows take their scope
63
+ * name; methods take their class (the part before '.') — that is what
64
+ * callers reference. Anonymous holders (file:line labels) and module
65
+ * scopes have no binding name.
66
+ */
67
+ private static bindingNameOf;
68
+ /**
69
+ * Scope ids referencing `bindingName` inside one file (invocations,
70
+ * pass-as-arg, rebindings — any non-declaration identifier).
71
+ */
72
+ private callersOf;
73
+ /**
74
+ * Callers in OTHER modules, followed through the module graph when the
75
+ * holder's binding is exported (the plan's "if f is exported" branch,
76
+ * including the barrel chase).
77
+ */
78
+ private findCrossFileCallers;
79
+ /**
80
+ * Modules importing bindings whose ORIGIN is `filePath` — the
81
+ * exports-and-usage bridge for terminal module scopes. Any binding kind
82
+ * counts (named, default, re-export): resolveImportOrigin chases barrels
83
+ * to the declaring module; namespace imports and external packages never
84
+ * resolve, so neither connects. Returned as module-scope scopeIds — a
85
+ * module's scopeId IS its resolved filePath.
86
+ */
87
+ private importersOf;
88
+ /**
89
+ * The local identifier an import binding presents for reference search,
90
+ * when the binding resolves to the holder's export — undefined otherwise.
91
+ */
92
+ private importReferencesHolder;
93
+ /**
94
+ * True when a namespace import's source module exposes `exportedName`
95
+ * whose origin is the holder's module. Expressed as resolving a synthetic
96
+ * named binding, so star barrels and named re-exports are chased by the
97
+ * same machinery as plain imports.
98
+ */
99
+ private namespaceExposes;
100
+ /**
101
+ * Chase an import binding to the module that actually declares it,
102
+ * following re-export chains (barrels). Same shape as
103
+ * ModuleGraphBuilder.resolveOrigin, run here over the BUILT graph
104
+ * (sourceModule values are already resolved absolute paths).
105
+ * Cycle-guarded; undefined when the origin is external or the chain loops.
106
+ */
107
+ private resolveImportOrigin;
108
+ /**
109
+ * All references to `name` in a file as location strings. The per-file
110
+ * index is built lazily in ONE pass (every identifier bucketed by text)
111
+ * and cached.
112
+ */
113
+ private referencesIn;
114
+ /**
115
+ * Bucket every identifier reference by name. Declaration and wiring
116
+ * positions are NOT references: import/export specifiers, declaration
117
+ * names, property-access `.name`, and property-assignment keys go into a
118
+ * skip set of NODES — program files can be unbound, so parent-pointer
119
+ * checks are impossible (the scopes walker precedent, Phase 2).
120
+ * ShorthandPropertyAssignment names DO count: `{ foo }` is a genuine
121
+ * reference to foo.
122
+ */
123
+ private static collectReferences;
124
+ /**
125
+ * Register the identifier nodes that must NOT count as references when
126
+ * `node` is a wiring/declaration construct. Runs on the parent before
127
+ * descending, so the skip set is populated before the identifier nodes
128
+ * themselves are visited.
129
+ */
130
+ private static registerSkips;
131
+ }