@eagleoutice/flowr 2.7.4 → 2.7.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.
Files changed (36) hide show
  1. package/README.md +15 -15
  2. package/cli/repl/commands/repl-commands.d.ts +2 -0
  3. package/cli/repl/commands/repl-commands.js +2 -0
  4. package/cli/repl/commands/repl-dataflow.d.ts +2 -0
  5. package/cli/repl/commands/repl-dataflow.js +38 -1
  6. package/cli/repl/core.js +22 -0
  7. package/config.d.ts +5 -0
  8. package/config.js +6 -0
  9. package/dataflow/graph/graph.js +2 -0
  10. package/documentation/wiki-analyzer.js +12 -0
  11. package/documentation/wiki-interface.js +3 -0
  12. package/documentation/wiki-query.js +1 -1
  13. package/package.json +5 -1
  14. package/project/context/flowr-analyzer-dependencies-context.d.ts +5 -1
  15. package/project/context/flowr-analyzer-functions-context.d.ts +16 -0
  16. package/project/context/flowr-analyzer-functions-context.js +6 -0
  17. package/project/context/flowr-analyzer-loading-order-context.d.ts +4 -4
  18. package/project/context/flowr-analyzer-loading-order-context.js +4 -0
  19. package/project/plugins/file-plugins/files/flowr-description-file.d.ts +18 -1
  20. package/project/plugins/file-plugins/files/flowr-description-file.js +70 -13
  21. package/project/plugins/loading-order-plugins/flowr-analyzer-loading-order-description-file-plugin.js +8 -3
  22. package/project/plugins/package-version-plugins/flowr-analyzer-package-versions-description-file-plugin.js +5 -2
  23. package/project/plugins/package-version-plugins/flowr-analyzer-package-versions-namespace-file-plugin.js +6 -1
  24. package/project/plugins/package-version-plugins/package.js +1 -1
  25. package/project/plugins/project-discovery/flowr-analyzer-project-discovery-plugin.js +12 -2
  26. package/queries/catalog/project-query/project-query-executor.js +12 -2
  27. package/queries/catalog/project-query/project-query-format.d.ts +13 -0
  28. package/queries/catalog/project-query/project-query-format.js +25 -2
  29. package/queries/query-print.js +8 -3
  30. package/util/mermaid/cfg.d.ts +3 -0
  31. package/util/mermaid/cfg.js +25 -0
  32. package/util/r-author.d.ts +39 -0
  33. package/util/r-author.js +194 -0
  34. package/util/simple-df/dfg-ascii.d.ts +5 -0
  35. package/util/simple-df/dfg-ascii.js +272 -0
  36. package/util/version.js +1 -1
