@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.
- package/CHANGELOG.md +66 -1590
- package/bin/cdsc.js +42 -46
- package/doc/CHANGELOG_ARCHIVE.md +1592 -0
- package/doc/CHANGELOG_BETA.md +3 -4
- package/doc/CHANGELOG_DEPRECATED.md +35 -1
- package/doc/{DeprecatedOptions.md → DeprecatedOptions_v2.md} +3 -1
- package/doc/Versioning.md +20 -1
- package/lib/api/.eslintrc.json +2 -2
- package/lib/api/main.js +312 -143
- package/lib/api/options.js +15 -85
- package/lib/api/validate.js +6 -10
- package/lib/base/keywords.js +280 -110
- package/lib/base/message-registry.js +80 -24
- package/lib/base/messages.js +103 -52
- package/lib/base/model.js +44 -2
- package/lib/base/optionProcessorHelper.js +53 -21
- package/lib/checks/actionsFunctions.js +7 -5
- package/lib/checks/annotationsOData.js +1 -1
- package/lib/checks/cdsPersistence.js +1 -0
- package/lib/checks/elements.js +6 -6
- package/lib/checks/invalidTarget.js +1 -1
- package/lib/checks/nonexpandableStructured.js +1 -1
- package/lib/checks/queryNoDbArtifacts.js +2 -1
- package/lib/checks/selectItems.js +5 -1
- package/lib/checks/types.js +4 -2
- package/lib/checks/utils.js +2 -2
- package/lib/checks/validator.js +2 -1
- package/lib/compiler/assert-consistency.js +15 -10
- package/lib/compiler/builtins.js +127 -10
- package/lib/compiler/define.js +6 -4
- package/lib/compiler/extend.js +63 -12
- package/lib/compiler/finalize-parse-cdl.js +20 -9
- package/lib/compiler/index.js +25 -11
- package/lib/compiler/moduleLayers.js +7 -0
- package/lib/compiler/populate.js +16 -14
- package/lib/compiler/propagator.js +3 -3
- package/lib/compiler/resolve.js +194 -222
- package/lib/compiler/shared.js +56 -76
- package/lib/compiler/tweak-assocs.js +9 -10
- package/lib/compiler/utils.js +7 -2
- package/lib/edm/annotations/genericTranslation.js +60 -6
- package/lib/edm/annotations/preprocessAnnotations.js +10 -11
- package/lib/edm/csn2edm.js +39 -41
- package/lib/edm/edm.js +22 -15
- package/lib/edm/edmPreprocessor.js +66 -69
- package/lib/edm/edmUtils.js +12 -62
- package/lib/gen/Dictionary.json +8 -6
- package/lib/gen/language.checksum +1 -1
- package/lib/gen/language.interp +8 -30
- package/lib/gen/language.tokens +105 -114
- package/lib/gen/languageLexer.interp +1 -34
- package/lib/gen/languageLexer.js +889 -1007
- package/lib/gen/languageLexer.tokens +95 -106
- package/lib/gen/languageParser.js +20717 -22376
- package/lib/json/from-csn.js +73 -68
- package/lib/json/to-csn.js +13 -10
- package/lib/language/antlrParser.js +2 -2
- package/lib/language/docCommentParser.js +61 -38
- package/lib/language/errorStrategy.js +52 -40
- package/lib/language/genericAntlrParser.js +333 -259
- package/lib/language/language.g4 +600 -645
- package/lib/language/multiLineStringParser.js +14 -42
- package/lib/language/textUtils.js +44 -0
- package/lib/main.d.ts +27 -42
- package/lib/main.js +104 -81
- package/lib/model/csnRefs.js +2 -1
- package/lib/model/csnUtils.js +183 -285
- package/lib/model/revealInternalProperties.js +32 -9
- package/lib/model/sortViews.js +32 -31
- package/lib/optionProcessor.js +64 -57
- package/lib/render/.eslintrc.json +1 -1
- package/lib/render/DuplicateChecker.js +4 -7
- package/lib/render/manageConstraints.js +70 -2
- package/lib/render/toCdl.js +334 -339
- package/lib/render/toHdbcds.js +20 -16
- package/lib/render/toRename.js +44 -22
- package/lib/render/toSql.js +60 -54
- package/lib/render/utils/common.js +15 -1
- package/lib/render/utils/sql.js +20 -19
- package/lib/sql-identifier.js +6 -0
- package/lib/transform/db/.eslintrc.json +3 -2
- package/lib/transform/db/cdsPersistence.js +5 -15
- package/lib/transform/db/constraints.js +1 -1
- package/lib/transform/db/expansion.js +7 -6
- package/lib/transform/db/flattening.js +18 -19
- package/lib/transform/db/views.js +3 -3
- package/lib/transform/draft/.eslintrc.json +2 -2
- package/lib/transform/draft/db.js +6 -6
- package/lib/transform/draft/odata.js +6 -7
- package/lib/transform/forHanaNew.js +19 -22
- package/lib/transform/forOdataNew.js +13 -15
- package/lib/transform/localized.js +35 -25
- package/lib/transform/odata/toFinalBaseType.js +11 -9
- package/lib/transform/odata/typesExposure.js +3 -3
- package/lib/transform/odata/utils.js +1 -38
- package/lib/transform/transformUtilsNew.js +63 -77
- package/lib/transform/translateAssocsToJoins.js +6 -2
- package/lib/transform/universalCsn/.eslintrc.json +2 -2
- package/lib/transform/universalCsn/coreComputed.js +11 -6
- package/lib/transform/universalCsn/universalCsnEnricher.js +33 -5
- package/lib/utils/file.js +31 -21
- package/lib/utils/timetrace.js +20 -21
- package/package.json +34 -4
- package/share/messages/syntax-expected-integer.md +9 -8
- package/doc/ApiMigration.md +0 -237
- package/doc/CommandLineMigration.md +0 -58
- package/doc/ErrorMessages.md +0 -175
- package/doc/FioriAnnotations.md +0 -94
- package/doc/ODataTransformation.md +0 -273
- package/lib/backends.js +0 -529
- package/lib/fix_antlr4-8_warning.js +0 -56
package/lib/compiler/extend.js
CHANGED
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
|
|
8
8
|
const { searchName, weakLocation } = require('../base/messages');
|
|
9
9
|
const {
|
|
10
|
-
isDeprecatedEnabled,
|
|
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
|
|
51
|
-
|
|
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
|
-
|
|
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, '
|
|
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, '
|
|
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, '
|
|
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, '
|
|
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, '
|
|
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
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
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;
|
package/lib/compiler/index.js
CHANGED
|
@@ -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
|
-
|
|
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
|
-
//
|
|
258
|
-
|
|
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:
|
|
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
|
-
|
|
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
|
};
|
package/lib/compiler/populate.js
CHANGED
|
@@ -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, '
|
|
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, '
|
|
83
|
-
!isDeprecatedEnabled( options, '
|
|
84
|
-
!isDeprecatedEnabled( options, '
|
|
85
|
-
!isDeprecatedEnabled( options, '
|
|
86
|
-
!isDeprecatedEnabled( options, '
|
|
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, '
|
|
88
|
+
= (isDeprecatedEnabled( options, '_noInheritedAutoexposeViaComposition' ))
|
|
89
89
|
? 'Composition'
|
|
90
90
|
: true;
|
|
91
|
-
const redirectInSubQueries = isDeprecatedEnabled( options, '
|
|
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.
|
|
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, '
|
|
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.
|
|
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, '
|
|
1114
|
-
const dedot = isDeprecatedEnabled( options, '
|
|
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, '
|
|
59
|
+
const enableExpandElements = !isDeprecatedEnabled( options, '_noElementsExpansion' );
|
|
60
60
|
// eslint-disable-next-line max-len
|
|
61
|
-
const oldVirtualNotNullPropagation = isDeprecatedEnabled( options, '
|
|
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.
|
|
192
|
+
// by the resolve(), and if not due to deprecated._noElementsExpansion
|
|
193
193
|
run( type );
|
|
194
194
|
return type[prop];
|
|
195
195
|
}
|