@eagleoutice/flowr 2.8.3 → 2.8.4

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 (37) hide show
  1. package/cli/repl/core.js +22 -0
  2. package/config.d.ts +14 -0
  3. package/config.js +10 -2
  4. package/control-flow/extract-cfg.js +35 -14
  5. package/core/print/slice-diff-ansi.js +1 -1
  6. package/dataflow/extractor.js +2 -2
  7. package/dataflow/graph/graph.js +0 -4
  8. package/dataflow/instrument/instrument-dataflow-count.d.ts +9 -0
  9. package/dataflow/instrument/instrument-dataflow-count.js +22 -0
  10. package/dataflow/internal/process/functions/call/built-in/built-in-assignment.js +14 -7
  11. package/dataflow/internal/process/functions/call/built-in/built-in-expression-list.js +4 -2
  12. package/documentation/wiki-interface.js +3 -1
  13. package/documentation/wiki-query.js +1 -1
  14. package/linter/rules/unused-definition.js +6 -5
  15. package/package.json +1 -1
  16. package/project/context/flowr-analyzer-files-context.d.ts +1 -0
  17. package/project/context/flowr-file.d.ts +2 -0
  18. package/project/context/flowr-file.js +2 -0
  19. package/project/plugins/file-plugins/flowr-analyzer-license-file-plugin.d.ts +24 -0
  20. package/project/plugins/file-plugins/flowr-analyzer-license-file-plugin.js +37 -0
  21. package/project/plugins/flowr-analyzer-plugin-defaults.js +2 -0
  22. package/project/plugins/plugin-registry.d.ts +2 -1
  23. package/project/plugins/plugin-registry.js +3 -1
  24. package/project/plugins/project-discovery/flowr-analyzer-project-discovery-plugin.js +0 -1
  25. package/queries/catalog/config-query/config-query-format.d.ts +2 -2
  26. package/queries/catalog/config-query/config-query-format.js +40 -2
  27. package/queries/catalog/dependencies-query/function-info/read-functions.js +8 -0
  28. package/queries/catalog/dependencies-query/function-info/write-functions.js +9 -0
  29. package/queries/query.d.ts +1 -1
  30. package/r-bridge/lang-4.x/tree-sitter/tree-sitter-normalize.js +481 -447
  31. package/r-bridge/roxygen2/documentation-provider.js +3 -1
  32. package/r-bridge/roxygen2/roxygen-parse.d.ts +1 -1
  33. package/r-bridge/roxygen2/roxygen-parse.js +9 -5
  34. package/util/r-version.js +17 -1
  35. package/util/range.d.ts +1 -1
  36. package/util/range.js +1 -1
  37. package/util/version.js +1 -1
@@ -6,6 +6,7 @@ exports.makeTreeSitterStrict = makeTreeSitterStrict;
6
6
  const normalizer_data_1 = require("../ast/parser/main/normalizer-data");
7
7
  const tree_sitter_types_1 = require("./tree-sitter-types");
8
8
  const type_1 = require("../ast/model/type");
9
+ const range_1 = require("../../../util/range");
9
10
  const retriever_1 = require("../../retriever");
10
11
  const convert_values_1 = require("../convert-values");
11
12
  const normalize_meta_1 = require("../ast/parser/main/normalize-meta");
@@ -13,6 +14,7 @@ const arrays_1 = require("../../../util/collections/arrays");
13
14
  const r_function_call_1 = require("../ast/model/nodes/r-function-call");
14
15
  const strings_1 = require("../../../util/text/strings");
15
16
  const log_1 = require("../../../util/log");
