@sap/cds-compiler 6.7.3 → 6.9.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 +70 -0
- package/README.md +4 -0
- package/bin/cdsc.js +5 -5
- package/bin/cdshi.js +1 -0
- package/bin/cdsse.js +1 -1
- package/lib/api/main.js +17 -9
- package/lib/api/options.js +5 -2
- package/lib/api/validate.js +1 -1
- package/lib/base/builtins.js +13 -9
- package/lib/{model → base}/csnRefs.js +8 -10
- package/lib/base/error.js +2 -0
- package/lib/base/message-registry.js +68 -4
- package/lib/base/messages.js +4 -2
- package/lib/{optionProcessor.js → base/optionProcessor.js} +5 -3
- package/lib/base/{model.js → specialOptions.js} +16 -39
- package/lib/checks/arrayOfs.js +1 -1
- package/lib/checks/elements.js +1 -1
- package/lib/checks/enricher.js +2 -2
- package/lib/checks/featureFlags.js +54 -24
- package/lib/checks/foreignKeys.js +1 -1
- package/lib/checks/invalidTarget.js +1 -1
- package/lib/checks/managedInType.js +1 -1
- package/lib/checks/onConditions.js +1 -1
- package/lib/checks/queryNoDbArtifacts.js +1 -1
- package/lib/checks/validator.js +10 -14
- package/lib/compiler/assert-consistency.js +11 -9
- package/lib/compiler/base.js +5 -1
- package/lib/compiler/builtins.js +1 -1
- package/lib/compiler/checks.js +3 -3
- package/lib/compiler/define.js +6 -3
- package/lib/{base → compiler}/dictionaries.js +4 -3
- package/lib/compiler/extend.js +121 -21
- package/lib/compiler/generate.js +2 -2
- package/lib/compiler/index.js +11 -3
- package/lib/compiler/kick-start.js +1 -1
- package/lib/compiler/lsp-api.js +3 -3
- package/lib/compiler/populate.js +6 -7
- package/lib/compiler/resolve.js +53 -36
- package/lib/compiler/shared.js +68 -18
- package/lib/compiler/tweak-assocs.js +2 -2
- package/lib/compiler/utils.js +28 -27
- package/lib/compiler/xpr-rewrite.js +3 -3
- package/lib/edm/EdmPrimitiveTypeDefinitions.js +4 -1
- package/lib/edm/annotations/edmJson.js +2 -4
- package/lib/edm/annotations/genericTranslation.js +51 -7
- package/lib/edm/csn2edm.js +3 -2
- package/lib/edm/edmAnnoPreprocessor.js +1 -1
- package/lib/edm/edmInboundChecks.js +2 -1
- package/lib/edm/edmPreprocessor.js +3 -3
- package/lib/edm/edmUtils.js +2 -2
- package/lib/gen/BaseParser.js +59 -108
- package/lib/gen/CdlGrammar.checksum +1 -1
- package/lib/gen/CdlParser.js +2052 -1965
- package/lib/gen/Dictionary.json +67 -7
- package/lib/json/from-csn.js +14 -14
- package/lib/json/to-csn.js +77 -38
- package/lib/main.js +3 -3
- package/lib/model/csnUtils.js +2 -2
- package/lib/modelCompare/compare.js +1 -1
- package/lib/modelCompare/utils/filter.js +1 -0
- package/lib/parsers/AstBuildingParser.js +83 -33
- package/lib/parsers/index.js +1 -1
- package/lib/render/manageConstraints.js +1 -1
- package/lib/render/toCdl.js +49 -30
- package/lib/render/toHdbcds.js +2 -2
- package/lib/render/toSql.js +16 -7
- package/lib/render/utils/common.js +11 -3
- package/lib/render/utils/sql.js +14 -5
- package/lib/render/utils/standardDatabaseFunctions.js +108 -99
- package/lib/sql-identifier.js +9 -1
- package/lib/{model → tool-lib}/enrichCsn.js +3 -2
- package/lib/{model → tool-lib}/revealInternalProperties.js +2 -1
- package/lib/transform/addTenantFields.js +1 -1
- package/lib/transform/db/applyTransformations.js +1 -1
- package/lib/transform/db/assertUnique.js +1 -1
- package/lib/transform/db/assocsToQueries/transformExists.js +1 -1
- package/lib/transform/db/backlinks.js +2 -2
- package/lib/transform/db/expansion.js +2 -2
- package/lib/transform/db/flattening.js +3 -4
- package/lib/transform/db/killAnnotations.js +1 -0
- package/lib/transform/db/processSqlServices.js +2 -1
- package/lib/transform/db/rewriteCalculatedElements.js +2 -2
- package/lib/transform/db/temporal.js +30 -5
- package/lib/transform/db/views.js +16 -20
- package/lib/transform/draft/db.js +1 -2
- package/lib/transform/effective/associations.js +1 -1
- package/lib/transform/effective/flattening.js +6 -5
- package/lib/transform/effective/main.js +24 -4
- package/lib/transform/effective/types.js +1 -1
- package/lib/transform/{odata/fioriTreeViews.js → fioriTreeViews.js} +48 -25
- package/lib/transform/forOdata.js +25 -7
- package/lib/transform/forRelationalDB.js +48 -12
- package/lib/transform/localized.js +2 -2
- package/lib/transform/odata/createForeignKeys.js +1 -1
- package/lib/transform/odata/flattening.js +2 -2
- package/lib/transform/odata/toFinalBaseType.js +3 -2
- package/lib/transform/odata/typesExposure.js +3 -2
- package/lib/transform/transformUtils.js +2 -2
- package/lib/transform/translateAssocsToJoins.js +2 -1
- package/lib/transform/tupleExpansion.js +44 -4
- package/lib/transform/universalCsn/universalCsnEnricher.js +7 -3
- package/lib/transform/universalCsn/utils.js +1 -1
- package/lib/{base → utils}/lazyload.js +9 -0
- package/lib/{base → utils}/node-helpers.js +2 -0
- package/lib/utils/objectUtils.js +29 -6
- package/lib/{base → utils}/optionProcessorHelper.js +16 -6
- package/package.json +3 -40
- /package/lib/{model → base}/cloneCsn.js +0 -0
- /package/lib/{model/api.js → base/model-api.js} +0 -0
- /package/lib/{api → base}/trace.js +0 -0
- /package/lib/{model → base}/xprAsTree.js +0 -0
- /package/lib/{inspect → tool-lib}/index.js +0 -0
- /package/lib/{inspect → tool-lib}/inspectModelStatistics.js +0 -0
- /package/lib/{inspect → tool-lib}/inspectPropagation.js +0 -0
- /package/lib/{inspect → tool-lib}/inspectUtils.js +0 -0
- /package/lib/{base → utils}/shuffle.js +0 -0
package/lib/gen/Dictionary.json
CHANGED
|
@@ -170,6 +170,8 @@
|
|
|
170
170
|
"Type": "Core.Tag"
|
|
171
171
|
},
|
|
172
172
|
"Capabilities.BatchContinueOnErrorSupported": {
|
|
173
|
+
"$deprecated": true,
|
|
174
|
+
"$deprecationText": "Deprecated in favor of the [`ContinueOnErrorSupported`](#BatchSupportType) property from the [`BatchSupport`](#BatchSupport) term",
|
|
173
175
|
"AppliesTo": [
|
|
174
176
|
"EntityContainer"
|
|
175
177
|
],
|
|
@@ -1167,13 +1169,15 @@
|
|
|
1167
1169
|
},
|
|
1168
1170
|
"Communication.IsEmailAddress": {
|
|
1169
1171
|
"AppliesTo": [
|
|
1170
|
-
"Property"
|
|
1172
|
+
"Property",
|
|
1173
|
+
"Parameter"
|
|
1171
1174
|
],
|
|
1172
1175
|
"Type": "Core.Tag"
|
|
1173
1176
|
},
|
|
1174
1177
|
"Communication.IsPhoneNumber": {
|
|
1175
1178
|
"AppliesTo": [
|
|
1176
|
-
"Property"
|
|
1179
|
+
"Property",
|
|
1180
|
+
"Parameter"
|
|
1177
1181
|
],
|
|
1178
1182
|
"Type": "Core.Tag"
|
|
1179
1183
|
},
|
|
@@ -1863,7 +1867,6 @@
|
|
|
1863
1867
|
}
|
|
1864
1868
|
}
|
|
1865
1869
|
},
|
|
1866
|
-
"$experimental": true,
|
|
1867
1870
|
"AppliesTo": [
|
|
1868
1871
|
"Property",
|
|
1869
1872
|
"Parameter"
|
|
@@ -2106,7 +2109,8 @@
|
|
|
2106
2109
|
"UI.Placeholder": {
|
|
2107
2110
|
"AppliesTo": [
|
|
2108
2111
|
"Property",
|
|
2109
|
-
"Parameter"
|
|
2112
|
+
"Parameter",
|
|
2113
|
+
"Record"
|
|
2110
2114
|
],
|
|
2111
2115
|
"Type": "Edm.String"
|
|
2112
2116
|
},
|
|
@@ -2145,7 +2149,11 @@
|
|
|
2145
2149
|
"AppliesTo": [
|
|
2146
2150
|
"EntityType"
|
|
2147
2151
|
],
|
|
2148
|
-
"
|
|
2152
|
+
"DerivedTypeConstraint": [
|
|
2153
|
+
"Edm.ComplexType",
|
|
2154
|
+
"Edm.EntityType"
|
|
2155
|
+
],
|
|
2156
|
+
"Type": "Edm.Untyped"
|
|
2149
2157
|
},
|
|
2150
2158
|
"UI.SelectionFields": {
|
|
2151
2159
|
"AppliesTo": [
|
|
@@ -2847,6 +2855,36 @@
|
|
|
2847
2855
|
"TypecastSegmentSupported": "Edm.Boolean"
|
|
2848
2856
|
}
|
|
2849
2857
|
},
|
|
2858
|
+
"Capabilities.ExpandByKeyRestrictionsBase": {
|
|
2859
|
+
"$kind": "ComplexType",
|
|
2860
|
+
"BaseType": "Capabilities.ExpandRestrictionsBase",
|
|
2861
|
+
"Properties": {
|
|
2862
|
+
"Expandable": "Edm.Boolean",
|
|
2863
|
+
"MaxLevels": "Edm.Int32",
|
|
2864
|
+
"StreamsExpandable": "Edm.Boolean"
|
|
2865
|
+
}
|
|
2866
|
+
},
|
|
2867
|
+
"Capabilities.ExpandByKeyRestrictionsType": {
|
|
2868
|
+
"$kind": "ComplexType",
|
|
2869
|
+
"BaseType": "Capabilities.ExpandByKeyRestrictionsBase",
|
|
2870
|
+
"Properties": {
|
|
2871
|
+
"Expandable": "Edm.Boolean",
|
|
2872
|
+
"MaxLevels": "Edm.Int32",
|
|
2873
|
+
"NonExpandableProperties": "Collection(Edm.NavigationPropertyPath)",
|
|
2874
|
+
"NonExpandableStreamProperties": "Collection(Edm.PropertyPath)",
|
|
2875
|
+
"StreamsExpandable": "Edm.Boolean"
|
|
2876
|
+
}
|
|
2877
|
+
},
|
|
2878
|
+
"Capabilities.ExpandCollectionRestrictionsType": {
|
|
2879
|
+
"$kind": "ComplexType",
|
|
2880
|
+
"BaseType": "Capabilities.ExpandRestrictionsBase",
|
|
2881
|
+
"Properties": {
|
|
2882
|
+
"ExpandByKeyRestrictions": "Capabilities.ExpandByKeyRestrictionsBase",
|
|
2883
|
+
"Expandable": "Edm.Boolean",
|
|
2884
|
+
"MaxLevels": "Edm.Int32",
|
|
2885
|
+
"StreamsExpandable": "Edm.Boolean"
|
|
2886
|
+
}
|
|
2887
|
+
},
|
|
2850
2888
|
"Capabilities.ExpandRestrictionsBase": {
|
|
2851
2889
|
"$kind": "ComplexType",
|
|
2852
2890
|
"Properties": {
|
|
@@ -2857,8 +2895,9 @@
|
|
|
2857
2895
|
},
|
|
2858
2896
|
"Capabilities.ExpandRestrictionsType": {
|
|
2859
2897
|
"$kind": "ComplexType",
|
|
2860
|
-
"BaseType": "Capabilities.
|
|
2898
|
+
"BaseType": "Capabilities.ExpandCollectionRestrictionsType",
|
|
2861
2899
|
"Properties": {
|
|
2900
|
+
"ExpandByKeyRestrictions": "Capabilities.ExpandByKeyRestrictionsBase",
|
|
2862
2901
|
"Expandable": "Edm.Boolean",
|
|
2863
2902
|
"MaxLevels": "Edm.Int32",
|
|
2864
2903
|
"NonExpandableProperties": "Collection(Edm.NavigationPropertyPath)",
|
|
@@ -4463,7 +4502,28 @@
|
|
|
4463
4502
|
"CriticalityRepresentation": "UI.CriticalityRepresentationType",
|
|
4464
4503
|
"IconUrl": "Edm.String",
|
|
4465
4504
|
"Label": "Edm.String",
|
|
4466
|
-
"Value":
|
|
4505
|
+
"Value": {
|
|
4506
|
+
"DerivedTypeConstraint": [
|
|
4507
|
+
"Edm.PrimitiveType",
|
|
4508
|
+
"Collection(Edm.Binary)",
|
|
4509
|
+
"Collection(Edm.Boolean)",
|
|
4510
|
+
"Collection(Edm.Byte)",
|
|
4511
|
+
"Collection(Edm.Date)",
|
|
4512
|
+
"Collection(Edm.DateTimeOffset)",
|
|
4513
|
+
"Collection(Edm.Decimal)",
|
|
4514
|
+
"Collection(Edm.Double)",
|
|
4515
|
+
"Collection(Edm.Duration)",
|
|
4516
|
+
"Collection(Edm.Guid)",
|
|
4517
|
+
"Collection(Edm.Int16)",
|
|
4518
|
+
"Collection(Edm.Int32)",
|
|
4519
|
+
"Collection(Edm.Int64)",
|
|
4520
|
+
"Collection(Edm.SByte)",
|
|
4521
|
+
"Collection(Edm.Single)",
|
|
4522
|
+
"Collection(Edm.String)",
|
|
4523
|
+
"Collection(Edm.TimeOfDay)"
|
|
4524
|
+
],
|
|
4525
|
+
"Type": "Edm.Untyped"
|
|
4526
|
+
}
|
|
4467
4527
|
}
|
|
4468
4528
|
},
|
|
4469
4529
|
"UI.DataFieldAbstract": {
|
package/lib/json/from-csn.js
CHANGED
|
@@ -115,9 +115,9 @@
|
|
|
115
115
|
* @returns {any} XSN property (e.g. string, object, ...)
|
|
116
116
|
*/
|
|
117
117
|
|
|
118
|
-
const { dictAdd } = require('../
|
|
118
|
+
const { dictAdd } = require('../compiler/dictionaries');
|
|
119
119
|
const { quotedLiteralPatterns } = require('../compiler/builtins');
|
|
120
|
-
const {
|
|
120
|
+
const { exprProperties } = require('../base/builtins');
|
|
121
121
|
const { CompilerAssertion } = require('../base/error');
|
|
122
122
|
const { Location } = require('../base/location');
|
|
123
123
|
const { XsnSource } = require('../compiler/xsn-model');
|
|
@@ -141,11 +141,6 @@ const typeProperties = [
|
|
|
141
141
|
'type', 'length', 'precision', 'scale', 'srid', 'localized', 'notNull', 'default',
|
|
142
142
|
'keys', 'on', // only with 'target'
|
|
143
143
|
];
|
|
144
|
-
const exprProperties = [
|
|
145
|
-
// do not include CSN v0.1.0 properties here:
|
|
146
|
-
'ref', 'xpr', 'list', 'val', '#', 'func', 'SELECT', 'SET', // Core Compiler checks SELECT/SET
|
|
147
|
-
'param', 'literal', 'args', 'cast', // only with 'ref'/'ref'/'val'/'func'
|
|
148
|
-
];
|
|
149
144
|
|
|
150
145
|
// Groups of properties which cannot be used together:
|
|
151
146
|
const xorGroups = {
|
|
@@ -619,16 +614,16 @@ const schema = compileSchema( {
|
|
|
619
614
|
optional: exprProperties,
|
|
620
615
|
},
|
|
621
616
|
where: {
|
|
622
|
-
class: 'condition',
|
|
617
|
+
class: 'condition', inKind: [ 'extend' ],
|
|
623
618
|
},
|
|
624
619
|
groupBy: {
|
|
625
|
-
arrayOf: expr, optional: exprProperties,
|
|
620
|
+
arrayOf: expr, optional: exprProperties, inKind: [ 'extend' ],
|
|
626
621
|
},
|
|
627
622
|
having: {
|
|
628
|
-
class: 'condition',
|
|
623
|
+
class: 'condition', inKind: [ 'extend' ],
|
|
629
624
|
},
|
|
630
625
|
orderBy: {
|
|
631
|
-
arrayOf: expr, optional: [ 'sort', 'nulls', ...exprProperties ],
|
|
626
|
+
arrayOf: expr, optional: [ 'sort', 'nulls', ...exprProperties ], inKind: [ 'extend' ],
|
|
632
627
|
},
|
|
633
628
|
sort: {
|
|
634
629
|
type: stringVal,
|
|
@@ -637,7 +632,7 @@ const schema = compileSchema( {
|
|
|
637
632
|
type: stringVal, // TODO: test for valid ones?
|
|
638
633
|
},
|
|
639
634
|
limit: {
|
|
640
|
-
type: object, requires: 'rows', optional: [ 'rows', 'offset' ],
|
|
635
|
+
type: object, requires: 'rows', optional: [ 'rows', 'offset' ], inKind: [ 'extend' ],
|
|
641
636
|
},
|
|
642
637
|
rows: {
|
|
643
638
|
class: 'expression',
|
|
@@ -752,7 +747,7 @@ const schema = compileSchema( {
|
|
|
752
747
|
type: namespace,
|
|
753
748
|
},
|
|
754
749
|
meta: { // meta information
|
|
755
|
-
type:
|
|
750
|
+
type: meta, // TODO: should we test s/th here?
|
|
756
751
|
},
|
|
757
752
|
version: { // deprecated top-level property
|
|
758
753
|
type: ignore,
|
|
@@ -904,6 +899,11 @@ function arrayOf( fn, filter = undefined ) {
|
|
|
904
899
|
|
|
905
900
|
// Generic functions, objects (std signature) --------------------------------
|
|
906
901
|
|
|
902
|
+
function meta( obj ) {
|
|
903
|
+
ignore( obj );
|
|
904
|
+
return obj;
|
|
905
|
+
}
|
|
906
|
+
|
|
907
907
|
function ignore( obj ) {
|
|
908
908
|
if (obj && typeof obj === 'object') {
|
|
909
909
|
const array = (Array.isArray( obj )) ? obj : Object.values( obj );
|
|
@@ -1462,7 +1462,7 @@ function annoValue( val, spec ) {
|
|
|
1462
1462
|
++virtualLine;
|
|
1463
1463
|
return r;
|
|
1464
1464
|
}
|
|
1465
|
-
else if (
|
|
1465
|
+
else if (exprProperties.some( prop => val[prop] !== undefined )) {
|
|
1466
1466
|
const s = schema['@'].schema['-expr'];
|
|
1467
1467
|
const r = { location: location() };
|
|
1468
1468
|
Object.assign( r, object( val, s ) );
|
package/lib/json/to-csn.js
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
'use strict';
|
|
13
13
|
|
|
14
14
|
const { locationString } = require('../base/messages');
|
|
15
|
-
const { isBetaEnabled } = require('../base/
|
|
15
|
+
const { isBetaEnabled } = require('../base/specialOptions');
|
|
16
16
|
const { pathName } = require('../compiler/utils');
|
|
17
17
|
const { CompilerAssertion } = require('../base/error');
|
|
18
18
|
|
|
@@ -234,11 +234,11 @@ function compactModel( model, options = model.options || {} ) {
|
|
|
234
234
|
}
|
|
235
235
|
// 'namespace' for complete model is 'namespace' of first source
|
|
236
236
|
// (not a really useful property at all, avoids XSN inspection by Umbrella)
|
|
237
|
-
|
|
237
|
+
const first = Object.keys( srcDict )[0];
|
|
238
|
+
if (first) {
|
|
238
239
|
const { namespace } = srcDict[first];
|
|
239
240
|
if (namespace?.name?.path)
|
|
240
241
|
csn.namespace = pathName( namespace.name.path );
|
|
241
|
-
break;
|
|
242
242
|
}
|
|
243
243
|
set( 'definitions', csn, model );
|
|
244
244
|
if (Object.keys(model.vocabularies || {}).length > 0)
|
|
@@ -249,21 +249,38 @@ function compactModel( model, options = model.options || {} ) {
|
|
|
249
249
|
set( 'i18n', csn, model );
|
|
250
250
|
set( 'sources', csn, model );
|
|
251
251
|
// Set $location, use $extra properties of first source as resulting $extra properties
|
|
252
|
-
|
|
253
|
-
|
|
252
|
+
const firstSourceName = Object.keys( srcDict )[0];
|
|
253
|
+
if (firstSourceName) {
|
|
254
|
+
const firstSource = srcDict[firstSourceName];
|
|
255
|
+
const loc = firstSource.location;
|
|
254
256
|
if (loc && loc.file) {
|
|
255
257
|
Object.defineProperty( csn, '$location', {
|
|
256
258
|
value: { file: loc.file }, configurable: true, writable: true, enumerable: withLocations,
|
|
257
259
|
} );
|
|
258
260
|
}
|
|
259
|
-
set( '$extra', csn,
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
261
|
+
set( '$extra', csn, firstSource );
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
const srcNames = Object.keys( srcDict );
|
|
265
|
+
const firstMeta = srcDict[srcNames[0]].meta;
|
|
266
|
+
const meta = srcNames.length === 1 && firstMeta ? { ...firstMeta } : undefined;
|
|
267
|
+
if (meta?.flavor)
|
|
268
|
+
delete meta.flavor; // not supported, compilerCsnFlavor is used instead
|
|
269
|
+
const flavorMap = {
|
|
270
|
+
client: 'inferred',
|
|
271
|
+
gensrc: 'xtended',
|
|
272
|
+
universal: 'universal',
|
|
273
|
+
};
|
|
274
|
+
const compilerCsnFlavor = flavorMap[options.csnFlavor] ||
|
|
275
|
+
(options.parseCdl ? 'parsed' : 'inferred');
|
|
263
276
|
if (!options.testMode) {
|
|
264
|
-
csn.meta = Object.assign( {}, model.meta,
|
|
277
|
+
csn.meta = Object.assign( {}, model.meta, meta,
|
|
278
|
+
{ creator, compilerVersion, compilerCsnFlavor } );
|
|
265
279
|
csn.$version = csnVersion;
|
|
266
280
|
}
|
|
281
|
+
else if (meta !== undefined) {
|
|
282
|
+
csn.meta = Object.assign( {}, meta );
|
|
283
|
+
}
|
|
267
284
|
return csn;
|
|
268
285
|
}
|
|
269
286
|
|
|
@@ -307,16 +324,11 @@ function usings( srcDict ) {
|
|
|
307
324
|
function extensions( node, csn, model ) {
|
|
308
325
|
if (model.kind && model.kind !== 'source')
|
|
309
326
|
return undefined;
|
|
310
|
-
|
|
311
|
-
if (gensrcFlavor) {
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
const result = { annotate: Object.create(null) };
|
|
316
|
-
attachAnnotations( result, 'annotate', { [name]: art }, art.$inferred );
|
|
317
|
-
if (result.annotate[name])
|
|
318
|
-
exts.push( { annotate: name, ...result.annotate[name] } );
|
|
319
|
-
}
|
|
327
|
+
let exts = node.map( definition );
|
|
328
|
+
if (gensrcFlavor && model.definitions) {
|
|
329
|
+
const gensrc = { annotate: Object.create( null ), extend: Object.create( null ) };
|
|
330
|
+
attachAnnotations( gensrc, null, model.definitions, null );
|
|
331
|
+
exts = exts.concat( Object.values( gensrc.annotate ), Object.values( gensrc.extend ) );
|
|
320
332
|
}
|
|
321
333
|
return exts.sort( // TODO: really sort with parse.cdl?
|
|
322
334
|
(a, b) => (a.annotate || a.extend).localeCompare( b.annotate || b.extend )
|
|
@@ -363,36 +375,64 @@ function sources( srcDict, csn, model ) {
|
|
|
363
375
|
}
|
|
364
376
|
}
|
|
365
377
|
|
|
366
|
-
|
|
367
|
-
|
|
378
|
+
// create annotate and extend statements for CSN flavor gensrc
|
|
379
|
+
// TODO: rename this function - also refactor
|
|
380
|
+
function attachAnnotations( annotate, prop, dict, inferred, withExtend, insideReturns = false ) {
|
|
381
|
+
const annoDict = prop && Object.create( dictionaryPrototype );
|
|
368
382
|
const names = Object.keys( dict );
|
|
369
383
|
if (strictMode)
|
|
370
384
|
names.sort();
|
|
371
385
|
for (const name of names) {
|
|
372
386
|
const entry = dict[name];
|
|
373
387
|
const inf = inferred || entry.$inferred; // is probably always inferred if parent was
|
|
374
|
-
const
|
|
375
|
-
|
|
388
|
+
const withExt = withExtend || entry.$expand === 'extend';
|
|
389
|
+
const extProp = (entry.$expand === 'extend') ? 'extend' : 'annotate';
|
|
390
|
+
if (withExt && !entry.$inferred && entry.kind === 'enum') {
|
|
391
|
+
// currently just added enum - test for safety
|
|
392
|
+
if (dict[$inferred])
|
|
393
|
+
annoDict[name] = definition( entry );
|
|
394
|
+
continue;
|
|
395
|
+
}
|
|
396
|
+
let sub = {};
|
|
397
|
+
if (inf)
|
|
398
|
+
annotationsAndDocComment( entry, sub );
|
|
399
|
+
|
|
400
|
+
if (entry.$expand === 'annotate' || entry.$expand === 'extend') {
|
|
376
401
|
if (entry.actions)
|
|
377
402
|
attachAnnotations( sub, 'actions', entry.actions, inf );
|
|
378
403
|
else if (entry.params)
|
|
379
404
|
attachAnnotations( sub, 'params', entry.params, inf );
|
|
405
|
+
|
|
406
|
+
if (entry.$expand === 'extend' && (sub.actions || sub.params)) {
|
|
407
|
+
// there is only `annotate` with actions/params
|
|
408
|
+
annotate.annotate[name] = { annotate: name, ...sub };
|
|
409
|
+
sub = {};
|
|
410
|
+
}
|
|
411
|
+
|
|
380
412
|
const obj = entry.returns || entry;
|
|
381
|
-
const many = obj.items || obj;
|
|
413
|
+
const many = obj.items || obj; // TODO: many many?
|
|
382
414
|
const elems = (many.targetAspect || many).elements;
|
|
383
|
-
if (elems)
|
|
384
|
-
attachAnnotations( sub, 'elements', elems, inf, entry.returns );
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
415
|
+
if (elems) {
|
|
416
|
+
attachAnnotations( sub, 'elements', elems, inf, withExt, entry.returns );
|
|
417
|
+
}
|
|
418
|
+
else if (many.enum) { // make 'enum' annotations appear in 'elements' annotate
|
|
419
|
+
attachAnnotations( sub, (withExt ? 'enum' : 'elements'),
|
|
420
|
+
many.enum, inf, withExt, entry.returns );
|
|
421
|
+
}
|
|
422
|
+
else if (entry.foreignKeys) { // make 'foreignKeys' annotations appear in 'elements' annotate
|
|
423
|
+
attachAnnotations( sub, 'elements', entry.foreignKeys, inf, withExt );
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
if (Object.keys( sub ).length > 0) {
|
|
427
|
+
if (prop)
|
|
428
|
+
annoDict[name] = (withExt) ? { kind: 'extend', ...sub } : sub;
|
|
429
|
+
else
|
|
430
|
+
annotate[extProp][name] = { [extProp]: name, ...sub };
|
|
389
431
|
}
|
|
390
|
-
if (Object.keys( sub ).length)
|
|
391
|
-
annoDict[name] = sub;
|
|
392
432
|
}
|
|
393
|
-
if (Object.keys( annoDict ).length) {
|
|
433
|
+
if (prop && Object.keys( annoDict ).length) {
|
|
394
434
|
if (insideReturns)
|
|
395
|
-
annotate.returns = {
|
|
435
|
+
annotate.returns = { [prop]: annoDict };
|
|
396
436
|
else
|
|
397
437
|
annotate[prop] = annoDict;
|
|
398
438
|
}
|
|
@@ -509,7 +549,7 @@ function enumerableQueryElements( select ) {
|
|
|
509
549
|
return (universalCsn && select !== select._main._leadingQuery);
|
|
510
550
|
}
|
|
511
551
|
|
|
512
|
-
// Should we render the elements? (and items?)
|
|
552
|
+
// Should we render the elements? (and enum, items?)
|
|
513
553
|
function keepElements( node, line ) {
|
|
514
554
|
if (universalCsn)
|
|
515
555
|
// $expand = null/undefined: not elements not via expansion
|
|
@@ -547,8 +587,7 @@ function keepElements( node, line ) {
|
|
|
547
587
|
*
|
|
548
588
|
* @param {object} node
|
|
549
589
|
*/
|
|
550
|
-
function annotationsAndDocComment( node ) {
|
|
551
|
-
const csn = {};
|
|
590
|
+
function annotationsAndDocComment( node, csn = {} ) {
|
|
552
591
|
const transformer = transformers['@'];
|
|
553
592
|
const keys = Object.keys( node ).filter( a => a.charAt(0) === '@' ).sort();
|
|
554
593
|
for (const prop of keys) {
|
package/lib/main.js
CHANGED
|
@@ -14,13 +14,13 @@
|
|
|
14
14
|
|
|
15
15
|
'use strict';
|
|
16
16
|
|
|
17
|
-
const lazyload = require('./
|
|
17
|
+
const lazyload = require('./utils/lazyload')( module );
|
|
18
18
|
|
|
19
|
-
const { traceApi } = require('./
|
|
19
|
+
const { traceApi } = require('./base/trace');
|
|
20
20
|
|
|
21
21
|
const snapi = lazyload('./api/main');
|
|
22
22
|
const csnUtils = lazyload('./model/csnUtils');
|
|
23
|
-
const modelApi = lazyload('./model
|
|
23
|
+
const modelApi = lazyload('./base/model-api');
|
|
24
24
|
const messages = lazyload('./base/messages');
|
|
25
25
|
const sqlIdentifier = lazyload('./sql-identifier');
|
|
26
26
|
const keywords = lazyload( './base/keywords' );
|
package/lib/model/csnUtils.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const { csnRefs, implicitAs, pathId } = require('
|
|
3
|
+
const { csnRefs, implicitAs, pathId } = require('../base/csnRefs');
|
|
4
4
|
const {
|
|
5
5
|
transformExpression,
|
|
6
6
|
transformAnnotationExpression,
|
|
@@ -13,7 +13,7 @@ const { isBuiltinType, isAnnotationExpression } = require('../base/builtins');
|
|
|
13
13
|
const { ModelError, CompilerAssertion } = require('../base/error');
|
|
14
14
|
const { typeParameters } = require('../compiler/builtins');
|
|
15
15
|
const { forEach } = require('../utils/objectUtils');
|
|
16
|
-
const { cloneAnnotationValue } = require('
|
|
16
|
+
const { cloneAnnotationValue } = require('../base/cloneCsn');
|
|
17
17
|
|
|
18
18
|
// Low-level utility functions to work with compact CSN.
|
|
19
19
|
|
|
@@ -148,6 +148,7 @@ const defaultAllowedTypeChanges = {
|
|
|
148
148
|
'cds.Integer': [ 'cds.Int32', 'cds.Int64', 'cds.Integer64' ],
|
|
149
149
|
'cds.Integer64': [ 'cds.Int64' ],
|
|
150
150
|
'cds.Int64': [ 'cds.Integer64' ],
|
|
151
|
+
'cds.String': [ 'cds.LargeString' ],
|
|
151
152
|
};
|
|
152
153
|
|
|
153
154
|
const allowedTypeChanges = {
|