@sap/cds-compiler 2.10.2 → 2.11.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 (82) hide show
  1. package/CHANGELOG.md +90 -5
  2. package/bin/.eslintrc.json +1 -2
  3. package/bin/cds_update_identifiers.js +3 -1
  4. package/bin/cdsc.js +49 -25
  5. package/bin/cdsse.js +1 -0
  6. package/bin/cdsv2m.js +3 -2
  7. package/doc/CHANGELOG_BETA.md +10 -0
  8. package/lib/api/.eslintrc.json +2 -0
  9. package/lib/api/main.js +8 -36
  10. package/lib/api/options.js +15 -6
  11. package/lib/api/validate.js +30 -3
  12. package/lib/backends.js +12 -13
  13. package/lib/base/dictionaries.js +2 -1
  14. package/lib/base/keywords.js +3 -2
  15. package/lib/base/message-registry.js +34 -10
  16. package/lib/base/messages.js +38 -18
  17. package/lib/base/model.js +5 -4
  18. package/lib/base/optionProcessorHelper.js +57 -23
  19. package/lib/checks/emptyOrOnlyVirtual.js +2 -2
  20. package/lib/checks/selectItems.js +4 -0
  21. package/lib/checks/unknownMagic.js +6 -3
  22. package/lib/compiler/assert-consistency.js +9 -2
  23. package/lib/compiler/base.js +65 -0
  24. package/lib/compiler/builtins.js +62 -16
  25. package/lib/compiler/checks.js +2 -1
  26. package/lib/compiler/definer.js +66 -108
  27. package/lib/compiler/index.js +29 -29
  28. package/lib/compiler/propagator.js +5 -2
  29. package/lib/compiler/resolver.js +225 -58
  30. package/lib/compiler/shared.js +53 -229
  31. package/lib/compiler/utils.js +184 -0
  32. package/lib/edm/annotations/genericTranslation.js +1 -1
  33. package/lib/edm/csn2edm.js +3 -2
  34. package/lib/edm/edmPreprocessor.js +34 -38
  35. package/lib/edm/edmUtils.js +3 -3
  36. package/lib/gen/language.checksum +1 -1
  37. package/lib/gen/language.interp +17 -1
  38. package/lib/gen/language.tokens +79 -73
  39. package/lib/gen/languageLexer.interp +19 -1
  40. package/lib/gen/languageLexer.js +779 -731
  41. package/lib/gen/languageLexer.tokens +71 -65
  42. package/lib/gen/languageParser.js +4668 -4072
  43. package/lib/json/from-csn.js +10 -10
  44. package/lib/json/to-csn.js +228 -47
  45. package/lib/language/antlrParser.js +11 -0
  46. package/lib/language/errorStrategy.js +26 -8
  47. package/lib/language/genericAntlrParser.js +73 -14
  48. package/lib/language/language.g4 +79 -3
  49. package/lib/main.d.ts +215 -18
  50. package/lib/main.js +3 -1
  51. package/lib/model/api.js +2 -2
  52. package/lib/model/csnRefs.js +117 -33
  53. package/lib/model/csnUtils.js +65 -133
  54. package/lib/model/enrichCsn.js +62 -37
  55. package/lib/model/revealInternalProperties.js +25 -8
  56. package/lib/model/sortViews.js +8 -1
  57. package/lib/modelCompare/compare.js +2 -1
  58. package/lib/optionProcessor.js +33 -18
  59. package/lib/render/.eslintrc.json +1 -2
  60. package/lib/render/DuplicateChecker.js +1 -1
  61. package/lib/render/toCdl.js +15 -8
  62. package/lib/render/toHdbcds.js +26 -49
  63. package/lib/render/toSql.js +61 -39
  64. package/lib/render/utils/common.js +1 -1
  65. package/lib/transform/db/applyTransformations.js +189 -0
  66. package/lib/transform/db/constraints.js +273 -119
  67. package/lib/transform/db/draft.js +3 -2
  68. package/lib/transform/db/expansion.js +6 -4
  69. package/lib/transform/db/flattening.js +19 -3
  70. package/lib/transform/db/transformExists.js +102 -9
  71. package/lib/transform/db/views.js +485 -0
  72. package/lib/transform/forHanaNew.js +93 -448
  73. package/lib/transform/forOdataNew.js +9 -2
  74. package/lib/transform/localized.js +2 -0
  75. package/lib/transform/odata/structuralPath.js +1 -5
  76. package/lib/transform/transformUtilsNew.js +22 -8
  77. package/lib/transform/translateAssocsToJoins.js +7 -15
  78. package/lib/utils/file.js +11 -5
  79. package/lib/utils/term.js +65 -42
  80. package/lib/utils/timetrace.js +48 -26
  81. package/package.json +1 -1
  82. package/lib/transform/db/helpers.js +0 -58
@@ -54,7 +54,7 @@ function initializeModel(csn, _options, messageFunctions)
54
54
  let options = validateOptions(_options);
55
55
 
56
56
  // Fetch service definitions
