ts2workflows 0.7.0 → 0.9.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.
@@ -1,10 +1,4 @@
1
1
  import { WorkflowStepAST } from '../ast/steps.js';
2
- /**
3
- * Performs various transformations on the AST.
4
- *
5
- * This flat list of steps and does not recurse into nested steps. This gets
6
- * called on each nesting level separately.
7
- */
8
2
  export declare function transformAST(steps: WorkflowStepAST[]): WorkflowStepAST[];
9
3
  /**
10
4
  * Merge a next step to the previous step.
@@ -1 +1 @@
1
- {"version":3,"file":"transformations.d.ts","sourceRoot":"","sources":["../../src/transpiler/transformations.ts"],"names":[],"mappings":"AAAA,OAAO,EASL,eAAe,EAChB,MAAM,iBAAiB,CAAA;AAqBxB;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,eAAe,EAAE,GAAG,eAAe,EAAE,CAQxE;AAiCD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,eAAe,EAAE,GACvB,eAAe,EAAE,CAqBnB"}
1
+ {"version":3,"file":"transformations.d.ts","sourceRoot":"","sources":["../../src/transpiler/transformations.ts"],"names":[],"mappings":"AACA,OAAO,EAQL,eAAe,EAChB,MAAM,iBAAiB,CAAA;AA6BxB,wBAAgB,YAAY,CAAC,KAAK,EAAE,eAAe,EAAE,GAAG,eAAe,EAAE,CAExE;AAiCD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,eAAe,EAAE,GACvB,eAAe,EAAE,CAqBnB"}
@@ -1,17 +1,15 @@
1
+ import * as R from 'ramda';
1
2
  import { AssignStepAST, CallStepAST, ForStepAST, RaiseStepAST, ReturnStepAST, SwitchStepAST, } from '../ast/steps.js';
2
3
  import { InternalTranspilingError } from '../errors.js';
3
- import { isRecord, mapRecordValues } from '../utils.js';
4
- import { BinaryExpression, FunctionInvocationExpression, MemberExpression, PrimitiveExpression, UnaryExpression, VariableReferenceExpression, isExpression, isLiteral, } from '../ast/expressions.js';
4
+ import { isRecord } from '../utils.js';
5
+ import { BinaryExpression, FunctionInvocationExpression, MemberExpression, PrimitiveExpression, UnaryExpression, VariableReferenceExpression, asExpression, isExpression, isLiteral, } from '../ast/expressions.js';
5
6
  import { blockingFunctions } from './generated/functionMetadata.js';
6
- const Unmodified = Symbol();
7
7
  /**
8
8
  * Performs various transformations on the AST.
9
- *
10
- * This flat list of steps and does not recurse into nested steps. This gets
11
- * called on each nesting level separately.
12
9
  */
10
+ const transformPipe = R.pipe(mapLiteralsAsAssignSteps, mergeAssignSteps, flattenPlainNextConditions, intrinsicFunctionImplementation, blockingCallsAsCallSteps);
13
11
  export function transformAST(steps) {
14
- return blockingCallsAsCallSteps(runtimeFunctionImplementation(flattenPlainNextConditions(mergeAssignSteps(mapLiteralsAsAssignSteps(steps)))));
12
+ return transformPipe(steps.map((x) => x.applyNestedSteps(transformAST)));
15
13
  }
16
14
  /**
17
15
  * Merge consecutive assign steps into one assign step
@@ -113,57 +111,40 @@ function flattenNextToCondition(step) {
113
111
  * return: ${__temp0}
114
112
  */
115
113
  function blockingCallsAsCallSteps(steps) {
116
- const transformer = (ex) => {
117
- const generateTemporaryVariableName = createTempVariableGenerator();
118
- const { transformedExpression, callSteps } = replaceBlockingCalls(ex, generateTemporaryVariableName);
119
- return [callSteps, transformedExpression];
120
- };
121
- return steps.reduce((acc, current) => {
122
- const transformedSteps = transformStepExpressions(current, transformer);
123
- acc.push(...transformedSteps);
124
- return acc;
125
- }, []);
114
+ const transform = transformStepExpressions(replaceBlockingCalls);
115
+ return R.chain(transform, steps);
126
116
  }
127
117
  function createTempVariableGenerator() {
128
118
  let i = 0;
129
- const generator = () => `__temp${i++}`;
130
- return generator;
119
+ return () => `__temp${i++}`;
131
120
  }
