@sap/cds-compiler 2.15.8 → 3.1.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 (127) hide show
  1. package/CHANGELOG.md +102 -1590
  2. package/bin/.eslintrc.json +2 -1
  3. package/bin/cdsc.js +61 -46
  4. package/doc/API.md +11 -0
  5. package/doc/CHANGELOG_ARCHIVE.md +1592 -0
  6. package/doc/CHANGELOG_BETA.md +26 -5
  7. package/doc/CHANGELOG_DEPRECATED.md +55 -1
  8. package/doc/{DeprecatedOptions.md → DeprecatedOptions_v2.md} +3 -1
  9. package/doc/Versioning.md +20 -1
  10. package/lib/api/.eslintrc.json +2 -2
  11. package/lib/api/main.js +282 -156
  12. package/lib/api/options.js +17 -88
  13. package/lib/api/validate.js +6 -10
  14. package/lib/base/keywords.js +280 -110
  15. package/lib/base/message-registry.js +85 -25
  16. package/lib/base/messages.js +119 -89
  17. package/lib/base/model.js +46 -2
  18. package/lib/base/optionProcessorHelper.js +53 -21
  19. package/lib/checks/actionsFunctions.js +15 -12
  20. package/lib/checks/annotationsOData.js +1 -1
  21. package/lib/checks/cdsPersistence.js +1 -0
  22. package/lib/checks/elements.js +6 -6
  23. package/lib/checks/invalidTarget.js +1 -1
  24. package/lib/checks/nonexpandableStructured.js +1 -1
  25. package/lib/checks/queryNoDbArtifacts.js +2 -1
  26. package/lib/checks/selectItems.js +101 -15
  27. package/lib/checks/types.js +7 -8
  28. package/lib/checks/utils.js +2 -2
  29. package/lib/checks/validator.js +3 -3
  30. package/lib/compiler/assert-consistency.js +78 -21
  31. package/lib/compiler/base.js +6 -4
  32. package/lib/compiler/builtins.js +177 -10
  33. package/lib/compiler/checks.js +1 -1
  34. package/lib/compiler/define.js +28 -23
  35. package/lib/compiler/extend.js +75 -18
  36. package/lib/compiler/finalize-parse-cdl.js +25 -18
  37. package/lib/compiler/index.js +27 -11
  38. package/lib/compiler/moduleLayers.js +7 -0
  39. package/lib/compiler/populate.js +26 -39
  40. package/lib/compiler/propagator.js +12 -7
  41. package/lib/compiler/resolve.js +207 -236
  42. package/lib/compiler/shared.js +100 -93
  43. package/lib/compiler/tweak-assocs.js +13 -20
  44. package/lib/compiler/utils.js +20 -6
  45. package/lib/edm/annotations/preprocessAnnotations.js +12 -13
  46. package/lib/edm/csn2edm.js +35 -37
  47. package/lib/edm/edm.js +22 -13
  48. package/lib/edm/edmAnnoPreprocessor.js +349 -0
  49. package/lib/edm/edmInboundChecks.js +85 -0
  50. package/lib/edm/edmPreprocessor.js +338 -689
  51. package/lib/edm/edmUtils.js +97 -67
  52. package/lib/gen/Dictionary.json +29 -9
  53. package/lib/gen/language.checksum +1 -1
  54. package/lib/gen/language.interp +8 -31
  55. package/lib/gen/language.tokens +105 -114
  56. package/lib/gen/languageLexer.interp +1 -34
  57. package/lib/gen/languageLexer.js +892 -1007
  58. package/lib/gen/languageLexer.tokens +95 -106
  59. package/lib/gen/languageParser.js +20629 -22474
  60. package/lib/inspect/.eslintrc.json +4 -0
  61. package/lib/inspect/index.js +14 -0
  62. package/lib/inspect/inspectModelStatistics.js +81 -0
  63. package/lib/inspect/inspectPropagation.js +189 -0
  64. package/lib/inspect/inspectUtils.js +44 -0
  65. package/lib/json/from-csn.js +74 -69
  66. package/lib/json/to-csn.js +17 -14
  67. package/lib/language/antlrParser.js +2 -2
  68. package/lib/language/docCommentParser.js +61 -38
  69. package/lib/language/errorStrategy.js +52 -40
  70. package/lib/language/genericAntlrParser.js +424 -292
  71. package/lib/language/language.g4 +604 -687
  72. package/lib/language/multiLineStringParser.js +14 -42
  73. package/lib/language/textUtils.js +44 -0
  74. package/lib/main.d.ts +28 -42
  75. package/lib/main.js +104 -81
  76. package/lib/model/api.js +1 -1
  77. package/lib/model/csnRefs.js +57 -30
  78. package/lib/model/csnUtils.js +189 -287
  79. package/lib/model/revealInternalProperties.js +32 -10
  80. package/lib/model/sortViews.js +32 -31
  81. package/lib/modelCompare/compare.js +3 -0
  82. package/lib/optionProcessor.js +91 -57
  83. package/lib/render/.eslintrc.json +1 -1
  84. package/lib/render/DuplicateChecker.js +4 -7
  85. package/lib/render/manageConstraints.js +70 -2
  86. package/lib/render/toCdl.js +387 -367
  87. package/lib/render/toHdbcds.js +20 -16
  88. package/lib/render/toRename.js +44 -22
  89. package/lib/render/toSql.js +81 -59
  90. package/lib/render/utils/common.js +16 -3
  91. package/lib/render/utils/sql.js +20 -19
  92. package/lib/sql-identifier.js +6 -0
  93. package/lib/transform/db/.eslintrc.json +3 -2
  94. package/lib/transform/db/associations.js +43 -35
  95. package/lib/transform/db/cdsPersistence.js +5 -16
  96. package/lib/transform/db/constraints.js +1 -1
  97. package/lib/transform/db/expansion.js +7 -6
  98. package/lib/transform/db/flattening.js +16 -18
  99. package/lib/transform/db/transformExists.js +7 -5
  100. package/lib/transform/db/views.js +3 -3
  101. package/lib/transform/draft/.eslintrc.json +2 -2
  102. package/lib/transform/draft/db.js +6 -6
  103. package/lib/transform/draft/odata.js +6 -7
  104. package/lib/transform/forHanaNew.js +30 -24
  105. package/lib/transform/forOdataNew.js +14 -16
  106. package/lib/transform/localized.js +35 -25
  107. package/lib/transform/odata/toFinalBaseType.js +10 -10
  108. package/lib/transform/odata/typesExposure.js +17 -8
  109. package/lib/transform/odata/utils.js +1 -38
  110. package/lib/transform/transformUtilsNew.js +63 -77
  111. package/lib/transform/translateAssocsToJoins.js +2 -2
  112. package/lib/transform/universalCsn/.eslintrc.json +2 -2
  113. package/lib/transform/universalCsn/coreComputed.js +11 -6
  114. package/lib/transform/universalCsn/universalCsnEnricher.js +33 -5
  115. package/lib/utils/file.js +31 -21
  116. package/lib/utils/moduleResolve.js +0 -1
  117. package/lib/utils/timetrace.js +20 -21
  118. package/package.json +34 -4
  119. package/share/messages/syntax-expected-integer.md +9 -8
  120. package/doc/ApiMigration.md +0 -237
  121. package/doc/CommandLineMigration.md +0 -58
  122. package/doc/ErrorMessages.md +0 -175
  123. package/doc/FioriAnnotations.md +0 -94
  124. package/doc/ODataTransformation.md +0 -273
  125. package/lib/backends.js +0 -529
  126. package/lib/checks/unknownMagic.js +0 -41
  127. package/lib/fix_antlr4-8_warning.js +0 -56
