@sap/cds-compiler 2.12.0 → 2.15.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 (128) hide show
  1. package/CHANGELOG.md +221 -15
  2. package/bin/cdsc.js +125 -50
  3. package/bin/cdsse.js +2 -2
  4. package/doc/CHANGELOG_BETA.md +13 -6
  5. package/doc/CHANGELOG_DEPRECATED.md +22 -6
  6. package/doc/NameResolution.md +21 -16
  7. package/lib/api/main.js +47 -84
  8. package/lib/api/options.js +5 -6
  9. package/lib/api/validate.js +6 -11
  10. package/lib/backends.js +15 -23
  11. package/lib/base/dictionaries.js +0 -8
  12. package/lib/base/error.js +26 -0
  13. package/lib/base/keywords.js +7 -17
  14. package/lib/base/location.js +9 -4
  15. package/lib/base/message-registry.js +114 -18
  16. package/lib/base/messages.js +101 -90
  17. package/lib/base/model.js +2 -63
  18. package/lib/base/optionProcessorHelper.js +177 -123
  19. package/lib/checks/annotationsOData.js +12 -33
  20. package/lib/checks/arrayOfs.js +1 -34
  21. package/lib/checks/cdsPersistence.js +2 -1
  22. package/lib/checks/enricher.js +17 -1
  23. package/lib/checks/invalidTarget.js +3 -1
  24. package/lib/checks/managedWithoutKeys.js +3 -1
  25. package/lib/checks/selectItems.js +4 -4
  26. package/lib/checks/sql-snippets.js +27 -26
  27. package/lib/checks/types.js +1 -1
  28. package/lib/checks/validator.js +6 -11
  29. package/lib/compiler/assert-consistency.js +6 -3
  30. package/lib/compiler/base.js +1 -0
  31. package/lib/compiler/builtins.js +19 -6
  32. package/lib/compiler/checks.js +23 -60
  33. package/lib/compiler/cycle-detector.js +1 -1
  34. package/lib/compiler/define.js +1151 -0
  35. package/lib/compiler/extend.js +1000 -0
  36. package/lib/compiler/finalize-parse-cdl.js +237 -0
  37. package/lib/compiler/index.js +107 -39
  38. package/lib/compiler/kick-start.js +190 -0
  39. package/lib/compiler/moduleLayers.js +4 -4
  40. package/lib/compiler/populate.js +1227 -0
  41. package/lib/compiler/propagator.js +114 -46
  42. package/lib/compiler/resolve.js +1521 -0
  43. package/lib/compiler/shared.js +126 -65
  44. package/lib/compiler/tweak-assocs.js +535 -0
  45. package/lib/compiler/utils.js +197 -33
  46. package/lib/edm/.eslintrc.json +5 -0
  47. package/lib/edm/annotations/genericTranslation.js +38 -24
  48. package/lib/edm/annotations/preprocessAnnotations.js +2 -2
  49. package/lib/edm/csn2edm.js +219 -100
  50. package/lib/edm/edm.js +302 -230
  51. package/lib/edm/edmPreprocessor.js +554 -419
  52. package/lib/edm/edmUtils.js +138 -44
  53. package/lib/gen/Dictionary.json +100 -19
  54. package/lib/gen/language.checksum +1 -1
  55. package/lib/gen/language.interp +11 -1
  56. package/lib/gen/language.tokens +86 -83
  57. package/lib/gen/languageLexer.interp +10 -1
  58. package/lib/gen/languageLexer.js +860 -833
  59. package/lib/gen/languageLexer.tokens +78 -75
  60. package/lib/gen/languageParser.js +5765 -4480
  61. package/lib/json/csnVersion.js +10 -11
  62. package/lib/json/from-csn.js +15 -3
  63. package/lib/json/to-csn.js +126 -68
  64. package/lib/language/docCommentParser.js +4 -4
  65. package/lib/language/genericAntlrParser.js +123 -5
  66. package/lib/language/language.g4 +355 -156
  67. package/lib/language/multiLineStringParser.js +5 -5
  68. package/lib/main.d.ts +486 -59
  69. package/lib/main.js +41 -9
  70. package/lib/model/api.js +3 -1
  71. package/lib/model/csnRefs.js +252 -156
  72. package/lib/model/csnUtils.js +384 -297
  73. package/lib/model/enrichCsn.js +71 -29
  74. package/lib/model/revealInternalProperties.js +29 -8
  75. package/lib/model/sortViews.js +2 -1
  76. package/lib/modelCompare/compare.js +23 -18
  77. package/lib/optionProcessor.js +63 -26
  78. package/lib/render/manageConstraints.js +35 -32
  79. package/lib/render/toCdl.js +897 -947
  80. package/lib/render/toHdbcds.js +205 -257
  81. package/lib/render/toSql.js +264 -225
  82. package/lib/render/utils/common.js +136 -25
  83. package/lib/render/utils/sql.js +4 -3
  84. package/lib/render/utils/stringEscapes.js +111 -0
  85. package/lib/sql-identifier.js +1 -1
  86. package/lib/transform/.eslintrc.json +5 -0
  87. package/lib/transform/db/.eslintrc.json +3 -1
  88. package/lib/transform/db/applyTransformations.js +35 -12
  89. package/lib/transform/db/assertUnique.js +1 -1
  90. package/lib/transform/db/associations.js +104 -306
  91. package/lib/transform/db/cdsPersistence.js +2 -2
  92. package/lib/transform/db/constraints.js +58 -53
  93. package/lib/transform/db/expansion.js +60 -33
  94. package/lib/transform/db/flattening.js +582 -104
  95. package/lib/transform/db/groupByOrderBy.js +3 -1
  96. package/lib/transform/db/transformExists.js +66 -13
  97. package/lib/transform/db/views.js +11 -7
  98. package/lib/transform/draft/.eslintrc.json +38 -0
  99. package/lib/transform/{db/draft.js → draft/db.js} +6 -5
  100. package/lib/transform/draft/odata.js +227 -0
  101. package/lib/transform/forHanaNew.js +109 -208
  102. package/lib/transform/forOdataNew.js +59 -212
  103. package/lib/transform/localized.js +46 -26
  104. package/lib/transform/odata/toFinalBaseType.js +85 -11
  105. package/lib/transform/odata/typesExposure.js +147 -199
  106. package/lib/transform/odata/utils.js +2 -2
  107. package/lib/transform/transformUtilsNew.js +44 -33
  108. package/lib/transform/translateAssocsToJoins.js +3 -20
  109. package/lib/transform/universalCsn/.eslintrc.json +36 -0
  110. package/lib/transform/universalCsn/coreComputed.js +172 -0
  111. package/lib/transform/universalCsn/universalCsnEnricher.js +737 -0
  112. package/lib/transform/universalCsn/utils.js +63 -0
  113. package/lib/utils/moduleResolve.js +13 -6
  114. package/lib/utils/objectUtils.js +30 -0
  115. package/package.json +1 -1
  116. package/share/messages/README.md +26 -0
  117. package/share/messages/message-explanations.json +2 -1
  118. package/share/messages/syntax-expected-integer.md +37 -0
  119. package/lib/compiler/definer.js +0 -2361
  120. package/lib/compiler/resolver.js +0 -3079
  121. package/lib/transform/odata/attachPath.js +0 -96
  122. package/lib/transform/odata/expandStructKeysInAssociations.js +0 -59
  123. package/lib/transform/odata/generateForeignKeyElements.js +0 -261
  124. package/lib/transform/odata/referenceFlattener.js +0 -290
  125. package/lib/transform/odata/sortByAssociationDependency.js +0 -105
  126. package/lib/transform/odata/structuralPath.js +0 -72
  127. package/lib/transform/odata/structureFlattener.js +0 -171
  128. package/lib/transform/universalCsnEnricher.js +0 -237
