@sap/cds-compiler 2.11.2 → 2.13.6
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 +175 -2
- package/bin/.eslintrc.json +1 -2
- package/bin/cds_update_identifiers.js +10 -8
- package/bin/cdsc.js +23 -17
- package/bin/cdsse.js +2 -2
- package/bin/cdsv2m.js +3 -2
- package/doc/CHANGELOG_ARCHIVE.md +1 -1
- package/doc/CHANGELOG_BETA.md +25 -6
- package/doc/CHANGELOG_DEPRECATED.md +22 -6
- package/doc/NameResolution.md +21 -16
- package/lib/api/main.js +32 -79
- package/lib/api/options.js +3 -2
- package/lib/api/validate.js +2 -1
- package/lib/backends.js +16 -26
- package/lib/base/dictionaries.js +0 -8
- package/lib/base/error.js +26 -0
- package/lib/base/keywords.js +10 -19
- package/lib/base/location.js +9 -4
- package/lib/base/message-registry.js +75 -9
- package/lib/base/messages.js +31 -35
- package/lib/base/model.js +2 -62
- package/lib/base/optionProcessorHelper.js +246 -183
- package/lib/checks/.eslintrc.json +2 -0
- package/lib/checks/actionsFunctions.js +2 -1
- package/lib/checks/annotationsOData.js +1 -1
- package/lib/checks/cdsPersistence.js +2 -1
- package/lib/checks/emptyOrOnlyVirtual.js +2 -2
- package/lib/checks/enricher.js +17 -1
- package/lib/checks/foreignKeys.js +4 -4
- package/lib/checks/invalidTarget.js +3 -1
- package/lib/checks/managedInType.js +4 -4
- package/lib/checks/managedWithoutKeys.js +3 -1
- package/lib/checks/queryNoDbArtifacts.js +1 -3
- package/lib/checks/selectItems.js +4 -4
- package/lib/checks/sql-snippets.js +94 -0
- package/lib/checks/types.js +1 -1
- package/lib/checks/unknownMagic.js +1 -1
- package/lib/checks/validator.js +12 -7
- package/lib/compiler/assert-consistency.js +12 -8
- package/lib/compiler/base.js +0 -1
- package/lib/compiler/builtins.js +42 -21
- package/lib/compiler/checks.js +46 -12
- package/lib/compiler/cycle-detector.js +1 -1
- package/lib/compiler/define.js +1103 -0
- package/lib/compiler/extend.js +983 -0
- package/lib/compiler/finalize-parse-cdl.js +231 -0
- package/lib/compiler/index.js +46 -39
- package/lib/compiler/kick-start.js +190 -0
- package/lib/compiler/moduleLayers.js +4 -4
- package/lib/compiler/populate.js +1226 -0
- package/lib/compiler/propagator.js +113 -47
- package/lib/compiler/resolve.js +1433 -0
- package/lib/compiler/shared.js +100 -65
- package/lib/compiler/tweak-assocs.js +529 -0
- package/lib/compiler/utils.js +215 -33
- package/lib/edm/.eslintrc.json +5 -0
- package/lib/edm/annotations/genericTranslation.js +38 -25
- package/lib/edm/annotations/preprocessAnnotations.js +3 -3
- package/lib/edm/csn2edm.js +10 -9
- package/lib/edm/edm.js +19 -20
- package/lib/edm/edmPreprocessor.js +166 -95
- package/lib/edm/edmUtils.js +127 -34
- package/lib/gen/Dictionary.json +92 -43
- package/lib/gen/language.checksum +1 -1
- package/lib/gen/language.interp +11 -1
- package/lib/gen/language.tokens +86 -82
- package/lib/gen/languageLexer.interp +18 -1
- package/lib/gen/languageLexer.js +925 -847
- package/lib/gen/languageLexer.tokens +78 -74
- package/lib/gen/languageParser.js +5434 -4298
- package/lib/json/from-csn.js +59 -17
- package/lib/json/to-csn.js +189 -71
- package/lib/language/antlrParser.js +3 -3
- package/lib/language/docCommentParser.js +3 -3
- package/lib/language/errorStrategy.js +26 -8
- package/lib/language/genericAntlrParser.js +144 -53
- package/lib/language/language.g4 +424 -200
- package/lib/language/multiLineStringParser.js +536 -0
- package/lib/main.d.ts +550 -61
- package/lib/main.js +38 -11
- package/lib/model/api.js +3 -1
- package/lib/model/csnRefs.js +322 -198
- package/lib/model/csnUtils.js +226 -370
- package/lib/model/enrichCsn.js +124 -69
- package/lib/model/revealInternalProperties.js +29 -7
- package/lib/model/sortViews.js +10 -2
- package/lib/modelCompare/compare.js +17 -12
- package/lib/optionProcessor.js +8 -3
- package/lib/render/.eslintrc.json +1 -2
- package/lib/render/DuplicateChecker.js +1 -1
- package/lib/render/manageConstraints.js +36 -33
- package/lib/render/toCdl.js +174 -275
- package/lib/render/toHdbcds.js +203 -122
- package/lib/render/toRename.js +7 -10
- package/lib/render/toSql.js +161 -82
- package/lib/render/utils/common.js +22 -8
- package/lib/render/utils/sql.js +10 -7
- package/lib/render/utils/stringEscapes.js +111 -0
- package/lib/sql-identifier.js +1 -1
- package/lib/transform/.eslintrc.json +5 -0
- package/lib/transform/braceExpression.js +4 -2
- package/lib/transform/db/.eslintrc.json +2 -0
- package/lib/transform/db/applyTransformations.js +212 -0
- package/lib/transform/db/assertUnique.js +1 -1
- package/lib/transform/db/associations.js +187 -0
- package/lib/transform/db/cdsPersistence.js +150 -0
- package/lib/transform/db/constraints.js +61 -56
- package/lib/transform/db/expansion.js +50 -29
- package/lib/transform/db/flattening.js +556 -106
- package/lib/transform/db/groupByOrderBy.js +3 -1
- package/lib/transform/db/temporal.js +236 -0
- package/lib/transform/db/transformExists.js +103 -28
- package/lib/transform/db/views.js +92 -44
- package/lib/transform/draft/.eslintrc.json +38 -0
- package/lib/transform/{db/draft.js → draft/db.js} +9 -7
- package/lib/transform/draft/odata.js +227 -0
- package/lib/transform/forHanaNew.js +98 -783
- package/lib/transform/forOdataNew.js +22 -175
- package/lib/transform/localized.js +36 -32
- package/lib/transform/odata/generateForeignKeyElements.js +3 -3
- package/lib/transform/odata/referenceFlattener.js +95 -89
- package/lib/transform/odata/structureFlattener.js +1 -1
- package/lib/transform/odata/toFinalBaseType.js +86 -12
- package/lib/transform/odata/typesExposure.js +5 -5
- package/lib/transform/odata/utils.js +2 -2
- package/lib/transform/transformUtilsNew.js +47 -33
- package/lib/transform/translateAssocsToJoins.js +13 -30
- package/lib/transform/universalCsn/.eslintrc.json +36 -0
- package/lib/transform/universalCsn/coreComputed.js +170 -0
- package/lib/transform/universalCsn/universalCsnEnricher.js +715 -0
- package/lib/transform/universalCsn/utils.js +63 -0
- package/lib/utils/file.js +8 -3
- package/lib/utils/objectUtils.js +30 -0
- package/lib/utils/timetrace.js +8 -2
- package/package.json +1 -1
- package/share/messages/README.md +26 -0
- package/lib/compiler/definer.js +0 -2349
- package/lib/compiler/resolver.js +0 -2922
- package/lib/transform/db/helpers.js +0 -58
- package/lib/transform/universalCsnEnricher.js +0 -67
package/lib/json/from-csn.js
CHANGED
|
@@ -89,6 +89,8 @@
|
|
|
89
89
|
|
|
90
90
|
const { dictAdd } = require('../base/dictionaries');
|
|
91
91
|
|
|
92
|
+
const $location = Symbol.for('cds.$location');
|
|
93
|
+
|
|
92
94
|
let inExtensions = null;
|
|
93
95
|
|
|
94
96
|
let vocabInDefinitions = null; // must be reset!
|
|
@@ -661,6 +663,9 @@ const schema = compileSchema( {
|
|
|
661
663
|
ignore: true, type: ignore,
|
|
662
664
|
},
|
|
663
665
|
// TODO: should we keep $parens ?
|
|
666
|
+
$generated: {
|
|
667
|
+
type: string,
|
|
668
|
+
},
|
|
664
669
|
$: { type: ignore, ignore: true }, // including $origin
|
|
665
670
|
_: { type: ignore, ignore: true },
|
|
666
671
|
} );
|
|
@@ -705,7 +710,7 @@ let csnFilename = '';
|
|
|
705
710
|
let virtualLine = 1;
|
|
706
711
|
/** @type {CSN.Location[]} */
|
|
707
712
|
let dollarLocations = [];
|
|
708
|
-
let
|
|
713
|
+
let arrayLevelCount = 0;
|
|
709
714
|
|
|
710
715
|
/**
|
|
711
716
|
* @param {Object.<string, SchemaSpec>} specs
|
|
@@ -931,8 +936,10 @@ function definition( def, spec, xsn, csn, name ) {
|
|
|
931
936
|
popLocation( def );
|
|
932
937
|
if (kind !== 'annotation' || prop === 'vocabularies')
|
|
933
938
|
return r;
|
|
934
|
-
if (!vocabInDefinitions)
|
|
939
|
+
if (!vocabInDefinitions) {
|
|
935
940
|
vocabInDefinitions = Object.create(null);
|
|
941
|
+
vocabInDefinitions[$location] = location();
|
|
942
|
+
}
|
|
936
943
|
vocabInDefinitions[name] = r; // deprecated: anno def in 'definitions'
|
|
937
944
|
return undefined;
|
|
938
945
|
|
|
@@ -957,6 +964,7 @@ function dictionaryOf( elementFct ) {
|
|
|
957
964
|
return ignore( dict );
|
|
958
965
|
}
|
|
959
966
|
const r = Object.create(null);
|
|
967
|
+
r[$location] = location();
|
|
960
968
|
const allNames = Object.keys( dict );
|
|
961
969
|
if (!allNames.length)
|
|
962
970
|
return r; // {} in one JSON line
|
|
@@ -980,6 +988,7 @@ function keys( array, spec, xsn ) {
|
|
|
980
988
|
if (!isArray( array, spec ))
|
|
981
989
|
return;
|
|
982
990
|
const r = Object.create(null);
|
|
991
|
+
r[$location] = location();
|
|
983
992
|
++virtualLine;
|
|
984
993
|
for (const def of array) {
|
|
985
994
|
const id = def.as || implicitName( def.ref );
|
|
@@ -1164,6 +1173,12 @@ function symbol( id, spec, xsn ) { // for CSN property '#'
|
|
|
1164
1173
|
xsn.sym = { id, location: location() };
|
|
1165
1174
|
}
|
|
1166
1175
|
|
|
1176
|
+
// returns: false = no "...", true = "..." without UP TO, 'upTo' = "..." with UP TO
|
|
1177
|
+
function isEllipsis( val ) {
|
|
1178
|
+
return val && typeof val === 'object' && '...' in val && Object.keys(val).length === 1 &&
|
|
1179
|
+
(val['...'] === true || 'upTo');
|
|
1180
|
+
}
|
|
1181
|
+
|
|
1167
1182
|
function annoValue( val, spec ) {
|
|
1168
1183
|
if (val == null) // TODO: reject undefined
|
|
1169
1184
|
return { val, literal: 'null', location: location() };
|
|
@@ -1171,22 +1186,40 @@ function annoValue( val, spec ) {
|
|
|
1171
1186
|
if (lit !== 'object')
|
|
1172
1187
|
return { val, literal: lit, location: location() };
|
|
1173
1188
|
if (Array.isArray( val )) {
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1189
|
+
/** @type {string|boolean} */
|
|
1190
|
+
let seenEllipsis = false;
|
|
1191
|
+
if (arrayLevelCount > 0) { // TODO: also inside structure (possible in CSN!)
|
|
1192
|
+
if (val.some( isEllipsis )) {
|
|
1193
|
+
error( 'syntax-csn-unexpected-ellipsis', location(true), { code: '...' },
|
|
1194
|
+
'Unexpected $(CODE) in nested array' );
|
|
1195
|
+
}
|
|
1178
1196
|
}
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1197
|
+
else {
|
|
1198
|
+
for (const item of val) {
|
|
1199
|
+
if (seenEllipsis !== true) {
|
|
1200
|
+
seenEllipsis = isEllipsis( item ) || seenEllipsis;
|
|
1201
|
+
}
|
|
1202
|
+
else if (isEllipsis( item )) { // with or without UP TO
|
|
1203
|
+
// error position at the beginning of the array, but that is fine
|
|
1204
|
+
error( 'syntax-csn-duplicate-ellipsis', location(true), { code: '...' },
|
|
1205
|
+
'Expected no more than one $(CODE)' );
|
|
1206
|
+
break;
|
|
1207
|
+
}
|
|
1208
|
+
}
|
|
1182
1209
|
}
|
|
1183
|
-
|
|
1210
|
+
arrayLevelCount++;
|
|
1184
1211
|
const retval = {
|
|
1185
1212
|
location: location(),
|
|
1186
1213
|
val: arrayOf( annoValue )( val, spec ),
|
|
1187
1214
|
literal: 'array',
|
|
1188
1215
|
};
|
|
1189
|
-
|
|
1216
|
+
arrayLevelCount--;
|
|
1217
|
+
if (seenEllipsis === 'upTo') {
|
|
1218
|
+
error( 'syntax-csn-expecting-ellipsis', location(true), // at closing bracket
|
|
1219
|
+
{ code: '... up to', newcode: '...' },
|
|
1220
|
+
// TODO: should we be more CSN specific in the message?
|
|
1221
|
+
'Expecting an array item $(NEWCODE) after an item with $(CODE)' );
|
|
1222
|
+
}
|
|
1190
1223
|
return retval;
|
|
1191
1224
|
}
|
|
1192
1225
|
if (typeof val['#'] === 'string') {
|
|
@@ -1205,12 +1238,19 @@ function annoValue( val, spec ) {
|
|
|
1205
1238
|
return refSplit( val['='], '=' );
|
|
1206
1239
|
}
|
|
1207
1240
|
}
|
|
1208
|
-
else if (val['...'] && Object.keys(val).length === 1) {
|
|
1209
|
-
|
|
1241
|
+
else if (val['...'] && Object.keys( val ).length === 1) {
|
|
1242
|
+
// TODO: only if not nested - see error above
|
|
1243
|
+
++virtualLine;
|
|
1244
|
+
const ell = val['...'];
|
|
1245
|
+
const r = {
|
|
1210
1246
|
val: '...',
|
|
1211
1247
|
literal: 'token',
|
|
1212
1248
|
location: location(),
|
|
1213
1249
|
};
|
|
1250
|
+
if (ell !== true)
|
|
1251
|
+
r.upTo = annoValue( ell, schema['@'] );
|
|
1252
|
+
++virtualLine;
|
|
1253
|
+
return r;
|
|
1214
1254
|
}
|
|
1215
1255
|
const struct = Object.create(null);
|
|
1216
1256
|
++virtualLine;
|
|
@@ -1354,12 +1394,11 @@ function exprArgs( cond, spec, xsn, csn ) {
|
|
|
1354
1394
|
|
|
1355
1395
|
function condition( cond, spec ) {
|
|
1356
1396
|
const loc = location();
|
|
1357
|
-
|
|
1397
|
+
return {
|
|
1358
1398
|
op: { val: 'xpr', location: loc },
|
|
1359
1399
|
args: exprArgs( cond, spec ),
|
|
1360
1400
|
location: loc,
|
|
1361
1401
|
};
|
|
1362
|
-
return x;
|
|
1363
1402
|
}
|
|
1364
1403
|
|
|
1365
1404
|
function vZeroValue( obj, spec, xsn ) {
|
|
@@ -1406,6 +1445,7 @@ function excluding( array, spec, xsn ) {
|
|
|
1406
1445
|
if (!isArray( array, spec ))
|
|
1407
1446
|
return;
|
|
1408
1447
|
const r = Object.create(null);
|
|
1448
|
+
r[$location] = location();
|
|
1409
1449
|
++virtualLine;
|
|
1410
1450
|
for (const ex of array) {
|
|
1411
1451
|
const id = string( ex, spec ) || '';
|
|
@@ -1666,8 +1706,8 @@ function pushLocation( obj ) {
|
|
|
1666
1706
|
error( 'syntax-csn-expected-object', location(true), { prop: '$location' } );
|
|
1667
1707
|
}
|
|
1668
1708
|
// hidden feature: string $location
|
|
1669
|
-
const m = /:(\d+)(?::(\d+)
|
|
1670
|
-
if (!m) {
|
|
1709
|
+
const m = /:(\d+)(?::(\d+))?$/.exec( loc ); // extra '^'s at end deliberately left out
|
|
1710
|
+
if (!m) { // without location or with '^'s: do not use
|
|
1671
1711
|
dollarLocations.push( null );
|
|
1672
1712
|
}
|
|
1673
1713
|
else {
|
|
@@ -1710,8 +1750,10 @@ function toXsn( csn, filename, options, messageFunctions ) {
|
|
|
1710
1750
|
csnFilename = filename;
|
|
1711
1751
|
virtualLine = 1;
|
|
1712
1752
|
dollarLocations = [];
|
|
1753
|
+
arrayLevelCount = 0;
|
|
1713
1754
|
inExtensions = null;
|
|
1714
1755
|
vocabInDefinitions = null;
|
|
1756
|
+
|
|
1715
1757
|
const xsn = { $frontend: 'json' };
|
|
1716
1758
|
|
|
1717
1759
|
// eslint-disable-next-line object-curly-newline
|