@sap/cds-compiler 3.7.2 → 3.8.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 (70) hide show
  1. package/CHANGELOG.md +71 -4
  2. package/bin/cdsc.js +3 -0
  3. package/doc/CHANGELOG_ARCHIVE.md +6 -6
  4. package/doc/CHANGELOG_BETA.md +15 -0
  5. package/doc/DeprecatedOptions_v2.md +1 -1
  6. package/doc/NameResolution.md +1 -1
  7. package/lib/api/main.js +61 -22
  8. package/lib/api/options.js +1 -0
  9. package/lib/api/validate.js +5 -0
  10. package/lib/base/dictionaries.js +5 -3
  11. package/lib/base/keywords.js +2 -0
  12. package/lib/base/message-registry.js +64 -22
  13. package/lib/base/messages.js +12 -7
  14. package/lib/base/model.js +3 -2
  15. package/lib/checks/arrayOfs.js +1 -1
  16. package/lib/checks/defaultValues.js +1 -1
  17. package/lib/checks/hasPersistedElements.js +1 -1
  18. package/lib/checks/invalidTarget.js +1 -1
  19. package/lib/checks/onConditions.js +9 -6
  20. package/lib/checks/sql-snippets.js +2 -2
  21. package/lib/checks/types.js +1 -2
  22. package/lib/compiler/assert-consistency.js +25 -6
  23. package/lib/compiler/base.js +51 -2
  24. package/lib/compiler/builtins.js +15 -6
  25. package/lib/compiler/checks.js +4 -4
  26. package/lib/compiler/define.js +59 -80
  27. package/lib/compiler/extend.js +717 -498
  28. package/lib/compiler/finalize-parse-cdl.js +4 -3
  29. package/lib/compiler/index.js +1 -1
  30. package/lib/compiler/kick-start.js +2 -2
  31. package/lib/compiler/populate.js +17 -9
  32. package/lib/compiler/propagator.js +12 -5
  33. package/lib/compiler/resolve.js +26 -173
  34. package/lib/compiler/shared.js +20 -58
  35. package/lib/compiler/tweak-assocs.js +1 -1
  36. package/lib/compiler/utils.js +2 -2
  37. package/lib/edm/annotations/genericTranslation.js +124 -46
  38. package/lib/edm/csn2edm.js +22 -1
  39. package/lib/edm/edmPreprocessor.js +41 -21
  40. package/lib/gen/Dictionary.json +4 -0
  41. package/lib/gen/language.checksum +1 -1
  42. package/lib/gen/language.interp +3 -1
  43. package/lib/gen/languageLexer.js +1 -1
  44. package/lib/gen/languageParser.js +4844 -4508
  45. package/lib/inspect/inspectPropagation.js +20 -36
  46. package/lib/json/from-csn.js +56 -7
  47. package/lib/json/to-csn.js +71 -110
  48. package/lib/language/errorStrategy.js +1 -0
  49. package/lib/language/genericAntlrParser.js +49 -9
  50. package/lib/language/language.g4 +106 -83
  51. package/lib/language/textUtils.js +13 -0
  52. package/lib/main.d.ts +43 -3
  53. package/lib/main.js +4 -2
  54. package/lib/model/csnRefs.js +19 -4
  55. package/lib/model/csnUtils.js +11 -74
  56. package/lib/model/revealInternalProperties.js +3 -0
  57. package/lib/optionProcessor.js +3 -0
  58. package/lib/render/toCdl.js +203 -104
  59. package/lib/render/toHdbcds.js +0 -1
  60. package/lib/render/toRename.js +14 -51
  61. package/lib/transform/braceExpression.js +6 -0
  62. package/lib/transform/db/rewriteCalculatedElements.js +55 -14
  63. package/lib/transform/forOdataNew.js +20 -15
  64. package/lib/transform/forRelationalDB.js +21 -14
  65. package/lib/transform/parseExpr.js +2 -0
  66. package/lib/transform/transformUtilsNew.js +36 -9
  67. package/lib/transform/translateAssocsToJoins.js +11 -4
  68. package/lib/transform/universalCsn/coreComputed.js +15 -7
  69. package/lib/transform/universalCsn/universalCsnEnricher.js +4 -4
  70. package/package.json +2 -1
package/CHANGELOG.md CHANGED
@@ -7,6 +7,75 @@
7
7
  Note: `beta` fixes, changes and features are usually not listed in this ChangeLog but [here](doc/CHANGELOG_BETA.md).
8
8
  The compiler behavior concerning `beta` features can change at any time without notice.
9
9
 
