@sap/cds-compiler 4.7.6 → 4.9.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 (129) hide show
  1. package/CHANGELOG.md +63 -3
  2. package/bin/cds_remove_invalid_whitespace.js +135 -0
  3. package/bin/cds_update_annotations.js +180 -0
  4. package/bin/cds_update_identifiers.js +3 -4
  5. package/bin/cdsc.js +28 -1
  6. package/bin/cdshi.js +13 -3
  7. package/doc/CHANGELOG_BETA.md +24 -1
  8. package/lib/api/main.js +119 -46
  9. package/lib/api/options.js +51 -0
  10. package/lib/api/validate.js +1 -5
  11. package/lib/base/builtins.js +116 -0
  12. package/lib/base/keywords.js +5 -1
  13. package/lib/base/location.js +91 -14
  14. package/lib/base/message-registry.js +76 -46
  15. package/lib/base/messages.js +121 -35
  16. package/lib/base/model.js +4 -7
  17. package/lib/checks/actionsFunctions.js +3 -3
  18. package/lib/checks/annotationsOData.js +3 -0
  19. package/lib/checks/defaultValues.js +5 -2
  20. package/lib/checks/elements.js +2 -1
  21. package/lib/checks/enricher.js +2 -2
  22. package/lib/checks/queryNoDbArtifacts.js +5 -3
  23. package/lib/checks/utils.js +1 -1
  24. package/lib/checks/validator.js +8 -56
  25. package/lib/compiler/assert-consistency.js +11 -7
  26. package/lib/compiler/builtins.js +0 -74
  27. package/lib/compiler/checks.js +105 -29
  28. package/lib/compiler/define.js +37 -25
  29. package/lib/compiler/extend.js +35 -12
  30. package/lib/compiler/index.js +9 -10
  31. package/lib/compiler/lsp-api.js +5 -0
  32. package/lib/compiler/populate.js +13 -5
  33. package/lib/compiler/propagator.js +24 -18
  34. package/lib/compiler/resolve.js +47 -45
  35. package/lib/compiler/shared.js +61 -21
  36. package/lib/compiler/tweak-assocs.js +15 -90
  37. package/lib/compiler/utils.js +3 -3
  38. package/lib/compiler/xpr-rewrite.js +689 -0
  39. package/lib/compiler/{classes.js → xsn-model.js} +0 -16
  40. package/lib/edm/annotations/edmJson.js +7 -5
  41. package/lib/edm/annotations/genericTranslation.js +149 -71
  42. package/lib/edm/csn2edm.js +25 -9
  43. package/lib/edm/edm.js +7 -7
  44. package/lib/edm/edmInboundChecks.js +57 -5
  45. package/lib/edm/edmPreprocessor.js +54 -25
  46. package/lib/edm/edmUtils.js +3 -16
  47. package/lib/gen/Dictionary.json +138 -14
  48. package/lib/gen/language.checksum +1 -1
  49. package/lib/gen/language.interp +1 -1
  50. package/lib/gen/languageParser.js +2085 -1989
  51. package/lib/json/csnVersion.js +7 -4
  52. package/lib/json/from-csn.js +21 -11
  53. package/lib/json/to-csn.js +8 -4
  54. package/lib/language/antlrParser.js +1 -1
  55. package/lib/language/genericAntlrParser.js +23 -16
  56. package/lib/language/multiLineStringParser.js +2 -2
  57. package/lib/language/textUtils.js +1 -1
  58. package/lib/main.d.ts +90 -14
  59. package/lib/main.js +9 -1
  60. package/lib/model/cloneCsn.js +21 -9
  61. package/lib/model/csnRefs.js +153 -42
  62. package/lib/model/csnUtils.js +14 -11
  63. package/lib/model/enrichCsn.js +4 -2
  64. package/lib/model/revealInternalProperties.js +2 -1
  65. package/lib/model/sortViews.js +14 -6
  66. package/lib/modelCompare/compare.js +135 -122
  67. package/lib/optionProcessor.js +49 -2
  68. package/lib/render/DuplicateChecker.js +6 -6
  69. package/lib/render/manageConstraints.js +1 -0
  70. package/lib/render/toCdl.js +6 -3
  71. package/lib/render/toHdbcds.js +4 -48
  72. package/lib/render/toSql.js +6 -3
  73. package/lib/transform/addTenantFields.js +58 -35
  74. package/lib/transform/db/applyTransformations.js +34 -1
  75. package/lib/transform/db/constraints.js +1 -1
  76. package/lib/transform/db/expansion.js +11 -3
  77. package/lib/transform/db/flattening.js +71 -46
  78. package/lib/transform/db/groupByOrderBy.js +2 -2
  79. package/lib/transform/db/temporal.js +6 -3
  80. package/lib/transform/db/transformExists.js +2 -2
  81. package/lib/transform/db/views.js +1 -4
  82. package/lib/transform/effective/annotations.js +194 -0
  83. package/lib/transform/effective/main.js +11 -10
  84. package/lib/transform/effective/misc.js +45 -14
  85. package/lib/transform/effective/types.js +4 -3
  86. package/lib/transform/forOdata.js +29 -12
  87. package/lib/transform/forRelationalDB.js +104 -113
  88. package/lib/transform/localized.js +7 -6
  89. package/lib/transform/odata/flattening.js +228 -107
  90. package/lib/transform/odata/toFinalBaseType.js +10 -26
  91. package/lib/transform/odata/typesExposure.js +41 -25
  92. package/lib/transform/parseExpr.js +4 -7
  93. package/lib/transform/transformUtils.js +50 -43
  94. package/lib/transform/translateAssocsToJoins.js +48 -48
  95. package/lib/transform/universalCsn/coreComputed.js +2 -1
  96. package/lib/transform/universalCsn/universalCsnEnricher.js +12 -16
  97. package/package.json +2 -2
  98. package/share/messages/README.md +4 -0
  99. package/share/messages/anno-duplicate-unrelated-layer.md +1 -1
  100. package/share/messages/anno-missing-rewrite.md +45 -0
  101. package/share/messages/check-proper-type-of.md +1 -1
  102. package/share/messages/def-duplicate-autoexposed.md +1 -1
  103. package/share/messages/extend-repeated-intralayer.md +3 -16
  104. package/share/messages/extend-unrelated-layer.md +1 -1
  105. package/share/messages/message-explanations.json +2 -0
  106. package/share/messages/redirected-to-ambiguous.md +1 -1
  107. package/share/messages/redirected-to-complex.md +1 -1
  108. package/share/messages/redirected-to-unrelated.md +1 -1
  109. package/share/messages/rewrite-not-supported.md +1 -1
  110. package/share/messages/syntax-expecting-unsigned-int.md +2 -2
  111. package/share/messages/type-missing-enum-value.md +59 -0
  112. package/share/messages/wildcard-excluding-one.md +1 -1
  113. package/bin/.eslintrc.json +0 -17
  114. package/lib/api/.eslintrc.json +0 -37
  115. package/lib/checks/.eslintrc.json +0 -31
  116. package/lib/compiler/.eslintrc.json +0 -8
  117. package/lib/edm/.eslintrc.json +0 -46
  118. package/lib/inspect/.eslintrc.json +0 -4
  119. package/lib/json/.eslintrc.json +0 -4
  120. package/lib/language/.eslintrc.json +0 -4
  121. package/lib/model/.eslintrc.json +0 -13
  122. package/lib/modelCompare/utils/.eslintrc.json +0 -22
  123. package/lib/render/.eslintrc.json +0 -22
  124. package/lib/transform/.eslintrc.json +0 -13
  125. package/lib/transform/db/.eslintrc.json +0 -41
  126. package/lib/transform/draft/.eslintrc.json +0 -4
  127. package/lib/transform/effective/.eslintrc.json +0 -4
  128. package/lib/transform/universalCsn/.eslintrc.json +0 -37
  129. package/lib/utils/.eslintrc.json +0 -7
