@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
@@ -24,7 +24,7 @@ const publicOptionsNewAPI = [
24
24
  'sqlChangeMode',
25
25
  'allowCsnDowngrade',
26
26
  'joinfk',
27
- 'magicVars', // deprecated
27
+ 'magicVars', // deprecated, not removed in v3 as we have specific error messages for it
28
28
  'variableReplacements',
29
29
  // ODATA
30
30
  'odataVersion',
@@ -57,9 +57,7 @@ const privateOptions = [
57
57
  'noRecompile',
58
58
  'internalMsg',
59
59
  'disableHanaComments', // in case of issues with hana comment rendering
60
- 'dependentAutoexposed', // deprecated, no effect - TODO: safe to remove?
61
- 'longAutoexposed', // deprecated, no effect - TODO: safe to remove?
62
- 'localizedWithoutCoalesce', // deprecated version of 'localizedLanguageFallback',
60
+ 'localizedWithoutCoalesce', // deprecated version of 'localizedLanguageFallback', TODO(v4): Remove option
63
61
  ];
64
62
 
65
63
  const overallOptions = publicOptionsNewAPI.concat(privateOptions);
@@ -107,47 +105,10 @@ function translateOptions(input = {}, defaults = {}, hardRequire = {},
107
105
  // Overwrite with the hardRequire options - like src: sql in to.sql()
108
106
  Object.assign(options, hardRequire);
109
107
 
110
- for (const optionName in options) {
111
- const optionValue = options[optionName];
112
- mapToOldNames(optionName, optionValue);
113
- }
114
-
115
108
  // Convenience for $user -> $user.id replacement
116
109
  if (options.variableReplacements && options.variableReplacements.$user && typeof options.variableReplacements.$user === 'string')
117
110
  options.variableReplacements.$user = { id: options.variableReplacements.$user };
118
111
 
119
- /**
120
- * Map a new-style option to it's old format
121
- *
122
- * @param {string} optionName Name of the option to map
123
- * @param {any} optionValue Value of the option to map
124
- */
125
- function mapToOldNames(optionName, optionValue) {
126
- // Keep all input options and add the "compatibility" options
127
- switch (optionName) {
128
- case 'beta':
129
- options.betaMode = optionValue;
130
- break;
131
- case 'odataVersion':
132
- options.version = optionValue;
133
- break;
134
- case 'sqlDialect':
135
- options.dialect = optionValue;
136
- break;
137
- case 'sqlMapping':
138
- options.names = optionValue;
139
- break;
140
- // No need to remap variableReplacements here - we use the new mechanism with that directly
141
- case 'magicVars':
142
- if (optionValue.user)
143
- options.user = optionValue.user;
144
- if (optionValue.locale)
145
- options.locale = optionValue.locale;
146
- break;
147
- default: break;
148
- }
149
- }
150
-
151
112
  return options;
152
113
  }
153
114
 
@@ -155,80 +116,48 @@ module.exports = {
155
116
  to: {
156
117
  cdl: options => translateOptions(options, undefined, undefined, undefined, undefined, 'to.cdl'),
157
118
  sql: (options) => {
158
- const hardOptions = { src: 'sql' };
119
+ const hardOptions = { src: 'sql', toSql: true, forHana: true };
159
120
  const defaultOptions = { sqlMapping: 'plain', sqlDialect: 'plain' };
160
121
  const processed = translateOptions(options, defaultOptions, hardOptions, undefined, [ 'sql-dialect-and-naming' ], 'to.sql');
161
122
 
162
- const result = Object.assign({}, processed);
163
- result.toSql = Object.assign({}, processed);
164
-
165
- return result;
123
+ return Object.assign({}, processed);
166
124
  },
167
125
  hdi: (options) => {
168
- const hardOptions = { src: 'hdi' };
126
+ const hardOptions = { src: 'hdi', toSql: true, forHana: true };
169
127
  const defaultOptions = { sqlMapping: 'plain', sqlDialect: 'hana' };
170
- const processed = translateOptions(options, defaultOptions, hardOptions, { sqlDialect: generateStringValidator([ 'hana' ]) }, undefined, 'to.hdi');
171
-
172
- const result = Object.assign({}, processed);
173
- result.toSql = Object.assign({}, processed);
174
-
175
- return result;
128
+ return translateOptions(options, defaultOptions, hardOptions, { sqlDialect: generateStringValidator([ 'hana' ]) }, undefined, 'to.hdi');
176
129
  },
177
130
  hdbcds: (options) => {
131
+ const hardOptions = { forHana: true };
178
132
  const defaultOptions = { sqlMapping: 'plain', sqlDialect: 'hana' };
179
- const processed = translateOptions(options, defaultOptions, {}, { sqlDialect: generateStringValidator([ 'hana' ]) }, undefined, 'to.hdbcds');
180
-
181
- const result = Object.assign({}, processed);
182
- result.forHana = Object.assign({}, processed);
183
-
184
- return result;
133
+ return translateOptions(options, defaultOptions, hardOptions, { sqlDialect: generateStringValidator([ 'hana' ]) }, undefined, 'to.hdbcds');
185
134
  },
186
135
  edm: (options) => {
187
- const hardOptions = { json: true, combined: true };
136
+ const hardOptions = { json: true, combined: true, toOdata: true };
188
137
  const defaultOptions = { odataVersion: 'v4', odataFormat: 'flat' };
189
- const processed = translateOptions(options, defaultOptions, hardOptions, { odataVersion: generateStringValidator([ 'v4' ]) }, [ 'valid-structured' ], 'to.edm');
190
-
191
- const result = Object.assign({}, processed);
192
- result.toOdata = Object.assign({}, processed);
193
-
194
- return result;
138
+ return translateOptions(options, defaultOptions, hardOptions, { odataVersion: generateStringValidator([ 'v4' ]) }, [ 'valid-structured' ], 'to.edm');
195
139
  },
196
140
  edmx: (options) => {
197
- const hardOptions = { xml: true, combined: true };
141
+ const hardOptions = { xml: true, combined: true, toOdata: true };
198
142
  const defaultOptions = {
199
143
  odataVersion: 'v4', odataFormat: 'flat',
200
144
  };
201
- const processed = translateOptions(options, defaultOptions, hardOptions, undefined, [ 'valid-structured' ], 'to.edmx');
202
-
203
- const result = Object.assign({}, processed);
204
- result.toOdata = Object.assign({}, processed);
205
-
206
- return result;
145
+ return translateOptions(options, defaultOptions, hardOptions, undefined, [ 'valid-structured' ], 'to.edmx');
207
146
  },
208
147
  },
209
148
  for: { // TODO: Rename version to oDataVersion
210
-
211
149
  odata: (options) => {
150
+ const hardOptions = { toOdata: true };
212
151
  const defaultOptions = { odataVersion: 'v4', odataFormat: 'flat' };
213
- const processed = translateOptions(options, defaultOptions, undefined, undefined, [ 'valid-structured' ], 'for.odata');
214
-
215
- const result = Object.assign({}, processed);
216
- result.toOdata = Object.assign({}, processed);
217
-
218
-
219
- return result;
152
+ return translateOptions(options, defaultOptions, hardOptions, undefined, [ 'valid-structured' ], 'for.odata');
220
153
  },
221
154
  hana: (options) => {
155
+ const hardOptions = { forHana: true };
222
156
  const defaultOptions = { sqlMapping: 'plain', sqlDialect: 'hana' };
223
- const processed = translateOptions(options, defaultOptions, undefined, undefined, undefined, 'for.hana');
224
-
225
- const result = Object.assign({}, processed);
226
- result.forHana = Object.assign({}, processed);
227
-
228
-
229
- return result;
157
+ return translateOptions(options, defaultOptions, hardOptions, undefined, undefined, 'for.hana');
230
158
  },
231
159
  },
160
+ overallOptions, // exported for testing
232
161
  };
233
162
 
234
163
 
@@ -65,13 +65,6 @@ const validators = {
65
65
  return val === null ? val : `type ${ typeof val }`;
66
66
  },
67
67
  },