10
+ ## Version 3.8.2 - 2023-03-30
11
+
12
+ ### Fixed
13
+
14
+ - parser: Identifiers that are keywords were not allowed in annotation values inside arrays
15
+ - compiler: Compatibility against cds-lsp was restored.
16
+ - to.sql/hdbcds/hdi/edm(x): Fix a crash for sub-queries inside nested expressions of on-conditions of JOINs.
17
+
18
+ ## Version 3.8.0 - 2023-03-27
19
+
20
+ ### Added
21
+
22
+ - compiler:
23
+ + Table aliases for sub-queries are no longer required.
24
+ + A time zone designator can now be used in time literals, e.g. `time'16:41:01+01:30'`or `time'16:41:01Z'`.
25
+ - Calculated elements ("on-read") are now enabled per default.
26
+ When used in views, they are replaced by their value, for example:
27
+ ```cds
28
+ entity E { one: Integer; two = one + 1; };
29
+ entity P as projection on E { two };
30
+ // P is the same as:
31
+ entity P as projection on E { one + 1 as two };
32
+ ```
33
+ This allows to define calculations centrally at the entity, which can be used by
34
+ other views.
35
+ - In CDL, a ternary operator was added as a shortcut for `CASE` expressions:
36
+ `a ? b : c` is a shortcut for `CASE WHEN a THEN b ELSE c END`. There is no CSN
37
+ representation. The ternary operator is rendered as a `CASE` expression in CSN.
38
+ - In CDL and CSN, `not null` can now also be used in type definitions.
39
+ - In CDL (and CSN as before), elements can be defined without specifying a type.
40
+
41
+ ### Changed
42
+
43
+ - API: We now report an error for most backends, if the input CSN has
44
+ `meta.flavor == 'xtended'`, because only client/inferred CSN is supported.
45
+ - Update OData vocabularies 'PersonalData', 'UI'
46
+ - for.odata: Shortcut annotations `@label`, `@title`, `@description`, `@readonly` are no longer
47
+ removed from the OData processed CSN.
48
+ - to.cdl:
49
+ + Annotation arrays are split into multiple lines, if a single line would be too long.
50
+ + Nested `SELECT`s are put into separate lines to make them more readable.
51
+ + (Annotation) paths are quoted less often.
52
+ - to.sql: The list of reserved SAP HANA identifiers was updated (for smart quoting).
53
+
54
+ ### Fixed
55
+
56
+ - The CSN parser now accepts bare `list`s in `columns[]`, similar to the CDL parser.
57
+ - to.cdl:
58
+ + Delimited identifiers in filters are now surrounded by spaces if necessary, to avoid `]]`
59
+ being interpreted as an escaped bracket.
60
+ - to.edm(x):
61
+ + Remove empty `Edm.EntityContainer` again. Removal of an empty entity container has been
62
+ revoked with [3.5.0](#fixed-7) which was wrong. An empty container must not be rendered
63
+ as it is not spec compliant.
64
+ + Correctly resolve chained enum symbols.
65
+ + Fix a program abort during structured rendering in combination with `--odata-foreign-keys`
66
+ and foreign keys in structured types.
67
+ + Correctly render paths to nested foreign keys as primary key in structured mode with
68
+ `--odata-foreign-keys`.
69
+ - to.hdi/to.sql/to.edm(x):
70
+ + Reject unmanaged associations as ON-condition path end points.
71
+ + Fix bug in message rendering for tuple expansion.
72
+ + Correctly detect invalid @sql.append/prepend in projections.
73
+ - to.hdi/to.sql: The list of SAP HANA keywords was updated to the latest version.
74
+
75
+ ### Removed
76
+
77
+ - for.odata: Undocumented shortcut annotation `@important` has been removed.
78
+
10
79
 
11
80
  ## Version 3.7.2 - 2023-02-24
12
81
 
@@ -15,6 +84,7 @@ The compiler behavior concerning `beta` features can change at any time without
15
84
  - CSN parser: Structured annotations containing `=` were accidentally interpreted as expressions,
16
85
  even though the corresponding beta flag was not set.
17
86
 
87
+
18
88
  ## Version 3.7.0 - 2023-02-22
19
89
 
20
90
  ### Added
@@ -44,9 +114,6 @@ The compiler behavior concerning `beta` features can change at any time without
44
114
  explicit redirection.
45
115
  - to.edm(x): Process value help list convenience annotations on unbound action parameters.
46
116
 
47
- ### Removed
48
-
49
- - tbd
50
117
 
51
118
  ## Version 3.6.2 - 2023-02-06
52
119
 
@@ -455,7 +522,7 @@ The compiler behavior concerning `beta` features can change at any time without
455
522
  + Enforce `odata-spec-violation-key-null` on explicit foreign keys of managed primary key associations.
456
523
  + Proxies/service cross references are no longer created for associations with arbitrary ON conditions.
457
524
  Only managed or `$self` backlink association targets are proxy/service cross reference candidates.
458
- + Explicit foreign keys of a managed association that are not a primary key in the target are exposed in the the proxy.
525
+ + Explicit foreign keys of a managed association that are not a primary key in the target are exposed in the proxy.
459
526
  + If an association is primary key, the resulting navigation property is set to `Nullable:false` in structured mode.
460
527
 
461
528
  ## Version 2.15.0 - 2022-05-06
package/bin/cdsc.js CHANGED
@@ -353,6 +353,9 @@ function executeCommandLine( command, options, args ) {
353
353
  options.odataFormat = 'structured';
354
354
  options.odataContainment = true;
355
355
  }
356
+ if (options.odataVocRefs && typeof options.odataVocRefs === 'string')
357
+ options.odataVocRefs = JSON.parse(options.odataVocRefs);
358
+
356
359
  const csn = options.directBackend ? model : compactModel(model, options);
357
360
  if (options.csn) {
358
361
  const odataCsn = main.for.odata(csn, options);
@@ -777,7 +777,7 @@ synchronously.
777
777
 
778
778
  - Introduce annotation `@cds.redirection.target`.
779
779
  With value `false`, the projection is not considered an implicit redirection target;
780
- with value `true`, is is considered a “preferred” redirection target.
780
+ with value `true`, is considered a “preferred” redirection target.
781
781
 
782
782
  ## Version 1.49.2 - 2021-02-16
783
783
 
@@ -1313,7 +1313,7 @@ synchronously.
1313
1313
 
1314
1314
  - HANA/SQL: Validate ON conditions of mixin association definitions in all subqueries
1315
1315
 
1316
- - OData V2: Assign various `@sap` annotations to the `<edmx:EnitySet>` and `<edmx:AssociationSet>`
1316
+ - OData V2: Assign various `@sap` annotations to the `<edmx:entitySet>` and `<edmx:AssociationSet>`
1317
1317
  if such annotations are assigned to CDS entities or associations.
1318
1318
 
1319
1319
  - OData V4 Structured: Omit foreign keys of managed associations that establish the containment relationship to
@@ -1445,7 +1445,7 @@ synchronously.
1445
1445
 
1446
1446
  ### Fixed
1447
1447
 
1448
- - Compiler: `type of <unmanaged assocation>` is now handled correctly by raising an error.
1448
+ - Compiler: `type of <unmanaged association>` is now handled correctly by raising an error.
1449
1449
 
1450
1450
  ## Version 1.25.0 - 2020-04-09
1451
1451
 
@@ -1629,7 +1629,7 @@ Fixes
1629
1629
  * In the Hana/Sql backend, correctly resolve forward `on` condition when using
1630
1630
  mixin association that backlinks to an unrelated 3rd party entity and association.
1631
1631
  * Raise a warning if the element of the forward association and the element of
1632
- the query source do not not originate from the same defining entity. Raise an
1632
+ the query source do not originate from the same defining entity. Raise an
1633
1633
  error if the element of the forward association cannot be found in the query
1634
1634
  source or is ambiguous.
1635
1635
  * Correctly create localization views with compiled model as input;
@@ -2267,7 +2267,7 @@ Changes
2267
2267
  _Update to v1.12.1_ if you experience problems – an inherited `@cds.autoexpose` had not been considered.
2268
2268
  * In `toSql` and `toHana` errors are raised
2269
2269
  + for duplicate definitions of elements that differ only in spelling,
2270
- + if the the entity is not `abstract` or annotated with any `@cds.persistence` set to true and
2270
+ + if the entity is not `abstract` or annotated with any `@cds.persistence` set to true and
2271
2271
  - an element is typed to be an `array of` a `type`,
2272
2272
  - an implicit managed composition has cardinality to many.
2273
2273
  * Raise a warning if an element is to be `localized` which is not of type `cds.String`.
@@ -2489,7 +2489,7 @@ Fixes
2489
2489
  while rewriting the `on` conditition of a projected association.
2490
2490
  * Apply OData specific checks (e.g. that all elements of an entity must have a type)
2491
2491
  applied only to objects that are exposed in a service.
2492
- * When generating SQL for SQLite, replace the the special variables `$now`, `$user.id`
2492
+ * When generating SQL for SQLite, replace the special variables `$now`, `$user.id`
2493
2493
  and `$user.locale` by `CURRENT_TIMESTAMP`, `'$user.id'`, and `'EN'`, respectively.
2494
2494
  * Issue a warning for conflicting cardinality declarations (e.g. `association[1] to many ...`).
2495
2495
  * Handle filters with cardinality correctly when translating associations to joins.
@@ -8,6 +8,21 @@ Note: `beta` fixes, changes and features are listed in this ChangeLog just for i
8
8
  The compiler behavior concerning `beta` features can change at any time without notice.
9
9
  **Don't use `beta` fixes, changes and features in productive mode.**
10
10
 
11
+ ## Version 3.8.0 - 2023-03-27
12
+
13
+ ### Added `v4preview`
14
+
15
+ This beta flags tries to imitate cds-compiler v4 behavior.
16
+ This includes new compiler messages as well as potentially breaking changes.
17
+
18
+ Enable this beta flag to ease upgrading to cds-compiler v4.
19
+
20
+ This flag does not guarantee full compatibility with v4, but only
21
+ helps to identify potential issues as soon as possible.
22
+
23
+ ### Removed `calculatedElements`
24
+
25
+ Now enabled per default.
11
26
 
12
27
  ## Version 3.7.0 - 2023-02-22
13
28
 
@@ -51,7 +51,7 @@ The compiled model contains the following generated entities:
51
51
  * the auto-exposed projection `our.Service.Proj.texts`
52
52
  which is a composition target of `our.Service.Proj:texts`
53
53
 
54
- For the following sub sections (and in general), is is important to understand that
54
+ For the following subsections (and in general), it is important to understand that
55
55
  you can define all auto-exposed entities yourself (well, they are not
56
56
  _auto_-exposed anymore)
57
57
  _without_ any difference in the compiled model
@@ -600,7 +600,7 @@ The list of search environments is created as follows:
600
600
 
601
601
  The above mentioned `:`-escape mechanism leads to the following name resolution:
602
602
 
603
- * The first lexical search environment is the the environment containing all parameter names of the current view.
603
+ * The first lexical search environment is the environment containing all parameter names of the current view.
604
604
  * The following search environments are the usual ones from the "main artifact name resolution";
605
605
  constant values can be accessed this way (_TODO_: probably not now).
606
606
 
package/lib/api/main.js CHANGED
@@ -335,7 +335,7 @@ function remapName( key, csn, filter = () => true ) {
335
335
  * @param {CSN.Model} csn A clean input CSN representing the desired "after-image"
336
336
  * @param {HdiOptions} options Options
337
337
  * @param {CSN.Model} beforeImage A db-transformed CSN representing the "before-image", or null in case no such image
338
- * is known, i.e. for the very first migration step
338
+ * is known, i.e. for the very first migration step.
339
339
  * @returns {object} An object with three properties:
340
340
  * - afterImage: A db-transformed CSN representing the "after-image"
341
341
  * - drops: An array of SQL statements to drop views/tables
@@ -812,18 +812,21 @@ function publishCsnProcessor( processor, _name ) {
812
812
  /**
813
813
  * Function that calls the processor and re-compiles in case of internal errors
814
814
  *
815
- * @param {object} csn CSN
816
- * @param {object} options Options
815
+ * @param {CSN.Model} csn CSN
816
+ * @param {CSN.Options} options Options
817
817
  * @param {any} args Any additional arguments
818
818
  * @returns {any} What ever the processor returns
819
819
  */
820
820
  function api( csn, options = {}, ...args ) {
821
821
  try {
822
- if (options.deprecated) {
823
- const messageFunctions = messages.makeMessageFunction(csn, options, 'api');
822
+ const messageFunctions = messages.makeMessageFunction(csn, options, 'api');
823
+ if (options.deprecated)
824
824
  checkRemovedDeprecatedFlags( options, messageFunctions );
825
- }
826
- checkOutdatedOptions( options );
825
+
826
+ checkOutdatedOptions( options, messageFunctions );
827
+ checkCsnFlavor( csn, options, messageFunctions, _name );
828
+
829
+ messageFunctions.throwWithError();
827
830
 
828
831
  timetrace.timetrace.start(_name);
829
832
  const result = processor( csn, options, ...args );
@@ -861,37 +864,73 @@ const oldBackendOptionNames = [ 'toSql', 'toOdata', 'toHana', 'forHana' ];
861
864
  * - toOdata/toSql/toHana/forHana -> now flat options
862
865
  *
863
866
  * @param {CSN.Options} options Backend options
867
+ * @param {object} messageFunctions Functions returned by makeMessageFunction()
864
868
  */
865
- function checkOutdatedOptions( options ) {
866
- const { error, throwWithError } = messages.makeMessageFunction(null, options, 'api');
867
-
869
+ function checkOutdatedOptions( options, messageFunctions ) {
868
870
  // This error has been emitted once, we don't need to emit it again.
869
- if (options.messages?.some(m => m.messageId === 'api-invalid-option')) {
870
- throwWithError();
871
+ if (options.messages?.some(m => m.messageId === 'api-invalid-option' || m.messageId === 'api-invalid-variable-replacement'))
871
872
  return;
872
- }
873
+
873
874
 
874
875
  for (const name of oldBackendOptionNames) {
875
876
  if (typeof options[name] === 'object') // may be a boolean due to internal options
876
- error('api-invalid-option', null, { '#': 'std', name });
877
+ messageFunctions.error('api-invalid-option', null, { '#': 'deprecated', name });
877
878
  }
878
879
 
879
880
  if (options.magicVars)
880
- error('api-invalid-option', null, { '#': 'magicVars' });
881
+ messageFunctions.error('api-invalid-option', null, { '#': 'magicVars', prop: 'magicVars', otherprop: 'variableReplacements' });
881
882
 
882
883
  // Don't check `options.magicVars`. It's likely that the user renamed `magicVars` but
883
884
  // forgot about user -> $user and locale -> $user.locale
884
- if (options.variableReplacements?.user)
885
- error('api-invalid-option', null, { '#': 'user' });
886
- if (options.variableReplacements?.locale)
887
- error('api-invalid-option', null, { '#': 'locale' });
885
+ if (options.variableReplacements?.user) {
886
+ messageFunctions.error('api-invalid-variable-replacement', null, {
887
+ '#': 'user', option: 'variableReplacements', prop: '$user', otherprop: 'user',
888
+ });
889
+ }
890
+ if (options.variableReplacements?.locale) {
891
+ messageFunctions.error('api-invalid-variable-replacement', null, {
892
+ '#': 'locale', option: 'variableReplacements', prop: '$user.locale', otherprop: 'locale',
893
+ });
894
+ }
888
895
 
889
896
  forEachKey(options.variableReplacements || {}, (name) => {
890
- if (!name.startsWith('$') && name !== 'user' && name !== 'locale')
891
- error('api-invalid-option', null, { '#': 'noDollar', name });
897
+ if (!name.startsWith('$') && name !== 'user' && name !== 'locale') {
898
+ messageFunctions.error('api-invalid-variable-replacement', null, {
899
+ '#': 'noDollar', option: 'variableReplacements', code: '$', name,
900
+ });
901
+ }
892
902
  });
903
+ }
893
904
 
894
- throwWithError();
905
+ /**
906
+ * Checks that the given CSN is usable by our backends, e.g. that
907
+ * the CSN is not a gensrc (a.k.a. xtended) for most backends.
908
+ *
909
+ * For reference, cds-compiler/cds-dk CSN flavor map:
910
+ * - client -> inferred
911
+ * - gensrc -> xtended
912
+ * - parseCdl -> parsed
913
+ *
914
+ * If this function becomes more complex (e.g. more module conditions),
915
+ * move it from then generic api wrapper to the individual module.
916
+ *
917
+ * TODO: The compiler does not set any marker in `meta`; we use the umbrella one
918
+ * for easier debugging.
919
+ *
920
+ * @param {CSN.Model} csn User CSN
921
+ * @param {CSN.Options} options User options
922
+ * @param {object} messageFunctions Functions returned by makeMessageFunction()
923
+ * @param {string} module Backend module, e.g. to.cdl or to.sql
924
+ */
925
+ function checkCsnFlavor( csn, options, messageFunctions, module ) {
926
+ if (module === 'to.cdl' || !csn)
927
+ return; // to.cdl allows every CSN flavor
928
+
929
+ if (csn.meta?.flavor === 'xtended') {
930
+ // TODO: csn.meta?.flavor === 'parsed'; currently used by `@sap/cds` tests.
931
+ messageFunctions.error('api-unsupported-csn-flavor', null, { name: module, option: csn.meta?.flavor },
932
+ 'Module $(NAME) expects a client/inferred CSN, not $(OPTION)');
933
+ }
895
934
  }
896
935
 
897
936
  /**
@@ -38,6 +38,7 @@ const publicOptionsNewAPI = [
38
38
  'odataProxies',
39
39
  'odataXServiceRefs',
40
40
  'odataV2PartialConstr',
41
+ 'odataVocRefs',
41
42
  'service',
42
43
  'serviceNames',
43
44
  //
@@ -82,6 +82,11 @@ const validators = {
82
82
  sqlMapping: generateStringValidator([ 'plain', 'quoted', 'hdbcds' ]),
83
83
  odataVersion: generateStringValidator([ 'v2', 'v4' ]),
84
84
  odataFormat: generateStringValidator([ 'flat', 'structured' ]),
85
+ odataVocRefs: {
86
+ validate: val => (typeof val === 'object' && !Array.isArray(val)),
87
+ expected: () => 'type JSON object',
88
+ found: val => `type ${ Array.isArray(val) ? 'JSON array' : typeof val }`,
89
+ },
85
90
  service: {
86
91
  validate: val => typeof val === 'string',
87
92
  expected: () => 'type string',
@@ -91,11 +91,13 @@ function dictFirst( dict ) {
91
91
  }
92
92
 
93
93
  // Push `entry` to the array value with key `name` in the dictionary `dict`.
94
- function pushToDict( dict, name, entry ) {
94
+ function pushToDict( dict, name, ...entries ) {
95
95
  if (dict[name])
96
- dict[name].push( entry );
96
+ dict[name].push( ...entries );
97
+ else if (name.charAt(0) !== '_')
98
+ dict[name] = entries;
97
99
  else
98
- dict[name] = [ entry ];
100
+ Object.defineProperty( dict, name, { value: entries, configurable: true, writable: true } );
99
101
  }
100
102
 
101
103
  module.exports = {
@@ -579,6 +579,7 @@ module.exports = {
579
579
  'ST_ALPHASHAPEAGGR',
580
580
  'ST_ALPHASHAPEAREAAGGR',
581
581
  'ST_ALPHASHAPEEDGEAGGR',
582
+ 'ST_ASGEOJSON',
582
583
  'ST_ASMVT',
583
584
  'ST_ASSVGAGGR',
584
585
  'ST_CIRCULARSTRING',
@@ -606,6 +607,7 @@ module.exports = {
606
607
  'ST_INTERSECTIONAGGR',
607
608
  'ST_LINESTRING',
608
609
  'ST_MAKELINE',
610
+ 'ST_MAKELINEAGGR',
609
611
  'ST_MAKEPOLYGON',
610
612
  'ST_MEMORY_LOB',
611
613
  'ST_MULTILINESTRING',
@@ -60,7 +60,7 @@ const centralMessages = {
60
60
  'anno-undefined-def': { severity: 'Warning' }, // for annotate statement (for CSN or CDL path cont)
61
61
  'anno-undefined-element': { severity: 'Warning' },
62
62
  'anno-undefined-param': { severity: 'Warning' },
63
- 'anno-unexpected-ellipsis-layers': { severity: 'Error', configurableFor: true }, // TODO(v3): Merge with anno-unexpected-ellipsis and make non-configurable
63
+ 'anno-unexpected-ellipsis': { severity: 'Error', configurableFor: 'v3' },
64
64
 
65
65
  'args-expected-named': { severity: 'Error', configurableFor: 'deprecated' }, // future --sloppy
66
66
  'args-no-params': { severity: 'Error', configurableFor: 'deprecated' }, // future --sloppy
@@ -185,6 +185,7 @@ const centralMessages = {
185
185
  'odata-spec-violation-property-name': { severity: 'Warning' }, // more than 30 chars
186
186
  'odata-anno-preproc': { severity: 'Warning', configurableFor: true },
187
187
  'odata-anno-dict': { severity: 'Warning', configurableFor: true },
188
+ 'odata-anno-vocref': { severity: 'Warning', configurableFor: true },
188
189
  'odata-anno-dict-enum': { severity: 'Error' },
189
190
  'odata-anno-value': { severity: 'Warning', configurableFor: true },
190
191
  'odata-anno-type': { severity: 'Warning', configurableFor: true },
@@ -220,13 +221,16 @@ for (const oldName in oldMessageIds) {
220
221
 
221
222
  const centralMessageTexts = {
222
223
  'api-invalid-option': {
223
- // TODO: too many different error situations for one message id,
224
- // TODO: use message parameter - do not use quotes in message texts
225
- std: 'Option $(NAME) is no longer supported! Use SNAPI options instead',
226
- magicVars: 'Option “magicVars” is no longer supported! Use “variableReplacements” instead. See <https://cap.cloud.sap/docs/guides/databases#configuring-variables> for details',
227
- user: 'Option “variableReplacements” expects “$user” instead of “user”. See <https://cap.cloud.sap/docs/guides/databases#configuring-variables> for details',
228
- locale: 'Option “variableReplacements” expects “$user.locale” instead of “locale”. See <https://cap.cloud.sap/docs/guides/databases#configuring-variables> for details',
229
- 'noDollar': 'Option “variableReplacements” does not know $(NAME). Did you forget a leading “$”?'
224
+ std: 'Invalid option $(NAME)!',
225
+ deprecated: 'Option $(NAME) is no longer supported! Use latest API options instead',
226
+ magicVars: 'Option $(PROP) is no longer supported! Use $(OTHERPROP) instead. See <https://cap.cloud.sap/docs/guides/databases#configuring-variables> for details',
227
+ },
228
+
229
+ 'api-invalid-variable-replacement': {
230
+ std: 'Option $(OPTION) does not support $(NAME)',
231
+ user: 'Option $(OPTION) expects $(PROP) instead of $(OTHERPROP). See <https://cap.cloud.sap/docs/guides/databases#configuring-variables> for details',
232
+ locale: 'Option $(OPTION) expects $(PROP) instead of $(OTHERPROP). See <https://cap.cloud.sap/docs/guides/databases#configuring-variables> for details',
233
+ 'noDollar': 'Option $(OPTION) does not know $(NAME). Did you forget a leading $(CODE)?'
230
234
  },
231
235
 
232
236
  'anno-duplicate': {
@@ -244,7 +248,6 @@ const centralMessageTexts = {
244
248
  'anno-unstable-array': 'Unstable order of array items due to repeated assignments for $(ANNO)',
245
249
  'anno-mismatched-ellipsis': 'An array with $(CODE) can only be used if there is an assignment below with an array value',
246
250
  'anno-unexpected-ellipsis': 'No base annotation available to apply $(CODE)',
247
- 'anno-unexpected-ellipsis-layers': 'No base annotation available to apply $(CODE)',
248
251
  'chained-array-of': '"Array of"/"many" must not be chained with another "array of"/"many" inside a service',
249
252
 
250
253
  'check-proper-type-of': {
@@ -268,6 +271,12 @@ const centralMessageTexts = {
268
271
  mixin: 'A mixin name starting with $(NAME) might shadow a special variable - replace by another name',
269
272
  },
270
273
 
274
+ 'name-missing-alias': {
275
+ std: 'Missing table alias for this subquery',
276
+ duplicate: 'Missing table alias for this subquery; add $(CODE) to fix name clash of internal and explicit table alias',
277
+ hdbcds: 'Missing table alias for a subquery; SAP HANA CDS requires table aliases'
278
+ },
279
+
271
280
  // Syntax messages, both CDL and CSN parser: ----------------------------------
272
281
  'syntax-deprecated-abstract': {
273
282
  std: 'Abstract entity definitions are deprecated; use aspect definitions instead',
@@ -300,9 +309,9 @@ const centralMessageTexts = {
300
309
  'std': 'Invalid literal value',
301
310
  'uneven-hex': 'A binary literal must have an even number of characters',
302
311
  'invalid-hex': 'A binary literal must only contain characters ‹0-9›, ‹a-f› and ‹A-F›',
303
- 'time': 'A time literal must look like ‹hh:mm:ss› or ‹hh:mm› where each letter represents a digit',
312
+ 'time': 'A time literal must look like ‹hh:mm:ss› or ‹hh:mm› where each letter represents a digit. A timezone is optional',
304
313
  'date': 'A date literal must look like ‹YYYY-MM-DD› where each letter represents a digit',
305
- 'timestamp': 'A timestamp literal must look like ‹YYYY-MM-DD hh:mm:ss.u…u› or ‹YYYY-MM-DD hh:mm› where each letter represents a digit, ‹u…u› represents 1 to 7 digits',
314
+ 'timestamp': 'A timestamp literal must look like ‹YYYY-MM-DD hh:mm:ss.u…u› or ‹YYYY-MM-DD hh:mm› where each letter represents a digit, ‹u…u› represents 1 to 7 digits. A timezone is optional',
306
315
  'number': 'The string value in property $(PROP) does not represent a number',
307
316
  'expecting': 'Expecting literal type $(OP) for the value in property $(OTHERPROP)',
308
317
  'typeof': 'String $(RAWVALUE) is no valid literal type for the string value in property $(OTHERPROP)',
@@ -384,6 +393,10 @@ const centralMessageTexts = {
384
393
  'zero-parens': 'Deprecated CSN v.0.1.0 representation of expressions in parentheses',
385
394
  'zero-replace': 'Replace CSN v0.1.0 value in $(PROP) by $(VALUE)',
386
395
  },
396
+ 'syntax-deprecated-type-ref': {
397
+ std: 'Expecting a string as value for property $(PROP) for a reference to a definition',
398
+ 'ref-item': 'Expecting a string as value for property $(PROP) for a type reference to an element',
399
+ },
387
400
 
388
401
  'syntax-expecting-object': {
389
402
  std: 'Expecting object for property $(PROP)',
@@ -438,6 +451,12 @@ const centralMessageTexts = {
438
451
  annotation: 'Annotation definitions can\'t have calculated elements',
439
452
  param: 'Parameters can\'t have calculated elements',
440
453
  },
454
+ 'ref-invalid-calc-elem': {
455
+ std: 'Can\'t include artifact with calculated element',
456
+ event: 'An event can\'t include an entity with calculated elements',
457
+ type: 'A type can\'t include an entity with calculated elements',
458
+ annotation: 'An annotation can\'t include an entity with calculated elements',
459
+ },
441
460
  'def-unsupported-calc-elem': {
442
461
  std: 'Calculated elements are not supported',
443
462
  nested: 'Calculated elements in structures are not supported, yet'
@@ -526,6 +545,7 @@ const centralMessageTexts = {
526
545
  'ref-unexpected-navigation': {
527
546
  std: 'Can\'t follow association $(ID) of path $(ELEMREF) in an ON-condition; only foreign keys can be referred to, but not $(NAME)',
528
547
  unmanaged: 'Can\'t follow unmanaged association $(ID) of path $(ELEMREF) in an ON-condition; only foreign keys can be referred to',
548
+ unmanagedleaf: 'Unexpected unmanged association as final path step of $(ELEMREF) in an ON-condition',
529
549
  },
530
550
 
531
551
  'type-unexpected-typeof': {
@@ -557,15 +577,21 @@ const centralMessageTexts = {
557
577
  element: 'Artifact $(ART) has no element $(NAME)',
558
578
  enum: 'Artifact $(ART) has no enum $(NAME)',
559
579
  returns: 'Return value of $(ART) has no element $(NAME)',
560
- 'entity-element': 'Elements of entity types can\'t be annotated',
580
+ 'enum-returns': 'Return value of $(ART) has no enum $(NAME)',
561
581
  },
562
582
  'anno-undefined-action': {
563
583
  std: 'Action $(ART) has not been found',
564
- action: 'Artifact $(ART) has no action $(MEMBER)'
584
+ action: 'Artifact $(ART) has no action $(NAME)'
565
585
  },
566
586
  'anno-undefined-param': {
567
587
  std: 'Parameter $(ART) has not been found',
568
- param: 'Artifact $(ART) has no parameter $(MEMBER)'
588
+ param: 'Artifact $(ART) has no parameter $(NAME)'
589
+ },
590
+
591
+ // annotation checks against their definition
592
+ 'anno-expecting-value': {
593
+ 'std': 'Expecting a value for the annotation; see annotation definition for $(ANNO)',
594
+ 'type': 'Expecting a value of type $(TYPE) for the annotation'
569
595
  },
570
596
 
571
597
  'def-unexpected-paramview-assoc': {
@@ -622,7 +648,10 @@ const centralMessageTexts = {
622
648
  action: 'Duplicate definition of action or function $(NAME)',
623
649
  param: 'Duplicate definition of parameter $(NAME)',
624
650
  alias: 'Duplicate definition of table alias or mixin $(NAME)',
651
+ 'include-elements': 'Duplicate element $(NAME) through multiple includes $(SORTED_ARTS)',
652
+ 'include-actions': 'Duplicate action or function $(NAME) through multiple includes $(SORTED_ARTS)',
625
653
  },
654
+ // TODO: Remove in v4, use duplicate-definition
626
655
  'ref-duplicate-include-member': {
627
656
  std: 'Duplicate member $(NAME) through multiple includes $(SORTED_ARTS)',
628
657
  elements: 'Duplicate element $(NAME) through multiple includes $(SORTED_ARTS)',
@@ -645,18 +674,18 @@ const centralMessageTexts = {
645
674
  'extend-unexpected-include': 'Can\'t extend $(META) with includes',
646
675
  'ref-expecting-bare-aspect': 'An aspect without elements is expected here',
647
676
 
677
+ 'ext-duplicate-same-file': 'Duplicate extension with $(PROP) in same file',
648
678
  'ext-duplicate-extend-type': 'Duplicate type extension for type $(TYPE)',
649
679
  'ext-duplicate-extend-type-unrelated-layer': 'Duplicate type extension for type $(TYPE)',
650
680
  'ext-invalid-type-property': {
651
- std: 'Property $(PROP) can only be extended',
652
- 'new-prop': 'Property $(PROP) can only be extended, not added',
681
+ std: 'Type property $(PROP) can only be extended',
682
+ 'indirect': 'Type property $(PROP) can only be extended if directly provided at the definition',
683
+ 'new-prop': 'Type property $(PROP) can only be extended, not added',
684
+ string: 'Only numerical properties can be extended, but found string for $(PROP)',
653
685
  // eslint-disable-next-line max-len
654
- smaller: 'Property $(PROP) can only be extended, but $(VALUE) is smaller than $(NUMBER) of type definition',
686
+ number: 'Value of type property $(PROP) must be $(NUMBER) or higher, it can\'t be smaller than originally provided',
655
687
  // eslint-disable-next-line max-len
656
- 'ext-smaller': 'Property $(PROP) can only be extended, but extended value $(VALUE) is smaller than $(NUMBER) from previous type extension',
657
- prop: 'Type property $(PROP) can\'t be extended',
658
- scale: 'If property $(PROP) is increased, then so must $(OTHERPROP)',
659
- string: 'Only numerical properties can be extended, but found string for $(PROP)',
688
+ scale: 'With the extension for type property $(OTHERPROP), the value of $(PROP) must be $(NUMBER) or higher',
660
689
  },
661
690
  'ref-expected-scalar-type': {
662
691
  std: 'Only scalar type definitions can be extended with type properties',
@@ -687,6 +716,12 @@ const centralMessageTexts = {
687
716
  'ref-sloppy-target': 'An entity or an aspect (not type) is expected here',
688
717
  'ref-sloppy-event-type': 'A type, an element, an event, or a service entity is expected here',
689
718
 
719
+ 'ref-ambiguous': {
720
+ std: 'Replace ambiguous $(ID) by $(NAMES)',
721
+ few: 'Replace ambiguous $(ID) by $(NAMES) or a new table alias for sub-queries that don\'t have one',
722
+ none: 'Ambiguous $(ID) requires an explicit table alias, but there are none: add table aliases to all sub-queries to disambiguate $(ID)',
723
+ },
724
+
690
725
  'type-managed-composition': {
691
726
  std: 'Managed compositions can\'t be used in types', // yet
692
727
  sub: 'Managed compositions can\'t be used in sub elements',
@@ -713,7 +748,8 @@ const centralMessageTexts = {
713
748
  'odata-spec-violation-id': {
714
749
  std: 'Expected EDM name $(ID) to start with a letter or underscore, followed by at most 127 letters, underscores or digits',
715
750
  'v2firstchar': 'Unexpected first character $(PROP) of EDM Name $(ID) for OData $(VERSION)',
716
- 'qualifier': 'Expected annotation qualifier $(ID) to start with a letter or underscore, followed by at most 127 letters, underscores or digits'
751
+ 'qualifier': 'Expected annotation qualifier $(ID) to start with a letter or underscore, followed by at most 127 letters, underscores or digits',
752
+ 'vocrefalias': 'Expected value $(VALUE) of vocabulary reference attribute $(ID) to start with a letter or underscore, followed by at most 127 letters, underscores or digits'
717
753
  },
718
754
  // version independent messages
719
755
  'odata-spec-violation-key-array': {
@@ -782,6 +818,12 @@ const centralMessageTexts = {
782
818
  'experimental': '$(ANNO) is experimental and can be changed or removed at any time, do not use productively!',
783
819
  'redefinition': '$(ANNO) is an official OASIS/SAP annotation and can\'t be redefined'
784
820
  },
821
+ 'odata-anno-vocref': {
822
+ 'std': 'Vocabulary reference $(ID) doesn\'t match alias $(NAME), reference is ignored',
823
+ 'redef': 'Vocabulary reference $(ID) is the alias of the official OASIS/SAP vocabulary $(TYPE) which can\'t be redefined, reference is ignored',
824
+ 'service': 'Vocabulary reference collides with service $(NAME), reference is ignored',
825
+ 'malformed': 'Vocabulary reference $(ID) has invalid or missing value for attribute $(NAME), reference is ignored'
826
+ },
785
827
  'odata-anno-dict-enum': {
786
828
  'std' : 'Unexpected annotation definition $(NAME) with many enum type',
787
829
  'type': 'Unexpected annotation definition $(NAME) with many enum type $(TYPE)',