package/CHANGELOG.md CHANGED
@@ -7,6 +7,64 @@
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 4.9.0 - 2024-04-25
11
+
12
+ ### Added
13
+
14
+ - compiler: Annotations with expressions are now rewritten when propagated.
15
+ - for.seal: Added API function that produces a CSN for SEAL.
16
+ - for.odata/to.edm(x): Support annotation path expressions including path flattening.
17
+
18
+ ### Changed
19
+
20
+ - parser: A space between `.` and `*`/`{` (nested projections) is now a warning.
21
+ Use `bin/cds_remove_invalid_whitespace.js` to automatically fix this warning.
22
+ - compiler:
23
+ + Published compositions with filters are changed to associations.
24
+ + Expressions as annotation values are rejected for few known annotations that don't expect them.
25
+ - Update OData vocabularies: 'Aggregation', 'Capabilities', 'Common', 'Hierarchy', 'PersonalData', 'Session', 'UI'.
26
+ - to.edm(x): Exposed anonymous parameter types are now prefixed with `ap`, `bap` and `ep` for actions, bound actions and entities.
27
+
28
+ ### Fixed
29
+
30
+ - compiler:
31
+ + Deprecated `$parameters` is no longer proposed in code completion.
32
+ + Duplicate mixin definitions lead to failing name resolution.
33
+ - to.cdl: Types were always rendered for associations with filters, even if it would lead to a compilation failure.
34
+ - to.edm(x):
35
+ + Fix a recursion bug in entity parameter handling.
36
+ + Fix event exclusion in service preprocessing.
37
+
38
+ ## Version 4.8.0 - 2024-03-21
39
+
40
+ ### Added
41
+
42
+ - compiler: Type `cds.Vector` was added. It is mapped to `REAL_VECTOR` on SAP HANA.
43
+ - Support associations to/from entities with parameters for SAP HANA SQL (hdi/direct).
44
+ - to.sql/to.hdi:
45
+ + SAP HANA keywords `ABSOLUTE`, `REAL_VECTOR`, and `ST_ASESRIJSON` are now included for smart quoting.
46
+ +PostgreSQL keyword `SYSTEM_USER` is now included for smart quoting.
47
+ - API: Added `to.sql.postgres.keywords` and `to.sql.h2.keywords`.
48
+ They contain keywords for the respective SQL dialect.
49
+
50
+ ### Changed
51
+
52
+ - compiler: Overriding an included element must not change the type to an association
53
+ if it wasn't an association before and vice versa.
54
+ - Update OData vocabularies: 'Authorization', 'Common', 'UI'.
55
+
56
+ ### Fixed
57
+
58
+ - compiler: `cast()`s to structured types and associations are now rejected. They could lead to crashes before.
59
+ - to.edm(x):
60
+ + Reject action/function return types that are declared `many of many`.
61
+ + Render user defined annotation type `cds.Integer` as `Edm.Int`.
62
+ - to.sql|hdi|hdbcds:
63
+ + Correctly handle `.list` during flattening.
64
+ + Improve handling of `.items`.
65
+ - to.sql|hdi.migration:
66
+ + Turn types and aspects into dummies to reduce CSN size.
67
+ + Correctly detect a removed `.default` and forcefully set the default to `null`.
10
68
 
