@sap/cds-compiler 5.1.2 → 5.3.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.
Files changed (68) hide show
  1. package/CHANGELOG.md +58 -0
  2. package/bin/cdsc.js +7 -2
  3. package/bin/cdshi.js +24 -17
  4. package/bin/cdsse.js +17 -18
  5. package/doc/CHANGELOG_BETA.md +9 -4
  6. package/lib/api/main.js +19 -2
  7. package/lib/api/options.js +4 -1
  8. package/lib/api/validate.js +5 -0
  9. package/lib/base/builtins.js +1 -0
  10. package/lib/base/message-registry.js +40 -3
  11. package/lib/base/messages.js +1 -1
  12. package/lib/base/model.js +0 -11
  13. package/lib/checks/actionsFunctions.js +0 -12
  14. package/lib/checks/structuredAnnoExpressions.js +10 -14
  15. package/lib/compiler/assert-consistency.js +21 -13
  16. package/lib/compiler/builtins.js +2 -2
  17. package/lib/compiler/checks.js +25 -6
  18. package/lib/compiler/define.js +27 -31
  19. package/lib/compiler/extend.js +16 -18
  20. package/lib/compiler/generate.js +3 -3
  21. package/lib/compiler/populate.js +22 -16
  22. package/lib/compiler/propagator.js +3 -2
  23. package/lib/compiler/resolve.js +87 -94
  24. package/lib/compiler/shared.js +12 -13
  25. package/lib/compiler/tweak-assocs.js +390 -86
  26. package/lib/compiler/utils.js +41 -33
  27. package/lib/compiler/xpr-rewrite.js +45 -58
  28. package/lib/edm/annotations/genericTranslation.js +17 -13
  29. package/lib/edm/csn2edm.js +28 -4
  30. package/lib/edm/edm.js +68 -28
  31. package/lib/edm/edmInboundChecks.js +5 -8
  32. package/lib/edm/edmPreprocessor.js +66 -40
  33. package/lib/edm/edmUtils.js +1 -1
  34. package/lib/gen/BaseParser.js +778 -0
  35. package/lib/gen/CdlParser.js +4477 -0
  36. package/lib/gen/language.checksum +1 -1
  37. package/lib/gen/language.interp +1 -1
  38. package/lib/gen/languageParser.js +4072 -4024
  39. package/lib/inspect/inspectPropagation.js +1 -1
  40. package/lib/json/from-csn.js +5 -3
  41. package/lib/json/to-csn.js +7 -10
  42. package/lib/language/antlrParser.js +96 -0
  43. package/lib/language/errorStrategy.js +1 -1
  44. package/lib/language/genericAntlrParser.js +32 -4
  45. package/lib/language/multiLineStringParser.js +1 -1
  46. package/lib/main.d.ts +23 -0
  47. package/lib/model/cloneCsn.js +22 -13
  48. package/lib/model/csnUtils.js +2 -0
  49. package/lib/model/revealInternalProperties.js +2 -0
  50. package/lib/modelCompare/utils/filter.js +70 -42
  51. package/lib/optionProcessor.js +16 -10
  52. package/lib/parsers/AstBuildingParser.js +1290 -0
  53. package/lib/parsers/CdlGrammar.g4 +2013 -0
  54. package/lib/parsers/Lexer.js +249 -0
  55. package/lib/render/toCdl.js +46 -45
  56. package/lib/render/toSql.js +5 -5
  57. package/lib/transform/addTenantFields.js +4 -4
  58. package/lib/transform/db/applyTransformations.js +54 -16
  59. package/lib/transform/draft/odata.js +10 -11
  60. package/lib/transform/effective/flattening.js +10 -14
  61. package/lib/transform/forRelationalDB.js +7 -6
  62. package/lib/transform/odata/flattening.js +42 -31
  63. package/lib/transform/odata/toFinalBaseType.js +7 -6
  64. package/lib/transform/universalCsn/universalCsnEnricher.js +1 -0
  65. package/lib/utils/moduleResolve.js +1 -1
  66. package/package.json +2 -2
  67. package/share/messages/redirected-to-ambiguous.md +5 -4
  68. package/share/messages/redirected-to-complex.md +6 -3
