@sap/cds-compiler 2.10.2 → 2.11.4

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 (82) hide show
  1. package/CHANGELOG.md +90 -5
  2. package/bin/.eslintrc.json +1 -2
  3. package/bin/cds_update_identifiers.js +3 -1
  4. package/bin/cdsc.js +49 -25
  5. package/bin/cdsse.js +1 -0
  6. package/bin/cdsv2m.js +3 -2
  7. package/doc/CHANGELOG_BETA.md +10 -0
  8. package/lib/api/.eslintrc.json +2 -0
  9. package/lib/api/main.js +8 -36
  10. package/lib/api/options.js +15 -6
  11. package/lib/api/validate.js +30 -3
  12. package/lib/backends.js +12 -13
  13. package/lib/base/dictionaries.js +2 -1
  14. package/lib/base/keywords.js +3 -2
  15. package/lib/base/message-registry.js +34 -10
  16. package/lib/base/messages.js +38 -18
  17. package/lib/base/model.js +5 -4
  18. package/lib/base/optionProcessorHelper.js +57 -23
  19. package/lib/checks/emptyOrOnlyVirtual.js +2 -2
  20. package/lib/checks/selectItems.js +4 -0
  21. package/lib/checks/unknownMagic.js +6 -3
  22. package/lib/compiler/assert-consistency.js +9 -2
  23. package/lib/compiler/base.js +65 -0
  24. package/lib/compiler/builtins.js +62 -16
  25. package/lib/compiler/checks.js +2 -1
  26. package/lib/compiler/definer.js +66 -108
  27. package/lib/compiler/index.js +29 -29
  28. package/lib/compiler/propagator.js +5 -2
  29. package/lib/compiler/resolver.js +225 -58
  30. package/lib/compiler/shared.js +53 -229
  31. package/lib/compiler/utils.js +184 -0
  32. package/lib/edm/annotations/genericTranslation.js +1 -1
  33. package/lib/edm/csn2edm.js +3 -2
  34. package/lib/edm/edmPreprocessor.js +34 -38
  35. package/lib/edm/edmUtils.js +3 -3
  36. package/lib/gen/language.checksum +1 -1
  37. package/lib/gen/language.interp +17 -1
  38. package/lib/gen/language.tokens +79 -73
  39. package/lib/gen/languageLexer.interp +19 -1
  40. package/lib/gen/languageLexer.js +779 -731
  41. package/lib/gen/languageLexer.tokens +71 -65
  42. package/lib/gen/languageParser.js +4668 -4072
  43. package/lib/json/from-csn.js +10 -10
  44. package/lib/json/to-csn.js +228 -47
  45. package/lib/language/antlrParser.js +11 -0
  46. package/lib/language/errorStrategy.js +26 -8
  47. package/lib/language/genericAntlrParser.js +73 -14
  48. package/lib/language/language.g4 +79 -3
  49. package/lib/main.d.ts +215 -18
  50. package/lib/main.js +3 -1
  51. package/lib/model/api.js +2 -2
  52. package/lib/model/csnRefs.js +117 -33
  53. package/lib/model/csnUtils.js +65 -133
  54. package/lib/model/enrichCsn.js +62 -37
  55. package/lib/model/revealInternalProperties.js +25 -8
  56. package/lib/model/sortViews.js +8 -1
  57. package/lib/modelCompare/compare.js +2 -1
  58. package/lib/optionProcessor.js +33 -18
  59. package/lib/render/.eslintrc.json +1 -2
  60. package/lib/render/DuplicateChecker.js +1 -1
  61. package/lib/render/toCdl.js +15 -8
  62. package/lib/render/toHdbcds.js +26 -49
  63. package/lib/render/toSql.js +61 -39
  64. package/lib/render/utils/common.js +1 -1
  65. package/lib/transform/db/applyTransformations.js +189 -0
  66. package/lib/transform/db/constraints.js +273 -119
  67. package/lib/transform/db/draft.js +3 -2
  68. package/lib/transform/db/expansion.js +6 -4
  69. package/lib/transform/db/flattening.js +19 -3
  70. package/lib/transform/db/transformExists.js +102 -9
  71. package/lib/transform/db/views.js +485 -0
  72. package/lib/transform/forHanaNew.js +93 -448
  73. package/lib/transform/forOdataNew.js +9 -2
  74. package/lib/transform/localized.js +2 -0
  75. package/lib/transform/odata/structuralPath.js +1 -5
  76. package/lib/transform/transformUtilsNew.js +22 -8
  77. package/lib/transform/translateAssocsToJoins.js +7 -15
  78. package/lib/utils/file.js +11 -5
  79. package/lib/utils/term.js +65 -42
  80. package/lib/utils/timetrace.js +48 -26
  81. package/package.json +1 -1
  82. package/lib/transform/db/helpers.js +0 -58
