@sap/cds-compiler 4.7.6 → 4.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 (129) hide show
  1. package/CHANGELOG.md +63 -3
  2. package/bin/cds_remove_invalid_whitespace.js +135 -0
  3. package/bin/cds_update_annotations.js +180 -0
  4. package/bin/cds_update_identifiers.js +3 -4
  5. package/bin/cdsc.js +28 -1
  6. package/bin/cdshi.js +13 -3
  7. package/doc/CHANGELOG_BETA.md +24 -1
  8. package/lib/api/main.js +119 -46
  9. package/lib/api/options.js +51 -0
  10. package/lib/api/validate.js +1 -5
  11. package/lib/base/builtins.js +116 -0
  12. package/lib/base/keywords.js +5 -1
  13. package/lib/base/location.js +91 -14
  14. package/lib/base/message-registry.js +76 -46
  15. package/lib/base/messages.js +121 -35
  16. package/lib/base/model.js +4 -7
  17. package/lib/checks/actionsFunctions.js +3 -3
  18. package/lib/checks/annotationsOData.js +3 -0
  19. package/lib/checks/defaultValues.js +5 -2
  20. package/lib/checks/elements.js +2 -1
  21. package/lib/checks/enricher.js +2 -2
  22. package/lib/checks/queryNoDbArtifacts.js +5 -3
  23. package/lib/checks/utils.js +1 -1
  24. package/lib/checks/validator.js +8 -56
  25. package/lib/compiler/assert-consistency.js +11 -7
  26. package/lib/compiler/builtins.js +0 -74
  27. package/lib/compiler/checks.js +105 -29
  28. package/lib/compiler/define.js +37 -25
  29. package/lib/compiler/extend.js +35 -12
  30. package/lib/compiler/index.js +9 -10
  31. package/lib/compiler/lsp-api.js +5 -0
  32. package/lib/compiler/populate.js +13 -5
  33. package/lib/compiler/propagator.js +24 -18
  34. package/lib/compiler/resolve.js +47 -45
  35. package/lib/compiler/shared.js +61 -21
  36. package/lib/compiler/tweak-assocs.js +15 -90
  37. package/lib/compiler/utils.js +3 -3
  38. package/lib/compiler/xpr-rewrite.js +689 -0
  39. package/lib/compiler/{classes.js → xsn-model.js} +0 -16
  40. package/lib/edm/annotations/edmJson.js +7 -5
  41. package/lib/edm/annotations/genericTranslation.js +149 -71
  42. package/lib/edm/csn2edm.js +25 -9
  43. package/lib/edm/edm.js +7 -7
  44. package/lib/edm/edmInboundChecks.js +57 -5
  45. package/lib/edm/edmPreprocessor.js +54 -25
  46. package/lib/edm/edmUtils.js +3 -16
  47. package/lib/gen/Dictionary.json +138 -14
  48. package/lib/gen/language.checksum +1 -1
  49. package/lib/gen/language.interp +1 -1
  50. package/lib/gen/languageParser.js +2085 -1989
  51. package/lib/json/csnVersion.js +7 -4
  52. package/lib/json/from-csn.js +21 -11
  53. package/lib/json/to-csn.js +8 -4
  54. package/lib/language/antlrParser.js +1 -1
  55. package/lib/language/genericAntlrParser.js +23 -16
  56. package/lib/language/multiLineStringParser.js +2 -2
  57. package/lib/language/textUtils.js +1 -1
  58. package/lib/main.d.ts +90 -14
  59. package/lib/main.js +9 -1
  60. package/lib/model/cloneCsn.js +21 -9
  61. package/lib/model/csnRefs.js +153 -42
  62. package/lib/model/csnUtils.js +14 -11
  63. package/lib/model/enrichCsn.js +4 -2
  64. package/lib/model/revealInternalProperties.js +2 -1
  65. package/lib/model/sortViews.js +14 -6
  66. package/lib/modelCompare/compare.js +135 -122
  67. package/lib/optionProcessor.js +49 -2
  68. package/lib/render/DuplicateChecker.js +6 -6
  69. package/lib/render/manageConstraints.js +1 -0
  70. package/lib/render/toCdl.js +6 -3
  71. package/lib/render/toHdbcds.js +4 -48
  72. package/lib/render/toSql.js +6 -3
  73. package/lib/transform/addTenantFields.js +58 -35
  74. package/lib/transform/db/applyTransformations.js +34 -1
  75. package/lib/transform/db/constraints.js +1 -1
  76. package/lib/transform/db/expansion.js +11 -3
  77. package/lib/transform/db/flattening.js +71 -46
  78. package/lib/transform/db/groupByOrderBy.js +2 -2
  79. package/lib/transform/db/temporal.js +6 -3
  80. package/lib/transform/db/transformExists.js +2 -2
  81. package/lib/transform/db/views.js +1 -4
  82. package/lib/transform/effective/annotations.js +194 -0
  83. package/lib/transform/effective/main.js +11 -10
  84. package/lib/transform/effective/misc.js +45 -14
  85. package/lib/transform/effective/types.js +4 -3
  86. package/lib/transform/forOdata.js +29 -12
  87. package/lib/transform/forRelationalDB.js +104 -113
  88. package/lib/transform/localized.js +7 -6
  89. package/lib/transform/odata/flattening.js +228 -107
  90. package/lib/transform/odata/toFinalBaseType.js +10 -26
  91. package/lib/transform/odata/typesExposure.js +41 -25
  92. package/lib/transform/parseExpr.js +4 -7
  93. package/lib/transform/transformUtils.js +50 -43
  94. package/lib/transform/translateAssocsToJoins.js +48 -48
  95. package/lib/transform/universalCsn/coreComputed.js +2 -1
  96. package/lib/transform/universalCsn/universalCsnEnricher.js +12 -16
  97. package/package.json +2 -2
  98. package/share/messages/README.md +4 -0
  99. package/share/messages/anno-duplicate-unrelated-layer.md +1 -1
  100. package/share/messages/anno-missing-rewrite.md +45 -0
  101. package/share/messages/check-proper-type-of.md +1 -1
  102. package/share/messages/def-duplicate-autoexposed.md +1 -1
  103. package/share/messages/extend-repeated-intralayer.md +3 -16
  104. package/share/messages/extend-unrelated-layer.md +1 -1
  105. package/share/messages/message-explanations.json +2 -0
  106. package/share/messages/redirected-to-ambiguous.md +1 -1
  107. package/share/messages/redirected-to-complex.md +1 -1
  108. package/share/messages/redirected-to-unrelated.md +1 -1
  109. package/share/messages/rewrite-not-supported.md +1 -1
  110. package/share/messages/syntax-expecting-unsigned-int.md +2 -2
  111. package/share/messages/type-missing-enum-value.md +59 -0
  112. package/share/messages/wildcard-excluding-one.md +1 -1
  113. package/bin/.eslintrc.json +0 -17
  114. package/lib/api/.eslintrc.json +0 -37
  115. package/lib/checks/.eslintrc.json +0 -31
  116. package/lib/compiler/.eslintrc.json +0 -8
  117. package/lib/edm/.eslintrc.json +0 -46
  118. package/lib/inspect/.eslintrc.json +0 -4
  119. package/lib/json/.eslintrc.json +0 -4
  120. package/lib/language/.eslintrc.json +0 -4
  121. package/lib/model/.eslintrc.json +0 -13
  122. package/lib/modelCompare/utils/.eslintrc.json +0 -22
  123. package/lib/render/.eslintrc.json +0 -22
  124. package/lib/transform/.eslintrc.json +0 -13
  125. package/lib/transform/db/.eslintrc.json +0 -41
  126. package/lib/transform/draft/.eslintrc.json +0 -4
  127. package/lib/transform/effective/.eslintrc.json +0 -4
  128. package/lib/transform/universalCsn/.eslintrc.json +0 -37
  129. package/lib/utils/.eslintrc.json +0 -7
