@sap/cds-compiler 6.7.3 → 6.9.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 (116) hide show
  1. package/CHANGELOG.md +70 -0
  2. package/README.md +4 -0
  3. package/bin/cdsc.js +5 -5
  4. package/bin/cdshi.js +1 -0
  5. package/bin/cdsse.js +1 -1
  6. package/lib/api/main.js +17 -9
  7. package/lib/api/options.js +5 -2
  8. package/lib/api/validate.js +1 -1
  9. package/lib/base/builtins.js +13 -9
  10. package/lib/{model → base}/csnRefs.js +8 -10
  11. package/lib/base/error.js +2 -0
  12. package/lib/base/message-registry.js +68 -4
  13. package/lib/base/messages.js +4 -2
  14. package/lib/{optionProcessor.js → base/optionProcessor.js} +5 -3
  15. package/lib/base/{model.js → specialOptions.js} +16 -39
  16. package/lib/checks/arrayOfs.js +1 -1
  17. package/lib/checks/elements.js +1 -1
  18. package/lib/checks/enricher.js +2 -2
  19. package/lib/checks/featureFlags.js +54 -24
  20. package/lib/checks/foreignKeys.js +1 -1
  21. package/lib/checks/invalidTarget.js +1 -1
  22. package/lib/checks/managedInType.js +1 -1
  23. package/lib/checks/onConditions.js +1 -1
  24. package/lib/checks/queryNoDbArtifacts.js +1 -1
  25. package/lib/checks/validator.js +10 -14
  26. package/lib/compiler/assert-consistency.js +11 -9
  27. package/lib/compiler/base.js +5 -1
  28. package/lib/compiler/builtins.js +1 -1
  29. package/lib/compiler/checks.js +3 -3
  30. package/lib/compiler/define.js +6 -3
  31. package/lib/{base → compiler}/dictionaries.js +4 -3
  32. package/lib/compiler/extend.js +121 -21
  33. package/lib/compiler/generate.js +2 -2
  34. package/lib/compiler/index.js +11 -3
  35. package/lib/compiler/kick-start.js +1 -1
  36. package/lib/compiler/lsp-api.js +3 -3
  37. package/lib/compiler/populate.js +6 -7
  38. package/lib/compiler/resolve.js +53 -36
  39. package/lib/compiler/shared.js +68 -18
  40. package/lib/compiler/tweak-assocs.js +2 -2
  41. package/lib/compiler/utils.js +28 -27
  42. package/lib/compiler/xpr-rewrite.js +3 -3
  43. package/lib/edm/EdmPrimitiveTypeDefinitions.js +4 -1
  44. package/lib/edm/annotations/edmJson.js +2 -4
  45. package/lib/edm/annotations/genericTranslation.js +51 -7
  46. package/lib/edm/csn2edm.js +3 -2
  47. package/lib/edm/edmAnnoPreprocessor.js +1 -1
  48. package/lib/edm/edmInboundChecks.js +2 -1
  49. package/lib/edm/edmPreprocessor.js +3 -3
  50. package/lib/edm/edmUtils.js +2 -2
  51. package/lib/gen/BaseParser.js +59 -108
  52. package/lib/gen/CdlGrammar.checksum +1 -1
  53. package/lib/gen/CdlParser.js +2052 -1965
  54. package/lib/gen/Dictionary.json +67 -7
  55. package/lib/json/from-csn.js +14 -14
  56. package/lib/json/to-csn.js +77 -38
  57. package/lib/main.js +3 -3
  58. package/lib/model/csnUtils.js +2 -2
  59. package/lib/modelCompare/compare.js +1 -1
  60. package/lib/modelCompare/utils/filter.js +1 -0
  61. package/lib/parsers/AstBuildingParser.js +83 -33
  62. package/lib/parsers/index.js +1 -1
  63. package/lib/render/manageConstraints.js +1 -1
  64. package/lib/render/toCdl.js +49 -30
  65. package/lib/render/toHdbcds.js +2 -2
  66. package/lib/render/toSql.js +16 -7
  67. package/lib/render/utils/common.js +11 -3
  68. package/lib/render/utils/sql.js +14 -5
  69. package/lib/render/utils/standardDatabaseFunctions.js +108 -99
  70. package/lib/sql-identifier.js +9 -1
  71. package/lib/{model → tool-lib}/enrichCsn.js +3 -2
  72. package/lib/{model → tool-lib}/revealInternalProperties.js +2 -1
  73. package/lib/transform/addTenantFields.js +1 -1
  74. package/lib/transform/db/applyTransformations.js +1 -1
  75. package/lib/transform/db/assertUnique.js +1 -1
  76. package/lib/transform/db/assocsToQueries/transformExists.js +1 -1
  77. package/lib/transform/db/backlinks.js +2 -2
  78. package/lib/transform/db/expansion.js +2 -2
  79. package/lib/transform/db/flattening.js +3 -4
  80. package/lib/transform/db/killAnnotations.js +1 -0
  81. package/lib/transform/db/processSqlServices.js +2 -1
  82. package/lib/transform/db/rewriteCalculatedElements.js +2 -2
  83. package/lib/transform/db/temporal.js +30 -5
  84. package/lib/transform/db/views.js +16 -20
  85. package/lib/transform/draft/db.js +1 -2
  86. package/lib/transform/effective/associations.js +1 -1
  87. package/lib/transform/effective/flattening.js +6 -5
  88. package/lib/transform/effective/main.js +24 -4
  89. package/lib/transform/effective/types.js +1 -1
  90. package/lib/transform/{odata/fioriTreeViews.js → fioriTreeViews.js} +48 -25
  91. package/lib/transform/forOdata.js +25 -7
  92. package/lib/transform/forRelationalDB.js +48 -12
  93. package/lib/transform/localized.js +2 -2
  94. package/lib/transform/odata/createForeignKeys.js +1 -1
  95. package/lib/transform/odata/flattening.js +2 -2
  96. package/lib/transform/odata/toFinalBaseType.js +3 -2
  97. package/lib/transform/odata/typesExposure.js +3 -2
  98. package/lib/transform/transformUtils.js +2 -2
  99. package/lib/transform/translateAssocsToJoins.js +2 -1
  100. package/lib/transform/tupleExpansion.js +44 -4
  101. package/lib/transform/universalCsn/universalCsnEnricher.js +7 -3
  102. package/lib/transform/universalCsn/utils.js +1 -1
  103. package/lib/{base → utils}/lazyload.js +9 -0
  104. package/lib/{base → utils}/node-helpers.js +2 -0
  105. package/lib/utils/objectUtils.js +29 -6
  106. package/lib/{base → utils}/optionProcessorHelper.js +16 -6
  107. package/package.json +3 -40
  108. /package/lib/{model → base}/cloneCsn.js +0 -0
  109. /package/lib/{model/api.js → base/model-api.js} +0 -0
  110. /package/lib/{api → base}/trace.js +0 -0
  111. /package/lib/{model → base}/xprAsTree.js +0 -0
  112. /package/lib/{inspect → tool-lib}/index.js +0 -0
  113. /package/lib/{inspect → tool-lib}/inspectModelStatistics.js +0 -0
  114. /package/lib/{inspect → tool-lib}/inspectPropagation.js +0 -0
  115. /package/lib/{inspect → tool-lib}/inspectUtils.js +0 -0
  116. /package/lib/{base → utils}/shuffle.js +0 -0
