@sap/cds-compiler 3.0.0 → 3.0.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 (38) hide show
  1. package/CHANGELOG.md +29 -9
  2. package/bin/cdsc.js +9 -16
  3. package/lib/api/main.js +92 -40
  4. package/lib/base/keywords.js +64 -1
  5. package/lib/base/message-registry.js +17 -1
  6. package/lib/base/messages.js +38 -28
  7. package/lib/base/optionProcessorHelper.js +53 -21
  8. package/lib/compiler/assert-consistency.js +1 -1
  9. package/lib/compiler/builtins.js +40 -1
  10. package/lib/compiler/define.js +4 -2
  11. package/lib/compiler/extend.js +4 -1
  12. package/lib/compiler/populate.js +3 -1
  13. package/lib/compiler/resolve.js +1 -4
  14. package/lib/compiler/shared.js +9 -0
  15. package/lib/compiler/utils.js +2 -2
  16. package/lib/edm/annotations/preprocessAnnotations.js +10 -11
  17. package/lib/edm/csn2edm.js +15 -14
  18. package/lib/edm/edm.js +13 -12
  19. package/lib/edm/edmPreprocessor.js +30 -33
  20. package/lib/edm/edmUtils.js +3 -39
  21. package/lib/gen/language.checksum +1 -1
  22. package/lib/gen/language.interp +1 -1
  23. package/lib/gen/languageParser.js +3311 -3289
  24. package/lib/json/from-csn.js +17 -19
  25. package/lib/json/to-csn.js +3 -2
  26. package/lib/language/genericAntlrParser.js +42 -42
  27. package/lib/language/language.g4 +28 -17
  28. package/lib/model/csnRefs.js +1 -0
  29. package/lib/model/csnUtils.js +19 -8
  30. package/lib/model/revealInternalProperties.js +4 -1
  31. package/lib/optionProcessor.js +54 -38
  32. package/lib/render/toHdbcds.js +1 -1
  33. package/lib/render/toSql.js +7 -3
  34. package/lib/transform/forOdataNew.js +3 -3
  35. package/lib/transform/localized.js +15 -11
  36. package/lib/utils/file.js +28 -18
  37. package/package.json +2 -3
  38. package/share/messages/syntax-expected-integer.md +9 -8
@@ -11,14 +11,11 @@ const {
11
11
  intersect,
12
12
  validateOptions,
13
13
  foreach,
14
- forAll,
15
- isAssociationOrComposition,
16
14
  isComposition,
17
15
  isStructuredArtifact,
18
16
  isParameterizedEntity,
19
17
  resolveOnConditionAndPrepareConstraints,
20
18
  finalizeReferentialConstraints,
21
- isEntity,
22
19
  getSchemaPrefix,
23
20
  } = require('./edmUtils.js');
24
21
 
@@ -124,7 +121,7 @@ function initializeModel(csn, _options, messageFunctions, requestedServiceNames=
124
121
  (def, defName) => {
125
122
  const mySchemaName = whatsMySchemaName(defName);
126
123
  mySchemaName && setProp(def, '$mySchemaName', mySchemaName);
127
- if(isMyServiceRequested(defName))
124
+ if(isMyServiceRequested(defName) && def.kind !== 'aspect')
128
125
  reqDefs.definitions[defName] = def;
129
126
  },
130
127
  linkAssociationTarget ]);