11
69
  ## Version 4.7.6 - 2024-02-29
12
70
 
@@ -27,14 +85,15 @@ The compiler behavior concerning `beta` features can change at any time without
27
85
 
28
86
  ### Fixed
29
87
 
30
- - Restored compatibility with `@sap/cds-dk` for Java runtime
88
+ - Restored compatibility with `@sap/cds-dk` for Java runtime.
89
+
31
90
 
32
91
 
33
92
  ## Version 4.7.0 - 2024-02-23
34
93
 
35
94
  ### Added
36
95
 
37
- - compiler: Virtual elements can now be referenced in expressions in annotation
96
+ - compiler: Virtual elements can now be referenced in expressions in annotation.
38
97
 
39
98
  ### Changed
40
99
 
@@ -48,7 +107,8 @@ The compiler behavior concerning `beta` features can change at any time without
48
107
  - compiler: published associations with filters sometimes had the filter applied twice
49
108
  if used in inline aspect compositions
50
109
  - to.sql|hdi|hdbcds[.migration]:
51
- + With `withHanaAssociations`: `false`, remove the association elements from the final CSN in order to correctly detect them during migration scenarios and
110
+ + With `withHanaAssociations`: `false`, remove the association elements from the final CSN in order
111
+ to correctly detect them during migration scenarios and
52
112
  with generated `hdbcds`.