@@ -0,0 +1,272 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.dfgToAscii = dfgToAscii;
4
+ const dagre_1 = require("dagre");
5
+ const edge_1 = require("../../dataflow/graph/edge");
6
+ const node_id_1 = require("../../r-bridge/lang-4.x/ast/model/processing/node-id");
7
+ const vertex_1 = require("../../dataflow/graph/vertex");
8
+ function combineAscii(has, add) {
9
+ if (has === ' ' || has === add) {
10
+ return add;
11
+ }
12
+ const [a, b] = [has, add].sort();
13
+ let res = add;
14
+ if (b === edgesChar.vertical && a === edgesChar.horizontal) {
15
+ res = '┼';
16
+ }
17
+ else if ((b === edgesChar.topRight || b === edgesChar.topLeft || b === '┬') && a === edgesChar.horizontal) {
18
+ res = '┬';
19
+ }
20
+ else if ((b === edgesChar.bottomRight || b === edgesChar.bottomLeft || b === '┴') && a === edgesChar.horizontal) {
21
+ res = '┴';
22
+ }
23
+ else if ((b === edgesChar.topRight || b === edgesChar.bottomRight || b === '┤') && a === edgesChar.vertical) {
24
+ res = '┤';
25
+ }
26
+ else if ((b === edgesChar.topLeft || b === edgesChar.bottomLeft || b === '├') && a === edgesChar.vertical) {
27
+ res = '├';
28
+ }
29
+ else if ((b === '┤' || b === '├') && a === edgesChar.horizontal) {
30
+ res = '┼';
31
+ }
32
+ else if ((b === '┬' || b === '┴') && a === edgesChar.vertical) {
33
+ res = '┼';
34
+ }
35
+ return res;
36
+ }
37
+ class AsciiCanvas {
38
+ filler;
39
+ grid;
40
+ shiftX;
41
+ shiftY;
42
+ constructor(filler = ' ', shiftX = 0, shiftY = 0) {
43
+ this.grid = [];
44
+ this.filler = filler;
45
+ this.shiftX = shiftX;
46
+ this.shiftY = shiftY;
47
+ }
48
+ set(x, y, char, overwrite = false) {
49
+ x += this.shiftX;
50
+ y += this.shiftY;
51
+ if (x < 0 || y < 0 || isNaN(x) || isNaN(y)) {
52
+ return;
53
+ }
54
+ while (this.grid.length <= y) {
55
+ this.grid.push([]);
56
+ }
57
+ while (this.grid[y].length <= x) {
58
+ this.grid[y].push(this.filler);
59
+ }
60
+ this.grid[y][x] = overwrite ? char : combineAscii(this.grid[y][x], char);
61
+ }
62
+ drawText(x, y, text) {
63
+ for (let i = 0; i < text.length; i++) {
64
+ this.set(x + i, y, text[i]);
65
+ }
66
+ }
67
+ toString() {
68
+ return this.grid.map(r => r.join('')).join('\n');
69
+ }
70
+ }
71
+ /**
72
+ * Converts the given dataflow graph to an ASCII representation.
73
+ */
74
+ function dfgToAscii(dfg) {
75
+ const g = new dagre_1.graphlib.Graph();
76
+ const verts = Array.from(dfg.vertices(true));
77
+ g.setGraph({
78
+ nodesep: 1,
79
+ ranksep: 4,
80
+ edgesep: 0,
81
+ rankdir: verts.length < 15 ? 'LR' : 'TB',
82
+ ranker: 'longest-path',
83
+ });
84
+ for (const [id, v] of verts) {
85
+ let label = (0, node_id_1.recoverName)(id, dfg.idMap) ?? v.tag;
86
+ if (label.length < 3) {
87
+ label = label.padStart(2, ' ').padEnd(3, ' ');
88
+ }
89
+ g.setNode(String(id), {
90
+ label,
91
+ width: Math.max(3, label.length * 2),
92
+ height: 3,
93
+ shape: 'rectangle'
94
+ });
95
+ }
96
+ const edgesDone = new Set();
97
+ let longestId = 0;
98
+ for (const [from, edges] of dfg.edges()) {
99
+ longestId = Math.max(longestId, String(from).length);
100
+ for (const [to, { types }] of edges) {
101
+ if (!g.hasNode(String(from)) || !g.hasNode(String(to)) || edgesDone.has(`${to}-${from}`)) {
102
+ continue;
103
+ }
104
+ longestId = Math.max(longestId, String(to).length);
105
+ g.setEdge(String(from), String(to), (0, edge_1.edgeTypesToNames)(types));
106
+ edgesDone.add(`${from}-${to}`);
107
+ }
108
+ }
109
+ (0, dagre_1.layout)(g, {
110
+ minlen: 2
111
+ });
112
+ const canvas = new AsciiCanvas();
113
+ renderEdges(g, canvas);
114
+ renderVertices(dfg, g, canvas);
115
+ const lines = canvas.toString().split('\n').filter(line => line.trim() !== '');
116
+ const edgeLines = [];
117
+ // add all edges
118
+ for (const [from, edges] of dfg.edges()) {
119
+ for (const [to, { types }] of edges) {
120
+ if (!g.hasNode(String(from)) || !g.hasNode(String(to))) {
121
+ continue;
122
+ }
123
+ edgeLines.push(`${from.toString().padStart(longestId, ' ')} -> ${to.toString().padStart(longestId, ' ')}: ${Array.from((0, edge_1.edgeTypesToNames)(types)).join(', ')}`);
124
+ }
125
+ }
126
+ // always merge two edgelines with padding
127
+ if (edgeLines.length > 0) {
128
+ lines.push('Edges:');
129
+ }
130
+ const longestFirstLine = Math.max(...edgeLines.map(l => l.length));
131
+ for (let i = 0; i < edgeLines.length; i += 2) {
132
+ const line1 = edgeLines[i];
133
+ const line2 = edgeLines[i + 1];
134
+ if (line2) {
135
+ lines.push(line1.padEnd(Math.min(50, longestFirstLine), ' ') + line2);
136
+ }
137
+ else {
138
+ lines.push(line1);
139
+ }
140
+ }
141
+ return lines.join('\n');
142
+ }
143
+ const type2Edge = {
144
+ [vertex_1.VertexType.FunctionCall]: 'c',
145
+ [vertex_1.VertexType.Use]: 'u',
146
+ [vertex_1.VertexType.FunctionDefinition]: 'f',
147
+ [vertex_1.VertexType.VariableDefinition]: 'v',
148
+ [vertex_1.VertexType.Value]: '0'
149
+ };
150
+ function renderVertices(dfg, g, canvas) {
151
+ for (const nodeId of g.nodes()) {
152
+ const node = g.node(nodeId);
153
+ if (!node) {
154
+ continue;
155
+ }
156
+ const label = node.label;
157
+ const x = Math.round(node.x);
158
+ const y = Math.round(node.y);
159
+ const tag = dfg.getVertex((0, node_id_1.normalizeIdToNumberIfPossible)(nodeId))?.tag;
160
+ let e = '+';
161
+ if (tag && tag in type2Edge) {
162
+ e = type2Edge[tag];
163
+ }
164
+ canvas.drawText(x - 1, y - 1, `${e}${'-'.repeat(label.length)}${e}`);
165
+ canvas.drawText(x - 1 + Math.round(label.length / 2 - nodeId.length / 2), y - 1, `<${nodeId}>`);
166
+ canvas.drawText(x - 1, y, `|${label}|`);
167
+ canvas.drawText(x - 1, y + 1, `${e}${'-'.repeat(label.length)}${e}`);
168
+ }
169
+ }
170
+ const edgesChar = {
171
+ vertical: '│',
172
+ horizontal: '─',
173
+ topLeft: '┌',
174
+ topRight: '┐',
175
+ bottomLeft: '└',
176
+ bottomRight: '┘',
177
+ };
178
+ function determineCornerChar(lastDirection, px, py, tx, ty) {
179
+ if (px === tx) {
180
+ return edgesChar.vertical;
181
+ }
182
+ else if (py === ty) {
183
+ return edgesChar.horizontal;
184
+ }
185
+ else if (px < tx) {
186
+ if (py < ty) {
187
+ return lastDirection === 'horizontal' ? edgesChar.topRight : edgesChar.bottomLeft;
188
+ }
189
+ else {
190
+ return lastDirection === 'horizontal' ? edgesChar.bottomRight : edgesChar.topLeft;
191
+ }
192
+ }
193
+ else {
194
+ if (py < ty) {
195
+ return lastDirection === 'horizontal' ? edgesChar.topLeft : edgesChar.bottomRight;
196
+ }
197
+ else {
198
+ return lastDirection === 'horizontal' ? edgesChar.bottomLeft : edgesChar.topRight;
199
+ }
200
+ }
201
+ }
202
+ function renderEdges(g, canvas) {
203
+ const otherEdges = new Set();
204
+ for (const e of g.edges()) {
205
+ const edge = g.edge(e);
206
+ let points = edge.points;
207
+ // we rework edges into sequences of straight lines only, adding intermediate points as needed
208
+ const newPoints = [points[0]];
209
+ for (let i = 1; i < points.length; i++) {
210
+ const prev = points[i - 1];
211
+ const curr = points[i];
212
+ if (prev.x !== curr.x && prev.y !== curr.y) {
213
+ const intermediate = { x: prev.x, y: curr.y };
214
+ newPoints.push(intermediate);
215
+ }
216
+ newPoints.push(curr);
217
+ }
218
+ points = newPoints;
219
+ let lastDirection = null;
220
+ // let single edges overwrite themselves
221
+ const writtenPoints = new Set();
222
+ for (let i = 0; i < points.length - 1; i++) {
223
+ const p = points[i - 1] ?? points[i];
224
+ const a = points[i];
225
+ const b = points[i + 1];
226
+ const px = Math.round(p.x);
227
+ const py = Math.round(p.y);
228
+ const x1 = Math.round(a.x);
229
+ const y1 = Math.round(a.y);
230
+ const x2 = Math.round(b.x);
231
+ const y2 = Math.round(b.y);
232
+ if (x1 === x2) {
233
+ // vertical
234
+ const [start, end] = y1 < y2 ? [y1, y2] : [y2, y1];
235
+ for (let y = start; y <= end; y++) {
236
+ const key = `${x1},${y}`;
237
+ const overwrite = writtenPoints.has(key) && !otherEdges.has(key);
238
+ if (y === (y1 < y2 ? start : end)) {
239
+ const cornerChar = determineCornerChar(lastDirection, px, py, x2, y2);
240
+ canvas.set(x1, y, cornerChar, overwrite);
241
+ }
242
+ else {
243
+ canvas.set(x1, y, edgesChar.vertical, overwrite);
244
+ }
245
+ writtenPoints.add(`${x1},${y}`);
246
+ }
247
+ lastDirection = 'vertical';
248
+ }
249
+ else if (y1 === y2) {
250
+ // horizontal
251
+ const [start, end] = x1 < x2 ? [x1, x2] : [x2, x1];
252
+ for (let x = start; x <= end; x++) {
253
+ const key = `${x},${y1}`;
254
+ const overwrite = writtenPoints.has(key) && !otherEdges.has(key);
255
+ if (x === (x1 < x2 ? start : end)) {
256
+ const cornerChar = determineCornerChar(lastDirection, px, py, x2, y2);
257
+ canvas.set(x, y1, cornerChar, overwrite);
258
+ }
259
+ else {
260
+ canvas.set(x, y1, edgesChar.horizontal, overwrite);
261
+ }
262
+ writtenPoints.add(`${x},${y1}`);
263
+ }
264
+ lastDirection = 'horizontal';
265
+ }
266
+ }
267
+ for (const p of writtenPoints) {
268
+ otherEdges.add(p);
269
+ }
270
+ }
271
+ }
272
+ //# sourceMappingURL=dfg-ascii.js.map
package/util/version.js CHANGED
@@ -6,7 +6,7 @@ exports.printVersionInformation = printVersionInformation;
6
6
  const semver_1 = require("semver");
7
7
  const assert_1 = require("./assert");
8
8
  // this is automatically replaced with the current version by release-it
9
- const version = '2.7.4';
9
+ const version = '2.7.5';
10
10
  /**
11
11
  * Retrieves the current flowR version as a new {@link SemVer} object.
12
12
  */