@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
@@ -11,6 +11,7 @@
11
11
  "no-process-exit": "off",
12
12
  "camelcase": "off",
13
13
  "radix": "off",
14
- "no-shadow": "warn"
14
+ "no-shadow": "warn",
15
+ "global-require": "off"
15
16
  }
16
17
  }
package/bin/cdsc.js CHANGED
@@ -19,7 +19,7 @@ const compiler = require('../lib/compiler');
19
19
  const main = require('../lib/main');
20
20
  const { for_sql, for_hdi, for_hdbcds } = require('../lib/api/main');
21
21
  const { compactModel } = require('../lib/json/to-csn');
22
- const { toRenameWithCsn, alterConstraintsWithCsn } = require('../lib/backends');
22
+ const { toRename: _toRename } = require('../lib/render/toRename');
23
23
  const util = require('util');
24
24
  const fs = require('fs');
25
25
  const path = require('path');
@@ -33,6 +33,7 @@ const { term } = require('../lib/utils/term');
33
33
  const { splitLines } = require('../lib/utils/file');
34
34
  const { addLocalizationViews } = require('../lib/transform/localized');
35
35
  const { availableBetaFlags } = require('../lib/base/model');
36
+ const { alterConstraintsWithCsn } = require('../lib/render/manageConstraints');
36
37
 
37
38
  // Note: Instead of throwing ProcessExitError, we would rather just call process.exit(exitCode),
38
39
  // but that might truncate the output of stdout and stderr, both of which are async (or rather,
@@ -56,15 +57,12 @@ catch (err) {
56
57
  throw err;
57
58
  }
58
59
 