@@ -1,4 +1,4 @@
1
- //Base class for generated parser, for redepage v0.3.2
1
+ // Base class for generated parser, for redepage v0.4.0
2
2
 
3
3
  'use strict';
4
4
 
@@ -24,7 +24,6 @@ recoverTokenIdx = -1;
24
24
  reuseErrorTokenIdx = null;
25
25
  fixKeywordTokenIdx = -1;
26
26
  conditionStackLength = -1;
27
- nextTokenAsId = false;
28
27
 
29
28
  s = null;
30
29
  errorState = null;
@@ -32,7 +31,7 @@ stack = [];
32
31
  dynamic_ = {};
33
32
  prec_ = null;
34
33
  $hasErrors = null;
35
- leanConditions = {};
34
+ hardGuards = {};
36
35
  _trace = [];
37
36
 
38
37
  constructor( lexer, keywords, table ) {
@@ -103,22 +102,30 @@ return this.tokens[this.stack[this.stack.length - 1].tokenIdx];
103
102
 
104
103
 
105
104
 
106
- l() {
105
+ lt() {
107
106
  return this.la().type;
108
107
  }
109
108
 
110
109
 
111
110
  lk() {
112
111
  const la = this.la();
113
- if (!this.nextTokenAsId)
114
112
  return la.keyword || la.type;
113
+ }
115
114
 
116
- this.nextTokenAsId = false;
117
- return la.type;
115
+ l() {
116
+ let cmd = this.table[this.s];
117
+ let { keyword, type } = this.la();
118
+ const kb = keyword && cmd[keyword];
119
+ if (Array.isArray( kb ) &&
120
+ (!kb[2] || this.fixKeywordTokenIdx === this.tokenIdx || this._predictKeyword( kb[2] )))
121
+ return (kb[3] && this._rejectCond( kb[3], kb[4] )) ? '' : keyword;
122
+ const tb = cmd[type];
123
+ return (!tb || tb[3] && this._rejectCond( tb[3], tb[4] )) ? '' : type;
118
124
  }
119
125
 
120
126
  e() {
121
127
  const la = this.la();
128
+ this.s = null;
122
129
 
123
130
  if (this.errorTokenIdx === this.tokenIdx &&
124
131
  (this.reuseErrorTokenIdx == null && this.reuseErrorTokenIdx < this.tokenIdx))
@@ -140,21 +147,11 @@ return false;
140
147
  }
141
148
 
142
149
 
143
- ei() {
144
- if (!this.la().keyword)
145
- return this.e();
146
- this.nextTokenAsId = true;
147
- return false;
148
- }
149
-
150
-
151
150
 
152
151
 
153
152
  gr( follow ) {
154
- if (this.stack[this.stack.length - 1].tokenIdx === this.tokenIdx)
155
-
156
- return this.e();
157
- this.s = 0;
153
+ if (!this.g( 0 ))
154
+ return false;
158
155
 
159
156
 
160
157
  const { type, keyword } = this.tokens[this.tokenIdx];
@@ -172,35 +169,11 @@ return (match ?? true) || this.e();
172
169
  }
173
170
 
174
171
 
175
- g( state, follow ) {
176
- if (!(state == null ? this.e() : state || this.gr( follow )))
177
- return false;
172
+ g( state ) {
178
173
  this.s = state;
179
- return true
180
- }
181
-
182
-
183
- giA( state, follow ) {
184
- if (!this.tokens[this.tokenIdx].keyword)
185
- return this.g( state, follow );
186
- this.nextTokenAsId = true;
187
- return false;
188
- }
189
-
190
-
191
- gi( state, follow ) {
192
- const lk = this.tokens[this.tokenIdx].keyword;
193
-
194
-
195
- if (!lk || this.keywords[lk])
196
- return this.g( state, follow );
197
- this.nextTokenAsId = true;
198
- return false;
199
- }
200
-
201
-
202
- gP( state, follow ) {
203
- return this.lP( follow ) && this.g( state );
174
+ return (state || this.stack[this.stack.length - 1].tokenIdx < this.tokenIdx)
175
+ ? true
176
+ : this.e();
204
177
  }
205
178
 
206
179
 
@@ -219,9 +192,9 @@ return (this.tokens[this.tokenIdx].type === 'Id')
219
192
  }
220
193
 
221
194
 
222
- miA( state, ident = true ) {
195
+ my( state, ident = true ) {
223
196
  return (this.tokens[this.tokenIdx].type === 'Id')
224
- ? this.ciA( state, ident )
197
+ ? this.cy( state, ident )
225
198
  : this.e();
226
199
  }
227
200
 
@@ -247,7 +220,7 @@ return this.e();
247
220
  const la = this.tokens[this.tokenIdx];
248
221
 
249
222
 
250
- if (this.keywords[la.keyword]) {
223
+ if (this.keywords[la.keyword] && this.errorTokenIdx !== this.tokenIdx) {
251
224
 
252
225
  if (this._runTransparently( () => {
253
226
  ++this.tokenIdx;
@@ -264,7 +237,7 @@ return this.c( state, ident )
264
237
  }
265
238
 
266
239
 
267
- ciA( state, ident = 'ident' ) {
240
+ cy( state, ident = 'ident' ) {
268
241
  return this.c( state, ident )
269
242
  }
270
243
 
@@ -274,12 +247,7 @@ return this.c( state, 'keyword' )
274
247
  }
275
248
 
276
249
 
277
- ckP( state, first2 ) {
278
- return this.lP( first2 ) && this.ck( state );
279
- }
280
-
281
-
282
- ckA( state ) {
250
+ cx( state ) {
283
251
 
284
252
  return this.c( state, (this.l() === 'Id' ? 'keyword' : 'token') );
285
253
  }
@@ -295,15 +263,11 @@ reuseToken_() {
295
263
 
296
264
 
297
265
 
298
-
299
-
300
-
301
-
302
- gc( state, cond, arg ) {
266
+ _rejectCond( cond, arg ) {
303
267
  if (this.conditionTokenIdx === this.tokenIdx &&
304
268
  this.conditionStackLength == null &&
305
269
  !this[cond].afterError)
306
- return true
270
+ return false
307
271
 
308
272
 
309
273
 
@@ -314,7 +278,8 @@ const fail = this[cond]( arg, true );
314
278
 
315
279
 
316
280
 
317
- if (fail) {
281
+ if (!fail)
282
+ return false;
318
283
 
319
284
 
320
285
 
@@ -326,17 +291,13 @@ const { keyword } = this.la();
326
291
  if (keyword && this.table[this.s][keyword])
327
292
  this.fixKeywordTokenIdx = this.tokenIdx;
328
293
  this.conditionTokenIdx = this.tokenIdx;
294
+
329
295
  this.conditionStackLength = this.stack.length;
330
296
  this.conditionName = cond;
331
297
 
332
298
 
333
299
  this.conditionFailure = fail;
334
- }
335
- return !fail || this.g( state ) && false;
336
- }
337
-
338
- ec( cond, arg ) {
339
- return this.gc( null, cond, arg );
300
+ return true;
340
301
  }
341
302
 
342
303
 
@@ -370,18 +331,7 @@ throw Error( `this.s === ${ this.s }; illegally set by action, or runtime/genera
370
331
  this.dynamic_ = Object.getPrototypeOf( this.dynamic_ );
371
332
  const caller = this.stack.pop();
372
333
  const immediately = this.tokenIdx === caller.tokenIdx && this.tokenIdx >= this.errorTokenIdx;
373
- if (this.constructor.tracingParser) {
374
- const post = this.s == null &&
375
- (immediately
376
- ? ' immediately'
377
- : caller.followState == null
378
- ? ' unsuccessfully'
379
- : ' prematurely');
380
- const text = immediately ? '⚠ exit rule' : '⏎ exit rule';
381
- this.s = caller.followState;
382
-
383
334
 
384
- }
385
335
  this.prec_ = caller.prec;
386
336
  this.s = caller.followState;
387
337
  if (immediately)
@@ -393,13 +343,10 @@ return true;
393
343
  }
394
344
 
395
345
 
346
+ _predictKeyword( first2 ) {
396
347
 
397
-
398
-
399
- lP( first2 ) {
400
-
401
- const { keyword: lk1 } = this.tokens[this.tokenIdx];
402
- if (!lk1 || this.keywords[lk1] !== 0 || this.fixKeywordTokenIdx === this.tokenIdx)
348
+ const { keyword: lk1 } = this.la();
349
+ if (this.keywords[lk1] !== 0)
403
350
  return true;
404
351
 
405
352
 
@@ -415,10 +362,7 @@ if (this._walkPred( this.table[this.s][lk1], lk1, lt2, lk2 ))
415
362
  return true;
416
363
 
417
364
  const choice = this.table[this.s];
418
- if (!this._walkPred( choice.Id || choice[''], null, lt2, lk2 ))
419
- return true;
420
- this.nextTokenAsId = true;
421
- return false;
365
+ return !this._walkPred( choice.Id || choice[''], null, lt2, lk2 );
422
366
  }
423
367
 
424
368
  _walkPred( cmd, lk1, lt2, lk2 ) {
@@ -494,9 +438,9 @@ cmd = !(c && this._rejectCondition( c, mode, lean )) && c || cmd[''];
494
438
  const state = this.s;
495
439
  this.s = cmd[1];
496
440
  switch (cmd[0]) {
497
- case 'c': case 'ck': case 'ckA':
441
+ case 'c': case 'ck': case 'cx':
498
442
  return true;
499
- case 'ciA':
443
+ case 'cy':
500
444
  return mode !== 'F';
501
445
 
502
446
 
@@ -505,6 +449,8 @@ case 'ci':
505
449
  if (!keyword ||
506
450
  !this.keywords[keyword] && this.fixKeywordTokenIdx !== this.tokenIdx)
507
451
  return mode !== 'F';
452
+
453
+
508
454
  cmd = this.table[state][''];
509
455
  this.s = cmd[1];
510
456
  break;
@@ -514,7 +460,7 @@ case 'mi':
514
460
  return type === 'Id' && mode !== 'F' &&
515
461
  (!keyword ||
516
462
  !this.keywords[keyword] && this.fixKeywordTokenIdx !== this.tokenIdx);
517
- case 'miA':
463
+ case 'my':
518
464
  return type === 'Id' && mode !== 'F';
519
465
  case 'mk':
520
466
  return keyword === cmd[2];
@@ -564,7 +510,7 @@ return (hasMatchedToken ?? this.tokenIdx > this.stack.at( -1 ).tokenIdx)
564
510
 
565
511
  _rejectCondition( cmd, mode, lean ) {
566
512
  const cond = cmd[3];
567
- if (!cond || lean && !this.leanConditions[cond])
513
+ if (!cond || lean && !this.hardGuards[cond])
568
514
  return false;
569
515
  if (!this.constructor.tracingParser)
570
516
  return !!this[cond]( cmd[4], mode );
@@ -591,9 +537,6 @@ this.s = this.stack[depth].followState;
591
537
 
592
538
  match = this._pred_next( type, keyword, mode );
593
539
 
594
-
595
-
596
-
597
540
  }
598
541
  this.dynamic_ = dynamic_;
599
542
  this.s = savedState;
@@ -671,12 +614,16 @@ cmd ??= this.table[this.s];
671
614
  if (!Array.isArray( cmd )) {
672
615
  const lookahead = cmd[' lookahead'];
673
616
  const dict = cmd;
617
+ cmd = dict[''];
674
618
  for (const prop in dict) {
675
619
  if (prop && Object.hasOwn( dict, prop ) && prop !== 'Id' &&
676
- !Object.hasOwn( expecting, prop ) && prop.charAt(0) !== ' ')
620
+ !Object.hasOwn( expecting, prop ) && prop.charAt(0) !== ' ') {
621
+
622
+ const ad = dict[prop];
623
+ if (ad[1] !== cmd[1] || ad[0] !== 'g')
677
624
  this.addTokenToSet_( expecting, prop, val, collectKeywordsAndIdOnly, lookahead );
678
625
  }
679
- cmd = dict[''];
626
+ }
680
627
  if (dict.Id) {
681
628
 
682
629
  if (cmd[0] === 'e') {
@@ -695,13 +642,13 @@ switch (cmd[0]) {
695
642
  case 'm': case 'mk':
696
643
  this.addTokenToSet_( expecting, cmd[2], val, collectKeywordsAndIdOnly );
697
644
  break loop;
698
- case 'ci': case 'ciA': case 'mi': case 'miA':
645
+ case 'ci': case 'cy': case 'mi': case 'my':
699
646
  this.addTokenToSet_( expecting, 'Id', val, false );
700
647
 
701
648
 
702
649
 
703
650
  break loop;
704
- case 'g': case 'gi': case 'e':
651
+ case 'g': case 'e':
705
652
  break;
706
653
  default:
707
654
  if (typeof cmd[0] !== 'number')
@@ -925,17 +872,21 @@ return table;
925
872
  for (const line of table) {
926
873
  if (typeof line !== 'object' || Array.isArray( line ))
927
874
  continue;
928
- const cache = Object.create( null );
929
- for (const prop of Object.keys( line )) {
930
- const alt = line[prop];
931
- if (!Array.isArray( alt ) && prop.charAt(0) !== ' ')
932
- line[prop] = (typeof alt === 'string') ? line[alt] : (cache[alt] ??= [ 'g', alt ]);
933
- }
875
+ for (const prop of Object.keys( line ))
876
+ compileTableItem( line, prop );
934
877
  if (!line[''])
935
878
  line[''] = [ 'e' ];
936
879
  }
937
880
  table.$compiled = true;
938
881
  return table;
939
882
  }
883
+ function compileTableItem( line, prop ) {
884
+ const alt = line[prop];
885
+ if (typeof alt === 'number')
886
+ return line[prop] = [ 'g', alt ];
887
+ else if (typeof alt === 'string' && prop.charAt(0) !== ' ')
888
+ return line[prop] = compileTableItem( line, alt );
889
+ return alt;
890
+ }
940
891
  BaseParser.prototype.isNoKeywordInRuleFollow.afterError = true;
941
892
  module.exports = BaseParser;
@@ -1 +1 @@
1
- f0320d5264a6107c245a82427b4f6338
1
+ 43e8ba55fd2a4f645dcbc0928d83528b