@@ -0,0 +1,63 @@
1
+ 'use strict';
2
+
3
+ const {
4
+ applyTransformations,
5
+ } = require('../../model/csnUtils');
6
+ const { setProp } = require('../../base/model');
7
+
8
+ /**
9
+ * Set the annotation on the carrier if it is not already present.
10
+ *
11
+ * @param {object} carrier Object having/getting the annotation
12
+ * @param {string} name Name of the annotations
13
+ * @param {any} value Value of the annotation
14
+ */
15
+ function setAnnotationIfNotDefined(carrier, name, value) {
16
+ if (carrier[name] === undefined)
17
+ carrier[name] = value;
18
+ }
19
+
20
+ /**
21
+ * Strip/change the CSN to ensure compatibility with what we have in the client CSN
22
+ * - Removes every occurrence of '$origin', '$generated' and '$source'
23
+ * - elements of subqueries become non-enumerable
24
+ * - remove `actions|params|virtual|notNull: null`, this stops the inheritance of the actions/params/virtual
25
+ * along the $origin chain, this can be ignored for the comparison in our tests.
26
+ *
27
+ * @param {CSN.Model} csn
28
+ */
29
+ function makeClientCompatible(csn) {
30
+ applyTransformations(csn, {
31
+ actions: removeNullProperty,
32
+ notNull: removeNullProperty,
33
+ params: removeNullProperty,
34
+ virtual: removeNullProperty,
35
+ $origin: (parent, prop) => delete parent[prop],
36
+ $generated: (parent, prop) => delete parent[prop],
37
+ $source: (parent, prop) => delete parent[prop],
38
+ SELECT: (parent, prop, query) => {
39
+ if (query.elements)
40
+ setProp(query, 'elements', query.elements);
41
+ },
42
+ SET: (parent, prop, query) => {
43
+ if (query.elements)
44
+ setProp(query, 'elements', query.elements);
45
+ },
46
+ });
47
+ }
48
+
49
+ /**
50
+ * Removes the `prop` from the `node` if `prop === null`
51
+ *
52
+ * @param {object} node
53
+ * @param {string} prop
54
+ */
55
+ function removeNullProperty(node, prop) {
56
+ if (node[prop] === null)
57
+ delete node[prop];
58
+ }
59
+
60
+ module.exports = {
61
+ setAnnotationIfNotDefined,
62
+ makeClientCompatible,
63
+ };
@@ -28,13 +28,18 @@ const extensions = [ '.cds', '.csn', '.json' ];
28
28
  * - Why a global? The Umbrella could pass it as an option.
