@sap/cds-compiler 2.15.2 → 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 (111) hide show
  1. package/CHANGELOG.md +66 -1590
  2. package/bin/cdsc.js +42 -46
  3. package/doc/CHANGELOG_ARCHIVE.md +1592 -0
  4. package/doc/CHANGELOG_BETA.md +3 -4
  5. package/doc/CHANGELOG_DEPRECATED.md +35 -1
  6. package/doc/{DeprecatedOptions.md → DeprecatedOptions_v2.md} +3 -1
  7. package/doc/Versioning.md +20 -1
  8. package/lib/api/.eslintrc.json +2 -2
  9. package/lib/api/main.js +312 -143
  10. package/lib/api/options.js +15 -85
  11. package/lib/api/validate.js +6 -10
  12. package/lib/base/keywords.js +280 -110
  13. package/lib/base/message-registry.js +80 -24
  14. package/lib/base/messages.js +103 -52
  15. package/lib/base/model.js +44 -2
  16. package/lib/base/optionProcessorHelper.js +53 -21
  17. package/lib/checks/actionsFunctions.js +7 -5
  18. package/lib/checks/annotationsOData.js +1 -1
  19. package/lib/checks/cdsPersistence.js +1 -0
  20. package/lib/checks/elements.js +6 -6
  21. package/lib/checks/invalidTarget.js +1 -1
  22. package/lib/checks/nonexpandableStructured.js +1 -1
  23. package/lib/checks/queryNoDbArtifacts.js +2 -1
  24. package/lib/checks/selectItems.js +5 -1
  25. package/lib/checks/types.js +4 -2
  26. package/lib/checks/utils.js +2 -2
  27. package/lib/checks/validator.js +2 -1
  28. package/lib/compiler/assert-consistency.js +15 -10
  29. package/lib/compiler/builtins.js +127 -10
  30. package/lib/compiler/define.js +6 -4
  31. package/lib/compiler/extend.js +63 -12
  32. package/lib/compiler/finalize-parse-cdl.js +20 -9
  33. package/lib/compiler/index.js +25 -11
  34. package/lib/compiler/moduleLayers.js +7 -0
  35. package/lib/compiler/populate.js +16 -14
  36. package/lib/compiler/propagator.js +3 -3
  37. package/lib/compiler/resolve.js +194 -222
  38. package/lib/compiler/shared.js +56 -76
  39. package/lib/compiler/tweak-assocs.js +9 -10
  40. package/lib/compiler/utils.js +7 -2
  41. package/lib/edm/annotations/genericTranslation.js +60 -6
  42. package/lib/edm/annotations/preprocessAnnotations.js +10 -11
  43. package/lib/edm/csn2edm.js +39 -41
  44. package/lib/edm/edm.js +22 -15
  45. package/lib/edm/edmPreprocessor.js +66 -69
  46. package/lib/edm/edmUtils.js +12 -62
  47. package/lib/gen/Dictionary.json +8 -6
  48. package/lib/gen/language.checksum +1 -1
  49. package/lib/gen/language.interp +8 -30
  50. package/lib/gen/language.tokens +105 -114
  51. package/lib/gen/languageLexer.interp +1 -34
  52. package/lib/gen/languageLexer.js +889 -1007
  53. package/lib/gen/languageLexer.tokens +95 -106
  54. package/lib/gen/languageParser.js +20717 -22376
  55. package/lib/json/from-csn.js +73 -68
  56. package/lib/json/to-csn.js +13 -10
  57. package/lib/language/antlrParser.js +2 -2
  58. package/lib/language/docCommentParser.js +61 -38
  59. package/lib/language/errorStrategy.js +52 -40
  60. package/lib/language/genericAntlrParser.js +333 -259
  61. package/lib/language/language.g4 +600 -645
  62. package/lib/language/multiLineStringParser.js +14 -42
  63. package/lib/language/textUtils.js +44 -0
  64. package/lib/main.d.ts +27 -42
  65. package/lib/main.js +104 -81
  66. package/lib/model/csnRefs.js +2 -1
  67. package/lib/model/csnUtils.js +183 -285
  68. package/lib/model/revealInternalProperties.js +32 -9
  69. package/lib/model/sortViews.js +32 -31
  70. package/lib/optionProcessor.js +64 -57
  71. package/lib/render/.eslintrc.json +1 -1
  72. package/lib/render/DuplicateChecker.js +4 -7
  73. package/lib/render/manageConstraints.js +70 -2
  74. package/lib/render/toCdl.js +334 -339
  75. package/lib/render/toHdbcds.js +20 -16
  76. package/lib/render/toRename.js +44 -22
  77. package/lib/render/toSql.js +60 -54
  78. package/lib/render/utils/common.js +15 -1
  79. package/lib/render/utils/sql.js +20 -19
  80. package/lib/sql-identifier.js +6 -0
  81. package/lib/transform/db/.eslintrc.json +3 -2
  82. package/lib/transform/db/cdsPersistence.js +5 -15
  83. package/lib/transform/db/constraints.js +1 -1
  84. package/lib/transform/db/expansion.js +7 -6
  85. package/lib/transform/db/flattening.js +18 -19
  86. package/lib/transform/db/views.js +3 -3
  87. package/lib/transform/draft/.eslintrc.json +2 -2
  88. package/lib/transform/draft/db.js +6 -6
  89. package/lib/transform/draft/odata.js +6 -7
  90. package/lib/transform/forHanaNew.js +19 -22
  91. package/lib/transform/forOdataNew.js +13 -15
  92. package/lib/transform/localized.js +35 -25
  93. package/lib/transform/odata/toFinalBaseType.js +11 -9
  94. package/lib/transform/odata/typesExposure.js +3 -3
  95. package/lib/transform/odata/utils.js +1 -38
  96. package/lib/transform/transformUtilsNew.js +63 -77
  97. package/lib/transform/translateAssocsToJoins.js +6 -2
  98. package/lib/transform/universalCsn/.eslintrc.json +2 -2
  99. package/lib/transform/universalCsn/coreComputed.js +11 -6
  100. package/lib/transform/universalCsn/universalCsnEnricher.js +33 -5
  101. package/lib/utils/file.js +31 -21
  102. package/lib/utils/timetrace.js +20 -21
  103. package/package.json +34 -4
  104. package/share/messages/syntax-expected-integer.md +9 -8
  105. package/doc/ApiMigration.md +0 -237
  106. package/doc/CommandLineMigration.md +0 -58
  107. package/doc/ErrorMessages.md +0 -175
  108. package/doc/FioriAnnotations.md +0 -94
  109. package/doc/ODataTransformation.md +0 -273
  110. package/lib/backends.js +0 -529
  111. package/lib/fix_antlr4-8_warning.js +0 -56