53
113
  + Skip expensive processing (for calculated elements and nested projections) if the model doesn't use it.
54
114
  + Don't greedily set alias on subqueries if not required.
@@ -0,0 +1,135 @@
1
+ #!/usr/bin/env node
2
+
3
+ // Remove whitespace where the compiler does not expect it and will
4
+ // emit an error in the next major version.
5
+ //
6
+ // This script removes whitespace where necessary.
7
+ // It does not remove comments, even though they count as whitespace.
8
+ //
9
+ // Example CDS:
10
+ // entity P as projection on E { s. * };
11
+ // will become:
12
+ // entity P as projection on E { s.* };
13
+ //
14
+ // Usage:
15
+ // ./cds_remove_invalid_whitespace.js my_file.cds
16
+ //
17
+ // If you want to update all files in a directory, you can use
18
+ // this shell script:
19
+ // find . -type f -iname '*.cds' -exec ./cds_remove_invalid_whitespace.js {} \;
20
+ //
21
+ // Note that you need to update the path to this script in the commands above.
22
+ //
23
+
24
+ 'use strict';
25
+
26
+ const parseLanguage = require('../lib/language/antlrParser');
27
+ const { createMessageFunctions } = require('../lib/base/messages');
28
+
29
+ const fs = require('fs');
30
+ const path = require('path');
31
+
32
+ const cliArgs = process.argv.slice(2);
33
+ const filepath = cliArgs[0];
34
+
35
+ if (filepath === '--help' || filepath === '-h')
36
+ exitError();
37
+
38
+ if (cliArgs.length !== 1)
39
+ exitError(`Expected exactly one argument, ${cliArgs.length} given`);
40
+
41
+ if (!filepath)
42
+ exitError('Expected non-empty filepath as argument!');
43
+
44
+ // Do not use allow-list approach.
45
+ // There may be CDS files with other extensions than `.cds`.
46
+ if (filepath.endsWith('.csn') || filepath.endsWith('.json'))
47
+ exitError('Only CDS files can be passed! Found CSN file!');
48
+
49
+ const sourceStr = fs.readFileSync(filepath, 'utf-8');
50
+ const newSourceStr = modernizeWhitespace(sourceStr, filepath);
51
+ if (newSourceStr !== sourceStr)
52
+ fs.writeFileSync(filepath, newSourceStr);
53
+ process.exit(0); // success
54
+
55
+ // --------------------------------------------------------
56
+
57
+ function modernizeWhitespace( source, filename ) {
58
+ const options = { messages: [], attachTokens: true };
59
+ const messageFunctions = createMessageFunctions( options, 'parse', null );
60
+
61
+ // parseLanguage does not throw on CompilationError, so
62
+ // we do not need a try...catch block.
63
+ const ast = parseLanguage(source, filename, options, messageFunctions);
64
+
65
+ // To avoid spam, only report errors.
66
+ // Users should use the compiler to get all messages.
67
+ const errors = options.messages.filter(msg => (msg.severity === 'Error'));
68
+ if (errors.length > 0) {
69
+ errors.forEach((msg) => {
70
+ console.error(msg.toString());
71
+ });
72
+ console.error(`Found ${errors.length} errors! \n`);
73
+ exitError('The CDS parser emitted errors. Fix them first and try again.');
74
+ }
75
+
76
+ if (!ast.artifacts)
77
+ return source;
78
+
79
+ let currentOffset = 0;
80
+
81
+ const { tokens } = ast.tokenStream;
82
+ for (let i = 0; i < tokens.length; ++i) {
83
+ const token = tokens[i];
84
+ const next = tokens[i + 1];
85
+ if (next && token.type === ast.tokenStream.DOTbeforeBRACE &&
86
+ (next.type === ast.tokenStream.ASTERISK || next.type === ast.tokenStream.BRACE))
87
+ updateWhitespace(token, next);
88
+ }
89
+
90
+ return source;
91
+
92
+ // -----------------------------------------------
93
+
94
+ function updateWhitespace( dot, braceOrAsterisk ) {
95
+ if (dot.stop === braceOrAsterisk.start)
96
+ return;
97
+
98
+ const from = dot.stop + currentOffset + 1; // end points at the position *before* the character
99
+ const to = braceOrAsterisk.start + currentOffset;
100
+
101
+ source = replaceSliceInSource(source, from, to, '');
102
+
103
+ currentOffset -= to - from;
104
+ }
105
+ }
106
+
107
+ /**
108
+ * Replaces a given span with @p replaceWith
109
+ *
110
+ * @param {string} source
111
+ * @param {number} startIndex
112
+ * @param {number} endIndex
113
+ * @param {string} replaceWith
114
+ * @return {string}
115
+ */
116
+ function replaceSliceInSource( source, startIndex, endIndex, replaceWith ) {
117
+ return source.substring(0, startIndex) +
118
+ replaceWith +
119
+ source.substring(endIndex);
120
+ }
121
+
122
+ /**
123
+ * @param {string} [msg]
124
+ */
125
+ function exitError( msg ) {
126
+ if (msg)
127
+ console.error(msg);
128
+ usage();
129
+ process.exit(1);
130
+ }
131
+
132
+ function usage() {
133
+ console.error('');
134
+ console.error(`usage: ${path.basename(process.argv[1])} <filename>`);
135
+ }
@@ -0,0 +1,180 @@
1
+ #!/usr/bin/env node
2
+
3
+ // Update CDS Annotation References to use v4 expression syntax.
4
+ //
5
+ // This script replaces bare, unchecked references in annotation assignments
6
+ // with the new syntax using `(`.
7
+ //
8
+ // Example CDS:
9
+ // @anno: ID entity E { key ID : String; };
10
+ // will become:
11
+ // @anno: (ID) entity E { key ID : String; };
12
+ //
13
+ // Usage:
14
+ // ./cds_update_annotations.js my_file.cds
15
+ //
16
+ // If you want to update all identifiers in a directory, you can use
17
+ // this Shell script:
18
+ // find . -type f -iname '*.cds' -exec ./cds_update_annotations.js {} \;
19
+ //
20
+ // Note that you need to update the path to this script in the commands above.
21
+ //
22
+
23
+ 'use strict';
24
+
25
+ const parseLanguage = require('../lib/language/antlrParser');
26
+ const { createMessageFunctions } = require('../lib/base/messages');
27
+
28
+ const fs = require('fs');
29
+ const path = require('path');
30
+ const { forEachMemberRecursively } = require('../lib/base/model');
31
+
32
+ const cliArgs = process.argv.slice(2);
33
+ const filepath = cliArgs[0];
34
+
35
+ if (filepath === '--help' || filepath === '-h')
36
+ exitError();
37
+
38
+ if (cliArgs.length !== 1)
39
+ exitError(`Expected exactly one argument, ${cliArgs.length} given`);
40
+
41
+ if (!filepath)
42
+ exitError('Expected non-empty filepath as argument!');
43
+
44
+ // Do not use allow-list approach.
45
+ // There may be CDS files with other extensions than `.cds`.
46
+ if (filepath.endsWith('.csn') || filepath.endsWith('.json'))
47
+ exitError('Only CDS files can be passed! Found CSN file!');
48
+
49
+ const sourceStr = fs.readFileSync(filepath, 'utf-8');
50
+ const newSourceStr = modernizeAnnotationExpressions(sourceStr, filepath);
51
+ if (newSourceStr !== sourceStr)
52
+ fs.writeFileSync(filepath, newSourceStr);
53
+ process.exit(0); // success
54
+
55
+ // --------------------------------------------------------
56
+
57
+ function modernizeAnnotationExpressions( source, filename ) {
58
+ const options = { messages: [], attachTokens: true };
59
+ const messageFunctions = createMessageFunctions( options, 'parse', null );
60
+
61
+ // parseLanguage does not throw on CompilationError, so
62
+ // we do not need a try...catch block.
63
+ const ast = parseLanguage(source, filename, options, messageFunctions);
64
+
65
+ // To avoid spam, only report errors.
66
+ // Users should use the compiler to get all messages.
67
+ const errors = options.messages.filter(msg => (msg.severity === 'Error'));
68
+ if (errors.length > 0) {
69
+ errors.forEach((msg) => {
70
+ console.error(msg.toString());
71
+ });
72
+ console.error(`Found ${errors.length} errors! \n`);
73
+ exitError('The parser emitted errors. Please fix them first and try again.');
74
+ }
75
+
76
+ if (!ast.artifacts)
77
+ return source;
78
+
79
+ let currentOffset = 0;
80
+
81
+ for (const artName in ast.artifacts) {
82
+ const art = ast.artifacts[artName];
83
+ updateAnnosOfArtifact(art);
84
+ forEachMemberRecursively(art, updateAnnosOfArtifact);
85
+ }
86
+ for (const vocName in ast.vocabularies) {
87
+ const voc = ast.vocabularies[vocName];
88
+ updateAnnosOfArtifact(voc);
89
+ forEachMemberRecursively(voc, updateAnnosOfArtifact);
90
+ }
91
+ for (const ext of ast.extensions)
92
+ updateAnnosOfArtifact(ext);
93
+
94
+ return source;
95
+
96
+ // -----------------------------------------------
97
+
98
+ function updateAnnosOfArtifact( art ) {
99
+ for (const prop in art) {
100
+ if (prop.charAt(0) === '@')
101
+ updateAnno(art[prop]);
102
+ }
103
+ }
104
+
105
+ function updateAnno( anno ) {
106
+ if (anno.literal === 'array') {
107
+ anno.val.forEach(val => updateAnno( val ));
108
+ }
109
+ else if (anno.literal === 'struct') {
110
+ const struct = Object.values(anno.struct);
111
+ struct.forEach(val => updateAnno( val ));
112
+ }
113
+ else if (!anno.$tokenTexts && anno.path) {
114
+ const first = anno.path[0];
115
+ const last = anno.path[anno.path.length - 1];
116
+ insertParentheses(first, last);
117
+ }
118
+ }
119
+
120
+ function findTokenFor( node ) {
121
+ const loc = node.location;
122
+ // We use slow linear search; we could do binary search, but not performance critical.
123
+ const { tokens } = ast.tokenStream;
124
+ for (const token of tokens) {
125
+ if (token.column + 1 === loc.col && token.line === loc.line)
126
+ return token;
127
+ }
128
+ return null;
129
+ }
130
+
131
+ function insertParentheses( first, last ) {
132
+ const firstToken = findTokenFor(first);
133
+ const lastToken = findTokenFor(last);
134
+
135
+ if (!firstToken?.stop || !lastToken?.stop)
136
+ throw new Error(`INTERNAL ERROR: Identifier at ${firstToken?.start} or ${lastToken?.start} has no end! (${filepath})`);
137
+
138
+ const start = firstToken.start + currentOffset;
139
+ const end = lastToken.stop + currentOffset + 1; // end points at the position *before* the character
140
+
141
+ const original = source.substring(start, end);
142
+ if (original.includes('@'))
143
+ return; // we ignore annotation references for now
144
+
145
+ const newSource = `( ${original} )`;
146
+ source = replaceSliceInSource(source, start, end, newSource);
147
+
148
+ currentOffset += (newSource.length - original.length);
149
+ }
150
+ }
151
+
152
+ /**
153
+ * Replaces a given span with @p replaceWith
154
+ *
155
+ * @param {string} source
156
+ * @param {number} startIndex
157
+ * @param {number} endIndex
158
+ * @param {string} replaceWith
159
+ * @return {string}
160
+ */
161
+ function replaceSliceInSource( source, startIndex, endIndex, replaceWith ) {
162
+ return source.substring(0, startIndex) +
163
+ replaceWith +
164
+ source.substring(endIndex);
165
+ }
166
+
167
+ /**
168
+ * @param {string} [msg]
169
+ */
170
+ function exitError( msg ) {
171
+ if (msg)
172
+ console.error(msg);
173
+ usage();
174
+ process.exit(1);
175
+ }
176
+
177
+ function usage() {
178
+ console.error('');
179
+ console.error(`usage: ${path.basename(process.argv[1])} <filename>`);
180
+ }
@@ -1,6 +1,5 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- //
4
3
  // Update CDS Delimited Identifiers
