@sap/cds-compiler 2.15.2 → 3.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (111) hide show
  1. package/CHANGELOG.md +66 -1590
  2. package/bin/cdsc.js +42 -46
  3. package/doc/CHANGELOG_ARCHIVE.md +1592 -0
  4. package/doc/CHANGELOG_BETA.md +3 -4
  5. package/doc/CHANGELOG_DEPRECATED.md +35 -1
  6. package/doc/{DeprecatedOptions.md → DeprecatedOptions_v2.md} +3 -1
  7. package/doc/Versioning.md +20 -1
  8. package/lib/api/.eslintrc.json +2 -2
  9. package/lib/api/main.js +312 -143
  10. package/lib/api/options.js +15 -85
  11. package/lib/api/validate.js +6 -10
  12. package/lib/base/keywords.js +280 -110
  13. package/lib/base/message-registry.js +80 -24
  14. package/lib/base/messages.js +103 -52
  15. package/lib/base/model.js +44 -2
  16. package/lib/base/optionProcessorHelper.js +53 -21
  17. package/lib/checks/actionsFunctions.js +7 -5
  18. package/lib/checks/annotationsOData.js +1 -1
  19. package/lib/checks/cdsPersistence.js +1 -0
  20. package/lib/checks/elements.js +6 -6
  21. package/lib/checks/invalidTarget.js +1 -1
  22. package/lib/checks/nonexpandableStructured.js +1 -1
  23. package/lib/checks/queryNoDbArtifacts.js +2 -1
  24. package/lib/checks/selectItems.js +5 -1
  25. package/lib/checks/types.js +4 -2
  26. package/lib/checks/utils.js +2 -2
  27. package/lib/checks/validator.js +2 -1
  28. package/lib/compiler/assert-consistency.js +15 -10
  29. package/lib/compiler/builtins.js +127 -10
  30. package/lib/compiler/define.js +6 -4
  31. package/lib/compiler/extend.js +63 -12
  32. package/lib/compiler/finalize-parse-cdl.js +20 -9
  33. package/lib/compiler/index.js +25 -11
  34. package/lib/compiler/moduleLayers.js +7 -0
  35. package/lib/compiler/populate.js +16 -14
  36. package/lib/compiler/propagator.js +3 -3
  37. package/lib/compiler/resolve.js +194 -222
  38. package/lib/compiler/shared.js +56 -76
  39. package/lib/compiler/tweak-assocs.js +9 -10
  40. package/lib/compiler/utils.js +7 -2
  41. package/lib/edm/annotations/genericTranslation.js +60 -6
  42. package/lib/edm/annotations/preprocessAnnotations.js +10 -11
  43. package/lib/edm/csn2edm.js +39 -41
  44. package/lib/edm/edm.js +22 -15
  45. package/lib/edm/edmPreprocessor.js +66 -69
  46. package/lib/edm/edmUtils.js +12 -62
  47. package/lib/gen/Dictionary.json +8 -6
  48. package/lib/gen/language.checksum +1 -1
  49. package/lib/gen/language.interp +8 -30
  50. package/lib/gen/language.tokens +105 -114
  51. package/lib/gen/languageLexer.interp +1 -34
  52. package/lib/gen/languageLexer.js +889 -1007
  53. package/lib/gen/languageLexer.tokens +95 -106
  54. package/lib/gen/languageParser.js +20717 -22376
  55. package/lib/json/from-csn.js +73 -68
  56. package/lib/json/to-csn.js +13 -10
  57. package/lib/language/antlrParser.js +2 -2
  58. package/lib/language/docCommentParser.js +61 -38
  59. package/lib/language/errorStrategy.js +52 -40
  60. package/lib/language/genericAntlrParser.js +333 -259
  61. package/lib/language/language.g4 +600 -645
  62. package/lib/language/multiLineStringParser.js +14 -42
  63. package/lib/language/textUtils.js +44 -0
  64. package/lib/main.d.ts +27 -42
  65. package/lib/main.js +104 -81
  66. package/lib/model/csnRefs.js +2 -1
  67. package/lib/model/csnUtils.js +183 -285
  68. package/lib/model/revealInternalProperties.js +32 -9
  69. package/lib/model/sortViews.js +32 -31
  70. package/lib/optionProcessor.js +64 -57
  71. package/lib/render/.eslintrc.json +1 -1
  72. package/lib/render/DuplicateChecker.js +4 -7
  73. package/lib/render/manageConstraints.js +70 -2
  74. package/lib/render/toCdl.js +334 -339
  75. package/lib/render/toHdbcds.js +20 -16
  76. package/lib/render/toRename.js +44 -22
  77. package/lib/render/toSql.js +60 -54
  78. package/lib/render/utils/common.js +15 -1
  79. package/lib/render/utils/sql.js +20 -19
  80. package/lib/sql-identifier.js +6 -0
  81. package/lib/transform/db/.eslintrc.json +3 -2
  82. package/lib/transform/db/cdsPersistence.js +5 -15
  83. package/lib/transform/db/constraints.js +1 -1
  84. package/lib/transform/db/expansion.js +7 -6
  85. package/lib/transform/db/flattening.js +18 -19
  86. package/lib/transform/db/views.js +3 -3
  87. package/lib/transform/draft/.eslintrc.json +2 -2
  88. package/lib/transform/draft/db.js +6 -6
  89. package/lib/transform/draft/odata.js +6 -7
  90. package/lib/transform/forHanaNew.js +19 -22
  91. package/lib/transform/forOdataNew.js +13 -15
  92. package/lib/transform/localized.js +35 -25
  93. package/lib/transform/odata/toFinalBaseType.js +11 -9
  94. package/lib/transform/odata/typesExposure.js +3 -3
  95. package/lib/transform/odata/utils.js +1 -38
  96. package/lib/transform/transformUtilsNew.js +63 -77
  97. package/lib/transform/translateAssocsToJoins.js +6 -2
  98. package/lib/transform/universalCsn/.eslintrc.json +2 -2
  99. package/lib/transform/universalCsn/coreComputed.js +11 -6
  100. package/lib/transform/universalCsn/universalCsnEnricher.js +33 -5
  101. package/lib/utils/file.js +31 -21
  102. package/lib/utils/timetrace.js +20 -21
  103. package/package.json +34 -4
  104. package/share/messages/syntax-expected-integer.md +9 -8
  105. package/doc/ApiMigration.md +0 -237
  106. package/doc/CommandLineMigration.md +0 -58
  107. package/doc/ErrorMessages.md +0 -175
  108. package/doc/FioriAnnotations.md +0 -94
  109. package/doc/ODataTransformation.md +0 -273
  110. package/lib/backends.js +0 -529
  111. package/lib/fix_antlr4-8_warning.js +0 -56
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);
@@ -273,6 +270,7 @@ function executeCommandLine(command, options, args) {
273
270
  if (!commands[command] && !commandsWithoutCompilation[command])
274
271
  throw new Error(`Missing implementation for command ${command}`);
275
272
 
273
+ remapCmdOptions( options, command );
276
274
 
277
275
  if (commandsWithoutCompilation[command]) {
278
276
  commandsWithoutCompilation[command]();
@@ -296,7 +294,7 @@ function executeCommandLine(command, options, args) {
296
294
  // Return the original model (for chaining)
297
295
  function toCdl( model ) {
298
296
  const csn = options.directBackend ? model : compactModel(model, options);
299
- const cdlResult = main.to.cdl(csn, remapCmdOptions(options));
297
+ const cdlResult = main.to.cdl(csn, options);
300
298
  for (const name in cdlResult)
301
299
  writeToFileOrDisplay(options.out, `${name}.cds`, cdlResult[name]);
302
300
 
@@ -321,11 +319,11 @@ function executeCommandLine(command, options, args) {
321
319
  function toHana( model ) {
322
320
  const csn = options.directBackend ? model : compactModel(model, options);
323
321
 
324
- if (options.toHana && options.toHana.csn) {
325
- displayNamedCsn(for_hdbcds(csn, remapCmdOptions(options, options.toHana)), 'hana_csn');
322
+ if (options.csn) {
323
+ displayNamedCsn(for_hdbcds(csn, options), 'hana_csn');
326
324
  }
327
325
  else {
328
- const hanaResult = main.to.hdbcds(csn, remapCmdOptions(options, options.toHana));
326
+ const hanaResult = main.to.hdbcds(csn, options);
329
327
  for (const name in hanaResult)
330
328
  writeToFileOrDisplay(options.out, name, hanaResult[name]);
331
329
  }
@@ -336,25 +334,23 @@ function executeCommandLine(command, options, args) {
336
334
  // Execute the command line option '--to-odata' and display the results.
337
335
  // Return the original model (for chaining)
338
336
  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;
337
+ if (options.odataVersion === 'v4x') {
338
+ options.odataVersion = 'v4';
339
+ options.odataFormat = 'structured';
340
+ options.odataContainment = true;
344
341
  }
345
342
  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);
343
+ if (options.csn) {
344
+ const odataCsn = main.for.odata(csn, options);
349
345
  displayNamedCsn(odataCsn, 'odata_csn');
350
346
  }
351
- else if (options.toOdata && options.toOdata.json) {
352
- const result = main.to.edm.all(csn, odataOptions);
347
+ else if (options.json) {
348
+ const result = main.to.edm.all(csn, options);
353
349
  for (const serviceName in result)
354
350
  writeToFileOrDisplay(options.out, `${serviceName}.json`, result[serviceName]);
355
351
  }
356
352
  else {
357
- const result = main.to.edmx.all(csn, odataOptions);
353
+ const result = main.to.edmx.all(csn, options);
358
354
  for (const serviceName in result)
359
355
  writeToFileOrDisplay(options.out, `${serviceName}.xml`, result[serviceName]);
360
356
  }
@@ -368,14 +364,14 @@ function executeCommandLine(command, options, args) {
368
364
  // / DO NOT DELETE THIS TORENAME FUNCTIONALITY!!
369
365
  function toRename( model ) {
370
366
  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`;
367
+ const renameResult = _toRename(csn, options);
368
+ let storedProcedure = `PROCEDURE RENAME_${renameResult.options.sqlMapping.toUpperCase()}_TO_PLAIN LANGUAGE SQLSCRIPT AS BEGIN\n`;
373
369
  for (const name in renameResult.rename) {
374
370
  storedProcedure += ` --\n -- ${name}\n --\n`;
375
371
  storedProcedure += renameResult.rename[name];
376
372
  }
377
373
  storedProcedure += 'END;\n';
378
- writeToFileOrDisplay(options.out, `storedProcedure_${renameResult.options.toRename.names}_to_plain.sql`, storedProcedure, true);
374
+ writeToFileOrDisplay(options.out, `storedProcedure_${renameResult.options.sqlMapping}_to_plain.sql`, storedProcedure, true);
379
375
  return model;
380
376
  }
381
377
 
@@ -397,21 +393,21 @@ function executeCommandLine(command, options, args) {
397
393
  // Return the original model (for chaining)
398
394
  function toSql( model ) {
399
395
  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');
396
+ if (options.src === 'hdi') {
397
+ if (options.csn) {
398
+ displayNamedCsn(for_hdi(csn, options), 'hdi_csn');
403
399
  }
404
400
  else {
405
- const hdiResult = main.to.hdi(csn, remapCmdOptions(options, options.toSql));
401
+ const hdiResult = main.to.hdi(csn, options);
406
402
  for (const name in hdiResult)
407
403
  writeToFileOrDisplay(options.out, name, hdiResult[name]);
408
404
  }
409
405
  }
410
- else if (options.toSql && options.toSql.csn) {
411
- displayNamedCsn(for_sql(csn, remapCmdOptions(options, options.toSql)), 'sql_csn');
406
+ else if (options.csn) {
407
+ displayNamedCsn(for_sql(csn, options), 'sql_csn');
412
408
  }
413
409
  else {
414
- const sqlResult = main.to.sql(csn, remapCmdOptions(options, options.toSql));
410
+ const sqlResult = main.to.sql(csn, options);
415
411
  writeToFileOrDisplay(options.out, 'model.sql', sqlResult.join('\n'), true);
416
412
  }
417
413
  return model;
@@ -522,9 +518,9 @@ function executeCommandLine(command, options, args) {
522
518
  else if (options.internalMsg) {
523
519
  writeToFileOrDisplay(options.out, `${name}_raw.txt`, util.inspect(reveal(xsn).messages, { depth: null, maxArrayLength: null }), true);
524
520
  }
525
- else if (!options.lintMode) {
521
+ else if (!options.parseOnly) { // no output if parseOnly but not rawOutput
526
522
  const csn = compactModel(xsn, options);
527
- if (command === 'toCsn' && options.toCsn && options.toCsn.withLocalized)
523
+ if (command === 'toCsn' && options.withLocalized)
528
524
  addLocalizationViews(csn, options);
529
525
  if (options.enrichCsn)
530
526
  enrichCsn( csn, options );
@@ -542,8 +538,8 @@ function executeCommandLine(command, options, args) {
542
538
  if (options.internalMsg) {
543
539
  writeToFileOrDisplay(options.out, `${name}_raw.txt`, options.messages, true);
544
540
  }
545
- else if (!options.lintMode && !options.internalMsg) {
546
- if (command === 'toCsn' && options.toCsn && options.toCsn.withLocalized)
541
+ else if (!options.internalMsg) {
542
+ if (command === 'toCsn' && options.withLocalized)
547
543
  addLocalizationViews(csn, options);
548
544
  writeToFileOrDisplay(options.out, `${name}.json`, csn, true);
549
545
  }
@@ -555,7 +551,7 @@ function executeCommandLine(command, options, args) {
555
551
  // If displaying to stdout, prepend a headline containing 'filename', unless 'omitHeadline' is set.
556
552
  // For filenames, illegal characters (slash, backslash, colon) are replaced by '_'.
557
553
  function writeToFileOrDisplay(dir, fileName, content, omitHeadline = false) {
558
- if (options.lintMode && !options.rawOutput || options.internalMsg)
554
+ if (options.internalMsg)
559
555
  return;
560
556
  fileName = fileName.replace(/[:/\\]/g, '_');
561
557