@sap/cds-compiler 4.4.4 → 4.5.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.
- package/CHANGELOG.md +52 -0
- package/bin/cdsc.js +5 -0
- package/bin/cdsv2m.js +7 -5
- package/doc/CHANGELOG_BETA.md +16 -0
- package/lib/api/main.js +68 -47
- package/lib/api/options.js +10 -6
- package/lib/api/validate.js +1 -1
- package/lib/base/message-registry.js +28 -6
- package/lib/base/messages.js +18 -13
- package/lib/base/model.js +3 -0
- package/lib/checks/annotationsOData.js +49 -0
- package/lib/checks/validator.js +6 -4
- package/lib/compiler/assert-consistency.js +38 -16
- package/lib/compiler/builtins.js +10 -49
- package/lib/compiler/checks.js +16 -8
- package/lib/compiler/cycle-detector.js +1 -4
- package/lib/compiler/define.js +4 -1
- package/lib/compiler/extend.js +21 -7
- package/lib/compiler/generate.js +3 -0
- package/lib/compiler/populate.js +5 -1
- package/lib/compiler/propagator.js +46 -9
- package/lib/compiler/resolve.js +68 -14
- package/lib/compiler/shared.js +44 -27
- package/lib/compiler/tweak-assocs.js +158 -37
- package/lib/compiler/utils.js +9 -0
- package/lib/edm/annotations/edmJson.js +35 -61
- package/lib/edm/annotations/genericTranslation.js +13 -5
- package/lib/edm/annotations/preprocessAnnotations.js +2 -3
- package/lib/edm/csn2edm.js +4 -1
- package/lib/edm/edmInboundChecks.js +59 -15
- package/lib/edm/edmPreprocessor.js +1 -7
- package/lib/gen/Dictionary.json +8 -0
- package/lib/gen/language.checksum +1 -1
- package/lib/gen/language.interp +12 -2
- package/lib/gen/languageParser.js +6095 -5195
- package/lib/json/from-csn.js +4 -5
- package/lib/json/to-csn.js +22 -3
- package/lib/language/errorStrategy.js +7 -3
- package/lib/language/genericAntlrParser.js +120 -24
- package/lib/language/textUtils.js +16 -0
- package/lib/model/csnUtils.js +9 -8
- package/lib/model/revealInternalProperties.js +5 -2
- package/lib/optionProcessor.js +2 -3
- package/lib/render/toCdl.js +31 -13
- package/lib/render/toHdbcds.js +20 -30
- package/lib/render/toSql.js +33 -54
- package/lib/render/utils/common.js +24 -6
- package/lib/transform/db/applyTransformations.js +59 -2
- package/lib/transform/db/backlinks.js +13 -1
- package/lib/transform/db/expansion.js +24 -3
- package/lib/transform/db/flattening.js +2 -2
- package/lib/transform/db/killAnnotations.js +37 -0
- package/lib/transform/db/rewriteCalculatedElements.js +46 -6
- package/lib/transform/forOdata.js +13 -46
- package/lib/transform/forRelationalDB.js +2 -1
- package/lib/transform/translateAssocsToJoins.js +13 -4
- package/lib/transform/universalCsn/coreComputed.js +1 -1
- package/lib/transform/universalCsn/universalCsnEnricher.js +4 -4
- package/package.json +7 -6
package/lib/edm/csn2edm.js
CHANGED
|
@@ -477,7 +477,10 @@ function csn2edmAll( _csn, _options, serviceNames = undefined ) {
|
|
|
477
477
|
const type = `${schema.name}.${EntityTypeName}`;
|
|
478
478
|
if (properties.length === 0)
|
|
479
479
|
warning(null, location, { type }, 'EDM EntityType $(TYPE) has no properties');
|
|
480
|
-
|
|
480
|
+
// only if this entity has an entity set, it is required to have a key
|
|
481
|
+
// this especially covers: 'items: composition of one { data : String; }'
|
|
482
|
+
// "keyless" composition targets in structured containment mode
|
|
483
|
+
else if (entityCsn.$hasEntitySet && entityCsn.$edmKeyPaths.length === 0 && !isSingleton)
|
|
481
484
|
message('odata-spec-violation-no-key', location);
|
|
482
485
|
|
|
483
486
|
if (!edmUtils.isODataSimpleIdentifier(EntityTypeName))
|
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
const { setProp, isBetaEnabled } = require('../base/model');
|
|
4
4
|
const {
|
|
5
|
-
forEachDefinition, forEachMemberRecursively,
|
|
5
|
+
forEachDefinition, forEachMemberRecursively, isBuiltinType, getUtils,
|
|
6
6
|
} = require('../model/csnUtils');
|
|
7
|
+
const { assignAnnotation } = require('./edmUtils.js');
|
|
7
8
|
|
|
8
9
|
// eslint-disable-next-line no-unused-vars
|
|
9
10
|
function resolveForeignKeyRefs( csn, csnUtils ) {
|
|
@@ -22,9 +23,11 @@ function resolveForeignKeyRefs( csn, csnUtils ) {
|
|
|
22
23
|
|
|
23
24
|
function inboundQualificationChecks( csn, options, messageFunctions,
|
|
24
25
|
serviceRootNames, requestedServiceNames, isMyServiceRequested, whatsMyServiceRootName, csnUtils ) {
|
|
25
|
-
const { message, throwWithError } = messageFunctions;
|
|
26
|
+
const { message, warning, throwWithError } = messageFunctions;
|
|
26
27
|
|
|
27
|
-
|
|
28
|
+
const { getFinalTypeInfo } = getUtils(csn);
|
|
29
|
+
|
|
30
|
+
forEachDefinition(csn, [ attach$path, onServiceMember ]);
|
|
28
31
|
checkNestedContextsAndServices();
|
|
29
32
|
throwWithError();
|
|
30
33
|
|
|
@@ -37,27 +40,68 @@ function inboundQualificationChecks( csn, options, messageFunctions,
|
|
|
37
40
|
}, [ 'definitions', defName ]);
|
|
38
41
|
}
|
|
39
42
|
|
|
40
|
-
|
|
43
|
+
// code that should be run only on service members
|
|
44
|
+
function onServiceMember( def, defName ) {
|
|
41
45
|
if (!isMyServiceRequested(defName))
|
|
42
46
|
return;
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
47
|
+
|
|
48
|
+
const location = [ 'definitions', defName ];
|
|
49
|
+
// check items.items
|
|
50
|
+
checkIfItemsOfItems(def, undefined, undefined, location);
|
|
51
|
+
forEachMemberRecursively(def, checkIfItemsOfItems, location);
|
|
52
|
+
|
|
53
|
+
// decorate UUID keys with @Core.ComputedDefaultValue and complain
|
|
54
|
+
// on named type UUID elements that have no such annotation
|
|
55
|
+
const anno = '@Core.ComputedDefaultValue';
|
|
56
|
+
if (def.kind === 'entity' && def.elements) {
|
|
57
|
+
Object.entries(def.elements).forEach(([ eltName, elt ]) => {
|
|
58
|
+
if (elt.key)
|
|
59
|
+
addCoreComputedDefaultValueOnUUIDKeys(elt, [ eltName ], location);
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function addCoreComputedDefaultValueOnUUIDKeys( elt, eltPath, path ) {
|
|
64
|
+
let type = elt.items?.type || elt.type;
|
|
65
|
+
if (type && !isBuiltinType(type)) {
|
|
66
|
+
type = getFinalTypeInfo(type);
|
|
67
|
+
if (!isBuiltinType(type.type))
|
|
68
|
+
path = [ 'definitions', type.type ];
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
type = elt;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (type.type === 'cds.UUID') {
|
|
75
|
+
if (path[1] === defName)
|
|
76
|
+
assignAnnotation(elt, anno, true);
|
|
77
|
+
|
|
78
|
+
else if (elt[anno] == null)
|
|
79
|
+
warning('odata-key-uuid-default-anno', path, { type: type.type, anno, id: `${defName}:${eltPath.join('.')}` });
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
const elements = type.items?.elements || type.elements;
|
|
83
|
+
if (elements) {
|
|
84
|
+
Object.entries(elements).forEach(([ eltName, subelt ]) => {
|
|
85
|
+
addCoreComputedDefaultValueOnUUIDKeys(subelt, [ ...eltPath, eltName ], [ ...path, 'elements', eltName ]);
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function checkIfItemsOfItems( member, _memberName, _prop, path ) {
|
|
92
|
+
const memberType = csnUtils.effectiveType(member);
|
|
93
|
+
if (memberType.items) {
|
|
94
|
+
if (memberType.items.target) {
|
|
95
|
+
const isComp = memberType.items.type === 'cds.Composition';
|
|
52
96
|
message('type-invalid-items', path, { '#': isComp ? 'comp' : 'assoc', prop: 'items' });
|
|
53
97
|
return;
|
|
54
98
|
}
|
|
55
|
-
if (
|
|
99
|
+
if (memberType.items.items) {
|
|
56
100
|
message('chained-array-of', path);
|
|
57
101
|
return;
|
|
58
102
|
}
|
|
59
103
|
|
|
60
|
-
const itemsType = csnUtils.effectiveType(
|
|
104
|
+
const itemsType = csnUtils.effectiveType(memberType.items);
|
|
61
105
|
if (itemsType.items)
|
|
62
106
|
message('chained-array-of', path);
|
|
63
107
|
}
|
|
@@ -168,7 +168,6 @@ function initializeModel( csn, _options, messageFunctions, requestedServiceNames
|
|
|
168
168
|
initEdmNavPropBindingTargets,
|
|
169
169
|
pullupCapabilitiesAnnotations,
|
|
170
170
|
annotateOptionalActFuncParams,
|
|
171
|
-
openService,
|
|
172
171
|
]);
|
|
173
172
|
}
|
|
174
173
|
|
|
@@ -2125,7 +2124,7 @@ function initializeModel( csn, _options, messageFunctions, requestedServiceNames
|
|
|
2125
2124
|
optPns.forEach((op) => {
|
|
2126
2125
|
const type = op.items?.type || op.type;
|
|
2127
2126
|
if (type !== special$self)
|
|
2128
|
-
|
|
2127
|
+
error('odata-parameter-order', location.concat(op.name));
|
|
2129
2128
|
});
|
|
2130
2129
|
optPns = [];
|
|
2131
2130
|
}
|
|
@@ -2134,11 +2133,6 @@ function initializeModel( csn, _options, messageFunctions, requestedServiceNames
|
|
|
2134
2133
|
}
|
|
2135
2134
|
}
|
|
2136
2135
|
|
|
2137
|
-
function openService( def ) {
|
|
2138
|
-
if (options.odataOpenType && !def.$isParamEntity && !def.$proxy)
|
|
2139
|
-
edmUtils.assignAnnotation(def, '@open', true);
|
|
2140
|
-
}
|
|
2141
|
-
|
|
2142
2136
|
// ////////////////////////////////////////////////////////////////////
|
|
2143
2137
|
//
|
|
2144
2138
|
// Helper section starts here
|
package/lib/gen/Dictionary.json
CHANGED
|
@@ -801,6 +801,13 @@
|
|
|
801
801
|
"Parameter"
|
|
802
802
|
]
|
|
803
803
|
},
|
|
804
|
+
"Common.ValueListShowValuesImmediately": {
|
|
805
|
+
"Type": "Core.Tag",
|
|
806
|
+
"AppliesTo": [
|
|
807
|
+
"Annotation"
|
|
808
|
+
],
|
|
809
|
+
"$experimental": true
|
|
810
|
+
},
|
|
804
811
|
"Common.ValueListForValidation": {
|
|
805
812
|
"Type": "Edm.String",
|
|
806
813
|
"AppliesTo": [
|
|
@@ -2956,6 +2963,7 @@
|
|
|
2956
2963
|
"Common.IntervalType": {
|
|
2957
2964
|
"$kind": "ComplexType",
|
|
2958
2965
|
"Properties": {
|
|
2966
|
+
"Label": "Edm.String",
|
|
2959
2967
|
"LowerBoundary": "Edm.PropertyPath",
|
|
2960
2968
|
"LowerBoundaryIncluded": "Edm.Boolean",
|
|
2961
2969
|
"UpperBoundary": "Edm.PropertyPath",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
942cce045e6fb6ecaf7cbf3039001aa9
|