@sap/cds-compiler 2.10.2 → 2.11.4
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 +90 -5
- package/bin/.eslintrc.json +1 -2
- package/bin/cds_update_identifiers.js +3 -1
- package/bin/cdsc.js +49 -25
- package/bin/cdsse.js +1 -0
- package/bin/cdsv2m.js +3 -2
- package/doc/CHANGELOG_BETA.md +10 -0
- package/lib/api/.eslintrc.json +2 -0
- package/lib/api/main.js +8 -36
- package/lib/api/options.js +15 -6
- package/lib/api/validate.js +30 -3
- package/lib/backends.js +12 -13
- package/lib/base/dictionaries.js +2 -1
- package/lib/base/keywords.js +3 -2
- package/lib/base/message-registry.js +34 -10
- package/lib/base/messages.js +38 -18
- package/lib/base/model.js +5 -4
- package/lib/base/optionProcessorHelper.js +57 -23
- package/lib/checks/emptyOrOnlyVirtual.js +2 -2
- package/lib/checks/selectItems.js +4 -0
- package/lib/checks/unknownMagic.js +6 -3
- package/lib/compiler/assert-consistency.js +9 -2
- package/lib/compiler/base.js +65 -0
- package/lib/compiler/builtins.js +62 -16
- package/lib/compiler/checks.js +2 -1
- package/lib/compiler/definer.js +66 -108
- package/lib/compiler/index.js +29 -29
- package/lib/compiler/propagator.js +5 -2
- package/lib/compiler/resolver.js +225 -58
- package/lib/compiler/shared.js +53 -229
- package/lib/compiler/utils.js +184 -0
- package/lib/edm/annotations/genericTranslation.js +1 -1
- package/lib/edm/csn2edm.js +3 -2
- package/lib/edm/edmPreprocessor.js +34 -38
- package/lib/edm/edmUtils.js +3 -3
- package/lib/gen/language.checksum +1 -1
- package/lib/gen/language.interp +17 -1
- package/lib/gen/language.tokens +79 -73
- package/lib/gen/languageLexer.interp +19 -1
- package/lib/gen/languageLexer.js +779 -731
- package/lib/gen/languageLexer.tokens +71 -65
- package/lib/gen/languageParser.js +4668 -4072
- package/lib/json/from-csn.js +10 -10
- package/lib/json/to-csn.js +228 -47
- package/lib/language/antlrParser.js +11 -0
- package/lib/language/errorStrategy.js +26 -8
- package/lib/language/genericAntlrParser.js +73 -14
- package/lib/language/language.g4 +79 -3
- package/lib/main.d.ts +215 -18
- package/lib/main.js +3 -1
- package/lib/model/api.js +2 -2
- package/lib/model/csnRefs.js +117 -33
- package/lib/model/csnUtils.js +65 -133
- package/lib/model/enrichCsn.js +62 -37
- package/lib/model/revealInternalProperties.js +25 -8
- package/lib/model/sortViews.js +8 -1
- package/lib/modelCompare/compare.js +2 -1
- package/lib/optionProcessor.js +33 -18
- package/lib/render/.eslintrc.json +1 -2
- package/lib/render/DuplicateChecker.js +1 -1
- package/lib/render/toCdl.js +15 -8
- package/lib/render/toHdbcds.js +26 -49
- package/lib/render/toSql.js +61 -39
- package/lib/render/utils/common.js +1 -1
- package/lib/transform/db/applyTransformations.js +189 -0
- package/lib/transform/db/constraints.js +273 -119
- package/lib/transform/db/draft.js +3 -2
- package/lib/transform/db/expansion.js +6 -4
- package/lib/transform/db/flattening.js +19 -3
- package/lib/transform/db/transformExists.js +102 -9
- package/lib/transform/db/views.js +485 -0
- package/lib/transform/forHanaNew.js +93 -448
- package/lib/transform/forOdataNew.js +9 -2
- package/lib/transform/localized.js +2 -0
- package/lib/transform/odata/structuralPath.js +1 -5
- package/lib/transform/transformUtilsNew.js +22 -8
- package/lib/transform/translateAssocsToJoins.js +7 -15
- package/lib/utils/file.js +11 -5
- package/lib/utils/term.js +65 -42
- package/lib/utils/timetrace.js +48 -26
- package/package.json +1 -1
- package/lib/transform/db/helpers.js +0 -58
|
@@ -54,7 +54,7 @@ function initializeModel(csn, _options, messageFunctions)
|
|
|
54
54
|
let options = validateOptions(_options);
|
|
55
55
|
|
|
56
56
|
// Fetch service definitions
|
|
57
|
-
const serviceRoots = Object.keys(csn.definitions).reduce((serviceRoots, artName) => {
|
|
57
|
+
const serviceRoots = Object.keys(csn.definitions || {}).reduce((serviceRoots, artName) => {
|
|
58
58
|
const art = csn.definitions[artName];
|
|
59
59
|
if(art.kind === 'service') {
|
|
60
60
|
serviceRoots[artName] = Object.assign(art, { name: artName });
|
|
@@ -67,6 +67,9 @@ function initializeModel(csn, _options, messageFunctions)
|
|
|
67
67
|
function whatsMyServiceRootName(n, self=true) {
|
|
68
68
|
return serviceRootNames.reduce((rc, sn) => !rc && n && n.startsWith(sn + '.') || (n === sn && self) ? sn : rc, undefined);
|
|
69
69
|
}
|
|
70
|
+
if(serviceRootNames.length === 0) {
|
|
71
|
+
return [serviceRoots, Object.create(null), whatsMyServiceRootName, options];
|
|
72
|
+
}
|
|
70
73
|
|
|
71
74
|
// Structural CSN inbound QA checks
|
|
72
75
|
inboundQualificationChecks();
|
|
@@ -594,6 +597,16 @@ function initializeModel(csn, _options, messageFunctions)
|
|
|
594
597
|
if(element['@cds.valid.from']) {
|
|
595
598
|
validFrom.push(element);
|
|
596
599
|
}
|
|
600
|
+
//forward annotations from managed association element to its foreign keys
|
|
601
|
+
const elements = construct.items && construct.items.elements || construct.elements;
|
|
602
|
+
forAll(elements[element['@odata.foreignKey4']], (attr, attrName) => {
|
|
603
|
+
if(attrName[0] === '@') {
|
|
604
|
+
element[attrName] = attr;
|
|
605
|
+
}
|
|
606
|
+
});
|
|
607
|
+
// and eventually remove some afterwards:)
|
|
608
|
+
if(options.isV2())
|
|
609
|
+
setSAPSpecificV2AnnotationsToAssociation(element);
|
|
597
610
|
|
|
598
611
|
// initialize an association
|
|
599
612
|
if(isAssociationOrComposition(element)) {
|
|
@@ -602,20 +615,6 @@ function initializeModel(csn, _options, messageFunctions)
|
|
|
602
615
|
assignProp(element._target, '$proxies', []);
|
|
603
616
|
// $abspath is used as partner path
|
|
604
617
|
assignProp(element, '$abspath', $path2path(element.$path));
|
|
605
|
-
|
|
606
|
-
//forward annotations from managed association element to its foreign keys
|
|
607
|
-
if(element.keys && options.isFlatFormat) {
|
|
608
|
-
const elements = construct.items && construct.items.elements || construct.elements;
|
|
609
|
-
for(let fk of element.keys) {
|
|
610
|
-
forAll(element, (attr, attrName) => {
|
|
611
|
-
if(attrName[0] === '@' && fk.$generatedFieldName && elements && elements[fk.$generatedFieldName]) {
|
|
612
|
-
elements[fk.$generatedFieldName][attrName] = attr;
|
|
613
|
-
}
|
|
614
|
-
});
|
|
615
|
-
}
|
|
616
|
-
}
|
|
617
|
-
// and afterwards eventually remove some :)
|
|
618
|
-
setSAPSpecificV2AnnotationsToAssociation(options, element, def);
|
|
619
618
|
}
|
|
620
619
|
|
|
621
620
|
// Collect keys
|
|
@@ -1351,7 +1350,8 @@ function initializeModel(csn, _options, messageFunctions)
|
|
|
1351
1350
|
// OData requires all elements along the path to be nullable: false (that is either key or notNull)
|
|
1352
1351
|
|
|
1353
1352
|
const finalType = getFinalTypeDef(eltCsn.items && eltCsn.items.type || eltCsn.type);
|
|
1354
|
-
const elements = eltCsn.elements || eltCsn.items && eltCsn.items.elements
|
|
1353
|
+
const elements = eltCsn.elements || eltCsn.items && eltCsn.items.elements ||
|
|
1354
|
+
(finalType && (finalType.elements || finalType.items && finalType.items.elements));
|
|
1355
1355
|
if(elements) {
|
|
1356
1356
|
Object.entries(elements).forEach(([eltName, elt]) => {
|
|
1357
1357
|
const newRefs = produceKeyRefPaths(elt, prefix + options.pathDelimiter + eltName);
|
|
@@ -1400,7 +1400,7 @@ function initializeModel(csn, _options, messageFunctions)
|
|
|
1400
1400
|
{name: pathSegment, '#': pathSegment ? 'std' : 'scalar'});
|
|
1401
1401
|
}
|
|
1402
1402
|
// many
|
|
1403
|
-
let type = elt.items || getFinalTypeDef(elt.type).items;
|
|
1403
|
+
let type = elt.items || elt.type && !isBuiltinType(elt.type) && getFinalTypeDef(elt.type).items;
|
|
1404
1404
|
if(type) {
|
|
1405
1405
|
error('odata-spec-violation-key-array', location,
|
|
1406
1406
|
{name: pathSegment, '#': pathSegment ? 'std' : 'scalar'});
|
|
@@ -2158,19 +2158,17 @@ function setSAPSpecificV2AnnotationsToEntitySet(options, carrier) {
|
|
|
2158
2158
|
}
|
|
2159
2159
|
}
|
|
2160
2160
|
|
|
2161
|
-
function setSAPSpecificV2AnnotationsToAssociation(
|
|
2162
|
-
if(!options.isV2())
|
|
2163
|
-
return;
|
|
2161
|
+
function setSAPSpecificV2AnnotationsToAssociation(carrier) {
|
|
2164
2162
|
// documented in https://wiki.scn.sap.com/wiki/display/EmTech/SAP+Annotations+for+OData+Version+2.0
|
|
2165
2163
|
const SetAttributes = {
|
|
2166
2164
|
// Applicable to NavProp and foreign keys, add to AssociationSet
|
|
2167
|
-
'@sap.creatable' : (
|
|
2165
|
+
'@sap.creatable' : (c, pn, pv) => { addToAssociationSet(c, pn, pv, false); },
|
|
2168
2166
|
// Not applicable to NavProp, applicable to foreign keys, add to AssociationSet
|
|
2169
|
-
'@sap.updatable' :
|
|
2167
|
+
'@sap.updatable' : addToAssociationSet,
|
|
2170
2168
|
// Not applicable to NavProp, not applicable to foreign key, add to AssociationSet
|
|
2171
|
-
'@sap.deletable': (
|
|
2172
|
-
|
|
2173
|
-
removeFromForeignKey(
|
|
2169
|
+
'@sap.deletable': (c, pn, pv) => {
|
|
2170
|
+
addToAssociationSet(c, pn, pv);
|
|
2171
|
+
removeFromForeignKey(c, pn);
|
|
2174
2172
|
},
|
|
2175
2173
|
// applicable to NavProp, not applicable to foreign keys, not applicable to AssociationSet
|
|
2176
2174
|
'@sap.creatable.path': removeFromForeignKey,
|
|
@@ -2178,24 +2176,22 @@ function setSAPSpecificV2AnnotationsToAssociation(options, carrier, struct) {
|
|
|
2178
2176
|
};
|
|
2179
2177
|
|
|
2180
2178
|
Object.entries(carrier).forEach(([p, v]) => {
|
|
2181
|
-
(SetAttributes[p] || function() {/* no-op */})(
|
|
2179
|
+
(SetAttributes[p] || function() {/* no-op */})(carrier, p, v);
|
|
2182
2180
|
});
|
|
2183
2181
|
|
|
2184
|
-
function
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2182
|
+
function addToAssociationSet(carrier, propName, propValue, removeFromType=true) {
|
|
2183
|
+
if(isAssociationOrComposition(carrier)) {
|
|
2184
|
+
assignProp(carrier, '_SetAttributes', Object.create(null));
|
|
2185
|
+
assignAnnotation(carrier._SetAttributes, propName, propValue);
|
|
2186
|
+
if(removeFromType) {
|
|
2187
|
+
delete carrier[propName];
|
|
2188
|
+
}
|
|
2189
2189
|
}
|
|
2190
2190
|
}
|
|
2191
2191
|
|
|
2192
|
-
function removeFromForeignKey(
|
|
2193
|
-
if(carrier.
|
|
2194
|
-
|
|
2195
|
-
if(e['@odata.foreignKey4'] === carrier.name) {
|
|
2196
|
-
delete e[propName];
|
|
2197
|
-
}
|
|
2198
|
-
});
|
|
2192
|
+
function removeFromForeignKey(carrier, propName) {
|
|
2193
|
+
if(carrier['@odata.foreignKey4'] && carrier[propName] !== undefined) {
|
|
2194
|
+
delete carrier[propName];
|
|
2199
2195
|
}
|
|
2200
2196
|
}
|
|
2201
2197
|
}
|
package/lib/edm/edmUtils.js
CHANGED
|
@@ -181,7 +181,7 @@ function resolveOnConditionAndPrepareConstraints(csn, assocCsn, messageFunctions
|
|
|
181
181
|
const parent = csn.definitions[parentName];
|
|
182
182
|
if(originAssocCsn) {
|
|
183
183
|
const originParentName = originAssocCsn.$abspath[0];
|
|
184
|
-
if(originAssocCsn._originalTarget !== parent && originAssocCsn._target !== parent) {
|
|
184
|
+
if(parent.$mySchemaName && originAssocCsn._originalTarget !== parent && originAssocCsn._target !== parent) {
|
|
185
185
|
isBacklink = false;
|
|
186
186
|
// Partnership is ambiguous
|
|
187
187
|
setProp(originAssocCsn, '$noPartner', true);
|
|
@@ -192,7 +192,7 @@ function resolveOnConditionAndPrepareConstraints(csn, assocCsn, messageFunctions
|
|
|
192
192
|
// Mark this association as backlink if $self appears exactly once
|
|
193
193
|
// to surpress edm:Association generation in V2 mode
|
|
194
194
|
if(isBacklink) {
|
|
195
|
-
//
|
|
195
|
+
// establish partnership with origin assoc but only if this association is the first one
|
|
196
196
|
if(originAssocCsn._selfReferences.length === 0) {
|
|
197
197
|
assocCsn._constraints._partnerCsn = originAssocCsn;
|
|
198
198
|
}
|
|
@@ -202,7 +202,7 @@ function resolveOnConditionAndPrepareConstraints(csn, assocCsn, messageFunctions
|
|
|
202
202
|
}
|
|
203
203
|
// store all backlinks at forward, required to calculate rendering of foreign keys
|
|
204
204
|
// if the termCount != 1 or more than one $self compare this is not a backlink
|
|
205
|
-
if(assocCsn._constraints.selfs.length === 1 && assocCsn._constraints.termCount === 1) {
|
|
205
|
+
if(parent.$mySchemaName && assocCsn._constraints.selfs.length === 1 && assocCsn._constraints.termCount === 1) {
|
|
206
206
|
originAssocCsn._selfReferences.push(assocCsn);
|
|
207
207
|
}
|
|
208
208
|
assocCsn._constraints._origins.push(originAssocCsn);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
cde5224056abde61cc2eb0b1b30bf694
|