5
4
  //
6
5
  // This script replaces the old delimited identifier style with the new one
@@ -12,11 +11,11 @@
12
11
  // entity ![My Entity] { ... }
13
12
  //
14
13
  // Usage:
15
- // cds_update_identifiers.js my_file.cds
14
+ // ./cds_update_identifiers.js my_file.cds
16
15
  //
17
16
  // If you want to update all identifiers in a directory, you can use
18
17
  // this Shell script:
19
- // find . -type f -iname '*.cds' -exec cds_update_identifiers.js {} \;
18
+ // find . -type f -iname '*.cds' -exec ./cds_update_identifiers.js {} \;
20
19
  //
21
20
  // Note that you need to update the path to this script in the commands above.
22
21
  //
@@ -70,7 +69,7 @@ function modernizeIdentifierStyle( source, filename ) {
70
69
  console.error(msg.toString());
71
70
  });
72
71
  console.error(`Found ${errors.length} errors! \n`);
73
- exitError('The parser emitted errors. Please fix them first and try again.');
72
+ exitError('The CDS parser emitted errors. Fix them first and try again.');
74
73
  }
75
74
 
76
75
  let currentOffset = 0;
package/bin/cdsc.js CHANGED
@@ -217,7 +217,7 @@ function cdsc_main() {
217
217
  * @param {object} args
218
218
  */
219
219
  function validateDirectBackendOption( command, options, args ) {
220
- if (![ 'toCdl', 'toOdata', 'toHana', 'toCsn', 'toSql' ].includes(command)) {
220
+ if (![ 'toCdl', 'toOdata', 'toHana', 'toCsn', 'toSql', 'forJava' ].includes(command)) {
221
221
  displayUsage(`Option '--direct-backend' can't be used with command '${command}'`,
222
222
  optionProcessor.helpText, 2);
223
223
  }
@@ -272,11 +272,13 @@ function executeCommandLine( command, options, args ) {
272
272
  toCsn,
273
273
  toHana,
274
274
  toOdata,
275
+ forJava,
275
276
  toRename,
276
277
  manageConstraints,
277
278
  toSql,
278
279
  inspect,
279
280
  toEffectiveCsn,
281
+ forSeal,
280
282
  };
281
283
  const commandsWithoutCompilation = {
282
284
  explain,
@@ -317,12 +319,29 @@ function executeCommandLine( command, options, args ) {
317
319
  }
318
320
 
319
321
  function toEffectiveCsn( model ) {
322
+ const features = [ 'resolveSimpleTypes', 'resolveProjections', 'remapOdataAnnotations', 'keepLocalized' ];
323
+ for (const feature of features) {
324
+ if (options[feature]) // map to boolean equivalent
325
+ options[feature] = options[feature] === 'true';
326
+ }
320
327
  const csn = options.directBackend ? model : compactModel(model, options);
321
328
  displayNamedCsn(main.for.effective(csn, options), 'effective');
322
329
 
323
330
  return model;
324
331
  }
325
332
 
333
+ function forSeal( model ) {
334
+ const features = [ 'remapOdataAnnotations' ];
335
+ for (const feature of features) {
336
+ if (options[feature]) // map to boolean equivalent
337
+ options[feature] = options[feature] === 'true';
338
+ }
339
+ const csn = options.directBackend ? model : compactModel(model, options);
340
+ displayNamedCsn(main.for.seal(csn, options), 'seal');
341
+
342
+ return model;
343
+ }
344
+
326
345
  // Execute the command line option 'toCsn' and display the results.
327
346
  // Return the original model (for chaining)
328
347
  function toCsn( model ) {
@@ -336,6 +355,14 @@ function executeCommandLine( command, options, args ) {
336
355
  return model;
337
356
  }
338
357
 
358
+ // Execute the command line command 'forJava' and display the results.
359
+ // Return the original model
360
+ function forJava( model ) {
361
+ const csn = options.directBackend ? model : compactModel(model, options);
362
+ displayNamedCsn( main.for.java( csn, options ), 'java');
363
+ return model;
364
+ }
365
+
339
366
  // Execute the command line option '--to-hana' and display the results.
340
367
  // Return the original model (for chaining)
341
368
  function toHana( model ) {
package/bin/cdshi.js CHANGED
@@ -15,16 +15,26 @@ const compiler = require('../lib/compiler');
15
15
  const fs = require('fs');
16
16
  fs.readFile( '/dev/stdin', 'utf8', highlight );
17
17
 
18
- const categoryChars = {
18
+ const categoryChars = { // default: first char of category name
19
+ // first char lowercase = reference other than via extend/annotate:
19
20
  artref: 'm',
21
+ uncheckedRef: 'r',
22
+ uncheckedAnno: 'a',
20
23
  paramname: 'b',
24
+ typeparamname: 'b',
25
+ // first char uppercase = definition, extend/annotate ref, or path after `namespace`:
21
26
  Entity: 'D',
22
27
  Enum: 'H',
23
28
  Index: 'J',
24
29
  AnnoDef: 'V',
25
- Extend: 'Z',
26
- Annotate: 'Z',
30
+ Ext: 'Z', // extend/annotate on main def other than service/context
31
+ ExtService: 'S', // highlight like service definition
32
+ ExtContext: 'C', // highlight like context definition
33
+ // ExtElement: 'E', // using the first letter is the default
34
+ ExtBoundAction: 'B', // highlight like bound action definition
35
+ ExtParam: 'P', // highlight like entity/action parameter definition
27
36
  Event: 'Y',
37
+ // Remark: do not use `x`/`X` (hex literal `x'1e3d'`)
28
38
  };
29
39
 
30
40
  function highlight( err, buf ) {
@@ -8,7 +8,30 @@ 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 4.x.x - 2024-mm-dd
11
+ ## Version 4.9.0 - 2024-04-25
12
+
13
+ ## Removed `odataAnnotationExpressions`
14
+
15
+ It is now enabled by default.
16
+
17
+ ## Removed `odataPathsInAnnotationExpressions`
18
+
19
+ It is now enabled by default.
20
+
21
+ ## Removed `annotationExpressions`
22
+
23
+ It is now enabled by default.
24
+
25
+ ## Added `temporalRawProjection`
26
+
27
+ Enables revocation of temporal where clause in projections of temporal entities if the
28
+ `@cds.valid { from, to }` annotations on the projection elements have falsy values.
29
+
30
+ ## Version 4.8.0 - 2024-03-21
31
+
32
+ ### Removed `vectorType`
33
+
34
+ It is now always enabled.
12
35
 
13
36
  ### Added `v5preview`
14
37