@@ -88,6 +88,7 @@
88
88
  */
89
89
 
90
90
  const { dictAdd } = require('../base/dictionaries');
91
+ const { quotedLiteralPatterns } = require('../compiler/builtins');
91
92
 
92
93
  const $location = Symbol.for('cds.$location');
93
94
 
@@ -135,7 +136,7 @@ const schemaClasses = {
135
136
  condition: {
136
137
  arrayOf: exprOrString,
137
138
  type: condition,
138
- msgId: 'syntax-csn-expected-term',
139
+ msgId: 'syntax-expected-term',
139
140
  // TODO: also specify requires here, and adapt onlyWith()
140
141
  optional: exprProperties,
141
142
  },
@@ -145,11 +146,11 @@ const schemaClasses = {
145
146
  },
146
147
  natnumOrStar: {
147
148
  type: natnumOrStar,
148
- msgId: 'syntax-csn-expected-cardinality',
149
+ msgId: 'syntax-expected-cardinality',
149
150
  },
150
151
  columns: {
151
152
  arrayOf: selectItem,
152
- msgId: 'syntax-csn-expected-column',
153
+ msgId: 'syntax-expected-column',
153
154
  defaultKind: '$column',
154
155
  validKinds: [], // pseudo kind '$column'
155
156
  // A column with only as+cast.type is a new association
@@ -290,7 +291,7 @@ const schema = compileSchema( {
290
291
  // type properties (except: elements, enum, keys, on): ---------------------
291
292
  type: {
292
293
  type: artifactRef,
293
- msgId: 'syntax-csn-expected-reference',
294
+ msgId: 'syntax-expected-reference',
294
295
  optional: [ 'ref', 'global' ],
295
296
  inKind: [ 'element', 'type', 'param', 'mixin', 'event', 'annotation' ],
296
297
  },
@@ -366,7 +367,7 @@ const schema = compileSchema( {
366
367
  ref: {
367
368
  arrayOf: refItem,
368
369
  type: renameTo( 'path', arrayOf( refItem ) ),
369
- msgId: 'syntax-csn-expected-reference',
370
+ msgId: 'syntax-expected-reference',
370
371
  minLength: 1,
371
372
  requires: 'id',
372
373
  optional: [ 'id', 'args', 'cardinality', 'where' ],
@@ -582,7 +583,7 @@ const schema = compileSchema( {
582
583
  inKind: [ 'element', '$column' ],
583
584
  },
584
585
  masked: {
585
- type: boolOrNull,
586
+ type: masked,
586
587
  inKind: [ 'element' ],
587
588
  },
588
589
  notNull: {
@@ -682,15 +683,6 @@ const topLevelSpec = {
682
683
  schema,
683
684
  };
684
685
 
685
- const validLiteralsExtra = Object.assign( Object.create(null), {
686
- // TODO: should we use quotedLiteralPatterns from genericAntlrParser?
687
- number: 'string',
688
- x: 'string',
689
- time: 'string',
690
- date: 'string',
691
- timestamp: 'string',
692
- } );
693
-
694
686
  // Module variables, schema compilation, and functors ------------------------
695
687
 
696
688
  /** @type {(id, location, textOrArguments, texts?) => void} */
@@ -779,7 +771,7 @@ function arrayOf( fn, filter = undefined ) {
779
771
  } );
780
772
  const minLength = spec.minLength || 0;
781
773
  if (minLength > val.length) {
782
- message( 'syntax-csn-expected-length', location(true),
774
+ message( 'syntax-expected-length', location(true),
783
775
  { prop: spec.prop, n: minLength, '#': minLength === 1 ? 'one' : 'std' });
784
776
  }
785
777
  if (val.length)
@@ -849,7 +841,7 @@ function object( obj, spec ) {
849
841
  if (requires === undefined || requires === true) {
850
842
  // console.log(csnProps,JSON.stringify(spec))
851
843
  if (!relevantProps) {
852
- error( 'syntax-csn-required-subproperty', location(true),
844
+ error( 'syntax-required-subproperty', location(true),
853
845
  {
854
846
  prop: spec.msgProp,
855
847
  '#': (
@@ -875,7 +867,7 @@ function object( obj, spec ) {
875
867
 
876
868
  function vZeroDelete( o, spec ) { // for old-CSN property 'origin'
877
869
  if (!csnVersionZero) {
878
- warning( 'syntax-csn-zero-delete', location(true), { prop: spec.msgProp },
870
+ warning( 'syntax-zero-delete', location(true), { prop: spec.msgProp },
879
871
  'Delete/inline CSN v0.1.0 property $(PROP)' );
880
872
  }
881
873
  string( o, spec );
@@ -960,7 +952,7 @@ function definition( def, spec, xsn, csn, name ) {
960
952
  function dictionaryOf( elementFct ) {
961
953
  return function dictionary( dict, spec ) {
962
954
  if (!dict || typeof dict !== 'object' || Array.isArray( dict )) {
963
- error( 'syntax-csn-expected-object', location(true),
955
+ error( 'syntax-expected-object', location(true),
964
956
  { prop: spec.prop }); // spec.prop, not spec.msgProp!
965
957
  return ignore( dict );
966
958
  }
@@ -972,7 +964,7 @@ function dictionaryOf( elementFct ) {
972
964
  ++virtualLine;
973
965
  for (const name of allNames) {
974
966
  if (!name) {
975
- warning( 'syntax-csn-empty-name', location(true),
967
+ warning( 'syntax-empty-name', location(true),
976
968
  { prop: spec.prop }, // TODO: Error
977
969
  'Property names in dictionary $(PROP) must not be empty' );
978
970
  }
@@ -1049,11 +1041,11 @@ function validKind( val, spec, xsn ) {
1049
1041
  if (val === xsn.kind) // has been set in definition - the same = ok!
1050
1042
  return undefined; // already set in definition
1051
1043
  if (val === 'view' && xsn.kind === 'entity') {
1052
- warning( 'syntax-csn-zero-value', location(true), { prop: spec.msgProp },
1044
+ warning( 'syntax-zero-value', location(true), { prop: spec.msgProp },
1053
1045
  'Replace CSN v0.1.0 value in $(PROP) by something specified' );
1054
1046
  }
1055
1047
  else if ((val === 'entity' || val === 'type') && xsn.kind === 'aspect') {
1056
- info( 'syntax-csn-aspect', location(true), { kind: 'aspect', '#': val },
1048
+ info( 'syntax-aspect', location(true), { kind: 'aspect', '#': val },
1057
1049
  {
1058
1050
  std: 'Use the dedicated kind $(KIND) for aspect definitions',
1059
1051
  // eslint-disable-next-line max-len
@@ -1061,7 +1053,7 @@ function validKind( val, spec, xsn ) {
1061
1053
  } );
1062
1054
  }
1063
1055
  else {
1064
- error( 'syntax-csn-expected-valid', location(true), { prop: spec.msgProp },
1056
+ error( 'syntax-expected-valid', location(true), { prop: spec.msgProp },
1065
1057
  'Expected valid string for property $(PROP)' );
1066
1058
  }
1067
1059
  return ignore( val );
@@ -1103,7 +1095,7 @@ function vZeroRef( name, spec, xsn ) {
1103
1095
  return;
1104
1096
  const path = name.split('.');
1105
1097
  if (!path.every( id => id)) {
1106
- warning( 'syntax-csn-expected-name', location(true), { prop: spec.msgProp },
1098
+ warning( 'syntax-expected-name', location(true), { prop: spec.msgProp },
1107
1099
  'Expected correct name for property $(PROP)' );
1108
1100
  }
1109
1101
  xsn.path = path.map( id => ({ id, location: location() }) );
@@ -1114,7 +1106,7 @@ function vZeroRef( name, spec, xsn ) {
1114
1106
  function boolOrNull( val, spec ) {
1115
1107
  if ([ true, false, null ].includes( val ))
1116
1108
  return { val, location: location() };
1117
- warning( 'syntax-csn-expected-boolean', location(true), { prop: spec.msgProp },
1109
+ warning( 'syntax-expected-boolean', location(true), { prop: spec.msgProp },
1118
1110
  'Expected boolean or null for property $(PROP)' );
1119
1111
  ignore( val );
1120
1112
  return { val: !!val, location: location() };
@@ -1124,7 +1116,7 @@ function string( val, spec ) {
1124
1116
  if (typeof val === 'string' && val)
1125
1117
  // XSN TODO: do not require literal
1126
1118
  return val;
1127
- error( 'syntax-csn-expected-string', location(true), { prop: spec.msgProp },
1119
+ error( 'syntax-expected-string', location(true), { prop: spec.msgProp },
1128
1120
  'Expected non-empty string for property $(PROP)' );
1129
1121
  return ignore( val );
1130
1122
  }
@@ -1133,7 +1125,7 @@ function stringVal( val, spec ) {
1133
1125
  if (typeof val === 'string' && val)
1134
1126
  // XSN TODO: do not require literal
1135
1127
  return { val, literal: 'string', location: location() };
1136
- error( 'syntax-csn-expected-string', location(true), { prop: spec.msgProp },
1128
+ error( 'syntax-expected-string', location(true), { prop: spec.msgProp },
1137
1129
  'Expected non-empty string for property $(PROP)' );
1138
1130
  return ignore( val );
1139
1131
  }
@@ -1155,7 +1147,7 @@ function natnum( val, spec ) {
1155
1147
  if (typeof val === 'number' && val >= 0)
1156
1148
  // XSN TODO: do not require literal
1157
1149
  return { val, literal: 'number', location: location() };
1158
- error( spec.msgId || 'syntax-csn-expected-natnum', location(true),
1150
+ error( spec.msgId || 'syntax-expected-natnum', location(true),
1159
1151
  { prop: spec.msgProp } );
1160
1152
  return ignore( val );
1161
1153
  }
@@ -1190,10 +1182,8 @@ function annoValue( val, spec ) {
1190
1182
  /** @type {string|boolean} */
1191
1183
  let seenEllipsis = false;
1192
1184
  if (arrayLevelCount > 0) { // TODO: also inside structure (possible in CSN!)
1193
- if (val.some( isEllipsis )) {
1194
- error( 'syntax-csn-unexpected-ellipsis', location(true), { code: '...' },
1195
- 'Unexpected $(CODE) in nested array' );
1196
- }
1185
+ if (val.some( isEllipsis ))
1186
+ error( 'syntax-unexpected-ellipsis', location(true), { '#': 'nested-array', code: '...' } );
1197
1187
  }
1198
1188
  else {
1199
1189
  for (const item of val) {
@@ -1202,7 +1192,7 @@ function annoValue( val, spec ) {
1202
1192
  }
1203
1193
  else if (isEllipsis( item )) { // with or without UP TO
1204
1194
  // error position at the beginning of the array, but that is fine
1205
- error( 'syntax-csn-duplicate-ellipsis', location(true), { code: '...' },
1195
+ error( 'syntax-duplicate-ellipsis', location(true), { code: '...' },
1206
1196
  'Expected no more than one $(CODE)' );
1207
1197
  break;
1208
1198
  }
@@ -1216,7 +1206,7 @@ function annoValue( val, spec ) {
1216
1206
  };
1217
1207
  arrayLevelCount--;
1218
1208
  if (seenEllipsis === 'upTo') {
1219
- error( 'syntax-csn-expecting-ellipsis', location(true), // at closing bracket
1209
+ error( 'syntax-expecting-ellipsis', location(true), // at closing bracket
1220
1210
  { code: '... up to', newcode: '...' },
1221
1211
  // TODO: should we be more CSN specific in the message?
1222
1212
  'Expecting an array item $(NEWCODE) after an item with $(CODE)' );
@@ -1263,11 +1253,14 @@ function annoValue( val, spec ) {
1263
1253
  }
1264
1254
 
1265
1255
  function annotation( val, spec, xsn, csn, name ) {
1266
- const variantIndex = name.indexOf('#') + 1 || name.length;
1267
- const n = refSplit( name.substring( (xsn ? 1 : 0), variantIndex ), spec.msgProp );
1256
+ const absolute = (xsn ? name.substring(1) : name);
1257
+ // TODO: really care about variant (qualifier parts)?
1258
+ const variantIndex = absolute.indexOf('#') + 1 || absolute.length;
1259
+ const n = refSplit( absolute.substring( 0, variantIndex ), spec.msgProp );
1268
1260
  if (!n)
1269
1261
  return undefined;
1270
- if (variantIndex < name.length)
1262
+ n.absolute = absolute;
1263
+ if (variantIndex < absolute.length)
1271
1264
  n.variant = { id: name.substring( variantIndex ), location: location() };
1272
1265
  const r = annoValue( val, spec );
1273
1266
  r.name = n;
@@ -1282,21 +1275,27 @@ function value( val, spec, xsn ) { // for CSN property 'val'
1282
1275
  xsn.literal = (val === null) ? 'null' : typeof val;
1283
1276
  return val;
1284
1277
  }
1285
- error( 'syntax-csn-expected-scalar', location(true), { prop: spec.msgProp },
1278
+ error( 'syntax-expected-scalar', location(true), { prop: spec.msgProp },
1286
1279
  'Only scalar values are supported for property $(PROP)' );
1287
1280
  return ignore( val );
1288
1281
  }
1289
1282
 
1290
- function literal( val, spec, xsn, csn ) {
1283
+ function literal( lit, spec, xsn, csn ) {
1291
1284
  // TODO: general: requires other property (here: 'val')
1292
1285
  const type = (csn.val == null) ? 'null' : typeof csn.val;
1293
- if (val === type) // also for 'object' which is an error for 'val'
1294
- return val;
1295
- if (typeof val === 'string' && validLiteralsExtra[val] === type)
1296
- return val;
1297
- error( 'syntax-csn-expected-valid', location(true), { prop: spec.msgProp },
1286
+ if (lit === type) // also for 'object' which is an error for 'val'
1287
+ return lit;
1288
+ if (typeof lit === 'string' && quotedLiteralPatterns[lit]?.json_type === type) {
1289
+ const p = quotedLiteralPatterns[lit];
1290
+ if (p && (p.test_fn && !p.test_fn(csn.val) || p.test_re && !p.test_re.test(csn.val)))
1291
+ warning( 'syntax-invalid-literal', location(), { '#': p.test_variant } );
1292
+ return lit;
1293
+ }
1294
+ if (lit === 'number' && type === 'string') // special case, not a quoted literal in CDL
1295
+ return lit;
1296
+ error( 'syntax-expected-valid', location(true), { prop: spec.msgProp },
1298
1297
  'Expected valid string for property $(PROP)' );
1299
- return ignore( val );
1298
+ return ignore( lit );
1300
1299
  }
1301
1300
 
1302
1301
  function func( val, spec, xsn ) {
@@ -1309,7 +1308,7 @@ function func( val, spec, xsn ) {
1309
1308
  function xpr( exprs, spec, xsn, csn ) {
1310
1309
  if (csn.func) {
1311
1310
  if (!exprs.length) {
1312
- message( 'syntax-csn-expected-length', location(true),
1311
+ message( 'syntax-expected-length', location(true),
1313
1312
  { prop: 'xpr', otherprop: 'func', '#': 'suffix' });
1314
1313
  }
1315
1314
  xsn.suffix = exprArgs( exprs, spec );
@@ -1342,7 +1341,7 @@ function args( exprs, spec ) {
1342
1341
  return arrayOf( exprOrString )( exprs, spec );
1343
1342
  }
1344
1343
  else if (!exprs || typeof exprs !== 'object') {
1345
- error( 'syntax-csn-expected-args', location(true),
1344
+ error( 'syntax-expected-args', location(true),
1346
1345
  { prop: spec.prop }, // spec.prop, not spec.msgProp!
1347
1346
  'Expected array or object for property $(PROP)' );
1348
1347
  return ignore( exprs );
@@ -1405,12 +1404,12 @@ function condition( cond, spec ) {
1405
1404
  function vZeroValue( obj, spec, xsn ) {
1406
1405
  if (xsn.value) {
1407
1406
  // TODO: also "sign" xsn.value created by inValue to complain about both 'value' and 'ref' etc
1408
- warning( 'syntax-csn-unexpected-property', location(true), { prop: spec.msgProp },
1407
+ warning( 'syntax-unexpected-property', location(true), { prop: spec.msgProp },
1409
1408
  'Unexpected CSN property $(PROP)' );
1410
1409
  return undefined;
1411
1410
  }
1412
1411
  if (!csnVersionZero) {
1413
- warning( 'syntax-csn-zero-delete', location(true), { prop: spec.msgProp },
1412
+ warning( 'syntax-zero-delete', location(true), { prop: spec.msgProp },
1414
1413
  'Delete/inline CSN v0.1.0 property $(PROP)' );
1415
1414
  }
1416
1415
  return expr( obj, spec );
@@ -1457,6 +1456,12 @@ function excluding( array, spec, xsn ) {
1457
1456
  xsn.excludingDict = r;
1458
1457
  }
1459
1458
 
1459
+ function masked( val, spec ) {
1460
+ message('syntax-invalid-masked', location(), { keyword: 'masked' },
1461
+ 'Keyword $(KEYWORD) not supported');
1462
+ return boolOrNull( val, spec );
1463
+ }
1464
+
1460
1465
  function duplicateExcluding( name, loc ) {
1461
1466
  error( 'duplicate-excluding', loc, { name, keyword: 'excluding' },
1462
1467
  'Duplicate $(NAME) in the $(KEYWORD) clause' );
@@ -1477,7 +1482,7 @@ function join( val, spec, xsn ) {
1477
1482
 
1478
1483
  function queryArgs( val, spec, xsn, csn ) {
1479
1484
  if (Array.isArray( val ) && val.length > 1 && !csn.op) {
1480
- warning( 'syntax-csn-expected-property', location(true),
1485
+ warning( 'syntax-expected-property', location(true),
1481
1486
  { prop: 'args', otherprop: 'op' },
1482
1487
  'CSN property $(PROP) expects property $(OTHERPROP) to be specified' );
1483
1488
  xsn.op = { val: 'union', location: location() };
@@ -1496,7 +1501,7 @@ function i18nLang( val, spec, xsn, csn, langKey ) {
1496
1501
  function translations( keyVal, spec, xsn, csn, textKey ) {
1497
1502
  if (typeof keyVal === 'string') // allow empty string
1498
1503
  return { val: keyVal, literal: 'string', location: location() };
1499
- error( 'syntax-csn-expected-translation', location(true),
1504
+ error( 'syntax-expected-translation', location(true),
1500
1505
  { prop: textKey, otherprop: spec.prop },
1501
1506
  'Expected string for text key $(PROP) of language $(OTHERPROP)' );
1502
1507
  return ignore( keyVal );
@@ -1510,7 +1515,7 @@ function getSpec( parentSpec, csn, prop, xor, expected, kind ) {
1510
1515
  if (!s || s.noPrefix && prop !== p0 ) {
1511
1516
  if (ourpropsRegex.test( prop )) {
1512
1517
  // TODO v2: Warning only with --sloppy
1513
- warning( 'syntax-csn-unknown-property', location(true), { prop },
1518
+ warning( 'syntax-unknown-property', location(true), { prop },
1514
1519
  'Unknown CSN property $(PROP)' );
1515
1520
  }
1516
1521
  else { // TODO v2: always (i.e. also with message) add to $extra
@@ -1521,14 +1526,14 @@ function getSpec( parentSpec, csn, prop, xor, expected, kind ) {
1521
1526
  if (s.ignore)
1522
1527
  return { type: ignore };
1523
1528
  if (s.vZeroIgnore && s.vZeroIgnore === csn[prop]) { // for "op": "call"
1524
- warning( 'syntax-csn-zero-delete', location(true), { prop },
1529
+ warning( 'syntax-zero-delete', location(true), { prop },
1525
1530
  'Delete/inline CSN v0.1.0 property $(PROP)' );
1526
1531
  return { type: ignore };
1527
1532
  }
1528
1533
  const zero = s.vZeroFor;
1529
1534
  if (zero) { // (potential) CSN v0.1.0 property
1530
1535
  const group = s.xorGroup;
1531
- if (zero && expected( zero, schema[zero] ) && !(group && xor[group])) {
1536
+ if (expected( zero, schema[zero] ) && !(group && xor[group])) {
1532
1537
  replaceZeroProp( prop, zero );
1533
1538
  if (group)
1534
1539
  xor[group] = prop;
@@ -1540,7 +1545,7 @@ function getSpec( parentSpec, csn, prop, xor, expected, kind ) {
1540
1545
  const variant = kind && s.inKind
1541
1546
  ? ([ 'extend', 'annotate' ].includes(kind) ? kind : 'def')
1542
1547
  : (parentSpec.msgProp ? 'std' : 'top');
1543
- message( 'syntax-csn-unexpected-property', location(true),
1548
+ message( 'syntax-unexpected-property', location(true),
1544
1549
  {
1545
1550
  prop, otherprop: parentSpec.msgProp, kind, '#': variant,
1546
1551
  },
@@ -1548,7 +1553,7 @@ function getSpec( parentSpec, csn, prop, xor, expected, kind ) {
1548
1553
  std: 'CSN property $(PROP) is not expected in $(OTHERPROP)',
1549
1554
  top: 'CSN property $(PROP) is not expected top-level',
1550
1555
  def: 'CSN property $(PROP) is not expected by a definition of kind $(KIND)',
1551
- extend: 'CSN property $(PROP) is not expected by an extend in $(OTHERPROP))',
1556
+ extend: 'CSN property $(PROP) is not expected by an extend in $(OTHERPROP)',
1552
1557
  annotate: 'CSN property $(PROP) is not expected by an annotate in $(OTHERPROP)',
1553
1558
  } );
1554
1559
  // TODO: or still augment it? (but then also handle xorGroup)
@@ -1598,13 +1603,13 @@ function onlyWith( spec, need, csn, prop, xor, expected ) {
1598
1603
  need = allowed.find( p => !xor[schema[p].xorGroup] ) || allowed[0];
1599
1604
  }
1600
1605
  if (prop) {
1601
- error( 'syntax-csn-dependent-property', location(true),
1606
+ error( 'syntax-dependent-property', location(true),
1602
1607
  { prop, otherprop: need },
1603
1608
  'CSN property $(PROP) can only be used in combination with $(OTHERPROP)');
1604
1609
  xor['no:req'] = prop;
1605
1610
  }
1606
1611
  else if (!xor['no:req']) {
1607
- error( 'syntax-csn-required-property', location(true),
1612
+ error( 'syntax-required-property', location(true),
1608
1613
  { prop: need, otherprop: spec.msgProp, '#': spec.prop },
1609
1614
  { // TODO $(PARENT), TODO: do not use prop===0 hack
1610
1615
  std: 'Object in $(OTHERPROP) must have the property $(PROP)',
@@ -1626,7 +1631,7 @@ function checkAndSetXorGroup( group, prop, xor ) {
1626
1631
  if (prop === 'func' && xor[group] === 'xpr' ||
1627
1632
  prop === 'xpr' && xor[group] === 'func')
1628
1633
  return true; // hack for window function: both func and xpr is allowed
1629
- error( 'syntax-csn-excluded-property', location(true),
1634
+ error( 'syntax-excluded-property', location(true),
1630
1635
  { prop, otherprop: xor[group] },
1631
1636
  'CSN property $(PROP) can only be used alternatively to $(OTHERPROP)');
1632
1637
  return false;
@@ -1641,7 +1646,7 @@ function implicitName( ref ) {
1641
1646
  function replaceZeroProp( otherprop, prop ) {
1642
1647
  if (csnVersionZero)
1643
1648
  return;
1644
- warning( 'syntax-csn-zero-prop', location(true), { prop, otherprop },
1649
+ warning( 'syntax-zero-prop', location(true), { prop, otherprop },
1645
1650
  'Replace CSN v0.1.0 property $(OTHERPROP) by $(PROP)' );
1646
1651
  }
1647
1652
 
@@ -1650,7 +1655,7 @@ function replaceZeroProp( otherprop, prop ) {
1650
1655
  function isArray( array, spec ) {
1651
1656
  if (Array.isArray( array ))
1652
1657
  return array;
1653
- error( 'syntax-csn-expected-array', location(true), { prop: spec.prop },
1658
+ error( 'syntax-expected-array', location(true), { prop: spec.prop },
1654
1659
  'Expected array for property $(PROP)' );
1655
1660
  return ignore( array );
1656
1661
  }
@@ -1658,7 +1663,7 @@ function isArray( array, spec ) {
1658
1663
  function isObject( obj, spec ) {
1659
1664
  if (obj && typeof obj === 'object' && !Array.isArray( obj ))
1660
1665
  return obj;
1661
- error( spec.msgId || 'syntax-csn-expected-object', location(true),
1666
+ error( spec.msgId || 'syntax-expected-object', location(true),
1662
1667
  { prop: spec.msgProp });
1663
1668
  return ignore( obj );
1664
1669
  }
@@ -1666,7 +1671,7 @@ function isObject( obj, spec ) {
1666
1671
  function refSplit( name, prop ) {
1667
1672
  const path = name.split('.');
1668
1673
  if (!path.every( id => id)) {
1669
- warning( 'syntax-csn-expected-name', location(true), { prop },
1674
+ warning( 'syntax-expected-name', location(true), { prop },
1670
1675
  'Expected correct name for property $(PROP)' );
1671
1676
  }
1672
1677
  return { path: path.map( id => ({ id, location: location() }) ), location: location() };
@@ -1674,7 +1679,7 @@ function refSplit( name, prop ) {
1674
1679
 
1675
1680
  function replaceZeroValue( spec ) {
1676
1681
  if (!csnVersionZero && spec.vZeroFor == null) { // but 0 does not match!
1677
- warning( 'syntax-csn-zero-value', location(true), { prop: spec.msgProp },
1682
+ warning( 'syntax-zero-value', location(true), { prop: spec.msgProp },
1678
1683
  'Replace CSN v0.1.0 value in $(PROP) by something specified' );
1679
1684
  }
1680
1685
  }
@@ -1704,7 +1709,7 @@ function pushLocation( obj ) {
1704
1709
  else if (!loc || typeof loc !== 'string') {
1705
1710
  if (loc)
1706
1711
  dollarLocations.push( null ); // must match with popLocation()
1707
- error( 'syntax-csn-expected-object', location(true), { prop: '$location' } );
1712
+ error( 'syntax-expected-object', location(true), { prop: '$location' } );
1708
1713
  }
1709
1714
  // hidden feature: string $location
1710
1715
  const m = /:(\d+)(?::(\d+))?$/.exec( loc ); // extra '^'s at end deliberately left out
@@ -1776,7 +1781,7 @@ function toXsn( csn, filename, options, messageFunctions ) {
1776
1781
  }
1777
1782
 
1778
1783
 
1779
- function augment( csn, filename = 'csn.json', options = {}, messageFunctions ) {
1784
+ function augment( csn, filename = 'csn.json', options = {}, messageFunctions = {} ) {
1780
1785
  try {
1781
1786
  return toXsn( csn, filename, options, messageFunctions );
1782
1787
  }
@@ -1786,7 +1791,7 @@ function augment( csn, filename = 'csn.json', options = {}, messageFunctions ) {
1786
1791
  }
1787
1792
  }
1788
1793
 
1789
- function parse( source, filename = 'csn.json', options = {}, messageFunctions ) {
1794
+ function parse( source, filename = 'csn.json', options = {}, messageFunctions = {} ) {
1790
1795
  try {
1791
1796
  return augment( JSON.parse(source), filename, options, messageFunctions );
1792
1797
  }
@@ -1817,7 +1822,7 @@ function parse( source, filename = 'csn.json', options = {}, messageFunctions )
1817
1822
  line,
1818
1823
  col: column,
1819
1824
  };
1820
- messageFunctions.error( 'syntax-csn-illegal-json', loc, { msg }, 'Illegal JSON: $(MSG)' );
1825
+ messageFunctions.error( 'syntax-illegal-json', loc, { msg }, 'Illegal JSON: $(MSG)' );
1821
1826
  return xsn;
1822
1827
  }
1823
1828
  }
@@ -13,6 +13,7 @@
13
13
 
14
14
  const { locationString } = require('../base/messages');
15
15
  const { isBetaEnabled, isDeprecatedEnabled } = require('../base/model');
16
+ const { pathName } = require('../compiler/utils');
16
17
 
17
18
  const compilerVersion = require('../../package.json').version;
18
19
  const creator = `CDS Compiler v${ compilerVersion }`;
@@ -222,7 +223,7 @@ const operators = {
222
223
  unboundedFollowing: [ 'unbounded', 'following' ],
223
224
  following: postfix( [ 'following' ] ),
224
225
  frameBetween: exprs => [ 'between', ...exprs[0], 'and', ...exprs[1] ],
225
- // xpr: (exprs) => [].concat( ...exprs ), see below - handled extra
226
+ ixpr: exprs => [].concat( ...exprs ), // xpr extra, due to extra parentheses
226
227
  };
227
228
 
228
229
  const csnDictionaries = [
@@ -725,7 +726,8 @@ function annotationsAndDocComment( node, annotated ) {
725
726
  const val = node[prop];
726
727
  // val.$priority isn't set for computed annotations like @Core.Computed
727
728
  // and @odata.containment.ignore
728
- if (val.$priority && (val.$priority !== 'define') === annotated) {
729
+ // TODO: use $inferred instead special $priority value
730
+ if (val.$priority !== undefined && (!!val.$priority) === annotated) {
729
731
  // transformer (= value) takes care to exclude $inferred annotation assignments
730
732
  const sub = transformer( val );
731
733
  // As value() just has one value, so we do not provide ( val, csn, node, prop )
@@ -1217,8 +1219,8 @@ function value( node ) {
1217
1219
  if (node.$inferred && gensrcFlavor)
1218
1220
  return undefined;
1219
1221
  if (node.path) {
1220
- const ref = node.path.map( id => id.id ).join('.');
1221
- return extra( { '=': node.variant ? `${ ref }#${ node.variant.id }` : ref }, node );
1222
+ const ref = pathName( node.path );
1223
+ return extra( { '=': node.variant ? `${ ref }#${ pathName(node.variant.path) }` : ref }, node );
1222
1224
  }
1223
1225
  if (node.literal === 'enum')
1224
1226
  return extra( { '#': node.sym.id }, node );
@@ -1588,10 +1590,11 @@ function compactExpr( e ) { // TODO: options
1588
1590
  */
1589
1591
  function initModuleVars( options = { csnFlavor: 'gensrc' } ) {
1590
1592
  gensrcFlavor = options.parseCdl || options.csnFlavor === 'gensrc' ||
1591
- options.toCsn && options.toCsn.flavor === 'gensrc';
1592
- universalCsn = (options.csnFlavor === 'universal' ||
1593
- options.toCsn && options.toCsn.flavor === 'universal' ) &&
1594
- isBetaEnabled( options, 'enableUniversalCsn' ) && !options.parseCdl;
1593
+ ( options.toCsn && options.toCsn.flavor === 'gensrc');
1594
+ universalCsn = ( options.csnFlavor === 'universal' ||
1595
+ ( options.toCsn && options.toCsn.flavor === 'universal') ) &&
1596
+ isBetaEnabled( options, 'enableUniversalCsn' ) &&
1597
+ !options.parseCdl;
1595
1598
  strictMode = options.testMode;
1596
1599
  const proto = options.dictionaryPrototype;
1597
1600
  // eslint-disable-next-line no-nested-ternary
@@ -1599,8 +1602,8 @@ function initModuleVars( options = { csnFlavor: 'gensrc' } ) {
1599
1602
  ? proto
1600
1603
  : (proto) ? Object.prototype : null;
1601
1604
  withLocations = options.withLocations;
1602
- parensAsStrings = isDeprecatedEnabled( options, 'parensAsStrings' );
1603
- projectionAsQuery = isDeprecatedEnabled( options, 'projectionAsQuery' );
1605
+ parensAsStrings = isDeprecatedEnabled( options, '_parensAsStrings' );
1606
+ projectionAsQuery = isDeprecatedEnabled( options, '_projectionAsQuery' );
1604
1607
  }
1605
1608
 
1606
1609
  module.exports = {
@@ -13,8 +13,8 @@ const antlr4 = require('antlr4');
13
13
  const { CompileMessage } = require('../base/messages');
14
14
  const errorStrategy = require('./errorStrategy');
15
15
 
16
- const Parser = require('../gen/languageParser').languageParser;
17
- const Lexer = require('../gen/languageLexer').languageLexer;
16
+ const Parser = require('../gen/languageParser').default;
17
+ const Lexer = require('../gen/languageLexer').default;
18
18
 
19
19
  // Error listener used for ANTLR4-generated parser
20
20
  class ErrorListener extends antlr4.error.ErrorListener {