29
29
  *
30
30
  * @param {string} modulePath
31
+ * @param {CSN.Options} options
31
32
  * @returns {string}
32
33
  */
33
- function adaptCdsModule(modulePath) {
34
- // eslint-disable-next-line
35
- if (global['cds'] && global['cds'].home && modulePath.startsWith( '@sap/cds/' ))
34
+ function adaptCdsModule(modulePath, options = {}) {
35
+ if (modulePath.startsWith( '@sap/cds/' )) {
36
+ if (options.cdsHome)
37
+ return options.cdsHome + modulePath.slice(8);
36
38
  // eslint-disable-next-line
37
- return global['cds'].home + modulePath.slice(8)
39
+ if (global['cds'] && global['cds'].home)
40
+ // eslint-disable-next-line
41
+ return global['cds'].home + modulePath.slice(8);
42
+ }
38
43
  return modulePath;
39
44
  }
40
45
 
@@ -42,6 +47,7 @@ function adaptCdsModule(modulePath) {
42
47
  * @param {object} dep
43
48
  * @param {object} fileCache
44
49
  * @param {CSN.Options} options
50
+ * @param {object} messageFunctions
45
51
  */
46
52
  function resolveModule( dep, fileCache, options, messageFunctions ) {
47
53
  const _fs = cdsFs(fileCache, options.traceFs);
@@ -58,7 +64,7 @@ function resolveModule( dep, fileCache, options, messageFunctions ) {
58
64
  realpath: _fs.realpath,
59
65
  };
60
66
  return new Promise( (fulfill, reject) => {
61
- const lookupPath = adaptCdsModule(dep.module);
67
+ const lookupPath = adaptCdsModule(dep.module, options);
62
68
  resolveCDS( lookupPath, opts, (err, res) => {
63
69
  // console.log('RESOLVE', dep, res, err)
64
70
  if (err) {
@@ -105,6 +111,7 @@ function resolveModule( dep, fileCache, options, messageFunctions ) {
105
111
  * @param {object} dep
106
112
  * @param {object} fileCache
107
113
  * @param {CSN.Options} options
114
+ * @param {object} messageFunctions
108
115
  */
109
116
  function resolveModuleSync( dep, fileCache, options, messageFunctions ) {
110
117
  const _fs = cdsFs(fileCache, options.traceFs);
@@ -118,7 +125,7 @@ function resolveModuleSync( dep, fileCache, options, messageFunctions ) {
118
125
 
119
126
  let result = null;
120
127
  let error = null;
121
- const lookupPath = adaptCdsModule(dep.module);
128
+ const lookupPath = adaptCdsModule(dep.module, options);
122
129
 
123
130
  resolveCDS( lookupPath, opts, (err, res) => {
124
131
  if (err)
@@ -42,8 +42,38 @@ function forEach(obj, callback) {
42
42
  }
43
43
  }
44
44
 
45
+ /**
46
+ * Loops over all elements in an object and calls the specified callback(o[key]) for each key
47
+ * --> can be used as substitute for `Object.values(…).forEach(…)`
48
+ *
49
+ * @param {object} o the object which values should be iterated
50
+ * @param {Function} callback
51
+ */
52
+ function forEachValue(o, callback) {
53
+ for (const key in o) {
54
+ if (Object.hasOwnProperty.call(o, key))
55
+ callback(o[key]);
56
+ }
57
+ }
58
+
59
+ /**
60
+ * Loops over all elements in an object and calls the specified callback(key) for each key
61
+ * --> can be used as substitute for `Object.keys(…).forEach(…)`
62
+ *
63
+ * @param {object} o the object which keys should be iterated
64
+ * @param {Function} callback
65
+ */
66
+ function forEachKey(o, callback) {
67
+ for (const key in o) {
68
+ if (Object.hasOwnProperty.call(o, key))
69
+ callback(key);
70
+ }
71
+ }
72
+
45
73
  module.exports = {
46
74
  copyPropIfExist,
47
75
  createDict,
48
76
  forEach,
77
+ forEachValue,
78
+ forEachKey,
49
79
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sap/cds-compiler",
3
- "version": "2.12.0",
3
+ "version": "2.15.2",
4
4
  "description": "CDS (Core Data Services) compiler and backends",
5
5
  "homepage": "https://cap.cloud.sap/",
6
6
  "author": "SAP SE (https://www.sap.com)",
@@ -30,3 +30,29 @@ Furthermore:
30
30
  If users open the message in a terminal, it is often 80 characters wide.
31
31
  Even if that was not the case, longer lines are harder to read, so keep them
32
32
  short.
33
+
34
+ ## Example Structure
35
+
36
+ ```markdown
37
+ # ‹message-id›
38
+
39
+ Longer message text. Some background info.
40
+ Usually mentions the severity.
41
+
42
+ ## Example
43
+
44
+ Code which also lead to the current message,
45
+ with an explanation why it is problematic.
46
+
47
+ ## How to Fix
48
+
49
+ Description of options how the issue can be fixed, using the example.
50
+
51
+ ## Notes on …
52
+
53
+ Optional: more background info.
54
+
55
+ ## Related messages
56
+
57
+ - Optional: message ids for similar issues.
58
+ ```
@@ -9,6 +9,7 @@
9
9
  "extend-unrelated-layer",
10
10
  "redirected-to-ambiguous",
11
11
  "redirected-to-unrelated",
12
- "rewrite-not-supported"
12
+ "rewrite-not-supported",
13
+ "syntax-expected-integer"
13
14
  ]
14
15
  }
@@ -0,0 +1,37 @@
1
+ # syntax-expected-integer
2
+
3
+ The compiler expects a safe integer here.
4
+ The last safe Integer is `2^53 - 1` or `9007199254740991`.
5
+
6
+ A safe integer is an integer that
7
+
8
+ - can be exactly represented as an IEEE-754 double precision number, and
9
+ - whose IEEE-754 representation cannot be the result of rounding any
10
+ other integer to fit the IEEE-754 representation.
11
+
12
+ The message's severity is `Error`.
13
+
14
+ ## Example
15
+
16
+ Erroneous code example:
17
+
18
+ ```cdl
19
+ type LengthIsUnsafe : String(9007199254740992);
20
+ type NotAnInteger : String(42.1);
21
+ ```
22
+
23
+ In the above example, the string length for the type `LengthIsUnsafe` is not a
24
+ safe Integer. It is too large.
25
+ Likewise, the string length for the type `NotAnInteger` is a decimal.
26
+
27
+ ## How to Fix
28
+
29
+ To fix the issue, you have to provide a safe integer:
30
+
31
+ ```cdl
32
+ type LengthIsSafe : String(9007199254740991);
33
+ type AnInteger : String(42);
34
+ ```
35
+
36
+ If not feasible, a string representation of the number needs to be used,
37
+ e.g. in annotation values.