@sap/cds-compiler 5.9.4 → 6.0.10

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 (111) hide show
  1. package/CHANGELOG.md +104 -319
  2. package/README.md +1 -1
  3. package/bin/cds_update_identifiers.js +3 -5
  4. package/bin/cdsc.js +22 -8
  5. package/bin/cdshi.js +1 -1
  6. package/bin/cdsse.js +4 -4
  7. package/doc/CHANGELOG_BETA.md +11 -0
  8. package/doc/CHANGELOG_DEPRECATED.md +29 -0
  9. package/lib/api/main.js +8 -5
  10. package/lib/api/options.js +12 -10
  11. package/lib/base/builtins.js +1 -0
  12. package/lib/base/message-registry.js +190 -96
  13. package/lib/base/messages.js +29 -20
  14. package/lib/base/model.js +14 -24
  15. package/lib/checks/actionsFunctions.js +10 -20
  16. package/lib/checks/annotationsOData.js +1 -1
  17. package/lib/checks/elements.js +30 -10
  18. package/lib/checks/enums.js +31 -0
  19. package/lib/checks/foreignKeys.js +2 -2
  20. package/lib/checks/hasPersistedElements.js +5 -0
  21. package/lib/checks/invalidTarget.js +1 -1
  22. package/lib/checks/managedWithoutKeys.js +5 -4
  23. package/lib/checks/queryNoDbArtifacts.js +10 -8
  24. package/lib/checks/types.js +5 -5
  25. package/lib/checks/validator.js +6 -4
  26. package/lib/compiler/assert-consistency.js +12 -9
  27. package/lib/compiler/checks.js +18 -50
  28. package/lib/compiler/define.js +6 -6
  29. package/lib/compiler/extend.js +2 -1
  30. package/lib/compiler/generate.js +14 -17
  31. package/lib/compiler/populate.js +8 -31
  32. package/lib/compiler/propagator.js +21 -35
  33. package/lib/compiler/resolve.js +35 -22
  34. package/lib/compiler/shared.js +7 -1
  35. package/lib/compiler/tweak-assocs.js +1 -1
  36. package/lib/compiler/utils.js +1 -1
  37. package/lib/edm/annotations/edmJson.js +20 -15
  38. package/lib/edm/annotations/genericTranslation.js +7 -8
  39. package/lib/edm/csn2edm.js +46 -50
  40. package/lib/edm/edm.js +8 -7
  41. package/lib/edm/edmPreprocessor.js +33 -83
  42. package/lib/edm/edmUtils.js +2 -2
  43. package/lib/gen/BaseParser.js +55 -44
  44. package/lib/gen/CdlGrammar.checksum +1 -1
  45. package/lib/gen/CdlParser.js +1133 -1150
  46. package/lib/json/from-csn.js +70 -43
  47. package/lib/json/to-csn.js +6 -8
  48. package/lib/language/multiLineStringParser.js +3 -2
  49. package/lib/main.d.ts +58 -24
  50. package/lib/model/csnUtils.js +28 -39
  51. package/lib/model/xprAsTree.js +23 -9
  52. package/lib/modelCompare/compare.js +5 -4
  53. package/lib/optionProcessor.js +21 -17
  54. package/lib/parsers/AstBuildingParser.js +63 -11
  55. package/lib/parsers/XprTree.js +57 -3
  56. package/lib/parsers/identifiers.js +1 -1
  57. package/lib/parsers/index.js +0 -3
  58. package/lib/render/manageConstraints.js +25 -25
  59. package/lib/render/toCdl.js +173 -170
  60. package/lib/render/toHdbcds.js +126 -128
  61. package/lib/render/toRename.js +7 -7
  62. package/lib/render/toSql.js +128 -125
  63. package/lib/render/utils/common.js +47 -22
  64. package/lib/render/utils/delta.js +25 -25
  65. package/lib/render/utils/operators.js +2 -2
  66. package/lib/render/utils/pretty.js +5 -5
  67. package/lib/render/utils/sql.js +13 -13
  68. package/lib/render/utils/standardDatabaseFunctions.js +115 -103
  69. package/lib/render/utils/unique.js +4 -4
  70. package/lib/transform/db/applyTransformations.js +1 -1
  71. package/lib/transform/db/assertUnique.js +2 -2
  72. package/lib/transform/db/associations.js +6 -7
  73. package/lib/transform/db/assocsToQueries/utils.js +4 -5
  74. package/lib/transform/db/backlinks.js +12 -9
  75. package/lib/transform/db/cdsPersistence.js +8 -7
  76. package/lib/transform/db/constraints.js +13 -10
  77. package/lib/transform/db/expansion.js +7 -3
  78. package/lib/transform/db/flattening.js +4 -14
  79. package/lib/transform/db/processSqlServices.js +2 -1
  80. package/lib/transform/db/temporal.js +5 -7
  81. package/lib/transform/db/views.js +2 -4
  82. package/lib/transform/draft/db.js +8 -8
  83. package/lib/transform/draft/odata.js +10 -7
  84. package/lib/transform/forOdata.js +10 -5
  85. package/lib/transform/forRelationalDB.js +5 -75
  86. package/lib/transform/localized.js +1 -1
  87. package/lib/transform/odata/createForeignKeys.js +11 -10
  88. package/lib/transform/odata/flattening.js +8 -4
  89. package/lib/transform/odata/foreignKeyRefsInXprAnnos.js +96 -0
  90. package/lib/transform/odata/typesExposure.js +3 -3
  91. package/lib/transform/transformUtils.js +4 -8
  92. package/lib/transform/translateAssocsToJoins.js +14 -7
  93. package/lib/transform/universalCsn/universalCsnEnricher.js +10 -4
  94. package/lib/utils/objectUtils.js +0 -17
  95. package/package.json +10 -13
  96. package/share/messages/def-upcoming-virtual-change.md +1 -1
  97. package/LICENSE +0 -37
  98. package/bin/cds_remove_invalid_whitespace.js +0 -138
  99. package/doc/CHANGELOG_ARCHIVE.md +0 -3604
  100. package/lib/gen/genericAntlrParser.js +0 -3
  101. package/lib/gen/language.checksum +0 -1
  102. package/lib/gen/language.interp +0 -456
  103. package/lib/gen/language.tokens +0 -180
  104. package/lib/gen/languageLexer.interp +0 -439
  105. package/lib/gen/languageLexer.js +0 -1483
  106. package/lib/gen/languageLexer.tokens +0 -167
  107. package/lib/gen/languageParser.js +0 -24941
  108. package/lib/language/antlrParser.js +0 -205
  109. package/lib/language/errorStrategy.js +0 -646
  110. package/lib/language/genericAntlrParser.js +0 -1572
  111. package/lib/parsers/CdlGrammar.g4 +0 -2070
