@sap/cds-compiler 2.11.4 → 2.13.8

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 (133) hide show
  1. package/CHANGELOG.md +159 -1
  2. package/bin/cds_update_identifiers.js +7 -7
  3. package/bin/cdsc.js +22 -23
  4. package/bin/cdsse.js +2 -2
  5. package/doc/CHANGELOG_ARCHIVE.md +1 -1
  6. package/doc/CHANGELOG_BETA.md +25 -6
  7. package/doc/CHANGELOG_DEPRECATED.md +22 -6
  8. package/doc/NameResolution.md +21 -16
  9. package/lib/api/main.js +30 -63
  10. package/lib/api/options.js +5 -5
  11. package/lib/api/validate.js +0 -5
  12. package/lib/backends.js +15 -23
  13. package/lib/base/dictionaries.js +0 -8
  14. package/lib/base/error.js +26 -0
  15. package/lib/base/keywords.js +7 -17
  16. package/lib/base/location.js +9 -4
  17. package/lib/base/message-registry.js +52 -2
  18. package/lib/base/messages.js +16 -26
  19. package/lib/base/model.js +2 -62
  20. package/lib/base/optionProcessorHelper.js +246 -183
  21. package/lib/checks/.eslintrc.json +2 -0
  22. package/lib/checks/actionsFunctions.js +2 -1
  23. package/lib/checks/annotationsOData.js +1 -1
  24. package/lib/checks/cdsPersistence.js +2 -1
  25. package/lib/checks/enricher.js +17 -1
  26. package/lib/checks/foreignKeys.js +4 -4
  27. package/lib/checks/invalidTarget.js +3 -1
  28. package/lib/checks/managedInType.js +4 -4
  29. package/lib/checks/managedWithoutKeys.js +3 -1
  30. package/lib/checks/queryNoDbArtifacts.js +1 -3
  31. package/lib/checks/selectItems.js +4 -4
  32. package/lib/checks/sql-snippets.js +94 -0
  33. package/lib/checks/types.js +1 -1
  34. package/lib/checks/validator.js +12 -7
  35. package/lib/compiler/assert-consistency.js +10 -6
  36. package/lib/compiler/base.js +0 -1
  37. package/lib/compiler/builtins.js +8 -6
  38. package/lib/compiler/checks.js +46 -12
  39. package/lib/compiler/cycle-detector.js +1 -1
  40. package/lib/compiler/define.js +1103 -0
  41. package/lib/compiler/extend.js +983 -0
  42. package/lib/compiler/finalize-parse-cdl.js +231 -0
  43. package/lib/compiler/index.js +33 -14
  44. package/lib/compiler/kick-start.js +190 -0
  45. package/lib/compiler/moduleLayers.js +4 -4
  46. package/lib/compiler/populate.js +1226 -0
  47. package/lib/compiler/propagator.js +113 -47
  48. package/lib/compiler/resolve.js +1433 -0
  49. package/lib/compiler/shared.js +76 -38
  50. package/lib/compiler/tweak-assocs.js +529 -0
  51. package/lib/compiler/utils.js +204 -33
  52. package/lib/edm/.eslintrc.json +5 -0
  53. package/lib/edm/annotations/genericTranslation.js +38 -25
  54. package/lib/edm/annotations/preprocessAnnotations.js +3 -3
  55. package/lib/edm/csn2edm.js +10 -9
  56. package/lib/edm/edm.js +19 -20
  57. package/lib/edm/edmPreprocessor.js +166 -95
  58. package/lib/edm/edmUtils.js +127 -34
  59. package/lib/gen/Dictionary.json +92 -43
  60. package/lib/gen/language.checksum +1 -1
  61. package/lib/gen/language.interp +11 -1
  62. package/lib/gen/language.tokens +86 -82
  63. package/lib/gen/languageLexer.interp +18 -1
  64. package/lib/gen/languageLexer.js +925 -847
  65. package/lib/gen/languageLexer.tokens +78 -74
  66. package/lib/gen/languageParser.js +5434 -4298
  67. package/lib/json/from-csn.js +59 -17
  68. package/lib/json/to-csn.js +143 -71
  69. package/lib/language/antlrParser.js +3 -3
  70. package/lib/language/docCommentParser.js +3 -3
  71. package/lib/language/genericAntlrParser.js +144 -54
  72. package/lib/language/language.g4 +424 -203
  73. package/lib/language/multiLineStringParser.js +536 -0
  74. package/lib/main.d.ts +472 -61
  75. package/lib/main.js +38 -11
  76. package/lib/model/api.js +3 -1
  77. package/lib/model/csnRefs.js +321 -204
  78. package/lib/model/csnUtils.js +224 -263
  79. package/lib/model/enrichCsn.js +97 -40
  80. package/lib/model/revealInternalProperties.js +27 -6
  81. package/lib/model/sortViews.js +2 -1
  82. package/lib/modelCompare/compare.js +17 -12
  83. package/lib/optionProcessor.js +7 -6
  84. package/lib/render/DuplicateChecker.js +1 -1
  85. package/lib/render/manageConstraints.js +36 -33
  86. package/lib/render/toCdl.js +174 -275
  87. package/lib/render/toHdbcds.js +201 -115
  88. package/lib/render/toRename.js +7 -10
  89. package/lib/render/toSql.js +149 -75
  90. package/lib/render/utils/common.js +22 -8
  91. package/lib/render/utils/sql.js +10 -7
  92. package/lib/render/utils/stringEscapes.js +111 -0
  93. package/lib/sql-identifier.js +1 -1
  94. package/lib/transform/.eslintrc.json +5 -0
  95. package/lib/transform/braceExpression.js +4 -2
  96. package/lib/transform/db/.eslintrc.json +2 -0
  97. package/lib/transform/db/applyTransformations.js +35 -12
  98. package/lib/transform/db/assertUnique.js +1 -1
  99. package/lib/transform/db/associations.js +187 -0
  100. package/lib/transform/db/cdsPersistence.js +150 -0
  101. package/lib/transform/db/constraints.js +61 -56
  102. package/lib/transform/db/expansion.js +50 -29
  103. package/lib/transform/db/flattening.js +552 -105
  104. package/lib/transform/db/groupByOrderBy.js +3 -1
  105. package/lib/transform/db/temporal.js +236 -0
  106. package/lib/transform/db/transformExists.js +94 -28
  107. package/lib/transform/db/views.js +5 -4
  108. package/lib/transform/draft/.eslintrc.json +38 -0
  109. package/lib/transform/{db/draft.js → draft/db.js} +9 -7
  110. package/lib/transform/draft/odata.js +227 -0
  111. package/lib/transform/forHanaNew.js +94 -801
  112. package/lib/transform/forOdataNew.js +22 -175
  113. package/lib/transform/localized.js +36 -32
  114. package/lib/transform/odata/generateForeignKeyElements.js +3 -3
  115. package/lib/transform/odata/referenceFlattener.js +95 -89
  116. package/lib/transform/odata/structureFlattener.js +1 -1
  117. package/lib/transform/odata/toFinalBaseType.js +86 -12
  118. package/lib/transform/odata/typesExposure.js +5 -5
  119. package/lib/transform/odata/utils.js +2 -2
  120. package/lib/transform/transformUtilsNew.js +47 -33
  121. package/lib/transform/translateAssocsToJoins.js +10 -27
  122. package/lib/transform/universalCsn/.eslintrc.json +36 -0
  123. package/lib/transform/universalCsn/coreComputed.js +170 -0
  124. package/lib/transform/universalCsn/universalCsnEnricher.js +715 -0
  125. package/lib/transform/universalCsn/utils.js +63 -0
  126. package/lib/utils/file.js +2 -1
  127. package/lib/utils/objectUtils.js +30 -0
  128. package/lib/utils/timetrace.js +8 -2
  129. package/package.json +1 -1
  130. package/share/messages/README.md +26 -0
  131. package/lib/compiler/definer.js +0 -2340
  132. package/lib/compiler/resolver.js +0 -2988
  133. package/lib/transform/universalCsnEnricher.js +0 -67
