@sap/cds-compiler 5.2.0 → 5.3.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 +32 -0
- package/bin/cdsc.js +5 -0
- package/bin/cdshi.js +8 -8
- package/doc/CHANGELOG_BETA.md +9 -4
- package/lib/api/validate.js +5 -0
- package/lib/base/message-registry.js +25 -1
- package/lib/base/messages.js +1 -1
- package/lib/base/model.js +0 -1
- package/lib/compiler/assert-consistency.js +2 -2
- package/lib/compiler/builtins.js +1 -1
- package/lib/compiler/checks.js +25 -6
- package/lib/compiler/define.js +24 -28
- package/lib/compiler/extend.js +11 -13
- package/lib/compiler/generate.js +3 -3
- package/lib/compiler/populate.js +13 -7
- package/lib/compiler/propagator.js +2 -2
- package/lib/compiler/resolve.js +58 -60
- package/lib/compiler/shared.js +5 -5
- package/lib/compiler/tweak-assocs.js +247 -34
- package/lib/compiler/utils.js +40 -32
- package/lib/compiler/xpr-rewrite.js +44 -58
- package/lib/edm/annotations/genericTranslation.js +4 -4
- package/lib/edm/csn2edm.js +2 -2
- package/lib/edm/edm.js +46 -21
- package/lib/edm/edmInboundChecks.js +0 -1
- package/lib/edm/edmPreprocessor.js +40 -27
- package/lib/edm/edmUtils.js +1 -1
- package/lib/gen/BaseParser.js +180 -122
- package/lib/gen/CdlParser.js +2226 -2170
- package/lib/gen/language.checksum +1 -1
- package/lib/gen/language.interp +1 -1
- package/lib/gen/languageParser.js +3820 -3777
- package/lib/inspect/inspectPropagation.js +1 -1
- package/lib/json/from-csn.js +5 -3
- package/lib/json/to-csn.js +7 -10
- package/lib/language/antlrParser.js +38 -4
- package/lib/language/errorStrategy.js +1 -1
- package/lib/language/genericAntlrParser.js +4 -4
- package/lib/language/multiLineStringParser.js +1 -1
- package/lib/main.d.ts +23 -0
- package/lib/model/cloneCsn.js +22 -13
- package/lib/optionProcessor.js +7 -7
- package/lib/parsers/AstBuildingParser.js +155 -37
- package/lib/parsers/CdlGrammar.g4 +154 -81
- package/lib/parsers/Lexer.js +20 -10
- package/lib/render/toCdl.js +23 -18
- package/lib/transform/addTenantFields.js +4 -4
- package/lib/transform/forRelationalDB.js +7 -6
- package/lib/utils/moduleResolve.js +1 -1
- package/package.json +1 -1
- package/share/messages/redirected-to-complex.md +6 -3
package/lib/render/toCdl.js
CHANGED
|
@@ -1331,6 +1331,9 @@ function csnToCdl( csn, options, msg ) {
|
|
|
1331
1331
|
if (artifact.localized) // works even for type definitions
|
|
1332
1332
|
result += 'localized ';
|
|
1333
1333
|
|
|
1334
|
+
// Some properties are always "top-level", even for "many", e.g. "default" or
|
|
1335
|
+
// "not null". Keep a reference to the outer artifact.
|
|
1336
|
+
const origArtifact = artifact;
|
|
1334
1337
|
if (!artifact.type && artifact.items) {
|
|
1335
1338
|
checkArrayedArtifact(artifact, env);
|
|
1336
1339
|
result += 'many '; // alternative: 'array of'; but not used
|
|
@@ -1342,11 +1345,14 @@ function csnToCdl( csn, options, msg ) {
|
|
|
1342
1345
|
|
|
1343
1346
|
if (!type && artifact.elements) {
|
|
1344
1347
|
result += renderElements(artifact, env);
|
|
1345
|
-
result += renderNullability(artifact);
|
|
1348
|
+
result += renderNullability(artifact.notNull);
|
|
1346
1349
|
// structured default not possible at the moment
|
|
1347
1350
|
return result;
|
|
1348
1351
|
}
|
|
1349
1352
|
|
|
1353
|
+
const defaultValue = origArtifact.default ? origArtifact.default : artifact.default;
|
|
1354
|
+
const notNull = origArtifact.notNull ? origArtifact.notNull : artifact.notNull;
|
|
1355
|
+
|
|
1350
1356
|
// Association type
|
|
1351
1357
|
if (isDirectAssocOrComp(type)) {
|
|
1352
1358
|
const isComp = type === 'cds.Composition';
|
|
@@ -1378,11 +1384,11 @@ function csnToCdl( csn, options, msg ) {
|
|
|
1378
1384
|
if (artifact.keys && !artifact.on)
|
|
1379
1385
|
result += ` ${ renderForeignKeys(artifact, env) }`;
|
|
1380
1386
|
|
|
1381
|
-
if (
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1387
|
+
if (!artifact.on) {
|
|
1388
|
+
// unmanaged associations can't be followed by "not null" or "default"
|
|
1389
|
+
result += renderNullability(notNull);
|
|
1390
|
+
result += renderDefaultExpr(defaultValue, env.withSubPath([ 'default' ]));
|
|
1391
|
+
}
|
|
1386
1392
|
return result;
|
|
1387
1393
|
}
|
|
1388
1394
|
|
|
@@ -1409,13 +1415,12 @@ function csnToCdl( csn, options, msg ) {
|
|
|
1409
1415
|
|
|
1410
1416
|
if (artifact.enum && !typeRefOnly)
|
|
1411
1417
|
result += renderEnum(artifact.enum, env);
|
|
1412
|
-
if (artifact.notNull !== undefined)
|
|
1413
|
-
result += renderNullability(artifact);
|
|
1414
1418
|
|
|
1419
|
+
result += renderNullability(notNull);
|
|
1415
1420
|
// If there is a default value, and it's a calculated element, do not
|
|
1416
1421
|
// render the default (because it's not supported for calc elements).
|
|
1417
|
-
if (
|
|
1418
|
-
result += renderDefaultExpr(
|
|
1422
|
+
if (defaultValue !== undefined && !artifact.value)
|
|
1423
|
+
result += renderDefaultExpr(defaultValue, env.withSubPath([ 'default' ]));
|
|
1419
1424
|
|
|
1420
1425
|
return result;
|
|
1421
1426
|
}
|
|
@@ -1789,24 +1794,24 @@ function csnToCdl( csn, options, msg ) {
|
|
|
1789
1794
|
return result;
|
|
1790
1795
|
}
|
|
1791
1796
|
|
|
1792
|
-
function renderDefaultExpr(
|
|
1793
|
-
if (!
|
|
1797
|
+
function renderDefaultExpr( defaultValue, env ) {
|
|
1798
|
+
if (!defaultValue)
|
|
1794
1799
|
return '';
|
|
1795
1800
|
let result = ' default ';
|
|
1796
|
-
if (
|
|
1797
|
-
result += exprRenderer.renderSubExpr(withoutCast(
|
|
1801
|
+
if (defaultValue.xpr && xprContainsCondition( defaultValue.xpr))
|
|
1802
|
+
result += exprRenderer.renderSubExpr(withoutCast(defaultValue), env);
|
|
1798
1803
|
else
|
|
1799
|
-
result += exprRenderer.renderExpr(withoutCast(
|
|
1804
|
+
result += exprRenderer.renderExpr(withoutCast(defaultValue), env);
|
|
1800
1805
|
return result;
|
|
1801
1806
|
}
|
|
1802
1807
|
|
|
1803
1808
|
// Render the nullability of an element or parameter (can be unset, true, or false)
|
|
1804
|
-
function renderNullability(
|
|
1805
|
-
if (
|
|
1809
|
+
function renderNullability( notNull /* , env */) {
|
|
1810
|
+
if (notNull === undefined) {
|
|
1806
1811
|
// Attribute not set at all
|
|
1807
1812
|
return '';
|
|
1808
1813
|
}
|
|
1809
|
-
return
|
|
1814
|
+
return notNull ? ' not null' : ' null';
|
|
1810
1815
|
}
|
|
1811
1816
|
|
|
1812
1817
|
/**
|
|
@@ -78,7 +78,7 @@ function addTenantFields( csn, options, messageFunctions ) {
|
|
|
78
78
|
else if (!independent && independent != null) {
|
|
79
79
|
error( 'tenant-invalid-anno-value', msgLocations( csnPath ),
|
|
80
80
|
{ anno: annoTenantIndep, value: independent },
|
|
81
|
-
// eslint-disable-next-line max-len
|
|
81
|
+
// eslint-disable-next-line @stylistic/js/max-len
|
|
82
82
|
'Can\'t add $(ANNO) with value $(VALUE) to a non-entity, which is always tenant-independent' );
|
|
83
83
|
}
|
|
84
84
|
else if (art.includes) {
|
|
@@ -119,9 +119,9 @@ function addTenantFields( csn, options, messageFunctions ) {
|
|
|
119
119
|
.filter( name => isTenantDepEntity( csn.definitions[name] ) );
|
|
120
120
|
if (names.length) {
|
|
121
121
|
error( 'tenant-invalid-include', msgLocations( csnPath ), { names }, {
|
|
122
|
-
// eslint-disable-next-line max-len
|
|
122
|
+
// eslint-disable-next-line @stylistic/js/max-len
|
|
123
123
|
std: 'Can\'t include the tenant-dependent entities $(NAMES) into a tenant-independent definition',
|
|
124
|
-
// eslint-disable-next-line max-len
|
|
124
|
+
// eslint-disable-next-line @stylistic/js/max-len
|
|
125
125
|
one: 'Can\'t include the tenant-dependent entity $(NAMES) into a tenant-independent definition',
|
|
126
126
|
} );
|
|
127
127
|
}
|
|
@@ -206,7 +206,7 @@ function addTenantFields( csn, options, messageFunctions ) {
|
|
|
206
206
|
if (art[annoTenantIndep]) {
|
|
207
207
|
error( 'tenant-expecting-tenant-source', msgLocations( csnPath ), { art: query },
|
|
208
208
|
// TODO: better the final entity name of assoc navigation in FROM
|
|
209
|
-
// eslint-disable-next-line max-len
|
|
209
|
+
// eslint-disable-next-line @stylistic/js/max-len
|
|
210
210
|
'Expecting the query source $(ART) to be tenant-dependent for a tenant-dependent query entity' );
|
|
211
211
|
}
|
|
212
212
|
return true;
|
|
@@ -817,16 +817,17 @@ function transformForRelationalDBWithCsn(csn, options, messageFunctions) {
|
|
|
817
817
|
function checkTypeParameters(artifact, artifactName) {
|
|
818
818
|
forEachMemberRecursively(artifact, (member, memberName, prop, path) => {
|
|
819
819
|
// Check type parameters (length, precision, scale ...)
|
|
820
|
-
if (!member.$ignore
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
820
|
+
if (!member.$ignore) {
|
|
821
|
+
if (member.type)
|
|
822
|
+
_check(member, memberName, csn, path);
|
|
823
|
+
if (member.items?.type)
|
|
824
|
+
_check(member.items, memberName, csn, path.concat([ 'items' ]));
|
|
825
|
+
}
|
|
825
826
|
}, [ 'definitions', artifactName ]);
|
|
826
827
|
|
|
827
828
|
// Check that required actual parameters on 'node.type' are set, that their values are in the correct range etc.
|
|
828
829
|
function _check(node, nodeName, model, path) {
|
|
829
|
-
if (node.type) {
|
|
830
|
+
if (node.type && !node.virtual) {
|
|
830
831
|
const absolute = node.type;
|
|
831
832
|
switch (absolute) {
|
|
832
833
|
case 'cds.String':
|
|
@@ -579,7 +579,7 @@ function checkFileCase( dep, realpath, nativeRealpath, { warning } ) {
|
|
|
579
579
|
}
|
|
580
580
|
for (const using of dep.usingFroms) {
|
|
581
581
|
warning('file-unexpected-case-mismatch', [ using.location, using ], {},
|
|
582
|
-
// eslint-disable-next-line max-len
|
|
582
|
+
// eslint-disable-next-line @stylistic/js/max-len
|
|
583
583
|
'The imported filename differs on the filesystem; ensure that capitalization matches the actual file\'s name');
|
|
584
584
|
}
|
|
585
585
|
}
|
package/package.json
CHANGED
|
@@ -53,9 +53,12 @@ CrossJoin
|
|
|
53
53
|
|
|
54
54
|
## How to Fix
|
|
55
55
|
|
|
56
|
-
|
|
57
|
-
redirection target. That means, the redirection target shouldn't
|
|
58
|
-
make it a to-many association.
|
|
56
|
+
First, ensure that the redirected association points to an entity that is
|
|
57
|
+
a reasonable redirection target. That means, the redirection target shouldn't
|
|
58
|
+
accidentally make it a to-many association.
|
|
59
|
+
|
|
60
|
+
Then add an explicit ON-condition or explicit foreign keys to the redirected
|
|
61
|
+
association. That will silence the compiler message.
|
|
59
62
|
|
|
60
63
|
## Related Messages
|
|
61
64
|
|