@sap/cds-compiler 3.4.4 → 3.5.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 +58 -0
- package/README.md +1 -0
- package/bin/cds_update_identifiers.js +5 -5
- package/bin/cdsc.js +12 -12
- package/doc/CHANGELOG_ARCHIVE.md +1 -1
- package/doc/CHANGELOG_BETA.md +9 -1
- package/doc/CHANGELOG_DEPRECATED.md +2 -0
- package/lib/api/main.js +58 -59
- package/lib/api/options.js +4 -2
- package/lib/api/validate.js +2 -2
- package/lib/base/cleanSymbols.js +2 -3
- package/lib/base/dictionaries.js +6 -6
- package/lib/base/error.js +2 -2
- package/lib/base/keywords.js +6 -6
- package/lib/base/location.js +11 -12
- package/lib/base/message-registry.js +124 -28
- package/lib/base/messages.js +247 -179
- package/lib/base/model.js +14 -11
- package/lib/base/node-helpers.js +9 -10
- package/lib/base/optionProcessorHelper.js +138 -129
- package/lib/checks/actionsFunctions.js +5 -5
- package/lib/checks/annotationsOData.js +4 -4
- package/lib/checks/arrayOfs.js +1 -1
- package/lib/checks/cdsPersistence.js +1 -1
- package/lib/checks/checkForTypes.js +3 -3
- package/lib/checks/defaultValues.js +3 -3
- package/lib/checks/elements.js +7 -7
- package/lib/checks/emptyOrOnlyVirtual.js +2 -2
- package/lib/checks/foreignKeys.js +1 -1
- package/lib/checks/invalidTarget.js +4 -4
- package/lib/checks/managedInType.js +1 -1
- package/lib/checks/managedWithoutKeys.js +1 -1
- package/lib/checks/nonexpandableStructured.js +5 -3
- package/lib/checks/nullableKeys.js +1 -1
- package/lib/checks/onConditions.js +5 -6
- package/lib/checks/parameters.js +1 -1
- package/lib/checks/queryNoDbArtifacts.js +2 -2
- package/lib/checks/selectItems.js +4 -4
- package/lib/checks/sql-snippets.js +4 -4
- package/lib/checks/types.js +7 -7
- package/lib/checks/utils.js +4 -4
- package/lib/checks/validator.js +16 -13
- package/lib/compiler/.eslintrc.json +1 -1
- package/lib/compiler/assert-consistency.js +0 -1
- package/lib/compiler/builtins.js +1 -1
- package/lib/compiler/checks.js +73 -15
- package/lib/compiler/define.js +3 -7
- package/lib/compiler/extend.js +212 -32
- package/lib/compiler/finalize-parse-cdl.js +7 -2
- package/lib/compiler/index.js +17 -14
- package/lib/compiler/populate.js +2 -5
- package/lib/compiler/propagator.js +2 -0
- package/lib/compiler/shared.js +23 -12
- package/lib/compiler/tweak-assocs.js +5 -6
- package/lib/compiler/utils.js +6 -0
- package/lib/edm/annotations/genericTranslation.js +553 -319
- package/lib/edm/annotations/preprocessAnnotations.js +39 -35
- package/lib/edm/csn2edm.js +88 -75
- package/lib/edm/edm.js +17 -3
- package/lib/edm/edmAnnoPreprocessor.js +5 -5
- package/lib/edm/edmPreprocessor.js +106 -76
- package/lib/edm/edmUtils.js +41 -2
- package/lib/gen/Dictionary.json +34 -0
- package/lib/gen/language.checksum +1 -1
- package/lib/gen/language.interp +66 -63
- package/lib/gen/language.tokens +81 -81
- package/lib/gen/languageLexer.interp +4 -10
- package/lib/gen/languageLexer.js +854 -869
- package/lib/gen/languageLexer.tokens +79 -81
- package/lib/gen/languageParser.js +14360 -14146
- package/lib/inspect/inspectModelStatistics.js +2 -2
- package/lib/inspect/inspectPropagation.js +6 -6
- package/lib/inspect/inspectUtils.js +2 -2
- package/lib/json/from-csn.js +82 -40
- package/lib/json/to-csn.js +82 -157
- package/lib/language/.eslintrc.json +1 -4
- package/lib/language/genericAntlrParser.js +59 -38
- package/lib/language/language.g4 +1508 -1490
- package/lib/language/multiLineStringParser.js +1 -1
- package/lib/main.js +3 -3
- package/lib/model/csnUtils.js +130 -122
- package/lib/model/revealInternalProperties.js +1 -1
- package/lib/model/sortViews.js +4 -6
- package/lib/modelCompare/utils/filter.js +4 -3
- package/lib/optionProcessor.js +5 -0
- package/lib/render/DuplicateChecker.js +1 -1
- package/lib/render/manageConstraints.js +12 -12
- package/lib/render/toCdl.js +225 -159
- package/lib/render/toHdbcds.js +63 -63
- package/lib/render/toRename.js +5 -5
- package/lib/render/toSql.js +55 -65
- package/lib/render/utils/common.js +20 -37
- package/lib/render/utils/delta.js +3 -3
- package/lib/render/utils/sql.js +22 -6
- package/lib/render/utils/stringEscapes.js +3 -3
- package/lib/transform/db/applyTransformations.js +3 -3
- package/lib/transform/db/assertUnique.js +13 -12
- package/lib/transform/db/associations.js +5 -5
- package/lib/transform/db/cdsPersistence.js +10 -8
- package/lib/transform/db/constraints.js +14 -14
- package/lib/transform/db/expansion.js +20 -22
- package/lib/transform/db/flattening.js +24 -42
- package/lib/transform/db/groupByOrderBy.js +3 -3
- package/lib/transform/db/temporal.js +6 -6
- package/lib/transform/db/transformExists.js +23 -23
- package/lib/transform/db/views.js +16 -16
- package/lib/transform/draft/db.js +10 -10
- package/lib/transform/draft/odata.js +2 -2
- package/lib/transform/forOdataNew.js +12 -40
- package/lib/transform/forRelationalDB.js +17 -7
- package/lib/transform/localized.js +2 -2
- package/lib/transform/odata/toFinalBaseType.js +41 -27
- package/lib/transform/odata/typesExposure.js +106 -62
- package/lib/transform/parseExpr.js +209 -106
- package/lib/transform/transformUtilsNew.js +2 -2
- package/lib/transform/translateAssocsToJoins.js +24 -19
- package/lib/transform/universalCsn/coreComputed.js +10 -10
- package/lib/transform/universalCsn/universalCsnEnricher.js +26 -26
- package/lib/transform/universalCsn/utils.js +3 -3
- package/lib/utils/file.js +5 -5
- package/lib/utils/moduleResolve.js +13 -13
- package/lib/utils/objectUtils.js +6 -6
- package/lib/utils/term.js +5 -2
- package/lib/utils/timetrace.js +51 -24
- package/package.json +5 -7
- package/share/messages/check-proper-type-of.md +1 -1
- package/share/messages/message-explanations.json +1 -1
- package/share/messages/redirected-to-complex.md +4 -4
- package/share/messages/{syntax-expecting-integer.md → syntax-expecting-unsigned-int.md} +7 -4
package/lib/utils/objectUtils.js
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* @param {string} property
|
|
9
9
|
* @param {object} targetObj
|
|
10
10
|
*/
|
|
11
|
-
function copyPropIfExist(sourceObj, property, targetObj) {
|
|
11
|
+
function copyPropIfExist( sourceObj, property, targetObj ) {
|
|
12
12
|
if (sourceObj && property in sourceObj)
|
|
13
13
|
targetObj[property] = sourceObj[property];
|
|
14
14
|
}
|
|
@@ -21,7 +21,7 @@ function copyPropIfExist(sourceObj, property, targetObj) {
|
|
|
21
21
|
* @param {object} obj Object with prototype.
|
|
22
22
|
* @return {object} Object without prototype, i.e. a dict.
|
|
23
23
|
*/
|
|
24
|
-
function createDict(obj) {
|
|
24
|
+
function createDict( obj ) {
|
|
25
25
|
const dict = Object.create(null);
|
|
26
26
|
const keys = Object.keys(obj);
|
|
27
27
|
for (const key of keys)
|
|
@@ -33,9 +33,9 @@ function createDict(obj) {
|
|
|
33
33
|
* Loops over all elements in an object and calls the specified callback(key,obj)
|
|
34
34
|
*
|
|
35
35
|
* @param {object} obj
|
|
36
|
-
* @param {(string, object) => void} callback
|
|
36
|
+
* @param {(key: string, value: object) => void} callback
|
|
37
37
|
*/
|
|
38
|
-
function forEach(obj, callback) {
|
|
38
|
+
function forEach( obj, callback ) {
|
|
39
39
|
for (const key in obj) {
|
|
40
40
|
if (Object.prototype.hasOwnProperty.call(obj, key))
|
|
41
41
|
callback(key, obj[key]);
|
|
@@ -49,7 +49,7 @@ function forEach(obj, callback) {
|
|
|
49
49
|
* @param {object} o the object which values should be iterated
|
|
50
50
|
* @param {Function} callback
|
|
51
51
|
*/
|
|
52
|
-
function forEachValue(o, callback) {
|
|
52
|
+
function forEachValue( o, callback ) {
|
|
53
53
|
for (const key in o) {
|
|
54
54
|
if (Object.prototype.hasOwnProperty.call(o, key))
|
|
55
55
|
callback(o[key]);
|
|
@@ -63,7 +63,7 @@ function forEachValue(o, callback) {
|
|
|
63
63
|
* @param {object} o the object which keys should be iterated
|
|
64
64
|
* @param {Function} callback
|
|
65
65
|
*/
|
|
66
|
-
function forEachKey(o, callback) {
|
|
66
|
+
function forEachKey( o, callback ) {
|
|
67
67
|
for (const key in o) {
|
|
68
68
|
if (Object.prototype.hasOwnProperty.call(o, key))
|
|
69
69
|
callback(key);
|
package/lib/utils/term.js
CHANGED
|
@@ -33,11 +33,14 @@ const t = {
|
|
|
33
33
|
cyan: '\x1b[36m', // Foreground Cyan
|
|
34
34
|
};
|
|
35
35
|
|
|
36
|
-
|
|
36
|
+
/**
|
|
37
|
+
* @param {string|boolean} [useColor]
|
|
38
|
+
*/
|
|
39
|
+
function term( useColor = 'auto' ) {
|
|
37
40
|
let hasColor = hasColorShell;
|
|
38
41
|
changeColorMode(useColor);
|
|
39
42
|
|
|
40
|
-
function changeColorMode(mode) {
|
|
43
|
+
function changeColorMode( mode ) {
|
|
41
44
|
switch (mode) {
|
|
42
45
|
case false:
|
|
43
46
|
case 'never':
|
package/lib/utils/timetrace.js
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
const { CompilerAssertion } = require('../base/error');
|
|
4
|
+
|
|
5
|
+
function hrtimeToSec( dt ) {
|
|
6
|
+
const sec = (dt / BigInt('1000000000')).toString().padStart(2, ' ');
|
|
7
|
+
// first, get remaining ns, then convert to ms.
|
|
8
|
+
const msec = ((dt % BigInt('1000000000')) / BigInt('1000000')).toString().padStart(3, '0');
|
|
9
|
+
return [ sec, msec ];
|
|
10
|
+
}
|
|
11
|
+
|
|
3
12
|
/**
|
|
4
13
|
* A single StopWatch encapsulates the runtime of a selected code frame.
|
|
5
14
|
*
|
|
@@ -71,6 +80,20 @@ class TimeTracer {
|
|
|
71
80
|
*/
|
|
72
81
|
constructor() {
|
|
73
82
|
this.traceStack = [];
|
|
83
|
+
this.lastStop = null;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Reset the time tracer. Use this if an exception is thrown, because then
|
|
88
|
+
* start/end won't correctly match.
|
|
89
|
+
*
|
|
90
|
+
* @param {string} reason
|
|
91
|
+
*/
|
|
92
|
+
reset(reason) {
|
|
93
|
+
// eslint-disable-next-line no-console
|
|
94
|
+
console.error(`Reset TimeTrace: Stopping all timers because: ${ reason }`);
|
|
95
|
+
while (this.traceStack.length)
|
|
96
|
+
this.stop(this.traceStack[this.traceStack.length - 1].id);
|
|
74
97
|
}
|
|
75
98
|
|
|
76
99
|
/**
|
|
@@ -81,46 +104,50 @@ class TimeTracer {
|
|
|
81
104
|
* @memberOf TimeTracer
|
|
82
105
|
*/
|
|
83
106
|
start(id) {
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
107
|
+
// Get time between last stop and new start: Those sections were not tracked.
|
|
108
|
+
const [ sec, msec ] = this.lastStop ? hrtimeToSec(this.lastStop.stop()) : [ ' 0', '000' ];
|
|
109
|
+
this.lastStop = null;
|
|
110
|
+
let base = `${ ' '.repeat(this.traceStack.length * 2) }${ id } started:`;
|
|
111
|
+
base += ' '.repeat(60 - base.length);
|
|
112
|
+
if (sec !== ' 0' || msec !== '000')
|
|
88
113
|
// eslint-disable-next-line no-console
|
|
89
|
-
console.error(`${
|
|
90
|
-
|
|
91
|
-
catch (e) {
|
|
114
|
+
console.error( `${ base } ${ sec }s ${ msec }ms (since last stop)` );
|
|
115
|
+
else
|
|
92
116
|
// eslint-disable-next-line no-console
|
|
93
|
-
console.error(
|
|
94
|
-
|
|
117
|
+
console.error( `${ base }` );
|
|
118
|
+
this.traceStack.push(new StopWatch(id));
|
|
95
119
|
}
|
|
96
120
|
|
|
97
121
|
/**
|
|
98
122
|
* Stop the current TimeTrace and log the execution time.
|
|
99
123
|
*
|
|
100
|
-
*
|
|
124
|
+
* @param {string} id
|
|
101
125
|
* @memberOf TimeTracer
|
|
102
126
|
*/
|
|
103
|
-
stop() {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
}
|
|
114
|
-
catch (e) {
|
|
115
|
-
// eslint-disable-next-line no-console
|
|
116
|
-
console.error(`Stopping time trace failed: ${ e }`);
|
|
127
|
+
stop(id) {
|
|
128
|
+
if (this.traceStack.length === 0)
|
|
129
|
+
throw new CompilerAssertion('TimeTracer mismatch: called stop() too many times');
|
|
130
|
+
const current = this.traceStack.pop();
|
|
131
|
+
if (current.id !== id)
|
|
132
|
+
throw new CompilerAssertion(`TimeTracer mismatch; expected id: “${ id }”, was “${ current.id }”`);
|
|
133
|
+
let diff = '';
|
|
134
|
+
if (this.lastStop !== null) {
|
|
135
|
+
const [ sec, msec ] = hrtimeToSec(this.lastStop.stop());
|
|
136
|
+
if ( sec !== ' 0' || msec !== '000')
|
|
137
|
+
diff = ` (diff to last stop: ${ sec }s ${ msec }ms)`;
|
|
117
138
|
}
|
|
139
|
+
const [ sec, msec ] = hrtimeToSec(current.stop());
|
|
140
|
+
const base = `${ ' '.repeat(this.traceStack.length * 2) }${ current.id } took:`;
|
|
141
|
+
// eslint-disable-next-line no-console
|
|
142
|
+
console.error( `${ base }${ ' '.repeat(60 - base.length) } ${ sec }s ${ msec }ms${ diff }` );
|
|
143
|
+
this.lastStop = new StopWatch(id);
|
|
118
144
|
}
|
|
119
145
|
}
|
|
120
146
|
|
|
121
147
|
const ignoreTimeTrace = {
|
|
122
148
|
start: () => { /* ignore */ },
|
|
123
149
|
stop: () => { /* ignore */ },
|
|
150
|
+
reset: () => { /* ignore */ },
|
|
124
151
|
};
|
|
125
152
|
|
|
126
153
|
const doTimeTrace = process && process.env && process.env.CDSC_TIMETRACING !== undefined;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sap/cds-compiler",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.5.2",
|
|
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)",
|
|
@@ -21,16 +21,14 @@
|
|
|
21
21
|
"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
22
|
"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/",
|
|
23
23
|
"testverbose": "node scripts/verifyGrammarChecksum.js && mocha --parallel test/ test3/",
|
|
24
|
-
"test3": "node scripts/verifyGrammarChecksum.js &&
|
|
25
|
-
"deployTest3SQL": "deployRefs=true mocha --reporter-option maxDiffSize=0 test3/
|
|
24
|
+
"test3": "node scripts/verifyGrammarChecksum.js && mocha --reporter-option maxDiffSize=0 test3/",
|
|
25
|
+
"deployTest3SQL": "deployRefs=true mocha --reporter-option maxDiffSize=0 test3/test.deploy.hana-sql.js",
|
|
26
26
|
"deployTest3": "deployRefs=true mocha --reporter-option maxDiffSize=0 test3/testDeployment.js",
|
|
27
|
+
"deployHanaDeltaSQL": "CDS_COMPILER_DEPLOY_HANA=1 mocha test3/test.deploy.hana-sql.delta.js",
|
|
27
28
|
"deployDiffs": "deployRefs=true mocha --reporter-option maxDiffSize=0 test3/deployDiffs.js",
|
|
28
29
|
"gentest3": "cross-env MAKEREFS=${MAKEREFS:-'true'} mocha --reporter-option maxDiffSize=0 test3/testRefFiles.js",
|
|
29
|
-
"testdb": "node scripts/verifyGrammarChecksum.js && cross-env TESTDB='TRUE' mocha",
|
|
30
|
-
"testmigration": "npm install --no-save @sap/hana-client@2.3.123 @sap/hdi-deploy@3.10.0 && node scripts/verifyGrammarChecksum.js && cross-env TESTMIGRATION='TRUE' mocha",
|
|
31
|
-
"testall": "npm install --no-save @sap/hana-client@2.3.123 @sap/hdi-deploy@3.10.0 && node scripts/verifyGrammarChecksum.js && cross-env TESTDB='TRUE' TESTMIGRATION='TRUE' mocha",
|
|
32
30
|
"coverage": "cross-env nyc mocha --reporter-option maxDiffSize=0 test/ test3/ && nyc report --reporter=lcov",
|
|
33
|
-
"lint": "eslint bin/ benchmark/ lib/ test/ test3/ scripts/ types/ && node scripts/linter/lintGrammar.js && node scripts/linter/lintTests.js test3/ && node scripts/linter/lintMessageIdCoverage.js lib/ && markdownlint README.md CHANGELOG.md doc/ internalDoc/ && cd share/messages && markdownlint .",
|
|
31
|
+
"lint": "eslint bin/ benchmark/ lib/ test/ test3/ scripts/ types/ && node scripts/linter/lintGrammar.js && node scripts/linter/lintTests.js test3/ && node scripts/linter/lintMessages.js && node scripts/linter/lintMessageIdCoverage.js lib/ && markdownlint README.md CHANGELOG.md doc/ internalDoc/ && cd share/messages && markdownlint .",
|
|
34
32
|
"tslint": "tsc --pretty -p .",
|
|
35
33
|
"updateVocs": "node scripts/odataAnnotations/generateDictMain.js && npm run generateAllRefs",
|
|
36
34
|
"generateCompilerRefs": "cross-env MAKEREFS='true' mocha test/testCompiler.js",
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
The redirected target is a complex view, for example, contains a JOIN or UNION.
|
|
4
4
|
|
|
5
5
|
The message's severity is `Info` and is raised by the compiler.
|
|
6
|
-
It is emitted to help developers identify possible
|
|
6
|
+
It is emitted to help developers identify possible modeling issues.
|
|
7
7
|
|
|
8
8
|
## Example
|
|
9
9
|
|
|
@@ -33,7 +33,7 @@ The cross join in the view `CrossJoin` results in multiple rows with the same
|
|
|
33
33
|
`id`. Following the redirected view now returns multiple results, effectively
|
|
34
34
|
making the to-one association a to-many association.
|
|
35
35
|
|
|
36
|
-
Visualizing the tables with a bit of data, this
|
|
36
|
+
Visualizing the tables with a bit of data, this issue becomes obvious:
|
|
37
37
|
|
|
38
38
|
```markdown
|
|
39
39
|
Main Secondary
|
|
@@ -54,8 +54,8 @@ CrossJoin
|
|
|
54
54
|
## How to Fix
|
|
55
55
|
|
|
56
56
|
Ensure that the redirected association points to an entity that is a reasonable
|
|
57
|
-
redirection target.
|
|
58
|
-
|
|
57
|
+
redirection target. That means, the redirection target shouldn't accidentally
|
|
58
|
+
make it a to-many association.
|
|
59
59
|
|
|
60
60
|
## Related Messages
|
|
61
61
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
# syntax-expecting-
|
|
1
|
+
# syntax-expecting-unsigned-int
|
|
2
2
|
|
|
3
|
-
The compiler expects a safe integer here.
|
|
3
|
+
The compiler expects a safe non-negative integer here.
|
|
4
4
|
The last safe integer is `2^53 - 1` or `9007199254740991`.
|
|
5
5
|
|
|
6
6
|
A safe integer is an integer that fulfills all of the following:
|
|
@@ -34,5 +34,8 @@ type LengthIsSafe : String(9007199254740991);
|
|
|
34
34
|
type AnInteger : String(42);
|
|
35
35
|
```
|
|
36
36
|
|
|
37
|
-
|
|
38
|
-
|
|
37
|
+
At other places, using unsafe integers (or non-integer numbers) is allowed:
|
|
38
|
+
|
|
39
|
+
- Annotation values: The value is then simply a string.
|
|
40
|
+
- Expressions: The `val` property in the CSN contains a string
|
|
41
|
+
having a sibling `literal: 'number'`.
|