@sap/cds-compiler 2.15.2 → 3.0.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 (111) hide show
  1. package/CHANGELOG.md +66 -1590
  2. package/bin/cdsc.js +42 -46
  3. package/doc/CHANGELOG_ARCHIVE.md +1592 -0
  4. package/doc/CHANGELOG_BETA.md +3 -4
  5. package/doc/CHANGELOG_DEPRECATED.md +35 -1
  6. package/doc/{DeprecatedOptions.md → DeprecatedOptions_v2.md} +3 -1
  7. package/doc/Versioning.md +20 -1
  8. package/lib/api/.eslintrc.json +2 -2
  9. package/lib/api/main.js +312 -143
  10. package/lib/api/options.js +15 -85
  11. package/lib/api/validate.js +6 -10
  12. package/lib/base/keywords.js +280 -110
  13. package/lib/base/message-registry.js +80 -24
  14. package/lib/base/messages.js +103 -52
  15. package/lib/base/model.js +44 -2
  16. package/lib/base/optionProcessorHelper.js +53 -21
  17. package/lib/checks/actionsFunctions.js +7 -5
  18. package/lib/checks/annotationsOData.js +1 -1
  19. package/lib/checks/cdsPersistence.js +1 -0
  20. package/lib/checks/elements.js +6 -6
  21. package/lib/checks/invalidTarget.js +1 -1
  22. package/lib/checks/nonexpandableStructured.js +1 -1
  23. package/lib/checks/queryNoDbArtifacts.js +2 -1
  24. package/lib/checks/selectItems.js +5 -1
  25. package/lib/checks/types.js +4 -2
  26. package/lib/checks/utils.js +2 -2
  27. package/lib/checks/validator.js +2 -1
  28. package/lib/compiler/assert-consistency.js +15 -10
  29. package/lib/compiler/builtins.js +127 -10
  30. package/lib/compiler/define.js +6 -4
  31. package/lib/compiler/extend.js +63 -12
  32. package/lib/compiler/finalize-parse-cdl.js +20 -9
  33. package/lib/compiler/index.js +25 -11
  34. package/lib/compiler/moduleLayers.js +7 -0
  35. package/lib/compiler/populate.js +16 -14
  36. package/lib/compiler/propagator.js +3 -3
  37. package/lib/compiler/resolve.js +194 -222
  38. package/lib/compiler/shared.js +56 -76
  39. package/lib/compiler/tweak-assocs.js +9 -10
  40. package/lib/compiler/utils.js +7 -2
  41. package/lib/edm/annotations/genericTranslation.js +60 -6
  42. package/lib/edm/annotations/preprocessAnnotations.js +10 -11
  43. package/lib/edm/csn2edm.js +39 -41
  44. package/lib/edm/edm.js +22 -15
  45. package/lib/edm/edmPreprocessor.js +66 -69
  46. package/lib/edm/edmUtils.js +12 -62
  47. package/lib/gen/Dictionary.json +8 -6
  48. package/lib/gen/language.checksum +1 -1
  49. package/lib/gen/language.interp +8 -30
  50. package/lib/gen/language.tokens +105 -114
  51. package/lib/gen/languageLexer.interp +1 -34
  52. package/lib/gen/languageLexer.js +889 -1007
  53. package/lib/gen/languageLexer.tokens +95 -106
  54. package/lib/gen/languageParser.js +20717 -22376
  55. package/lib/json/from-csn.js +73 -68
  56. package/lib/json/to-csn.js +13 -10
  57. package/lib/language/antlrParser.js +2 -2
  58. package/lib/language/docCommentParser.js +61 -38
  59. package/lib/language/errorStrategy.js +52 -40
  60. package/lib/language/genericAntlrParser.js +333 -259
  61. package/lib/language/language.g4 +600 -645
  62. package/lib/language/multiLineStringParser.js +14 -42
  63. package/lib/language/textUtils.js +44 -0
  64. package/lib/main.d.ts +27 -42
  65. package/lib/main.js +104 -81
  66. package/lib/model/csnRefs.js +2 -1
  67. package/lib/model/csnUtils.js +183 -285
  68. package/lib/model/revealInternalProperties.js +32 -9
  69. package/lib/model/sortViews.js +32 -31
  70. package/lib/optionProcessor.js +64 -57
  71. package/lib/render/.eslintrc.json +1 -1
  72. package/lib/render/DuplicateChecker.js +4 -7
  73. package/lib/render/manageConstraints.js +70 -2
  74. package/lib/render/toCdl.js +334 -339
  75. package/lib/render/toHdbcds.js +20 -16
  76. package/lib/render/toRename.js +44 -22
  77. package/lib/render/toSql.js +60 -54
  78. package/lib/render/utils/common.js +15 -1
  79. package/lib/render/utils/sql.js +20 -19
  80. package/lib/sql-identifier.js +6 -0
  81. package/lib/transform/db/.eslintrc.json +3 -2
  82. package/lib/transform/db/cdsPersistence.js +5 -15
  83. package/lib/transform/db/constraints.js +1 -1
  84. package/lib/transform/db/expansion.js +7 -6
  85. package/lib/transform/db/flattening.js +18 -19
  86. package/lib/transform/db/views.js +3 -3
  87. package/lib/transform/draft/.eslintrc.json +2 -2
  88. package/lib/transform/draft/db.js +6 -6
  89. package/lib/transform/draft/odata.js +6 -7
  90. package/lib/transform/forHanaNew.js +19 -22
  91. package/lib/transform/forOdataNew.js +13 -15
  92. package/lib/transform/localized.js +35 -25
  93. package/lib/transform/odata/toFinalBaseType.js +11 -9
  94. package/lib/transform/odata/typesExposure.js +3 -3
  95. package/lib/transform/odata/utils.js +1 -38
  96. package/lib/transform/transformUtilsNew.js +63 -77
  97. package/lib/transform/translateAssocsToJoins.js +6 -2
  98. package/lib/transform/universalCsn/.eslintrc.json +2 -2
  99. package/lib/transform/universalCsn/coreComputed.js +11 -6
  100. package/lib/transform/universalCsn/universalCsnEnricher.js +33 -5
  101. package/lib/utils/file.js +31 -21
  102. package/lib/utils/timetrace.js +20 -21
  103. package/package.json +34 -4
  104. package/share/messages/syntax-expected-integer.md +9 -8
  105. package/doc/ApiMigration.md +0 -237
  106. package/doc/CommandLineMigration.md +0 -58
  107. package/doc/ErrorMessages.md +0 -175
  108. package/doc/FioriAnnotations.md +0 -94
  109. package/doc/ODataTransformation.md +0 -273
  110. package/lib/backends.js +0 -529
  111. package/lib/fix_antlr4-8_warning.js +0 -56
