@sap/cds-compiler 2.12.0 → 2.15.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 +221 -15
- package/bin/cdsc.js +125 -50
- package/bin/cdsse.js +2 -2
- package/doc/CHANGELOG_BETA.md +13 -6
- package/doc/CHANGELOG_DEPRECATED.md +22 -6
- package/doc/NameResolution.md +21 -16
- package/lib/api/main.js +47 -84
- package/lib/api/options.js +5 -6
- package/lib/api/validate.js +6 -11
- package/lib/backends.js +15 -23
- package/lib/base/dictionaries.js +0 -8
- package/lib/base/error.js +26 -0
- package/lib/base/keywords.js +7 -17
- package/lib/base/location.js +9 -4
- package/lib/base/message-registry.js +114 -18
- package/lib/base/messages.js +101 -90
- package/lib/base/model.js +2 -63
- package/lib/base/optionProcessorHelper.js +177 -123
- package/lib/checks/annotationsOData.js +12 -33
- package/lib/checks/arrayOfs.js +1 -34
- package/lib/checks/cdsPersistence.js +2 -1
- package/lib/checks/enricher.js +17 -1
- package/lib/checks/invalidTarget.js +3 -1
- package/lib/checks/managedWithoutKeys.js +3 -1
- package/lib/checks/selectItems.js +4 -4
- package/lib/checks/sql-snippets.js +27 -26
- package/lib/checks/types.js +1 -1
- package/lib/checks/validator.js +6 -11
- package/lib/compiler/assert-consistency.js +6 -3
- package/lib/compiler/base.js +1 -0
- package/lib/compiler/builtins.js +19 -6
- package/lib/compiler/checks.js +23 -60
- package/lib/compiler/cycle-detector.js +1 -1
- package/lib/compiler/define.js +1151 -0
- package/lib/compiler/extend.js +1000 -0
- package/lib/compiler/finalize-parse-cdl.js +237 -0
- package/lib/compiler/index.js +107 -39
- package/lib/compiler/kick-start.js +190 -0
- package/lib/compiler/moduleLayers.js +4 -4
- package/lib/compiler/populate.js +1227 -0
- package/lib/compiler/propagator.js +114 -46
- package/lib/compiler/resolve.js +1521 -0
- package/lib/compiler/shared.js +126 -65
- package/lib/compiler/tweak-assocs.js +535 -0
- package/lib/compiler/utils.js +197 -33
- package/lib/edm/.eslintrc.json +5 -0
- package/lib/edm/annotations/genericTranslation.js +38 -24
- package/lib/edm/annotations/preprocessAnnotations.js +2 -2
- package/lib/edm/csn2edm.js +219 -100
- package/lib/edm/edm.js +302 -230
- package/lib/edm/edmPreprocessor.js +554 -419
- package/lib/edm/edmUtils.js +138 -44
- package/lib/gen/Dictionary.json +100 -19
- package/lib/gen/language.checksum +1 -1
- package/lib/gen/language.interp +11 -1
- package/lib/gen/language.tokens +86 -83
- package/lib/gen/languageLexer.interp +10 -1
- package/lib/gen/languageLexer.js +860 -833
- package/lib/gen/languageLexer.tokens +78 -75
- package/lib/gen/languageParser.js +5765 -4480
- package/lib/json/csnVersion.js +10 -11
- package/lib/json/from-csn.js +15 -3
- package/lib/json/to-csn.js +126 -68
- package/lib/language/docCommentParser.js +4 -4
- package/lib/language/genericAntlrParser.js +123 -5
- package/lib/language/language.g4 +355 -156
- package/lib/language/multiLineStringParser.js +5 -5
- package/lib/main.d.ts +486 -59
- package/lib/main.js +41 -9
- package/lib/model/api.js +3 -1
- package/lib/model/csnRefs.js +252 -156
- package/lib/model/csnUtils.js +384 -297
- package/lib/model/enrichCsn.js +71 -29
- package/lib/model/revealInternalProperties.js +29 -8
- package/lib/model/sortViews.js +2 -1
- package/lib/modelCompare/compare.js +23 -18
- package/lib/optionProcessor.js +63 -26
- package/lib/render/manageConstraints.js +35 -32
- package/lib/render/toCdl.js +897 -947
- package/lib/render/toHdbcds.js +205 -257
- package/lib/render/toSql.js +264 -225
- package/lib/render/utils/common.js +136 -25
- package/lib/render/utils/sql.js +4 -3
- 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/db/.eslintrc.json +3 -1
- package/lib/transform/db/applyTransformations.js +35 -12
- package/lib/transform/db/assertUnique.js +1 -1
- package/lib/transform/db/associations.js +104 -306
- package/lib/transform/db/cdsPersistence.js +2 -2
- package/lib/transform/db/constraints.js +58 -53
- package/lib/transform/db/expansion.js +60 -33
- package/lib/transform/db/flattening.js +582 -104
- package/lib/transform/db/groupByOrderBy.js +3 -1
- package/lib/transform/db/transformExists.js +66 -13
- package/lib/transform/db/views.js +11 -7
- package/lib/transform/draft/.eslintrc.json +38 -0
- package/lib/transform/{db/draft.js → draft/db.js} +6 -5
- package/lib/transform/draft/odata.js +227 -0
- package/lib/transform/forHanaNew.js +109 -208
- package/lib/transform/forOdataNew.js +59 -212
- package/lib/transform/localized.js +46 -26
- package/lib/transform/odata/toFinalBaseType.js +85 -11
- package/lib/transform/odata/typesExposure.js +147 -199
- package/lib/transform/odata/utils.js +2 -2
- package/lib/transform/transformUtilsNew.js +44 -33
- package/lib/transform/translateAssocsToJoins.js +3 -20
- package/lib/transform/universalCsn/.eslintrc.json +36 -0
- package/lib/transform/universalCsn/coreComputed.js +172 -0
- package/lib/transform/universalCsn/universalCsnEnricher.js +737 -0
- package/lib/transform/universalCsn/utils.js +63 -0
- package/lib/utils/moduleResolve.js +13 -6
- package/lib/utils/objectUtils.js +30 -0
- package/package.json +1 -1
- package/share/messages/README.md +26 -0
- package/share/messages/message-explanations.json +2 -1
- package/share/messages/syntax-expected-integer.md +37 -0
- package/lib/compiler/definer.js +0 -2361
- package/lib/compiler/resolver.js +0 -3079
- package/lib/transform/odata/attachPath.js +0 -96
- package/lib/transform/odata/expandStructKeysInAssociations.js +0 -59
- package/lib/transform/odata/generateForeignKeyElements.js +0 -261
- package/lib/transform/odata/referenceFlattener.js +0 -290
- package/lib/transform/odata/sortByAssociationDependency.js +0 -105
- package/lib/transform/odata/structuralPath.js +0 -72
- package/lib/transform/odata/structureFlattener.js +0 -171
- package/lib/transform/universalCsnEnricher.js +0 -237
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const { isBetaEnabled } = require('../base/model');
|
|
4
|
-
|
|
5
3
|
// Only to be used with validator.js - a correct this value needs to be provided!
|
|
6
4
|
|
|
7
5
|
/**
|
|
@@ -14,20 +12,18 @@ const { isBetaEnabled } = require('../base/model');
|
|
|
14
12
|
* @returns {void}
|
|
15
13
|
*/
|
|
16
14
|
function checkSqlAnnotationOnElement(member, memberName, prop, path) {
|
|
17
|
-
if (
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
this.error('anno-invalid-sql-element', path, { anno: 'sql.prepend' }, `Annotation $(ANNO) can't be used on elements` );
|
|
15
|
+
if (member['@sql.replace'])
|
|
16
|
+
this.error(null, path, { anno: 'sql.replace' }, `Annotation $(ANNO) is reserved and must not be used`);
|
|
17
|
+
if (member['@sql.prepend'])
|
|
18
|
+
this.message('anno-invalid-sql-element', path, { anno: 'sql.prepend' }, `Annotation $(ANNO) can't be used on elements` );
|
|
22
19
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
}
|
|
20
|
+
if (member['@sql.append']) {
|
|
21
|
+
if (this.artifact.query)
|
|
22
|
+
this.message('anno-invalid-sql-view-element', path, { anno: 'sql.append' }, `Annotation $(ANNO) can't be used on elements in views` );
|
|
23
|
+
else if (this.csnUtils.isStructured(member))
|
|
24
|
+
this.message('anno-invalid-sql-struct', path, { anno: 'sql.append' }, `Annotation $(ANNO) can't be used on structured elements` );
|
|
25
|
+
else
|
|
26
|
+
checkValidAnnoValue(member, '@sql.append', path, this.error, this.options);
|
|
31
27
|
}
|
|
32
28
|
}
|
|
33
29
|
|
|
@@ -54,19 +50,24 @@ function checkValidAnnoValue(carrier, annotation, path, error, options) {
|
|
|
54
50
|
* @param {string} artifactName
|
|
55
51
|
*/
|
|
56
52
|
function checkSqlAnnotationOnArtifact(artifact, artifactName) {
|
|
57
|
-
if (
|
|
58
|
-
if (artifact['@sql.prepend'])
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
53
|
+
if (artifact.kind !== 'entity') {
|
|
54
|
+
if (artifact['@sql.prepend'])
|
|
55
|
+
this.message('anno-invalid-sql-kind', [ 'definitions', artifactName ], { name: '@sql.prepend', kind: artifact.kind }, `Annotation $(NAME) can't be used on an artifact of kind $(KIND)` );
|
|
56
|
+
if (artifact['@sql.append'])
|
|
57
|
+
this.message('anno-invalid-sql-kind', [ 'definitions', artifactName ], { name: '@sql.append', kind: artifact.kind }, `Annotation $(NAME) can't be used on an artifact of kind $(KIND)` );
|
|
58
|
+
}
|
|
59
|
+
else if (artifact['@sql.prepend']) {
|
|
60
|
+
if (artifact.query)
|
|
61
|
+
this.message('anno-invalid-sql-view', [ 'definitions', artifactName ], { name: '@sql.prepend' }, `Annotation $(NAME) can't be used on views` );
|
|
62
|
+
else
|
|
63
|
+
checkValidAnnoValue(artifact, '@sql.prepend', [ 'definitions', artifactName ], this.error, this.options);
|
|
64
|
+
}
|
|
64
65
|
|
|
65
|
-
if (artifact['@sql.replace'])
|
|
66
|
-
this.error(null, [ 'definitions', artifactName ], { anno: 'sql.replace' }, `Annotation $(ANNO) is reserved and must not be used`);
|
|
67
66
|
|
|
68
|
-
|
|
69
|
-
|
|
67
|
+
if (artifact['@sql.replace'])
|
|
68
|
+
this.error(null, [ 'definitions', artifactName ], { anno: 'sql.replace' }, `Annotation $(ANNO) is reserved and must not be used`);
|
|
69
|
+
|
|
70
|
+
checkValidAnnoValue(artifact, '@sql.append', [ 'definitions', artifactName ], this.error, this.options);
|
|
70
71
|
}
|
|
71
72
|
|
|
72
73
|
// Anything that could terminate the "old" statement and start a new one basically.
|
package/lib/checks/types.js
CHANGED
|
@@ -19,7 +19,7 @@ function checkDecimalScale(member, memberName, prop, path) {
|
|
|
19
19
|
// skip is already filtered in validator, here for completeness
|
|
20
20
|
hasAnnotationValue(this.artifact, '@cds.persistence.skip'))
|
|
21
21
|
return;
|
|
22
|
-
if (member.scale &&
|
|
22
|
+
if (member.scale && (member.scale === 'variable' || member.scale === 'floating'))
|
|
23
23
|
this.error(null, path, { name: member.scale }, 'Unexpected scale $(NAME)');
|
|
24
24
|
}
|
|
25
25
|
|
package/lib/checks/validator.js
CHANGED
|
@@ -14,11 +14,10 @@ const checkUsedTypesForAnonymousAspectComposition = require('./managedInType');
|
|
|
14
14
|
const checkForEmptyOrOnlyVirtual = require('./emptyOrOnlyVirtual');
|
|
15
15
|
// forOdata
|
|
16
16
|
const { validateDefaultValues } = require('./defaultValues');
|
|
17
|
-
// const { checkChainedArray } = require('./arrayOfs');
|
|
18
17
|
const { checkActionOrFunction } = require('./actionsFunctions');
|
|
19
18
|
const {
|
|
20
|
-
checkCoreMediaTypeAllowence,
|
|
21
|
-
|
|
19
|
+
checkCoreMediaTypeAllowence, checkAnalytics,
|
|
20
|
+
checkAtSapAnnotations, checkReadOnlyAndInsertOnly,
|
|
22
21
|
} = require('./annotationsOData');
|
|
23
22
|
// both
|
|
24
23
|
const { validateOnCondition, validateMixinOnCondition } = require('./onConditions');
|
|
@@ -92,7 +91,6 @@ const forOdataArtifactValidators
|
|
|
92
91
|
// the renderer does not work because the enricher can't handle certain
|
|
93
92
|
// OData specifics.
|
|
94
93
|
// checkChainedArray,
|
|
95
|
-
checkForMultipleCoreMediaTypes,
|
|
96
94
|
checkReadOnlyAndInsertOnly,
|
|
97
95
|
];
|
|
98
96
|
|
|
@@ -129,7 +127,7 @@ function _validate(csn, that,
|
|
|
129
127
|
iterateOptions = {}) {
|
|
130
128
|
const { cleanup } = enrich(csn);
|
|
131
129
|
|
|
132
|
-
applyTransformations(csn, mergeCsnValidators(csnValidators, that), [],
|
|
130
|
+
applyTransformations(csn, mergeCsnValidators(csnValidators, that), [], { drillRef: true });
|
|
133
131
|
|
|
134
132
|
forEachDefinition(csn, (artifact, artifactName, prop, path) => {
|
|
135
133
|
artifactValidators.forEach((artifactValidator) => {
|
|
@@ -204,12 +202,9 @@ function forHana(csn, that) {
|
|
|
204
202
|
),
|
|
205
203
|
forHanaQueryValidators.concat(commonQueryValidators),
|
|
206
204
|
{
|
|
207
|
-
skipArtifact: artifact => artifact.abstract ||
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
'function',
|
|
211
|
-
'event',
|
|
212
|
-
],
|
|
205
|
+
skipArtifact: artifact => artifact.abstract ||
|
|
206
|
+
hasAnnotationValue(artifact, '@cds.persistence.skip') ||
|
|
207
|
+
[ 'action', 'function', 'event' ].includes(artifact.kind),
|
|
213
208
|
});
|
|
214
209
|
}
|
|
215
210
|
|
|
@@ -72,6 +72,7 @@ const { locationString, hasErrors } = require('../base/messages');
|
|
|
72
72
|
// Properties that can appear where a type can have type arguments.
|
|
73
73
|
const typeProperties = [
|
|
74
74
|
'type', '$typeArgs', 'length', 'precision', 'scale', 'srid',
|
|
75
|
+
'_effectiveType',
|
|
75
76
|
];
|
|
76
77
|
|
|
77
78
|
function assertConsistency( model, stage ) {
|
|
@@ -298,6 +299,7 @@ function assertConsistency( model, stage ) {
|
|
|
298
299
|
},
|
|
299
300
|
expand: { kind: [ 'element' ], inherits: 'columns' },
|
|
300
301
|
inline: { kind: [ 'element' ], inherits: 'columns' },
|
|
302
|
+
$noOrigin: { kind: [ 'element' ], test: TODO },
|
|
301
303
|
excludingDict: {
|
|
302
304
|
kind: 'element',
|
|
303
305
|
test: isDictionary( definition ), // definition since redef
|
|
@@ -325,8 +327,8 @@ function assertConsistency( model, stage ) {
|
|
|
325
327
|
kind: true,
|
|
326
328
|
requires: [ 'location' ],
|
|
327
329
|
optional: [
|
|
328
|
-
'path', 'elements', '_outer',
|
|
329
|
-
'scope', '_artifact', '$inferred', '$expand',
|
|
330
|
+
'path', 'elements', '_outer', '_parent', '_main', '_block', 'kind',
|
|
331
|
+
'scope', '_artifact', '$inferred', '$expand', '$tableAliases', '_$next',
|
|
330
332
|
'_effectiveType', // by propagation
|
|
331
333
|
],
|
|
332
334
|
},
|
|
@@ -641,7 +643,8 @@ function assertConsistency( model, stage ) {
|
|
|
641
643
|
* and `localized` namespaces.
|
|
642
644
|
*/
|
|
643
645
|
function builtin( node, parent, prop, spec, name ) {
|
|
644
|
-
|
|
646
|
+
const type = typeof node;
|
|
647
|
+
if (type !== 'string' && type !== 'boolean')
|
|
645
648
|
throw new Error(`Property '${ prop }' must be a boolean or string but was '${ typeof node }'${ at( [ node, parent ], prop, name ) }` );
|
|
646
649
|
|
|
647
650
|
if (parent.kind !== 'namespace')
|
package/lib/compiler/base.js
CHANGED
|
@@ -45,6 +45,7 @@ const kindProperties = {
|
|
|
45
45
|
noDep: 'special',
|
|
46
46
|
elements: true, /* only for parse-cdl */
|
|
47
47
|
actions: true, /* only for parse-cdl */
|
|
48
|
+
enum: true, /* only for parse-cdl */
|
|
48
49
|
},
|
|
49
50
|
annotate: {
|
|
50
51
|
isExtension: true, noDep: 'special', elements: true, enum: true, actions: true, params: true,
|
package/lib/compiler/builtins.js
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
// The builtin artifacts of CDS
|
|
2
2
|
|
|
3
|
+
// TODO: split this file
|
|
4
|
+
// - in base/: common definitions
|
|
5
|
+
// - in compiler/: XSN-specific
|
|
6
|
+
// - in ?: CSN-specific
|
|
7
|
+
|
|
3
8
|
'use strict';
|
|
4
9
|
|
|
5
10
|
const { builtinLocation } = require('../base/location');
|
|
6
|
-
const { setProp } = require('./utils');
|
|
11
|
+
const { setLink: setProp } = require('./utils');
|
|
7
12
|
|
|
8
13
|
const core = {
|
|
9
14
|
String: { parameters: [ 'length' ], category: 'string' },
|
|
@@ -41,6 +46,16 @@ const coreHana = {
|
|
|
41
46
|
ST_GEOMETRY: { parameters: [ { name: 'srid', literal: 'number', val: 0 } ], category: 'geo' },
|
|
42
47
|
};
|
|
43
48
|
|
|
49
|
+
const typeParameters = {
|
|
50
|
+
expectedLiteralsFor: {
|
|
51
|
+
length: [ 'number' ],
|
|
52
|
+
scale: [ 'number', 'string' ],
|
|
53
|
+
precision: [ 'number' ],
|
|
54
|
+
srid: [ 'number' ],
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
typeParameters.list = Object.keys( typeParameters.expectedLiteralsFor );
|
|
58
|
+
|
|
44
59
|
// const hana = {
|
|
45
60
|
// BinaryFloat: {},
|
|
46
61
|
// LocalDate: {},
|
|
@@ -56,7 +71,6 @@ const coreHana = {
|
|
|
56
71
|
* (do not add more - make it part of the SQL renderer to remove parentheses for
|
|
57
72
|
* other funny SQL functions like CURRENT_UTCTIMESTAMP).
|
|
58
73
|
*/
|
|
59
|
-
|
|
60
74
|
const functionsWithoutParens = [
|
|
61
75
|
'CURRENT_DATE', 'CURRENT_TIME', 'CURRENT_TIMESTAMP',
|
|
62
76
|
'CURRENT_USER', 'SESSION_USER', 'SYSTEM_USER',
|
|
@@ -176,7 +190,8 @@ function isRelationTypeName(typeName) {
|
|
|
176
190
|
function isInReservedNamespace(absolute) {
|
|
177
191
|
return absolute.startsWith( 'cds.') &&
|
|
178
192
|
!absolute.match(/^cds\.foundation(\.|$)/) &&
|
|
179
|
-
!absolute.match(/^cds\.outbox(\.|$)/)
|
|
193
|
+
!absolute.match(/^cds\.outbox(\.|$)/) && // Requested by Node runtime
|
|
194
|
+
!absolute.match(/^cds\.xt(\.|$)/); // Requested by Mtx
|
|
180
195
|
}
|
|
181
196
|
|
|
182
197
|
/**
|
|
@@ -214,9 +229,6 @@ function initBuiltins( model ) {
|
|
|
214
229
|
model.$builtins.hana = hana;
|
|
215
230
|
cds._subArtifacts.hana = hana;
|
|
216
231
|
env( coreHana, 'cds.hana.', hana );
|
|
217
|
-
// namespace:"localized" stores localized convenience views ---
|
|
218
|
-
const localized = createNamespace( 'localized', true );
|
|
219
|
-
model.definitions.localized = localized;
|
|
220
232
|
model.$internal = { $frontend: '$internal' };
|
|
221
233
|
return;
|
|
222
234
|
|
|
@@ -310,6 +322,7 @@ function initBuiltins( model ) {
|
|
|
310
322
|
}
|
|
311
323
|
|
|
312
324
|
module.exports = {
|
|
325
|
+
typeParameters,
|
|
313
326
|
functionsWithoutParens,
|
|
314
327
|
specialFunctions,
|
|
315
328
|
initBuiltins,
|
package/lib/compiler/checks.js
CHANGED
|
@@ -24,6 +24,7 @@ function check( model ) { // = XSN
|
|
|
24
24
|
error, warning, message,
|
|
25
25
|
} = model.$messageFunctions;
|
|
26
26
|
forEachDefinition( model, checkArtifact );
|
|
27
|
+
checkSapCommonLocale( model, model.$messageFunctions );
|
|
27
28
|
return;
|
|
28
29
|
|
|
29
30
|
function checkArtifact( art ) {
|
|
@@ -447,69 +448,10 @@ function check( model ) { // = XSN
|
|
|
447
448
|
// params are limited to actual values and params
|
|
448
449
|
if (pathStep.args)
|
|
449
450
|
checkExpression(pathStep.args);
|
|
450
|
-
|
|
451
|
-
if (!path[0] || !path[0]._navigation) { // TODO: Discuss (see #4108)
|
|
452
|
-
checkPathForMissingArguments(pathStep);
|
|
453
|
-
}
|
|
454
451
|
}
|
|
455
452
|
});
|
|
456
453
|
}
|
|
457
454
|
|
|
458
|
-
/**
|
|
459
|
-
* Check whether the argument count of the given path expression matches its artifact.
|
|
460
|
-
* If there is a mismatch, an error is issued.
|
|
461
|
-
*
|
|
462
|
-
* @param {object} pathStep The expression to check
|
|
463
|
-
*/
|
|
464
|
-
function checkPathForMissingArguments(pathStep) {
|
|
465
|
-
// _artifact may not be set, e.g. for functions like `convert_currency( amount => 3 )`
|
|
466
|
-
// _navigation must not be set or we would (for example) check each field of an entity
|
|
467
|
-
if (!pathStep._artifact || pathStep._navigation)
|
|
468
|
-
return;
|
|
469
|
-
|
|
470
|
-
const isAssociation = !!pathStep._artifact.target;
|
|
471
|
-
if (isAssociation) {
|
|
472
|
-
const targetFinalType = pathStep._artifact.target._artifact &&
|
|
473
|
-
pathStep._artifact.target._artifact._effectiveType;
|
|
474
|
-
const finalTypeParams = targetFinalType ? targetFinalType.params : null;
|
|
475
|
-
compareActualNamedArgsWithFormalNamedArgs(pathStep.args, finalTypeParams);
|
|
476
|
-
}
|
|
477
|
-
else {
|
|
478
|
-
// Parameters can only be provided when navigating along associations, so because this path
|
|
479
|
-
// is for non-associations, checking arguments along a navigation is unnecessary and faulty.
|
|
480
|
-
compareActualNamedArgsWithFormalNamedArgs(pathStep.args, pathStep._artifact.params);
|
|
481
|
-
}
|
|
482
|
-
|
|
483
|
-
/**
|
|
484
|
-
* Compare two argument dictionaries for correct argument count.
|
|
485
|
-
* @param {object} actualArgs
|
|
486
|
-
* @param {object} formalArgs
|
|
487
|
-
*/
|
|
488
|
-
function compareActualNamedArgsWithFormalNamedArgs(actualArgs, formalArgs) {
|
|
489
|
-
actualArgs = actualArgs || {};
|
|
490
|
-
formalArgs = formalArgs || {};
|
|
491
|
-
|
|
492
|
-
const aArgsCount = Object.keys(actualArgs).length;
|
|
493
|
-
const expectedNames = Object.keys(formalArgs);
|
|
494
|
-
|
|
495
|
-
const missingArgs = [];
|
|
496
|
-
for (const fAName in formalArgs) {
|
|
497
|
-
if (!actualArgs[fAName] && !formalArgs[fAName].default)
|
|
498
|
-
missingArgs.push(fAName);
|
|
499
|
-
}
|
|
500
|
-
|
|
501
|
-
if (missingArgs.length) {
|
|
502
|
-
error(null, [ pathStep.location, pathStep ],
|
|
503
|
-
{ names: missingArgs, expected: expectedNames.length, given: aArgsCount },
|
|
504
|
-
'Expected $(EXPECTED) arguments but $(GIVEN) given; missing: $(NAMES)');
|
|
505
|
-
}
|
|
506
|
-
// Note:
|
|
507
|
-
// Unknown arguments are already handled by messages
|
|
508
|
-
// args-expected-named and args-undefined-param
|
|
509
|
-
}
|
|
510
|
-
}
|
|
511
|
-
|
|
512
|
-
|
|
513
455
|
function checkAssociation(elem) {
|
|
514
456
|
// TODO: yes, a check similar to this could make it into the compiler)
|
|
515
457
|
// when virtual element is part of association
|
|
@@ -635,7 +577,7 @@ function check( model ) { // = XSN
|
|
|
635
577
|
return checkTreeLikeExpression(xpr, allowAssocTail);
|
|
636
578
|
}
|
|
637
579
|
/**
|
|
638
|
-
* Check
|
|
580
|
+
* Check whether the supplied argument is a virtual element
|
|
639
581
|
*
|
|
640
582
|
* TO CLARIFY: do we want the "no virtual element" check for virtual elements/columns, too?
|
|
641
583
|
*
|
|
@@ -945,6 +887,27 @@ function check( model ) { // = XSN
|
|
|
945
887
|
}
|
|
946
888
|
}
|
|
947
889
|
|
|
890
|
+
/**
|
|
891
|
+
* Checks that sap.common.Locale is of type cds.String. This limitation may
|
|
892
|
+
* be lifted later on.
|
|
893
|
+
*
|
|
894
|
+
* @param {XSN.Model} model
|
|
895
|
+
* @param {object} messageFunctions
|
|
896
|
+
*/
|
|
897
|
+
function checkSapCommonLocale( model, messageFunctions ) {
|
|
898
|
+
const localeArt = model.definitions['sap.common.Locale'];
|
|
899
|
+
if (localeArt) {
|
|
900
|
+
const type = localeArt._effectiveType;
|
|
901
|
+
const isCdsString = type && type.name && type.name.absolute === 'cds.String';
|
|
902
|
+
if (!isCdsString) {
|
|
903
|
+
const { message } = messageFunctions;
|
|
904
|
+
message('type-expected-builtin', [ localeArt.name.location, localeArt ],
|
|
905
|
+
{ name: 'sap.common.Locale' },
|
|
906
|
+
'Expected $(NAME) to be a string type');
|
|
907
|
+
}
|
|
908
|
+
}
|
|
909
|
+
}
|
|
910
|
+
|
|
948
911
|
// For each property named 'path' in 'node' (recursively), call callback(path, node)
|
|
949
912
|
//
|
|
950
913
|
// TODO: remove - this is not a good way to traverse expressions
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
|
|
17
17
|
'use strict';
|
|
18
18
|
|
|
19
|
-
const { setProp } = require('
|
|
19
|
+
const { setLink: setProp } = require('./utils'); // check enum/non-enum
|
|
20
20
|
|
|
21
21
|
// Detect cyclic dependencies between all nodes reachable from `definitions`.
|
|
22
22
|
// If such a dependency is found, call `reportCycle` with arguments `dep.art`
|