@sap/cds-compiler 5.9.2 → 6.0.10
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 +109 -319
- package/README.md +1 -1
- package/bin/cds_update_identifiers.js +3 -5
- package/bin/cdsc.js +22 -8
- package/bin/cdshi.js +1 -1
- package/bin/cdsse.js +4 -4
- package/doc/CHANGELOG_BETA.md +11 -0
- package/doc/CHANGELOG_DEPRECATED.md +29 -0
- package/lib/api/main.js +8 -5
- package/lib/api/options.js +12 -10
- package/lib/base/builtins.js +1 -0
- package/lib/base/message-registry.js +190 -96
- package/lib/base/messages.js +29 -20
- package/lib/base/model.js +14 -24
- package/lib/checks/actionsFunctions.js +10 -20
- package/lib/checks/annotationsOData.js +1 -1
- package/lib/checks/elements.js +30 -10
- package/lib/checks/enums.js +31 -0
- package/lib/checks/foreignKeys.js +2 -2
- package/lib/checks/hasPersistedElements.js +5 -0
- package/lib/checks/invalidTarget.js +1 -1
- package/lib/checks/managedWithoutKeys.js +5 -4
- package/lib/checks/queryNoDbArtifacts.js +10 -8
- package/lib/checks/types.js +5 -5
- package/lib/checks/validator.js +6 -4
- package/lib/compiler/assert-consistency.js +12 -9
- package/lib/compiler/checks.js +18 -50
- package/lib/compiler/define.js +6 -6
- package/lib/compiler/extend.js +2 -1
- package/lib/compiler/generate.js +14 -17
- package/lib/compiler/populate.js +8 -31
- package/lib/compiler/propagator.js +21 -35
- package/lib/compiler/resolve.js +35 -22
- package/lib/compiler/shared.js +7 -1
- package/lib/compiler/tweak-assocs.js +1 -1
- package/lib/compiler/utils.js +1 -1
- package/lib/edm/annotations/edmJson.js +20 -15
- package/lib/edm/annotations/genericTranslation.js +7 -8
- package/lib/edm/csn2edm.js +46 -50
- package/lib/edm/edm.js +8 -7
- package/lib/edm/edmPreprocessor.js +37 -85
- package/lib/edm/edmUtils.js +2 -2
- package/lib/gen/BaseParser.js +55 -44
- package/lib/gen/CdlGrammar.checksum +1 -1
- package/lib/gen/CdlParser.js +1133 -1150
- package/lib/json/from-csn.js +70 -43
- package/lib/json/to-csn.js +6 -8
- package/lib/language/multiLineStringParser.js +3 -2
- package/lib/main.d.ts +58 -24
- package/lib/model/csnUtils.js +28 -39
- package/lib/model/xprAsTree.js +23 -9
- package/lib/modelCompare/compare.js +5 -4
- package/lib/optionProcessor.js +21 -17
- package/lib/parsers/AstBuildingParser.js +63 -11
- package/lib/parsers/XprTree.js +57 -3
- package/lib/parsers/identifiers.js +1 -1
- package/lib/parsers/index.js +0 -3
- package/lib/render/manageConstraints.js +25 -25
- package/lib/render/toCdl.js +173 -170
- package/lib/render/toHdbcds.js +126 -128
- package/lib/render/toRename.js +7 -7
- package/lib/render/toSql.js +128 -125
- package/lib/render/utils/common.js +47 -22
- package/lib/render/utils/delta.js +25 -25
- package/lib/render/utils/operators.js +2 -2
- package/lib/render/utils/pretty.js +5 -5
- package/lib/render/utils/sql.js +13 -13
- package/lib/render/utils/standardDatabaseFunctions.js +115 -103
- package/lib/render/utils/unique.js +4 -4
- package/lib/transform/db/applyTransformations.js +1 -1
- package/lib/transform/db/assertUnique.js +2 -2
- package/lib/transform/db/associations.js +6 -7
- package/lib/transform/db/assocsToQueries/utils.js +4 -5
- package/lib/transform/db/backlinks.js +12 -9
- package/lib/transform/db/cdsPersistence.js +8 -7
- package/lib/transform/db/constraints.js +13 -10
- package/lib/transform/db/expansion.js +7 -3
- package/lib/transform/db/flattening.js +4 -14
- package/lib/transform/db/processSqlServices.js +2 -1
- package/lib/transform/db/temporal.js +5 -7
- package/lib/transform/db/views.js +2 -4
- package/lib/transform/draft/db.js +8 -8
- package/lib/transform/draft/odata.js +10 -7
- package/lib/transform/forOdata.js +10 -5
- package/lib/transform/forRelationalDB.js +5 -75
- package/lib/transform/localized.js +1 -1
- package/lib/transform/odata/createForeignKeys.js +11 -10
- package/lib/transform/odata/flattening.js +8 -4
- package/lib/transform/odata/foreignKeyRefsInXprAnnos.js +96 -0
- package/lib/transform/odata/typesExposure.js +3 -3
- package/lib/transform/transformUtils.js +4 -8
- package/lib/transform/translateAssocsToJoins.js +14 -7
- package/lib/transform/universalCsn/universalCsnEnricher.js +10 -4
- package/lib/utils/objectUtils.js +0 -17
- package/package.json +10 -13
- package/share/messages/def-upcoming-virtual-change.md +1 -1
- package/LICENSE +0 -37
- package/bin/cds_remove_invalid_whitespace.js +0 -138
- package/doc/CHANGELOG_ARCHIVE.md +0 -3604
- package/lib/gen/genericAntlrParser.js +0 -3
- package/lib/gen/language.checksum +0 -1
- package/lib/gen/language.interp +0 -456
- package/lib/gen/language.tokens +0 -180
- package/lib/gen/languageLexer.interp +0 -439
- package/lib/gen/languageLexer.js +0 -1483
- package/lib/gen/languageLexer.tokens +0 -167
- package/lib/gen/languageParser.js +0 -24941
- package/lib/language/antlrParser.js +0 -205
- package/lib/language/errorStrategy.js +0 -646
- package/lib/language/genericAntlrParser.js +0 -1572
- package/lib/parsers/CdlGrammar.g4 +0 -2070
|
@@ -83,7 +83,7 @@ function xpr2edmJson( carrier, anno, location, options, messageFunctions ) {
|
|
|
83
83
|
});
|
|
84
84
|
delete parent[op];
|
|
85
85
|
};
|
|
86
|
-
const noOp = () =>
|
|
86
|
+
const noOp = () => {};
|
|
87
87
|
//----------------------------------
|
|
88
88
|
// Create the transformer dictionary
|
|
89
89
|
const transform = {
|
|
@@ -96,7 +96,6 @@ function xpr2edmJson( carrier, anno, location, options, messageFunctions ) {
|
|
|
96
96
|
isNull: (p, o) => notADynExpr(p, o, null, null, null, null, 'is null'),
|
|
97
97
|
isNotNull: (p, o) => notADynExpr(p, o, null, null, null, null, 'is not null'),
|
|
98
98
|
exists: notADynExpr,
|
|
99
|
-
'#': notADynExpr,
|
|
100
99
|
SELECT: notADynExpr,
|
|
101
100
|
SET: (p, o) => notADynExpr(p, o, null, null, null, null, 'UNION'),
|
|
102
101
|
like: notADynExpr,
|
|
@@ -312,8 +311,16 @@ function xpr2edmJson( carrier, anno, location, options, messageFunctions ) {
|
|
|
312
311
|
else
|
|
313
312
|
parentparent[parentprop] = xpr;
|
|
314
313
|
};
|
|
314
|
+
transform['#'] = (parent, prop, xpr, csnPath, parentParent, parentprop, txt) => {
|
|
315
|
+
if (parent['#'] && parent.val) // enum reference that was resolved by the compiler
|
|
316
|
+
delete parent['#'];
|
|
317
|
+
else
|
|
318
|
+
notADynExpr(parent, prop, xpr, csnPath, parentParent, parentprop, txt);
|
|
319
|
+
};
|
|
315
320
|
transform.ref = (parent, prop, xpr, csnPath, parentparent, parentprop) => {
|
|
316
|
-
|
|
321
|
+
// until empty filter syntax is introduced for the annotation expressions,
|
|
322
|
+
// we ignore the filters in order to generate EDMX
|
|
323
|
+
if (xpr.some(ps => ps.args/* || ps.where */)) {
|
|
317
324
|
error('odata-anno-xpr-ref', location, {
|
|
318
325
|
anno, elemref: parent, '#': 'args',
|
|
319
326
|
});
|
|
@@ -492,12 +499,12 @@ function xpr2edmJson( carrier, anno, location, options, messageFunctions ) {
|
|
|
492
499
|
const td = EdmPrimitiveTypeMap[typeDef];
|
|
493
500
|
if (td) {
|
|
494
501
|
if (td.v2 !== options.isV2() && td.v4 !== options.isV4()) {
|
|
495
|
-
message('odata-
|
|
502
|
+
message('odata-unexpected-edm-type', location,
|
|
496
503
|
{
|
|
497
504
|
anno,
|
|
498
505
|
type: typeDef,
|
|
499
506
|
version: (options.isV4() ? '4.0' : '2.0'),
|
|
500
|
-
'#': '
|
|
507
|
+
'#': 'anno',
|
|
501
508
|
});
|
|
502
509
|
}
|
|
503
510
|
evalArgs(td, typeFacets, typeDef);
|
|
@@ -516,13 +523,13 @@ function xpr2edmJson( carrier, anno, location, options, messageFunctions ) {
|
|
|
516
523
|
const facetArgs = typeFacets.filter(arg => arg.func === facetName || arg.func === `$${ facetName }`);
|
|
517
524
|
|
|
518
525
|
if (facetArgs.length === 0 && !optional && (options.isV2() === facetDef.v2 || options.isV4() === facetDef.v4)) {
|
|
519
|
-
message('odata-
|
|
526
|
+
message('odata-unexpected-edm-facet', location,
|
|
520
527
|
{
|
|
521
528
|
anno,
|
|
522
529
|
type: typeDef,
|
|
523
530
|
name: facetName,
|
|
524
531
|
version: (options.isV4() ? '4.0' : '2.0'),
|
|
525
|
-
'#': '
|
|
532
|
+
'#': 'anno',
|
|
526
533
|
});
|
|
527
534
|
}
|
|
528
535
|
else if (facetArgs.length > 1) {
|
|
@@ -566,14 +573,12 @@ function xpr2edmJson( carrier, anno, location, options, messageFunctions ) {
|
|
|
566
573
|
const precision = Number.parseInt(parent.$Precision, 10);
|
|
567
574
|
const scale = Number.parseInt(parent.$Scale, 10);
|
|
568
575
|
if (!Number.isNaN(precision) && !Number.isNaN(scale) && scale > precision) {
|
|
569
|
-
message('odata-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
'#': 'scale_anno',
|
|
576
|
-
});
|
|
576
|
+
message('odata-invalid-scale', location, {
|
|
577
|
+
'#': 'anno',
|
|
578
|
+
anno,
|
|
579
|
+
number: scale,
|
|
580
|
+
rawvalue: precision,
|
|
581
|
+
});
|
|
577
582
|
}
|
|
578
583
|
}
|
|
579
584
|
if (options.isV2() && parent.$Scale === 'variable') {
|
|
@@ -852,14 +852,13 @@ function csn2annotationEdm( reqDefs, reqDefsUtils, csnVocabularies, serviceName,
|
|
|
852
852
|
|
|
853
853
|
termNameWithoutQualifiers.split('.').forEach((id) => {
|
|
854
854
|
if (!edmUtils.isODataSimpleIdentifier(id))
|
|
855
|
-
message('odata-
|
|
855
|
+
message('odata-invalid-name', msg.location, { id });
|
|
856
856
|
});
|
|
857
857
|
newAnno = new Edm.Annotation(v, termNameWithoutQualifiers);
|
|
858
858
|
if (qualifier?.length) {
|
|
859
|
-
if (!edmUtils.isODataSimpleIdentifier(qualifier))
|
|
860
|
-
message('odata-
|
|
861
|
-
|
|
862
|
-
}
|
|
859
|
+
if (!edmUtils.isODataSimpleIdentifier(qualifier))
|
|
860
|
+
message('odata-invalid-qualifier', msg.location, { id: qualifier });
|
|
861
|
+
|
|
863
862
|
newAnno.setEdmAttribute('Term', termNameWithoutQualifiers);
|
|
864
863
|
newAnno.setEdmAttribute('Qualifier', qualifier);
|
|
865
864
|
}
|
|
@@ -1428,7 +1427,7 @@ function csn2annotationEdm( reqDefs, reqDefsUtils, csnVocabularies, serviceName,
|
|
|
1428
1427
|
// in a record or term
|
|
1429
1428
|
if (Array.isArray(value)) {
|
|
1430
1429
|
message('odata-anno-value', msg.location,
|
|
1431
|
-
{ anno: msg.anno(), '#': '
|
|
1430
|
+
{ anno: msg.anno(), '#': 'nestedCollection' });
|
|
1432
1431
|
}
|
|
1433
1432
|
else if (value && typeof value === 'object') {
|
|
1434
1433
|
if (value['=']) {
|
|
@@ -1439,7 +1438,7 @@ function csn2annotationEdm( reqDefs, reqDefsUtils, csnVocabularies, serviceName,
|
|
|
1439
1438
|
}
|
|
1440
1439
|
else if (value['#']) {
|
|
1441
1440
|
message('odata-anno-value', msg.location,
|
|
1442
|
-
{ anno: msg.anno(), '#': '
|
|
1441
|
+
{ anno: msg.anno(), '#': 'enuminCollection' });
|
|
1443
1442
|
}
|
|
1444
1443
|
else if (value.$edmJson) {
|
|
1445
1444
|
newCollection.append(handleEdmJson(value.$edmJson, msg));
|
|
@@ -1774,7 +1773,7 @@ function mergeOdataVocabularies( options, message ) {
|
|
|
1774
1773
|
defOk = false;
|
|
1775
1774
|
}
|
|
1776
1775
|
else if (name === 'Alias' && !edmUtils.isODataSimpleIdentifier(def[name])) {
|
|
1777
|
-
message('odata-
|
|
1776
|
+
message('odata-invalid-vocabulary-alias', null, { id: name, value: def[name] });
|
|
1778
1777
|
defOk = false;
|
|
1779
1778
|
}
|
|
1780
1779
|
});
|
package/lib/edm/csn2edm.js
CHANGED
|
@@ -79,7 +79,7 @@ function csn2edmAll( _csn, _options, serviceNames, messageFunctions ) {
|
|
|
79
79
|
|
|
80
80
|
const mergedVocabularies = translate.mergeOdataVocabularies(options, message);
|
|
81
81
|
|
|
82
|
-
const Edm = getEdm(options
|
|
82
|
+
const Edm = getEdm(options);
|
|
83
83
|
|
|
84
84
|
const { v } = options;
|
|
85
85
|
if (Object.keys(allServices).length === 0) {
|
|
@@ -304,14 +304,13 @@ function csn2edmAll( _csn, _options, serviceNames, messageFunctions ) {
|
|
|
304
304
|
|
|
305
305
|
const usages = UsedTypes[typeName].filter(u => !u.$NameClashReported);
|
|
306
306
|
if (usages.length > 0 && def && !def.$isRendered && def['@cds.external']) {
|
|
307
|
-
message('odata-
|
|
307
|
+
message('odata-invalid-external-type', usages[0].$location,
|
|
308
308
|
{
|
|
309
309
|
type: typeName,
|
|
310
310
|
anno: '@cds.external',
|
|
311
311
|
name: serviceCsn.name,
|
|
312
312
|
code: def.elements ? 'Edm.ComplexType' : 'Edm.TypeDefinition',
|
|
313
313
|
version: options.isV4() ? '4.0' : '2.0',
|
|
314
|
-
'#': 'external',
|
|
315
314
|
});
|
|
316
315
|
}
|
|
317
316
|
}
|
|
@@ -407,14 +406,14 @@ function csn2edmAll( _csn, _options, serviceNames, messageFunctions ) {
|
|
|
407
406
|
const reservedNames = [ 'Edm', 'odata', 'System', 'Transient' ];
|
|
408
407
|
const loc = [ 'definitions', schema.name ];
|
|
409
408
|
if (reservedNames.includes(schema.name))
|
|
410
|
-
message('odata-
|
|
409
|
+
message('odata-invalid-service-name', loc, { names: reservedNames });
|
|
411
410
|
if (schema.name.length > 511) {
|
|
412
|
-
message('odata-
|
|
411
|
+
message('odata-invalid-service-name', loc, { '#': 'length' });
|
|
413
412
|
}
|
|
414
413
|
else {
|
|
415
414
|
schema.name.split('.').forEach((id) => {
|
|
416
415
|
if (!edmUtils.isODataSimpleIdentifier(id))
|
|
417
|
-
message('odata-
|
|
416
|
+
message('odata-invalid-name', loc, { id });
|
|
418
417
|
});
|
|
419
418
|
}
|
|
420
419
|
|
|
@@ -523,29 +522,31 @@ function csn2edmAll( _csn, _options, serviceNames, messageFunctions ) {
|
|
|
523
522
|
// this especially covers: 'items: composition of one { data : String; }'
|
|
524
523
|
// "keyless" composition targets in structured containment mode
|
|
525
524
|
else if (entityCsn.$hasEntitySet && entityCsn.$edmKeyPaths.length === 0 && !isSingleton)
|
|
526
|
-
message('odata-
|
|
525
|
+
message('odata-missing-key', location);
|
|
527
526
|
|
|
528
527
|
if (!edmUtils.isODataSimpleIdentifier(EntityTypeName))
|
|
529
|
-
message('odata-
|
|
528
|
+
message('odata-invalid-name', location, { id: EntityTypeName });
|
|
530
529
|
|
|
531
530
|
properties.forEach((p) => {
|
|
532
531
|
const pLoc = [ ...location, 'elements', p._edmAttributes.Name ];
|
|
533
532
|
edmTypeCompatibilityCheck(p, pLoc);
|
|
534
533
|
if (p._edmAttributes.Name === EntityTypeName)
|
|
535
|
-
message('odata-
|
|
534
|
+
message('odata-invalid-property-name', pLoc, { meta: entityCsn.kind });
|
|
536
535
|
|
|
537
536
|
if (options.isV2() && p.$isCollection && !p._csn.target)
|
|
538
|
-
message('odata-
|
|
537
|
+
message('odata-unexpected-array', pLoc, { version: '2.0' });
|
|
539
538
|
|
|
540
539
|
if (!edmUtils.isODataSimpleIdentifier(p._edmAttributes.Name)) {
|
|
541
|
-
message('odata-
|
|
540
|
+
message('odata-invalid-name', pLoc, { id: p._edmAttributes.Name });
|
|
542
541
|
}
|
|
543
542
|
else if (options.isV2() && /^(_|\d)/.test(p._edmAttributes.Name)) {
|
|
544
543
|
// FIXME: Rewrite signalIllegalIdentifier function to be more flexible
|
|
545
|
-
message('odata-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
544
|
+
message('odata-invalid-name', pLoc, {
|
|
545
|
+
'#': 'v2firstChar',
|
|
546
|
+
prop: p._edmAttributes.Name[0],
|
|
547
|
+
id: p._edmAttributes.Name,
|
|
548
|
+
version: '2.0',
|
|
549
|
+
});
|
|
549
550
|
}
|
|
550
551
|
});
|
|
551
552
|
|
|
@@ -603,23 +604,23 @@ function csn2edmAll( _csn, _options, serviceNames, messageFunctions ) {
|
|
|
603
604
|
const location = [ 'definitions', structuredTypeCsn.name ];
|
|
604
605
|
|
|
605
606
|
if (!edmUtils.isODataSimpleIdentifier(attributes.Name))
|
|
606
|
-
message('odata-
|
|
607
|
+
message('odata-invalid-name', location, { id: attributes.Name });
|
|
607
608
|
|
|
608
609
|
properties.forEach((p) => {
|
|
609
610
|
const pLoc = [ ...location, ...(structuredTypeCsn.items ? [ 'items', 'elements' ] : [ 'elements' ]), p._edmAttributes.Name ];
|
|
610
611
|
edmTypeCompatibilityCheck(p, pLoc);
|
|
611
612
|
if (p._edmAttributes.Name === complexType._edmAttributes.Name)
|
|
612
|
-
message('odata-
|
|
613
|
+
message('odata-invalid-property-name', pLoc, { meta: structuredTypeCsn.kind });
|
|
613
614
|
|
|
614
615
|
if (!edmUtils.isODataSimpleIdentifier(p._edmAttributes.Name))
|
|
615
|
-
message('odata-
|
|
616
|
+
message('odata-invalid-name', pLoc, { id: p._edmAttributes.Name });
|
|
616
617
|
|
|
617
618
|
if (options.isV2()) {
|
|
618
619
|
if (p.$isCollection && !p._csn.target)
|
|
619
|
-
message('odata-
|
|
620
|
+
message('odata-unexpected-array', pLoc, { version: '2.0' });
|
|
620
621
|
|
|
621
622
|
if (p._csn.target)
|
|
622
|
-
message('odata-
|
|
623
|
+
message('odata-unexpected-assoc', pLoc, { version: '2.0' });
|
|
623
624
|
}
|
|
624
625
|
});
|
|
625
626
|
|
|
@@ -713,7 +714,7 @@ function csn2edmAll( _csn, _options, serviceNames, messageFunctions ) {
|
|
|
713
714
|
// derived types are already resolved to base types
|
|
714
715
|
const attributes = { Name: typeCsn.name.replace(schemaNamePrefix, '') };
|
|
715
716
|
if (!edmUtils.isODataSimpleIdentifier(attributes.Name))
|
|
716
|
-
message('odata-
|
|
717
|
+
message('odata-invalid-name', typeCsn.$path, { id: attributes.Name });
|
|
717
718
|
|
|
718
719
|
const typeDef = new Edm.TypeDefinition(v, attributes, typeCsn );
|
|
719
720
|
edmTypeCompatibilityCheck(typeDef, typeCsn.$path);
|
|
@@ -732,7 +733,7 @@ function csn2edmAll( _csn, _options, serviceNames, messageFunctions ) {
|
|
|
732
733
|
|
|
733
734
|
|
|
734
735
|
if (!edmUtils.isODataSimpleIdentifier(attributes.Name))
|
|
735
|
-
message('odata-
|
|
736
|
+
message('odata-invalid-name', location, { id: attributes.Name });
|
|
736
737
|
|
|
737
738
|
if (!iAmAnAction)
|
|
738
739
|
attributes.IsComposable = false;
|
|
@@ -766,7 +767,7 @@ function csn2edmAll( _csn, _options, serviceNames, messageFunctions ) {
|
|
|
766
767
|
setProp(firstParam, '_edmType', bpType);
|
|
767
768
|
}
|
|
768
769
|
if (!edmUtils.isODataSimpleIdentifier(bpName))
|
|
769
|
-
message('odata-
|
|
770
|
+
message('odata-invalid-name', [ ...location, 'params', bpName ], { id: bpName });
|
|
770
771
|
}
|
|
771
772
|
}
|
|
772
773
|
|
|
@@ -795,7 +796,7 @@ function csn2edmAll( _csn, _options, serviceNames, messageFunctions ) {
|
|
|
795
796
|
}
|
|
796
797
|
|
|
797
798
|
if (!edmUtils.isODataSimpleIdentifier(bpName))
|
|
798
|
-
message('odata-
|
|
799
|
+
message('odata-invalid-name', bpnAnnoLoc, { id: bpName });
|
|
799
800
|
if (actionCsn.params && actionCsn.params[bpName])
|
|
800
801
|
error('duplicate-definition', bpnAnnoLoc, { '#': 'param', name: bpName });
|
|
801
802
|
}
|
|
@@ -839,7 +840,7 @@ function csn2edmAll( _csn, _options, serviceNames, messageFunctions ) {
|
|
|
839
840
|
const p = new Edm.Parameter(v, { Name: parameterName }, parameterCsn );
|
|
840
841
|
const pLoc = [ ...location, 'params', p._edmAttributes.Name ];
|
|
841
842
|
if (!edmUtils.isODataSimpleIdentifier(parameterName))
|
|
842
|
-
message('odata-
|
|
843
|
+
message('odata-invalid-name', pLoc, { id: parameterName });
|
|
843
844
|
collectUsedType(parameterCsn);
|
|
844
845
|
edmTypeCompatibilityCheck(p, pLoc);
|
|
845
846
|
actionNode.append(p);
|
|
@@ -880,7 +881,7 @@ function csn2edmAll( _csn, _options, serviceNames, messageFunctions ) {
|
|
|
880
881
|
: [ 'definitions', actionCsn.name ];
|
|
881
882
|
|
|
882
883
|
if (!edmUtils.isODataSimpleIdentifier(attributes.Name))
|
|
883
|
-
message('odata-
|
|
884
|
+
message('odata-invalid-name', location, { id: attributes.Name });
|
|
884
885
|
|
|
885
886
|
const rt = actionCsn.returns && ((actionCsn.returns.items && actionCsn.returns.items.type) || actionCsn.returns.type);
|
|
886
887
|
if (rt) { // add EntitySet attribute only if return type is an entity
|
|
@@ -936,17 +937,17 @@ function csn2edmAll( _csn, _options, serviceNames, messageFunctions ) {
|
|
|
936
937
|
collectUsedType(parameterCsn);
|
|
937
938
|
edmTypeCompatibilityCheck(param, pLoc);
|
|
938
939
|
if (!edmUtils.isODataSimpleIdentifier(parameterName))
|
|
939
|
-
message('odata-
|
|
940
|
+
message('odata-invalid-name', pLoc, { id: parameterName });
|
|
940
941
|
|
|
941
942
|
// only scalar or structured type in V2 (not entity)
|
|
942
943
|
if (param._type &&
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
message('odata-
|
|
944
|
+
!param._type.startsWith('Edm.') &&
|
|
945
|
+
csn.definitions[param._type] &&
|
|
946
|
+
!edmUtils.isStructuredType(csn.definitions[param._type]))
|
|
947
|
+
message('odata-invalid-param-type', pLoc, { version: '2.0' });
|
|
947
948
|
|
|
948
949
|
if (param.$isCollection)
|
|
949
|
-
message('odata-
|
|
950
|
+
message('odata-unexpected-array', pLoc, { version: '2.0' });
|
|
950
951
|
|
|
951
952
|
functionImport.append(param);
|
|
952
953
|
}
|
|
@@ -966,27 +967,26 @@ function csn2edmAll( _csn, _options, serviceNames, messageFunctions ) {
|
|
|
966
967
|
if (type) {
|
|
967
968
|
collectUsedType(action.returns);
|
|
968
969
|
if (!isBuiltinType(type) && csn.definitions[type].kind !== 'entity' && csn.definitions[type].kind !== 'type') {
|
|
969
|
-
message('odata-
|
|
970
|
+
message('odata-invalid-return-type', returnsLoc, { kind: action.kind, version: '2.0' });
|
|
970
971
|
}
|
|
971
972
|
else if (isBuiltinType(type)) {
|
|
972
973
|
type = edmUtils.mapCdsToEdmType(returns, messageFunctions, _options);
|
|
973
974
|
if (type) {
|
|
974
975
|
const td = EdmPrimitiveTypeMap[type];
|
|
975
976
|
if (td && !td.v2) {
|
|
976
|
-
message('odata-
|
|
977
|
-
{ type, version: '2.0'
|
|
977
|
+
message('odata-unexpected-edm-type', returnsLoc,
|
|
978
|
+
{ type, version: '2.0' });
|
|
978
979
|
}
|
|
979
980
|
}
|
|
980
981
|
else {
|
|
981
|
-
message('odata-
|
|
982
|
+
message('odata-unknown-edm-type', returnsLoc, { type });
|
|
982
983
|
}
|
|
983
984
|
}
|
|
984
985
|
if (action.returns.$isCollection)
|
|
985
986
|
type = `Collection(${ type })`;
|
|
986
987
|
}
|
|
987
988
|
else {
|
|
988
|
-
|
|
989
|
-
message('odata-spec-violation-type', returnsLoc);
|
|
989
|
+
message('odata-missing-type', returnsLoc);
|
|
990
990
|
}
|
|
991
991
|
}
|
|
992
992
|
return type;
|
|
@@ -1159,7 +1159,7 @@ function csn2edmAll( _csn, _options, serviceNames, messageFunctions ) {
|
|
|
1159
1159
|
function edmTypeCompatibilityCheck( p, pLoc ) {
|
|
1160
1160
|
const edmType = p._type;
|
|
1161
1161
|
if (!edmType) {
|
|
1162
|
-
message('odata-
|
|
1162
|
+
message('odata-missing-type', pLoc);
|
|
1163
1163
|
}
|
|
1164
1164
|
else if (p._scalarType) {
|
|
1165
1165
|
const td = EdmPrimitiveTypeMap[edmType];
|
|
@@ -1167,8 +1167,8 @@ function csn2edmAll( _csn, _options, serviceNames, messageFunctions ) {
|
|
|
1167
1167
|
// The renderer/type mapper doesn't/shouldn't produce incompatible types and facets.
|
|
1168
1168
|
// Only the unknown type warning may be triggered by an unknown @odata.Type override.
|
|
1169
1169
|
if (td.v2 !== p.v2 && td.v4 !== p.v4) {
|
|
1170
|
-
message('odata-
|
|
1171
|
-
{ type: edmType, version: (p.v4 ? '4.0' : '2.0')
|
|
1170
|
+
message('odata-unexpected-edm-type', pLoc,
|
|
1171
|
+
{ type: edmType, version: (p.v4 ? '4.0' : '2.0') });
|
|
1172
1172
|
}
|
|
1173
1173
|
EdmTypeFacetNames.forEach((name) => {
|
|
1174
1174
|
const facet = EdmTypeFacetMap[name];
|
|
@@ -1183,25 +1183,21 @@ function csn2edmAll( _csn, _options, serviceNames, messageFunctions ) {
|
|
|
1183
1183
|
// facet is member of type definition and mandatory
|
|
1184
1184
|
// node and facet version match
|
|
1185
1185
|
if (!p._edmAttributes[name] && td[name] && !optional && (p.v2 === facet.v2 || p.v4 === facet.v4)) {
|
|
1186
|
-
message('odata-
|
|
1187
|
-
{
|
|
1188
|
-
type: edmType, name, version: (p.v4 ? '4.0' : '2.0'), '#': 'facet',
|
|
1189
|
-
});
|
|
1186
|
+
message('odata-unexpected-edm-facet', pLoc,
|
|
1187
|
+
{ type: edmType, name, version: (p.v4 ? '4.0' : '2.0') });
|
|
1190
1188
|
}
|
|
1191
1189
|
});
|
|
1192
1190
|
if (edmType === 'Edm.Decimal') {
|
|
1193
1191
|
const precision = Number.parseInt(p._edmAttributes.Precision, 10);
|
|
1194
1192
|
const scale = Number.parseInt(p._edmAttributes.Scale, 10);
|
|
1195
1193
|
if (!Number.isNaN(precision) && !Number.isNaN(scale) && scale > precision) {
|
|
1196
|
-
message('odata-
|
|
1197
|
-
{
|
|
1198
|
-
type: edmType, number: scale, rawvalue: precision, '#': 'scale',
|
|
1199
|
-
});
|
|
1194
|
+
message('odata-invalid-scale', pLoc,
|
|
1195
|
+
{ number: scale, rawvalue: precision });
|
|
1200
1196
|
}
|
|
1201
1197
|
}
|
|
1202
1198
|
}
|
|
1203
1199
|
else {
|
|
1204
|
-
message('odata-
|
|
1200
|
+
message('odata-unknown-edm-type', pLoc, { type: edmType });
|
|
1205
1201
|
}
|
|
1206
1202
|
}
|
|
1207
1203
|
}
|
package/lib/edm/edm.js
CHANGED
|
@@ -8,9 +8,9 @@ const {
|
|
|
8
8
|
EdmTypeFacetNames,
|
|
9
9
|
EdmPrimitiveTypeMap,
|
|
10
10
|
} = require('./EdmPrimitiveTypeDefinitions.js');
|
|
11
|
+
const { CompilerAssertion } = require('../base/error');
|
|
11
12
|
|
|
12
|
-
function getEdm( options
|
|
13
|
-
const { error } = messageFunctions || { error: () => true, warning: () => true };
|
|
13
|
+
function getEdm( options ) {
|
|
14
14
|
class Node {
|
|
15
15
|
/**
|
|
16
16
|
* @param {boolean[]} version Versions in the form of [<v2>, <v4>].
|
|
@@ -19,11 +19,11 @@ function getEdm( options, messageFunctions ) {
|
|
|
19
19
|
*/
|
|
20
20
|
constructor(version, attributes = Object.create(null), csn = undefined) {
|
|
21
21
|
if (!attributes || typeof attributes !== 'object')
|
|
22
|
-
|
|
22
|
+
throw new CompilerAssertion('Debug me: attributes must be a dictionary');
|
|
23
23
|
if (!Array.isArray(version))
|
|
24
|
-
|
|
24
|
+
throw new CompilerAssertion(`Debug me: v is either undefined or not an array: ${ version }`);
|
|
25
25
|
if (version.filter(v => v).length !== 1)
|
|
26
|
-
|
|
26
|
+
throw new CompilerAssertion('Debug me: exactly one version must be set');
|
|
27
27
|
|
|
28
28
|
// Common attributes of JSON and XML.
|
|
29
29
|
// Note: Can't assign attributes directly, due to the input object being modified.
|
|
@@ -741,6 +741,7 @@ function getEdm( options, messageFunctions ) {
|
|
|
741
741
|
this._edmAttributes.OpenType = true;
|
|
742
742
|
}
|
|
743
743
|
}
|
|
744
|
+
|
|
744
745
|
class EntityType extends ComplexType {
|
|
745
746
|
constructor(version, details, properties, csn) {
|
|
746
747
|
super(version, details, csn);
|
|
@@ -1142,7 +1143,7 @@ function getEdm( options, messageFunctions ) {
|
|
|
1142
1143
|
json.$OnDelete = c._edmAttributes.Action;
|
|
1143
1144
|
break;
|
|
1144
1145
|
default:
|
|
1145
|
-
|
|
1146
|
+
throw new CompilerAssertion(`Debug me: Unhandled NavProp child: ${ c.kind }`);
|
|
1146
1147
|
}
|
|
1147
1148
|
});
|
|
1148
1149
|
// TODO Annotations
|
|
@@ -1340,7 +1341,7 @@ function getEdm( options, messageFunctions ) {
|
|
|
1340
1341
|
break;
|
|
1341
1342
|
}
|
|
1342
1343
|
default:
|
|
1343
|
-
|
|
1344
|
+
throw new CompilerAssertion(`Debug me: Unhandled Record child: ${ c.kind }`);
|
|
1344
1345
|
}
|
|
1345
1346
|
});
|
|
1346
1347
|
return json;
|