@sap/cds-compiler 2.5.2 → 2.11.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 +235 -9
- package/bin/cdsc.js +44 -27
- package/bin/cdsse.js +1 -0
- package/doc/CHANGELOG_BETA.md +37 -3
- package/lib/api/.eslintrc.json +2 -0
- package/lib/api/main.js +37 -123
- package/lib/api/options.js +27 -15
- package/lib/api/validate.js +34 -9
- package/lib/backends.js +9 -89
- package/lib/base/dictionaries.js +2 -1
- package/lib/base/keywords.js +32 -2
- package/lib/base/message-registry.js +73 -11
- package/lib/base/messages.js +86 -30
- package/lib/base/model.js +6 -6
- package/lib/base/optionProcessorHelper.js +56 -22
- package/lib/checks/defaultValues.js +27 -2
- package/lib/checks/elements.js +1 -6
- 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 +25 -7
- package/lib/checks/selectItems.js +29 -2
- package/lib/checks/types.js +26 -2
- package/lib/checks/unknownMagic.js +41 -0
- package/lib/checks/utils.js +61 -0
- package/lib/checks/validator.js +60 -7
- package/lib/compiler/assert-consistency.js +23 -7
- package/lib/compiler/base.js +65 -0
- package/lib/compiler/builtins.js +30 -1
- package/lib/compiler/checks.js +8 -5
- package/lib/compiler/definer.js +157 -133
- package/lib/compiler/index.js +89 -31
- package/lib/compiler/propagator.js +5 -2
- package/lib/compiler/resolver.js +375 -185
- package/lib/compiler/shared.js +49 -202
- package/lib/compiler/utils.js +173 -0
- package/lib/edm/annotations/genericTranslation.js +183 -187
- package/lib/edm/csn2edm.js +104 -108
- package/lib/edm/edm.js +18 -21
- package/lib/edm/edmPreprocessor.js +388 -146
- package/lib/edm/edmUtils.js +104 -34
- package/lib/gen/Dictionary.json +22 -0
- package/lib/gen/language.checksum +1 -1
- package/lib/gen/language.interp +28 -1
- package/lib/gen/language.tokens +79 -69
- package/lib/gen/languageLexer.interp +28 -1
- package/lib/gen/languageLexer.js +879 -805
- package/lib/gen/languageLexer.tokens +71 -62
- package/lib/gen/languageParser.js +5330 -4300
- package/lib/json/from-csn.js +110 -52
- package/lib/json/to-csn.js +434 -120
- package/lib/language/antlrParser.js +15 -3
- package/lib/language/errorStrategy.js +1 -0
- package/lib/language/genericAntlrParser.js +93 -26
- package/lib/language/language.g4 +172 -31
- package/lib/main.d.ts +216 -19
- package/lib/main.js +32 -7
- package/lib/model/api.js +78 -0
- package/lib/model/csnRefs.js +413 -149
- package/lib/model/csnUtils.js +286 -75
- package/lib/model/enrichCsn.js +50 -6
- package/lib/model/revealInternalProperties.js +22 -5
- package/lib/modelCompare/compare.js +39 -21
- package/lib/optionProcessor.js +35 -18
- package/lib/render/.eslintrc.json +4 -1
- package/lib/render/DuplicateChecker.js +9 -6
- package/lib/render/toCdl.js +121 -36
- package/lib/render/toHdbcds.js +148 -98
- package/lib/render/toSql.js +114 -43
- package/lib/render/utils/common.js +8 -13
- package/lib/render/utils/sql.js +3 -3
- package/lib/sql-identifier.js +6 -1
- package/lib/transform/db/assertUnique.js +5 -6
- package/lib/transform/db/constraints.js +281 -106
- package/lib/transform/db/draft.js +11 -8
- package/lib/transform/db/expansion.js +584 -0
- package/lib/transform/db/flattening.js +341 -0
- package/lib/transform/db/groupByOrderBy.js +2 -2
- package/lib/transform/db/transformExists.js +345 -65
- package/lib/transform/db/views.js +438 -0
- package/lib/transform/forHanaNew.js +131 -793
- package/lib/transform/forOdataNew.js +30 -24
- package/lib/transform/localized.js +39 -10
- package/lib/transform/odata/attachPath.js +19 -4
- package/lib/transform/odata/generateForeignKeyElements.js +11 -10
- package/lib/transform/odata/referenceFlattener.js +60 -39
- package/lib/transform/odata/sortByAssociationDependency.js +2 -2
- package/lib/transform/odata/structuralPath.js +72 -0
- package/lib/transform/odata/structureFlattener.js +19 -18
- package/lib/transform/odata/typesExposure.js +22 -12
- package/lib/transform/transformUtilsNew.js +144 -78
- package/lib/transform/translateAssocsToJoins.js +22 -27
- package/lib/transform/universalCsnEnricher.js +67 -0
- package/lib/utils/file.js +5 -14
- package/lib/utils/moduleResolve.js +6 -8
- package/lib/utils/term.js +65 -42
- package/lib/utils/timetrace.js +48 -26
- package/package.json +1 -1
- package/lib/json/walker.js +0 -26
- package/lib/transform/sqlite +0 -0
- package/lib/utils/string.js +0 -17
package/lib/render/toCdl.js
CHANGED
|
@@ -8,11 +8,13 @@ const {
|
|
|
8
8
|
isBuiltinType, generatedByCompilerVersion, getNormalizedQuery,
|
|
9
9
|
} = require('../model/csnUtils');
|
|
10
10
|
const keywords = require('../base/keywords');
|
|
11
|
-
const { renderFunc,
|
|
11
|
+
const { renderFunc, beautifyExprArray, findElement } = require('./utils/common');
|
|
12
12
|
const { checkCSNVersion } = require('../json/csnVersion');
|
|
13
|
-
const timetrace = require('../utils/timetrace');
|
|
13
|
+
const { timetrace } = require('../utils/timetrace');
|
|
14
14
|
const { csnRefs } = require('../model/csnRefs');
|
|
15
15
|
const { forEachDefinition } = require('../model/csnUtils');
|
|
16
|
+
const enrichUniversalCsn = require('../transform/universalCsnEnricher');
|
|
17
|
+
const { isBetaEnabled } = require('../base/model');
|
|
16
18
|
|
|
17
19
|
/**
|
|
18
20
|
* Render the CSN model 'model' to CDS source text. One source is created per
|
|
@@ -33,6 +35,9 @@ function toCdsSourceCsn(csn, options) {
|
|
|
33
35
|
// Skip compactModel if already using CSN
|
|
34
36
|
// const csn = cloneCsn(model, options);
|
|
35
37
|
|
|
38
|
+
if (options.csnFlavor === 'universal' && isBetaEnabled(options, 'enableUniversalCsn'))
|
|
39
|
+
enrichUniversalCsn(csn, options);
|
|
40
|
+
|
|
36
41
|
checkCSNVersion(csn, options);
|
|
37
42
|
|
|
38
43
|
const result = Object.create(null);
|
|
@@ -50,16 +55,20 @@ function toCdsSourceCsn(csn, options) {
|
|
|
50
55
|
result[main] += `${sourceStr}\n`;
|
|
51
56
|
});
|
|
52
57
|
|
|
53
|
-
// Apply possible subelement annotations with an "annotate X with"
|
|
58
|
+
// Apply possible subelement/action return annotations with an "annotate X with"
|
|
59
|
+
// Some of them appear in csn.extensions, some not...
|
|
54
60
|
if (subelementAnnotates.length > 0) {
|
|
55
|
-
for (const [ artName, element, elementName ] of subelementAnnotates) {
|
|
56
|
-
|
|
57
|
-
sourceStr
|
|
61
|
+
for (const [ artName, element, elementName, suffix ] of subelementAnnotates) {
|
|
62
|
+
// Suffix is used with action return annotations
|
|
63
|
+
let sourceStr = `annotate ${artName} with ${suffix ? `${suffix} ` : ''}{\n`;
|
|
64
|
+
if (elementName) // action returns do not have element name - we need less {} there
|
|
65
|
+
sourceStr += ` ${elementName} {\n`;
|
|
58
66
|
const env = increaseIndent(increaseIndent(createEnv()));
|
|
59
67
|
const subelements = renderSubelementAnnotates(element, env);
|
|
60
68
|
if (subelements !== '') {
|
|
61
69
|
sourceStr += `${subelements}\n`;
|
|
62
|
-
|
|
70
|
+
if (elementName) // action returns do not have element name - we need less {} there
|
|
71
|
+
sourceStr += ' }\n';
|
|
63
72
|
sourceStr += '}\n';
|
|
64
73
|
result[main] += `${sourceStr}\n`;
|
|
65
74
|
}
|
|
@@ -145,6 +154,12 @@ function toCdsSourceCsn(csn, options) {
|
|
|
145
154
|
if (ext.elements)
|
|
146
155
|
result += renderElementExtensions(ext.elements, env);
|
|
147
156
|
|
|
157
|
+
// Returns annotations
|
|
158
|
+
if (ext.returns) {
|
|
159
|
+
const childEnv = increaseIndent(env);
|
|
160
|
+
result += ` with returns${renderElementExtensions(ext.returns.elements, childEnv)}`;
|
|
161
|
+
}
|
|
162
|
+
|
|
148
163
|
// Action annotations
|
|
149
164
|
if (ext.actions) {
|
|
150
165
|
result += ' actions {\n';
|
|
@@ -162,10 +177,19 @@ function toCdsSourceCsn(csn, options) {
|
|
|
162
177
|
|
|
163
178
|
result += `${paramAnnotations.join(',\n')}\n${childEnv.indent})`;
|
|
164
179
|
}
|
|
180
|
+
// Annotations on action returns
|
|
181
|
+
if (action.returns && action.returns.elements) {
|
|
182
|
+
const grandChildEnv = increaseIndent(childEnv);
|
|
183
|
+
result += ` returns${renderElementExtensions(action.returns.elements, grandChildEnv)}`;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
|
|
165
187
|
result += ';\n';
|
|
166
188
|
}
|
|
167
189
|
result += `${env.indent}}`;
|
|
168
190
|
}
|
|
191
|
+
|
|
192
|
+
|
|
169
193
|
result += ';';
|
|
170
194
|
return result;
|
|
171
195
|
}).join('\n');
|
|
@@ -205,6 +229,7 @@ function toCdsSourceCsn(csn, options) {
|
|
|
205
229
|
function renderArtifact(artifactName, art, env) {
|
|
206
230
|
// FIXME: Correctly build the paths during runtime to give better locations
|
|
207
231
|
env.path = [ 'definitions', artifactName ];
|
|
232
|
+
env.artifactName = artifactName;
|
|
208
233
|
|
|
209
234
|
switch (art.kind) {
|
|
210
235
|
case 'entity':
|
|
@@ -509,6 +534,7 @@ function toCdsSourceCsn(csn, options) {
|
|
|
509
534
|
* @param {Boolean} [isSubElement]
|
|
510
535
|
*/
|
|
511
536
|
function renderElement(elementName, elm, env, isSubElement) {
|
|
537
|
+
env.elementName = elementName;
|
|
512
538
|
let result = renderDocComment(elm, env) + renderAnnotationAssignments(elm, env);
|
|
513
539
|
const quotedElementName = quoteOrUppercaseId(elementName);
|
|
514
540
|
result += `${env.indent + (elm.virtual ? 'virtual ' : '') +
|
|
@@ -516,10 +542,11 @@ function toCdsSourceCsn(csn, options) {
|
|
|
516
542
|
((elm.masked && !elm._ignoreMasked) ? 'masked ' : '') +
|
|
517
543
|
quotedElementName} : ${
|
|
518
544
|
renderTypeReference(elm, env, undefined)
|
|
519
|
-
}${renderNullability(elm)}`;
|
|
545
|
+
}${elm.on ? '' : renderNullability(elm)}`;
|
|
520
546
|
if (elm.default)
|
|
521
547
|
result += ` default ${renderExpr(elm.default, env)}`;
|
|
522
548
|
|
|
549
|
+
delete env.elementName;
|
|
523
550
|
return `${result};\n`;
|
|
524
551
|
}
|
|
525
552
|
|
|
@@ -552,7 +579,7 @@ function toCdsSourceCsn(csn, options) {
|
|
|
552
579
|
* @return {string}
|
|
553
580
|
*/
|
|
554
581
|
function renderQueryActionsAndFunctions(artifactName, art, env) {
|
|
555
|
-
let result =
|
|
582
|
+
let result = renderActionsAndFunctions(art, env);
|
|
556
583
|
// Even if we have seen actions/functions, they might all have been ignored
|
|
557
584
|
if (result !== '')
|
|
558
585
|
result = `${env.indent}extend entity ${artifactName} with${result};`;
|
|
@@ -585,7 +612,7 @@ function toCdsSourceCsn(csn, options) {
|
|
|
585
612
|
}
|
|
586
613
|
// Now iterate elements - render an annotation if it is different from the column's
|
|
587
614
|
const childEnv = increaseIndent(env);
|
|
588
|
-
let result =
|
|
615
|
+
let result = '';
|
|
589
616
|
for (const elemName in art.elements) {
|
|
590
617
|
let elemAnnotations = '';
|
|
591
618
|
const elem = art.elements[elemName];
|
|
@@ -688,7 +715,7 @@ function toCdsSourceCsn(csn, options) {
|
|
|
688
715
|
|
|
689
716
|
// Even the first step might have parameters and/or a filter
|
|
690
717
|
if (path.ref[0].args)
|
|
691
|
-
result += `(${renderArgs(path.ref[0]
|
|
718
|
+
result += `(${renderArgs(path.ref[0], ':', env)})`;
|
|
692
719
|
|
|
693
720
|
if (path.ref[0].where)
|
|
694
721
|
result += `[${path.ref[0].cardinality ? (`${path.ref[0].cardinality.max}: `) : ''}${renderExpr(path.ref[0].where, env, true, true)}]`;
|
|
@@ -739,17 +766,13 @@ function toCdsSourceCsn(csn, options) {
|
|
|
739
766
|
result += 'virtual ';
|
|
740
767
|
|
|
741
768
|
const key = col.key ? 'key ' : '';
|
|
742
|
-
|
|
769
|
+
// Use special rendering for .expand/.inline - renderExpr cannot easily handle some cases
|
|
770
|
+
result += key + ((col.expand || col.inline) ? renderInlineExpand(col, env) : renderExpr(col, env, true));
|
|
743
771
|
|
|
744
|
-
|
|
772
|
+
// Alias is already handled by renderInlineExpand
|
|
773
|
+
if (!col.inline && !col.expand && col.as)
|
|
745
774
|
result += ` as ${quoteOrUppercaseId(col.as)}`;
|
|
746
775
|
|
|
747
|
-
if (col.inline)
|
|
748
|
-
renderInlineExpand('inline');
|
|
749
|
-
|
|
750
|
-
if (col.expand)
|
|
751
|
-
renderInlineExpand('expand');
|
|
752
|
-
|
|
753
776
|
// Explicit type provided for the view element?
|
|
754
777
|
if (col.cast) {
|
|
755
778
|
// Special case: Explicit association type is actually a redirect
|
|
@@ -764,24 +787,69 @@ function toCdsSourceCsn(csn, options) {
|
|
|
764
787
|
}
|
|
765
788
|
}
|
|
766
789
|
return result;
|
|
790
|
+
}
|
|
767
791
|
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
792
|
+
/**
|
|
793
|
+
* For the current column, render a (nested) inline/expand. If the current column
|
|
794
|
+
* does not have an .expand/.inline, '' is returned
|
|
795
|
+
*
|
|
796
|
+
* @param {object} col Thing with .expand or .inline
|
|
797
|
+
* @param {CdlRenderEnvironment} parentEnv
|
|
798
|
+
* @returns {string}
|
|
799
|
+
*/
|
|
800
|
+
function renderInlineExpand(col, parentEnv) {
|
|
801
|
+
if (!col.inline && !col.expand)
|
|
802
|
+
return '';
|
|
803
|
+
|
|
804
|
+
return renderIX(col, parentEnv);
|
|
805
|
+
|
|
806
|
+
function renderIX(obj, env) {
|
|
807
|
+
// No expression to render for { * } as alias
|
|
808
|
+
let result = (obj.as && obj.expand && !obj.ref) ? '' : renderExpr(obj, env);
|
|
809
|
+
|
|
810
|
+
// s as alias { * }
|
|
811
|
+
if (obj.as && (obj.ref || obj.xpr || obj.val !== undefined || obj.func !== undefined))
|
|
812
|
+
result += ` as ${obj.as}`;
|
|
813
|
+
|
|
814
|
+
// We found a leaf - no further drilling
|
|
815
|
+
if (!obj.inline && !obj.expand) {
|
|
816
|
+
if (obj.cast && obj.cast.type) {
|
|
817
|
+
result += ` : ${renderTypeReference(obj.cast, createEnv())}`;
|
|
818
|
+
}
|
|
819
|
+
else if (obj.cast && obj.cast.target) { // test tbd
|
|
820
|
+
result += ` : redirected to ${renderAbsoluteNameWithQuotes(obj.cast.target)}`;
|
|
821
|
+
if (obj.cast.on)
|
|
822
|
+
result += ` on ${renderExpr(obj.cast.on, env, true, true)}`;
|
|
823
|
+
else if (obj.cast.keys)
|
|
824
|
+
result += ` { ${Object.keys(obj.cast.keys).map(name => renderForeignKey(obj.cast.keys[name], env)).join(', ')} }`;
|
|
825
|
+
}
|
|
826
|
+
return result;
|
|
827
|
+
}
|
|
828
|
+
|
|
829
|
+
if (obj.inline)
|
|
775
830
|
result += '.{\n';
|
|
776
831
|
else
|
|
777
|
-
result += ' {\n';
|
|
832
|
+
result += result !== '' ? ' {\n' : '{\n';
|
|
778
833
|
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
834
|
+
// Drill down and render children of the expand/inline
|
|
835
|
+
const childEnv = increaseIndent(env);
|
|
836
|
+
const expandInline = obj.expand || obj.inline;
|
|
837
|
+
expandInline.forEach((elm, i) => {
|
|
838
|
+
result += `${childEnv.indent}${renderIX(elm, childEnv)}`;
|
|
839
|
+
if (i < expandInline.length - 1)
|
|
782
840
|
result += ',\n';
|
|
783
841
|
});
|
|
784
842
|
result += `\n${env.indent}}`;
|
|
843
|
+
|
|
844
|
+
// Don't forget about the .excluding
|
|
845
|
+
if (obj.excluding)
|
|
846
|
+
result += ` excluding { ${obj.excluding.join(',')} }`;
|
|
847
|
+
|
|
848
|
+
// { * } as expand
|
|
849
|
+
if (!obj.ref && obj.as)
|
|
850
|
+
result += ` as ${obj.as}`;
|
|
851
|
+
|
|
852
|
+
return result;
|
|
785
853
|
}
|
|
786
854
|
}
|
|
787
855
|
|
|
@@ -1015,8 +1083,11 @@ function toCdsSourceCsn(csn, options) {
|
|
|
1015
1083
|
const childEnv = increaseIndent(env);
|
|
1016
1084
|
const parameters = Object.keys(act.params || []).map(name => renderParameter(name, act.params[name], childEnv)).join(',\n');
|
|
1017
1085
|
result += (parameters === '') ? '()' : `(\n${parameters}\n${env.indent})`;
|
|
1018
|
-
if (act.returns)
|
|
1086
|
+
if (act.returns) {
|
|
1087
|
+
if (act.returns.type && act.returns.elements) // action returns annotations
|
|
1088
|
+
subelementAnnotates.push([ actionName, act.returns, '', 'returns' ]);
|
|
1019
1089
|
result += ` returns ${renderTypeReference(act.returns, env)}${renderNullability(act.returns)}`;
|
|
1090
|
+
}
|
|
1020
1091
|
|
|
1021
1092
|
result += ';\n';
|
|
1022
1093
|
return result;
|
|
@@ -1092,6 +1163,10 @@ function toCdsSourceCsn(csn, options) {
|
|
|
1092
1163
|
let rc = `many ${renderTypeReference(elm.items, env)}`;
|
|
1093
1164
|
if (elm.items.notNull != null)
|
|
1094
1165
|
rc += elm.items.notNull ? ' not null' : ' null';
|
|
1166
|
+
// many sub element annotates
|
|
1167
|
+
if (elm.items.type && elm.items.elements && env.artifactName)
|
|
1168
|
+
subelementAnnotates.push([ env.artifactName, elm.items, env.elementName ]);
|
|
1169
|
+
|
|
1095
1170
|
return rc;
|
|
1096
1171
|
}
|
|
1097
1172
|
|
|
@@ -1275,7 +1350,7 @@ function toCdsSourceCsn(csn, options) {
|
|
|
1275
1350
|
function renderExpr(x, env, inline = true, inExpr = false) {
|
|
1276
1351
|
// Compound expression
|
|
1277
1352
|
if (Array.isArray(x))
|
|
1278
|
-
return
|
|
1353
|
+
return beautifyExprArray(x.map(item => renderExpr(item, env, inline, inExpr)));
|
|
1279
1354
|
|
|
1280
1355
|
if (typeof x === 'object' && x !== null) {
|
|
1281
1356
|
if (inExpr && x.cast && x.cast.type)
|
|
@@ -1329,6 +1404,12 @@ function toCdsSourceCsn(csn, options) {
|
|
|
1329
1404
|
// FIXME: no extra magic with x.param or x.global
|
|
1330
1405
|
return `${(x.param || x.global) ? ':' : ''}${x.ref.map(renderPathStep).join('.')}`;
|
|
1331
1406
|
}
|
|
1407
|
+
else if (x.xpr && x.func) {
|
|
1408
|
+
// window function
|
|
1409
|
+
const funcDef = renderFunc( x.func, x, null, a => renderArgs(a, '=>', env) );
|
|
1410
|
+
const windowFunctionOperator = x.xpr.shift(); // OVER ...
|
|
1411
|
+
return `${funcDef} ${windowFunctionOperator} ( ${renderExpr(x.xpr, env, true)} )`;
|
|
1412
|
+
}
|
|
1332
1413
|
// Function call, possibly with args (use '=>' for named args)
|
|
1333
1414
|
else if (x.func) {
|
|
1334
1415
|
// test for non-regular HANA identifier that needs to be quoted
|
|
@@ -1399,18 +1480,19 @@ function toCdsSourceCsn(csn, options) {
|
|
|
1399
1480
|
|
|
1400
1481
|
// Not really a path step but an object-like function call
|
|
1401
1482
|
if (s.func)
|
|
1402
|
-
return `${s.func}(${renderArgs(s
|
|
1483
|
+
return `${s.func}(${renderArgs(s, '=>', env)})`;
|
|
1403
1484
|
|
|
1404
1485
|
// Path step, possibly with view parameters and/or filters
|
|
1405
1486
|
let result = `${quoteOrUppercaseId(s.id)}`;
|
|
1406
1487
|
if (s.args) {
|
|
1407
1488
|
// View parameters
|
|
1408
|
-
result += `(${renderArgs(s
|
|
1489
|
+
result += `(${renderArgs(s, ':', env)})`;
|
|
1409
1490
|
}
|
|
1410
1491
|
if (s.where) {
|
|
1411
1492
|
// Filter, possibly with cardinality
|
|
1412
1493
|
result += `[${s.cardinality ? (`${s.cardinality.max}: `) : ''}${renderExpr(s.where, env, inline, true)}]`;
|
|
1413
1494
|
}
|
|
1495
|
+
|
|
1414
1496
|
return result;
|
|
1415
1497
|
}
|
|
1416
1498
|
|
|
@@ -1422,12 +1504,13 @@ function toCdsSourceCsn(csn, options) {
|
|
|
1422
1504
|
* Render function arguments or view parameters (positional if array, named if object/dict),
|
|
1423
1505
|
* using 'sep' as separator for positional parameters
|
|
1424
1506
|
*
|
|
1425
|
-
* @param {object
|
|
1507
|
+
* @param {object} node with `args` to render
|
|
1426
1508
|
* @param {string} sep
|
|
1427
1509
|
* @param {CdlRenderEnvironment} env
|
|
1428
1510
|
* @returns {string}
|
|
1429
1511
|
*/
|
|
1430
|
-
function renderArgs(
|
|
1512
|
+
function renderArgs(node, sep, env) {
|
|
1513
|
+
const args = node.args ? node.args : {};
|
|
1431
1514
|
// Positional arguments
|
|
1432
1515
|
if (Array.isArray(args))
|
|
1433
1516
|
return args.map(arg => renderExpr(arg, env)).join(', ');
|
|
@@ -1819,6 +1902,8 @@ function toCdsSourceCsn(csn, options) {
|
|
|
1819
1902
|
*
|
|
1820
1903
|
* @property {string} indent Current indentation as a string, e.g. ' ' for two spaces.
|
|
1821
1904
|
* @property {CSN.Path} [path] CSN path to the current artifact
|
|
1905
|
+
* @property {string} artifactName Name of the artifact - set in renderArtifact
|
|
1906
|
+
* @property {string} elementName Name of the element being rendered - set in renderElement
|
|
1822
1907
|
* @property {{[name: string]: {
|
|
1823
1908
|
quotedName: string,
|
|
1824
1909
|
quotedAlias: string
|