57
- const serviceRoots = Object.keys(csn.definitions).reduce((serviceRoots, artName) => {
57
+ const serviceRoots = Object.keys(csn.definitions || {}).reduce((serviceRoots, artName) => {
58
58
  const art = csn.definitions[artName];
59
59
  if(art.kind === 'service') {
60
60
  serviceRoots[artName] = Object.assign(art, { name: artName });
@@ -67,6 +67,9 @@ function initializeModel(csn, _options, messageFunctions)
67
67
  function whatsMyServiceRootName(n, self=true) {
68
68
  return serviceRootNames.reduce((rc, sn) => !rc && n && n.startsWith(sn + '.') || (n === sn && self) ? sn : rc, undefined);
69
69
  }
70
+ if(serviceRootNames.length === 0) {
71
+ return [serviceRoots, Object.create(null), whatsMyServiceRootName, options];
72
+ }
70
73
 
71
74
  // Structural CSN inbound QA checks
72
75
  inboundQualificationChecks();
@@ -594,6 +597,16 @@ function initializeModel(csn, _options, messageFunctions)
594
597
  if(element['@cds.valid.from']) {
595
598
  validFrom.push(element);
596
599
  }
600
+ //forward annotations from managed association element to its foreign keys
601
+ const elements = construct.items && construct.items.elements || construct.elements;
602
+ forAll(elements[element['@odata.foreignKey4']], (attr, attrName) => {
603
+ if(attrName[0] === '@') {
604
+ element[attrName] = attr;
605
+ }
606
+ });
607
+ // and eventually remove some afterwards:)
608
+ if(options.isV2())
609
+ setSAPSpecificV2AnnotationsToAssociation(element);
597
610
 
598
611
  // initialize an association
599
612
  if(isAssociationOrComposition(element)) {
@@ -602,20 +615,6 @@ function initializeModel(csn, _options, messageFunctions)
602
615
  assignProp(element._target, '$proxies', []);
603
616
  // $abspath is used as partner path
604
617
  assignProp(element, '$abspath', $path2path(element.$path));
605
-
606
- //forward annotations from managed association element to its foreign keys
607
- if(element.keys && options.isFlatFormat) {
608
- const elements = construct.items && construct.items.elements || construct.elements;
609
- for(let fk of element.keys) {
610
- forAll(element, (attr, attrName) => {
611
- if(attrName[0] === '@' && fk.$generatedFieldName && elements && elements[fk.$generatedFieldName]) {
612
- elements[fk.$generatedFieldName][attrName] = attr;
613
- }
614
- });
615
- }
616
- }
617
- // and afterwards eventually remove some :)
618
- setSAPSpecificV2AnnotationsToAssociation(options, element, def);
619
618
  }
620
619
 
621
620
  // Collect keys
@@ -1351,7 +1350,8 @@ function initializeModel(csn, _options, messageFunctions)
1351
1350
  // OData requires all elements along the path to be nullable: false (that is either key or notNull)
1352
1351
 
1353
1352
  const finalType = getFinalTypeDef(eltCsn.items && eltCsn.items.type || eltCsn.type);
1354
- const elements = eltCsn.elements || eltCsn.items && eltCsn.items.elements|| finalType.elements || finalType.items && finalType.items.elements;
1353
+ const elements = eltCsn.elements || eltCsn.items && eltCsn.items.elements ||
1354
+ (finalType && (finalType.elements || finalType.items && finalType.items.elements));
1355
1355
  if(elements) {
1356
1356
  Object.entries(elements).forEach(([eltName, elt]) => {
1357
1357
  const newRefs = produceKeyRefPaths(elt, prefix + options.pathDelimiter + eltName);
@@ -1400,7 +1400,7 @@ function initializeModel(csn, _options, messageFunctions)
1400
1400
  {name: pathSegment, '#': pathSegment ? 'std' : 'scalar'});
1401
1401
  }
1402
1402
  // many
1403
- let type = elt.items || getFinalTypeDef(elt.type).items;
1403
+ let type = elt.items || elt.type && !isBuiltinType(elt.type) && getFinalTypeDef(elt.type).items;
1404
1404
  if(type) {
1405
1405
  error('odata-spec-violation-key-array', location,
1406
1406
  {name: pathSegment, '#': pathSegment ? 'std' : 'scalar'});
@@ -2158,19 +2158,17 @@ function setSAPSpecificV2AnnotationsToEntitySet(options, carrier) {
2158
2158
  }
2159
2159
  }
2160
2160
 
2161
- function setSAPSpecificV2AnnotationsToAssociation(options, carrier, struct) {
2162
- if(!options.isV2())
2163
- return;
2161
+ function setSAPSpecificV2AnnotationsToAssociation(carrier) {
2164
2162
  // documented in https://wiki.scn.sap.com/wiki/display/EmTech/SAP+Annotations+for+OData+Version+2.0
2165
2163
  const SetAttributes = {
2166
2164
  // Applicable to NavProp and foreign keys, add to AssociationSet
2167
- '@sap.creatable' : (struct, c,pn, pv) => { addToSetAttr(struct, c, pn, pv, false); },
2165
+ '@sap.creatable' : (c, pn, pv) => { addToAssociationSet(c, pn, pv, false); },
2168
2166
  // Not applicable to NavProp, applicable to foreign keys, add to AssociationSet
2169
- '@sap.updatable' : addToSetAttr,
2167
+ '@sap.updatable' : addToAssociationSet,
2170
2168
  // Not applicable to NavProp, not applicable to foreign key, add to AssociationSet
2171
- '@sap.deletable': (struct, c, pn, pv) => {
2172
- addToSetAttr(struct, c, pn, pv);
2173
- removeFromForeignKey(struct, c, pn);
2169
+ '@sap.deletable': (c, pn, pv) => {
2170
+ addToAssociationSet(c, pn, pv);
2171
+ removeFromForeignKey(c, pn);
2174
2172
  },
2175
2173
  // applicable to NavProp, not applicable to foreign keys, not applicable to AssociationSet
2176
2174
  '@sap.creatable.path': removeFromForeignKey,
@@ -2178,24 +2176,22 @@ function setSAPSpecificV2AnnotationsToAssociation(options, carrier, struct) {
2178
2176
  };
2179
2177
 
2180
2178
  Object.entries(carrier).forEach(([p, v]) => {
2181
- (SetAttributes[p] || function() {/* no-op */})(struct, carrier, p, v);
2179
+ (SetAttributes[p] || function() {/* no-op */})(carrier, p, v);
2182
2180
  });
2183
2181
 
2184
- function addToSetAttr(struct, carrier, propName, propValue, removeFromType=true) {
2185
- assignProp(carrier, '_SetAttributes', Object.create(null));
2186
- assignAnnotation(carrier._SetAttributes, propName, propValue);
2187
- if(removeFromType) {
2188
- delete carrier[propName];
2182
+ function addToAssociationSet(carrier, propName, propValue, removeFromType=true) {
2183
+ if(isAssociationOrComposition(carrier)) {
2184
+ assignProp(carrier, '_SetAttributes', Object.create(null));
2185
+ assignAnnotation(carrier._SetAttributes, propName, propValue);
2186
+ if(removeFromType) {
2187
+ delete carrier[propName];
2188
+ }
2189
2189
  }
2190
2190
  }
2191
2191
 
2192
- function removeFromForeignKey(struct, carrier, propName) {
2193
- if(carrier.target && carrier.keys) {
2194
- struct.elements && Object.values(struct.elements).forEach(e => {
2195
- if(e['@odata.foreignKey4'] === carrier.name) {
2196
- delete e[propName];
2197
- }
2198
- });
2192
+ function removeFromForeignKey(carrier, propName) {
2193
+ if(carrier['@odata.foreignKey4'] && carrier[propName] !== undefined) {
2194
+ delete carrier[propName];
2199
2195
  }
2200
2196
  }
2201
2197
  }
@@ -181,7 +181,7 @@ function resolveOnConditionAndPrepareConstraints(csn, assocCsn, messageFunctions
181
181
  const parent = csn.definitions[parentName];
182
182
  if(originAssocCsn) {
183
183
  const originParentName = originAssocCsn.$abspath[0];
184
- if(originAssocCsn._originalTarget !== parent && originAssocCsn._target !== parent) {
184
+ if(parent.$mySchemaName && originAssocCsn._originalTarget !== parent && originAssocCsn._target !== parent) {
185
185
  isBacklink = false;
186
186
  // Partnership is ambiguous
187
187
  setProp(originAssocCsn, '$noPartner', true);
@@ -192,7 +192,7 @@ function resolveOnConditionAndPrepareConstraints(csn, assocCsn, messageFunctions
192
192
  // Mark this association as backlink if $self appears exactly once
193
193
  // to surpress edm:Association generation in V2 mode
194
194
  if(isBacklink) {
195
- // use first backlink as partner
195
+ // establish partnership with origin assoc but only if this association is the first one
196
196
  if(originAssocCsn._selfReferences.length === 0) {
197
197
  assocCsn._constraints._partnerCsn = originAssocCsn;
198
198
  }
@@ -202,7 +202,7 @@ function resolveOnConditionAndPrepareConstraints(csn, assocCsn, messageFunctions
202
202
  }
203
203
  // store all backlinks at forward, required to calculate rendering of foreign keys
204
204
  // if the termCount != 1 or more than one $self compare this is not a backlink
205
- if(assocCsn._constraints.selfs.length === 1 && assocCsn._constraints.termCount === 1) {
205
+ if(parent.$mySchemaName && assocCsn._constraints.selfs.length === 1 && assocCsn._constraints.termCount === 1) {
206
206
  originAssocCsn._selfReferences.push(assocCsn);
207
207
  }
208
208
  assocCsn._constraints._origins.push(originAssocCsn);
@@ -1 +1 @@
1
- 1bb596306f100150c345f169744f5170
1
+ cde5224056abde61cc2eb0b1b30bf694