@@ -171,15 +171,14 @@
171
171
  // hierarchy, query number, table aliases and links from a column to its
172
172
  // respective inferred element.
173
173
 
174
- // TODO: some `name` property would be useful (also set with `initDefinition`)
175
-
176
174
  // Properties in cache:
177
175
  //
178
176
  // - _effectiveType on def/member/items: cached result of effectiveType()
179
177
  // - _origin on def/member/items: the "prototype"
180
178
  // - $origin on def/member/items: whether implicit _origin refs have been set for direct members
181
179
  // - _parent: currently just use to allow ref to `up_` in anonymous aspect
182
- // for managed compositions
180
+ // for managed compositions;
181
+ // in queries always the main artifact (see `$next` for name resolution)
183
182
  // - _env on non-string path item: environment provided by the ref so far,
184
183
  // next path item is element in it
185
184
  // - _ref on non-string `type` or `from` ref, or on alias: the referred def/elem
@@ -193,10 +192,11 @@
193
192
 
194
193
  'use strict';
195
194
 
195
+
196
196
  const BUILTIN_TYPE = {};
197
- const { locationString } = require('../base/location');
197
+ const { SemanticLocation, locationString } = require('../base/location');
198
198
  const { ModelError, CompilerAssertion } = require('../base/error');
199
- const { isAnnotationExpression } = require('../compiler/builtins');
199
+ const { isAnnotationExpression } = require('../base/builtins');
200
200
 