@@ -7,8 +7,8 @@
7
7
 
8
8
  const { searchName, weakLocation } = require('../base/messages');
9
9
  const {
10
- isDeprecatedEnabled, isBetaEnabled,
11
- forEachGeneric, forEachInOrder,
10
+ isDeprecatedEnabled,
11
+ forEachGeneric, forEachInOrder, forEachDefinition,
12
12
  } = require('../base/model');
13
13
  const { dictAdd } = require('../base/dictionaries');
14
14
  const { kindProperties, dictKinds } = require('./base');
@@ -47,15 +47,16 @@ function extend( model ) {
47
47
 
48
48
  applyExtensions();
49
49
 
50
- const commonLanguagesEntity // TODO: remove beta after a grace period
51
- = (options.addTextsLanguageAssoc || isBetaEnabled( options, 'addTextsLanguageAssoc' )) &&
52
- model.definitions['sap.common.Languages'];
50
+ const commonLanguagesEntity = options.addTextsLanguageAssoc &&
51
+ model.definitions['sap.common.Languages'];
53
52
  const addTextsLanguageAssoc = !!(commonLanguagesEntity && commonLanguagesEntity.elements &&
54
53
  commonLanguagesEntity.elements.code);
55
54
  Object.keys( model.definitions ).forEach( processArtifact );
56
55
 
57
56
  lateExtensions( false );
58
57
 
58
+ compositionChildPersistence();
59
+
59
60
  /**
60
61
  * Process "composition of" artifacts.
61
62
  *
@@ -88,6 +89,25 @@ function extend( model ) {
88
89
  }
89
90
  }
90
91
 
92
+ /**
93
+ * Copy `@cds.persistence.skip` and `@cds.persistence.skip` from parent to child
94
+ * for managed compositions. This needs to be done after extensions, i.e. annotations,
95
+ * have been applied or `annotate E.comp` would not have an effect on `E.comp.subComp`.
96
+ */
97
+ function compositionChildPersistence() {
98
+ const processed = new WeakSet();
99
+ forEachDefinition(model, processCompositionPersistence);
100
+
101
+ function processCompositionPersistence(def) {
102
+ if (def.$inferred === 'composition-entity' && !processed.has(def)) {
103
+ if (def._parent)
104
+ processCompositionPersistence(def._parent);
105
+ copyPersistenceAnnotations(def, def._parent, options);
106
+ processed.add(def);
107
+ }
108
+ }
109
+ }
110
+
91
111
  // extend ------------------------------------------------------------------
92
112
 
93
113
  /**
@@ -369,7 +389,10 @@ function extend( model ) {
369
389
  for (const ext of exts) {
370
390
  delete ext.name.path[0]._artifact; // get message for root
371
391
  // TODO: make resolvePath('extend'/'annotate') ignore namespaces
372
- if (resolvePath( ext.name, ext.kind, ext )) { // should issue error/info
392
+ // Don't try to apply annotations in the `localized.` namespace.
393
+ // That's done in `localized.js`.
394
+ if (!name.startsWith('localized.') &&
395
+ resolvePath( ext.name, ext.kind, ext )) { // should issue error/info
373
396
  // should issue error for cds extensions (annotate ok)
374
397
  if (art.kind === 'namespace') {
375
398
  info( 'anno-namespace', [ ext.name.location, ext ], {},
@@ -492,7 +515,7 @@ function extend( model ) {
492
515
  const fioriAnno = art['@fiori.draft.enabled'];
493
516
  const fioriEnabled = fioriAnno && (fioriAnno.val === undefined || fioriAnno.val);
494
517
 
495
- const textsName = (isDeprecatedEnabled( options, 'generatedEntityNameWithUnderscore' ))
518
+ const textsName = (isDeprecatedEnabled( options, '_generatedEntityNameWithUnderscore' ))
496
519
  ? `${ art.name.absolute }_texts`
497
520
  : `${ art.name.absolute }.texts`;
498
521
  const textsEntity = model.definitions[textsName];
@@ -501,8 +524,9 @@ function extend( model ) {
501
524
  return;
502
525
  if (textsEntity) // expanded localized data in source
503
526
  return; // -> make it idempotent
504
- createTextsEntity( art, textsName, localized, fioriEnabled );
527
+ const newTextsEntity = createTextsEntity( art, textsName, localized, fioriEnabled );
505
528
  addTextsAssociations( art, textsName, localized );
529
+ copyPersistenceAnnotations(newTextsEntity, art, options);
506
530
  }
507
531
 
508
532
  /**
@@ -636,7 +660,7 @@ function extend( model ) {
636
660
  };
637
661
  dictAdd( art.elements, 'ID_texts', textId );
638
662
  }
639
- if (isDeprecatedEnabled( options, 'generatedEntityNameWithUnderscore' ))
663
+ if (isDeprecatedEnabled( options, '_generatedEntityNameWithUnderscore' ))
640
664
  setLink( art, '_base', base );
641
665
 
642
666
  dictAdd( art.elements, 'locale', locale );
@@ -695,6 +719,8 @@ function extend( model ) {
695
719
  }
696
720
  if (fioriEnabled)
697
721
  annotateWith( art, '@assert.unique.locale', art.location, assertUniqueValue, 'array' );
722
+
723
+ return art;
698
724
  }
699
725
 
700
726
  /**
@@ -808,7 +834,7 @@ function extend( model ) {
808
834
  target = resolvePath( origin.targetAspect, 'compositionTarget', origin );
809
835
  if (!target || !target.elements)
810
836
  return;
811
- const entityName = (isDeprecatedEnabled( options, 'generatedEntityNameWithUnderscore' ))
837
+ const entityName = (isDeprecatedEnabled( options, '_generatedEntityNameWithUnderscore' ))
812
838
  ? `${ base.name.absolute }_${ elem.name.id }`
813
839
  : `${ base.name.absolute }.${ elem.name.id }`;
814
840
  const entity = allowAspectComposition( target, elem, keys, entityName ) &&
@@ -931,7 +957,7 @@ function extend( model ) {
931
957
  // By default, 'up_' is a managed primary key association.
932
958
  // If 'up_' shall be rendered unmanaged, infer the parent
933
959
  // primary keys and add the ON condition
934
- if (isDeprecatedEnabled( options, 'unmanagedUpInComponent' )) {
960
+ if (isDeprecatedEnabled( options, '_unmanagedUpInComponent' )) {
935
961
  addProxyElements( art, keys, 'aspect-composition', target.name && location,
936
962
  'up__', '@odata.containment.ignore' );
937
963
  up.on = augmentEqual( location, 'up_', Object.values( keys ), 'up__' );
@@ -942,7 +968,7 @@ function extend( model ) {
942
968
  // even if target cardinality is 1..1
943
969
  up.notNull = { location, val: true };
944
970
  }
945
- if (isDeprecatedEnabled( options, 'generatedEntityNameWithUnderscore' ))
971
+ if (isDeprecatedEnabled( options, '_generatedEntityNameWithUnderscore' ))
946
972
  setLink( art, '_base', base._base || base );
947
973
 
948
974
  dictAdd( art.elements, 'up_', up);
@@ -951,6 +977,10 @@ function extend( model ) {
951
977
  setLink( art, '_block', model.$internal );
952
978
  model.definitions[entityName] = art;
953
979
  initArtifact( art );
980
+
981
+ // Copy persistence annotations from aspect.
982
+ copyPersistenceAnnotations(art, target, options);
983
+
954
984
  return art;
955
985
  }
956
986
 
@@ -972,6 +1002,27 @@ function extend( model ) {
972
1002
  }
973
1003
  }
974
1004
 
1005
+ /**
1006
+ * Copy the annotations `@cds.persistence.skip`/`@cds.persistence.exists` from
1007
+ * source to target if present on source but not target.
1008
+ *
1009
+ * @param {object} target
1010
+ * @param {object} source
1011
+ * @param {CSN.Options} options
1012
+ */
1013
+ function copyPersistenceAnnotations(target, source, options) {
1014
+ if (!source)
1015
+ return;
1016
+ // Copy @cds.persistence.skip/exists annotation.
1017
+ const noCopyExists = isDeprecatedEnabled( options, 'eagerPersistenceForGeneratedEntities' );
1018
+ const existsAnno = '@cds.persistence.exists';
1019
+ const skipAnno = '@cds.persistence.skip';
1020
+ if (!noCopyExists && source[existsAnno] && !target[existsAnno])
1021
+ target[existsAnno] = source[existsAnno];
1022
+ if (source[skipAnno] && !target[skipAnno])
1023
+ target[skipAnno] = source[skipAnno];
1024
+ }
1025
+
975
1026
  function augmentEqual( location, assocname, relations, prefix = '' ) {
976
1027
  const args = relations.map( eq );
977
1028
  return (args.length === 1)
@@ -2,6 +2,7 @@
2
2
 
3
3
  'use strict';
4
4
 
5
+ const { dictAddArray } = require('../base/dictionaries');
5
6
  const { forEachGeneric, forEachMember } = require('../base/model');
6
7
  const { setLink, setArtifactLink } = require('./utils');
7
8
 
@@ -33,7 +34,7 @@ function finalizeParseCdl( model ) {
33
34
  for (const ext of extensionsDict[name]) {
34
35
  ext.name.absolute = resolveUncheckedPath( ext.name, 'extend', ext );
35
36
  // Define annotations of this top-level extension
36
- defineAnnotations( ext, ext, ext._block );
37
+ defineAnnotations( ext, ext, ext._block, 'extend' );
37
38
  mergeAnnotatesForSameArtifact( ext );
38
39
  // Initialize members and define annotations in sub-elements.
39
40
  initMembers( ext, ext, ext._block, true );
@@ -221,17 +222,27 @@ function finalizeParseCdl( model ) {
221
222
 
222
223
  forEachMember(ext, sub => mergeAnnotatesForSameArtifact(sub));
223
224
 
224
- if (ext.$annotations && Array.isArray(ext.$duplicates)) {
225
- const annotates = ext.$duplicates.filter(val => (val.kind === 'annotate'));
226
- for (const dup of annotates) {
227
- ext.$annotations.push(...dup.$annotations);
228
- delete dup.$annotations;
225
+ // do not do a complex merge:
226
+ if (isComplexExtension( ext ) ||
227
+ !Array.isArray( ext.$duplicates ) || ext.$duplicates.some( isComplexExtension ))
228
+ return;
229
+ for (const dup of ext.$duplicates) {
230
+ for (const prop in dup) {
231
+ if (prop.charAt(0) === '@')
232
+ dictAddArray( ext, prop, dup[prop] );
229
233
  }
230
- ext.$duplicates = ext.$duplicates.filter(val => (val.kind !== 'annotate'));
231
- if (ext.$duplicates.length === 0)
232
- delete ext.$duplicates;
233
234
  }
235
+ delete ext.$duplicates;
234
236
  }
235
237
  }
236
238
 
239
+ /**
240
+ * We only de-duplicate an extend/annotate `ext` in function
241
+ * mergeAnnotatesForSameArtifact() if the extend/annotate is simple, i.e. has
242
+ * no members like elements.
243
+ */
244
+ function isComplexExtension( ext ) {
245
+ return ext.kind !== 'annotate' || ext.elements || ext.parameters || ext.actions;
246
+ }
247
+
237
248
  module.exports = finalizeParseCdl;
@@ -33,6 +33,7 @@ const check = require('./checks');
33
33
 
34
34
  const { emptyWeakLocation } = require('../base/location');
35
35
  const { createMessageFunctions, deduplicateMessages } = require('../base/messages');
36
+ const { checkRemovedDeprecatedFlags } = require('../base/model');
36
37
  const { promiseAllDoNotRejectImmediately } = require('../base/node-helpers');
37
38
  const { cdsFs } = require('../utils/file');
38
39
 
@@ -224,6 +225,7 @@ function compileX( filenames, dir = '', options = {}, fileCache = Object.create(
224
225
  * @param {string} [dir=""] Base directory. All files are resolved relatively
225
226
  * to this directory
226
227
  * @param {object} [options={}] Compilation options.
228
+ * @param {object} [fileCache]
227
229
  * @returns {XSN.Model} Augmented CSN
228
230
  */
229
231
  function compileSyncX( filenames, dir = '', options = {}, fileCache = Object.create(null) ) {
@@ -235,7 +237,7 @@ function compileSyncX( filenames, dir = '', options = {}, fileCache = Object.cre
235
237
  const model = { sources: a.sources, options };
236
238
  model.$messageFunctions = createMessageFunctions( options, 'compile', model );
237
239
 
238
- let asts = [];
240
+ const asts = [];
239
241
  const errors = [];
240
242
  a.files.forEach( val => readAndParseSync( val, (err, ast) => {
241
243
  if (err)
@@ -253,17 +255,16 @@ function compileSyncX( filenames, dir = '', options = {}, fileCache = Object.cre
253
255
  if (!options.parseOnly && !options.parseCdl) {
254
256
  while (asts.length) {
255
257
  const fileNames = readDependenciesSync( asts );
256
- asts = [];
257
- // TODO: check the following eslint error
258
- // eslint-disable-next-line no-loop-func
259
- fileNames.forEach( (fileName) => {
258
+ asts.length = 0;
259
+ // Push dependencies to `ast`. Only works because readAndParseSync() is synchronous.
260
+ for (const fileName of fileNames) {
260
261
  readAndParseSync(fileName, ( err, ast ) => {
261
262
  if (err)
262
263
  throw err;
263
264
  if (ast)
264
265
  asts.push( ast );
265
266
  });
266
- } );
267
+ }
267
268
  }
268
269
  }
269
270
 
@@ -378,6 +379,15 @@ function compileSourcesX( sourcesDict, options = {} ) {
378
379
  ast.location = { file: filename };
379
380
  assertConsistency( ast, options );
380
381
  }
382
+
383
+ for (const dep of sources[filename].dependencies || []) {
384
+ if (!dep.realname) {
385
+ // `realname` is used by setLayers(). For compileSources(), we don't resolve
386
+ // the USING paths and use the literal instead, which may be part of the
387
+ // source dictionary.
388
+ dep.realname = dep.val;
389
+ }
390
+ }
381
391
  }
382
392
  moduleLayers.setLayers( sources );
383
393
 
@@ -391,14 +401,15 @@ function compileSourcesX( sourcesDict, options = {} ) {
391
401
  * @param {object} options Options
392
402
  * @returns {object} XSN
393
403
  *
394
- * TODO: probaby issue message api-recompiled-csn there.
404
+ * TODO: probably issue message api-recompiled-csn there.
395
405
  */
396
406
  function recompileX( csn, options ) {
397
- options = { ...options, parseCdl: false, $recompile: true };
398
- // TODO: $recompile: true should be enough
399
407
  // Explicitly set parseCdl to false because backends cannot handle it
400
- // Explicitly delete all toCsn options:
408
+ options = { ...options, parseCdl: false, $recompile: true };
409
+ // Reset csnFlavor: Use client style (default)
410
+ delete options.csnFlavor;
401
411
  delete options.toCsn;
412
+ // TODO: $recompile: true should be enough
402
413
 
403
414
  const file = csn.$location && csn.$location.file &&
404
415
  csn.$location.file.replace(/[.]cds$/, '.cds.csn') || '<recompile>.csn';
@@ -428,6 +439,9 @@ function compileDoX( model ) {
428
439
  const { throwWithError } = model.$messageFunctions;
429
440
  if (!options.testMode)
430
441
  model.meta = {}; // provide initial central meta object
442
+
443
+ checkRemovedDeprecatedFlags( options, model.$messageFunctions );
444
+
431
445
  if (options.parseOnly) {
432
446
  throwWithError();
433
447
  return model;
@@ -500,7 +514,7 @@ function processFilenamesSync( filenames, dir ) {
500
514
  // Resolve possible symbolic link; if the file does not exist
501
515
  // we just continue using the original name because readFile()
502
516
  // already handles non-existent files.
503
- name = fs.realpathSync(name);
517
+ name = fs.realpathSync.native(name);
504
518
  }
505
519
  catch (e) {
506
520
  // Ignore the not-found (ENOENT) error
@@ -53,6 +53,12 @@ function layer( art ) {
53
53
  return art && art._layerRepresentative;
54
54
  }
55
55
 
56
+ function realname( art ) {
57
+ while (art && art.kind !== 'source')
58
+ art = art._block;
59
+ return art && art.realname || '';
60
+ }
61
+
56
62
  function compareLayer( a, b ) {
57
63
  while (a && a.kind !== 'source')
58
64
  a = a._block;
@@ -64,5 +70,6 @@ function compareLayer( a, b ) {
64
70
  module.exports = {
65
71
  setLayers,
66
72
  layer,
73
+ realname,
67
74
  compareLayer,
68
75
  };
@@ -74,21 +74,21 @@ function populate( model ) {
74
74
  let newAutoExposed = [];
75
75
 
76
76
  // behavior depending on option `deprecated`:
77
- const enableExpandElements = !isDeprecatedEnabled( options, 'noElementsExpansion' );
77
+ const enableExpandElements = !isDeprecatedEnabled( options, '_noElementsExpansion' );
78
78
  // TODO: we should get rid of noElementsExpansion soon; both
79
79
  // beta.nestedProjections and beta.universalCsn do not work with it.
80
80
  const scopedRedirections
81
81
  = enableExpandElements &&
82
- !isDeprecatedEnabled( options, 'generatedEntityNameWithUnderscore' ) &&
83
- !isDeprecatedEnabled( options, 'shortAutoexposed' ) &&
84
- !isDeprecatedEnabled( options, 'longAutoexposed' ) &&
85
- !isDeprecatedEnabled( options, 'noInheritedAutoexposeViaComposition' ) &&
86
- !isDeprecatedEnabled( options, 'noScopedRedirections' );
82
+ !isDeprecatedEnabled( options, '_generatedEntityNameWithUnderscore' ) &&
83
+ !isDeprecatedEnabled( options, '_shortAutoexposed' ) &&
84
+ !isDeprecatedEnabled( options, '_longAutoexposed' ) &&
85
+ !isDeprecatedEnabled( options, '_noInheritedAutoexposeViaComposition' ) &&
86
+ !isDeprecatedEnabled( options, '_noScopedRedirections' );
87
87
  const autoexposeViaComposition
88
- = (isDeprecatedEnabled( options, 'noInheritedAutoexposeViaComposition' ))
88
+ = (isDeprecatedEnabled( options, '_noInheritedAutoexposeViaComposition' ))
89
89
  ? 'Composition'
90
90
  : true;
91
- const redirectInSubQueries = isDeprecatedEnabled( options, 'redirectInSubQueries' );
91
+ const redirectInSubQueries = isDeprecatedEnabled( options, '_redirectInSubQueries' );
92
92
 
93
93
  forEachDefinition( model, traverseElementEnvironments );
94
94
  while (newAutoExposed.length) {
@@ -246,7 +246,9 @@ function populate( model ) {
246
246
  let struct = user;
247
247
  while (struct.kind === 'element')
248
248
  struct = struct._parent;
249
- if (struct.kind === 'select') {
249
+ if (struct.kind === 'select' || struct.kind === 'annotation') {
250
+ // `type of` in annotation definitions can't work, because csn type refs
251
+ // always refer to definitions.
250
252
  message( 'type-unexpected-typeof', [ ref.location, user ],
251
253
  { keyword: 'type of', '#': struct.kind } );
252
254
  // we actually refer to an element in _combined; TODO: return null if
@@ -1094,7 +1096,7 @@ function populate( model ) {
1094
1096
  return false;
1095
1097
  }
1096
1098
  // no @cds.autoexpose or @cds.autoexpose:null
1097
- // TODO: introduce deprecated.noInheritedAutoexposeViaComposition
1099
+ // TODO: introduce deprecated._noInheritedAutoexposeViaComposition
1098
1100
  art.$autoexpose = model.$compositionTargets[art.name.absolute]
1099
1101
  ? autoexposeViaComposition
1100
1102
  : null;
@@ -1103,15 +1105,15 @@ function populate( model ) {
1103
1105
 
1104
1106
  function autoExposedName( target, service, elemScope ) {
1105
1107
  const { absolute } = target.name;
1106
- if (isDeprecatedEnabled( options, 'shortAutoexposed' )) {
1108
+ if (isDeprecatedEnabled( options, '_shortAutoexposed' )) {
1107
1109
  const parent = definitionScope( target )._parent;
1108
1110
  const name = (parent) ? absolute.substring( parent.name.absolute.length + 1 ) : absolute;
1109
- // no need for dedot here (as opposed to deprecated.longAutoexposed), as
1111
+ // no need for dedot here (as opposed to deprecated._longAutoexposed), as
1110
1112
  // the name for dependent entities have already been created using `_` then
1111
1113
  return `${ service.name.absolute }.${ name }`;
1112
1114
  }
1113
- if (isDeprecatedEnabled( options, 'longAutoexposed' )) {
1114
- const dedot = isDeprecatedEnabled( options, 'generatedEntityNameWithUnderscore' );
1115
+ if (isDeprecatedEnabled( options, '_longAutoexposed' )) {
1116
+ const dedot = isDeprecatedEnabled( options, '_generatedEntityNameWithUnderscore' );
1115
1117
  return `${ service.name.absolute }.${ dedot ? absolute.replace( /\./g, '_' ) : absolute }`;
1116
1118
  }
1117
1119
  const base = definitionScope( target );
@@ -56,9 +56,9 @@ function propagate( model ) {
56
56
  returns,
57
57
  };
58
58
  const { options } = model;
59
- const enableExpandElements = !isDeprecatedEnabled( options, 'noElementsExpansion' );
59
+ const enableExpandElements = !isDeprecatedEnabled( options, '_noElementsExpansion' );
60
60
  // eslint-disable-next-line max-len
61
- const oldVirtualNotNullPropagation = isDeprecatedEnabled( options, 'oldVirtualNotNullPropagation' );
61
+ const oldVirtualNotNullPropagation = isDeprecatedEnabled( options, '_oldVirtualNotNullPropagation' );
62
62
 
63
63
  forEachDefinition( model, run );
64
64
 
@@ -189,7 +189,7 @@ function propagate( model ) {
189
189
  if (!type || type._main)
190
190
  return false;
191
191
  // We do not consider the $expand status, as elements are already expanded
192
- // by the resolve(), and if not due to deprecated.noElementsExpansion
192
+ // by the resolve(), and if not due to deprecated._noElementsExpansion
193
193
  run( type );
194
194
  return type[prop];
195
195
  }