132
- function replaceBlockingCalls(expression, generateName) {
121
+ function replaceBlockingCalls(expression) {
133
122
  function replaceBlockingFunctionInvocations(ex) {
134
- if (ex.expressionType === 'functionInvocation') {
135
- const callStepsForArguments = [];
136
- const replacedArguments = ex.arguments.map((ex) => {
137
- const replaced = replaceBlockingCalls(ex, generateName);
138
- callStepsForArguments.push(...replaced.callSteps);
139
- return replaced.transformedExpression;
140
- });
141
- const blockingCallArgumentNames = blockingFunctions.get(ex.functionName);
142
- if (blockingCallArgumentNames) {
143
- if (replacedArguments.length > blockingCallArgumentNames.length) {
144
- throw new InternalTranspilingError('FunctionInvocationTerm has more arguments than metadata allows!');
145
- }
146
- const nameAndValue = replacedArguments.map((val, i) => [blockingCallArgumentNames[i], val]);
147
- const args = Object.fromEntries(nameAndValue);
148
- const tempCallResultVariable = generateName();
149
- callSteps.push(...callStepsForArguments);
150
- callSteps.push(new CallStepAST(ex.functionName, args, tempCallResultVariable));
151
- // replace function invocation with a reference to the temporary variable
152
- return new VariableReferenceExpression(tempCallResultVariable);
153
- }
154
- else {
155
- return Unmodified;
123
+ if (ex.expressionType !== 'functionInvocation') {
124
+ return ex;
125
+ }
126
+ const blockingCallArgumentNames = blockingFunctions.get(ex.functionName);
127
+ if (blockingCallArgumentNames) {
128
+ if (ex.arguments.length > blockingCallArgumentNames.length) {
129
+ throw new InternalTranspilingError('FunctionInvocationTerm has more arguments than metadata allows!');
156
130
  }
131
+ const nameAndValue = R.zip(blockingCallArgumentNames, ex.arguments);
132
+ const callArgs = R.fromPairs(nameAndValue);
133
+ const tempCallResultVariable = generateName();
134
+ callSteps.push(new CallStepAST(ex.functionName, callArgs, tempCallResultVariable));
135
+ // replace function invocation with a reference to the temporary variable
136
+ return new VariableReferenceExpression(tempCallResultVariable);
157
137
  }
158
138
  else {
159
- return Unmodified;
139
+ return ex;
160
140
  }
161
141
  }
142
+ const generateName = createTempVariableGenerator();
162
143
  const callSteps = [];
163
- return {
164
- transformedExpression: transformExpression(expression, replaceBlockingFunctionInvocations),
144
+ return [
165
145
  callSteps,
166
- };
146
+ transformExpression(replaceBlockingFunctionInvocations, expression),
147
+ ];
167
148
  }
168
149
  /**
169
150
  * Transform expressions in a step by applying transform.
@@ -172,20 +153,21 @@ function replaceBlockingCalls(expression, generateName) {
172
153
  * additional steps constructed during the transformation. For example, a
173
154
  * transformation might extract blocking call expressions into call steps.
174
155
  */
175
- function transformStepExpressions(step, transform) {
156
+ const transformStepExpressions = R.curry(function (transform, step) {
176
157
  switch (step.tag) {
177
158
  case 'assign':
178
- return transformExpressionsAssign(step, transform);
159
+ return transformExpressionsAssign(transform, step);
179
160
  case 'call':
180
- return transformExpressionsCall(step, transform);
161
+ return transformExpressionsCall(transform, step);
181
162
  case 'for':
182
- return transformExpressionsFor(step, transform);
163
+ return transformExpressionsFor(transform, step);
183
164
  case 'raise':
184
- return transformExpressionsRaise(step, transform);
165
+ return transformExpressionsRaise(transform, step);
185
166
  case 'return':
186
- return transformExpressionsReturn(step, transform);
167
+ return transformExpressionsReturn(transform, step);
187
168
  case 'switch':
188
- return transformExpressionsSwitch(step, transform);
169
+ return transformExpressionsSwitch(transform, step);
170
+ case 'forrange':
189
171
  case 'next':
190
172
  case 'parallel':
191
173
  case 'steps':
@@ -193,8 +175,8 @@ function transformStepExpressions(step, transform) {
193
175
  case 'jumptarget':
194
176
  return [step];
195
177
  }
196
- }
197
- function transformExpressionsAssign(step, transform) {
178
+ });
179
+ function transformExpressionsAssign(transform, step) {
198
180
  if (step.assignments) {
199
181
  const newSteps = [];
200
182
  const newAssignments = step.assignments.map(([name, ex]) => {
@@ -209,14 +191,14 @@ function transformExpressionsAssign(step, transform) {
209
191
  return [step];
210
192
  }
211
193
  }
212
- function transformExpressionsCall(step, transform) {
194
+ function transformExpressionsCall(transform, step) {
213
195
  if (step.args) {
214
196
  const newSteps = [];
215
- const newArgs = mapRecordValues(step.args, (ex) => {
197
+ const newArgs = R.map((ex) => {
216
198
  const [steps2, ex2] = transform(ex);
217
199
  newSteps.push(...steps2);
218
200
  return ex2;
219
- });
201
+ }, step.args);
220
202
  newSteps.push(new CallStepAST(step.call, newArgs, step.result, step.label));
221
203
  return newSteps;
222
204
  }
@@ -224,17 +206,17 @@ function transformExpressionsCall(step, transform) {
224
206
  return [step];
225
207
  }
226
208
  }
227
- function transformExpressionsFor(step, transform) {
209
+ function transformExpressionsFor(transform, step) {
228
210
  if (step.listExpression) {
229
211
  const [newSteps, newListExpression] = transform(step.listExpression);
230
- newSteps.push(new ForStepAST(step.steps, step.loopVariableName, newListExpression, step.indexVariableName, step.rangeStart, step.rangeEnd, step.label));
212
+ newSteps.push(new ForStepAST(step.steps, step.loopVariableName, newListExpression, step.indexVariableName, step.label));
231
213
  return newSteps;
232
214
  }
233
215
  else {
234
216
  return [step];
235
217
  }
236
218
  }
237
- function transformExpressionsRaise(step, transform) {
219
+ function transformExpressionsRaise(transform, step) {
238
220
  if (step.value) {
239
221
  const [newSteps, newEx] = transform(step.value);
240
222
  newSteps.push(new RaiseStepAST(newEx, step.label));
@@ -244,7 +226,7 @@ function transformExpressionsRaise(step, transform) {
244
226
  return [step];
245
227
  }
246
228
  }
247
- function transformExpressionsReturn(step, transform) {
229
+ function transformExpressionsReturn(transform, step) {
248
230
  if (step.value) {
249
231
  const [newSteps, newEx] = transform(step.value);
250
232
  newSteps.push(new ReturnStepAST(newEx, step.label));
@@ -254,7 +236,7 @@ function transformExpressionsReturn(step, transform) {
254
236
  return [step];
255
237
  }
256
238
  }
257
- function transformExpressionsSwitch(step, transform) {
239
+ function transformExpressionsSwitch(transform, step) {
258
240
  const newSteps = [];
259
241
  const newBranches = step.branches.map((cond) => {
260
242
  const [steps2, ex2] = transform(cond.condition);
@@ -268,87 +250,50 @@ function transformExpressionsSwitch(step, transform) {
268
250
  newSteps.push(new SwitchStepAST(newBranches, step.label));
269
251
  return newSteps;
270
252
  }
271
- function transformExpression(ex, transform) {
272
- const transformed = transform(ex);
273
- if (transformed !== Unmodified) {
274
- // Use the transformed version of this term
275
- return transformed;
276
- }
277
- else {
278
- // Otherwise, recurse into the nested expression
279
- switch (ex.expressionType) {
280
- case 'primitive':
281
- if (isLiteral(ex)) {
282
- return ex;
283
- }
284
- else {
285
- const newPrimitive = transformPrimitive(ex.value, transform);
286
- return newPrimitive === ex.value
287
- ? ex
288
- : new PrimitiveExpression(newPrimitive);
289
- }
290
- case 'binary':
291
- return transformBinaryExpression(ex, transform);
292
- case 'functionInvocation':
293
- return transformFunctionInvocationExpression(ex, transform);
294
- case 'member':
295
- return transformMemberExpression(ex, transform);
296
- case 'unary':
297
- return transformUnaryExpression(ex, transform);
298
- case 'variableReference':
253
+ /**
254
+ * Apply transform to expressions recursively.
255
+ * Transform leaf expresionssins first.
256
+ */
257
+ function transformExpression(transform, ex) {
258
+ return transform(transformNestedExpressions(transform, ex));
259
+ }
260
+ function transformNestedExpressions(transform, ex) {
261
+ const tr = (y) => transformExpression(transform, y);
262
+ switch (ex.expressionType) {
263
+ case 'primitive':
264
+ if (isLiteral(ex)) {
299
265
  return ex;
300
- }
266
+ }
267
+ else {
268
+ const newPrimitive = transformPrimitive(transform, ex.value);
269
+ return newPrimitive === ex.value
270
+ ? ex
271
+ : new PrimitiveExpression(newPrimitive);
272
+ }
273
+ case 'binary':
274
+ return new BinaryExpression(tr(ex.left), ex.binaryOperator, tr(ex.right));
275
+ case 'variableReference':
276
+ return ex;
277
+ case 'functionInvocation':
278
+ return new FunctionInvocationExpression(ex.functionName, ex.arguments.map(tr));
279
+ case 'member':
280
+ return new MemberExpression(tr(ex.object), tr(ex.property), ex.computed);
281
+ case 'unary':
282
+ return new UnaryExpression(ex.operator, tr(ex.value));
301
283
  }
302
284
  }
303
- function transformPrimitive(val, transform) {
285
+ function transformPrimitive(transform, val) {
286
+ const tranformVal = R.ifElse(isExpression, (x) => transformExpression(transform, x), (x) => transformPrimitive(transform, x));
304
287
  if (Array.isArray(val)) {
305
- return val.map((x) => isExpression(x)
306
- ? transformExpression(x, transform)
307
- : transformPrimitive(x, transform));
288
+ return R.map(tranformVal, val);
308
289
  }
309
290
  else if (isRecord(val)) {
310
- return mapRecordValues(val, (x) => isExpression(x)
311
- ? transformExpression(x, transform)
312
- : transformPrimitive(x, transform));
291
+ return R.map(tranformVal, val);
313
292
  }
314
293
  else {
315
294
  return val;
316
295
  }
317
296
  }
318
- function transformBinaryExpression(ex, transform) {
319
- // Transform left first to keep the correct order of execution of sub-expressions
320
- const newLeft = transformExpression(ex.left, transform);
321
- const newRight = transformExpression(ex.right, transform);
322
- if (newLeft === ex.left && newRight === ex.right) {
323
- return ex;
324
- }
325
- else {
326
- return new BinaryExpression(newLeft, ex.binaryOperator, newRight);
327
- }
328
- }
329
- function transformFunctionInvocationExpression(ex, transform) {
330
- const newArguments = ex.arguments.map((x) => transformExpression(x, transform));
331
- if (newArguments.every((x, i) => x === ex.arguments[i])) {
332
- return ex;
333
- }
334
- else {
335
- return new FunctionInvocationExpression(ex.functionName, newArguments);
336
- }
337
- }
338
- function transformMemberExpression(ex, transform) {
339
- const newObject = transformExpression(ex.object, transform);
340
- const newProperty = transformExpression(ex.property, transform);
341
- if (newObject === ex.object && newProperty === ex.property) {
342
- return ex;
343
- }
344
- else {
345
- return new MemberExpression(newObject, newProperty, ex.computed);
346
- }
347
- }
348
- function transformUnaryExpression(ex, transform) {
349
- const newValue = transformExpression(ex.value, transform);
350
- return newValue === ex.value ? ex : new UnaryExpression(ex.operator, newValue);
351
- }
352
297
  /**
353
298
  * Search for map literals in expressions and replace them with assign step + variable.
354
299
  *
@@ -369,7 +314,8 @@ function transformUnaryExpression(ex, transform) {
369
314
  * return: ${__temp0.value}
370
315
  */
371
316
  function mapLiteralsAsAssignSteps(steps) {
372
- return steps.flatMap((step) => transformStepExpressions(step, transformNestedMaps));
317
+ const transformNestedMapsInExpressions = transformStepExpressions(transformNestedMaps);
318
+ return R.chain(transformNestedMapsInExpressions, steps);
373
319
  }
374
320
  function transformNestedMaps(ex) {
375
321
  const generateTemporaryVariableName = createTempVariableGenerator();
@@ -395,11 +341,8 @@ function extractNestedMaps(ex, generateName, nestingLevel) {
395
341
  }
396
342
  function extractNestedMapPrimitive(primitiveEx, generateName, nestingLevel) {
397
343
  const { transformed, tempVariables } = extractNestedMapPrimitiveRecursive(primitiveEx, generateName, nestingLevel);
398
- const ex = isExpression(transformed)
399
- ? transformed
400
- : new PrimitiveExpression(transformed);
401
344
  return {
402
- transformedExpression: ex,
345
+ transformedExpression: asExpression(transformed),
403
346
  tempVariables,
404
347
  };
405
348
  }
@@ -511,15 +454,12 @@ function extractNestedMapUnary(ex, generateName, nestingLevel) {
511
454
  /**
512
455
  * Replace `Array.isArray(x)` with `get_type(x) == "list"`
513
456
  */
514
- function runtimeFunctionImplementation(steps) {
515
- return steps.reduce((acc, current) => {
516
- const transformedSteps = transformStepExpressions(current, (ex) => [
517
- [],
518
- transformExpression(ex, replaceIsArray),
519
- ]);
520
- acc.push(...transformedSteps);
521
- return acc;
522
- }, []);
457
+ function intrinsicFunctionImplementation(steps) {
458
+ const tr = transformStepExpressions((ex) => [
459
+ [],
460
+ transformExpression(replaceIsArray, ex),
461
+ ]);
462
+ return R.chain(tr, steps);
523
463
  }
524
464
  function replaceIsArray(ex) {
525
465
  if (ex.expressionType === 'functionInvocation' &&
@@ -527,6 +467,6 @@ function replaceIsArray(ex) {
527
467
  return new BinaryExpression(new FunctionInvocationExpression('get_type', ex.arguments), '==', new PrimitiveExpression('list'));
528
468
  }
529
469
  else {
530
- return Unmodified;
470
+ return ex;
531
471
  }
532
472
  }
package/dist/utils.d.ts CHANGED
@@ -1,13 +1,9 @@
1
1
  export declare function isRecord(object: unknown): object is Record<keyof never, unknown>;
2
- /**
3
- * Apply f to values of obj and return the result
4
- */
5
- export declare function mapRecordValues<T, U>(obj: Record<string, T>, f: (t: T) => U): Record<string, U>;
6
2
  /**
7
3
  * Like arr.flatMap() but the callback takes two consecutive array elements.
8
4
  *
9
5
  * During the last execution of the callback, the second argument (which would
10
6
  * be element after the last array element) will be undefined.
11
7
  */
12
- export declare function flatMapPair<T, U>(arr: T[], callback: (val: T, next: T | undefined) => U[]): U[];
8
+ export declare function chainPairs<T, U>(callback: (val: T, next: T | undefined) => U[], arr: readonly T[]): U[];
13
9
  //# sourceMappingURL=utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,wBAAgB,QAAQ,CACtB,MAAM,EAAE,OAAO,GACd,MAAM,IAAI,MAAM,CAAC,MAAM,KAAK,EAAE,OAAO,CAAC,CAExC;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,CAAC,EAClC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,EACtB,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,GACb,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAEnB;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,CAAC,EAC9B,GAAG,EAAE,CAAC,EAAE,EACR,QAAQ,EAAE,CAAC,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,GAAG,SAAS,KAAK,CAAC,EAAE,GAC7C,CAAC,EAAE,CAaL"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAEA,wBAAgB,QAAQ,CACtB,MAAM,EAAE,OAAO,GACd,MAAM,IAAI,MAAM,CAAC,MAAM,KAAK,EAAE,OAAO,CAAC,CAExC;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,CAAC,EAC7B,QAAQ,EAAE,CAAC,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,GAAG,SAAS,KAAK,CAAC,EAAE,EAC9C,GAAG,EAAE,SAAS,CAAC,EAAE,GAChB,CAAC,EAAE,CAKL"}
package/dist/utils.js CHANGED
@@ -1,26 +1,13 @@
1
+ import * as R from 'ramda';
1
2
  export function isRecord(object) {
2
3
  return object instanceof Object && object.constructor === Object;
3
4
  }
4
- /**
5
- * Apply f to values of obj and return the result
6
- */
7
- export function mapRecordValues(obj, f) {
8
- return Object.fromEntries(Object.entries(obj).map(([k, v]) => [k, f(v)]));
9
- }
10
5
  /**
11
6
  * Like arr.flatMap() but the callback takes two consecutive array elements.
12
7
  *
13
8
  * During the last execution of the callback, the second argument (which would
14
9
  * be element after the last array element) will be undefined.
15
10
  */
16
- export function flatMapPair(arr, callback) {
17
- if (arr.length <= 0) {
18
- return [];
19
- }
20
- const mapped = [];
21
- for (let i = 0; i < arr.length - 1; i++) {
22
- mapped.push(...callback(arr[i], arr[i + 1]));
23
- }
24
- mapped.push(...callback(arr[arr.length - 1], undefined));
25
- return mapped;
11
+ export function chainPairs(callback, arr) {
12
+ return R.chain(R.apply(callback), R.zip(arr, R.append(undefined, R.tail(arr))));
26
13
  }