68
- magicVars: {
69
- validate: val => val !== null && typeof val === 'object' && !Array.isArray(val),
70
- expected: () => 'type object',
71
- found: (val) => {
72
- return val === null ? val : `type ${ typeof val }`;
73
- },
74
- },
75
68
  // TODO: Maybe do a deep validation of the whole object with leafs?
76
69
  variableReplacements: {
77
70
  validate: val => val !== null && typeof val === 'object' && !Array.isArray(val),
@@ -85,7 +78,7 @@ const validators = {
85
78
  expected: () => 'type array',
86
79
  found: val => `type ${ typeof val }`,
87
80
  },
88
- sqlDialect: generateStringValidator([ 'sqlite', 'hana', 'plain' ]),
81
+ sqlDialect: generateStringValidator([ 'sqlite', 'hana', 'plain', 'postgres' ]),
89
82
  sqlMapping: generateStringValidator([ 'plain', 'quoted', 'hdbcds' ]),
90
83
  odataVersion: generateStringValidator([ 'v2', 'v4' ]),
91
84
  odataFormat: generateStringValidator([ 'flat', 'structured' ]),
@@ -131,16 +124,19 @@ const allCombinationValidators = {
131
124
  'valid-structured': {
132
125
  validate: options => options.odataVersion === 'v2' && options.odataFormat === 'structured',
133
126
  severity: 'error',
127
+ getParameters: () => {},
134
128
  getMessage: () => 'Structured OData is only supported with OData version v4',
135
129
  },
136
130
  'sql-dialect-and-naming': {
137
131
  validate: options => options.sqlDialect && options.sqlMapping && ![ 'hana' ].includes(options.sqlDialect) && [ 'quoted', 'hdbcds' ].includes(options.sqlMapping),
138
132
  severity: 'error',
139
- getMessage: options => `sqlDialect '${ options.sqlDialect }' can't be combined with sqlMapping '${ options.sqlMapping }'`,
133
+ getParameters: options => ({ name: options.sqlDialect, prop: options.sqlMapping }),
134
+ getMessage: () => 'sqlDialect $(NAME) can\'t be combined with sqlMapping $(PROP)',
140
135
  },
141
136
  'beta-no-test': {
142
137
  validate: options => options.beta && !options.testMode,
143
138
  severity: 'warning',
139
+ getParameters: () => {},
144
140
  getMessage: () => 'Option "beta" was used. This option should not be used in productive scenarios!',
145
141
  },
146
142
  };
@@ -176,7 +172,7 @@ function validate(options, moduleName, customValidators = {}, combinationValidat
176
172
  for (const combinationValidatorName of combinationValidators.concat([ 'beta-no-test' ])) {
177
173
  const combinationValidator = allCombinationValidators[combinationValidatorName];
178
174
  if (combinationValidator.validate(options))
179
- message[combinationValidator.severity]('invalid-option-combination', null, {}, combinationValidator.getMessage(options));
175
+ message[combinationValidator.severity]('invalid-option-combination', null, combinationValidator.getParameters(options), combinationValidator.getMessage(options));
180
176
  }
181
177
 
182
178
  message.throwWithAnyError();