@@ -336,23 +333,21 @@ function initializeModel(csn, _options, messageFunctions, requestedServiceNames=
336
333
  // link association target to association and add @odata.contained to compositions in V4
337
334
  function linkAssociationTarget(struct) {
338
335
  forEachMemberRecursively(struct, (element, name, prop, subpath) => {
339
- if(isAssociationOrComposition(element)) {
340
- if(!element._target) {
341
- let target = csn.definitions[element.target];
342
- if(target) {
343
- setProp(element, '_target', target);
336
+ if(element.target && !element._target) {
337
+ let target = csn.definitions[element.target];
338
+ if(target) {
339
+ setProp(element, '_target', target);
344
340
  // If target has parameters, xref assoc at target for redirection
345
- if(isParameterizedEntity(target)) {
346
- if(!target.$sources) {
347
- setProp(target, '$sources', Object.create(null));
348
- }
349
- target.$sources[struct.name + '.' + name] = element;
341
+ if(isParameterizedEntity(target)) {
342
+ if(!target.$sources) {
343
+ setProp(target, '$sources', Object.create(null));
350
344
  }
351
- }
352
- else {
353
- error(null, subpath, { target: element.target }, "Target $(TARGET) can't be found in the model");
345
+ target.$sources[struct.name + '.' + name] = element;
354
346
  }
355
347
  }
348
+ else {
349
+ error(null, subpath, { target: element.target }, "Target $(TARGET) can't be found in the model");
350
+ }
356
351
  }
357
352
  // in V4 tag all compositions to be containments
358
353
  if(options.odataContainment &&
@@ -384,7 +379,7 @@ function initializeModel(csn, _options, messageFunctions, requestedServiceNames=
384
379
  }
385
380
 
386
381
  function initContainments(elt, eltName) {
387
- if(isAssociationOrComposition(elt) && elt['@odata.contained'] && !elt._ignore) {
382
+ if(elt.target && elt['@odata.contained'] && !elt._ignore) {
388
383
  // Let the containee know its container
389
384
  // (array because the contanee may contained more then once)
390
385
  let containee = elt._target;
@@ -655,17 +650,19 @@ function initializeModel(csn, _options, messageFunctions, requestedServiceNames=
655
650
  }
656
651
  //forward annotations from managed association element to its foreign keys
657
652
  const elements = construct.items && construct.items.elements || construct.elements;
658
- forAll(elements[element['@odata.foreignKey4']], (attr, attrName) => {
653
+ const fk = elements[element['@odata.foreignKey4']];
654
+ for(const attrName in fk) {
655
+ const attr = fk[attrName];
659
656
  if(attrName[0] === '@') {
660
657
  element[attrName] = attr;
661
658
  }
662
- });
659
+ }
663
660
  // and eventually remove some afterwards:)
664
661
  if(options.isV2())
665
662
  setSAPSpecificV2AnnotationsToAssociation(element);
666
663
 
667
664
  // initialize an association
668
- if(isAssociationOrComposition(element)) {
665
+ if(element.target) {
669
666
  // in case this is a forward assoc, store the backlink partners here, _selfReferences.length > 1 => error
670
667
  assignProp(element, '_selfReferences', []);
671
668
  assignProp(element._target, '$proxies', []);
@@ -694,7 +691,7 @@ function initializeModel(csn, _options, messageFunctions, requestedServiceNames=
694
691
  // @Core.AlternateKeys: [{ Key: [ { Name: 'slID', Alias: 'slID' }, { Name: 'validFrom', Alias: 'validFrom'} ] }]
695
692
  if(validKey.length) {
696
693
  let altKeys = [{ Key: [] }];
697
- forAll(keys, (k, kn) => {
694
+ Object.entries(([kn, k]) => {
698
695
  altKeys[0].Key.push( { Name: kn, Alias: kn } );
699
696
  delete k.key;
700
697
  });
@@ -717,7 +714,7 @@ function initializeModel(csn, _options, messageFunctions, requestedServiceNames=
717
714
  }
718
715
 
719
716
  // prepare the structure itself
720
- if(isEntity(def)) {
717
+ if(def.kind === 'entity') {
721
718
  assignProp(def, '_SetAttributes', Object.create(null));
722
719
  assignProp(def, '$keys', keys);
723
720
  applyAppSpecificLateCsnTransformationOnStructure(options, def, error);
@@ -733,7 +730,7 @@ function initializeModel(csn, _options, messageFunctions, requestedServiceNames=
733
730
  forEachMemberRecursively(def.items || def, initConstraintsOnAssoc, [], true, { elementsOnly: true });
734
731
  }
735
732
  function initConstraintsOnAssoc(element) {
736
- if (isAssociationOrComposition(element) && !element._constraints) {
733
+ if (element.target && !element._constraints) {
737
734
  // setup the constraints object
738
735
  setProp(element, '_constraints', { constraints: Object.create(null), selfs: [], _origins: [], termCount: 0 });
739
736
  // and crack the ON condition
@@ -817,7 +814,7 @@ function initializeModel(csn, _options, messageFunctions, requestedServiceNames=
817
814
  forEachMemberRecursively(def.items || def, finalizeConstraintsOnAssoc, [], true, { elementsOnly: true });
818
815
  }
819
816
  function finalizeConstraintsOnAssoc(element) {
820
- if (isAssociationOrComposition(element) && !element._ignore && element._constraints) {
817
+ if (element.target && !element._ignore && element._constraints) {
821
818
  finalizeReferentialConstraints(csn, element, options, info);
822
819
 
823
820
  if(element._constraints._partnerCsn && element.cardinality && element.cardinality.max) {
@@ -907,7 +904,7 @@ function initializeModel(csn, _options, messageFunctions, requestedServiceNames=
907
904
  // if this artifact is a service member check its associations
908
905
  if(globalSchemaPrefix) {
909
906
  forEachGeneric(struct.items || struct, 'elements', element => {
910
- if(!isAssociationOrComposition(element) || element['@odata.navigable'] === false)
907
+ if(!element.target || element['@odata.navigable'] === false)
911
908
  return;
912
909
  /*
913
910
  * Consider everything @cds.autoexpose: falsy to be a proxy candidate for now
@@ -1063,7 +1060,7 @@ function initializeModel(csn, _options, messageFunctions, requestedServiceNames=
1063
1060
  // copy over the primary keys of the target and trigger the type exposure
1064
1061
  // if the element already exists we assume it was fully exposed
1065
1062
  function populateProxyElements(assoc, proxy, elements) {
1066
- forAll(elements, e => {
1063
+ Object.values(elements).forEach(e => {
1067
1064
  if (isEdmPropertyRendered(e, options)) {
1068
1065
  let newElt = proxy.elements[e.name];
1069
1066
  if(!newElt) {
@@ -1551,7 +1548,7 @@ function initializeModel(csn, _options, messageFunctions, requestedServiceNames=
1551
1548
 
1552
1549
  // check for legal scalar types, proxy exposed structured types are not resolvable in CSN
1553
1550
  // V2 allows any Edm.PrimitiveType (even Double and Binary), V4 is more specific:
1554
- if(options.isV4() && type && !isAssociationOrComposition(type) && isBuiltinType(type.type)) {
1551
+ if(options.isV4() && type && !type.target && isBuiltinType(type.type)) {
1555
1552
  const edmType = edmUtils.mapCdsToEdmType(type);
1556
1553
  const legalEdmTypes = {
1557
1554
  'Edm.Boolean':1, 'Edm.Byte':1, 'Edm.Date':1, 'Edm.DateTimeOffset':1, 'Edm.Decimal':1, 'Edm.Duration':1,
@@ -1604,7 +1601,7 @@ function initializeModel(csn, _options, messageFunctions, requestedServiceNames=
1604
1601
  if(isEdmPropertyRendered(elt, options)) {
1605
1602
  // Assoc can never be a derived TypeDefinition, no need to
1606
1603
  // unroll derived type chains for assocs
1607
- if(isAssociationOrComposition(elt) && !elt.$touched) {
1604
+ if(elt.target && !elt.$touched) {
1608
1605
  if(!elt._target.$edmTgtPaths)
1609
1606
  setProp(elt._target, '$edmTgtPaths', []);
1610
1607
  // drill into target only if
@@ -1649,7 +1646,7 @@ function initializeModel(csn, _options, messageFunctions, requestedServiceNames=
1649
1646
  if(isEdmPropertyRendered(elt, options)) {
1650
1647
  // Assoc can never be a derived TypeDefinition, no need to
1651
1648
  // unroll derived type chains for assocs
1652
- if(isAssociationOrComposition(elt) && !elt.$touched) {
1649
+ if(elt.target && !elt.$touched) {
1653
1650
  // drill into target only if
1654
1651
  // 1) target has no entity set and this assoc is not going to the container
1655
1652
  // 2) current definition and target are the same (cycle)
@@ -1713,7 +1710,7 @@ function initializeModel(csn, _options, messageFunctions, requestedServiceNames=
1713
1710
  // 1) must not be a proxy and not a containee in V4
1714
1711
  // No annos are rendered for non-existing EntitySet targets.
1715
1712
  if(def.$hasEntitySet === undefined) {
1716
- const hasEntitySet = isEntity(def) && !(options.isV4() && edmUtils.isContainee(def)) && !def.$proxy;
1713
+ const hasEntitySet = def.kind === 'entity' && !(options.isV4() && edmUtils.isContainee(def)) && !def.$proxy;
1717
1714
  setProp(def, '$hasEntitySet', hasEntitySet);
1718
1715
  }
1719
1716
  }
@@ -1958,7 +1955,7 @@ function initializeModel(csn, _options, messageFunctions, requestedServiceNames=
1958
1955
  }
1959
1956
 
1960
1957
  function mapCdsToEdmProp(obj) {
1961
- if (obj.type && isBuiltinType(obj.type) && !isAssociationOrComposition(obj) && !obj.targetAspect) {
1958
+ if (obj.type && isBuiltinType(obj.type) && !obj.target && !obj.targetAspect) {
1962
1959
  let edmType = edmUtils.mapCdsToEdmType(obj, messageFunctions, _options.odataVersion === 'v2', obj['@Core.MediaType']);
1963
1960
  assignProp(obj, '_edmType', edmType);
1964
1961
  } else if (obj._isCollection && (obj.items && isBuiltinType(csnUtils.getFinalTypeDef(obj.items.type)))) {
@@ -2321,7 +2318,7 @@ function setSAPSpecificV2AnnotationsToAssociation(carrier) {
2321
2318
  });
2322
2319
 
2323
2320
  function addToAssociationSet(carrier, propName, propValue, removeFromType=true) {
2324
- if(isAssociationOrComposition(carrier)) {
2321
+ if(carrier.target) {
2325
2322
  assignProp(carrier, '_SetAttributes', Object.create(null));
2326
2323
  assignAnnotation(carrier._SetAttributes, propName, propValue);
2327
2324
  if(removeFromType) {
@@ -56,11 +56,6 @@ function foreach(dictionary, filter, func) {
56
56
  });
57
57
  }
58
58
 
59
- // Call func(art, name) for each artifact 'art' with name 'name' in 'dictionary'
60
- function forAll(dictionary, func) {
61
- foreach(dictionary, ()=>true, func);
62
- }
63
-
64
59
  // true if _containerEntity is unequal to artifact name (non-recursive containment association)
65
60
  // or if artifact belongs to an artificial parameter entity
66
61
  function isContainee(artifact) {
@@ -68,27 +63,11 @@ function isContainee(artifact) {
68
63
  return (artifact._containerEntity && (artifact._containerEntity.length > 1 || artifact._containerEntity[0] != artifact.name));
69
64
  }
70
65
 
71
- // Return true if 'artifact' has an association type
72
- function isAssociation(artifact) {
73
- return (artifact.type === 'cds.Association' || artifact.type === 'Association') && artifact.target != undefined;
74
- //return artifact.target != undefined;
75
- }
76
-
77
66
  function isComposition(artifact) {
78
67
  return (artifact.type === 'cds.Composition' || artifact.type === 'Composition') &&
79
68
  artifact.target != undefined;
80
69
  }
81
70
 
82
- function isAssociationOrComposition(artifact)
83
- {
84
- return isAssociation(artifact) || isComposition(artifact);
85
- }
86
-
87
- function isManagedAssociation(artifact)
88
- {
89
- return isAssociation(artifact) && artifact.on == undefined;
90
- }
91
-
92
71
  // Return true if the association 'assoc' has cardinality 'to-many'
93
72
  function isToMany(assoc) {
94
73
  if (!assoc.cardinality) {
@@ -108,13 +87,8 @@ function isSingleton(entityCsn) {
108
87
  return singleton || ((singleton === undefined || singleton === null) && hasNullable);
109
88
  }
110
89
 
111
- function isEntity(artifact)
112
- {
113
- return artifact.kind === 'entity';
114
- }
115
-
116
90
  function isParameterizedEntity(artifact) {
117
- return isEntity(artifact) && artifact.params;
91
+ return artifact.kind === 'entity' && artifact.params;
118
92
  }
119
93
 
120
94
  // Return true if 'artifact' is structured (i.e. has elements, like a structured type or an entity)
@@ -132,10 +106,6 @@ function isDerivedType(artifact) {
132
106
  return artifact.kind === 'type' && !isStructuredArtifact(artifact);
133
107
  }
134
108
 
135
- function isActionOrFunction(artifact) {
136
- return artifact.kind === 'action' || artifact.kind === 'function';
137
- }
138
-
139
109
  function resolveOnConditionAndPrepareConstraints(csn, assocCsn, messageFunctions) {
140
110
  if(!assocCsn._constraints)
141
111
  throw Error('Please debug me: need _constraints');
@@ -175,7 +145,7 @@ function resolveOnConditionAndPrepareConstraints(csn, assocCsn, messageFunctions
175
145
  info(null, ['definitions', parentName, 'elements', assocCsn.name],
176
146
  `"${originParentName}:${partnerPath.join('.')}" with target "${originAssocCsn._target.name}" is compared with $self which represents "${parentName}"`);
177
147
  }
178
- if(isAssociationOrComposition(originAssocCsn)) {
148
+ if(originAssocCsn.target) {
179
149
  // Mark this association as backlink if $self appears exactly once
180
150
  // to surpress edm:Association generation in V2 mode
181
151
  if(isBacklink) {
@@ -345,7 +315,7 @@ function finalizeReferentialConstraints(csn, assocCsn, options, info)
345
315
  // in structured mode only resolve top level element (path rewriting is done elsewhere)
346
316
  const depEltName = ( options.isFlatFormat ? c[0].join('_') : c[0][0] );
347
317
  const principalEltName = ( options.isFlatFormat ? c[1].join('_') : c[1][0] );
348
- const fk = (isEntity(dependentEntity) && dependentEntity.elements[ depEltName ]) ||
318
+ const fk = (dependentEntity.kind === 'entity' && dependentEntity.elements[ depEltName ]) ||
349
319
  (localDepEntity && localDepEntity.elements && localDepEntity.elements[ depEltName ]);
350
320
  const pk = principalEntity.$keys && principalEntity.$keys[ principalEltName ];
351
321
  if(isConstraintCandidate(fk) && isConstraintCandidate(pk)) {
@@ -787,20 +757,14 @@ module.exports = {
787
757
  validateOptions,
788
758
  intersect,
789
759
  foreach,
790
- forAll,
791
760
  isContainee,
792
- isAssociation,
793
- isManagedAssociation,
794
761
  isComposition,
795
- isAssociationOrComposition,
796
762
  isToMany,
797
763
  isSingleton,
798
- isEntity,
799
764
  isStructuredType,
800
765
  isStructuredArtifact,
801
766
  isParameterizedEntity,
802
767
  isDerivedType,
803
- isActionOrFunction,
804
768
  resolveOnConditionAndPrepareConstraints,
805
769
  finalizeReferentialConstraints,
806
770
  determineMultiplicity,
@@ -1 +1 @@
1
- dd18d05cabbe93eabf1bd17b83add5ee
1
+ ca4caa65192cebc39f35cd598958dbb0