201
201
  // Properties in which artifact or members are defined - next property in the
202
202
  // "csnPath" is the name or index of that property; 'args' (its value can be a
@@ -230,7 +230,8 @@ const referenceSemantics = {
230
230
  orderBy_ref: { lexical: query => query, dynamic: 'query' },
231
231
  orderBy_expr: { lexical: query => query, dynamic: 'source' }, // ref in ORDER BY expression
232
232
  orderBy_set_ref: { lexical: query => query.$next, dynamic: 'query' }, // to outer SELECT (from UNION)
233
- // refs in ORDER BY expr in UNION not really allowed - only with table alias (of outer queries) or $self
233
+ // refs in ORDER BY expr in UNION not really allowed
234
+ // only with table alias (of outer queries) or $self
234
235
  orderBy_set_expr: { lexical: query => query.$next, dynamic: false },
235
236
  // default: { lexical: query => query, dynamic: 'source' }
236
237
  };
@@ -244,11 +245,13 @@ function justDollar() {
244
245
  * @param {boolean|string} [universalReady]
245
246
  */
246
247
  function csnRefs( csn, universalReady ) {
248
+ // some users exchange the dict while using csn-refs !?! see test/testDraft.js
249
+ // const { definitions } = csn;
247
250
  const cache = new WeakMap();
248
251
  setCache( BUILTIN_TYPE, '_origin', null );
249
252
  if (universalReady === 'init-all') {
250
- for (const art of Object.values( csn.definitions || {}))
251
- initDefinition( art );
253
+ for (const name of Object.keys( csn.definitions || {}))
254
+ initDefinition( name );
252
255
  }
253
256
  // Functions which set the new `baseEnv`:
254
257
  resolveRef.expandInline = function resolveExpandInline( ref, ...args ) {
@@ -275,6 +278,7 @@ function csnRefs( csn, universalReady ) {
275
278
  initDefinition,
276
279
  dropDefinitionCache,
277
280
  targetAspect,
281
+ msgLocations,
278
282
  __getCache_forEnrichCsnDebugging: obj => cache.get( obj ),
279
283
  };
280
284
 
@@ -324,9 +328,7 @@ function csnRefs( csn, universalReady ) {
324
328
  const target = (staticAssoc ? targetAspect( env ) : env.target || env.targetAspect);
325
329
  if (typeof target !== 'string')
326
330
  return target || env;
327
- const def = csn.definitions[target];
328
- initDefinition( def );
329
- return def;
331
+ return initDefinition( target );
330
332
  }
331
333
 
332
334
  /**
@@ -342,18 +344,19 @@ function csnRefs( csn, universalReady ) {
342
344
  if (typeof ref === 'string') {
343
345
  const main = csn.definitions[ref];
344
346
  if (main)
345
- return initDefinition( main );
347
+ return initDefinition( ref );
348
+ // notFound only meant for builtins and $self
349
+ if (notFound !== undefined)
350
+ return notFound;
346
351
  }
347
352
  else {
348
353
  const art = cached( ref, '_ref', artifactPathRef );
349
354
  if (art)
350
355
  return art;
356
+ // Backend bug workaround, TODO: delete next 2 lines
357
+ if (notFound !== undefined)
358
+ return notFound;
351
359
  }
352
- if (notFound !== undefined && typeof ref === 'string')
353
- return notFound; // is only meant for builtins and $self
354
- // Backend bug workaround, TODO: delete next 2 lines
355
- if (notFound !== undefined)
356
- return notFound;
357
360
  throw new ModelError( `Unknown artifact reference: ${ typeof ref !== 'string' ? JSON.stringify(ref.ref) : ref }` );
358
361
  }
359
362
 
@@ -367,8 +370,7 @@ function csnRefs( csn, universalReady ) {
367
370
 
368
371
  function artifactPathRef( ref ) {
369
372
  const [ head, ...tail ] = ref.ref;
370
- let art = csn.definitions[pathId( head )];
371
- initDefinition( art );
373
+ let art = initDefinition( pathId( head ) );
372
374
  for (const elem of tail) {
373
375
  const env = navigationEnv( art );
374
376
  art = env.elements[pathId( elem )];
@@ -378,8 +380,7 @@ function csnRefs( csn, universalReady ) {
378
380
 
379
381
  function artifactFromRef( ref, noLast ) {
380
382
  const [ head, ...tail ] = ref.ref;
381
- let art = csn.definitions[pathId( head )];
382
- initDefinition( art );
383
+ let art = initDefinition( pathId( head ) );
383
384
  for (const elem of tail) {
384
385
  const env = navigationEnv( art );
385
386
  art = env.elements[pathId( elem )];
@@ -401,9 +402,7 @@ function csnRefs( csn, universalReady ) {
401
402
  const targetName = refCtx !== 'keys_origin' && art.target ||
402
403
  art.$origin && art.$origin.target ||
403
404
  art.cast.target;
404
- const target = csn.definitions[targetName];
405
- initDefinition( target );
406
- return target;
405
+ return initDefinition( targetName );
407
406
  }
408
407
 
409
408
  function getOrigin( art ) {
@@ -411,8 +410,11 @@ function csnRefs( csn, universalReady ) {
411
410
  }
412
411
 
413
412
  function getOriginRaw( art ) {
414
- if (art.type) // TODO: make robust against "linked" = only direct
415
- return artifactRef( art.type, BUILTIN_TYPE );
413
+ if (art.type) { // TODO: make robust against "linked" = only direct
414
+ return (art.type !== '$self' || csn.definitions.$self)
415
+ ? artifactRef( art.type, BUILTIN_TYPE )
416
+ : getCache( boundActionOrMain( art ), '_parent' );
417
+ }
416
418
  if (typeof art.$origin === 'object') // null, […], {…}
417
419
  return getOriginExplicit( art.$origin );
418
420
 
@@ -437,9 +439,8 @@ function csnRefs( csn, universalReady ) {
437
439
  if (!Array.isArray( $origin )) // anonymous prototype in $origin
438
440
  return getOriginExplicit( $origin.$origin );
439
441
  const [ head, ...tail ] = $origin;
440
- const main = csn.definitions[head];
441
442
  // if (!main) throw Error(JSON.stringify({$origin,csn}))
442
- initDefinition( main );
443
+ const main = initDefinition( head );
443
444
  return tail.reduce( originNavigation, main );
444
445
  }
445
446
 
@@ -483,8 +484,13 @@ function csnRefs( csn, universalReady ) {
483
484
  }
484
485
 
485
486
  function initDefinition( main ) {
487
+ const name = typeof main === 'string' && main;
488
+ if (name) {
489
+ main = csn.definitions[name];
490
+ setCache( main, '$name', name );
491
+ }
486
492
  // TODO: some --test-mode check that the argument is in ‹csn›.definitions ?
487
- if (getCache( main, '$queries' ) !== undefined) // already computed
493
+ if (!main || getCache( main, '$queries' ) !== undefined) // already computed
488
494
  return main;
489
495
  traverseDef( main, null, null, null, initNode );
490
496
  const queries = cached( main, '$queries', allQueries );
@@ -650,7 +656,7 @@ function csnRefs( csn, universalReady ) {
650
656
  const up = getCache( parent, '_parent' );
651
657
  const target = up && typeof up.target === 'string' && csn.definitions[up.target];
652
658
  if (target && target.elements) {
653
- initDefinition( target );
659
+ initDefinition( up.target );
654
660
  art = target.elements.up_;
655
661
  }
656
662
  }
@@ -696,7 +702,8 @@ function csnRefs( csn, universalReady ) {
696
702
  const links = path.map( (_v, idx) => ({ idx }) );
697
703
  // TODO: backends should be changed to enable uncommenting:
698
704
  // if (!art) // does not work with test3/Associations/KeylessManagedAssociation/
699
- // throw new ModelError( `Path item 0=${ pathId( path[0] ) } refers to nothing, scope: ${ scope }`);
705
+ // throw new ModelError( `Path item 0=${ pathId( path[0] )
706
+ // } refers to nothing, scope: ${ scope }`);
700
707
  links[0].art = art;
701
708
  for (let i = 1; i < links.length; ++i) { // yes, starting at 1, links[0] is set above
702
709
  parent = navigationEnv( art, staticAssoc );
@@ -734,6 +741,110 @@ function csnRefs( csn, universalReady ) {
734
741
  };
735
742
  }
736
743
 
744
+ /**
745
+ * Return [ Location, SemanticLocation ] from `csnPath`.
746
+ */
747
+ function msgLocations( csnPath ) {
748
+ let location = csn?.$location;
749
+ const artifact = new SemanticLocation();
750
+ let obj = csn;
751
+ let index = 0;
752
+ let inlinePathIndex = null;
753
+ if (typeof csnPath[0] === 'object')
754
+ startPath( csnPath[0] );
755
+
756
+ /* eslint-disable no-return-assign */
757
+ const pathFunctions = {
758
+ definitions: name => absolute( name, 'type' ),
759
+ vocabularies: name => absolute( name, 'annotation' ),
760
+ extensions,
761
+ projection,
762
+ SELECT: projection,
763
+ // TODO: alias
764
+ mixin: name => nameInProp( name, 'mixin' ),
765
+ actions: name => nameInProp( name, 'action' ),
766
+ params: name => nameInProp( name, 'param' ),
767
+ returns: () => (artifact.param = ''),
768
+ elements: name => elements( name, artifact.select == null ? null : 'element' ),
769
+ columns: elements,
770
+ expand: elements,
771
+ inline: elements,
772
+ keys: pos => elements( pos, 'key' ),
773
+ enum: name => elements( name, 'enum' ),
774
+ item: () => (artifact.innerKind = 'item'),
775
+ // targetAspect: () => (artifact.innerKind = 'aspect')
776
+ '@': suffix,
777
+ }; /* eslint-enable no-return-assign */
778
+
779
+ while (obj && index < csnPath.length) {
780
+ const step = csnPath[index++];
781
+ obj = obj[step];
782
+ const fn = pathFunctions[step] || pathFunctions[step.charAt( 0 )];
783
+ if (fn)
784
+ fn( csnPath[index] );
785
+ if (obj?.$location)
786
+ location = obj.$location;
787
+ }
788
+ return [ location, artifact ];
789
+
790
+ function startPath( art ) {
791
+ const parent = getCache( art, '_parent' );
792
+ if (parent) {
793
+ if (!art.SELECT && !art.projection)
794
+ throw new CompilerAssertion( 'CSN path starts with object other than def or query' );
795
+ }
796
+ obj = csn.definitions;
797
+ absolute( getCache( parent || art, '$name' ), 'type' );
798
+ obj = art;
799
+ location = art.$location || parent?.$location || csn.$location;
800
+ }
801
+
802
+ function absolute( name, defaultKind ) {
803
+ obj = obj[name];
804
+ artifact.mainKind = obj.kind || defaultKind;
805
+ artifact.absolute = name;
806
+ ++index;
807
+ }
808
+ function extensions( pos ) {
809
+ obj = obj[pos];
810
+ artifact.mainKind = obj.annotate ? 'annotate' : 'extend';
811
+ artifact.absolute = obj.annotate || obj.extend;
812
+ ++index;
813
+ }
814
+ function projection() {
815
+ let select = getCache( obj, '$queryNumber' );
816
+ if (select === 1) {
817
+ const parent = getCache( obj, '_parent' );
818
+ if (parent && getCache( parent, '$queries' )?.length === 1)
819
+ select = 0;
820
+ }
821
+ artifact.select = select;
822
+ }
823
+ function nameInProp( name, prop ) {
824
+ obj = obj[name];
825
+ artifact[prop] = name;
826
+ ++index;
827
+ }
828
+ function elements( name, kind ) {
829
+ obj = obj[name];
830
+ const elem = (typeof name === 'string') ? name : !obj.inline && columnAlias( obj );
831
+ if (obj.inline) { // inline
832
+ inlinePathIndex ??= artifact.element.length;
833
+ }
834
+ else if (inlinePathIndex != null) { // inline before: remove inline col indexes
835
+ if (elem)
836
+ artifact.element.length = inlinePathIndex;
837
+ inlinePathIndex = null;
838
+ }
839
+ artifact.element.push( elem || name + 1);
840
+ artifact.innerKind = kind || undefined;
841
+ ++index;
842
+ }
843
+ function suffix( prop ) {
844
+ artifact.suffix = prop;
845
+ obj = null; // stop
846
+ }
847
+ }
737
848
  /**
738
849
  * Get the array of all (sub-)queries (value of the `SELECT`/`projection`
739
850
  * property) inside the given `main` artifact (of `main.query`).
@@ -904,8 +1015,8 @@ function queryOrMain( query, main ) {
904
1015
  * - NOT on a `join` node inside `from`.
905
1016
  *
906
1017
  * @param {CSN.Query} query
907
- * @param {CSN.QuerySelect} fromSelect: for query in `from`
908
- * @param {CSN.Query} parentQuery: for a sub query (ex those in `from`)
1018
+ * @param {CSN.QuerySelect} fromSelect for query in `from`
1019
+ * @param {CSN.Query} parentQuery for a sub query (ex those in `from`)
909
1020
  * @param {(query: CSN.Query&CSN.QueryFrom, select: CSN.QuerySelectEnriched, parentQuery: CSN.Query) => void} callback
910
1021
  */
911
1022
  function traverseQuery( query, fromSelect, parentQuery, callback ) {
@@ -1021,16 +1132,18 @@ function implicitAs( ref ) {
1021
1132
  function startCsnPath( csnPath, csn ) {
1022
1133
  const head = csnPath[0];
1023
1134
  if (typeof head !== 'string') {
1024
- const { main, parent, art } = head;
1135
+ const {
1136
+ main, parent, art, query,
1137
+ } = head;
1025
1138
  return {
1026
- index: 1, main, parent, art,
1139
+ index: 1, main, parent, art, query,
1027
1140
  };
1028
1141
  }
1029
- if (csnPath.length < 2 || csnPath[0] !== 'definitions' && csnPath[0] !== 'vocabularies')
1030
- throw new CompilerAssertion( 'References outside definitions and vocabularies not supported yet');
1031
- const art = csn[csnPath[0]][csnPath[1]];
1142
+ if (csnPath.length < 2 || head !== 'definitions' && head !== 'vocabularies')
1143
+ throw new CompilerAssertion( 'References outside definitions and vocabularies not supported yet' );
1144
+ const art = csn[head][csnPath[1]];
1032
1145
  return {
1033
- index: 2, main: art, parent: art, art,
1146
+ index: 2, main: art, parent: art, art, query: null,
1034
1147
  };
1035
1148
  }
1036
1149
 
@@ -1041,8 +1154,6 @@ function startCsnPath( csnPath, csn ) {
1041
1154
  * @param {any} resolve
1042
1155
  */
1043
1156
  function analyseCsnPath( csnPath, csn, resolve ) {
1044
- /** @type {object} */
1045
- let query = null;
1046
1157
  /** @type {any} */
1047
1158
  let refCtx = null;
1048
1159
  /** @type {boolean|string|number} */
@@ -1051,7 +1162,7 @@ function analyseCsnPath( csnPath, csn, resolve ) {
1051
1162
  let baseCtx = null;
1052
1163
  let baseEnv = null;
1053
1164
  let {
1054
- index, main, parent, art,
1165
+ index, main, parent, art, query,
1055
1166
  } = startCsnPath( csnPath, csn );
1056
1167
  let obj = art;
1057
1168
 
@@ -6,8 +6,9 @@ const {
6
6
  applyTransformations,
7
7
  applyTransformationsOnNonDictionary,
8
8
  applyTransformationsOnDictionary,
9
+ mergeTransformers,
9
10
  } = require('../transform/db/applyTransformations');
10
- const { isBuiltinType, isMagicVariable, isAnnotationExpression } = require('../compiler/builtins.js');
11
+ const { isBuiltinType, isAnnotationExpression } = require('../base/builtins');
11
12
  const { ModelError, CompilerAssertion } = require('../base/error');
12
13
  const { typeParameters } = require('../compiler/builtins');
13
14
  const { forEach } = require('../utils/objectUtils');
@@ -134,7 +135,8 @@ function getUtils( model, universalReady ) {
134
135
  }
135
136
  else if (arg.ref) {
136
137
  const art = artifactRef.from(arg);
137
- elements = mergeElementsIntoMap(elements, art.elements, art.$location, arg.as || implicitAs(arg.ref), implicitAs(arg.ref) || arg.as);
138
+ elements = mergeElementsIntoMap(elements, art.elements, art.$location,
139
+ arg.as || implicitAs(arg.ref), implicitAs(arg.ref) || arg.as);
138
140
  }
139
141
  else if (arg.SELECT || arg.SET) {
140
142
  elements = mergeElementMaps(elements, getSources(arg, true));
@@ -670,11 +672,13 @@ function isEdmPropertyRendered( elementCsn, options ) {
670
672
  // V4 struct: on/off
671
673
  if (elementCsn == null)
672
674
  return false;
673
- const renderForeignKey = (options.odataVersion === 'v4' && options.odataFormat === 'structured') ? !!options.odataForeignKeys : true;
675
+ const renderForeignKey = (options.odataVersion === 'v4' && options.odataFormat === 'structured')
676
+ ? !!options.odataForeignKeys : true;
674
677
  const isNotIgnored = !elementCsn.target ? !elementCsn['@cds.api.ignore'] : true;
675
678
  const isNavigable = elementCsn.target
676
679
  ? (elementCsn['@odata.navigable'] === undefined ||
677
- elementCsn['@odata.navigable'] !== undefined && (elementCsn['@odata.navigable'] === null || elementCsn['@odata.navigable'] === true)) : true;
680
+ elementCsn['@odata.navigable'] !== undefined &&
681
+ (elementCsn['@odata.navigable'] === null || elementCsn['@odata.navigable'] === true)) : true;
678
682
  // Foreign Keys can be ignored
679
683
  if (elementCsn['@odata.foreignKey4'])
680
684
  return isNotIgnored && renderForeignKey;
@@ -1124,7 +1128,7 @@ function moveAnnotationsAndDoc( sourceNode, targetNode, overwrite = false ) {
1124
1128
  * override: Whether to ignore existing annotations.
1125
1129
  * filter: Positive filter. If it returns true, annotations for the referenced artifact
1126
1130
  * will be applied.
1127
- * applyToElements: Wether to apply annotations to elements or only to artifacts
1131
+ * applyToElements: Whether to apply annotations to elements or only to artifacts
1128
1132
  */
1129
1133
  function applyAnnotationsFromExtensions( csn, config ) {
1130
1134
  if (!csn.extensions)
@@ -1189,7 +1193,8 @@ function isAspect( node ) {
1189
1193
  */
1190
1194
  function hasValidSkipOrExists( artifact ) {
1191
1195
  return artifact.kind === 'entity' &&
1192
- (hasAnnotationValue(artifact, '@cds.persistence.exists', true) || hasAnnotationValue(artifact, '@cds.persistence.skip', true));
1196
+ (hasAnnotationValue(artifact, '@cds.persistence.exists', true) ||
1197
+ hasAnnotationValue(artifact, '@cds.persistence.skip', true));
1193
1198
  }
1194
1199
 
1195
1200
  /**
@@ -1368,7 +1373,8 @@ function functionList( functions, thisArg ) {
1368
1373
  * @returns {boolean}
1369
1374
  */
1370
1375
  function isDollarSelfOrProjectionOperand( arg ) {
1371
- return arg.ref && arg.ref.length === 1 && (arg.ref[0] === '$self' || arg.ref[0] === '$projection');
1376
+ return arg.ref && arg.ref.length === 1 &&
1377
+ (arg.ref[0] === '$self' || arg.ref[0] === '$projection');
1372
1378
  }
1373
1379
 
1374
1380
  /**
@@ -1408,15 +1414,11 @@ function findAnnotationExpression( node, prop ) {
1408
1414
  },
1409
1415
  });
1410
1416
  }
1411
-
1412
1417
  return isExpr;
1413
1418
  }
1414
1419
 
1415
1420
  module.exports = {
1416
1421
  getUtils,
1417
- isBuiltinType,
1418
- isMagicVariable,
1419
- isAnnotationExpression,
1420
1422
  applyAnnotationsFromExtensions,
1421
1423
  forEachGeneric,
1422
1424
  forEachDefinition,
@@ -1433,6 +1435,7 @@ module.exports = {
1433
1435
  applyTransformations,
1434
1436
  applyTransformationsOnNonDictionary,
1435
1437
  applyTransformationsOnDictionary,
1438
+ mergeTransformers,
1436
1439
  setDependencies,
1437
1440
  isPersistedOnDatabase,
1438
1441
  isPersistedAsView,
@@ -42,7 +42,7 @@
42
42
  const { csnRefs, artifactProperties } = require('./csnRefs');
43
43
  const { locationString } = require('../base/location');
44
44
  const { CompilerAssertion } = require('../base/error');
45
- const { isAnnotationExpression } = require('../compiler/builtins');
45
+ const { isAnnotationExpression } = require('../base/builtins');
46
46
  const shuffleGen = require('../base/shuffle');
47
47
 
48
48
  function enrichCsn( csn, options = {} ) {
@@ -207,7 +207,9 @@ function enrichCsn( csn, options = {} ) {
207
207
  }
208
208
 
209
209
  function pathRef( parent, prop, path, inspectionPath = csnPath ) {
210
- const inspection = handleError( err => ((err) ? { scope: err.toString() } : inspectRef( inspectionPath )));
210
+ const inspection = handleError( err => ((err)
211
+ ? { scope: err.toString() }
212
+ : inspectRef( inspectionPath )));
211
213
  const {
212
214
  links, art, scope, $env,
213
215
  } = inspection;
@@ -38,7 +38,8 @@ const kindsRepresentedAsLinks = {
38
38
  // represent table alias in from / join-args property as link:
39
39
  $tableAlias: tableAliasAsLink,
40
40
  // represent "navigation elements" in _combined as links:
41
- $navElement: (art, parent) => art._parent && parent !== art._parent.elements && art._parent.kind !== 'aspect',
41
+ $navElement: (art, parent) => art._parent && parent !== art._parent.elements &&
42
+ art._parent.kind !== 'aspect',
42
43
  // represent mixin in $tableAliases as link:
43
44
  mixin: tableAliasAsLink,
44
45
  // represent $projection as link, as it is just another search name for $self:
@@ -5,8 +5,11 @@ const { ModelError } = require('../base/error');
5
5
 
6
6
  /**
7
7
  * @typedef {Object} Layers
8
- * @property {Array[]} layers - An array of arrays, each subarray encompassing one Layer - L0 being layers[0].
9
- * @property {CSN.Artifact[]} leftover - Any artifacts not sorted into a layer due to unmet dependencies - points to there being some error.
8
+ * @property {Array[]} layers
9
+ * An array of arrays, each subarray encompassing one Layer - L0 being layers[0].
10
+ * @property {CSN.Artifact[]} leftover
11
+ * Any artifacts not sorted into a layer due to unmet dependencies.
12
+ * Points to there being some error.
10
13
  */
11
14
 
12
15
  /**
@@ -22,7 +25,8 @@ const { ModelError } = require('../base/error');
22
25
  */
23
26
  function sortTopologically( csn, _dependents, _dependencies ) {
24
27
  const layers = [];
25
- let { zero, nonZero } = _calculateDepth(Object.entries(csn.definitions), _dependents, _dependencies);
28
+ let { zero, nonZero } = _calculateDepth(Object.entries(csn.definitions),
29
+ _dependents, _dependencies);
26
30
  while (zero.length !== 0) {
27
31
  const currentLayer = [];
28
32
  zero.forEach(([ artifactName, artifact ]) => {
@@ -87,8 +91,10 @@ function _findWithXPointers( definitionsArray, x, _dependents, _dependencies ) {
87
91
  * For ordering, only the FROM clause of views is checked - this requires A2J to
88
92
  * be run beforehand to resolve association usages.
89
93
  *
90
- * @param {{sql: string, csn: CSN.Model}} arg sql: Map of <object name>: "CREATE STATEMENT", csn: Model
91
- * @returns {{name: string, sql: string}[]} Sorted array of artifact name / "CREATE STATEMENTS" pairs
94
+ * @param {{sql: string, csn: CSN.Model}} arg
95
+ * sql: Map of <object name>: "CREATE STATEMENT", csn: Model
96
+ * @returns {{name: string, sql: string}[]}
97
+ * Sorted array of artifact name / "CREATE STATEMENTS" pairs
92
98
  */
93
99
  module.exports = function sortViews({ sql, csn }) {
94
100
  const { cleanup, _dependents, _dependencies } = setDependencies(csn);
@@ -98,7 +104,9 @@ module.exports = function sortViews({ sql, csn }) {
98
104
 
99
105
  const result = [];
100
106
  // keep the "artifact name" - needed for to.hdi sorting
101
- layers.forEach(layer => layer.forEach(objName => result.push({ name: objName, sql: sql[objName], dependents: csn.definitions[objName][_dependents] })));
107
+ layers.forEach(layer => layer.forEach(objName => result.push({
108
+ name: objName, sql: sql[objName], dependents: csn.definitions[objName][_dependents],
109
+ })));
102
110
  // attach sql artifacts which are not considered during the view sorting algorithm
103
111
  // --> this is the case for "ALTER TABLE ADD CONSTRAINT" statements,
104
112
  // because their identifiers are not part of the csn.definitions