@sap/cds-compiler 5.8.2 → 5.9.2

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 (87) hide show
  1. package/CHANGELOG.md +38 -0
  2. package/bin/cds_remove_invalid_whitespace.js +5 -3
  3. package/bin/cds_update_identifiers.js +9 -6
  4. package/bin/cdsc.js +79 -59
  5. package/bin/cdsse.js +14 -10
  6. package/bin/cdsv2m.js +3 -1
  7. package/lib/api/options.js +28 -6
  8. package/lib/base/message-registry.js +15 -4
  9. package/lib/checks/validator.js +3 -0
  10. package/lib/compiler/base.js +1 -1
  11. package/lib/compiler/checks.js +70 -50
  12. package/lib/compiler/extend.js +1 -1
  13. package/lib/compiler/generate.js +8 -2
  14. package/lib/compiler/index.js +1 -1
  15. package/lib/compiler/lsp-api.js +1 -1
  16. package/lib/compiler/propagator.js +2 -2
  17. package/lib/compiler/resolve.js +78 -31
  18. package/lib/compiler/shared.js +3 -3
  19. package/lib/compiler/tweak-assocs.js +1 -1
  20. package/lib/compiler/utils.js +10 -0
  21. package/lib/compiler/xpr-rewrite.js +1 -1
  22. package/lib/edm/annotations/edmJson.js +42 -39
  23. package/lib/edm/annotations/genericTranslation.js +55 -55
  24. package/lib/edm/annotations/preprocessAnnotations.js +5 -5
  25. package/lib/edm/csn2edm.js +16 -16
  26. package/lib/edm/edm.js +62 -62
  27. package/lib/edm/edmAnnoPreprocessor.js +2 -2
  28. package/lib/edm/edmInboundChecks.js +1 -1
  29. package/lib/edm/edmPreprocessor.js +32 -32
  30. package/lib/edm/edmUtils.js +8 -8
  31. package/lib/gen/CdlGrammar.checksum +1 -1
  32. package/lib/gen/CdlParser.js +77 -81
  33. package/lib/gen/Dictionary.json +3062 -3072
  34. package/lib/gen/language.checksum +1 -1
  35. package/lib/gen/language.interp +1 -1
  36. package/lib/gen/languageParser.js +1238 -1236
  37. package/lib/json/from-csn.js +1 -1
  38. package/lib/json/to-csn.js +30 -3
  39. package/lib/language/genericAntlrParser.js +16 -0
  40. package/lib/main.d.ts +79 -1
  41. package/lib/model/csnRefs.js +12 -5
  42. package/lib/model/xprAsTree.js +71 -0
  43. package/lib/modelCompare/utils/filter.js +1 -1
  44. package/lib/optionProcessor.js +46 -32
  45. package/lib/parsers/CdlGrammar.g4 +33 -28
  46. package/lib/parsers/Lexer.js +1 -1
  47. package/lib/parsers/XprTree.js +25 -16
  48. package/lib/render/toCdl.js +902 -414
  49. package/lib/render/toHdbcds.js +1 -1
  50. package/lib/render/toSql.js +8 -0
  51. package/lib/render/utils/common.js +2 -2
  52. package/lib/render/utils/operators.js +160 -0
  53. package/lib/render/utils/pretty.js +337 -0
  54. package/lib/sql-identifier.js +7 -9
  55. package/lib/transform/addTenantFields.js +39 -41
  56. package/lib/transform/db/applyTransformations.js +4 -4
  57. package/lib/transform/db/assertUnique.js +6 -5
  58. package/lib/transform/db/associations.js +3 -3
  59. package/lib/transform/db/assocsToQueries/transformExists.js +13 -13
  60. package/lib/transform/db/assocsToQueries/utils.js +8 -0
  61. package/lib/transform/db/backlinks.js +19 -14
  62. package/lib/transform/db/constraints.js +6 -6
  63. package/lib/transform/db/expansion.js +1 -1
  64. package/lib/transform/db/flattening.js +2 -2
  65. package/lib/transform/db/groupByOrderBy.js +1 -1
  66. package/lib/transform/db/processSqlServices.js +3 -3
  67. package/lib/transform/db/rewriteCalculatedElements.js +2 -2
  68. package/lib/transform/db/temporal.js +7 -9
  69. package/lib/transform/db/views.js +6 -6
  70. package/lib/transform/draft/odata.js +2 -0
  71. package/lib/transform/effective/annotations.js +1 -1
  72. package/lib/transform/effective/associations.js +1 -1
  73. package/lib/transform/effective/main.js +1 -0
  74. package/lib/transform/effective/service.js +2 -2
  75. package/lib/transform/forRelationalDB.js +11 -5
  76. package/lib/transform/localized.js +2 -0
  77. package/lib/transform/odata/adaptAnnotationRefs.js +10 -9
  78. package/lib/transform/parseExpr.js +2 -2
  79. package/lib/transform/transformUtils.js +9 -7
  80. package/lib/transform/translateAssocsToJoins.js +0 -2
  81. package/lib/transform/universalCsn/coreComputed.js +2 -2
  82. package/lib/utils/moduleResolve.js +7 -5
  83. package/package.json +1 -1
  84. package/share/messages/def-upcoming-virtual-change.md +55 -0
  85. package/share/messages/file-unexpected-case-mismatch.md +61 -0
  86. package/share/messages/message-explanations.json +2 -0
  87. package/lib/transform/braceExpression.js +0 -77