@@ -83,7 +83,7 @@ function xpr2edmJson( carrier, anno, location, options, messageFunctions ) {
83
83
  });
84
84
  delete parent[op];
85
85
  };
86
- const noOp = () => (true);
86
+ const noOp = () => {};
87
87
  //----------------------------------
88
88
  // Create the transformer dictionary
89
89
  const transform = {
@@ -96,7 +96,6 @@ function xpr2edmJson( carrier, anno, location, options, messageFunctions ) {
96
96
  isNull: (p, o) => notADynExpr(p, o, null, null, null, null, 'is null'),
97
97
  isNotNull: (p, o) => notADynExpr(p, o, null, null, null, null, 'is not null'),
98
98
  exists: notADynExpr,
99
- '#': notADynExpr,
100
99
  SELECT: notADynExpr,
101
100
  SET: (p, o) => notADynExpr(p, o, null, null, null, null, 'UNION'),
102
101
  like: notADynExpr,
@@ -312,8 +311,16 @@ function xpr2edmJson( carrier, anno, location, options, messageFunctions ) {
312
311
  else
313
312
  parentparent[parentprop] = xpr;
314
313
  };
314
+ transform['#'] = (parent, prop, xpr, csnPath, parentParent, parentprop, txt) => {
315
+ if (parent['#'] && parent.val) // enum reference that was resolved by the compiler
316
+ delete parent['#'];
317
+ else
318
+ notADynExpr(parent, prop, xpr, csnPath, parentParent, parentprop, txt);
319
+ };
315
320
  transform.ref = (parent, prop, xpr, csnPath, parentparent, parentprop) => {
316
- if (xpr.some(ps => ps.args || ps.where)) {
321
+ // until empty filter syntax is introduced for the annotation expressions,
322
+ // we ignore the filters in order to generate EDMX
323
+ if (xpr.some(ps => ps.args/* || ps.where */)) {
317
324
  error('odata-anno-xpr-ref', location, {
318
325
  anno, elemref: parent, '#': 'args',
319
326
  });
@@ -492,12 +499,12 @@ function xpr2edmJson( carrier, anno, location, options, messageFunctions ) {
492
499
  const td = EdmPrimitiveTypeMap[typeDef];
493
500
  if (td) {
494
501
  if (td.v2 !== options.isV2() && td.v4 !== options.isV4()) {
495
- message('odata-spec-violation-type', location,
502
+ message('odata-unexpected-edm-type', location,
496
503
  {
497
504
  anno,
498
505
  type: typeDef,
499
506
  version: (options.isV4() ? '4.0' : '2.0'),
500
- '#': 'incompatible_anno',
507
+ '#': 'anno',
501
508
  });
502
509
  }
503
510
  evalArgs(td, typeFacets, typeDef);
@@ -516,13 +523,13 @@ function xpr2edmJson( carrier, anno, location, options, messageFunctions ) {
516
523
  const facetArgs = typeFacets.filter(arg => arg.func === facetName || arg.func === `$${ facetName }`);
517
524
 
518
525
  if (facetArgs.length === 0 && !optional && (options.isV2() === facetDef.v2 || options.isV4() === facetDef.v4)) {
519
- message('odata-spec-violation-type', location,
526
+ message('odata-unexpected-edm-facet', location,
520
527
  {
521
528
  anno,
522
529
  type: typeDef,
523
530
  name: facetName,
524
531
  version: (options.isV4() ? '4.0' : '2.0'),
525
- '#': 'facet_anno',
532
+ '#': 'anno',
526
533
  });
527
534
  }
528
535
  else if (facetArgs.length > 1) {
@@ -566,14 +573,12 @@ function xpr2edmJson( carrier, anno, location, options, messageFunctions ) {
566
573
  const precision = Number.parseInt(parent.$Precision, 10);
567
574
  const scale = Number.parseInt(parent.$Scale, 10);
568
575
  if (!Number.isNaN(precision) && !Number.isNaN(scale) && scale > precision) {
569
- message('odata-spec-violation-type', location,
570
- {
571
- anno,
572
- type: typeDef,
573
- number: scale,
574
- rawvalue: precision,
575
- '#': 'scale_anno',
576
- });
576
+ message('odata-invalid-scale', location, {
577
+ '#': 'anno',
578
+ anno,
579
+ number: scale,
580
+ rawvalue: precision,
581
+ });
577
582
  }
578
583
  }
579
584
  if (options.isV2() && parent.$Scale === 'variable') {
@@ -852,14 +852,13 @@ function csn2annotationEdm( reqDefs, reqDefsUtils, csnVocabularies, serviceName,
852
852
 
853
853
  termNameWithoutQualifiers.split('.').forEach((id) => {
854
854
  if (!edmUtils.isODataSimpleIdentifier(id))
855
- message('odata-spec-violation-id', msg.location, { id });
855
+ message('odata-invalid-name', msg.location, { id });
856
856
  });
857
857
  newAnno = new Edm.Annotation(v, termNameWithoutQualifiers);
858
858
  if (qualifier?.length) {
859
- if (!edmUtils.isODataSimpleIdentifier(qualifier)) {
860
- message('odata-spec-violation-id', msg.location,
861
- { id: qualifier, '#': 'qualifier' });
862
- }
859
+ if (!edmUtils.isODataSimpleIdentifier(qualifier))
860
+ message('odata-invalid-qualifier', msg.location, { id: qualifier });
861
+
863
862
  newAnno.setEdmAttribute('Term', termNameWithoutQualifiers);
864
863
  newAnno.setEdmAttribute('Qualifier', qualifier);
865
864
  }
@@ -1428,7 +1427,7 @@ function csn2annotationEdm( reqDefs, reqDefsUtils, csnVocabularies, serviceName,
1428
1427
  // in a record or term
1429
1428
  if (Array.isArray(value)) {
1430
1429
  message('odata-anno-value', msg.location,
1431
- { anno: msg.anno(), '#': 'nestedcollection' });
1430
+ { anno: msg.anno(), '#': 'nestedCollection' });
1432
1431
  }
1433
1432
  else if (value && typeof value === 'object') {
1434
1433
  if (value['=']) {
@@ -1439,7 +1438,7 @@ function csn2annotationEdm( reqDefs, reqDefsUtils, csnVocabularies, serviceName,
1439
1438
  }
1440
1439
  else if (value['#']) {
1441
1440
  message('odata-anno-value', msg.location,
1442
- { anno: msg.anno(), '#': 'enumincollection' });
1441
+ { anno: msg.anno(), '#': 'enuminCollection' });
1443
1442
  }
1444
1443
  else if (value.$edmJson) {
1445
1444
  newCollection.append(handleEdmJson(value.$edmJson, msg));
@@ -1774,7 +1773,7 @@ function mergeOdataVocabularies( options, message ) {
1774
1773
  defOk = false;
1775
1774
  }
1776
1775
  else if (name === 'Alias' && !edmUtils.isODataSimpleIdentifier(def[name])) {
1777
- message('odata-spec-violation-id', null, { id: name, value: def[name], '#': 'vocRefAlias' });
1776
+ message('odata-invalid-vocabulary-alias', null, { id: name, value: def[name] });
1778
1777
  defOk = false;
1779
1778
  }
1780
1779
  });
@@ -79,7 +79,7 @@ function csn2edmAll( _csn, _options, serviceNames, messageFunctions ) {
79
79
 
80
80
  const mergedVocabularies = translate.mergeOdataVocabularies(options, message);
81
81
 
82
- const Edm = getEdm(options, messageFunctions);
82
+ const Edm = getEdm(options);
83
83
 
84
84
  const { v } = options;
85
85
  if (Object.keys(allServices).length === 0) {
@@ -304,14 +304,13 @@ function csn2edmAll( _csn, _options, serviceNames, messageFunctions ) {
304
304
 
305
305
  const usages = UsedTypes[typeName].filter(u => !u.$NameClashReported);
306
306
  if (usages.length > 0 && def && !def.$isRendered && def['@cds.external']) {
307
- message('odata-spec-violation-type', usages[0].$location,
307
+ message('odata-invalid-external-type', usages[0].$location,
308
308
  {
309
309
  type: typeName,
310
310
  anno: '@cds.external',
311
311
  name: serviceCsn.name,
312
312
  code: def.elements ? 'Edm.ComplexType' : 'Edm.TypeDefinition',
313
313
  version: options.isV4() ? '4.0' : '2.0',
314
- '#': 'external',
315
314
  });
316
315
  }
317
316
  }
@@ -407,14 +406,14 @@ function csn2edmAll( _csn, _options, serviceNames, messageFunctions ) {
407
406
  const reservedNames = [ 'Edm', 'odata', 'System', 'Transient' ];
408
407
  const loc = [ 'definitions', schema.name ];
409
408
  if (reservedNames.includes(schema.name))
410
- message('odata-spec-violation-namespace', loc, { names: reservedNames });
409
+ message('odata-invalid-service-name', loc, { names: reservedNames });
411
410
  if (schema.name.length > 511) {
412
- message('odata-spec-violation-namespace', loc, { '#': 'length' });
411
+ message('odata-invalid-service-name', loc, { '#': 'length' });
413
412
  }
414
413
  else {
415
414
  schema.name.split('.').forEach((id) => {
416
415
  if (!edmUtils.isODataSimpleIdentifier(id))
417
- message('odata-spec-violation-id', loc, { id });
416
+ message('odata-invalid-name', loc, { id });
418
417
  });
419
418
  }
420
419
 
@@ -523,29 +522,31 @@ function csn2edmAll( _csn, _options, serviceNames, messageFunctions ) {
523
522
  // this especially covers: 'items: composition of one { data : String; }'
524
523
  // "keyless" composition targets in structured containment mode
525
524
  else if (entityCsn.$hasEntitySet && entityCsn.$edmKeyPaths.length === 0 && !isSingleton)
526
- message('odata-spec-violation-no-key', location);
525
+ message('odata-missing-key', location);
527
526
 
528
527
  if (!edmUtils.isODataSimpleIdentifier(EntityTypeName))
529
- message('odata-spec-violation-id', location, { id: EntityTypeName });
528
+ message('odata-invalid-name', location, { id: EntityTypeName });
530
529
 
531
530
  properties.forEach((p) => {
532
531
  const pLoc = [ ...location, 'elements', p._edmAttributes.Name ];
533
532
  edmTypeCompatibilityCheck(p, pLoc);
534
533
  if (p._edmAttributes.Name === EntityTypeName)
535
- message('odata-spec-violation-property-name', pLoc, { meta: entityCsn.kind });
534
+ message('odata-invalid-property-name', pLoc, { meta: entityCsn.kind });
536
535
 
537
536
  if (options.isV2() && p.$isCollection && !p._csn.target)
538
- message('odata-spec-violation-array', pLoc, { version: '2.0' });
537
+ message('odata-unexpected-array', pLoc, { version: '2.0' });
539
538
 
540
539
  if (!edmUtils.isODataSimpleIdentifier(p._edmAttributes.Name)) {
541
- message('odata-spec-violation-id', pLoc, { id: p._edmAttributes.Name });
540
+ message('odata-invalid-name', pLoc, { id: p._edmAttributes.Name });
542
541
  }
543
542
  else if (options.isV2() && /^(_|\d)/.test(p._edmAttributes.Name)) {
544
543
  // FIXME: Rewrite signalIllegalIdentifier function to be more flexible
545
- message('odata-spec-violation-id', pLoc,
546
- {
547
- prop: p._edmAttributes.Name[0], id: p._edmAttributes.Name, version: '2.0', '#': 'v2firstChar',
548
- });
544
+ message('odata-invalid-name', pLoc, {
545
+ '#': 'v2firstChar',
546
+ prop: p._edmAttributes.Name[0],
547
+ id: p._edmAttributes.Name,
548
+ version: '2.0',
549
+ });
549
550
  }
550
551
  });
551
552
 
@@ -603,23 +604,23 @@ function csn2edmAll( _csn, _options, serviceNames, messageFunctions ) {
603
604
  const location = [ 'definitions', structuredTypeCsn.name ];
604
605
 
605
606
  if (!edmUtils.isODataSimpleIdentifier(attributes.Name))
606
- message('odata-spec-violation-id', location, { id: attributes.Name });
607
+ message('odata-invalid-name', location, { id: attributes.Name });
607
608
 
608
609
  properties.forEach((p) => {
609
610
  const pLoc = [ ...location, ...(structuredTypeCsn.items ? [ 'items', 'elements' ] : [ 'elements' ]), p._edmAttributes.Name ];
610
611
  edmTypeCompatibilityCheck(p, pLoc);
611
612
  if (p._edmAttributes.Name === complexType._edmAttributes.Name)
612
- message('odata-spec-violation-property-name', pLoc, { meta: structuredTypeCsn.kind });
613
+ message('odata-invalid-property-name', pLoc, { meta: structuredTypeCsn.kind });
613
614
 
614
615
  if (!edmUtils.isODataSimpleIdentifier(p._edmAttributes.Name))
615
- message('odata-spec-violation-id', pLoc, { id: p._edmAttributes.Name });
616
+ message('odata-invalid-name', pLoc, { id: p._edmAttributes.Name });
616
617
 
617
618
  if (options.isV2()) {
618
619
  if (p.$isCollection && !p._csn.target)
619
- message('odata-spec-violation-array', pLoc, { version: '2.0' });
620
+ message('odata-unexpected-array', pLoc, { version: '2.0' });
620
621
 
621
622
  if (p._csn.target)
622
- message('odata-spec-violation-assoc', pLoc, { version: '2.0' });
623
+ message('odata-unexpected-assoc', pLoc, { version: '2.0' });
623
624
  }
624
625
  });
625
626
 
@@ -713,7 +714,7 @@ function csn2edmAll( _csn, _options, serviceNames, messageFunctions ) {
713
714
  // derived types are already resolved to base types
714
715
  const attributes = { Name: typeCsn.name.replace(schemaNamePrefix, '') };
715
716
  if (!edmUtils.isODataSimpleIdentifier(attributes.Name))
716
- message('odata-spec-violation-id', typeCsn.$path, { id: attributes.Name });
717
+ message('odata-invalid-name', typeCsn.$path, { id: attributes.Name });
717
718
 
718
719
  const typeDef = new Edm.TypeDefinition(v, attributes, typeCsn );
719
720
  edmTypeCompatibilityCheck(typeDef, typeCsn.$path);
@@ -732,7 +733,7 @@ function csn2edmAll( _csn, _options, serviceNames, messageFunctions ) {
732
733
 
733
734
 
734
735
  if (!edmUtils.isODataSimpleIdentifier(attributes.Name))
735
- message('odata-spec-violation-id', location, { id: attributes.Name });
736
+ message('odata-invalid-name', location, { id: attributes.Name });
736
737
 
737
738
  if (!iAmAnAction)
738
739
  attributes.IsComposable = false;
@@ -766,7 +767,7 @@ function csn2edmAll( _csn, _options, serviceNames, messageFunctions ) {
766
767
  setProp(firstParam, '_edmType', bpType);
767
768
  }
768
769
  if (!edmUtils.isODataSimpleIdentifier(bpName))
769
- message('odata-spec-violation-id', [ ...location, 'params', bpName ], { id: bpName });
770
+ message('odata-invalid-name', [ ...location, 'params', bpName ], { id: bpName });
770
771
  }
771
772
  }
772
773
 
@@ -795,7 +796,7 @@ function csn2edmAll( _csn, _options, serviceNames, messageFunctions ) {
795
796
  }
796
797
 
797
798
  if (!edmUtils.isODataSimpleIdentifier(bpName))
798
- message('odata-spec-violation-id', bpnAnnoLoc, { id: bpName });
799
+ message('odata-invalid-name', bpnAnnoLoc, { id: bpName });
799
800
  if (actionCsn.params && actionCsn.params[bpName])
800
801
  error('duplicate-definition', bpnAnnoLoc, { '#': 'param', name: bpName });
801
802
  }
@@ -839,7 +840,7 @@ function csn2edmAll( _csn, _options, serviceNames, messageFunctions ) {
839
840
  const p = new Edm.Parameter(v, { Name: parameterName }, parameterCsn );
840
841
  const pLoc = [ ...location, 'params', p._edmAttributes.Name ];
841
842
  if (!edmUtils.isODataSimpleIdentifier(parameterName))
842
- message('odata-spec-violation-id', pLoc, { id: parameterName });
843
+ message('odata-invalid-name', pLoc, { id: parameterName });
843
844
  collectUsedType(parameterCsn);
844
845
  edmTypeCompatibilityCheck(p, pLoc);
845
846
  actionNode.append(p);
@@ -880,7 +881,7 @@ function csn2edmAll( _csn, _options, serviceNames, messageFunctions ) {
880
881
  : [ 'definitions', actionCsn.name ];
881
882
 
882
883
  if (!edmUtils.isODataSimpleIdentifier(attributes.Name))
883
- message('odata-spec-violation-id', location, { id: attributes.Name });
884
+ message('odata-invalid-name', location, { id: attributes.Name });
884
885
 
885
886
  const rt = actionCsn.returns && ((actionCsn.returns.items && actionCsn.returns.items.type) || actionCsn.returns.type);
886
887
  if (rt) { // add EntitySet attribute only if return type is an entity
@@ -936,17 +937,17 @@ function csn2edmAll( _csn, _options, serviceNames, messageFunctions ) {
936
937
  collectUsedType(parameterCsn);
937
938
  edmTypeCompatibilityCheck(param, pLoc);
938
939
  if (!edmUtils.isODataSimpleIdentifier(parameterName))
939
- message('odata-spec-violation-id', pLoc, { id: parameterName });
940
+ message('odata-invalid-name', pLoc, { id: parameterName });
940
941
 
941
942
  // only scalar or structured type in V2 (not entity)
942
943
  if (param._type &&
943
- !param._type.startsWith('Edm.') &&
944
- csn.definitions[param._type] &&
945
- !edmUtils.isStructuredType(csn.definitions[param._type]))
946
- message('odata-spec-violation-param', pLoc, { version: '2.0' });
944
+ !param._type.startsWith('Edm.') &&
945
+ csn.definitions[param._type] &&
946
+ !edmUtils.isStructuredType(csn.definitions[param._type]))
947
+ message('odata-invalid-param-type', pLoc, { version: '2.0' });
947
948
 
948
949
  if (param.$isCollection)
949
- message('odata-spec-violation-array', pLoc, { version: '2.0' });
950
+ message('odata-unexpected-array', pLoc, { version: '2.0' });
950
951
 
951
952
  functionImport.append(param);
952
953
  }
@@ -966,27 +967,26 @@ function csn2edmAll( _csn, _options, serviceNames, messageFunctions ) {
966
967
  if (type) {
967
968
  collectUsedType(action.returns);
968
969
  if (!isBuiltinType(type) && csn.definitions[type].kind !== 'entity' && csn.definitions[type].kind !== 'type') {
969
- message('odata-spec-violation-returns', returnsLoc, { kind: action.kind, version: '2.0' });
970
+ message('odata-invalid-return-type', returnsLoc, { kind: action.kind, version: '2.0' });
970
971
  }
971
972
  else if (isBuiltinType(type)) {
972
973
  type = edmUtils.mapCdsToEdmType(returns, messageFunctions, _options);
973
974
  if (type) {
974
975
  const td = EdmPrimitiveTypeMap[type];
975
976
  if (td && !td.v2) {
976
- message('odata-spec-violation-type', returnsLoc,
977
- { type, version: '2.0', '#': 'incompatible' });
977
+ message('odata-unexpected-edm-type', returnsLoc,
978
+ { type, version: '2.0' });
978
979
  }
979
980
  }
980
981
  else {
981
- message('odata-spec-violation-type-unknown', returnsLoc, { type });
982
+ message('odata-unknown-edm-type', returnsLoc, { type });
982
983
  }
983
984
  }
984
985
  if (action.returns.$isCollection)
985
986
  type = `Collection(${ type })`;
986
987
  }
987
988
  else {
988
- // type is missing
989
- message('odata-spec-violation-type', returnsLoc);
989
+ message('odata-missing-type', returnsLoc);
990
990
  }
991
991
  }
992
992
  return type;
@@ -1159,7 +1159,7 @@ function csn2edmAll( _csn, _options, serviceNames, messageFunctions ) {
1159
1159
  function edmTypeCompatibilityCheck( p, pLoc ) {
1160
1160
  const edmType = p._type;
1161
1161
  if (!edmType) {
1162
- message('odata-spec-violation-type', pLoc);
1162
+ message('odata-missing-type', pLoc);
1163
1163
  }
1164
1164
  else if (p._scalarType) {
1165
1165
  const td = EdmPrimitiveTypeMap[edmType];
@@ -1167,8 +1167,8 @@ function csn2edmAll( _csn, _options, serviceNames, messageFunctions ) {
1167
1167
  // The renderer/type mapper doesn't/shouldn't produce incompatible types and facets.
1168
1168
  // Only the unknown type warning may be triggered by an unknown @odata.Type override.
1169
1169
  if (td.v2 !== p.v2 && td.v4 !== p.v4) {
1170
- message('odata-spec-violation-type', pLoc,
1171
- { type: edmType, version: (p.v4 ? '4.0' : '2.0'), '#': 'incompatible' });
1170
+ message('odata-unexpected-edm-type', pLoc,
1171
+ { type: edmType, version: (p.v4 ? '4.0' : '2.0') });
1172
1172
  }
1173
1173
  EdmTypeFacetNames.forEach((name) => {
1174
1174
  const facet = EdmTypeFacetMap[name];
@@ -1183,25 +1183,21 @@ function csn2edmAll( _csn, _options, serviceNames, messageFunctions ) {
1183
1183
  // facet is member of type definition and mandatory
1184
1184
  // node and facet version match
1185
1185
  if (!p._edmAttributes[name] && td[name] && !optional && (p.v2 === facet.v2 || p.v4 === facet.v4)) {
1186
- message('odata-spec-violation-type', pLoc,
1187
- {
1188
- type: edmType, name, version: (p.v4 ? '4.0' : '2.0'), '#': 'facet',
1189
- });
1186
+ message('odata-unexpected-edm-facet', pLoc,
1187
+ { type: edmType, name, version: (p.v4 ? '4.0' : '2.0') });
1190
1188
  }
1191
1189
  });
1192
1190
  if (edmType === 'Edm.Decimal') {
1193
1191
  const precision = Number.parseInt(p._edmAttributes.Precision, 10);
1194
1192
  const scale = Number.parseInt(p._edmAttributes.Scale, 10);
1195
1193
  if (!Number.isNaN(precision) && !Number.isNaN(scale) && scale > precision) {
1196
- message('odata-spec-violation-type', pLoc,
1197
- {
1198
- type: edmType, number: scale, rawvalue: precision, '#': 'scale',
1199
- });
1194
+ message('odata-invalid-scale', pLoc,
1195
+ { number: scale, rawvalue: precision });
1200
1196
  }
1201
1197
  }
1202
1198
  }
1203
1199
  else {
1204
- message('odata-spec-violation-type-unknown', pLoc, { type: edmType });
1200
+ message('odata-unknown-edm-type', pLoc, { type: edmType });
1205
1201
  }
1206
1202
  }
1207
1203
  }
package/lib/edm/edm.js CHANGED
@@ -8,9 +8,9 @@ const {
8
8
  EdmTypeFacetNames,
9
9
  EdmPrimitiveTypeMap,
10
10
  } = require('./EdmPrimitiveTypeDefinitions.js');
11
+ const { CompilerAssertion } = require('../base/error');
11
12
 
12
- function getEdm( options, messageFunctions ) {
13
- const { error } = messageFunctions || { error: () => true, warning: () => true };
13
+ function getEdm( options ) {
14
14
  class Node {
15
15
  /**
16
16
  * @param {boolean[]} version Versions in the form of [<v2>, <v4>].
@@ -19,11 +19,11 @@ function getEdm( options, messageFunctions ) {
19
19
  */
20
20
  constructor(version, attributes = Object.create(null), csn = undefined) {
21
21
  if (!attributes || typeof attributes !== 'object')
22
- error(null, 'Debug me: attributes must be a dictionary');
22
+ throw new CompilerAssertion('Debug me: attributes must be a dictionary');
23
23
  if (!Array.isArray(version))
24
- error(null, `Debug me: v is either undefined or not an array: ${ version }`);
24
+ throw new CompilerAssertion(`Debug me: v is either undefined or not an array: ${ version }`);
25
25
  if (version.filter(v => v).length !== 1)
26
- error(null, 'Debug me: exactly one version must be set');
26
+ throw new CompilerAssertion('Debug me: exactly one version must be set');
27
27
 
28
28
  // Common attributes of JSON and XML.
29
29
  // Note: Can't assign attributes directly, due to the input object being modified.
@@ -741,6 +741,7 @@ function getEdm( options, messageFunctions ) {
741
741
  this._edmAttributes.OpenType = true;
742
742
  }
743
743
  }
744
+
744
745
  class EntityType extends ComplexType {
745
746
  constructor(version, details, properties, csn) {
746
747
  super(version, details, csn);
@@ -1142,7 +1143,7 @@ function getEdm( options, messageFunctions ) {
1142
1143
  json.$OnDelete = c._edmAttributes.Action;
1143
1144
  break;
1144
1145
  default:
1145
- error(null, `Debug me: Unhandled NavProp child: ${ c.kind }`);
1146
+ throw new CompilerAssertion(`Debug me: Unhandled NavProp child: ${ c.kind }`);
1146
1147
  }
1147
1148
  });
1148
1149
  // TODO Annotations
@@ -1340,7 +1341,7 @@ function getEdm( options, messageFunctions ) {
1340
1341
  break;
1341
1342
  }
1342
1343
  default:
1343
- error(null, `Pease debug me: Unhandled Record child: ${ c.kind }`);
1344
+ throw new CompilerAssertion(`Debug me: Unhandled Record child: ${ c.kind }`);
1344
1345
  }
1345
1346
  });
1346
1347
  return json;