@sap/cds-compiler 2.7.0 → 2.11.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 +167 -0
- package/bin/cdsc.js +42 -25
- package/bin/cdsse.js +1 -0
- package/doc/CHANGELOG_BETA.md +10 -0
- package/lib/api/.eslintrc.json +2 -0
- package/lib/api/main.js +17 -33
- package/lib/api/options.js +25 -13
- package/lib/api/validate.js +33 -9
- package/lib/backends.js +9 -8
- package/lib/base/dictionaries.js +2 -1
- package/lib/base/keywords.js +32 -2
- package/lib/base/message-registry.js +26 -2
- package/lib/base/messages.js +25 -9
- package/lib/base/model.js +5 -3
- package/lib/base/optionProcessorHelper.js +56 -22
- package/lib/checks/onConditions.js +5 -0
- package/lib/checks/selectItems.js +4 -0
- package/lib/checks/types.js +26 -2
- package/lib/checks/unknownMagic.js +41 -0
- package/lib/checks/validator.js +7 -2
- package/lib/compiler/assert-consistency.js +18 -5
- package/lib/compiler/base.js +65 -0
- package/lib/compiler/builtins.js +30 -1
- package/lib/compiler/checks.js +5 -2
- package/lib/compiler/definer.js +145 -120
- package/lib/compiler/index.js +16 -4
- package/lib/compiler/propagator.js +5 -2
- package/lib/compiler/resolver.js +207 -47
- package/lib/compiler/shared.js +47 -200
- package/lib/compiler/utils.js +173 -0
- package/lib/edm/annotations/genericTranslation.js +183 -187
- package/lib/edm/csn2edm.js +94 -98
- package/lib/edm/edm.js +16 -20
- package/lib/edm/edmPreprocessor.js +302 -115
- package/lib/edm/edmUtils.js +31 -12
- package/lib/gen/language.checksum +1 -1
- package/lib/gen/language.interp +28 -1
- package/lib/gen/language.tokens +79 -69
- package/lib/gen/languageLexer.interp +28 -1
- package/lib/gen/languageLexer.js +879 -805
- package/lib/gen/languageLexer.tokens +71 -62
- package/lib/gen/languageParser.js +5308 -4308
- package/lib/json/from-csn.js +59 -30
- package/lib/json/to-csn.js +354 -105
- package/lib/language/antlrParser.js +11 -0
- package/lib/language/errorStrategy.js +1 -0
- package/lib/language/genericAntlrParser.js +81 -14
- package/lib/language/language.g4 +163 -31
- package/lib/main.d.ts +136 -17
- package/lib/main.js +7 -1
- package/lib/model/api.js +78 -0
- package/lib/model/csnRefs.js +115 -32
- package/lib/model/csnUtils.js +71 -33
- package/lib/model/enrichCsn.js +36 -9
- package/lib/model/revealInternalProperties.js +20 -4
- package/lib/modelCompare/compare.js +2 -1
- package/lib/optionProcessor.js +33 -16
- package/lib/render/.eslintrc.json +3 -1
- package/lib/render/DuplicateChecker.js +1 -1
- package/lib/render/toCdl.js +60 -17
- package/lib/render/toHdbcds.js +122 -74
- package/lib/render/toSql.js +57 -32
- package/lib/render/utils/common.js +6 -10
- package/lib/sql-identifier.js +6 -1
- package/lib/transform/db/constraints.js +273 -119
- package/lib/transform/db/draft.js +9 -6
- package/lib/transform/db/expansion.js +19 -7
- package/lib/transform/db/flattening.js +31 -7
- package/lib/transform/db/transformExists.js +344 -66
- package/lib/transform/db/views.js +438 -0
- package/lib/transform/forHanaNew.js +65 -436
- package/lib/transform/forOdataNew.js +21 -10
- package/lib/transform/localized.js +2 -0
- package/lib/transform/odata/attachPath.js +19 -4
- package/lib/transform/odata/generateForeignKeyElements.js +11 -10
- package/lib/transform/odata/referenceFlattener.js +44 -38
- package/lib/transform/odata/sortByAssociationDependency.js +2 -2
- package/lib/transform/odata/structuralPath.js +72 -0
- package/lib/transform/odata/structureFlattener.js +13 -10
- package/lib/transform/odata/typesExposure.js +22 -12
- package/lib/transform/transformUtilsNew.js +55 -9
- package/lib/transform/translateAssocsToJoins.js +11 -17
- package/lib/transform/universalCsnEnricher.js +67 -0
- package/lib/utils/file.js +5 -3
- package/lib/utils/term.js +65 -42
- package/lib/utils/timetrace.js +48 -26
- package/package.json +1 -1
package/lib/json/from-csn.js
CHANGED
|
@@ -145,7 +145,7 @@ const schemaClasses = {
|
|
|
145
145
|
type: natnumOrStar,
|
|
146
146
|
msgId: 'syntax-csn-expected-cardinality',
|
|
147
147
|
},
|
|
148
|
-
|
|
148
|
+
columns: {
|
|
149
149
|
arrayOf: selectItem,
|
|
150
150
|
msgId: 'syntax-csn-expected-column',
|
|
151
151
|
defaultKind: '$column',
|
|
@@ -238,15 +238,15 @@ const schema = compileSchema( {
|
|
|
238
238
|
validKinds: [],
|
|
239
239
|
},
|
|
240
240
|
columns: {
|
|
241
|
-
class: '
|
|
241
|
+
class: 'columns',
|
|
242
242
|
inKind: [ 'extend' ], // only valid in extend and SELECT/projection
|
|
243
243
|
},
|
|
244
244
|
expand: {
|
|
245
|
-
class: '
|
|
245
|
+
class: 'columns',
|
|
246
246
|
inKind: [ '$column' ], // only valid in $column
|
|
247
247
|
},
|
|
248
248
|
inline: {
|
|
249
|
-
class: '
|
|
249
|
+
class: 'columns',
|
|
250
250
|
inKind: [ '$column' ], // only valid in $column
|
|
251
251
|
},
|
|
252
252
|
keys: {
|
|
@@ -272,7 +272,7 @@ const schema = compileSchema( {
|
|
|
272
272
|
},
|
|
273
273
|
annotate: {
|
|
274
274
|
type: kindAndName,
|
|
275
|
-
inKind:
|
|
275
|
+
inKind: [ 'annotate' ],
|
|
276
276
|
},
|
|
277
277
|
extend: {
|
|
278
278
|
type: kindAndName,
|
|
@@ -326,7 +326,7 @@ const schema = compileSchema( {
|
|
|
326
326
|
inKind: [ 'element', 'type', 'param', 'annotation' ],
|
|
327
327
|
},
|
|
328
328
|
scale: {
|
|
329
|
-
type:
|
|
329
|
+
type: scalenum,
|
|
330
330
|
inKind: [ 'element', 'type', 'param', 'annotation' ],
|
|
331
331
|
},
|
|
332
332
|
srid: {
|
|
@@ -609,10 +609,10 @@ const schema = compileSchema( {
|
|
|
609
609
|
inKind: [ 'entity', 'type', 'aspect', 'event', 'extend' ],
|
|
610
610
|
},
|
|
611
611
|
returns: {
|
|
612
|
-
type:
|
|
612
|
+
type: returnsDefinition,
|
|
613
613
|
defaultKind: 'param',
|
|
614
614
|
validKinds: [ 'param' ],
|
|
615
|
-
inKind: [ 'action', 'function' ],
|
|
615
|
+
inKind: [ 'action', 'function', 'annotate' ],
|
|
616
616
|
},
|
|
617
617
|
technicalConfig: { // treat it like external_property
|
|
618
618
|
type: extra,
|
|
@@ -739,14 +739,15 @@ function compileSchema( specs, proto = null) {
|
|
|
739
739
|
throw new Error( `Missing type specification for property "${ p }"` );
|
|
740
740
|
}
|
|
741
741
|
}
|
|
742
|
-
|
|
743
|
-
return r;
|
|
742
|
+
// Set property 'xorGroup' in main and sub schema:
|
|
744
743
|
for (const group in xorGroups) {
|
|
745
744
|
for (const prop of xorGroups[group]) {
|
|
746
745
|
if (r[prop].xorGroup === undefined)
|
|
747
746
|
r[prop].xorGroup = group;
|
|
748
747
|
}
|
|
749
748
|
}
|
|
749
|
+
if (proto)
|
|
750
|
+
return r;
|
|
750
751
|
for (const prop of exprProperties) {
|
|
751
752
|
if (r[prop].inValue === undefined)
|
|
752
753
|
r[prop].inValue = true;
|
|
@@ -772,12 +773,8 @@ function arrayOf( fn, filter = undefined ) {
|
|
|
772
773
|
} );
|
|
773
774
|
const minLength = spec.minLength || 0;
|
|
774
775
|
if (minLength > val.length) {
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
{
|
|
778
|
-
std: 'Expected array in $(PROP) to have at least $(N) items',
|
|
779
|
-
one: 'Expected array in $(PROP) to have at least one item',
|
|
780
|
-
} );
|
|
776
|
+
message( 'syntax-csn-expected-length', location(true),
|
|
777
|
+
{ prop: spec.prop, n: minLength, '#': minLength === 1 ? 'one' : 'std' });
|
|
781
778
|
}
|
|
782
779
|
if (val.length)
|
|
783
780
|
++virtualLine; // [] in one JSON line
|
|
@@ -912,7 +909,7 @@ function definition( def, spec, xsn, csn, name ) {
|
|
|
912
909
|
++virtualLine;
|
|
913
910
|
}
|
|
914
911
|
}
|
|
915
|
-
if (!r.name && name) {
|
|
912
|
+
if (!r.name && name != null) {
|
|
916
913
|
r.name = { id: name, location: r.location };
|
|
917
914
|
if (prop === 'columns' || prop === 'keys' || prop === 'foreignKeys')
|
|
918
915
|
r.name.$inferred = 'as';
|
|
@@ -944,7 +941,10 @@ function definition( def, spec, xsn, csn, name ) {
|
|
|
944
941
|
return s.inKind && s.inKind( kind, spec );
|
|
945
942
|
return s.inKind.includes( kind ) &&
|
|
946
943
|
// for an 'annotate', both 'annotate' and the "host" kind must be expected
|
|
947
|
-
(!inExtensions || s.inKind.includes( inExtensions )
|
|
944
|
+
(!inExtensions || s.inKind.includes( inExtensions ) ||
|
|
945
|
+
// extending elements in returns can be without 'returns' in CSN
|
|
946
|
+
// TODO: with warning/info?
|
|
947
|
+
inExtensions === 'action' && p === 'elements');
|
|
948
948
|
}
|
|
949
949
|
}
|
|
950
950
|
|
|
@@ -992,12 +992,23 @@ function keys( array, spec, xsn ) {
|
|
|
992
992
|
}
|
|
993
993
|
|
|
994
994
|
function selectItem( def, spec, xsn, csn ) {
|
|
995
|
-
if (def === '*')
|
|
995
|
+
if (def === '*') // compile() will complain about repeated '*'s
|
|
996
996
|
return { val: '*', location: location() };
|
|
997
997
|
|
|
998
998
|
return definition( def, spec, xsn, csn, null ); // definer sets name
|
|
999
999
|
}
|
|
1000
1000
|
|
|
1001
|
+
function returnsDefinition( def, spec, xsn, csn ) {
|
|
1002
|
+
// TODO: be stricter in what is allowed inside returns
|
|
1003
|
+
if (!inExtensions)
|
|
1004
|
+
return definition( def, spec, xsn, csn, '' );
|
|
1005
|
+
// for the moment, flatten elements in returns in an annotate
|
|
1006
|
+
// TODO: bigger Core Compiler changes would have to be done otherwise
|
|
1007
|
+
xsn.elements = definition( def, spec, xsn, csn, '' ).elements;
|
|
1008
|
+
xsn.$syntax = 'returns';
|
|
1009
|
+
return undefined;
|
|
1010
|
+
}
|
|
1011
|
+
|
|
1001
1012
|
// For v1 CSNs with annotation definitions
|
|
1002
1013
|
function attachVocabInDefinitions( csn ) {
|
|
1003
1014
|
if (!csn.vocabularies) {
|
|
@@ -1124,6 +1135,12 @@ function stringValOrNull( val, spec ) {
|
|
|
1124
1135
|
return stringVal(val, spec);
|
|
1125
1136
|
}
|
|
1126
1137
|
|
|
1138
|
+
function scalenum( val, spec ) {
|
|
1139
|
+
if ([ 'floating', 'variable' ].includes(val))
|
|
1140
|
+
return { val, literal: 'string', location: location() };
|
|
1141
|
+
return natnum(val, spec );
|
|
1142
|
+
}
|
|
1143
|
+
|
|
1127
1144
|
function natnum( val, spec ) {
|
|
1128
1145
|
if (typeof val === 'number' && val >= 0)
|
|
1129
1146
|
// XSN TODO: do not require literal
|
|
@@ -1248,9 +1265,18 @@ function func( val, spec, xsn ) {
|
|
|
1248
1265
|
return { path: [ { id: val, location: location() } ], location: location() };
|
|
1249
1266
|
}
|
|
1250
1267
|
|
|
1251
|
-
function xpr( exprs, spec, xsn ) {
|
|
1252
|
-
|
|
1253
|
-
|
|
1268
|
+
function xpr( exprs, spec, xsn, csn ) {
|
|
1269
|
+
if (csn.func) {
|
|
1270
|
+
if (!exprs.length) {
|
|
1271
|
+
message( 'syntax-csn-expected-length', location(true),
|
|
1272
|
+
{ prop: 'xpr', otherprop: 'func', '#': 'suffix' });
|
|
1273
|
+
}
|
|
1274
|
+
xsn.suffix = exprArgs( exprs, spec );
|
|
1275
|
+
}
|
|
1276
|
+
else {
|
|
1277
|
+
xsn.op = { val: 'xpr', location: location() };
|
|
1278
|
+
xsn.args = exprArgs( exprs, spec, xsn );
|
|
1279
|
+
}
|
|
1254
1280
|
}
|
|
1255
1281
|
|
|
1256
1282
|
function list( exprs, spec, xsn ) {
|
|
@@ -1258,15 +1284,15 @@ function list( exprs, spec, xsn ) {
|
|
|
1258
1284
|
xsn.args = arrayOf( exprOrString )( exprs, spec, xsn );
|
|
1259
1285
|
}
|
|
1260
1286
|
|
|
1261
|
-
function xprInValue( exprs, spec, xsn ) {
|
|
1287
|
+
function xprInValue( exprs, spec, xsn, csn ) {
|
|
1262
1288
|
// if the top-level xpr is just for a cast:
|
|
1263
1289
|
if (exprs.length === 1 && exprs[0].cast) {
|
|
1264
1290
|
const x = {};
|
|
1265
|
-
xpr( exprs, spec, x );
|
|
1291
|
+
xpr( exprs, spec, x, csn );
|
|
1266
1292
|
Object.assign( xsn, x.args[0] );
|
|
1267
1293
|
}
|
|
1268
1294
|
else {
|
|
1269
|
-
xpr( exprs, spec, xsn );
|
|
1295
|
+
xpr( exprs, spec, xsn, csn );
|
|
1270
1296
|
}
|
|
1271
1297
|
}
|
|
1272
1298
|
|
|
@@ -1315,9 +1341,9 @@ function exprOrString( e, spec ) {
|
|
|
1315
1341
|
}
|
|
1316
1342
|
|
|
1317
1343
|
// mark path argument of 'exits' predicate with $expected:'exists'
|
|
1318
|
-
function
|
|
1319
|
-
const rxsn = arrayOf( exprOrString )(cond, spec, xsn, csn);
|
|
1320
|
-
if (Array.isArray(rxsn) && rxsn.some(x => x === 'exists')) {
|
|
1344
|
+
function exprArgs( cond, spec, xsn, csn ) {
|
|
1345
|
+
const rxsn = arrayOf( exprOrString )( cond, spec, xsn, csn );
|
|
1346
|
+
if (Array.isArray( rxsn ) && rxsn.some( x => x === 'exists' )) {
|
|
1321
1347
|
for (let i = 0; i < rxsn.length - 1; i++) {
|
|
1322
1348
|
if (rxsn[i] === 'exists' && rxsn[i + 1].path)
|
|
1323
1349
|
rxsn[++i].$expected = 'exists';
|
|
@@ -1330,7 +1356,7 @@ function condition( cond, spec ) {
|
|
|
1330
1356
|
const loc = location();
|
|
1331
1357
|
const x = {
|
|
1332
1358
|
op: { val: 'xpr', location: loc },
|
|
1333
|
-
args:
|
|
1359
|
+
args: exprArgs( cond, spec ),
|
|
1334
1360
|
location: loc,
|
|
1335
1361
|
};
|
|
1336
1362
|
return x;
|
|
@@ -1500,7 +1526,7 @@ function calculateKind( def, spec ) {
|
|
|
1500
1526
|
return 'annotate';
|
|
1501
1527
|
}
|
|
1502
1528
|
if (spec.prop === 'extensions') {
|
|
1503
|
-
inExtensions = (def.extend) ? '' : '
|
|
1529
|
+
inExtensions = (def.extend) ? '' : 'annotate';
|
|
1504
1530
|
return (def.extend) ? 'extend' : 'annotate';
|
|
1505
1531
|
}
|
|
1506
1532
|
const kind = (def.kind === 'view') ? 'entity' : def.kind; // 'view' is CSN v0.1.0
|
|
@@ -1556,6 +1582,9 @@ function checkAndSetXorGroup( group, prop, xor ) {
|
|
|
1556
1582
|
xor[group] = prop;
|
|
1557
1583
|
return true;
|
|
1558
1584
|
}
|
|
1585
|
+
if (prop === 'func' && xor[group] === 'xpr' ||
|
|
1586
|
+
prop === 'xpr' && xor[group] === 'func')
|
|
1587
|
+
return true; // hack for window function: both func and xpr is allowed
|
|
1559
1588
|
error( 'syntax-csn-excluded-property', location(true),
|
|
1560
1589
|
{ prop, otherprop: xor[group] },
|
|
1561
1590
|
'CSN property $(PROP) can only be used alternatively to $(OTHERPROP)');
|