@sap/cds-compiler 3.5.4 → 3.6.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 +56 -2
- package/bin/cdsc.js +14 -6
- package/doc/CHANGELOG_ARCHIVE.md +10 -10
- package/doc/CHANGELOG_DEPRECATED.md +2 -2
- package/lib/api/main.js +32 -55
- package/lib/api/validate.js +5 -0
- package/lib/base/message-registry.js +104 -32
- package/lib/base/messages.js +277 -212
- package/lib/base/optionProcessorHelper.js +9 -2
- package/lib/base/shuffle.js +50 -0
- package/lib/checks/actionsFunctions.js +37 -20
- package/lib/checks/foreignKeys.js +13 -6
- package/lib/checks/nonexpandableStructured.js +1 -2
- package/lib/checks/onConditions.js +21 -19
- package/lib/checks/parameters.js +1 -1
- package/lib/checks/queryNoDbArtifacts.js +2 -0
- package/lib/checks/types.js +16 -22
- package/lib/compiler/assert-consistency.js +31 -28
- package/lib/compiler/builtins.js +20 -4
- package/lib/compiler/checks.js +72 -63
- package/lib/compiler/define.js +396 -314
- package/lib/compiler/extend.js +55 -49
- package/lib/compiler/index.js +5 -0
- package/lib/compiler/populate.js +28 -11
- package/lib/compiler/propagator.js +2 -1
- package/lib/compiler/resolve.js +28 -13
- package/lib/compiler/shared.js +15 -10
- package/lib/compiler/utils.js +7 -7
- package/lib/edm/annotations/genericTranslation.js +51 -46
- package/lib/edm/annotations/preprocessAnnotations.js +37 -40
- package/lib/edm/csn2edm.js +69 -21
- package/lib/edm/edm.js +2 -2
- package/lib/edm/edmInboundChecks.js +6 -8
- package/lib/edm/edmPreprocessor.js +88 -80
- package/lib/edm/edmUtils.js +6 -15
- package/lib/gen/Dictionary.json +81 -13
- package/lib/gen/language.checksum +1 -1
- package/lib/gen/language.interp +2 -1
- package/lib/gen/languageParser.js +4680 -4484
- package/lib/inspect/inspectModelStatistics.js +2 -1
- package/lib/inspect/inspectPropagation.js +2 -1
- package/lib/json/from-csn.js +131 -78
- package/lib/json/to-csn.js +39 -23
- package/lib/language/antlrParser.js +0 -3
- package/lib/language/docCommentParser.js +7 -3
- package/lib/language/errorStrategy.js +3 -2
- package/lib/language/genericAntlrParser.js +96 -41
- package/lib/language/language.g4 +112 -128
- package/lib/language/multiLineStringParser.js +2 -1
- package/lib/main.d.ts +115 -2
- package/lib/main.js +16 -3
- package/lib/model/csnRefs.js +3 -3
- package/lib/model/csnUtils.js +109 -179
- package/lib/model/enrichCsn.js +13 -8
- package/lib/model/revealInternalProperties.js +4 -3
- package/lib/optionProcessor.js +19 -3
- package/lib/render/manageConstraints.js +11 -15
- package/lib/render/toCdl.js +144 -47
- package/lib/render/toHdbcds.js +22 -22
- package/lib/render/toRename.js +3 -4
- package/lib/render/toSql.js +29 -20
- package/lib/render/utils/delta.js +3 -1
- package/lib/render/utils/sql.js +2 -14
- package/lib/transform/db/associations.js +6 -6
- package/lib/transform/db/cdsPersistence.js +3 -3
- package/lib/transform/db/constraints.js +4 -6
- package/lib/transform/db/expansion.js +4 -4
- package/lib/transform/db/flattening.js +12 -15
- package/lib/transform/db/temporal.js +4 -3
- package/lib/transform/db/transformExists.js +2 -1
- package/lib/transform/draft/db.js +7 -7
- package/lib/transform/forOdataNew.js +15 -4
- package/lib/transform/forRelationalDB.js +53 -39
- package/lib/transform/odata/toFinalBaseType.js +106 -82
- package/lib/transform/odata/typesExposure.js +26 -17
- package/lib/transform/odata/utils.js +1 -1
- package/lib/transform/parseExpr.js +1 -1
- package/lib/transform/transformUtilsNew.js +33 -10
- package/lib/transform/translateAssocsToJoins.js +8 -7
- package/lib/transform/universalCsn/coreComputed.js +7 -5
- package/lib/transform/universalCsn/universalCsnEnricher.js +12 -4
- package/lib/utils/timetrace.js +2 -2
- package/package.json +1 -2
|
@@ -10,7 +10,7 @@ const { setProp } = require('../base/model');
|
|
|
10
10
|
const { copyAnnotations, applyTransformations } = require('../model/csnUtils');
|
|
11
11
|
const { cloneCsnNonDict, cloneCsnDictionary, getUtils } = require('../model/csnUtils');
|
|
12
12
|
const { typeParameters, isBuiltinType } = require('../compiler/builtins');
|
|
13
|
-
const { ModelError } = require('../base/error');
|
|
13
|
+
const { ModelError, CompilerAssertion} = require('../base/error');
|
|
14
14
|
const { forEach } = require('../utils/objectUtils');
|
|
15
15
|
const { pathName } = require('../compiler/utils');
|
|
16
16
|
|
|
@@ -185,7 +185,7 @@ function getTransformers(model, options, pathDelimiter = '_') {
|
|
|
185
185
|
return;
|
|
186
186
|
}
|
|
187
187
|
if(iKey.ref.length>1)
|
|
188
|
-
throw
|
|
188
|
+
throw new CompilerAssertion(`createForeignKeyElement(${artifactName},${assocName},${iKey.$path.join('/')}) unexpected reference: `+ iKey.ref)
|
|
189
189
|
newForeignKey(iKeyArtifact,foreignKeyElementName+'_'+iKey.ref[0])
|
|
190
190
|
})
|
|
191
191
|
}
|
|
@@ -899,13 +899,13 @@ function getTransformers(model, options, pathDelimiter = '_') {
|
|
|
899
899
|
let annotation = node && node[fromName];
|
|
900
900
|
// Sanity checks
|
|
901
901
|
if (!fromName.startsWith('@')) {
|
|
902
|
-
throw
|
|
902
|
+
throw new CompilerAssertion('Annotation name should start with "@": ' + fromName);
|
|
903
903
|
}
|
|
904
904
|
if (!toName.startsWith('@')) {
|
|
905
|
-
throw
|
|
905
|
+
throw new CompilerAssertion('Annotation name should start with "@": ' + toName);
|
|
906
906
|
}
|
|
907
907
|
if (annotation === undefined) {
|
|
908
|
-
throw
|
|
908
|
+
throw new CompilerAssertion('Annotation ' + fromName + ' not found in ' + JSON.stringify(node));
|
|
909
909
|
}
|
|
910
910
|
if(node[toName] === undefined || node[toName] === null) {
|
|
911
911
|
delete node[fromName];
|
|
@@ -924,10 +924,10 @@ function getTransformers(model, options, pathDelimiter = '_') {
|
|
|
924
924
|
*/
|
|
925
925
|
function setAnnotation(node, name, value) {
|
|
926
926
|
if (!name.startsWith('@')) {
|
|
927
|
-
throw
|
|
927
|
+
throw new CompilerAssertion('Annotation name should start with "@": ' + name);
|
|
928
928
|
}
|
|
929
929
|
if (value === undefined) {
|
|
930
|
-
throw
|
|
930
|
+
throw new CompilerAssertion('Annotation value must not be undefined');
|
|
931
931
|
}
|
|
932
932
|
|
|
933
933
|
if(node[name] === undefined || node[name] === null)
|
|
@@ -948,10 +948,10 @@ function getTransformers(model, options, pathDelimiter = '_') {
|
|
|
948
948
|
*/
|
|
949
949
|
function resetAnnotation(node, name, value, info, path) {
|
|
950
950
|
if (!name.startsWith('@')) {
|
|
951
|
-
throw
|
|
951
|
+
throw new CompilerAssertion('Annotation name should start with "@": ' + name);
|
|
952
952
|
}
|
|
953
953
|
if (value === undefined) {
|
|
954
|
-
throw
|
|
954
|
+
throw new CompilerAssertion('Annotation value must not be undefined');
|
|
955
955
|
}
|
|
956
956
|
|
|
957
957
|
const wasOverwritten = node[name] !== undefined && node[name] !== null && node[name] !== value;
|
|
@@ -1406,10 +1406,33 @@ function transformModel(csn, customTransformations, transformNonEnumerableElemen
|
|
|
1406
1406
|
}
|
|
1407
1407
|
}
|
|
1408
1408
|
|
|
1409
|
+
/**
|
|
1410
|
+
* Mandatory input transformation for all backends:
|
|
1411
|
+
* Replace
|
|
1412
|
+
* type: { ref: [ 'cds.<type>' ] }
|
|
1413
|
+
* with the direct type
|
|
1414
|
+
* type: 'cds.<type>'
|
|
1415
|
+
*
|
|
1416
|
+
* @param {CSN.Model} csn
|
|
1417
|
+
*/
|
|
1418
|
+
function rewriteBuiltinTypeRef(csn) {
|
|
1419
|
+
const special$self = !csn?.definitions?.$self && '$self';
|
|
1420
|
+
applyTransformations(csn, {
|
|
1421
|
+
type: (parent, _prop, type) => {
|
|
1422
|
+
if(type.ref && (
|
|
1423
|
+
isBuiltinType(type.ref[0]) ||
|
|
1424
|
+
type.ref[0] === special$self)
|
|
1425
|
+
) {
|
|
1426
|
+
parent.type = type.ref[0];
|
|
1427
|
+
}
|
|
1428
|
+
}
|
|
1429
|
+
});
|
|
1430
|
+
}
|
|
1409
1431
|
|
|
1410
1432
|
module.exports = {
|
|
1411
1433
|
// This function retrieves the actual exports
|
|
1412
1434
|
getTransformers,
|
|
1413
1435
|
transformModel,
|
|
1414
|
-
RelationalOperators
|
|
1436
|
+
RelationalOperators,
|
|
1437
|
+
rewriteBuiltinTypeRef,
|
|
1415
1438
|
};
|
|
@@ -7,6 +7,7 @@ const { linkToOrigin, pathName } = require('../compiler/utils');
|
|
|
7
7
|
const {compactModel, compactExpr} = require('../json/to-csn');
|
|
8
8
|
const { deduplicateMessages } = require('../base/messages');
|
|
9
9
|
const { timetrace } = require('../utils/timetrace');
|
|
10
|
+
const {CompilerAssertion} = require('../base/error');
|
|
10
11
|
// Paths that start with an artifact of protected kind are special
|
|
11
12
|
// either ignore them in QAT building or in path rewriting
|
|
12
13
|
const internalArtifactKinds = ['builtin', '$parameters', 'param'];
|
|
@@ -336,7 +337,7 @@ function translateAssocsToJoins(model, inputOptions = {})
|
|
|
336
337
|
// const revealInternalProperties = require('../model/revealInternalProperties.js');
|
|
337
338
|
// console.log('++++++++ Path tail: ', revealInternalProperties(tail[tail.length-1]._artifact));
|
|
338
339
|
// console.log('******** Flat FKs\n', tail[i]._artifact.$flatSrcFKs.map(f => revealInternalProperties(f._artifact)));
|
|
339
|
-
throw
|
|
340
|
+
throw new CompilerAssertion('Please debug me: No flat FK found for FK rewriting');
|
|
340
341
|
}
|
|
341
342
|
// replace tail path with flattened foreign key including prefix
|
|
342
343
|
tail.splice(i, tail.length, fk);
|
|
@@ -444,7 +445,7 @@ function translateAssocsToJoins(model, inputOptions = {})
|
|
|
444
445
|
}
|
|
445
446
|
else if(art.target) { // it's not an artifact, so it should be an assoc step
|
|
446
447
|
if(joinTree === undefined)
|
|
447
|
-
throw
|
|
448
|
+
throw new CompilerAssertion('Can\'t follow Associations without starting Entity');
|
|
448
449
|
|
|
449
450
|
if(!childQat.$QA)
|
|
450
451
|
childQat.$QA = createQA(env, art.target._artifact, art.name.id, childQat._namedArgs);
|
|
@@ -570,7 +571,7 @@ function translateAssocsToJoins(model, inputOptions = {})
|
|
|
570
571
|
setProp(assoc, '$flatTgtFKs', flattenElement(assoc, false));
|
|
571
572
|
|
|
572
573
|
if(assoc.$flatSrcFKs.length != assoc.$flatTgtFKs.length)
|
|
573
|
-
throw
|
|
574
|
+
throw new CompilerAssertion('srcPaths length ['+assoc.$flatSrcFKs.length+'] != tgtPaths length ['+assoc.$flatTgtFKs.length+']');
|
|
574
575
|
|
|
575
576
|
/*
|
|
576
577
|
Put all src/tgt path siblings into the EQ term and create the proper path objects
|
|
@@ -991,7 +992,7 @@ function translateAssocsToJoins(model, inputOptions = {})
|
|
|
991
992
|
function createQA(env, artifact, alias=undefined, namedArgs=undefined)
|
|
992
993
|
{
|
|
993
994
|
if(alias === undefined) {
|
|
994
|
-
throw
|
|
995
|
+
throw new CompilerAssertion('no alias provided');
|
|
995
996
|
}
|
|
996
997
|
|
|
997
998
|
const pathStep = {
|
|
@@ -1129,7 +1130,7 @@ function translateAssocsToJoins(model, inputOptions = {})
|
|
|
1129
1130
|
}
|
|
1130
1131
|
return paths.map(p => {
|
|
1131
1132
|
return {
|
|
1132
|
-
id: (prefix ? prefix + pathDelimiter : '' ) + p.id,
|
|
1133
|
+
id: (prefix ? prefix + pathDelimiter : '' ) + p.id,
|
|
1133
1134
|
acc: (acc ? acc + pathDelimiter : '') + p.acc,
|
|
1134
1135
|
_artifact: p._artifact
|
|
1135
1136
|
}
|
|
@@ -1455,7 +1456,7 @@ function translateAssocsToJoins(model, inputOptions = {})
|
|
|
1455
1456
|
}
|
|
1456
1457
|
|
|
1457
1458
|
if(qatParent == undefined)
|
|
1458
|
-
throw
|
|
1459
|
+
throw new CompilerAssertion('table alias/qathost not found for path: ' + pathAsStr(path));
|
|
1459
1460
|
|
|
1460
1461
|
let rootQat = qatParent;
|
|
1461
1462
|
|
|
@@ -1578,7 +1579,7 @@ function translateAssocsToJoins(model, inputOptions = {})
|
|
|
1578
1579
|
});
|
|
1579
1580
|
|
|
1580
1581
|
if(!qat)
|
|
1581
|
-
throw
|
|
1582
|
+
throw new CompilerAssertion('No leaf qat for head: ' + head + ' tail: ' + pathAsStr(tail, '"') + ' produced');
|
|
1582
1583
|
|
|
1583
1584
|
/*
|
|
1584
1585
|
If path terminates on an entity or an association (from clause,
|
|
@@ -1,19 +1,21 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const {
|
|
4
|
-
|
|
4
|
+
forEachDefinition, forAllQueries, getNormalizedQuery,
|
|
5
5
|
} = require('../../model/csnUtils');
|
|
6
6
|
const { setAnnotationIfNotDefined } = require('./utils');
|
|
7
|
+
const { CompilerAssertion } = require('../../base/error');
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
* Set @Core.Computed on the elements of views (and projections).
|
|
10
11
|
*
|
|
11
12
|
* @param {CSN.Model} csn
|
|
13
|
+
* @param {object} csnUtils
|
|
12
14
|
*/
|
|
13
|
-
function setCoreComputedOnViews( csn ) {
|
|
15
|
+
function setCoreComputedOnViews( csn, csnUtils ) {
|
|
14
16
|
const {
|
|
15
17
|
artifactRef, getColumn, getElement, getOrigin,
|
|
16
|
-
} =
|
|
18
|
+
} = csnUtils;
|
|
17
19
|
|
|
18
20
|
forEachDefinition(csn, (artifact, name, prop, path) => {
|
|
19
21
|
if (artifact.query || artifact.projection) {
|
|
@@ -65,7 +67,7 @@ function setCoreComputedOnViews( csn ) {
|
|
|
65
67
|
const origin = getOrigin(element);
|
|
66
68
|
if (origin)
|
|
67
69
|
return origin;
|
|
68
|
-
throw new
|
|
70
|
+
throw new CompilerAssertion(`Could not find ancestor for ${JSON.stringify(element)} named ${name}`);
|
|
69
71
|
}
|
|
70
72
|
|
|
71
73
|
/**
|
|
@@ -98,7 +100,7 @@ function setCoreComputedOnViews( csn ) {
|
|
|
98
100
|
return checkJoinSources(base.args, name);
|
|
99
101
|
}
|
|
100
102
|
|
|
101
|
-
throw new
|
|
103
|
+
throw new CompilerAssertion(JSON.stringify(base));
|
|
102
104
|
}
|
|
103
105
|
|
|
104
106
|
/**
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const { setProp } = require('../../base/model');
|
|
4
|
+
const shuffleGen = require('../../base/shuffle');
|
|
4
5
|
const { setAnnotationIfNotDefined, makeClientCompatible } = require('./utils');
|
|
5
6
|
const {
|
|
6
7
|
forEachDefinition,
|
|
@@ -22,9 +23,10 @@ const { setCoreComputedOnViews } = require('./coreComputed');
|
|
|
22
23
|
* @param {CSN.Options} options
|
|
23
24
|
*/
|
|
24
25
|
module.exports = (csn, options) => {
|
|
26
|
+
const csnUtils = getUtils(csn, 'init-all');
|
|
25
27
|
const {
|
|
26
28
|
initDefinition, getOrigin, getQueryPrimarySource, artifactRef, getColumn,
|
|
27
|
-
} =
|
|
29
|
+
} = csnUtils;
|
|
28
30
|
// Properties on definition level that we treat specially.
|
|
29
31
|
const definitionPropagationRules = {
|
|
30
32
|
'@cds.autoexpose': onlyViaArtifact,
|
|
@@ -98,6 +100,10 @@ module.exports = (csn, options) => {
|
|
|
98
100
|
cardinality: notWithItemsOrElements,
|
|
99
101
|
};
|
|
100
102
|
|
|
103
|
+
if (options.testMode) {
|
|
104
|
+
const { shuffleDict } = shuffleGen( options.testMode );
|
|
105
|
+
csn.definitions = shuffleDict( csn.definitions );
|
|
106
|
+
}
|
|
101
107
|
generate();
|
|
102
108
|
|
|
103
109
|
propagateOnMemberLevel();
|
|
@@ -128,7 +134,7 @@ module.exports = (csn, options) => {
|
|
|
128
134
|
* `@Core.Computed' must be calculated manually as this annotation
|
|
129
135
|
* is not set in the universal csn flavor.
|
|
130
136
|
*/
|
|
131
|
-
setCoreComputedOnViews( csn );
|
|
137
|
+
setCoreComputedOnViews( csn, csnUtils );
|
|
132
138
|
/**
|
|
133
139
|
* Construct an extensions object which maps a built-in type to it's annotations
|
|
134
140
|
*/
|
|
@@ -399,8 +405,10 @@ module.exports = (csn, options) => {
|
|
|
399
405
|
|
|
400
406
|
const chain = getOriginChain(art);
|
|
401
407
|
|
|
402
|
-
if (chain.length)
|
|
403
|
-
chain.reverse()
|
|
408
|
+
if (chain.length) {
|
|
409
|
+
chain.reverse();
|
|
410
|
+
chain.forEach(chainLink => definitionPropagation(chainLink.target, chainLink.origin, chain[0].origin));
|
|
411
|
+
}
|
|
404
412
|
|
|
405
413
|
/**
|
|
406
414
|
* @param {CSN.Element} targetDefinition
|
package/lib/utils/timetrace.js
CHANGED
|
@@ -68,7 +68,7 @@ class StopWatch {
|
|
|
68
68
|
*
|
|
69
69
|
* Results are logged to stderr
|
|
70
70
|
*
|
|
71
|
-
* To enable time tracing, set
|
|
71
|
+
* To enable time tracing, set CDSC_TRACE_TIME to true in the environment
|
|
72
72
|
*
|
|
73
73
|
* @class TimeTracer
|
|
74
74
|
*/
|
|
@@ -150,7 +150,7 @@ const ignoreTimeTrace = {
|
|
|
150
150
|
reset: () => { /* ignore */ },
|
|
151
151
|
};
|
|
152
152
|
|
|
153
|
-
const doTimeTrace = process
|
|
153
|
+
const doTimeTrace = process?.env?.CDSC_TRACE_TIME !== undefined;
|
|
154
154
|
module.exports = {
|
|
155
155
|
timetrace: (doTimeTrace ? new TimeTracer() : ignoreTimeTrace),
|
|
156
156
|
TimeTracer,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sap/cds-compiler",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.6.0",
|
|
4
4
|
"description": "CDS (Core Data Services) compiler and backends",
|
|
5
5
|
"homepage": "https://cap.cloud.sap/",
|
|
6
6
|
"author": "SAP SE (https://www.sap.com)",
|
|
@@ -16,7 +16,6 @@
|
|
|
16
16
|
"scripts": {
|
|
17
17
|
"download": "node scripts/downloadANTLR.js",
|
|
18
18
|
"gen": "node ./scripts/build.js && node scripts/genGrammarChecksum.js",
|
|
19
|
-
"xmakeBeforeInstall": "echo \"Due to binary mirror, use sqlite 5.1.2 explicitly\" && npm install --save --save-exact --no-package-lock sqlite3@5.1.2",
|
|
20
19
|
"xmakeAfterInstall": "npm run gen",
|
|
21
20
|
"xmakePrepareRelease": "echo \"$(node scripts/stripReadme.js README.md)\" > README.md && node scripts/assertSnapshotVersioning.js && node scripts/assertChangelog.js && node scripts/cleanup.js --remove-dev",
|
|
22
21
|
"test": "node scripts/verifyGrammarChecksum.js && mocha --reporter min --reporter-option maxDiffSize=0 scripts/testLazyLoading.js && mocha --parallel --reporter min --reporter-option maxDiffSize=0 test/ test3/",
|