@@ -1,5 +1,17 @@
1
1
  // Main XSN-based compiler functions
2
2
 
3
+ // ...
4
+
5
+ // How functions are shared across the Core Compiler sub modules:
6
+
7
+ // - Shared XSN-related functions which do not use a context are in utils.js,
8
+ // they are `require`d as usual at the beginning of sub modules.
9
+ // - The XSN is the only context which context-dependent functions can depend on.
10
+ // - Sharing such a function is by adding it to `‹xsn›.$functions`,
11
+ // e.g. `resolvePath` and similar will be attached to the XSN.
12
+ // - Functions which might be overwritten in a next sub module
13
+ // are added to `‹xsn›.$volatileFunctions`, currently just `environment`.
14
+
3
15
  'use strict';
4
16
 
5
17
  const { resolveModule, resolveModuleSync } = require('../utils/moduleResolve');
@@ -8,12 +20,12 @@ const parseCsn = require('../json/from-csn');
8
20
 
9
21
  const assertConsistency = require('./assert-consistency');
10
22
  const moduleLayers = require('./moduleLayers');
23
+ const { fns } = require('./shared');
11
24
  const { define } = require('./definer');
12
25
  const resolve = require('./resolver');
13
26
  const propagator = require('./propagator');
14
27
  const check = require('./checks');
15
28
 
16
-
17
29
  const { emptyWeakLocation } = require('../base/location');
18
30
  const { createMessageFunctions, deduplicateMessages } = require('../base/messages');
19
31
  const { promiseAllDoNotRejectImmediately } = require('../base/node-helpers');