@@ -477,10 +477,10 @@ function fns( model ) {
477
477
  * Traverse arguments `args` if they match a specific pattern:
478
478
  *
479
479
  * - a (sub) expression is a comparison, i.e. uses one of the binary operators
480
- * `=`, `<>`, `!=`, `in` or `not in`,
480
+ * `=`, `<>`, '==', `!=`, `in` or `not in`,
481
481
  * - one side of the comparison is a reference or a `cast` function call when
482
482
  * typed with an enum type,
483
- * - the other side is a enum reference, an enum reference in parentheses, or a
483
+ * - the other side is an enum reference, an enum reference in parentheses, or a
484
484
  * list of enum references.
485
485
  *
486
486
  * Return an array of the arguments which are to be traversed normally, or
@@ -489,7 +489,7 @@ function fns( model ) {
489
489
  function traverseSpecialArgs( args, exprCtx, user, type, callback ) {
490
490
  if (args.length <= 3) {
491
491
  if (args.length === 3 && args[1].literal === 'token' &&
492
- [ '=', '<>', '!=', 'in' ].includes( args[1].val ))
492
+ [ '=', '<>', '==', '!=', 'in' ].includes( args[1].val ))
493
493
  return traverseComparison( args[0], args[2], exprCtx, user, callback );
494
494
  }
495
495
  else if (args[0].val === 'case' && args[0].literal === 'token') {
@@ -860,7 +860,7 @@ function tweakAssocs( model ) {
860
860
  }
861
861
 
862
862
  /**
863
- * @param {XSN.Path} ref
863
+ * @param {object} ref
864
864
  * @param {number} index
865
865
  * @param {XSN.Artifact} user
866
866
  * @param {boolean} isTargetSide
@@ -603,6 +603,15 @@ function userQuery( user ) {
603
603
  return null;
604
604
  }
605
605
 
606
+ function userParam( user ) {
607
+ while (user._main) {
608
+ if (user.kind === 'param')
609
+ return user;
610
+ user = user._parent;
611
+ }
612
+ return null;
613
+ }
614
+
606
615
  function pathStartsWithSelf( ref ) {
607
616
  const head = ref && !ref.scope && ref.path?.[0];
608
617
  if (head?._navigation?.kind === '$self')
@@ -720,6 +729,7 @@ module.exports = {
720
729
  isDirectComposition,
721
730
  targetCantBeAspect,
722
731
  userQuery,
732
+ userParam,
723
733
  pathStartsWithSelf,
724
734
  columnRefStartsWithSelf,
725
735
  isAssocToPrimaryKeys,
@@ -276,7 +276,7 @@ function xprRewriteFns( model ) {
276
276
  * @param {XSN.Expression} expr
277
277
  * @param {AnnoRewriteConfig} config
278
278
  * @param {string} refCtx
279
- * @returns {null} Returns true if the expression couldn't be rewritten.
279
+ * @returns {null|true} Returns true if the expression couldn't be rewritten.
280
280
  */
281
281
  function rewriteAnnoExpr( expr, config, refCtx ) {
282
282
  const root = expr.path && (expr.path[0]?._navigation || expr.path[0]?._artifact);
@@ -194,23 +194,23 @@ function xpr2edmJson( carrier, anno, location, options, messageFunctions ) {
194
194
  args = args.filter(a => a);
195
195
  if (argDef.min != null && (!args || argDef.min > args.length)) {
196
196
  error('odata-anno-xpr-args', location, {
197
- anno, op: `${propName}(…)`, count: argDef.min, '#': 'atleast',
197
+ anno, op: `${ propName }(…)`, count: argDef.min, '#': 'atleast',
198
198
  });
199
199
  }
200
200
  if (argDef.max != null && (!args || argDef.max < args.length)) {
201
201
  error('odata-anno-xpr-args', location, {
202
- anno, op: `${propName}(…)`, count: argDef.max, '#': 'atmost',
202
+ anno, op: `${ propName }(…)`, count: argDef.max, '#': 'atmost',
203
203
  });
204
204
  }
205
205
  if (argDef.exact != null && (!args || argDef.exact !== args.length)) {
206
206
  if (argDef.exact === 0) {
207
207
  error('odata-anno-xpr-args', location, {
208
- anno, op: `${propName}(…)`,
208
+ anno, op: `${ propName }(…)`,
209
209
  });
210
210
  }
211
211
  else {
212
212
  error('odata-anno-xpr-args', location, {
213
- anno, op: `${propName}(…)`, count: argDef.exact, '#': 'exactly',
213
+ anno, op: `${ propName }(…)`, count: argDef.exact, '#': 'exactly',
214
214
  });
215
215
  }
216
216
  }
@@ -235,6 +235,7 @@ function xpr2edmJson( carrier, anno, location, options, messageFunctions ) {
235
235
  //----------------------------------
236
236
  // RELATIONAL
237
237
  transform['='] = op('$Eq');
238
+ transform['=='] = op('$Eq');
238
239
  transform.$Eq = noOp;
239
240
  transform['<>'] = op('$Ne');
240
241
  transform['!='] = op('$Ne');
@@ -337,7 +338,7 @@ function xpr2edmJson( carrier, anno, location, options, messageFunctions ) {
337
338
  parent.args = newArgs;
338
339
  if (foundProps.length !== 1) {
339
340
  error('odata-anno-xpr-args', location, {
340
- anno, op: `${xpr}(…)`, prop: `${argName}(…)`, '#': 'wrongcount',
341
+ anno, op: `${ xpr }(…)`, prop: `${ argName }(…)`, '#': 'wrongcount',
341
342
  });
342
343
  }
343
344
  else {
@@ -348,7 +349,7 @@ function xpr2edmJson( carrier, anno, location, options, messageFunctions ) {
348
349
  parent[argName] = /* func.args[0].ref?.join('.') || */ func.args[0].val;
349
350
  if (evalVal && !parent[argName]) {
350
351
  error('odata-anno-xpr-args', location, {
351
- anno, op: `${argName}(…)`, meta: argDef.meta || 'literal', '#': 'wrongval_meta',
352
+ anno, op: `${ argName }(…)`, meta: argDef.meta || 'literal', '#': 'wrongval_meta',
352
353
  });
353
354
  }
354
355
  }
@@ -374,7 +375,7 @@ function xpr2edmJson( carrier, anno, location, options, messageFunctions ) {
374
375
  evalArgs({ exact: 1 }, type.args, type.func);
375
376
  if (type.args?.length === 1) {
376
377
  const typeName = type.args[0].func;
377
- if (EdmPrimitiveTypeMap[`Edm.${type.args[0].func}`])
378
+ if (EdmPrimitiveTypeMap[`Edm.${ type.args[0].func }`])
378
379
  newArgs.push({ func: typeName, args: type.args[0].args || [] });
379
380
  else
380
381
  newArgs.push(type);
@@ -389,13 +390,13 @@ function xpr2edmJson( carrier, anno, location, options, messageFunctions ) {
389
390
  [ foundTypeProps, newArgs ]
390
391
  = parent.args
391
392
  ? parent.args.reduce((acc, arg) => {
392
- (EdmPrimitiveTypeMap[`Edm.${arg.func}`] ? acc[0] : acc[1]).push(arg);
393
+ (EdmPrimitiveTypeMap[`Edm.${ arg.func }`] ? acc[0] : acc[1]).push(arg);
393
394
  return acc;
394
395
  }, [ [], [] ] )
395
396
  : [ [], [] ];
396
397
  if (foundTypeProps.length) {
397
398
  foundTypeProps.forEach((type) => {
398
- const edmType = `Edm.${type.func}`;
399
+ const edmType = `Edm.${ type.func }`;
399
400
  const td = EdmPrimitiveTypeMap[edmType];
400
401
  const typeFuncDef = {
401
402
  func: typePropName,
@@ -408,7 +409,7 @@ function xpr2edmJson( carrier, anno, location, options, messageFunctions ) {
408
409
  const facetDef = td[facetName];
409
410
  if (facetDef && i < type.args.length) {
410
411
  const facetFuncDef = {
411
- func: `${facetName}`,
412
+ func: `${ facetName }`,
412
413
  args: [ type.args[i++] ],
413
414
  };
414
415
  typeFuncDef.args.push(facetFuncDef);
@@ -431,7 +432,7 @@ function xpr2edmJson( carrier, anno, location, options, messageFunctions ) {
431
432
  parent.args = newArgs;
432
433
  if (foundTypeProps.length !== 1) {
433
434
  typePropName = isDollarFunc ? '$Type' : 'Type';
434
- error('odata-anno-xpr-type', location, { anno, op: `${xpr}(…)` });
435
+ error('odata-anno-xpr-type', location, { anno, op: `${ xpr }(…)` });
435
436
  rc = false;
436
437
  }
437
438
  else {
@@ -455,17 +456,17 @@ function xpr2edmJson( carrier, anno, location, options, messageFunctions ) {
455
456
  }, [ [], [] ] );
456
457
 
457
458
  let typeOpStr = collTypes.length
458
- ? `${typePropName}(${isDollarFunc ? '$Collection' : 'Collection'}(…))`
459
- : `${typePropName}(…)`;
459
+ ? `${ typePropName }(${ isDollarFunc ? '$Collection' : 'Collection' }(…))`
460
+ : `${ typePropName }(…)`;
460
461
 
461
462
  if (collTypes.length) {
462
463
  if (collTypes.length > 1 || scalarTypes.length) {
463
- error('odata-anno-xpr-type', location, { anno, op: `${xpr}(…)` });
464
+ error('odata-anno-xpr-type', location, { anno, op: `${ xpr }(…)` });
464
465
  }
465
466
  else {
466
- typeOpStr = `${typePropName}(${collTypes[0].func}(…))`;
467
+ typeOpStr = `${ typePropName }(${ collTypes[0].func }(…))`;
467
468
  if (collTypes[0].args.length !== 1) {
468
- error('odata-anno-xpr-type', location, { anno, op: `${xpr}(…)` });
469
+ error('odata-anno-xpr-type', location, { anno, op: `${ xpr }(…)` });
469
470
  }
470
471
  else {
471
472
  typeArg = collTypes[0].args[0];
@@ -474,7 +475,7 @@ function xpr2edmJson( carrier, anno, location, options, messageFunctions ) {
474
475
  }
475
476
  }
476
477
  else if (scalarTypes.length !== 1) {
477
- error('odata-anno-xpr-type', location, { anno, op: `${xpr}(…)` });
478
+ error('odata-anno-xpr-type', location, { anno, op: `${ xpr }(…)` });
478
479
  rc = false;
479
480
  }
480
481
  else {
@@ -484,7 +485,7 @@ function xpr2edmJson( carrier, anno, location, options, messageFunctions ) {
484
485
  // do final type checks and assignment
485
486
  const typeDef = typeArg?.ref?.join('.') || typeArg?.val;
486
487
  if (typeof typeDef !== 'string')
487
- error('odata-anno-xpr-type', location, { anno, op: `${xpr}(…)` });
488
+ error('odata-anno-xpr-type', location, { anno, op: `${ xpr }(…)` });
488
489
  else
489
490
  parent.$Type = typeDef;
490
491
 
@@ -511,8 +512,8 @@ function xpr2edmJson( carrier, anno, location, options, messageFunctions ) {
511
512
 
512
513
  if (td[facetName]) {
513
514
  // ignore facets that are not type relevant
514
- const facetFuncName = isDollarFunc ? `$${facetName}` : facetName;
515
- const facetArgs = typeFacets.filter(arg => arg.func === facetName || arg.func === `$${facetName}`);
515
+ const facetFuncName = isDollarFunc ? `$${ facetName }` : facetName;
516
+ const facetArgs = typeFacets.filter(arg => arg.func === facetName || arg.func === `$${ facetName }`);
516
517
 
517
518
  if (facetArgs.length === 0 && !optional && (options.isV2() === facetDef.v2 || options.isV4() === facetDef.v4)) {
518
519
  message('odata-spec-violation-type', location,
@@ -526,14 +527,14 @@ function xpr2edmJson( carrier, anno, location, options, messageFunctions ) {
526
527
  }
527
528
  else if (facetArgs.length > 1) {
528
529
  error('odata-anno-xpr-args', location, {
529
- anno, op: typeOpStr, prop: `${facetFuncName}(…)`, '#': 'wrongcount',
530
+ anno, op: typeOpStr, prop: `${ facetFuncName }(…)`, '#': 'wrongcount',
530
531
  });
531
532
  }
532
533
  else if (facetArgs.length === 1) {
533
534
  const facetArg = facetArgs[0];
534
535
  if (facetArg.args.length !== 1) {
535
536
  error('odata-anno-xpr-args', location, {
536
- anno, op: `${facetFuncName}(…)`, count: 1, '#': 'exactly',
537
+ anno, op: `${ facetFuncName }(…)`, count: 1, '#': 'exactly',
537
538
  });
538
539
  }
539
540
  else {
@@ -542,7 +543,7 @@ function xpr2edmJson( carrier, anno, location, options, messageFunctions ) {
542
543
  if (isNan && options.isV4() && facetName === 'Scale' && facetVal !== 'variable') {
543
544
  error('odata-anno-xpr-args', location, {
544
545
  anno,
545
- op: `${facetFuncName}(…)`,
546
+ op: `${ facetFuncName }(…)`,
546
547
  meta: 'number',
547
548
  rawvalues: [ 'variable' ],
548
549
  '#': 'wrongval_meta_list',
@@ -550,11 +551,11 @@ function xpr2edmJson( carrier, anno, location, options, messageFunctions ) {
550
551
  }
551
552
  else if (isNan && facetName !== 'Scale') {
552
553
  error('odata-anno-xpr-args', location, {
553
- anno, op: `${facetFuncName}(…)`, meta: 'number', '#': 'wrongval_meta',
554
+ anno, op: `${ facetFuncName }(…)`, meta: 'number', '#': 'wrongval_meta',
554
555
  });
555
556
  }
556
557
  else {
557
- parent[`$${facetName}`] = facetVal;
558
+ parent[`$${ facetName }`] = facetVal;
558
559
  }
559
560
  }
560
561
  }
@@ -587,7 +588,7 @@ function xpr2edmJson( carrier, anno, location, options, messageFunctions ) {
587
588
  // reqDef entry etc...
588
589
  if (typeDef) { // eslint-disable-line no-lonely-if
589
590
  error('odata-anno-xpr-type', location, {
590
- anno, op: `${xpr}(…)`, type: `${typeDef}`, '#': 'edm',
591
+ anno, op: `${ xpr }(…)`, type: `${ typeDef }`, '#': 'edm',
591
592
  });
592
593
  }
593
594
  /*
@@ -627,7 +628,7 @@ function xpr2edmJson( carrier, anno, location, options, messageFunctions ) {
627
628
  };
628
629
 
629
630
  const dollar = () => {
630
- parent[`$${xpr}`] = parent[xpr];
631
+ parent[`$${ xpr }`] = parent[xpr];
631
632
  delete parent[xpr];
632
633
  };
633
634
 
@@ -637,7 +638,7 @@ function xpr2edmJson( carrier, anno, location, options, messageFunctions ) {
637
638
  let funcName = parent[propName];
638
639
  if (funcName) {
639
640
  if (!funcName.startsWith('odata.'))
640
- funcName = `odata.${funcName}`;
641
+ funcName = `odata.${ funcName }`;
641
642
 
642
643
  const argDef = canonicFunctionDefinitions[funcName];
643
644
  if (argDef) {
@@ -654,7 +655,7 @@ function xpr2edmJson( carrier, anno, location, options, messageFunctions ) {
654
655
  funcName = parent[propName];
655
656
  if (funcName.split('.').length !== 2) {
656
657
  error('odata-anno-xpr', location, {
657
- anno, op: `${propName}(…)`, code: funcName, meta: 'namespace', othermeta: 'function', '#': 'canonfuncalias',
658
+ anno, op: `${ propName }(…)`, code: funcName, meta: 'namespace', othermeta: 'function', '#': 'canonfuncalias',
658
659
  });
659
660
  }
660
661
  }
@@ -701,6 +702,8 @@ function xpr2edmJson( carrier, anno, location, options, messageFunctions ) {
701
702
  },
702
703
  LabeledElement: () => {
703
704
  rewriteArgs({ Name: { exact: 1, meta: 'qualified name' } });
705
+ parent.$Name = parent.Name; // Make it an attribute or rendering fails.
706
+ delete parent.Name;
704
707
  oneArg();
705
708
  dollar();
706
709
  },
@@ -708,7 +711,7 @@ function xpr2edmJson( carrier, anno, location, options, messageFunctions ) {
708
711
  oneArg();
709
712
  if (parent[xpr].length === 1 && typeof parent[xpr][0].val !== 'string') {
710
713
  error('odata-anno-xpr-args', location, {
711
- anno, op: `${xpr}(…)`, meta: 'literal', '#': 'wrongval_meta',
714
+ anno, op: `${ xpr }(…)`, meta: 'literal', '#': 'wrongval_meta',
712
715
  });
713
716
  }
714
717
  },
@@ -724,7 +727,7 @@ function xpr2edmJson( carrier, anno, location, options, messageFunctions ) {
724
727
  const args = parent[xpr];
725
728
  if (args?.length && typeof args[0].val !== 'string') {
726
729
  error('odata-anno-xpr-args', location, {
727
- anno, op: `${xpr}(…)`, meta: 'string', '#': 'wrongval_meta',
730
+ anno, op: `${ xpr }(…)`, meta: 'string', '#': 'wrongval_meta',
728
731
  });
729
732
  }
730
733
  transformExpression(parentparent, parentprop, transform);
@@ -733,7 +736,7 @@ function xpr2edmJson( carrier, anno, location, options, messageFunctions ) {
733
736
  parent[xpr] = true;
734
737
  delete parent.func;
735
738
  if (parent.args?.length)
736
- error('odata-anno-xpr-args', location, { anno, op: `${xpr}(…)` });
739
+ error('odata-anno-xpr-args', location, { anno, op: `${ xpr }(…)` });
737
740
  delete parent.args;
738
741
  },
739
742
  };
@@ -750,12 +753,12 @@ function xpr2edmJson( carrier, anno, location, options, messageFunctions ) {
750
753
  transformExpression(parent, undefined, transform);
751
754
  }
752
755
  else {
753
- const funcName = xpr.startsWith('odata.') ? xpr : `odata.${xpr}`;
756
+ const funcName = xpr.startsWith('odata.') ? xpr : `odata.${ xpr }`;
754
757
  const argDef = canonicFunctionDefinitions[funcName];
755
758
  if (argDef) {
756
759
  if (argDef.use) {
757
760
  error('odata-anno-xpr', location, {
758
- anno, op: `${xpr}(…)`, code: argDef.use, '#': 'use',
761
+ anno, op: `${ xpr }(…)`, code: argDef.use, '#': 'use',
759
762
  });
760
763
  }
761
764
  else {
@@ -769,7 +772,7 @@ function xpr2edmJson( carrier, anno, location, options, messageFunctions ) {
769
772
  }
770
773
  else {
771
774
  error('odata-anno-xpr', location, {
772
- anno, op: `${xpr}(…)`, '#': 'notadynexpr',
775
+ anno, op: `${ xpr }(…)`, '#': 'notadynexpr',
773
776
  });
774
777
  }
775
778
  }
@@ -824,13 +827,13 @@ function getEdmJsonHandler( Edm, options, messageFunctions, handleTerm ) {
824
827
  },
825
828
  $Cast: {
826
829
  create: () => new Edm.Cast(v),
827
- attr: [ '$Type', ...EdmTypeFacetNames.map(n => `$${n}`), '@sap.variable.scale' ],
830
+ attr: [ '$Type', ...EdmTypeFacetNames.map(n => `$${ n }`), '@sap.variable.scale' ],
828
831
  jsonAttr: [ '$Collection' ],
829
832
  anno: true,
830
833
  },
831
834
  $IsOf: {
832
835
  create: () => new Edm.IsOf(v),
833
- attr: [ '$Type', ...EdmTypeFacetNames.map(n => `$${n}`), '@sap.variable.scale' ],
836
+ attr: [ '$Type', ...EdmTypeFacetNames.map(n => `$${ n }`), '@sap.variable.scale' ],
834
837
  jsonAttr: [ '$Collection' ],
835
838
  anno: true,
836
839
  },
@@ -944,7 +947,7 @@ function getEdmJsonHandler( Edm, options, messageFunctions, handleTerm ) {
944
947
  }
945
948
  else if (exprDef.attr && exprDef.attr.includes(name)) {
946
949
  if (options.isV2() && name.startsWith('@sap.'))
947
- edmNode.setXml( { [`sap:${name.slice(5).replace(/\./g, '-')}`]: val } );
950
+ edmNode.setXml( { [`sap:${ name.slice(5).replace(/\./g, '-') }`]: val } );
948
951
  if (name[0] === '$')
949
952
  edmNode.setEdmAttribute(name.slice(1), val);
950
953
  }
@@ -982,7 +985,7 @@ function getEdmJsonHandler( Edm, options, messageFunctions, handleTerm ) {
982
985
  const typeName = getXmlTypeName(val);
983
986
  if (typeName === 'Int')
984
987
  return 'Edm.Int32';
985
- return `Edm.${typeName}`;
988
+ return `Edm.${ typeName }`;
986
989
  }
987
990
  }
988
991
  }