diffninja 0.1.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.
Files changed (154) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +259 -0
  3. package/dist/calltree.d.ts +47 -0
  4. package/dist/calltree.js +296 -0
  5. package/dist/cli.d.ts +57 -0
  6. package/dist/cli.js +340 -0
  7. package/dist/diff.d.ts +7 -0
  8. package/dist/diff.js +114 -0
  9. package/dist/extract.d.ts +26 -0
  10. package/dist/extract.js +152 -0
  11. package/dist/git.d.ts +40 -0
  12. package/dist/git.js +288 -0
  13. package/dist/index.d.ts +9 -0
  14. package/dist/index.js +8 -0
  15. package/dist/infer.d.ts +21 -0
  16. package/dist/infer.js +189 -0
  17. package/dist/languages/bash.d.ts +2 -0
  18. package/dist/languages/bash.js +208 -0
  19. package/dist/languages/c.d.ts +2 -0
  20. package/dist/languages/c.js +218 -0
  21. package/dist/languages/call-syntax.d.ts +125 -0
  22. package/dist/languages/call-syntax.js +997 -0
  23. package/dist/languages/cpp.d.ts +2 -0
  24. package/dist/languages/cpp.js +321 -0
  25. package/dist/languages/csharp.d.ts +2 -0
  26. package/dist/languages/csharp.js +324 -0
  27. package/dist/languages/elixir.d.ts +2 -0
  28. package/dist/languages/elixir.js +331 -0
  29. package/dist/languages/go.d.ts +2 -0
  30. package/dist/languages/go.js +299 -0
  31. package/dist/languages/grammars.d.ts +50 -0
  32. package/dist/languages/grammars.js +351 -0
  33. package/dist/languages/haskell.d.ts +2 -0
  34. package/dist/languages/haskell.js +250 -0
  35. package/dist/languages/java.d.ts +2 -0
  36. package/dist/languages/java.js +351 -0
  37. package/dist/languages/javascript.d.ts +4 -0
  38. package/dist/languages/javascript.js +648 -0
  39. package/dist/languages/kotlin.d.ts +2 -0
  40. package/dist/languages/kotlin.js +368 -0
  41. package/dist/languages/lua.d.ts +2 -0
  42. package/dist/languages/lua.js +212 -0
  43. package/dist/languages/ocaml.d.ts +2 -0
  44. package/dist/languages/ocaml.js +291 -0
  45. package/dist/languages/perl.d.ts +2 -0
  46. package/dist/languages/perl.js +418 -0
  47. package/dist/languages/php.d.ts +2 -0
  48. package/dist/languages/php.js +397 -0
  49. package/dist/languages/python.d.ts +2 -0
  50. package/dist/languages/python.js +376 -0
  51. package/dist/languages/registry.d.ts +7 -0
  52. package/dist/languages/registry.js +69 -0
  53. package/dist/languages/ruby.d.ts +2 -0
  54. package/dist/languages/ruby.js +391 -0
  55. package/dist/languages/rust.d.ts +2 -0
  56. package/dist/languages/rust.js +261 -0
  57. package/dist/languages/scala.d.ts +2 -0
  58. package/dist/languages/scala.js +307 -0
  59. package/dist/languages/solidity.d.ts +2 -0
  60. package/dist/languages/solidity.js +240 -0
  61. package/dist/languages/swift.d.ts +2 -0
  62. package/dist/languages/swift.js +268 -0
  63. package/dist/languages/types.d.ts +36 -0
  64. package/dist/languages/types.js +74 -0
  65. package/dist/languages/typescript-contracts.d.ts +57 -0
  66. package/dist/languages/typescript-contracts.js +528 -0
  67. package/dist/languages/typescript-dispatch.d.ts +68 -0
  68. package/dist/languages/typescript-dispatch.js +710 -0
  69. package/dist/languages/typescript.d.ts +4 -0
  70. package/dist/languages/typescript.js +722 -0
  71. package/dist/languages/zig.d.ts +2 -0
  72. package/dist/languages/zig.js +243 -0
  73. package/dist/loc.d.ts +17 -0
  74. package/dist/loc.js +34 -0
  75. package/dist/reach.d.ts +17 -0
  76. package/dist/reach.js +65 -0
  77. package/dist/render.d.ts +18 -0
  78. package/dist/render.js +83 -0
  79. package/dist/review/brand.d.ts +8 -0
  80. package/dist/review/brand.js +25 -0
  81. package/dist/review/call-context.d.ts +27 -0
  82. package/dist/review/call-context.js +446 -0
  83. package/dist/review/call-flow-html.d.ts +32 -0
  84. package/dist/review/call-flow-html.js +1870 -0
  85. package/dist/review/call-flow-nav.d.ts +151 -0
  86. package/dist/review/call-flow-nav.js +317 -0
  87. package/dist/review/call-flow.d.ts +47 -0
  88. package/dist/review/call-flow.js +229 -0
  89. package/dist/review/change-facts.d.ts +69 -0
  90. package/dist/review/change-facts.js +729 -0
  91. package/dist/review/cli.d.ts +2 -0
  92. package/dist/review/cli.js +50 -0
  93. package/dist/review/connected-analysis.d.ts +100 -0
  94. package/dist/review/connected-analysis.js +163 -0
  95. package/dist/review/connected-html.d.ts +17 -0
  96. package/dist/review/connected-html.js +2853 -0
  97. package/dist/review/connected.d.ts +23 -0
  98. package/dist/review/connected.js +141 -0
  99. package/dist/review/escape-html.d.ts +2 -0
  100. package/dist/review/escape-html.js +9 -0
  101. package/dist/review/evidence-html.d.ts +21 -0
  102. package/dist/review/evidence-html.js +521 -0
  103. package/dist/review/evidence-syntax.d.ts +132 -0
  104. package/dist/review/evidence-syntax.js +478 -0
  105. package/dist/review/evidence-types.d.ts +62 -0
  106. package/dist/review/evidence-types.js +1 -0
  107. package/dist/review/evidence.d.ts +31 -0
  108. package/dist/review/evidence.js +1603 -0
  109. package/dist/review/file-role.d.ts +9 -0
  110. package/dist/review/file-role.js +29 -0
  111. package/dist/review/github.d.ts +204 -0
  112. package/dist/review/github.js +1245 -0
  113. package/dist/review/history.d.ts +101 -0
  114. package/dist/review/history.js +412 -0
  115. package/dist/review/html.d.ts +34 -0
  116. package/dist/review/html.js +1104 -0
  117. package/dist/review/input.d.ts +10 -0
  118. package/dist/review/input.js +113 -0
  119. package/dist/review/intent.d.ts +4 -0
  120. package/dist/review/intent.js +75 -0
  121. package/dist/review/mcp-cli.d.ts +2 -0
  122. package/dist/review/mcp-cli.js +25 -0
  123. package/dist/review/mcp.d.ts +12 -0
  124. package/dist/review/mcp.js +414 -0
  125. package/dist/review/module-resolution.d.ts +2 -0
  126. package/dist/review/module-resolution.js +86 -0
  127. package/dist/review/palette.d.ts +7 -0
  128. package/dist/review/palette.js +104 -0
  129. package/dist/review/pipeline.d.ts +77 -0
  130. package/dist/review/pipeline.js +227 -0
  131. package/dist/review/pr-input.d.ts +19 -0
  132. package/dist/review/pr-input.js +130 -0
  133. package/dist/review/questions.d.ts +201 -0
  134. package/dist/review/questions.js +174 -0
  135. package/dist/review/reference-check.d.ts +7 -0
  136. package/dist/review/reference-check.js +733 -0
  137. package/dist/review/report-pages.d.ts +109 -0
  138. package/dist/review/report-pages.js +328 -0
  139. package/dist/review/service.d.ts +23 -0
  140. package/dist/review/service.js +198 -0
  141. package/dist/review/setup.d.ts +112 -0
  142. package/dist/review/setup.js +549 -0
  143. package/dist/review/source.d.ts +26 -0
  144. package/dist/review/source.js +276 -0
  145. package/dist/review/toml.d.ts +38 -0
  146. package/dist/review/toml.js +565 -0
  147. package/dist/review/types.d.ts +179 -0
  148. package/dist/review/types.js +1 -0
  149. package/dist/run.d.ts +49 -0
  150. package/dist/run.js +311 -0
  151. package/dist/types.d.ts +366 -0
  152. package/dist/types.js +83 -0
  153. package/package.json +88 -0
  154. package/scripts/ensure-native-grammar.mjs +188 -0
