@sap/cds-compiler 2.4.4 → 2.10.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 +241 -1
- package/bin/.eslintrc.json +17 -0
- package/bin/cds_update_identifiers.js +8 -7
- package/bin/cdsc.js +180 -132
- package/bin/cdshi.js +18 -11
- package/bin/cdsse.js +38 -32
- package/bin/cdsv2m.js +8 -7
- package/doc/CHANGELOG_BETA.md +36 -1
- package/lib/api/main.js +81 -100
- package/lib/api/options.js +17 -11
- package/lib/api/validate.js +12 -8
- package/lib/backends.js +0 -81
- package/lib/base/keywords.js +32 -2
- package/lib/base/location.js +2 -2
- package/lib/base/message-registry.js +66 -4
- package/lib/base/messages.js +84 -27
- package/lib/base/model.js +2 -61
- package/lib/checks/arrayOfs.js +0 -1
- package/lib/checks/defaultValues.js +27 -2
- package/lib/checks/elements.js +1 -6
- package/lib/checks/enricher.js +8 -2
- package/lib/checks/foreignKeys.js +0 -6
- package/lib/checks/managedWithoutKeys.js +17 -0
- package/lib/checks/nonexpandableStructured.js +38 -0
- package/lib/checks/onConditions.js +9 -45
- package/lib/checks/queryNoDbArtifacts.js +27 -9
- package/lib/checks/selectItems.js +25 -2
- package/lib/checks/types.js +26 -2
- package/lib/checks/unknownMagic.js +38 -0
- package/lib/checks/utils.js +61 -0
- package/lib/checks/validator.js +66 -13
- package/lib/compiler/assert-consistency.js +24 -12
- package/lib/compiler/builtins.js +2 -0
- package/lib/compiler/checks.js +6 -4
- package/lib/compiler/definer.js +101 -39
- package/lib/compiler/index.js +88 -59
- package/lib/compiler/resolver.js +455 -209
- package/lib/compiler/shared.js +57 -33
- package/lib/edm/annotations/genericTranslation.js +183 -187
- package/lib/edm/csn2edm.js +128 -99
- package/lib/edm/edm.js +18 -21
- package/lib/edm/edmPreprocessor.js +361 -127
- package/lib/edm/edmUtils.js +103 -33
- package/lib/gen/Dictionary.json +74 -28
- package/lib/gen/language.checksum +1 -1
- package/lib/gen/language.interp +18 -4
- package/lib/gen/language.tokens +124 -118
- package/lib/gen/languageLexer.interp +13 -1
- package/lib/gen/languageLexer.js +870 -839
- package/lib/gen/languageLexer.tokens +116 -111
- package/lib/gen/languageParser.js +5894 -5614
- package/lib/json/from-csn.js +152 -67
- package/lib/json/to-csn.js +334 -135
- package/lib/language/antlrParser.js +4 -3
- package/lib/language/errorStrategy.js +1 -0
- package/lib/language/genericAntlrParser.js +24 -14
- package/lib/language/language.g4 +188 -128
- package/lib/main.d.ts +435 -0
- package/lib/main.js +31 -7
- package/lib/model/api.js +78 -0
- package/lib/model/csnRefs.js +463 -187
- package/lib/model/csnUtils.js +280 -136
- package/lib/model/enrichCsn.js +75 -4
- package/lib/model/revealInternalProperties.js +2 -1
- package/lib/modelCompare/compare.js +70 -25
- package/lib/optionProcessor.js +13 -10
- package/lib/render/.eslintrc.json +4 -1
- package/lib/render/DuplicateChecker.js +8 -5
- package/lib/render/toCdl.js +123 -40
- package/lib/render/toHdbcds.js +156 -65
- package/lib/render/toSql.js +87 -11
- package/lib/render/utils/common.js +55 -9
- package/lib/render/utils/sql.js +3 -3
- package/lib/sql-identifier.js +6 -1
- package/lib/transform/{sql → db}/.eslintrc.json +0 -0
- package/lib/transform/{sql → db}/assertUnique.js +7 -8
- package/lib/transform/{sql → db}/constraints.js +35 -20
- package/lib/transform/db/draft.js +353 -0
- package/lib/transform/db/expansion.js +582 -0
- package/lib/transform/db/flattening.js +325 -0
- package/lib/transform/{sql → db}/groupByOrderBy.js +8 -16
- package/lib/transform/{sql → db}/helpers.js +0 -0
- package/lib/transform/{sql → db}/transformExists.js +256 -60
- package/lib/transform/forHanaNew.js +216 -765
- package/lib/transform/forOdataNew.js +60 -56
- package/lib/transform/localized.js +48 -26
- package/lib/transform/odata/attachPath.js +19 -4
- package/lib/transform/odata/expandStructKeysInAssociations.js +2 -2
- package/lib/transform/odata/generateForeignKeyElements.js +13 -12
- package/lib/transform/odata/referenceFlattener.js +60 -36
- package/lib/transform/odata/sortByAssociationDependency.js +4 -4
- package/lib/transform/odata/structuralPath.js +76 -0
- package/lib/transform/odata/structureFlattener.js +21 -22
- package/lib/transform/odata/toFinalBaseType.js +5 -5
- package/lib/transform/odata/typesExposure.js +27 -17
- package/lib/transform/odata/utils.js +2 -2
- package/lib/transform/transformUtilsNew.js +141 -77
- package/lib/transform/translateAssocsToJoins.js +17 -14
- package/lib/transform/universalCsnEnricher.js +67 -0
- package/lib/utils/file.js +0 -11
- package/lib/utils/moduleResolve.js +6 -8
- package/lib/utils/timetrace.js +6 -1
- package/package.json +2 -1
- package/lib/base/deepCopy.js +0 -66
- package/lib/json/walker.js +0 -26
- package/lib/utils/string.js +0 -17
package/lib/compiler/shared.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
'use strict';
|
|
5
5
|
|
|
6
|
-
const { searchName
|
|
6
|
+
const { searchName } = require('../base/messages');
|
|
7
7
|
const { dictAdd, dictAddArray, pushToDict } = require('../base/dictionaries');
|
|
8
8
|
const { setProp } = require('../base/model');
|
|
9
9
|
|
|
@@ -60,7 +60,7 @@ const kindProperties = {
|
|
|
60
60
|
|
|
61
61
|
function propExists( prop, parent ) {
|
|
62
62
|
const obj = parent.returns || parent;
|
|
63
|
-
return (obj.items || obj)[prop];
|
|
63
|
+
return (obj.items || obj.targetAspect || obj)[prop];
|
|
64
64
|
}
|
|
65
65
|
|
|
66
66
|
function artifactsEnv( art ) {
|
|
@@ -83,7 +83,7 @@ function fns( model, environment = artifactsEnv ) {
|
|
|
83
83
|
const options = model.options || {};
|
|
84
84
|
const {
|
|
85
85
|
info, warning, error, message,
|
|
86
|
-
} =
|
|
86
|
+
} = model.$messageFunctions;
|
|
87
87
|
// TODO: combine envFn and assoc ?
|
|
88
88
|
const specExpected = {
|
|
89
89
|
global: { // for using declaration
|
|
@@ -284,6 +284,16 @@ function fns( model, environment = artifactsEnv ) {
|
|
|
284
284
|
return art.name.absolute;
|
|
285
285
|
}
|
|
286
286
|
|
|
287
|
+
function userQuery( user ) {
|
|
288
|
+
// TODO: we need _query links set by the definer
|
|
289
|
+
while (user._main) {
|
|
290
|
+
if (user.kind === 'select' || user.kind === '$join')
|
|
291
|
+
return user;
|
|
292
|
+
user = user._parent;
|
|
293
|
+
}
|
|
294
|
+
return null;
|
|
295
|
+
}
|
|
296
|
+
|
|
287
297
|
// Return artifact or element referred by the path in `ref`. The first
|
|
288
298
|
// environment we search in is `env`. If no such artifact or element exist,
|
|
289
299
|
// complain with message and return `undefined`. Record a dependency from
|
|
@@ -325,12 +335,8 @@ function fns( model, environment = artifactsEnv ) {
|
|
|
325
335
|
}
|
|
326
336
|
else if (spec.next) { // TODO: combine spec.next / spec.lexical to spec.lexical
|
|
327
337
|
// TODO: SIMPLIFY this function
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
? user._main // in path filter, just $magic (and $parameters)
|
|
331
|
-
: (user.kind === 'select' || user.kind === '$join')
|
|
332
|
-
? user
|
|
333
|
-
: user._parent && user._parent.kind === 'select' && user._parent;
|
|
338
|
+
const query = (spec.lexical === 'main') ? user._main : userQuery( user );
|
|
339
|
+
// in path filter, just $magic (and $parameters)
|
|
334
340
|
env = (spec.lexical === 'from') ? query._parent : query || user._main || user;
|
|
335
341
|
// queries: first tabaliases, then $magic - value refs: first $self, then $magic
|
|
336
342
|
if (!extDict && !spec.noExt) {
|
|
@@ -350,7 +356,7 @@ function fns( model, environment = artifactsEnv ) {
|
|
|
350
356
|
if (!art) {
|
|
351
357
|
return setLink( ref, art );
|
|
352
358
|
}
|
|
353
|
-
else if (user._pathHead) {
|
|
359
|
+
else if (!spec.envFn && user._pathHead) {
|
|
354
360
|
// eslint-disable-next-line no-empty
|
|
355
361
|
}
|
|
356
362
|
else if (art.kind === 'using') {
|
|
@@ -397,7 +403,7 @@ function fns( model, environment = artifactsEnv ) {
|
|
|
397
403
|
? ref.scope || Number.MAX_SAFE_INTEGER
|
|
398
404
|
: spec.artItemsCount || 1;
|
|
399
405
|
// console.log(expected, ref.path.map(a=>a.id),artItemsCount)
|
|
400
|
-
art = getPathItem( path, spec, user, artItemsCount, user._pathHead && art);
|
|
406
|
+
art = getPathItem( path, spec, user, artItemsCount, !spec.envFn && user._pathHead && art);
|
|
401
407
|
if (!art)
|
|
402
408
|
return setLink( ref, art );
|
|
403
409
|
|
|
@@ -505,7 +511,8 @@ function fns( model, environment = artifactsEnv ) {
|
|
|
505
511
|
// if the artifact does not exist. Return a "fresh" artifact for
|
|
506
512
|
// non-existing external using references if `unchecked` is truthy.
|
|
507
513
|
function getPathRoot( path, spec, user, env, extDict, msgArt ) {
|
|
508
|
-
if (user._pathHead) {
|
|
514
|
+
if (!spec.envFn && user._pathHead) {
|
|
515
|
+
// TODO: not necessarily for explicit ON condition in expand
|
|
509
516
|
environment( user._pathHead ); // make sure _origin is set
|
|
510
517
|
return user._pathHead._origin;
|
|
511
518
|
}
|
|
@@ -650,13 +657,28 @@ function fns( model, environment = artifactsEnv ) {
|
|
|
650
657
|
return false;
|
|
651
658
|
continue;
|
|
652
659
|
}
|
|
653
|
-
|
|
654
|
-
// do not check any elements of the path, e.g. $session
|
|
655
|
-
return art;
|
|
656
|
-
}
|
|
660
|
+
|
|
657
661
|
const fn = (spec.envFn && artItemsCount >= 0) ? spec.envFn : environment;
|
|
658
662
|
const env = fn( art, item.location, user, spec.assoc );
|
|
663
|
+
|
|
664
|
+
// do not check any elements of the path, e.g. $session - but still don't return path-head
|
|
665
|
+
if (art && art.$uncheckedElements) {
|
|
666
|
+
if (env && env[item.id]) // something like $user.id/$user.locale
|
|
667
|
+
return env[item.id];
|
|
668
|
+
|
|
669
|
+
// $user.foo - build our own valid path step obj
|
|
670
|
+
// Important: Don't directly modify item!
|
|
671
|
+
const obj = {
|
|
672
|
+
location: item.location,
|
|
673
|
+
kind: 'builtin',
|
|
674
|
+
name: { id: item.id, element: path.map(p => p.id).join('.') },
|
|
675
|
+
};
|
|
676
|
+
setLink(obj, art, '_parent');
|
|
677
|
+
return obj;
|
|
678
|
+
}
|
|
679
|
+
|
|
659
680
|
const sub = setLink( item, env && env[item.id] );
|
|
681
|
+
|
|
660
682
|
if (!sub)
|
|
661
683
|
return (sub === 0) ? 0 : errorNotFound( item, env );
|
|
662
684
|
else if (Array.isArray(sub)) // redefinitions
|
|
@@ -805,7 +827,7 @@ function fns( model, environment = artifactsEnv ) {
|
|
|
805
827
|
// * do something for extensions by CSN or Properties parsers
|
|
806
828
|
// * make sure that we do not issue repeated warnings due to flattening if an
|
|
807
829
|
// annotation definition is missing
|
|
808
|
-
function defineAnnotations( construct, art, block, priority ) {
|
|
830
|
+
function defineAnnotations( construct, art, block, priority = 'define' ) {
|
|
809
831
|
if (!options.parseCdl && construct.kind === 'annotate') {
|
|
810
832
|
// Namespaces cannot be annotated in CSN but because they exist as XSN artifacts
|
|
811
833
|
// they can still be applied. Namespace annotations are extracted in to-csn.js
|
|
@@ -826,11 +848,10 @@ function fns( model, environment = artifactsEnv ) {
|
|
|
826
848
|
// TODO: block should be construct._block
|
|
827
849
|
if (construct.$annotations && construct.$annotations.doc )
|
|
828
850
|
art.doc = construct.$annotations.doc;
|
|
829
|
-
if (!construct.$annotations
|
|
830
|
-
if (
|
|
831
|
-
return;
|
|
832
|
-
//
|
|
833
|
-
// the input is CSN so we extract them.
|
|
851
|
+
if (!construct.$annotations) {
|
|
852
|
+
if (!block || block.$frontend !== 'json')
|
|
853
|
+
return; // namespace, or in CDL source without @annos:
|
|
854
|
+
// CSN input: set _block and $priority, shallow-copy from extension
|
|
834
855
|
for (const annoProp in construct) {
|
|
835
856
|
if (annoProp.charAt(0) === '@') {
|
|
836
857
|
let annos = construct[annoProp];
|
|
@@ -838,7 +859,9 @@ function fns( model, environment = artifactsEnv ) {
|
|
|
838
859
|
annos = [ annos ];
|
|
839
860
|
for (const a of annos) {
|
|
840
861
|
setProp( a, '_block', block );
|
|
841
|
-
|
|
862
|
+
a.$priority = priority;
|
|
863
|
+
if (construct !== art)
|
|
864
|
+
dictAddArray( art, annoProp, a );
|
|
842
865
|
}
|
|
843
866
|
}
|
|
844
867
|
}
|
|
@@ -888,14 +911,10 @@ function fns( model, environment = artifactsEnv ) {
|
|
|
888
911
|
setProp( anno, '_block', block );
|
|
889
912
|
// TODO: _parent, _main is set later (if we have ElementRef), or do we
|
|
890
913
|
// set _artifact?
|
|
891
|
-
|
|
914
|
+
anno.$priority = priority;
|
|
915
|
+
dictAddArray( art, annoProp, anno );
|
|
892
916
|
}
|
|
893
917
|
}
|
|
894
|
-
|
|
895
|
-
function setAnnotation( art, annoProp, anno, priority = 'define') {
|
|
896
|
-
anno.$priority = priority;
|
|
897
|
-
dictAddArray( art, annoProp, anno );
|
|
898
|
-
}
|
|
899
918
|
}
|
|
900
919
|
|
|
901
920
|
// Return string 'A.B.C' for parsed source `A.B.C` (is vector of ids with
|
|
@@ -937,10 +956,11 @@ function linkToOrigin( origin, name, parent, prop, location, silentDep ) {
|
|
|
937
956
|
|
|
938
957
|
function setMemberParent( elem, name, parent, prop ) {
|
|
939
958
|
if (prop) { // extension or structure include
|
|
940
|
-
// TODO: consider ARRAY OF and RETURNS, COMPOSITION OF type
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
959
|
+
// TODO: consider nested ARRAY OF and RETURNS, COMPOSITION OF type
|
|
960
|
+
const p = parent.items || parent.targetAspect || parent;
|
|
961
|
+
if (!(prop in p))
|
|
962
|
+
p[prop] = Object.create(null);
|
|
963
|
+
dictAdd( p[prop], name, elem );
|
|
944
964
|
}
|
|
945
965
|
if (parent._outer)
|
|
946
966
|
parent = parent._outer;
|
|
@@ -996,6 +1016,10 @@ function storeExtension( elem, name, prop, parent, block ) {
|
|
|
996
1016
|
const kind = `_${ elem.kind }`; // _extend or _annotate
|
|
997
1017
|
if (!parent[kind])
|
|
998
1018
|
setProp( parent, kind, {} );
|
|
1019
|
+
// if (name === '' && prop === 'params') {
|
|
1020
|
+
// pushToDict( parent[kind], 'returns', elem ); // not really a dict
|
|
1021
|
+
// return;
|
|
1022
|
+
// }
|
|
999
1023
|
if (!parent[kind][prop])
|
|
1000
1024
|
parent[kind][prop] = Object.create(null);
|
|
1001
1025
|
pushToDict( parent[kind][prop], name, elem );
|