package/lib/edm/edm.js CHANGED
@@ -31,6 +31,7 @@ function getEdm( options, messageFunctions ) {
31
31
  this._edmAttributes = Object.assign(Object.create(null), attributes);
32
32
  this._xmlOnlyAttributes = Object.create(null);
33
33
  this._jsonOnlyAttributes = Object.create(null);
34
+ this._openApiHints = Object.create(null);
34
35
 
35
36
  this._children = [];
36
37
  this._ignoreChildren = false;
@@ -38,6 +39,8 @@ function getEdm( options, messageFunctions ) {
38
39
 
39
40
  if (this.v2)
40
41
  this.setSapVocabularyAsAttributes(csn);
42
+
43
+ this.setOpenApiHints(csn);
41
44
  }
42
45
 
43
46
  get v2() {
@@ -103,6 +106,17 @@ function getEdm( options, messageFunctions ) {
103
106
  return this;
104
107
  }
105
108
 
109
+ setOpenApiHints(csn) {
110
+ if (csn && options.odataOpenapiHints) {
111
+ const jsonAttr = Object.create(null);
112
+ Object.entries(csn).filter(([ k, _v ] ) => k.startsWith('@OpenAPI.')).forEach(([ k, v ]) => {
113
+ jsonAttr[k] = v;
114
+ });
115
+ Object.assign(this._openApiHints, jsonAttr);
116
+ }
117
+ return this._openApiHints;
118
+ }
119
+
106
120
  // virtual
107
121
  toJSON() {
108
122
  const json = Object.create(null);
@@ -110,17 +124,24 @@ function getEdm( options, messageFunctions ) {
110
124
  if (!(this.kind in Node.noJsonKinds))
111
125
  json.$Kind = this.kind;
112
126
 
113
- this.toJSONattributes(json);
114
- this.toJSONchildren(json);
115
- return json;
127
+ return this.toJSONchildren(this.toJSONattributes(json));
116
128
  }
117
129
 
118
130
  // virtual
119
- toJSONattributes(json) {
131
+ toJSONattributes(json, withHints = true) {
120
132
  forEach(this._edmAttributes, (p, v) => {
121
133
  if (p !== 'Name')
122
134
  json[p[0] === '@' ? p : `$${p}`] = v;
123
135
  });
136
+ return (withHints ? this.toOpenApiHints(json) : json);
137
+ }
138
+
139
+ toOpenApiHints(json) {
140
+ if (options.odataOpenapiHints && this._openApiHints) {
141
+ Object.entries(this._openApiHints).forEach(([ p, v ]) => {
142
+ json[p[0] === '@' ? p : `$${p}`] = v;
143
+ });
144
+ }
124
145
  return json;
125
146
  }
126
147
 
@@ -131,6 +152,7 @@ function getEdm( options, messageFunctions ) {
131
152
  this._children.filter(c => c._edmAttributes.Name).forEach((c) => {
132
153
  json[c._edmAttributes.Name] = c.toJSON();
133
154
  });
155
+ return json;
134
156
  }
135
157
 
136
158
  // virtual
@@ -243,6 +265,10 @@ function getEdm( options, messageFunctions ) {
243
265
  super.setSapVocabularyAsAttributes(csn, true);
244
266
  }
245
267
 
268
+ toJSONattributes(json) {
269
+ return super.toJSONattributes(json, false);
270
+ }
271
+
246
272
  register(entry) {
247
273
  if (!this._registry[entry._edmAttributes.Name])
248
274
  this._registry[entry._edmAttributes.Name] = [ entry ];
@@ -258,6 +284,7 @@ function getEdm( options, messageFunctions ) {
258
284
  if (alias !== undefined)
259
285
  props.Alias = alias;
260
286
  super(version, props);
287
+ this.setOpenApiHints(serviceCsn);
261
288
  this._annotations = annotations;
262
289
  this._actions = Object.create(null);
263
290
  this.setXml( { xmlns: (this.v2) ? 'http://schemas.microsoft.com/ado/2008/09/edm' : 'http://docs.oasis-open.org/odata/ns/edm' } );
@@ -321,11 +348,17 @@ function getEdm( options, messageFunctions ) {
321
348
  json[p[0] === '@' ? p : `$${p}`] = v;
322
349
  });
323
350
  }
351
+ return this.toOpenApiHints(json);
324
352
  }
325
353
 
326
354
  toJSONchildren(json) {
327
355
  // 'edmx:DataServices' should not appear in JSON
328
- super.toJSONchildren(json);
356
+ // Annotations first
357
+ this._children.filter(c => c._edmAttributes.Term).forEach((c) => {
358
+ json = { ...json, ...c.toJSON() };
359
+ });
360
+
361
+ json = super.toJSONchildren(json);
329
362
  if (this._annotations.length > 0) {
330
363
  this._annotations.filter(a => a._edmAttributes.Term).forEach((a) => {
331
364
  Object.entries(a.toJSON()).forEach(([ n, v ]) => {
@@ -445,8 +478,7 @@ function getEdm( options, messageFunctions ) {
445
478
  json.$Reference = referenceJson;
446
479
 
447
480
  this._service.toJSONattributes(json);
448
- this._service.toJSONchildren(json);
449
- return json;
481
+ return this._service.toJSONchildren(json);
450
482
  }
451
483
 
452
484
  // all(default), metadata, annotations
@@ -546,8 +578,8 @@ function getEdm( options, messageFunctions ) {
546
578
  */
547
579
 
548
580
  class ActionFunctionBase extends Node {
549
- constructor(version, details) {
550
- super(version, details);
581
+ constructor(version, details, csn) {
582
+ super(version, details, csn);
551
583
  this._returnType = undefined;
552
584
  }
553
585
 
@@ -698,7 +730,7 @@ function getEdm( options, messageFunctions ) {
698
730
  if (this.$isCollection)
699
731
  json.$Collection = this.$isCollection;
700
732
 
701
- return json;
733
+ return this.toOpenApiHints(json);
702
734
  }
703
735
  }
704
736
 
@@ -749,11 +781,11 @@ function getEdm( options, messageFunctions ) {
749
781
  else
750
782
  this._keys = undefined;
751
783
 
752
- if (options.odataOpenapiHints) {
784
+ if (this._openApiHints) {
753
785
  if (csn['@cds.autoexpose'])
754
- this.setJSON({ '@cds.autoexpose': true });
786
+ this._openApiHints['@cds.autoexpose'] = true;
755
787
  if (csn['@cds.autoexposed'])
756
- this.setJSON({ '@cds.autoexposed': true });
788
+ this._openApiHints['@cds.autoexposed'] = true;
757
789
  }
758
790
  }
759
791
 
@@ -802,7 +834,7 @@ function getEdm( options, messageFunctions ) {
802
834
  class Member extends Node {
803
835
  toJSONattributes(json) {
804
836
  json[this._edmAttributes.Name] = this._edmAttributes.Value;
805
- return json;
837
+ return super.toOpenApiHints(json);
806
838
  }
807
839
  }
808
840
 
@@ -819,11 +851,6 @@ function getEdm( options, messageFunctions ) {
819
851
  }
820
852
  }
821
853
 
822
- toJSONattributes(json) {
823
- super.toJSONattributes(json);
824
- return json;
825
- }
826
-
827
854
  toJSONchildren(json) {
828
855
  this._children.forEach(c => c.toJSONattributes(json));
829
856
  return json;
@@ -1154,8 +1181,11 @@ function getEdm( options, messageFunctions ) {
1154
1181
  toJSON() {
1155
1182
  const json = Object.create(null);
1156
1183
  this.toJSONattributes(json);
1157
- this.toJSONchildren(json);
1158
- return json;
1184
+ return this.toJSONchildren(json);
1185
+ }
1186
+
1187
+ toJSONattributes(json) {
1188
+ return super.toJSONattributes(json, false);
1159
1189
  }
1160
1190
 
1161
1191
  getConstantExpressionValue() {
@@ -1226,6 +1256,7 @@ function getEdm( options, messageFunctions ) {
1226
1256
  json[n] = v;
1227
1257
  });
1228
1258
  });
1259
+ return json;
1229
1260
  }
1230
1261
  }
1231
1262
 
@@ -1242,8 +1273,9 @@ function getEdm( options, messageFunctions ) {
1242
1273
  // since it was discovered, that in JSON the EnumMember type must be
1243
1274
  // transported this is no longer the case....
1244
1275
  class Annotation extends AnnotationBase {
1245
- constructor(version, termName) {
1276
+ constructor(version, termName, ...children) {
1246
1277
  super(version, { Term: termName } );
1278
+ this.append(...children);
1247
1279
  }
1248
1280
 
1249
1281
  toJSON() {
@@ -1263,6 +1295,11 @@ function getEdm( options, messageFunctions ) {
1263
1295
  }
1264
1296
 
1265
1297
  class Collection extends AnnotationBase {
1298
+ constructor(version, ...children) {
1299
+ super(version);
1300
+ this.append(...children);
1301
+ }
1302
+
1266
1303
  toJSON() {
1267
1304
  // EDM JSON doesn't mention annotations on collections
1268
1305
  return this._children.map(a => a.toJSON());
@@ -1270,12 +1307,17 @@ function getEdm( options, messageFunctions ) {
1270
1307
  }
1271
1308
 
1272
1309
  class Record extends AnnotationBase {
1310
+ constructor(version, ...children) {
1311
+ super(version);
1312
+ this.append(...children);
1313
+ }
1273
1314
  toJSONattributes(json) {
1274
1315
  if (this._jsonOnlyAttributes.Type)
1275
1316
  json['@type'] = this._jsonOnlyAttributes.Type;
1276
1317
  const keys = Object.keys(this._edmAttributes).filter(k => k !== 'Type');
1277
1318
  for (const key of keys)
1278
1319
  json[`$${key}`] = this._edmAttributes[key];
1320
+ return json;
1279
1321
  }
1280
1322
 
1281
1323
  toJSONchildren(json) {
@@ -1300,6 +1342,7 @@ function getEdm( options, messageFunctions ) {
1300
1342
  error(null, `Pease debug me: Unhandled Record child: ${c.kind}`);
1301
1343
  }
1302
1344
  });
1345
+ return json;
1303
1346
  }
1304
1347
  }
1305
1348
 
@@ -1382,8 +1425,7 @@ function getEdm( options, messageFunctions ) {
1382
1425
  toJSON() {
1383
1426
  const json = this.mergeJSONAnnotations();
1384
1427
  json[`$${this.kind}`] = this._children.filter(c => c.kind !== 'Annotation').map(c => c.toJSON());
1385
- this.toJSONattributes(json);
1386
- return json;
1428
+ return this.toJSONattributes(json);
1387
1429
  }
1388
1430
  }
1389
1431
  class Cast extends AnnotationBase {
@@ -1402,8 +1444,7 @@ function getEdm( options, messageFunctions ) {
1402
1444
  // first expression only, if any
1403
1445
  const children = this._children.filter(child => child.kind !== 'Annotation');
1404
1446
  json[`$${this.kind}`] = children.length ? children[0].toJSON() : {};
1405
- this.toJSONattributes(json);
1406
- return json;
1447
+ return this.toJSONattributes(json);
1407
1448
  }
1408
1449
  toJSONattributes(json) {
1409
1450
  super.toJSONattributes(json);
@@ -1430,8 +1471,7 @@ function getEdm( options, messageFunctions ) {
1430
1471
  // first expression only, if any
1431
1472
  const children = this._children.filter(child => child.kind !== 'Annotation');
1432
1473
  json[`$${this.kind}`] = children.length ? children[0].toJSON() : '';
1433
- this.toJSONattributes(json);
1434
- return json;
1474
+ return this.toJSONattributes(json);
1435
1475
  }
1436
1476
 
1437
1477
  toJSONattributes(json) { // including Name
@@ -3,7 +3,7 @@
3
3
  const { setProp, isBetaEnabled } = require('../base/model');
4
4
  const {
5
5
  forEachDefinition, forEachMemberRecursively, getUtils,
6
- transformExpression, findAnnotationExpression,
6
+ transformAnnotationExpression,
7
7
  } = require('../model/csnUtils');
8
8
  const { isBuiltinType } = require('../base/builtins');
9
9
  const { assignAnnotation } = require('./edmUtils.js');
@@ -59,7 +59,6 @@ function inboundQualificationChecks( csn, options, messageFunctions,
59
59
  markBindingParamPaths(action, aLoc);
60
60
  forEachMemberRecursively(action, checkIfItemsOfItems, aLoc);
61
61
  checkIfItemsOfItems(action.returns, undefined, undefined, aLoc.concat('returns'));
62
- markBindingParamPaths(action, aLoc);
63
62
  });
64
63
  }
65
64
 
@@ -144,14 +143,12 @@ function inboundQualificationChecks( csn, options, messageFunctions,
144
143
  parent.$bparam = true;
145
144
  },
146
145
  };
147
- let exprAnnos = Object.keys(action).filter(pn => findAnnotationExpression(action, pn));
148
- exprAnnos.forEach((pn) => {
149
- transformExpression(action, pn, markBindingParam, loc);
146
+ Object.keys(action).filter(pn => pn[0] === '@').forEach((pn) => {
147
+ transformAnnotationExpression(action, pn, markBindingParam, loc);
150
148
  });
151
149
  forEachMemberRecursively(action, (member, _memberName, _prop, path, _parent) => {
152
- exprAnnos = Object.keys(member).filter(pn => findAnnotationExpression(member, pn));
153
- exprAnnos.forEach((pn) => {
154
- transformExpression(member, pn, markBindingParam, path);
150
+ Object.keys(member).filter(pn => pn[0] === '@').forEach((pn) => {
151
+ transformAnnotationExpression(member, pn, markBindingParam, path);
155
152
  });
156
153
  }, loc);
157
154
  }
@@ -5,7 +5,7 @@ const { setProp, isDeprecatedEnabled, isBetaEnabled } = require('../base/model')
5
5
  const {
6
6
  forEachDefinition, forEachGeneric, forEachMemberRecursively,
7
7
  isEdmPropertyRendered, getUtils,
8
- applyTransformations, transformExpression, findAnnotationExpression,
8
+ applyTransformations, transformAnnotationExpression, findAnnotationExpression,
9
9
  cardinality2str,
10
10
  } = require('../model/csnUtils');
11
11
  const { isBuiltinType, isMagicVariable } = require('../base/builtins');
@@ -160,6 +160,7 @@ function initializeModel( csn, _options, messageFunctions, requestedServiceNames
160
160
  forEachDefinition(reqDefs, [
161
161
  exposeTargetsAsProxiesOrSchemaRefs,
162
162
  determineEntitySet,
163
+ annotateOptionalActFuncParams,
163
164
  ]);
164
165
  // finalize proxy creation
165
166
  mergeProxiesIntoModel();
@@ -170,7 +171,6 @@ function initializeModel( csn, _options, messageFunctions, requestedServiceNames
170
171
  forEachDefinition(reqDefs, [
171
172
  initEdmNavPropBindingTargets,
172
173
  pullupCapabilitiesAnnotations,
173
- annotateOptionalActFuncParams,
174
174
  ]);
175
175
  }
176
176
 
@@ -685,8 +685,8 @@ function initializeModel( csn, _options, messageFunctions, requestedServiceNames
685
685
  return;
686
686
 
687
687
  let keys = Object.create(null);
688
- const validFrom = []; const
689
- validKey = [];
688
+ const validFrom = [];
689
+ const validKey = [];
690
690
 
691
691
  // Iterate all struct elements
692
692
  forEachMemberRecursively(def.items || def, (element, elementName, prop, _path, construct) => {
@@ -796,7 +796,7 @@ function initializeModel( csn, _options, messageFunctions, requestedServiceNames
796
796
  Do not render (ignore) elements as properties
797
797
  In V4:
798
798
  1) If this is a foreign key of an association to a container which *is* used
799
- to establish the containment via composition and $self comparison.
799
+ to establish the relation via composition and $self comparison.
800
800
  The $self comparison can only be evaluated after the ON conditions have been
801
801
  parsed in prepareConstraints().
802
802
  2) For all other foreign keys let isEdmPropertyRendered() decide.
@@ -1890,12 +1890,12 @@ function initializeModel( csn, _options, messageFunctions, requestedServiceNames
1890
1890
  mapCdsToEdmProp(def.returns);
1891
1891
  annotateAllowedValues(def.returns, [ ...defLocation, 'returns' ]);
1892
1892
  }
1893
- forEachMemberRecursively(def, (member, _memberName, _prop, location) => {
1893
+ forEachMemberRecursively(def, (member, _memberName, prop, location) => {
1894
1894
  edmUtils.assignAnnotation(member, '@Core.Description', member.doc);
1895
1895
  markCollection(member);
1896
1896
  mapCdsToEdmProp(member);
1897
1897
  annotateAllowedValues(member, location);
1898
- ComputedDefaultValue(member);
1898
+ ComputedDefaultValue(member, prop, location);
1899
1899
  rewriteAnnotationExpressions(member);
1900
1900
  if (member.returns) {
1901
1901
  edmUtils.assignAnnotation(member.returns, '@Core.Description', member.returns.doc);
@@ -2082,8 +2082,6 @@ function initializeModel( csn, _options, messageFunctions, requestedServiceNames
2082
2082
  parameters appear rightmost.
2083
2083
  */
2084
2084
  function annotateOptionalActFuncParams( def, defName ) {
2085
- if (!isBetaEnabled(options, 'optionalActionFunctionParameters'))
2086
- return;
2087
2085
  // return if there is nothing to do
2088
2086
  const loc = [ 'definitions', defName ];
2089
2087
  if (def.kind === 'function' || def.kind === 'action')
@@ -2097,33 +2095,57 @@ function initializeModel( csn, _options, messageFunctions, requestedServiceNames
2097
2095
 
2098
2096
  function iterateParams( action, location ) {
2099
2097
  let optPns = [];
2098
+ const isBP = p => (p.items?.type || p.type) === special$self;
2099
+
2100
2100
  if (action.params) {
2101
- Object.values(action.params).forEach((p) => {
2102
- // user assigned annotation, don't touch it
2103
- if (Object.keys(p).some(a => a.startsWith('@Core.OptionalParameter') && p[a] !== null)) {
2104
- optPns.push(p);
2105
- }
2106
- // default value automatically makes param optional
2107
- else if (p.default) {
2108
- if (p.default.val)
2109
- edmUtils.assignAnnotation(p, '@Core.OptionalParameter.DefaultValue', p.default.val);
2110
- else
2111
- edmUtils.assignAnnotation(p, '@Core.OptionalParameter.$Type', '');
2112
- optPns.push(p);
2113
- }
2114
- // if no default is available, nullable makes param optional
2115
- else if (!p.notNull) {
2116
- edmUtils.assignAnnotation(p, '@Core.OptionalParameter.$Type', '');
2117
- optPns.push(p);
2101
+ Object.entries(action.params).forEach(([ pn, p ]) => {
2102
+ // user assigned annotation, don't touch it
2103
+ const defT = reqDefs.definitions[p.items?.type || p.type];
2104
+ const isStructType = !!(defT?.items?.elements || defT?.elements);
2105
+ const isItems = !!(p.items || defT?.items);
2106
+
2107
+ if (Object.keys(p).some(a => a.startsWith('@Core.OptionalParameter') && p[a] != null)) {
2108
+ // expand short cut annotation for unspecified default value
2109
+ if (typeof p['@Core.OptionalParameter'] === 'boolean') {
2110
+ if (p['@Core.OptionalParameter'] && !isBP(p) && !options.isV2()) {
2111
+ if (p.default?.val !== undefined) {
2112
+ if (p.default.val !== null && (isStructType || isItems))
2113
+ warning('odata-ignoring-param-default', location.concat(pn), { '#': 'colitem' });
2114
+ else
2115
+ p['@Core.OptionalParameter'] = { DefaultValue: p.default.val };
2116
+ }
2117
+ else {
2118
+ p['@Core.OptionalParameter'] = { $Type: '' };
2119
+ }
2120
+ optPns.push(p);
2121
+ }
2122
+ else { // reset falsy annotation, param is NOT optional
2123
+ p['@Core.OptionalParameter'] = null;
2124
+ }
2125
+ }
2126
+ else {
2127
+ optPns.push(p);
2128
+ }
2118
2129
  }
2119
- else {
2120
- // this is a mandatory parameter, warn about all previously collected optional parameters
2121
- optPns.forEach((op) => {
2122
- const type = op.items?.type || op.type;
2123
- if (type !== special$self)
2124
- error('odata-parameter-order', location.concat(op.name));
2125
- });
2126
- optPns = [];
2130
+ else if (!isBP(p) && !options.isV2()) {
2131
+ // default value automatically makes param optional
2132
+ if (p.default?.val !== undefined) {
2133
+ if (p.default.val !== null && (isStructType || isItems))
2134
+ warning('odata-ignoring-param-default', location.concat(pn), { '#': 'colitem' });
2135
+ else
2136
+ edmUtils.assignAnnotation(p, '@Core.OptionalParameter.DefaultValue', p.default.val);
2137
+ optPns.push(p);
2138
+ }
2139
+ // nullable action params are optional (implicit default null)
2140
+ else if (!p.notNull && action.kind === 'action') {
2141
+ optPns.push(p);
2142
+ }
2143
+ else if (action.kind === 'function') {
2144
+ // this is a mandatory parameter, warn about all previously collected optional parameters
2145
+ if (optPns.filter(op => (op.items?.type || op.type) !== special$self).length)
2146
+ error('odata-parameter-order', location.concat(pn));
2147
+ optPns = [];
2148
+ }
2127
2149
  }
2128
2150
  });
2129
2151
  }
@@ -2152,7 +2174,7 @@ function initializeModel( csn, _options, messageFunctions, requestedServiceNames
2152
2174
  }
2153
2175
  }
2154
2176
 
2155
- function ComputedDefaultValue( member ) {
2177
+ function ComputedDefaultValue( member, prop, location ) {
2156
2178
  if (member.default && !csn['@Core.ComputedDefaultValue']) {
2157
2179
  let def = member.default;
2158
2180
  let noTailExpr = false;
@@ -2166,8 +2188,12 @@ function initializeModel( csn, _options, messageFunctions, requestedServiceNames
2166
2188
  def = def.xpr[i];
2167
2189
  }
2168
2190
  // it is a computed value if it is not a simple value or an annotation
2169
- if (!((def.val !== undefined && !noTailExpr) || def['#']))
2170
- edmUtils.assignAnnotation(member, '@Core.ComputedDefaultValue', true);
2191
+ if (!((def.val !== undefined && !noTailExpr) || def['#'])) {
2192
+ if (prop === 'params')
2193
+ warning('odata-ignoring-param-default', location, { '#': 'xpr' });
2194
+ else
2195
+ edmUtils.assignAnnotation(member, '@Core.ComputedDefaultValue', true);
2196
+ }
2171
2197
  }
2172
2198
  }
2173
2199
 
@@ -2258,13 +2284,13 @@ function initializeModel( csn, _options, messageFunctions, requestedServiceNames
2258
2284
 
2259
2285
  xprANames.forEach((xprAName) => {
2260
2286
  isSubTreeSpan = true;
2261
- transformExpression(carrier, xprAName, subTreeSpan);
2287
+ transformAnnotationExpression(carrier, xprAName, subTreeSpan);
2262
2288
  if (isSubTreeSpan) {
2263
- transformExpression(carrier, xprAName, relativize);
2289
+ transformAnnotationExpression(carrier, xprAName, relativize);
2264
2290
  }
2265
2291
  else {
2266
2292
  absolutize.scope = scope;
2267
- transformExpression(carrier, xprAName, absolutize);
2293
+ transformAnnotationExpression(carrier, xprAName, absolutize);
2268
2294
  if (!def[proxyDict])
2269
2295
  setProp(def, proxyDict, Object.create(null));
2270
2296
  let proxyCarrier = def[proxyDict][eltPath];
@@ -386,7 +386,7 @@ function finalizeReferentialConstraints( csn, assocCsn, options, info ) {
386
386
  // If this association points to a redirected Parameter EntityType, do not calculate any constraints,
387
387
  // continue with multiplicity
388
388
  if (assocCsn._target.$isParamEntity)
389
- assocCsn._constraints.constraints = Object.create(null);
389
+ assocCsn._constraints.constraints = {};
390
390
 
391
391
  return assocCsn._constraints;
392
392