@@ -125,6 +125,7 @@ class CompileMessage {
125
125
  * @param {CSN.MessageSeverity} [severity='Error'] Severity: Debug, Info, Warning, Error
126
126
  * @param {string} [id] The ID of the message - visible as property messageId
127
127
  * @param {any} [home]
128
+ * @param {string} [moduleName] Name of the module that created this message
128
129
  *
129
130
  * @memberOf CompileMessage
130
131
  */
@@ -175,22 +176,6 @@ function dollarLocation( location ) {
175
176
  return loc;
176
177
  }
177
178
 
178
- /**
179
- * Handle compiler messages, i.e. throw a compiler exception if there are errors.
180
- *
181
- * @param {object} model CSN or XSN
182
- * @param {CSN.Options} [options]
183
- * @deprecated Use throwWithError() from makeMessageFunction instead.
184
- */
185
- function handleMessages( model, options = {} ) {
186
- const messages = options.messages;
187
- if (messages && messages.length) {
188
- if (hasErrors( messages ))
189
- throw new CompilationError( messages, options.attachValidNames && model );
190
- }
191
- return model;
192
- }
193
-
194
179
  const severitySpecs = {
195
180
  error: { name: 'Error', level: 0 },
196
181
  warning: { name: 'Warning', level: 1 },
@@ -282,16 +267,16 @@ function compareSeverities( a, b ) {
282
267
  /**
283
268
  * @todo This was copied from somewhere just to make CSN paths work.
284
269
  * @param {CSN.Model} model
285
- * @param {CSN.Path} path
270
+ * @param {CSN.Path} csnPath
286
271
  */
287
- function searchForLocation( model, path ) {
272
+ function searchForLocation( model, csnPath ) {
288
273
  if (!model)
289
274
  return null;
290
275
  // Don't display a location if we cannot find one!
291
276
  let lastLocation = null;
292
277
  /** @type {object} */
293
278
  let currentStep = model;
294
- for (const step of path) {
279
+ for (const step of csnPath) {
295
280
  if (!currentStep)
296
281
  return lastLocation;
297
282
  currentStep = currentStep[step];
@@ -1101,13 +1086,15 @@ function artName( art, omit ) {
1101
1086
  r.push( (art.kind === 'extend' ? 'block:' : 'query:') + name.select ); // TODO: rename to 'select:1' and consider whether there are more selects
1102
1087
  if (name.action && omit !== 'action')
1103
1088
  r.push( memberActionName(art) + ':' + quoted( name.action ) );
1104
- if (name.alias)
1089
+ if (name.alias && art.kind !== '$self')
1105
1090
  r.push( (art.kind === 'mixin' ? 'mixin:' : 'alias:') + quoted( name.alias ) )
1106
1091
  if (name.param != null && omit !== 'param')
1107
1092
  r.push( name.param ? 'param:' + quoted( name.param ) : 'returns' ); // TODO: join
1108
1093
  if (name.element && omit !== 'element')
1109
1094
  // r.push( `${ art.kind }: ${ quoted( name.element )}` ); or even better element:"assoc"/key:"i" same with enum
1110
1095
  r.push( (art.kind === 'enum' ? 'enum:' : 'element:') + quoted( name.element ) );
1096
+ if (art.kind === '$self')
1097
+ r.push( 'alias:' + quoted( name.alias ) ) // should be late due to $self in anonymous aspect
1111
1098
  return r.join('/');
1112
1099
  }
1113
1100
 
@@ -1120,6 +1107,7 @@ function memberActionName( art ) {
1120
1107
  return 'action';
1121
1108
  }
1122
1109
 
1110
+ // TODO: XSN-specific things should probably move out
1123
1111
  function homeName( art, absoluteOnly ) {
1124
1112
  if (!art)
1125
1113
  return art;
@@ -1135,8 +1123,10 @@ function homeName( art, absoluteOnly ) {
1135
1123
  return homeName( art.name._artifact, absoluteOnly ); // use corresponding definition
1136
1124
  else if (absoluteOnly)
1137
1125
  return art.name.absolute;
1138
- else
1139
- return (art._main ? art._main.kind : art.kind) + ':' + artName( art );
1126
+ let main = art._main || art;
1127
+ while (main._outer) // anonymous aspect
1128
+ main = main._outer._main;
1129
+ return main.kind + ':' + artName( art );
1140
1130
  }
1141
1131
 
1142
1132
  // The "home" for extensions is handled differently because `_artifact` is not
@@ -1190,9 +1180,9 @@ function constructSemanticLocationFromCsnPath(csnPath, model) {
1190
1180
 
1191
1181
  // remove definitions
1192
1182
  csnPath.shift();
1193
- const artName = csnPath.shift();
1194
- let currentThing = model.definitions[artName];
1195
- let result = `${ (currentThing && currentThing.kind) ? currentThing.kind : 'artifact' }:${ _quoted(artName) }`;
1183
+ const artifactName = csnPath.shift();
1184
+ let currentThing = model.definitions[artifactName];
1185
+ let result = `${ (currentThing && currentThing.kind) ? currentThing.kind : 'artifact' }:${ _quoted(artifactName) }`;
1196
1186
 
1197
1187
  if (!currentThing)
1198
1188
  return result;
@@ -1444,12 +1434,12 @@ module.exports = {
1444
1434
  createMessageFunctions,
1445
1435
  makeMessageFunction,
1446
1436
  artName,
1447
- handleMessages,
1448
1437
  sortMessages: (m => m.sort(compareMessage)),
1449
1438
  sortMessagesSeverityAware: (m => m.sort(compareMessageSeverityAware)),
1450
1439
  deduplicateMessages,
1451
1440
  CompileMessage,
1452
1441
  CompilationError,
1442
+ isMessageDowngradable: isDowngradable,
1453
1443
  explainMessage,
1454
1444
  hasMessageExplanation,
1455
1445
  messageIdsWithExplanation,
package/lib/base/model.js CHANGED
@@ -63,7 +63,7 @@ function isBetaEnabled( options, feature ) {
63
63
  */
64
64
  function isDeprecatedEnabled( options, feature = null ) {
65
65
  const { deprecated } = options;
66
- if(!feature)
66
+ if (!feature)
67
67
  return !!deprecated;
68
68
  return deprecated && typeof deprecated === 'object' && deprecated[feature];
69
69
  }
@@ -93,63 +93,6 @@ function forEachMember( construct, callback, target ) {
93
93
 
94
94
  }
95
95
 
96
- // Apply function `callback(member, memberName, prop)` to each member in
97
- // `construct`, recursively (i.e. also for sub-elements of elements).
98
- function forEachMemberRecursively( construct, callback ) {
99
- forEachMember( construct, ( member, memberName, prop ) => {
100
- callback( member, memberName, prop );
101
- // Descend into nested members, too
102
- forEachMemberRecursively( member, callback );
103
- });
104
- // If 'construct' has more than one query, descend into the elements of the remaining ones, too
105
- if (construct.$queries && construct.$queries.length > 1) {
106
- construct.$queries.slice(1).forEach(query => forEachMemberRecursively(query, callback));
107
- }
108
- }
109
-
110
- /**
111
- * Apply function `callback` to all members of object `obj` (main artifact or
112
- * parent member). Members are considered those in dictionaries `elements`,
113
- * `enum`, `actions` and `params` of `obj`, `elements` and `enums` are also
114
- * searched inside property `items` (array of). `$queries`, `mixin` and
115
- * `columns` are also visited in contrast to `forEachMember()`.
116
- * See function `forEachGeneric()` for details.
117
- *
118
- * @param {XSN.Artifact} construct
119
- * @param {(member: object, memberName: string, prop: string) => any} callback
120
- * @param {object} [target]
121
- */
122
- function forEachMemberWithQuery( construct, callback, target ) {
123
- let obj = construct.returns || construct; // why the extra `returns` for actions?
124
- obj = obj.items || obj;
125
- forEachGeneric( target || obj, 'elements', callback );
126
- forEachGeneric( obj, 'enum', callback );
127
- forEachGeneric( obj, 'foreignKeys', callback );
128
- forEachGeneric( construct, 'actions', callback );
129
- forEachGeneric( construct, 'params', callback );
130
- // For Queries
131
- forEachGeneric( construct, '$queries', callback );
132
- forEachGeneric( construct, 'mixin', callback );
133
- forEachGeneric( construct, 'columns', callback );
134
- }
135
-
136
- /**
137
- * Apply function `callback(member, memberName, prop)` to each member in
138
- * `construct`, recursively (i.e. also for sub-elements of elements).
139
- * In contrast to `forEachMemberRecursively()` this function also traverses
140
- * queries and mixins.
141
- *
142
- * @param {XSN.Artifact} construct
143
- * @param {(member: object, memberName: string, prop: string) => any} callback
144
- */
145
- function forEachMemberRecursivelyWithQuery( construct, callback ) {
146
- forEachMemberWithQuery( construct, ( member, memberName, prop ) => {
147
- callback( member, memberName, prop );
148
- // Descend into nested members, too
149
- forEachMemberRecursivelyWithQuery( member, callback );
150
- });
151
- }
152
-
153
96
  // Apply function `callback` to all objects in dictionary `dict`, including all
154
97
  // duplicates (found under the same name). Function `callback` is called with
155
98
  // the following arguments: the object, the name, and -if it is a duplicate-
@@ -157,7 +100,7 @@ function forEachMemberRecursivelyWithQuery( construct, callback ) {
157
100
  function forEachGeneric( obj, prop, callback ) {
158
101
  let dict = obj[prop];
159
102
  for (let name in dict) {
160
- let obj = dict[name];
103
+ obj = dict[name];
161
104
  callback( obj, name, prop );
162
105
  if (Array.isArray(obj.$duplicates)) // redefinitions
163
106
  obj.$duplicates.forEach( o => callback( o, name, prop ) )
@@ -189,9 +132,6 @@ module.exports = {
189
132
  queryOps,
190
133
  forEachDefinition,
191
134
  forEachMember,
192
- forEachMemberRecursively,
193
- forEachMemberWithQuery,
194
- forEachMemberRecursivelyWithQuery,
195
135
  forEachGeneric,
196
136
  forEachInOrder,
197
137
  setProp,