59
- function remapCmdOptions(options, cmdOptions) {
60
- if (!cmdOptions)
61
- return options;
60
+ function remapCmdOptions(options, command) {
61
+ if (!command || !options[command])
62
+ return;
62
63
 
63
- for (const [ key, value ] of Object.entries(cmdOptions)) {
64
+ for (const [ key, value ] of Object.entries(options[command])) {
64
65
  switch (key) {
65
- case 'names':
66
- options.sqlMapping = value;
67
- break;
68
66
  case 'user':
69
67
  if (!options.variableReplacements)
70
68
  options.variableReplacements = {};
@@ -72,12 +70,6 @@ function remapCmdOptions(options, cmdOptions) {
72
70
  options.variableReplacements.$user = {};
73
71
  options.variableReplacements.$user.id = value;
74
72
  break;
75
- case 'dialect':
76
- options.sqlDialect = value;
77
- break;
78
- case 'version':
79
- options.odataVersion = value;
80
- break;
81
73
  case 'locale':
82
74
  if (!options.variableReplacements)
83
75
  options.variableReplacements = {};
@@ -92,7 +84,7 @@ function remapCmdOptions(options, cmdOptions) {
92
84
  options[key] = value;
93
85
  }
94
86
  }
95
- return options;
87
+ delete options[command];
96
88
  }
97
89
 
98
90
  function cdsc_main() {
@@ -154,12 +146,17 @@ function cdsc_main() {
154
146
  if (cmdLine.options.rawOutput)
155
147
  cmdLine.options.attachValidNames = true;
156
148
 
157
- // Internally, parseCdl is an option so we map the command to it.
149
+ // Internally, parseCdl/parseOnly are options, so we map the command to it.
158
150
  if (cmdLine.command === 'parseCdl') {
159
151
  cmdLine.command = 'toCsn';
160
152
  cmdLine.options.parseCdl = true;
161
153
  cmdLine.args.files = [ cmdLine.args.file ];
162
154
  }
155
+ else if (cmdLine.command === 'parseOnly') {
156
+ cmdLine.command = 'toCsn';
157
+ cmdLine.options.parseOnly = true;
158
+ cmdLine.args.files = [ cmdLine.args.file ];
159
+ }
163
160
 
164
161
  if (cmdLine.options.directBackend)
165
162
  validateDirectBackendOption(cmdLine.command, cmdLine.options, cmdLine.args);
@@ -265,6 +262,7 @@ function executeCommandLine(command, options, args) {
265
262
  toRename,
266
263
  manageConstraints,
267
264
  toSql,
265
+ inspect,
268
266
  };
269
267
  const commandsWithoutCompilation = {
270
268
  explain,
@@ -273,6 +271,7 @@ function executeCommandLine(command, options, args) {
273
271
  if (!commands[command] && !commandsWithoutCompilation[command])
274
272
  throw new Error(`Missing implementation for command ${command}`);
275
273
 
274
+ remapCmdOptions( options, command );
276
275
 
277
276
  if (commandsWithoutCompilation[command]) {
278
277
  commandsWithoutCompilation[command]();
@@ -296,7 +295,7 @@ function executeCommandLine(command, options, args) {
296
295
  // Return the original model (for chaining)
297
296
  function toCdl( model ) {
298
297
  const csn = options.directBackend ? model : compactModel(model, options);
299
- const cdlResult = main.to.cdl(csn, remapCmdOptions(options));
298
+ const cdlResult = main.to.cdl(csn, options);
300
299
  for (const name in cdlResult)
301
300
  writeToFileOrDisplay(options.out, `${name}.cds`, cdlResult[name]);
302
301
 
@@ -321,11 +320,11 @@ function executeCommandLine(command, options, args) {
321
320
  function toHana( model ) {
322
321
  const csn = options.directBackend ? model : compactModel(model, options);
323
322
 
324
- if (options.toHana && options.toHana.csn) {
325
- displayNamedCsn(for_hdbcds(csn, remapCmdOptions(options, options.toHana)), 'hana_csn');
323
+ if (options.csn) {
324
+ displayNamedCsn(for_hdbcds(csn, options), 'hana_csn');
326
325
  }
327
326
  else {
328
- const hanaResult = main.to.hdbcds(csn, remapCmdOptions(options, options.toHana));
327
+ const hanaResult = main.to.hdbcds(csn, options);
329
328
  for (const name in hanaResult)
330
329
  writeToFileOrDisplay(options.out, name, hanaResult[name]);
331
330
  }
@@ -336,25 +335,23 @@ function executeCommandLine(command, options, args) {
336
335
  // Execute the command line option '--to-odata' and display the results.
337
336
  // Return the original model (for chaining)
338
337
  function toOdata( model ) {
339
- if (options.toOdata &&
340
- options.toOdata.version === 'v4x') {
341
- options.toOdata.version = 'v4';
342
- options.toOdata.odataFormat = 'structured';
343
- options.toOdata.odataContainment = true;
338
+ if (options.odataVersion === 'v4x') {
339
+ options.odataVersion = 'v4';
340
+ options.odataFormat = 'structured';
341
+ options.odataContainment = true;
344
342
  }
345
343
  const csn = options.directBackend ? model : compactModel(model, options);
346
- const odataOptions = remapCmdOptions(options, options.toOdata);
347
- if (options.toOdata && options.toOdata.csn) {
348
- const odataCsn = main.for.odata(csn, odataOptions);
344
+ if (options.csn) {
345
+ const odataCsn = main.for.odata(csn, options);
349
346
  displayNamedCsn(odataCsn, 'odata_csn');
350
347
  }
351
- else if (options.toOdata && options.toOdata.json) {
352
- const result = main.to.edm.all(csn, odataOptions);
348
+ else if (options.json) {
349
+ const result = main.to.edm.all(csn, options);
353
350
  for (const serviceName in result)
354
351
  writeToFileOrDisplay(options.out, `${serviceName}.json`, result[serviceName]);
355
352
  }
356
353
  else {
357
- const result = main.to.edmx.all(csn, odataOptions);
354
+ const result = main.to.edmx.all(csn, options);
358
355
  for (const serviceName in result)
359
356
  writeToFileOrDisplay(options.out, `${serviceName}.xml`, result[serviceName]);
360
357
  }
@@ -368,14 +365,14 @@ function executeCommandLine(command, options, args) {
368
365
  // / DO NOT DELETE THIS TORENAME FUNCTIONALITY!!
369
366
  function toRename( model ) {
370
367
  const csn = options.directBackend ? model : compactModel(model, options);
371
- const renameResult = toRenameWithCsn(csn, options);
372
- let storedProcedure = `PROCEDURE RENAME_${renameResult.options.toRename.names.toUpperCase()}_TO_PLAIN LANGUAGE SQLSCRIPT AS BEGIN\n`;
368
+ const renameResult = _toRename(csn, options);
369
+ let storedProcedure = `PROCEDURE RENAME_${renameResult.options.sqlMapping.toUpperCase()}_TO_PLAIN LANGUAGE SQLSCRIPT AS BEGIN\n`;
373
370
  for (const name in renameResult.rename) {
374
371
  storedProcedure += ` --\n -- ${name}\n --\n`;
375
372
  storedProcedure += renameResult.rename[name];
376
373
  }
377
374
  storedProcedure += 'END;\n';
378
- writeToFileOrDisplay(options.out, `storedProcedure_${renameResult.options.toRename.names}_to_plain.sql`, storedProcedure, true);
375
+ writeToFileOrDisplay(options.out, `storedProcedure_${renameResult.options.sqlMapping}_to_plain.sql`, storedProcedure, true);
379
376
  return model;
380
377
  }
381
378
 
@@ -397,21 +394,21 @@ function executeCommandLine(command, options, args) {
397
394
  // Return the original model (for chaining)
398
395
  function toSql( model ) {
399
396
  const csn = options.directBackend ? model : compactModel(model, options);
400
- if (options.toSql && options.toSql.src === 'hdi') {
401
- if (options.toSql.csn) {
402
- displayNamedCsn(for_hdi(csn, remapCmdOptions(options, options.toSql)), 'hdi_csn');
397
+ if (options.src === 'hdi') {
398
+ if (options.csn) {
399
+ displayNamedCsn(for_hdi(csn, options), 'hdi_csn');
403
400
  }
404
401
  else {
405
- const hdiResult = main.to.hdi(csn, remapCmdOptions(options, options.toSql));
402
+ const hdiResult = main.to.hdi(csn, options);
406
403
  for (const name in hdiResult)
407
404
  writeToFileOrDisplay(options.out, name, hdiResult[name]);
408
405
  }
409
406
  }
410
- else if (options.toSql && options.toSql.csn) {
411
- displayNamedCsn(for_sql(csn, remapCmdOptions(options, options.toSql)), 'sql_csn');
407
+ else if (options.csn) {
408
+ displayNamedCsn(for_sql(csn, options), 'sql_csn');
412
409
  }
413
410
  else {
414
- const sqlResult = main.to.sql(csn, remapCmdOptions(options, options.toSql));
411
+ const sqlResult = main.to.sql(csn, options);
415
412
  writeToFileOrDisplay(options.out, 'model.sql', sqlResult.join('\n'), true);
416
413
  }
417
414
  return model;
@@ -429,6 +426,24 @@ function executeCommandLine(command, options, args) {
429
426
  console.log(explainMessage(args.messageId));
430
427
  }
431
428
 
429
+ function inspect(model) {
430
+ const inspectModel = require('../lib/inspect');
431
+
432
+ if (options.statistics) {
433
+ const result = inspectModel.inspectModelStatistics(model, options);
434
+ if (result)
435
+ console.log(result);
436
+ }
437
+
438
+ if (options.propagation) {
439
+ const result = inspectModel.inspectPropagation(model, options, options.propagation);
440
+ if (result)
441
+ console.log(result);
442
+ }
443
+
444
+ return model;
445
+ }
446
+
432
447
  // Display error messages in `err` resulting from a compilation. Also set
433
448
  // process.exitCode - process.exit() will force the process to exit as quickly
434
449
  // as possible = is problematic, since console.error() might be asynchronous
@@ -522,9 +537,9 @@ function executeCommandLine(command, options, args) {
522
537
  else if (options.internalMsg) {
523
538
  writeToFileOrDisplay(options.out, `${name}_raw.txt`, util.inspect(reveal(xsn).messages, { depth: null, maxArrayLength: null }), true);
524
539
  }
525
- else if (!options.lintMode) {
540
+ else if (!options.parseOnly) { // no output if parseOnly but not rawOutput
526
541
  const csn = compactModel(xsn, options);
527
- if (command === 'toCsn' && options.toCsn && options.toCsn.withLocalized)
542
+ if (command === 'toCsn' && options.withLocalized)
528
543
  addLocalizationViews(csn, options);
529
544
  if (options.enrichCsn)
530
545
  enrichCsn( csn, options );
@@ -542,8 +557,8 @@ function executeCommandLine(command, options, args) {
542
557
  if (options.internalMsg) {
543
558
  writeToFileOrDisplay(options.out, `${name}_raw.txt`, options.messages, true);
544
559
  }
545
- else if (!options.lintMode && !options.internalMsg) {
546
- if (command === 'toCsn' && options.toCsn && options.toCsn.withLocalized)
560
+ else if (!options.internalMsg) {
561
+ if (command === 'toCsn' && options.withLocalized)
547
562
  addLocalizationViews(csn, options);
548
563
  writeToFileOrDisplay(options.out, `${name}.json`, csn, true);
549
564
  }
@@ -555,7 +570,7 @@ function executeCommandLine(command, options, args) {
555
570
  // If displaying to stdout, prepend a headline containing 'filename', unless 'omitHeadline' is set.
556
571
  // For filenames, illegal characters (slash, backslash, colon) are replaced by '_'.
557
572
  function writeToFileOrDisplay(dir, fileName, content, omitHeadline = false) {
558
- if (options.lintMode && !options.rawOutput || options.internalMsg)
573
+ if (options.internalMsg)
559
574
  return;
560
575
  fileName = fileName.replace(/[:/\\]/g, '_');
561
576
 
package/doc/API.md ADDED
@@ -0,0 +1,11 @@
1
+ # CDS Compiler API Documentation
2
+
3
+ The API of `@sap/cds-compiler` is described in a TypeScript declaration file
4
+ [`main.d.ts`](../lib/main.d.ts).
5
+
6
+ Refer to that file for documentation on option names, API calls, and more.
7
+
8
+ You can use [TypeDoc] to render an HTML documentation from it.
9
+
10
+
11
+ [TypeDoc]: https://typedoc.org/