@@ -14,6 +14,7 @@
14
14
  const msg = require('../base/messages');
15
15
 
16
16
  const $inferred = Symbol.for('cds.$inferred');
17
+ const $location = Symbol.for('cds.$location');
17
18
 
18
19
  class NOT_A_DICTIONARY {} // used for consol.log display
19
20
 
@@ -57,7 +58,6 @@ function tableAliasAsLink( art, parent, name ) {
57
58
  *
58
59
  * @param {XSN.Model} model
59
60
  * @param {string} [nameOrPath]
60
- * @returns {string}
61
61
  */
62
62
  function revealInternalProperties( model, nameOrPath ) {
63
63
  const transformers = {
@@ -96,6 +96,7 @@ function revealInternalProperties( model, nameOrPath ) {
96
96
  _annotate: reveal,
97
97
  _deps: dependencyInfo,
98
98
  _status: primOrString, // is a string anyway
99
+ $annotations: as => as.map( $annotation ),
99
100
  $messageFunctions: () => '‹some functions›',
100
101
  }
101
102
  unique_id = 1;
@@ -129,7 +130,10 @@ function revealInternalProperties( model, nameOrPath ) {
129
130
 
130
131
  path = path.split('/');
131
132
  if (path.length === 1) {
132
- return reveal( xsn.definitions[path] || xsn.vocabularies && xsn.vocabularies[path] );
133
+ const def = xsn.definitions?.[path[0]] || xsn.vocabularies?.[path[0]];
134
+ if (!def)
135
+ throw new Error(`reveal xsn: Unknown definition: “${path[0]}”`)
136
+ return reveal( def );
133
137
  }
134
138
 
135
139
  // with the code below, we might miss the right transformer function
@@ -149,7 +153,7 @@ function revealInternalProperties( model, nameOrPath ) {
149
153
 
150
154
  function shortenName( node, parent ) {
151
155
  const name = reveal( node, parent );
152
- if (name && typeof name === 'object' && name.absolute) {
156
+ if (name && typeof name === 'object' && name.absolute && node.kind) {
153
157
  const text = artifactIdentifier( parent );
154
158
  delete name.absolute;
155
159
  delete name.select;
@@ -178,11 +182,20 @@ function revealInternalProperties( model, nameOrPath ) {
178
182
  return r;
179
183
  }
180
184
 
185
+ function $annotation( anno ) { // property for cds-lsp
186
+ const { name, $flatten } = anno.value || anno;
187
+ const value = ($flatten)
188
+ ? { name: reveal( name ), $flatten: $flatten.map( $annotation ) }
189
+ : `@${name?.absolute}`;
190
+ return { value, location: locationString( anno.location || anno.name.location ) };
191
+ }
192
+
181
193
  function columns( nodes, query ) {
182
194
  // If we will have specified elements, we need another test to see columns in --parse-cdl
183
- return nodes && nodes.map( c => (c._parent && c._parent.elements)
184
- ? artifactIdentifier( c, query )
185
- : reveal( c, nodes ) );
195
+ return nodes && array( nodes,
196
+ c => (c._parent && c._parent.elements)
197
+ ? artifactIdentifier( c, query )
198
+ : reveal( c, nodes ) );
186
199
  }
187
200
 
188
201
  function elements( dict, parent ) {
@@ -215,7 +228,7 @@ function revealInternalProperties( model, nameOrPath ) {
215
228
  if (!node || typeof node !== 'object')
216
229
  return primOrString( node );
217
230
  if (Array.isArray(node)) // with args
218
- return node.map( n => reveal( n, node ) );
231
+ return array( node, reveal );
219
232
  // Make unexpected prototype visible with node-10+:
220
233
  const r = Object.create( Object.getPrototypeOf(node)
221
234
  ? NOT_A_DICTIONARY.prototype
@@ -225,6 +238,8 @@ function revealInternalProperties( model, nameOrPath ) {
225
238
  }
226
239
  if (node[$inferred] && !node['[$inferred]'])
227
240
  r['[$inferred]'] = node[$inferred];
241
+ if (node[$location] && !node['[$location]'])
242
+ r['[$location]'] = locationString( node[$location] );
228
243
  return r;
229
244
  }
230
245
 
@@ -239,7 +254,7 @@ function revealInternalProperties( model, nameOrPath ) {
239
254
  if (node == null || typeof node !== 'object' )
240
255
  return primOrString( node );
241
256
  if (Array.isArray(node))
242
- return node.map( n => revealNonEnum( n, node ) );
257
+ return array( node, revealNonEnum );
243
258
 
244
259
  if (Object.getPrototypeOf( node ))
245
260
  return artifactIdentifier( node, parent );
@@ -250,7 +265,7 @@ function revealInternalProperties( model, nameOrPath ) {
250
265
  if (node == null || typeof node !== 'object' )
251
266
  return node
252
267
  if (Array.isArray(node))
253
- return node.map( n => reveal( n, node, name ) );
268
+ return array( node, n => reveal( n, node, name ) );
254
269
 
255
270
  const asLinkTest = kindsRepresentedAsLinks[ node.kind ];
256
271
  if (asLinkTest && asLinkTest( node, parent, name ))
@@ -280,6 +295,13 @@ function revealInternalProperties( model, nameOrPath ) {
280
295
  }
281
296
  }
282
297
 
298
+ function array( node, fn ) {
299
+ const r = node.map( n => fn( n, node ) );
300
+ if (node[$location])
301
+ r.push( { '[$location]': locationString( node[$location] ) } );
302
+ return (node.$prefix) ? [ { $prefix: node.$prefix }, ...node ] : r;
303
+ }
304
+
283
305
  function artifactIdentifier( node, parent ) {
284
306
  if (Array.isArray(node))
285
307
  return node.map( a => artifactIdentifier( a, node ) );
@@ -335,7 +357,7 @@ function primOrString( node ) {
335
357
  if (node == null || typeof node !== 'object')
336
358
  return node
337
359
  if (Array.isArray(node))
338
- return node.map( primOrString );
360
+ return array( node, primOrString );
339
361
  if (Object.getPrototypeOf( node ))
340
362
  return '' + node;
341
363
  else
@@ -21,7 +21,7 @@ const { ModelError } = require("../base/error");
21
21
  */
22
22
  function sortTopologically(csn, _dependents, _dependencies){
23
23
  const layers = [];
24
- let { zero, nonZero } = calculateDepth(Object.entries(csn.definitions));
24
+ let { zero, nonZero } = _calculateDepth(Object.entries(csn.definitions), _dependents, _dependencies);
25
25
  while (zero.length !== 0){
26
26
  const currentLayer = [];
27
27
  zero.forEach(([artifactName, artifact]) => {
@@ -34,46 +34,46 @@ function sortTopologically(csn, _dependents, _dependencies){
34
34
  }
35
35
  });
36
36
  layers.push(currentLayer);
37
- ({zero, nonZero} = findWithXPointers(nonZero, 0));
37
+ ({zero, nonZero} = _findWithXPointers(nonZero, 0, _dependents, _dependencies));
38
38
  }
39
39
 
40
40
  return { layers, leftover: nonZero };
41
+ }
41
42
 
42
- function calculateDepth(definitionsArray) {
43
- const zero = [];
44
- const nonZero = [];
43
+ function _calculateDepth(definitionsArray, _dependents, _dependencies) {
44
+ const zero = [];
45
+ const nonZero = [];
45
46
 
46
- definitionsArray.forEach(([artifactName, artifact]) => {
47
- if(artifact[_dependencies]) {
48
- artifact.$pointers = artifact[_dependencies].size;
49
- nonZero.push([artifactName, artifact]);
50
- } else {
51
- artifact.$pointers = 0;
52
- zero.push([artifactName, artifact]);
53
- }
54
- });
55
- return {
56
- zero,
57
- nonZero
47
+ definitionsArray.forEach(([artifactName, artifact]) => {
48
+ if(artifact[_dependencies]) {
49
+ artifact.$pointers = artifact[_dependencies].size;
50
+ nonZero.push([artifactName, artifact]);
51
+ } else {
52
+ artifact.$pointers = 0;
53
+ zero.push([artifactName, artifact]);
58
54
  }
55
+ });
56
+ return {
57
+ zero,
58
+ nonZero
59
59
  }
60
+ }
60
61
 
61
- function findWithXPointers(definitionsArray, x=0){
62
- const zero = [];
63
- const nonZero = [];
64
-
65
- definitionsArray.forEach(([artifactName, artifact]) => {
66
- if(artifact.$pointers !== undefined && artifact.$pointers === x) {
67
- zero.push([artifactName, artifact]);
68
- } else {
69
- nonZero.push([artifactName, artifact]);
70
- }
71
- });
62
+ function _findWithXPointers(definitionsArray, x, _dependents, _dependencies){
63
+ const zero = [];
64
+ const nonZero = [];
72
65
 
73
- return {
74
- zero,
75
- nonZero
66
+ definitionsArray.forEach(([artifactName, artifact]) => {
67
+ if(artifact.$pointers !== undefined && artifact.$pointers === x) {
68
+ zero.push([artifactName, artifact]);
69
+ } else {
70
+ nonZero.push([artifactName, artifact]);
76
71
  }
72
+ });
73
+
74
+ return {
75
+ zero,
76
+ nonZero
77
77
  }
78
78
  }
79
79
 
@@ -83,6 +83,7 @@ function sortTopologically(csn, _dependents, _dependencies){
83
83
  * be run beforehand to resolve association usages.
84
84
  *
85
85
  * @param {object} sql Map of <object name>: "CREATE STATEMENT"
86
+ * @param {CSN.Model} csn
86
87
  *
87
88
  * @returns {{name: string, sql: string}[]} Sorted array of artifact name / "CREATE STATEMENTS" pairs
88
89
  *
@@ -169,6 +169,9 @@ function getElementComparator(otherArtifact, addedElementsDict = null, changedEl
169
169
  }
170
170
  if (relevantTypeChange(element.type, otherElement.type) || typeParametersChanged(element, otherElement)) {
171
171
  // Type or parameters, e.g. association target, changed.
172
+ if(otherElement.notNull && element.notNull === undefined) {
173
+ element.$notNull = false; // Explictily set notNull to the implicit default so we render the correct ALTER
174
+ }
172
175
  changedElementsDict[name] = changedElement(element, otherElement);
173
176
  }
174
177
 
@@ -19,10 +19,7 @@ optionProcessor
19
19
  .option(' --color <mode>', ['auto', 'always', 'never'])
20
20
  .option('-o, --out <dir>')
21
21
  .option(' --cds-home <dir>')
22
- .option(' --lint-mode')
23
22
  .option(' --fuzzy-csn-error')
24
- .option(' --trace-parser')
25
- .option(' --trace-parser-amb')
26
23
  .option(' --trace-fs')
27
24
  .option(' --error <id-list>')
28
25
  .option(' --warn <id-list>')
@@ -34,9 +31,7 @@ optionProcessor
34
31
  .option(' --beta-mode')
35
32
  .option(' --beta <list>')
36
33
  .option(' --deprecated <list>')
37
- .option(' --hana-flavor')
38
34
  .option(' --direct-backend')
39
- .option(' --parse-only')
40
35
  .option(' --fallback-parser <type>', ['cdl', 'csn', 'csn!'])
41
36
  .option(' --test-mode')
42
37
  .option(' --test-sort-csn')
@@ -79,7 +74,6 @@ optionProcessor
79
74
  never:
80
75
  -o, --out <dir> Place generated files in directory <dir>, default is "-" for <stdout>
81
76
  --cds-home <dir> When set, modules starting with '@sap/cds/' are searched in <dir>
82
- --lint-mode Generate nothing, just produce messages if any (for use by editors)
83
77
  --fuzzy-csn-error Report free-style CSN properties as errors
84
78
  -- Indicate the end of options (helpful if source names start with "-")
85
79
 
@@ -88,8 +82,6 @@ optionProcessor
88
82
  --default-string-length <length> Default 'length' for 'cds.String'
89
83
 
90
84
  Diagnostic options
91
- --trace-parser Trace parser
92
- --trace-parser-amb Trace parser ambiguities
93
85
  --trace-fs Trace file system access caused by "using from"
94
86
 
95
87
  Severity options
@@ -107,22 +99,15 @@ optionProcessor
107
99
  --beta-mode Enable all unsupported, incomplete (beta) features
108
100
  --beta <list> Comma separated list of unsupported, incomplete (beta) features to use.
109
101
  Valid values are:
110
- addTextsLanguageAssoc
111
102
  hanaAssocRealCardinality
112
103
  mapAssocToJoinCardinality
113
104
  ignoreAssocPublishingInUnion
105
+ odataOpenType
106
+ optionalActionFunctionParameters
114
107
  --deprecated <list> Comma separated list of deprecated options.
115
108
  Valid values are:
116
- noElementsExpansion
117
- v1KeysForTemporal
118
- parensAsStrings
119
- projectionAsQuery
120
- renderVirtualElements
121
- unmanagedUpInComponent
122
- createLocalizedViews
123
- redirectInSubQueries
124
- --hana-flavor Compile with backward compatibility for HANA CDS (incomplete)
125
- --parse-only Stop compilation after parsing and write result to <stdout>
109
+ autoCorrectOrderBySourceRefs
110
+ eagerPersistenceForGeneratedEntities
126
111
  --fallback-parser <type> If the language cannot be deduced by the file's extensions, use this
127
112
  parser as a fallback. Valid values are:
128
113
  cdl : Use CDL parser
@@ -151,15 +136,18 @@ optionProcessor
151
136
  toCsn [options] <files...> (default) Generate original model as CSN
152
137
  parseCdl [options] <file> Generate a CSN that is close to the CDL source.
153
138
  explain <message-id> Explain a compiler message.
139
+ parseOnly [options] <files...> (internal) Stop compilation after parsing, write messages to <stderr>,
140
+ per default no output.
154
141
  toRename [options] <files...> (internal) Generate SQL DDL rename statements
155
142
  manageConstraints [options] <files...> (internal) Generate ALTER TABLE statements to
156
143
  add / modify referential constraints.
144
+ inspect [options] <files...> (internal) Inspect the given CDS files.
157
145
  `);
158
146
 
159
147
  // ----------- toHana -----------
160
148
  optionProcessor.command('H, toHana')
161
149
  .option('-h, --help')
162
- .option('-n, --names <style>', ['plain', 'quoted', 'hdbcds'])
150
+ .option('-n, --sql-mapping <style>', ['plain', 'quoted', 'hdbcds'], { aliases: ['--names'] })
163
151
  .option(' --render-virtual')
164
152
  .option(' --joinfk')
165
153
  .option('-u, --user <user>')
@@ -169,6 +157,7 @@ optionProcessor.command('H, toHana')
169
157
  .option(' --integrity-not-enforced')
170
158
  .option(' --assert-integrity <mode>', ['true', 'false', 'individual'])
171
159
  .option(' --assert-integrity-type <type>', ['RT', 'DB'], { ignoreCase: true })
160
+ .option(' --disable-hana-comments')
172
161
  .help(`
173
162
  Usage: cdsc toHana [options] <files...>
174
163
 
@@ -176,7 +165,7 @@ optionProcessor.command('H, toHana')
176
165
 
177
166
  Options
178
167
  -h, --help Show this help text
179
- -n, --names <style> Naming style for generated entity and element names:
168
+ -n, --sql-mapping <style> Naming style for generated entity and element names:
180
169
  plain : (default) Produce HANA entity and element names in
181
170
  uppercase and flattened with underscores. Do not generate
182
171
  structured types.
@@ -203,11 +192,12 @@ optionProcessor.command('H, toHana')
203
192
  RT : (default) No database constraint for an association
204
193
  if not explicitly demanded via annotation
205
194
  DB : Create database constraints for associations
195
+ --disable-hana-comments Disable rendering of doc comments as SAP HANA comments.
206
196
  `);
207
197
 
208
198
  optionProcessor.command('O, toOdata')
209
199
  .option('-h, --help')
210
- .option('-v, --version <version>', ['v2', 'v4', 'v4x'])
200
+ .option('-v, --odata-version <version>', ['v2', 'v4', 'v4x'], { aliases: ['--version'] })
211
201
  .option('-x, --xml')
212
202
  .option('-j, --json')
213
203
  .option(' --odata-containment')
@@ -217,7 +207,7 @@ optionProcessor.command('O, toOdata')
217
207
  .option(' --odata-v2-partial-constr')
218
208
  .option('-c, --csn')
219
209
  .option('-f, --odata-format <format>', ['flat', 'structured'])
220
- .option('-n, --names <style>', ['plain', 'quoted', 'hdbcds'])
210
+ .option('-n, --sql-mapping <style>', ['plain', 'quoted', 'hdbcds'], { aliases: [ '--names' ] })
221
211
  .option('-s, --service-names <list>')
222
212
  .help(`
223
213
  Usage: cdsc toOdata [options] <files...>
@@ -226,10 +216,10 @@ optionProcessor.command('O, toOdata')
226
216
 
227
217
  Options
228
218
  -h, --help Show this help text
229
- -v, --version <version> ODATA version
230
- v2: ODATA V2
231
- v4: (default) ODATA V4
232
- v4x: { version: 'v4', odataContainment:true, format:'structured' }
219
+ -v, --odata-version <version> ODATA version
220
+ v2: ODATA V2
221
+ v4: (default) ODATA V4
222
+ v4x: { version: 'v4', odataContainment:true, format:'structured' }
233
223
  -x, --xml (default) Generate XML output (separate or combined)
234
224
  -j, --json Generate JSON output as "<svc>.json" (not available for v2)
235
225
  -c, --csn Generate "odata_csn.json" with ODATA-preprocessed model
@@ -242,15 +232,15 @@ optionProcessor.command('O, toOdata')
242
232
  --odata-foreign-keys Render foreign keys in structured format (V4 only)
243
233
  --odata-v2-partial-constr Render referential constraints also for partial principal key tuple
244
234
  (Not spec compliant and V2 only)
245
- -n, --names <style> Annotate artifacts and elements with "@cds.persistence.name", which is
246
- the corresponding database name (see "--names" for "toHana or "toSql")
247
- plain : (default) Names in uppercase and flattened with underscores
248
- quoted : Names in original case as in CDL. Entity names with dots,
249
- but element names flattened with underscores
250
- hdbcds : Names as HANA CDS would generate them from the same CDS
251
- source (like "quoted", but using element names with dots)
235
+ -n, --sql-mapping <style> Annotate artifacts and elements with "@cds.persistence.name", which is
236
+ the corresponding database name (see "--sql-mapping" for "toHana or "toSql")
237
+ plain : (default) Names in uppercase and flattened with underscores
238
+ quoted : Names in original case as in CDL. Entity names with dots,
239
+ but element names flattened with underscores
240
+ hdbcds : Names as HANA CDS would generate them from the same CDS
241
+ source (like "quoted", but using element names with dots)
252
242
  -s, --service-names <list> List of comma-separated service names to be rendered
253
- (default) empty, all services are rendered
243
+ (default) empty, all services are rendered
254
244
  `);
255
245
 
256
246
  optionProcessor.command('C, toCdl')
@@ -266,10 +256,10 @@ optionProcessor.command('C, toCdl')
266
256
 
267
257
  optionProcessor.command('Q, toSql')
268
258
  .option('-h, --help')
269
- .option('-n, --names <style>', ['plain', 'quoted', 'hdbcds'])
259
+ .option('-n, --sql-mapping <style>', ['plain', 'quoted', 'hdbcds'], { aliases: [ '--names' ] })
260
+ .option('-d, --sql-dialect <dialect>', ['hana', 'sqlite', 'plain', 'postgres'], { aliases: [ '--dialect' ] })
270
261
  .option(' --render-virtual')
271
262
  .option(' --joinfk')
272
- .option('-d, --dialect <dialect>', ['hana', 'sqlite', 'plain'])
273
263
  .option('-u, --user <user>')
274
264
  .option('-l, --locale <locale>')
275
265
  .option('-s, --src <style>', ['sql', 'hdi'])
@@ -279,6 +269,7 @@ optionProcessor.command('Q, toSql')
279
269
  .option(' --assert-integrity <mode>', ['true', 'false', 'individual'])
280
270
  .option(' --assert-integrity-type <type>', ['RT', 'DB'], { ignoreCase: true })
281
271
  .option(' --constraints-in-create-table')
272
+ .option(' --disable-hana-comments')
282
273
  .help(`
283
274
  Usage: cdsc toSql [options] <files...>
284
275
 
@@ -286,7 +277,7 @@ optionProcessor.command('Q, toSql')
286
277
 
287
278
  Options
288
279
  -h, --help Show this help text
289
- -n, --names <style> Naming style for generated entity and element names:
280
+ -n, --sql-mapping <style> Naming style for generated entity and element names:
290
281
  plain : (default) Produce SQL table and view names in
291
282
  flattened with underscores format (no quotes required)
292
283
  quoted : Produce SQL table and view names in original case as in
@@ -299,10 +290,11 @@ optionProcessor.command('Q, toSql')
299
290
  combination with "hana" dialect.
300
291
  --render-virtual Render virtual elements in views and draft tables
301
292
  --joinfk Create JOINs for foreign key accesses
302
- -d, --dialect <dialect> SQL dialect to be generated:
303
- plain : (default) Common SQL - no assumptions about DB restrictions
304
- hana : SQL with HANA specific language features
305
- sqlite : Common SQL for sqlite
293
+ -d, --sql-dialect <dialect> SQL dialect to be generated:
294
+ plain : (default) Common SQL - no assumptions about DB restrictions
295
+ hana : SQL with HANA specific language features
296
+ sqlite : Common SQL for sqlite
297
+ postgres : Common SQL for postgres - beta-feature
306
298
  -u, --user <user> Value for the "$user" variable
307
299
  -l, --locale <locale> Value for the "$user.locale" variable in "sqlite"/"plain" dialect
308
300
  -s, --src <style> Generate SQL source files as <artifact>.<suffix>
@@ -325,32 +317,34 @@ optionProcessor.command('Q, toSql')
325
317
  --constraints-in-create-table If set, the foreign key constraints will be rendered as
326
318
  part of the "CREATE TABLE" statements rather than as separate
327
319
  "ALTER TABLE ADD CONSTRAINT" statements
320
+ --disable-hana-comments Disable rendering of doc comments as SAP HANA comments.
328
321
  `);
329
322
 
330
323
  optionProcessor.command('toRename')
331
324
  .option('-h, --help')
332
- .option('-n, --names <style>', ['quoted', 'hdbcds'])
325
+ .option('-n, --sql-mapping <style>', ['quoted', 'hdbcds'], { aliases: ['--names'] })
333
326
  .help(`
334
327
  Usage: cdsc toRename [options] <files...>
335
328
 
336
329
  (internal, subject to change): Generate SQL stored procedure containing DDL statements to
337
330
  "storedProcedure.sql" that allows to rename existing tables and their columns so that they
338
- match the result of "toHana" or "toSql" with the "--names plain" option.
331
+ match the result of "toHana" or "toSql" with the "--sql-mapping plain" option.
339
332
 
340
333
  Options
341
334
  -h, --help Display this help text
342
- -n, --names <style> Assume existing tables were generated with "--names <style>":
335
+ -n, --sql-mapping <style>
336
+ Assume existing tables were generated with "--sql-mapping <style>":
343
337
  quoted : Assume existing SQL tables and views were named in original
344
338
  case as in CDL (with dots), but column names were flattened
345
- with underscores (e.g. resulting from "toHana --names quoted")
339
+ with underscores (e.g. resulting from "toHana --sql-mapping quoted")
346
340
  hdbcds : (default) Assume existing SQL tables, views and columns were
347
341
  generated by HANA CDS from the same CDS source (or resulting
348
- from "toHana --names hdbcds")
342
+ from "toHana --sql-mapping hdbcds")
349
343
  `);
350
344
 
351
345
  optionProcessor.command('manageConstraints')
352
346
  .option('-h, --help')
353
- .option('-n, --names <style>', ['plain', 'quoted', 'hdbcds'])
347
+ .option('-n, --sql-mapping <style>', ['plain', 'quoted', 'hdbcds'], { aliases: ['--names'] })
354
348
  .option('-s, --src <style>', ['sql', 'hdi'])
355
349
  .option(' --drop')
356
350
  .option(' --alter')
@@ -366,7 +360,8 @@ optionProcessor.command('manageConstraints')
366
360
 
367
361
  Options
368
362
  -h, --help Display this help text
369
- -n, --names <style> Assume existing tables were generated with "--names <style>":
363
+ -n, --sql-mapping <style>
364
+ Assume existing tables were generated with "--sql-mapping <style>":
370
365
  plain : (default) Assume SQL tables were flattened and dots were
371
366
  replaced by underscores
372
367
  quoted : Assume existing SQL tables and views were named in original
@@ -388,8 +383,9 @@ optionProcessor.command('manageConstraints')
388
383
 
389
384
  optionProcessor.command('toCsn')
390
385
  .option('-h, --help')
391
- .option('-f, --flavor <flavor>', ['client', 'gensrc', 'universal'])
386
+ .option('-f, --csn-flavor <flavor>', ['client', 'gensrc', 'universal'], { aliases: ['--flavor'] })
392
387
  .option(' --with-localized')
388
+ .option(' --with-locations')
393
389
  .help(`
394
390
  Usage: cdsc toCsn [options] <files...>
395
391
 
@@ -397,13 +393,15 @@ optionProcessor.command('toCsn')
397
393
 
398
394
  Options
399
395
  -h, --help Show this help text
400
- -f, --flavor <flavor> Generate CSN in one of two flavors:
401
- client : (default) Standard CSN consumable by clients and backends
402
- gensrc : CSN specifically for use as a source, e.g. for
403
- combination with additional "extend" or "annotate"
404
- statements, but not suitable for consumption by clients or
405
- backends
406
- universal: in development (BETA)
396
+ -f, --csn-flavor <flavor> Generate CSN in one of two flavors:
397
+ client : (default) Standard CSN consumable by clients and backends
398
+ gensrc : CSN specifically for use as a source, e.g. for
399
+ combination with additional "extend" or "annotate"
400
+ statements, but not suitable for consumption by clients or
401
+ backends
402
+ universal: in development (BETA)
403
+ --with-locations Add $location to CSN artifacts. In contrast to \`--enrich-csn\`,
404
+ $location is an object with 'file', 'line' and 'col' properties.
407
405
 
408
406
  Internal options (for testing only, may be changed/removed at any time)
409
407
  --with-localized Add localized convenience views to the CSN output.
@@ -422,6 +420,26 @@ optionProcessor.command('parseCdl')
422
420
  -h, --help Show this help text
423
421
  `);
424
422
 
423
+ optionProcessor.command('parseOnly')
424
+ .option('-h, --help')
425
+ .option(' --trace-parser')
426
+ .option(' --trace-parser-amb')
427
+ .positionalArgument('<file>')
428
+ .help(`
429
+ Usage: cdsc parseOnly [options] <files...>
430
+
431
+ (internal): Stop compilation after parsing and write messages to <stderr>.
432
+ Per default, nothing is printed. With \`--raw-output +\`, XSN is printed
433
+ to <stdout>.
434
+
435
+ Options
436
+ -h, --help Show this help text
437
+
438
+ Diagnostic options
439
+ --trace-parser Trace parser
440
+ --trace-parser-amb Trace parser ambiguities
441
+ `);
442
+
425
443
  optionProcessor.command('explain')
426
444
  .option('-h, --help')
427
445
  .positionalArgument('<message-id>')
@@ -437,6 +455,22 @@ optionProcessor.command('explain')
437
455
  -h, --help Show this help text
438
456
  `);
439
457
 
458
+ optionProcessor.command('inspect')
459
+ .option('-h, --help')
460
+ .option(' --statistics')
461
+ .option(' --propagation <art>')
462
+ .positionalArgument('<files...>')
463
+ .help(`
464
+ Usage: cdsc inspect [options] <files...>
465
+
466
+ (internal): Inspect the CSN model compiled from the provided CDS files.
467
+
468
+ Options
469
+ -h, --help Show this help text
470
+ --statistics Print model statistics
471
+ --propagation <art> Show propagation sources for <art>
472
+ `);
473
+
440
474
  module.exports = {
441
475
  optionProcessor
442
476
  };
@@ -16,6 +16,6 @@
16
16
  "no-shadow": "warn"
17
17
  },
18
18
  "env": {
19
- "es6": true
19
+ "es2020": true
20
20
  }
21
21
  }
@@ -2,12 +2,14 @@
2
2
  * Usage: Create an instance to process artifacts which should be checked for collision.
3
3
  * First call addArtifact to specify the current artifact,
4
4
  * then call addElement to register the elements of the current artifact.
5
- * Finally call the "done" function to check for duplicates.
6
- * In addition the internal structures will be reinitialized to enable reuse of the instance.
5
+ * Finally, call the "done" function to check for duplicates.
6
+ * In addition, the internal structures will be reinitialized to enable reuse of the instance.
7
7
  */
8
8
 
9
9
  'use strict';
10
10
 
11
+ const { forEach } = require('../utils/objectUtils');
12
+
11
13
  /**
12
14
  * database name - uppercase if not quoted
13
15
  *
@@ -121,9 +123,4 @@ class DuplicateChecker {
121
123
  }
122
124
  }
123
125
 
124
- function forEach(obj, callback) {
125
- for (const key in obj)
126
- callback(key, obj[key]);
127
- }
128
-
129
126
  module.exports = DuplicateChecker;