17
+ const parser_1 = require("../ast/parser/json/parser");
16
18
  /**
17
19
  * @param tree - The tree to normalize
18
20
  * @param lax - Whether to use lax parsing (i.e., ignore errors) or strict parsing (i.e., fail on errors)
@@ -63,427 +65,453 @@ function makeTreeSitterStrict() {
63
65
  nonErrorChildren = nonErrorChildrenStrict;
64
66
  }
65
67
  function convertTreeNode(node) {
66
- // generally, the grammar source file dictates what children a node has in what order:
67
- // https://github.com/r-lib/tree-sitter-r/blob/main/grammar.js
68
- const range = makeSourceRange(node);
69
- const defaultInfo = {
70
- info: {
71
- fullRange: range,
72
- additionalTokens: [],
73
- fullLexeme: node.text,
74
- treeSitterId: node.id
75
- }
76
- };
77
- switch (node.type) {
78
- case tree_sitter_types_1.TreeSitterType.Program: {
79
- const [comments, children] = splitComments(nonErrorChildren(node));
80
- const body = children.map(n => [n, convertTreeNode(n)]);
81
- const remainingComments = linkCommentsToNextNodes(body, comments);
82
- return {
83
- type: type_1.RType.ExpressionList,
84
- children: body.map(n => n[1]),
85
- grouping: undefined,
86
- lexeme: undefined,
87
- info: {
88
- additionalTokens: remainingComments.map(c => c[1]),
89
- treeSitterId: node.id
90
- }
91
- };
92
- }
93
- case tree_sitter_types_1.TreeSitterType.BracedExpression:
94
- case tree_sitter_types_1.TreeSitterType.ParenthesizedExpression: {
95
- const [comments, children] = splitComments(nonErrorChildren(node));
96
- const opening = children[0];
97
- const body = children.slice(1, -1).map(n => [n, convertTreeNode(n)]);
98
- const remainingComments = linkCommentsToNextNodes(body, comments);
99
- const closing = children[children.length - 1];
100
- return {
101
- type: type_1.RType.ExpressionList,
102
- location: undefined,
103
- lexeme: undefined,
104
- children: body.map(n => n[1]),
105
- grouping: [
106
- {
107
- type: type_1.RType.Symbol,
108
- location: makeSourceRange(opening),
109
- content: (0, retriever_1.removeRQuotes)(opening.text),
110
- lexeme: opening.text,
111
- namespace: undefined,
112
- ...defaultInfo
113
- }, {
114
- type: type_1.RType.Symbol,
115
- location: makeSourceRange(closing),
116
- content: (0, retriever_1.removeRQuotes)(closing.text),
117
- lexeme: closing.text,
118
- namespace: undefined,
119
- ...defaultInfo
120
- }
121
- ],
122
- info: {
123
- additionalTokens: remainingComments.map(c => c[1]),
124
- treeSitterId: node.id
125
- }
126
- };
127
- }
128
- case tree_sitter_types_1.TreeSitterType.BinaryOperator: {
129
- const children = nonErrorChildren(node);
130
- const lhs = convertTreeNode(children[0]);
131
- const rhs = convertTreeNode(children[children.length - 1]);
132
- const [commentsBoth, [op]] = splitComments(children.slice(1, -1));
133
- const comments = commentsBoth.map(c => c[1]);
134
- const opSource = makeSourceRange(op);
135
- const lhsAsArg = {
136
- type: type_1.RType.Argument,
137
- location: lhs.location,
138
- value: lhs,
139
- name: undefined,
140
- lexeme: lhs.lexeme,
141
- info: {
142
- treeSitterId: lhs.info.treeSitterId
143
- }
144
- };
145
- if (op.type == 'special') {
68
+ if (!node) {
69
+ return {
70
+ type: type_1.RType.ExpressionList,
71
+ location: undefined,
72
+ lexeme: undefined,
73
+ children: [],
74
+ grouping: undefined,
75
+ info: {
76
+ fullRange: (0, range_1.invalidRange)(),
77
+ additionalTokens: [],
78
+ treeSitterId: -1,
79
+ }
80
+ };
81
+ }
82
+ try {
83
+ // generally, the grammar source file dictates what children a node has in what order:
84
+ // https://github.com/r-lib/tree-sitter-r/blob/main/grammar.js
85
+ const range = makeSourceRange(node);
86
+ const defaultInfo = {
87
+ info: {
88
+ fullRange: range,
89
+ additionalTokens: [],
90
+ fullLexeme: node.text,
91
+ treeSitterId: node.id
92
+ }
93
+ };
94
+ switch (node.type) {
95
+ case tree_sitter_types_1.TreeSitterType.Program: {
96
+ const [comments, children] = splitComments(nonErrorChildren(node));
97
+ const body = children.map(n => [n, convertTreeNode(n)]);
98
+ const remainingComments = linkCommentsToNextNodes(body, comments);
146
99
  return {
147
- type: type_1.RType.FunctionCall,
148
- location: opSource,
149
- lexeme: node.text,
150
- functionName: {
151
- type: type_1.RType.Symbol,
152
- location: opSource,
153
- lexeme: op.text,
154
- content: op.text,
155
- namespace: undefined,
156
- info: {
157
- treeSitterId: op.id
158
- }
159
- },
160
- arguments: [lhsAsArg, {
161
- type: type_1.RType.Argument,
162
- location: rhs.location,
163
- value: rhs,
164
- name: undefined,
165
- lexeme: rhs.lexeme,
166
- info: {
167
- treeSitterId: rhs.info.treeSitterId
168
- }
169
- }],
170
- named: true,
171
- infixSpecial: true,
100
+ type: type_1.RType.ExpressionList,
101
+ children: body.map(n => n[1]),
102
+ grouping: undefined,
103
+ lexeme: undefined,
172
104
  info: {
173
- additionalTokens: comments,
105
+ additionalTokens: remainingComments.map(c => c[1]),
174
106
  treeSitterId: node.id
175
107
  }
176
108
  };
177
109
  }
178
- else if (op.text === '|>') {
110
+ case tree_sitter_types_1.TreeSitterType.BracedExpression:
111
+ case tree_sitter_types_1.TreeSitterType.ParenthesizedExpression: {
112
+ const [comments, children] = splitComments(nonErrorChildren(node));
113
+ const opening = children[0];
114
+ const body = children.slice(1, -1).map(n => [n, convertTreeNode(n)]);
115
+ const remainingComments = linkCommentsToNextNodes(body, comments);
116
+ const closing = children[children.length - 1];
179
117
  return {
180
- type: type_1.RType.Pipe,
181
- location: opSource,
182
- lhs: lhsAsArg,
183
- rhs,
184
- lexeme: op.text,
185
- ...defaultInfo,
118
+ type: type_1.RType.ExpressionList,
119
+ location: undefined,
120
+ lexeme: undefined,
121
+ children: body.map(n => n[1]),
122
+ grouping: [
123
+ {
124
+ type: type_1.RType.Symbol,
125
+ location: makeSourceRange(opening),
126
+ content: (0, retriever_1.removeRQuotes)(opening.text),
127
+ lexeme: opening.text,
128
+ namespace: undefined,
129
+ ...defaultInfo
130
+ }, {
131
+ type: type_1.RType.Symbol,
132
+ location: makeSourceRange(closing),
133
+ content: (0, retriever_1.removeRQuotes)(closing.text),
134
+ lexeme: closing.text,
135
+ namespace: undefined,
136
+ ...defaultInfo
137
+ }
138
+ ],
186
139
  info: {
187
- fullRange: range,
188
- additionalTokens: comments,
189
- fullLexeme: node.text,
140
+ additionalTokens: remainingComments.map(c => c[1]),
190
141
  treeSitterId: node.id
191
142
  }
192
143
  };
193
144
  }
194
- else {
145
+ case tree_sitter_types_1.TreeSitterType.BinaryOperator: {
146
+ const children = nonErrorChildren(node);
147
+ const lhs = convertTreeNode(children[0]);
148
+ const rhs = convertTreeNode(children[children.length - 1]);
149
+ const [commentsBoth, [op]] = splitComments(children.slice(1, -1));
150
+ const comments = commentsBoth.map(c => c[1]);
151
+ const opSource = makeSourceRange(op);
152
+ const lhsAsArg = {
153
+ type: type_1.RType.Argument,
154
+ location: lhs.location,
155
+ value: lhs,
156
+ name: undefined,
157
+ lexeme: lhs.lexeme,
158
+ info: {
159
+ treeSitterId: lhs.info.treeSitterId
160
+ }
161
+ };
162
+ if (op.type == 'special') {
163
+ return {
164
+ type: type_1.RType.FunctionCall,
165
+ location: opSource,
166
+ lexeme: node.text,
167
+ functionName: {
168
+ type: type_1.RType.Symbol,
169
+ location: opSource,
170
+ lexeme: op.text,
171
+ content: op.text,
172
+ namespace: undefined,
173
+ info: {
174
+ treeSitterId: op.id
175
+ }
176
+ },
177
+ arguments: [lhsAsArg, {
178
+ type: type_1.RType.Argument,
179
+ location: rhs.location,
180
+ value: rhs,
181
+ name: undefined,
182
+ lexeme: rhs.lexeme,
183
+ info: {
184
+ treeSitterId: rhs.info.treeSitterId
185
+ }
186
+ }],
187
+ named: true,
188
+ infixSpecial: true,
189
+ info: {
190
+ additionalTokens: comments,
191
+ treeSitterId: node.id
192
+ }
193
+ };
194
+ }
195
+ else if (op.text === '|>') {
196
+ return {
197
+ type: type_1.RType.Pipe,
198
+ location: opSource,
199
+ lhs: lhsAsArg,
200
+ rhs,
201
+ lexeme: op.text,
202
+ ...defaultInfo,
203
+ info: {
204
+ fullRange: range,
205
+ additionalTokens: comments,
206
+ fullLexeme: node.text,
207
+ treeSitterId: node.id
208
+ }
209
+ };
210
+ }
211
+ else {
212
+ return {
213
+ type: type_1.RType.BinaryOp,
214
+ location: opSource,
215
+ lhs, rhs,
216
+ operator: op.text,
217
+ lexeme: op.text,
218
+ info: {
219
+ fullRange: range,
220
+ additionalTokens: comments,
221
+ fullLexeme: node.text,
222
+ treeSitterId: node.id
223
+ }
224
+ };
225
+ }
226
+ }
227
+ case tree_sitter_types_1.TreeSitterType.UnaryOperator: {
228
+ const [op, operand] = nonErrorChildren(node);
195
229
  return {
196
- type: type_1.RType.BinaryOp,
197
- location: opSource,
198
- lhs, rhs,
230
+ type: type_1.RType.UnaryOp,
231
+ operand: convertTreeNode(operand),
232
+ location: makeSourceRange(op),
199
233
  operator: op.text,
200
234
  lexeme: op.text,
201
- info: {
202
- fullRange: range,
203
- additionalTokens: comments,
204
- fullLexeme: node.text,
205
- treeSitterId: node.id
206
- }
235
+ ...defaultInfo
207
236
  };
208
237
  }
209
- }
210
- case tree_sitter_types_1.TreeSitterType.UnaryOperator: {
211
- const [op, operand] = nonErrorChildren(node);
212
- return {
213
- type: type_1.RType.UnaryOp,
214
- operand: convertTreeNode(operand),
215
- location: makeSourceRange(op),
216
- operator: op.text,
217
- lexeme: op.text,
218
- ...defaultInfo
219
- };
220
- }
221
- case tree_sitter_types_1.TreeSitterType.NamespaceOperator: {
222
- const [lhs, /* :: or ::: */ , rhs] = nonErrorChildren(node);
223
- return {
224
- type: type_1.RType.Symbol,
225
- location: makeSourceRange(rhs),
226
- content: rhs.text,
227
- lexeme: rhs.text,
228
- namespace: lhs.text,
229
- ...defaultInfo
230
- };
231
- }
232
- case '(':
233
- case ')':
234
- case tree_sitter_types_1.TreeSitterType.Na:
235
- case tree_sitter_types_1.TreeSitterType.Null:
236
- case tree_sitter_types_1.TreeSitterType.Dots:
237
- case tree_sitter_types_1.TreeSitterType.DotDotI:
238
- case tree_sitter_types_1.TreeSitterType.Identifier:
239
- case tree_sitter_types_1.TreeSitterType.Return:
240
- return {
241
- type: type_1.RType.Symbol,
242
- location: range,
243
- content: (0, strings_1.startAndEndsWith)(node.text, '`') ? node.text.slice(1, -1) : (0, retriever_1.removeRQuotes)(node.text),
244
- lexeme: node.text,
245
- namespace: undefined,
246
- ...defaultInfo
247
- };
248
- case tree_sitter_types_1.TreeSitterType.IfStatement: {
249
- const [ifNode, /* ( */ , condition, /* ) */ , then, /* else */ , ...otherwise] = nonErrorChildren(node);
250
- const filteredOtherwise = otherwise.filter(n => n.type !== tree_sitter_types_1.TreeSitterType.ElseStatement);
251
- return {
252
- type: type_1.RType.IfThenElse,
253
- condition: convertTreeNode(condition),
254
- then: (0, normalize_meta_1.ensureExpressionList)(convertTreeNode(then)),
255
- otherwise: filteredOtherwise.length > 0 ? (0, normalize_meta_1.ensureExpressionList)(convertTreeNode(filteredOtherwise[0])) : undefined,
256
- location: makeSourceRange(ifNode),
257
- lexeme: ifNode.text,
258
- ...defaultInfo
259
- };
260
- }
261
- case tree_sitter_types_1.TreeSitterType.ForStatement: {
262
- const children = nonErrorChildren(node);
263
- const forNode = children[0]; // we follow with a (
264
- const variable = getNodesUntil(children, 'in', 2); // we follow with the "in"
265
- const sequence = getNodesUntil(children, ')', 2 + variable.length + 1); // we follow with a (
266
- const body = children[2 + variable.length + 1 + sequence.length + 1];
267
- const [variableComments, [variableNode]] = splitComments(variable);
268
- const [sequenceComments, [sequenceNode]] = splitComments(sequence);
269
- return {
270
- type: type_1.RType.ForLoop,
271
- variable: {
238
+ case tree_sitter_types_1.TreeSitterType.NamespaceOperator: {
239
+ const [lhs, /* :: or ::: */ , rhs] = nonErrorChildren(node);
240
+ return {
272
241
  type: type_1.RType.Symbol,
273
- location: makeSourceRange(variableNode),
274
- content: (0, retriever_1.removeRQuotes)(variableNode.text),
275
- lexeme: variableNode.text,
242
+ location: makeSourceRange(rhs),
243
+ content: rhs.text,
244
+ lexeme: rhs.text,
245
+ namespace: lhs.text,
246
+ ...defaultInfo
247
+ };
248
+ }
249
+ case '(':
250
+ case ')':
251
+ case tree_sitter_types_1.TreeSitterType.Na:
252
+ case tree_sitter_types_1.TreeSitterType.Null:
253
+ case tree_sitter_types_1.TreeSitterType.Dots:
254
+ case tree_sitter_types_1.TreeSitterType.DotDotI:
255
+ case tree_sitter_types_1.TreeSitterType.Identifier:
256
+ case tree_sitter_types_1.TreeSitterType.Return:
257
+ return {
258
+ type: type_1.RType.Symbol,
259
+ location: range,
260
+ content: (0, strings_1.startAndEndsWith)(node.text, '`') ? node.text.slice(1, -1) : (0, retriever_1.removeRQuotes)(node.text),
261
+ lexeme: node.text,
276
262
  namespace: undefined,
277
- info: {
278
- fullRange: undefined,
279
- additionalTokens: [],
280
- fullLexeme: undefined,
281
- treeSitterId: variableNode.id
282
- }
283
- },
284
- vector: convertTreeNode(sequenceNode),
285
- body: (0, normalize_meta_1.ensureExpressionList)(convertTreeNode(body)),
286
- location: makeSourceRange(forNode),
287
- lexeme: forNode.text,
288
- info: {
289
- fullRange: range,
290
- additionalTokens: variableComments.concat(sequenceComments).map(c => c[1]),
291
- fullLexeme: node.text,
292
- treeSitterId: node.id
293
- }
294
- };
295
- }
296
- case tree_sitter_types_1.TreeSitterType.WhileStatement: {
297
- const [whileNode, /* ( */ , condition, /* ) */ , body] = nonErrorChildren(node);
298
- return {
299
- type: type_1.RType.WhileLoop,
300
- condition: convertTreeNode(condition),
301
- body: (0, normalize_meta_1.ensureExpressionList)(convertTreeNode(body)),
302
- location: makeSourceRange(whileNode),
303
- lexeme: whileNode.text,
304
- ...defaultInfo
305
- };
306
- }
307
- case tree_sitter_types_1.TreeSitterType.RepeatStatement: {
308
- const [repeatNode, body] = nonErrorChildren(node);
309
- return {
310
- type: type_1.RType.RepeatLoop,
311
- body: (0, normalize_meta_1.ensureExpressionList)(convertTreeNode(body)),
312
- location: makeSourceRange(repeatNode),
313
- lexeme: repeatNode.text,
314
- ...defaultInfo
315
- };
316
- }
317
- case tree_sitter_types_1.TreeSitterType.Call: {
318
- const [func, argsParentheses] = nonErrorChildren(node);
319
- // tree-sitter wraps next and break in a function call, but we don't, so unwrap
320
- if (func.type === tree_sitter_types_1.TreeSitterType.Next || func.type == tree_sitter_types_1.TreeSitterType.Break) {
263
+ ...defaultInfo
264
+ };
265
+ case tree_sitter_types_1.TreeSitterType.IfStatement: {
266
+ const [ifNode, /* ( */ , condition, /* ) */ , then, /* else */ , ...otherwise] = nonErrorChildren(node);
267
+ const filteredOtherwise = otherwise.filter(n => n.type !== tree_sitter_types_1.TreeSitterType.ElseStatement);
321
268
  return {
322
- ...convertTreeNode(func),
269
+ type: type_1.RType.IfThenElse,
270
+ condition: convertTreeNode(condition),
271
+ then: (0, normalize_meta_1.ensureExpressionList)(convertTreeNode(then)),
272
+ otherwise: filteredOtherwise.length > 0 ? (0, normalize_meta_1.ensureExpressionList)(convertTreeNode(filteredOtherwise[0])) : undefined,
273
+ location: makeSourceRange(ifNode),
274
+ lexeme: ifNode.text,
323
275
  ...defaultInfo
324
276
  };
325
277
  }
326
- const rawArgs = nonErrorChildren(argsParentheses);
327
- const [comments, noCommentrawArgs] = splitComments(rawArgs);
328
- const args = (0, arrays_1.splitArrayOn)(noCommentrawArgs.slice(1, -1), x => x.type === 'comma');
329
- const funcRange = makeSourceRange(func);
330
- const mappedArgs = args.map(n => n.length == 0 ? r_function_call_1.EmptyArgument : convertTreeNode(n[0]));
331
- const call = {
332
- arguments: mappedArgs,
333
- location: funcRange,
334
- lexeme: func.text,
335
- ...defaultInfo,
336
- info: {
337
- ...defaultInfo.info,
338
- additionalTokens: comments.map(c => c[1]),
339
- }
340
- };
341
- if (func.type === tree_sitter_types_1.TreeSitterType.Identifier || func.type === tree_sitter_types_1.TreeSitterType.String || func.type === tree_sitter_types_1.TreeSitterType.NamespaceOperator || func.type === tree_sitter_types_1.TreeSitterType.Return) {
342
- let funcNode = convertTreeNode(func);
343
- if (funcNode.type === type_1.RType.String) {
344
- funcNode = {
345
- ...funcNode,
278
+ case tree_sitter_types_1.TreeSitterType.ForStatement: {
279
+ const children = nonErrorChildren(node);
280
+ const forNode = children[0]; // we follow with a (
281
+ const variable = getNodesUntil(children, 'in', 2); // we follow with the "in"
282
+ const sequence = getNodesUntil(children, ')', 2 + variable.length + 1); // we follow with a (
283
+ const body = children[2 + variable.length + 1 + sequence.length + 1];
284
+ const [variableComments, [variableNode]] = splitComments(variable);
285
+ const [sequenceComments, [sequenceNode]] = splitComments(sequence);
286
+ return {
287
+ type: type_1.RType.ForLoop,
288
+ variable: {
346
289
  type: type_1.RType.Symbol,
290
+ location: makeSourceRange(variableNode),
291
+ content: (0, retriever_1.removeRQuotes)(variableNode.text),
292
+ lexeme: variableNode.text,
347
293
  namespace: undefined,
348
- content: (0, retriever_1.removeRQuotes)(func.text)
349
- };
350
- }
351
- return {
352
- ...call,
353
- type: type_1.RType.FunctionCall,
354
- functionName: {
355
- ...funcNode,
356
294
  info: {
357
- fullRange: range,
295
+ fullRange: undefined,
358
296
  additionalTokens: [],
359
- fullLexeme: node.text,
360
- treeSitterId: node.id
297
+ fullLexeme: undefined,
298
+ treeSitterId: variableNode.id
361
299
  }
362
300
  },
363
- named: true
301
+ vector: convertTreeNode(sequenceNode),
302
+ body: (0, normalize_meta_1.ensureExpressionList)(convertTreeNode(body)),
303
+ location: makeSourceRange(forNode),
304
+ lexeme: forNode.text,
305
+ info: {
306
+ fullRange: range,
307
+ additionalTokens: variableComments.concat(sequenceComments).map(c => c[1]),
308
+ fullLexeme: node.text,
309
+ treeSitterId: node.id
310
+ }
364
311
  };
365
312
  }
366
- else {
313
+ case tree_sitter_types_1.TreeSitterType.WhileStatement: {
314
+ const [whileNode, /* ( */ , condition, /* ) */ , body] = nonErrorChildren(node);
367
315
  return {
368
- ...call,
369
- type: type_1.RType.FunctionCall,
370
- calledFunction: convertTreeNode(func),
371
- named: undefined
316
+ type: type_1.RType.WhileLoop,
317
+ condition: convertTreeNode(condition),
318
+ body: (0, normalize_meta_1.ensureExpressionList)(convertTreeNode(body)),
319
+ location: makeSourceRange(whileNode),
320
+ lexeme: whileNode.text,
321
+ ...defaultInfo
372
322
  };
373
323
  }
374
- }
375
- case tree_sitter_types_1.TreeSitterType.FunctionDefinition: {
376
- const [name, paramsParens, body] = nonErrorChildren(node);
377
- const [comments, noCommentRawParams] = splitComments(paramsParens.children.slice(1, -1));
378
- const params = (0, arrays_1.splitArrayOn)(noCommentRawParams, x => x.type === 'comma');
379
- return {
380
- type: type_1.RType.FunctionDefinition,
381
- parameters: params.map(n => convertTreeNode(n[0])),
382
- body: (0, normalize_meta_1.ensureExpressionList)(convertTreeNode(body)),
383
- location: makeSourceRange(name),
384
- lexeme: name.text,
385
- info: {
386
- ...defaultInfo.info,
387
- additionalTokens: comments.map(c => c[1]),
324
+ case tree_sitter_types_1.TreeSitterType.RepeatStatement: {
325
+ const [repeatNode, body] = nonErrorChildren(node);
326
+ return {
327
+ type: type_1.RType.RepeatLoop,
328
+ body: (0, normalize_meta_1.ensureExpressionList)(convertTreeNode(body)),
329
+ location: makeSourceRange(repeatNode),
330
+ lexeme: repeatNode.text,
331
+ ...defaultInfo
332
+ };
333
+ }
334
+ case tree_sitter_types_1.TreeSitterType.Call: {
335
+ const [func, argsParentheses] = nonErrorChildren(node);
336
+ // tree-sitter wraps next and break in a function call, but we don't, so unwrap
337
+ if (func.type === tree_sitter_types_1.TreeSitterType.Next || func.type == tree_sitter_types_1.TreeSitterType.Break) {
338
+ return {
339
+ ...convertTreeNode(func),
340
+ ...defaultInfo
341
+ };
388
342
  }
389
- };
390
- }
391
- case tree_sitter_types_1.TreeSitterType.String:
392
- return {
393
- type: type_1.RType.String,
394
- location: range,
395
- content: (0, convert_values_1.string2ts)(node.text),
396
- lexeme: node.text,
397
- ...defaultInfo
398
- };
399
- case tree_sitter_types_1.TreeSitterType.Float:
400
- case tree_sitter_types_1.TreeSitterType.Integer:
401
- case tree_sitter_types_1.TreeSitterType.Complex:
402
- case tree_sitter_types_1.TreeSitterType.Inf:
403
- case tree_sitter_types_1.TreeSitterType.Nan:
404
- return {
405
- type: type_1.RType.Number,
406
- location: range,
407
- content: (0, convert_values_1.number2ts)(node.text),
408
- lexeme: node.text,
409
- ...defaultInfo
410
- };
411
- case tree_sitter_types_1.TreeSitterType.True:
412
- case tree_sitter_types_1.TreeSitterType.False:
413
- return {
414
- type: type_1.RType.Logical,
415
- location: range,
416
- content: (0, convert_values_1.boolean2ts)(node.text),
417
- lexeme: node.text,
418
- ...defaultInfo
419
- };
420
- case tree_sitter_types_1.TreeSitterType.Break:
421
- case tree_sitter_types_1.TreeSitterType.Next:
422
- return {
423
- type: node.type == tree_sitter_types_1.TreeSitterType.Break ? type_1.RType.Break : type_1.RType.Next,
424
- location: range,
425
- lexeme: node.text,
426
- ...defaultInfo
427
- };
428
- case tree_sitter_types_1.TreeSitterType.Subset:
429
- case tree_sitter_types_1.TreeSitterType.Subset2: {
430
- // subset has children like a and [x]
431
- const [func, content] = nonErrorChildren(node);
432
- // bracket is now [ or [[ and argsClosing is x] or x]]
433
- const [bracket, ...argsClosing] = nonErrorChildren(content);
434
- const args = (0, arrays_1.splitArrayOn)(argsClosing.slice(0, -1), x => x.type === 'comma');
435
- return {
436
- type: type_1.RType.Access,
437
- operator: bracket.text,
438
- accessed: convertTreeNode(func),
439
- access: args.map(n => n.length == 0 ? r_function_call_1.EmptyArgument : convertTreeNode(n[0])),
440
- location: makeSourceRange(bracket),
441
- lexeme: bracket.text,
442
- ...defaultInfo
443
- };
444
- }
445
- case tree_sitter_types_1.TreeSitterType.ExtractOperator: {
446
- const [lhs, operator, rhs] = nonErrorChildren(node);
447
- const rhsRange = makeSourceRange(rhs);
448
- return {
449
- type: type_1.RType.Access,
450
- operator: operator.text,
451
- accessed: convertTreeNode(lhs),
452
- access: [{
453
- type: type_1.RType.Argument,
454
- name: undefined,
455
- value: {
456
- ...convertTreeNode(rhs),
457
- ...defaultInfo
343
+ const rawArgs = nonErrorChildren(argsParentheses);
344
+ const [comments, noCommentrawArgs] = splitComments(rawArgs);
345
+ const args = (0, arrays_1.splitArrayOn)(noCommentrawArgs.slice(1, -1), x => x.type === 'comma');
346
+ const funcRange = makeSourceRange(func);
347
+ const mappedArgs = args.map(n => n.length == 0 ? r_function_call_1.EmptyArgument : convertTreeNode(n[0]));
348
+ const call = {
349
+ arguments: mappedArgs,
350
+ location: funcRange,
351
+ lexeme: func.text,
352
+ ...defaultInfo,
353
+ info: {
354
+ ...defaultInfo.info,
355
+ additionalTokens: comments.map(c => c[1]),
356
+ }
357
+ };
358
+ if (func.type === tree_sitter_types_1.TreeSitterType.Identifier || func.type === tree_sitter_types_1.TreeSitterType.String || func.type === tree_sitter_types_1.TreeSitterType.NamespaceOperator || func.type === tree_sitter_types_1.TreeSitterType.Return) {
359
+ let funcNode = convertTreeNode(func);
360
+ if (funcNode.type === type_1.RType.String) {
361
+ funcNode = {
362
+ ...funcNode,
363
+ type: type_1.RType.Symbol,
364
+ namespace: undefined,
365
+ content: (0, retriever_1.removeRQuotes)(func.text)
366
+ };
367
+ }
368
+ return {
369
+ ...call,
370
+ type: type_1.RType.FunctionCall,
371
+ functionName: {
372
+ ...funcNode,
373
+ info: {
374
+ fullRange: range,
375
+ additionalTokens: [],
376
+ fullLexeme: node.text,
377
+ treeSitterId: node.id
378
+ }
458
379
  },
459
- location: rhsRange,
460
- lexeme: rhs.text,
380
+ named: true
381
+ };
382
+ }
383
+ else {
384
+ return {
385
+ ...call,
386
+ type: type_1.RType.FunctionCall,
387
+ calledFunction: convertTreeNode(func),
388
+ named: undefined
389
+ };
390
+ }
391
+ }
392
+ case tree_sitter_types_1.TreeSitterType.FunctionDefinition: {
393
+ const [name, paramsParens, body] = nonErrorChildren(node);
394
+ const [comments, noCommentRawParams] = splitComments(paramsParens.children.slice(1, -1));
395
+ const params = (0, arrays_1.splitArrayOn)(noCommentRawParams, x => x.type === 'comma');
396
+ return {
397
+ type: type_1.RType.FunctionDefinition,
398
+ parameters: params.map(n => convertTreeNode(n[0])),
399
+ body: (0, normalize_meta_1.ensureExpressionList)(convertTreeNode(body)),
400
+ location: makeSourceRange(name),
401
+ lexeme: name.text,
402
+ info: {
403
+ ...defaultInfo.info,
404
+ additionalTokens: comments.map(c => c[1]),
405
+ }
406
+ };
407
+ }
408
+ case tree_sitter_types_1.TreeSitterType.String:
409
+ return {
410
+ type: type_1.RType.String,
411
+ location: range,
412
+ content: (0, convert_values_1.string2ts)(node.text),
413
+ lexeme: node.text,
414
+ ...defaultInfo
415
+ };
416
+ case tree_sitter_types_1.TreeSitterType.Float:
417
+ case tree_sitter_types_1.TreeSitterType.Integer:
418
+ case tree_sitter_types_1.TreeSitterType.Complex:
419
+ case tree_sitter_types_1.TreeSitterType.Inf:
420
+ case tree_sitter_types_1.TreeSitterType.Nan:
421
+ return {
422
+ type: type_1.RType.Number,
423
+ location: range,
424
+ content: (0, convert_values_1.number2ts)(node.text),
425
+ lexeme: node.text,
426
+ ...defaultInfo
427
+ };
428
+ case tree_sitter_types_1.TreeSitterType.True:
429
+ case tree_sitter_types_1.TreeSitterType.False:
430
+ return {
431
+ type: type_1.RType.Logical,
432
+ location: range,
433
+ content: (0, convert_values_1.boolean2ts)(node.text),
434
+ lexeme: node.text,
435
+ ...defaultInfo
436
+ };
437
+ case tree_sitter_types_1.TreeSitterType.Break:
438
+ case tree_sitter_types_1.TreeSitterType.Next:
439
+ return {
440
+ type: node.type == tree_sitter_types_1.TreeSitterType.Break ? type_1.RType.Break : type_1.RType.Next,
441
+ location: range,
442
+ lexeme: node.text,
443
+ ...defaultInfo
444
+ };
445
+ case tree_sitter_types_1.TreeSitterType.Subset:
446
+ case tree_sitter_types_1.TreeSitterType.Subset2: {
447
+ // subset has children like a and [x]
448
+ const [func, content] = nonErrorChildren(node);
449
+ // bracket is now [ or [[ and argsClosing is x] or x]]
450
+ const [bracket, ...argsClosing] = nonErrorChildren(content);
451
+ const args = (0, arrays_1.splitArrayOn)(argsClosing.slice(0, -1), x => x.type === 'comma');
452
+ return {
453
+ type: type_1.RType.Access,
454
+ operator: bracket.text,
455
+ accessed: convertTreeNode(func),
456
+ access: args.map(n => n.length == 0 ? r_function_call_1.EmptyArgument : convertTreeNode(n[0])),
457
+ location: makeSourceRange(bracket),
458
+ lexeme: bracket.text,
459
+ ...defaultInfo
460
+ };
461
+ }
462
+ case tree_sitter_types_1.TreeSitterType.ExtractOperator: {
463
+ const [lhs, operator, rhs] = nonErrorChildren(node);
464
+ const rhsRange = makeSourceRange(rhs);
465
+ return {
466
+ type: type_1.RType.Access,
467
+ operator: operator.text,
468
+ accessed: convertTreeNode(lhs),
469
+ access: [{
470
+ type: type_1.RType.Argument,
471
+ name: undefined,
472
+ value: {
473
+ ...convertTreeNode(rhs),
474
+ ...defaultInfo
475
+ },
476
+ location: rhsRange,
477
+ lexeme: rhs?.text,
478
+ info: {
479
+ fullRange: rhsRange,
480
+ additionalTokens: [],
481
+ fullLexeme: rhs?.text,
482
+ treeSitterId: rhs?.id
483
+ }
484
+ }],
485
+ location: makeSourceRange(operator),
486
+ lexeme: operator.text,
487
+ ...defaultInfo
488
+ };
489
+ }
490
+ case tree_sitter_types_1.TreeSitterType.Parameter: {
491
+ const children = nonErrorChildren(node);
492
+ const name = children[0];
493
+ const nameRange = makeSourceRange(name);
494
+ let defaultValue = undefined;
495
+ if (children.length == 3) {
496
+ defaultValue = convertTreeNode(children[2]);
497
+ }
498
+ return {
499
+ type: type_1.RType.Parameter,
500
+ name: {
501
+ type: type_1.RType.Symbol,
502
+ location: nameRange,
503
+ content: name.text,
504
+ lexeme: name.text,
461
505
  info: {
462
- fullRange: rhsRange,
506
+ fullRange: range,
463
507
  additionalTokens: [],
464
- fullLexeme: rhs.text,
465
- treeSitterId: rhs.id
508
+ fullLexeme: name.text,
509
+ treeSitterId: name.id
466
510
  }
467
- }],
468
- location: makeSourceRange(operator),
469
- lexeme: operator.text,
470
- ...defaultInfo
471
- };
472
- }
473
- case tree_sitter_types_1.TreeSitterType.Parameter: {
474
- const children = nonErrorChildren(node);
475
- const name = children[0];
476
- const nameRange = makeSourceRange(name);
477
- let defaultValue = undefined;
478
- if (children.length == 3) {
479
- defaultValue = convertTreeNode(children[2]);
480
- }
481
- return {
482
- type: type_1.RType.Parameter,
483
- name: {
484
- type: type_1.RType.Symbol,
511
+ },
512
+ special: name.text === '...',
513
+ defaultValue,
485
514
  location: nameRange,
486
- content: name.text,
487
515
  lexeme: name.text,
488
516
  info: {
489
517
  fullRange: range,
@@ -491,84 +519,90 @@ function convertTreeNode(node) {
491
519
  fullLexeme: name.text,
492
520
  treeSitterId: name.id
493
521
  }
494
- },
495
- special: name.text === '...',
496
- defaultValue,
497
- location: nameRange,
498
- lexeme: name.text,
499
- info: {
500
- fullRange: range,
501
- additionalTokens: [],
502
- fullLexeme: name.text,
503
- treeSitterId: name.id
522
+ };
523
+ }
524
+ case tree_sitter_types_1.TreeSitterType.Argument: {
525
+ const children = nonErrorChildren(node);
526
+ if (children.length == 1) {
527
+ const [arg] = children;
528
+ return {
529
+ type: type_1.RType.Argument,
530
+ name: undefined,
531
+ value: convertTreeNode(arg),
532
+ location: range,
533
+ lexeme: node.text,
534
+ ...defaultInfo
535
+ };
504
536
  }
505
- };
506
- }
507
- case tree_sitter_types_1.TreeSitterType.Argument: {
508
- const children = nonErrorChildren(node);
509
- if (children.length == 1) {
510
- const [arg] = children;
537
+ else {
538
+ const [nameNode, /* = */ , valueNode] = children;
539
+ let name = convertTreeNode(nameNode);
540
+ // unescape argument names
541
+ if (name.type === type_1.RType.String) {
542
+ name = {
543
+ ...name,
544
+ type: type_1.RType.Symbol,
545
+ content: name.content.str,
546
+ namespace: undefined
547
+ };
548
+ }
549
+ else if ((0, strings_1.startAndEndsWith)(name.content, '`')) {
550
+ name.content = name.content.slice(1, -1);
551
+ }
552
+ const nameRange = makeSourceRange(nameNode);
553
+ return {
554
+ type: type_1.RType.Argument,
555
+ name,
556
+ value: valueNode ? convertTreeNode(valueNode) : undefined,
557
+ location: nameRange,
558
+ lexeme: nameNode.text,
559
+ info: {
560
+ fullRange: nameRange,
561
+ additionalTokens: [],
562
+ fullLexeme: nameNode.text,
563
+ treeSitterId: nameNode.id
564
+ }
565
+ };
566
+ }
567
+ }
568
+ case tree_sitter_types_1.TreeSitterType.Comment:
511
569
  return {
512
- type: type_1.RType.Argument,
513
- name: undefined,
514
- value: convertTreeNode(arg),
570
+ type: type_1.RType.Comment,
515
571
  location: range,
516
572
  lexeme: node.text,
517
573
  ...defaultInfo
518
574
  };
519
- }
520
- else {
521
- const [nameNode, /* = */ , valueNode] = children;
522
- let name = convertTreeNode(nameNode);
523
- // unescape argument names
524
- if (name.type === type_1.RType.String) {
525
- name = {
526
- ...name,
527
- type: type_1.RType.Symbol,
528
- content: name.content.str,
529
- namespace: undefined
530
- };
531
- }
532
- else if ((0, strings_1.startAndEndsWith)(name.content, '`')) {
533
- name.content = name.content.slice(1, -1);
534
- }
535
- const nameRange = makeSourceRange(nameNode);
575
+ case tree_sitter_types_1.TreeSitterType.Error:
536
576
  return {
537
- type: type_1.RType.Argument,
538
- name,
539
- value: valueNode ? convertTreeNode(valueNode) : undefined,
540
- location: nameRange,
541
- lexeme: nameNode.text,
542
- info: {
543
- fullRange: nameRange,
544
- additionalTokens: [],
545
- fullLexeme: nameNode.text,
546
- treeSitterId: nameNode.id
547
- }
577
+ type: type_1.RType.ExpressionList,
578
+ location: undefined,
579
+ lexeme: undefined,
580
+ children: [],
581
+ grouping: undefined,
582
+ ...defaultInfo
548
583
  };
549
- }
550
584
  }
551
- case tree_sitter_types_1.TreeSitterType.Comment:
552
- return {
553
- type: type_1.RType.Comment,
554
- location: range,
555
- lexeme: node.text,
556
- ...defaultInfo
557
- };
558
- case tree_sitter_types_1.TreeSitterType.Error:
559
- return {
560
- type: type_1.RType.ExpressionList,
561
- location: undefined,
562
- lexeme: undefined,
563
- children: [],
564
- grouping: undefined,
565
- ...defaultInfo
566
- };
567
- default:
568
- throw new normalizer_data_1.ParseError(`unexpected node type ${node.type} at ${JSON.stringify(range)}`);
569
585
  }
586
+ catch {
587
+ parser_1.parseLog.error(`[Tree-Sitter] Failed to convert node of type ${node.type} at ${JSON.stringify(makeSourceRange(node))}`);
588
+ }
589
+ return {
590
+ type: type_1.RType.ExpressionList,
591
+ location: undefined,
592
+ lexeme: undefined,
593
+ children: [],
594
+ grouping: undefined,
595
+ info: {
596
+ fullRange: (0, range_1.invalidRange)(),
597
+ additionalTokens: [],
598
+ treeSitterId: -1,
599
+ }
600
+ };
570
601
  }
571
602
  function makeSourceRange(node) {
603
+ if (!node) {
604
+ return (0, range_1.invalidRange)();
605
+ }
572
606
  if (node.startPosition && node.endPosition) {
573
607
  return [
574
608
  // tree-sitter is 0-based but we want 1-based