@@ -110,7 +122,6 @@ function compileX( filenames, dir = '', options = {}, fileCache = Object.create(
110
122
  // fileCache = Object.assign( Object.create(null), fileCache );
111
123
  dir = path.resolve(dir);
112
124
  const a = processFilenames( filenames, dir );
113
- a.fileContentDict = Object.create(null);
114
125
 
115
126
  const model = { sources: a.sources, options };
116
127
  model.$messageFunctions = createMessageFunctions( options, 'compile', model );
@@ -132,37 +143,25 @@ function compileX( filenames, dir = '', options = {}, fileCache = Object.create(
132
143
  });
133
144
 
134
145
  // Read file `filename` and parse its content, return messages
135
- function readAndParse( filename ) {
146
+ async function readAndParse( filename ) {
147
+ const { sources } = a;
136
148
  if ( filename === false ) // module which has not been found
137
149
  return [];
138
- const rel = a.sources[filename] || path.relative( dir, filename );
150
+ const rel = sources[filename] || path.relative( dir, filename );
139
151
  if (typeof rel === 'object') // already parsed
140
152
  return []; // no further dependency processing
141
153
  // no parallel readAndParse with same resolved filename should read the file,
142
- // also ensure deterministic sequence in a.sources:
143
- a.sources[filename] = { location: { file: rel } };
154
+ // also ensure deterministic sequence in sources:
155
+ sources[filename] = { location: { file: rel } };
144
156
 
145
- return new Promise( (fulfill, reject) => {
146
- cdsFs( fileCache, options.traceFs ).readFile( filename, 'utf8', (err, source) => {
147
- if (err) {
148
- reject(err);
149
- }
150
- else {
151
- try {
152
- a.fileContentDict[filename] = source;
153
- const ast = parseX( source, rel, options, model.$messageFunctions );
154
- a.sources[filename] = ast;
155
- ast.location = { file: rel };
156
- ast.dirname = path.dirname( filename );
157
- assertConsistency( ast, options );
158
- fulfill( ast );
159
- }
160
- catch (e) {
161
- reject( e );
162
- }
163
- }
164
- });
165
- });
157
+ const source = await cdsFs( fileCache, options.traceFs ).readFileAsync( filename, 'utf8' );
158
+ const ast = parseX( source, rel, options, model.$messageFunctions );
159
+ sources[filename] = ast;
160
+ ast.location = { file: rel };
161
+ ast.dirname = path.dirname( filename );
162
+ assertConsistency( ast, options );
163
+
164
+ return ast;
166
165
  }
167
166
 
168
167
  // Combine the parse results (if there are not file IO errors)
@@ -220,7 +219,6 @@ function compileSyncX( filenames, dir = '', options = {}, fileCache = Object.cre
220
219
  // absolute file names - they start with `/` or `\` or similar
221
220
  dir = path.resolve(dir);
222
221
  const a = processFilenames( filenames, dir );
223
- a.fileContentDict = Object.create(null);
224
222
 
225
223
  const model = { sources: a.sources, options };
226
224
  model.$messageFunctions = createMessageFunctions( options, 'compile', model );
@@ -281,7 +279,6 @@ function compileSyncX( filenames, dir = '', options = {}, fileCache = Object.cre
281
279
  }
282
280
  else {
283
281
  try {
284
- a.fileContentDict[filename] = source;
285
282
  const ast = parseX( source, rel, options, model.$messageFunctions );
286
283
  a.sources[filename] = ast;
287
284
  ast.location = { file: rel };
@@ -416,6 +413,9 @@ function compileDoX( model ) {
416
413
  throwWithError();
417
414
  return model;
418
415
  }
416
+ model.$functions = {};
417
+ model.$volatileFunctions = {};
418
+ fns( model ); // attach (mostly) paths functions
419
419
  define( model );
420
420
  // do not run the resolver in parse-cdl mode or we get duplicate annotations, etc.
421
421
  // TODO: do not use this function for parseCdl anyway…
@@ -8,7 +8,7 @@ const {
8
8
  setProp,
9
9
  isDeprecatedEnabled,
10
10
  } = require( '../base/model');
11
- const { linkToOrigin, withAssociation } = require('./shared');
11
+ const { linkToOrigin, withAssociation } = require('./utils');
12
12
  // const { refString } = require( '../base/messages')
13
13
 
14
14
  function propagate( model ) {
@@ -179,6 +179,8 @@ function propagate( model ) {
179
179
  // accessed at their type being a main artifact
180
180
  function expensive( prop, target, source ) {
181
181
  // console.log(prop,source.name,'->',target.kind,target.name);
182
+ if (source.kind === 'builtin')
183
+ return;
182
184
  if (prop !== 'foreignKeys' && availableAtType( prop, target, source ))
183
185
  // foreignKeys must always be copied with target to avoid any confusion
184
186
  // whether we have to generated implicit keys
@@ -211,7 +213,8 @@ function propagate( model ) {
211
213
  }
212
214
 
213
215
  function onlyViaParent( prop, target, source ) {
214
- if (target.$inferred === 'proxy') // assocs and enums do not have 'include'
216
+ if (target.$inferred === 'proxy' || target.$inferred === 'expand-element')
217
+ // assocs and enums do not have 'include'
215
218
  always( prop, target, source );
216
219
  }
217
220