@@ -0,0 +1,291 @@
1
+ import { heuristicCallSyntax } from "./call-syntax.js";
2
+ import { childByType, collapseWs, locFromNode, namedChildren, } from "./types.js";
3
+ function getParamsLabel(binding) {
4
+ const names = [];
5
+ for (const c of namedChildren(binding)) {
6
+ if (c.type !== "parameter")
7
+ continue;
8
+ const pat = childByType(c, "value_pattern") ??
9
+ childByType(c, "unit") ??
10
+ c.namedChild(0);
11
+ if (!pat) {
12
+ names.push("_");
13
+ continue;
14
+ }
15
+ if (pat.type === "unit")
16
+ continue; // `()` param → show as no-arg slot
17
+ names.push(pat.text);
18
+ }
19
+ return names.length === 0 ? "()" : `(${names.join(", ")})`;
20
+ }
21
+ function valuePathKey(node, moduleName) {
22
+ if (node.type === "value_name") {
23
+ return moduleName ? `${moduleName}.${node.text}` : node.text;
24
+ }
25
+ if (node.type === "value_path") {
26
+ const value = childByType(node, "value_name");
27
+ if (!value)
28
+ return null;
29
+ const modPath = childByType(node, "module_path");
30
+ if (modPath) {
31
+ // Flatten module_path text: Runner.Validate.x → keep as written
32
+ const mods = [];
33
+ const collectMods = (n) => {
34
+ for (const c of namedChildren(n)) {
35
+ if (c.type === "module_path")
36
+ collectMods(c);
37
+ else if (c.type === "module_name")
38
+ mods.push(c.text);
39
+ }
40
+ };
41
+ collectMods(modPath);
42
+ return mods.length > 0 ? `${mods.join(".")}.${value.text}` : value.text;
43
+ }
44
+ // Bare value inside module → Module.value
45
+ return moduleName ? `${moduleName}.${value.text}` : value.text;
46
+ }
47
+ if (node.type === "field_get_expression") {
48
+ const obj = node.namedChild(0);
49
+ const field = childByType(node, "field_path") ?? node.namedChild(1);
50
+ const fieldName = field && (childByType(field, "field_name")?.text ?? field.text);
51
+ if (!fieldName)
52
+ return null;
53
+ if (obj?.type === "value_path") {
54
+ const simple = childByType(obj, "value_name");
55
+ if (simple && !childByType(obj, "module_path")) {
56
+ return `${simple.text}.${fieldName}`;
57
+ }
58
+ }
59
+ return fieldName;
60
+ }
61
+ return null;
62
+ }
63
+ function collectExpr(file, node, moduleName) {
64
+ if (!node)
65
+ return [];
66
+ const steps = [];
67
+ const seen = new Set();
68
+ const addCall = (key, node) => {
69
+ const mark = `${key}:${node.startIndex}`;
70
+ if (seen.has(mark))
71
+ return;
72
+ seen.add(mark);
73
+ const step = { type: "call", key, ...locFromNode(file, node) };
74
+ step.syntax = heuristicCallSyntax(node, key);
75
+ steps.push(step);
76
+ };
77
+ const walk = (n) => {
78
+ // Nested functions
79
+ if (n.type === "fun_expression" ||
80
+ n.type === "function_expression" ||
81
+ n.type === "value_definition" ||
82
+ n.type === "let_binding" ||
83
+ n.type === "module_definition") {
84
+ // Nested lets/functions/modules are not attributed to the outer caller;
85
+ // `let x = e in body` is handled separately below.
86
+ return;
87
+ }
88
+ if (n.type === "let_expression") {
89
+ // let x = rhs in body — walk rhs + body; skip indexing nested binding
90
+ const vd = childByType(n, "value_definition");
91
+ if (vd) {
92
+ for (const b of namedChildren(vd)) {
93
+ if (b.type !== "let_binding")
94
+ continue;
95
+ const hasParams = namedChildren(b).some((c) => c.type === "parameter");
96
+ // Nested function bodies are not attributed to the outer caller
97
+ if (hasParams)
98
+ continue;
99
+ // rhs is last non-parameter child
100
+ const kids = namedChildren(b);
101
+ const rhs = kids.find((c) => c.type !== "value_name" &&
102
+ c.type !== "parameter" &&
103
+ c.type !== "type_constraint") ?? kids[kids.length - 1] ?? null;
104
+ if (rhs)
105
+ walk(rhs);
106
+ }
107
+ }
108
+ // body is typically last named child
109
+ const body = namedChildren(n).find((c) => c.type !== "value_definition") ?? null;
110
+ if (body)
111
+ walk(body);
112
+ return;
113
+ }
114
+ if (n.type === "match_expression" || n.type === "try_expression") {
115
+ if (n.type === "try_expression") {
116
+ const tryBody = namedChildren(n).find((c) => c.type !== "match_case") ?? null;
117
+ steps.push({
118
+ type: "branch",
119
+ key: "try",
120
+ label: "try",
121
+ ...locFromNode(file, n),
122
+ children: tryBody ? collectExpr(file, tryBody, moduleName) : [],
123
+ });
124
+ }
125
+ for (const clause of namedChildren(n)) {
126
+ if (clause.type !== "match_case")
127
+ continue;
128
+ const kids = namedChildren(clause);
129
+ const body = kids[kids.length - 1] ?? null;
130
+ const pattern = kids.length > 1 ? kids[0] : null;
131
+ const text = pattern ? collapseWs(pattern.text) : "";
132
+ const labelKind = n.type === "try_expression" ? "with" : "case";
133
+ steps.push({
134
+ type: "branch",
135
+ key: text ? `${labelKind}:${text}` : labelKind,
136
+ label: text ? `${labelKind} ${text}` : labelKind,
137
+ ...locFromNode(file, pattern ?? clause),
138
+ children: body ? collectExpr(file, body, moduleName) : [],
139
+ });
140
+ }
141
+ return;
142
+ }
143
+ if (n.type === "if_expression") {
144
+ const kids = namedChildren(n);
145
+ const thenClause = childByType(n, "then_clause");
146
+ const elseClause = childByType(n, "else_clause");
147
+ const cond = kids.find((c) => c.type !== "then_clause" && c.type !== "else_clause") ?? null;
148
+ const condText = cond ? collapseWs(cond.text) : "";
149
+ steps.push({
150
+ type: "branch",
151
+ key: condText ? `if:${condText}` : "if",
152
+ label: condText ? `if ${condText}` : "if",
153
+ ...locFromNode(file, cond ?? n),
154
+ children: thenClause
155
+ ? collectExpr(file, thenClause.namedChild(0) ?? thenClause, moduleName)
156
+ : [],
157
+ });
158
+ if (elseClause) {
159
+ const elseBody = elseClause.namedChild(0) ?? elseClause;
160
+ if (elseBody.type === "if_expression") {
161
+ const nested = collectExpr(file, elseBody, moduleName);
162
+ for (const s of nested) {
163
+ if (s.type === "branch" && (s.key === "if" || s.key.startsWith("if:"))) {
164
+ steps.push({
165
+ ...s,
166
+ key: s.key === "if" ? "else-if" : s.key.replace(/^if:/, "else-if:"),
167
+ label: s.label.replace(/^if /, "else if "),
168
+ });
169
+ }
170
+ else {
171
+ steps.push(s);
172
+ }
173
+ }
174
+ }
175
+ else {
176
+ steps.push({
177
+ type: "branch",
178
+ key: "else",
179
+ label: "else",
180
+ ...locFromNode(file, elseClause),
181
+ children: collectExpr(file, elseBody, moduleName),
182
+ });
183
+ }
184
+ }
185
+ if (cond)
186
+ walk(cond);
187
+ return;
188
+ }
189
+ if (n.type === "application_expression") {
190
+ const callee = n.namedChild(0);
191
+ if (callee) {
192
+ const key = valuePathKey(callee, moduleName);
193
+ if (key)
194
+ addCall(key, n);
195
+ }
196
+ for (const child of namedChildren(n).slice(1))
197
+ walk(child);
198
+ return;
199
+ }
200
+ if (n.type === "sequence_expression") {
201
+ for (const child of namedChildren(n))
202
+ walk(child);
203
+ return;
204
+ }
205
+ for (const child of namedChildren(n))
206
+ walk(child);
207
+ };
208
+ walk(node);
209
+ return steps;
210
+ }
211
+ function bindingBody(binding) {
212
+ const kids = namedChildren(binding);
213
+ // skip value_name, parameters, type constraints
214
+ const body = [...kids]
215
+ .reverse()
216
+ .find((c) => c.type !== "value_name" &&
217
+ c.type !== "parameter" &&
218
+ c.type !== "type_constraint" &&
219
+ c.type !== "attribute") ?? null;
220
+ return body;
221
+ }
222
+ function handleLetBinding(file, binding, moduleName, functions) {
223
+ const name = childByType(binding, "value_name")?.text ?? null;
224
+ if (!name)
225
+ return;
226
+ // Only treat as function if it has parameters or is clearly a fun
227
+ const hasParams = namedChildren(binding).some((c) => c.type === "parameter");
228
+ const body = bindingBody(binding);
229
+ // `let f = fun x -> ...` is callable; any other binding without parameters is not.
230
+ if (!hasParams && body?.type !== "fun_expression")
231
+ return;
232
+ const key = moduleName ? `${moduleName}.${name}` : name;
233
+ const funBody = body?.type === "fun_expression"
234
+ ? bindingBody(body) ?? body.namedChild(body.namedChildCount - 1)
235
+ : body;
236
+ functions.push({
237
+ key,
238
+ label: `${key}${getParamsLabel(binding)}`,
239
+ file,
240
+ steps: collectExpr(file, funBody, moduleName),
241
+ exported: true,
242
+ start: binding.startIndex,
243
+ end: binding.endIndex,
244
+ });
245
+ }
246
+ function handleValueDefinition(file, node, moduleName, functions) {
247
+ for (const b of namedChildren(node)) {
248
+ if (b.type === "let_binding") {
249
+ handleLetBinding(file, b, moduleName, functions);
250
+ }
251
+ }
252
+ }
253
+ function handleModule(file, node, functions) {
254
+ const binding = childByType(node, "module_binding") ?? node;
255
+ const name = childByType(binding, "module_name")?.text ??
256
+ childByType(node, "module_name")?.text ??
257
+ null;
258
+ if (!name)
259
+ return;
260
+ const structure = childByType(binding, "structure") ?? childByType(node, "structure");
261
+ if (!structure)
262
+ return;
263
+ for (const item of namedChildren(structure)) {
264
+ if (item.type === "value_definition") {
265
+ handleValueDefinition(file, item, name, functions);
266
+ }
267
+ else if (item.type === "module_definition") {
268
+ // nested modules — prefix could be nested; skip deep nesting for prototype
269
+ handleModule(file, item, functions);
270
+ }
271
+ }
272
+ }
273
+ function extractFromTree(file, _source, tree) {
274
+ const functions = [];
275
+ for (const stmt of namedChildren(tree.rootNode)) {
276
+ if (stmt.type === "value_definition") {
277
+ handleValueDefinition(file, stmt, null, functions);
278
+ }
279
+ else if (stmt.type === "module_definition") {
280
+ handleModule(file, stmt, functions);
281
+ }
282
+ }
283
+ return functions;
284
+ }
285
+ export const ocamlExtractor = {
286
+ id: "ocaml",
287
+ extensions: [".ml"],
288
+ grammarPackage: "tree-sitter-ocaml",
289
+ grammarExport: "ocaml",
290
+ extract: extractFromTree,
291
+ };
@@ -0,0 +1,2 @@
1
+ import { type LanguageExtractor } from "./types.js";
2
+ export declare const perlExtractor: LanguageExtractor;