@sap/cds-compiler 5.9.4 → 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 +104 -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 +33 -83
- 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
package/lib/render/toCdl.js
CHANGED
|
@@ -163,14 +163,14 @@ class NameScopeStack {
|
|
|
163
163
|
const baseAlias = aliasName;
|
|
164
164
|
while (this.nonRootSegments.has(aliasName) || this.rootSegments.has(aliasName) || this.#aliasToFqn[aliasName]) {
|
|
165
165
|
// Alias must be unique among _all_ segments and existing USINGs.
|
|
166
|
-
aliasName = `${baseAlias}${++counter}`;
|
|
166
|
+
aliasName = `${ baseAlias }${ ++counter }`;
|
|
167
167
|
}
|
|
168
168
|
}
|
|
169
169
|
|
|
170
170
|
// Always add an alias, even if unnecessary, as we'd otherwise try to create
|
|
171
171
|
// it in #useAliasForPath() again if the same rootName is seen again.
|
|
172
172
|
if (this.#aliasToFqn[aliasName])
|
|
173
|
-
throw new CompilerAssertion(`to.cdl: Alias "${aliasName}" already exists; collision for ${fqn} and ${this.#aliasToFqn[aliasName].path}`);
|
|
173
|
+
throw new CompilerAssertion(`to.cdl: Alias "${ aliasName }" already exists; collision for ${ fqn } and ${ this.#aliasToFqn[aliasName].path }`);
|
|
174
174
|
const alias = new UsingAlias(fqn, aliasName);
|
|
175
175
|
this.#aliasToFqn[aliasName] = alias;
|
|
176
176
|
this.#fqnToAlias[fqn] = alias;
|
|
@@ -196,7 +196,7 @@ class NameScopeStack {
|
|
|
196
196
|
// - `annotate cds.String;` works
|
|
197
197
|
return fqn;
|
|
198
198
|
}
|
|
199
|
-
if (fqn.startsWith(`${leaf.name }.`))
|
|
199
|
+
if (fqn.startsWith(`${ leaf.name }.`))
|
|
200
200
|
return fqn.substring(leaf.name.length + 1); // '+1' => also remove '.'
|
|
201
201
|
throw new CompilerAssertion('to.cdl: Definition to be rendered is not in current name scope!');
|
|
202
202
|
}
|
|
@@ -222,7 +222,7 @@ class NameScopeStack {
|
|
|
222
222
|
for (let i = this.#scopes.length - 1; i >= 1; i--) {
|
|
223
223
|
const tree = this.#scopes[i];
|
|
224
224
|
|
|
225
|
-
if (tree.name && fqn.startsWith(`${tree.name }.`)) {
|
|
225
|
+
if (tree.name && fqn.startsWith(`${ tree.name }.`)) {
|
|
226
226
|
// FQN is in current scope.
|
|
227
227
|
const relativeName = fqn.substring(tree.name.length + 1);
|
|
228
228
|
const relativeRoot = rootPathSegment(relativeName);
|
|
@@ -363,7 +363,7 @@ function createDefinitionPathTree( csn, options ) {
|
|
|
363
363
|
if (!csn.definitions)
|
|
364
364
|
return tree;
|
|
365
365
|
|
|
366
|
-
const useNesting = options.renderCdlDefinitionNesting;
|
|
366
|
+
const useNesting = options.renderCdlDefinitionNesting !== false;
|
|
367
367
|
|
|
368
368
|
for (const defName in csn.definitions) {
|
|
369
369
|
const segments = defName.split('.');
|
|
@@ -415,7 +415,7 @@ class CsnToCdl {
|
|
|
415
415
|
|
|
416
416
|
const env = createEnv();
|
|
417
417
|
|
|
418
|
-
const useNesting =
|
|
418
|
+
const useNesting = this.options.renderCdlDefinitionNesting !== false;
|
|
419
419
|
this.definitionTree = createDefinitionPathTree(this.csn, this.options);
|
|
420
420
|
this.commonNamespace = this.getCommonNamespace();
|
|
421
421
|
|
|
@@ -441,18 +441,13 @@ class CsnToCdl {
|
|
|
441
441
|
|
|
442
442
|
cdlResult.model = this.renderUsingAliases(env.nameEnvStack.getUsings(), env) + cdlResult.model;
|
|
443
443
|
if (this.csn.requires) {
|
|
444
|
-
let usingsStr = this.csn.requires.map(req => `using from '${req}';`).join('\n');
|
|
444
|
+
let usingsStr = this.csn.requires.map(req => `using from '${ req }';`).join('\n');
|
|
445
445
|
usingsStr += '\n\n';
|
|
446
446
|
cdlResult.model = usingsStr + cdlResult.model;
|
|
447
447
|
}
|
|
448
448
|
|
|
449
449
|
if (this.commonNamespace.name)
|
|
450
|
-
cdlResult.model = `namespace ${this.renderArtifactName(this.commonNamespace.name, env)};\n\n${cdlResult.model}`;
|
|
451
|
-
|
|
452
|
-
if (this.csn.namespace) {
|
|
453
|
-
cdlResult.namespace = `namespace ${this.renderArtifactName(this.csn.namespace, createEnv())};\n`;
|
|
454
|
-
cdlResult.namespace += 'using from \'./model.cds\';';
|
|
455
|
-
}
|
|
450
|
+
cdlResult.model = `namespace ${ this.renderArtifactName(this.commonNamespace.name, env) };\n\n${ cdlResult.model }`;
|
|
456
451
|
|
|
457
452
|
this.msg.throwWithError();
|
|
458
453
|
return cdlResult;
|
|
@@ -466,7 +461,7 @@ class CsnToCdl {
|
|
|
466
461
|
*/
|
|
467
462
|
getCommonNamespace() {
|
|
468
463
|
let root = this.definitionTree;
|
|
469
|
-
if (
|
|
464
|
+
if (this.options.renderCdlDefinitionNesting === false || this.options.renderCdlCommonNamespace === false)
|
|
470
465
|
return root; // User does not want common namespace.
|
|
471
466
|
|
|
472
467
|
if (this.csn.vocabularies) {
|
|
@@ -506,20 +501,20 @@ class CsnToCdl {
|
|
|
506
501
|
* @returns {string}
|
|
507
502
|
*/
|
|
508
503
|
renderUsingAliases(aliases, env) {
|
|
509
|
-
if (
|
|
504
|
+
if (this.options.renderCdlDefinitionNesting !== false) {
|
|
510
505
|
// openAPI importer searches for a single USING statement and replaces it.
|
|
511
506
|
// Let's try to be backward compatible.
|
|
512
|
-
return aliases.length > 0 ? `using { ${aliases.map(entry => (entry.requiresExplicitAlias()
|
|
513
|
-
? `${this.quotePathIfRequired(entry.path, env)} as ${this.quoteNonIdentifierOrKeyword(entry.alias, env)}`
|
|
514
|
-
: entry.path)).join(', ')} };\n\n` : '';
|
|
507
|
+
return aliases.length > 0 ? `using { ${ aliases.map(entry => (entry.requiresExplicitAlias()
|
|
508
|
+
? `${ this.quotePathIfRequired(entry.path, env) } as ${ this.quoteNonIdentifierOrKeyword(entry.alias, env) }`
|
|
509
|
+
: entry.path)).join(', ') } };\n\n` : '';
|
|
515
510
|
}
|
|
516
511
|
|
|
517
512
|
let result = '';
|
|
518
513
|
for (const entry of aliases) {
|
|
519
514
|
if (entry.requiresExplicitAlias())
|
|
520
|
-
result += `using { ${this.quotePathIfRequired(entry.path, env)} as ${this.quoteNonIdentifierOrKeyword(entry.alias, env)} };\n`;
|
|
515
|
+
result += `using { ${ this.quotePathIfRequired(entry.path, env) } as ${ this.quoteNonIdentifierOrKeyword(entry.alias, env) } };\n`;
|
|
521
516
|
else
|
|
522
|
-
result += `using { ${entry.path } };\n`;
|
|
517
|
+
result += `using { ${ entry.path } };\n`;
|
|
523
518
|
}
|
|
524
519
|
return result !== '' ? `${ result }\n` : result;
|
|
525
520
|
}
|
|
@@ -535,7 +530,7 @@ class CsnToCdl {
|
|
|
535
530
|
forEachDefinition(this.csn, (artifact, artifactName) => {
|
|
536
531
|
const sourceStr = this.renderDefinition(artifactName, artifact, env);
|
|
537
532
|
if (sourceStr !== '')
|
|
538
|
-
result += `${sourceStr}\n`;
|
|
533
|
+
result += `${ sourceStr }\n`;
|
|
539
534
|
});
|
|
540
535
|
return result;
|
|
541
536
|
}
|
|
@@ -564,7 +559,7 @@ class CsnToCdl {
|
|
|
564
559
|
// Render service/context with nested definitions.
|
|
565
560
|
env.path = [ 'definitions', entry.name ];
|
|
566
561
|
result += that.renderAnnotationAssignmentsAndDocComment(def, env);
|
|
567
|
-
result += `${env.indent}${def.kind} ${ that.renderArtifactName(entry.name, env) } {\n`;
|
|
562
|
+
result += `${ env.indent }${ def.kind } ${ that.renderArtifactName(entry.name, env) } {\n`;
|
|
568
563
|
env.increaseIndent();
|
|
569
564
|
env.nameEnvStack.pushNameEnv(entry);
|
|
570
565
|
if (entry.children)
|
|
@@ -573,12 +568,12 @@ class CsnToCdl {
|
|
|
573
568
|
env.decreaseIndent();
|
|
574
569
|
if (result.at(-1) === '\n' && result.at(-2) === '\n')
|
|
575
570
|
result = result.substring(0, result.length - 1); // to get the closing brace on the next line after a definition, remove one linebreak
|
|
576
|
-
result += `${env.indent}};\n\n`;
|
|
571
|
+
result += `${ env.indent }};\n\n`;
|
|
577
572
|
}
|
|
578
573
|
else if (def) {
|
|
579
574
|
const sourceStr = that.renderDefinition(entry.name, def, env);
|
|
580
575
|
if (sourceStr !== '')
|
|
581
|
-
result += `${sourceStr}\n`;
|
|
576
|
+
result += `${ sourceStr }\n`;
|
|
582
577
|
if (entry.children)
|
|
583
578
|
renderTree(entry);
|
|
584
579
|
}
|
|
@@ -617,7 +612,7 @@ class CsnToCdl {
|
|
|
617
612
|
// indentation and name resolution issues
|
|
618
613
|
env.path = [ 'vocabularies', name ];
|
|
619
614
|
const sourceStr = this.renderArtifact(name, anno, env, 'annotation');
|
|
620
|
-
return `${sourceStr}\n`;
|
|
615
|
+
return `${ sourceStr }\n`;
|
|
621
616
|
}
|
|
622
617
|
|
|
623
618
|
/**
|
|
@@ -668,20 +663,20 @@ class CsnToCdl {
|
|
|
668
663
|
// Includes can't be combined with anything in braces {}.
|
|
669
664
|
const affix = isElementExtend ? 'element ' : '';
|
|
670
665
|
const includes = ext.includes.map((inc, i) => this.renderDefinitionReference(inc, env.withSubPath([ 'includes', i ]))).join(', ');
|
|
671
|
-
result += `${env.indent}extend ${affix}${extName} with ${includes};\n`;
|
|
666
|
+
result += `${ env.indent }extend ${ affix }${ extName } with ${ includes };\n`;
|
|
672
667
|
return result;
|
|
673
668
|
}
|
|
674
669
|
|
|
675
670
|
const typeParams = this.renderTypeParameters(ext, true);
|
|
676
671
|
if (typeParams) {
|
|
677
|
-
result += `${env.indent}extend ${extName} with ${typeParams};\n`;
|
|
672
|
+
result += `${ env.indent }extend ${ extName } with ${ typeParams };\n`;
|
|
678
673
|
return result;
|
|
679
674
|
}
|
|
680
675
|
|
|
681
676
|
// If there is nothing to extend, e.g. only annotations, don't render an
|
|
682
677
|
// empty element list. This would end up in diffs with parseCdl CSN.
|
|
683
678
|
if (!ext.elements && !ext.columns && !ext.actions && !ext.enum) {
|
|
684
|
-
result += `${env.indent}extend ${extName};\n`;
|
|
679
|
+
result += `${ env.indent }extend ${ extName };\n`;
|
|
685
680
|
return result;
|
|
686
681
|
}
|
|
687
682
|
|
|
@@ -691,9 +686,9 @@ class CsnToCdl {
|
|
|
691
686
|
// If there are actions, check if there are also elements/columns, and if so, use the prefix notation.
|
|
692
687
|
const usePrefixNotation = ext.actions && (ext.columns || ext.elements);
|
|
693
688
|
if (usePrefixNotation)
|
|
694
|
-
result += `${env.indent}extend ${this.getExtendPrefixVariant(ext)} ${extName} with {\n`;
|
|
689
|
+
result += `${ env.indent }extend ${ this.getExtendPrefixVariant(ext) } ${ extName } with {\n`;
|
|
695
690
|
else
|
|
696
|
-
result += `${env.indent}extend ${extName} with ${this.getExtendPostfixVariant(ext)}{\n`;
|
|
691
|
+
result += `${ env.indent }extend ${ extName } with ${ this.getExtendPostfixVariant(ext) }{\n`;
|
|
697
692
|
|
|
698
693
|
if (ext.columns)
|
|
699
694
|
result += this.renderViewColumns(ext, env.withIncreasedIndent());
|
|
@@ -711,10 +706,10 @@ class CsnToCdl {
|
|
|
711
706
|
if (!usePrefixNotation)
|
|
712
707
|
result += actions;
|
|
713
708
|
else if (actions !== '')
|
|
714
|
-
result += `${env.indent}} actions {\n${actions}`;
|
|
709
|
+
result += `${ env.indent }} actions {\n${ actions }`;
|
|
715
710
|
}
|
|
716
711
|
|
|
717
|
-
result += `${env.indent}};\n`;
|
|
712
|
+
result += `${ env.indent }};\n`;
|
|
718
713
|
return result;
|
|
719
714
|
}
|
|
720
715
|
|
|
@@ -804,14 +799,14 @@ class CsnToCdl {
|
|
|
804
799
|
let result = this.renderAnnotationAssignmentsAndDocComment(ext, env);
|
|
805
800
|
// Note: Not renderDefinitionReference, because we don't care if there
|
|
806
801
|
// are annotations to unknown things. That's allowed!
|
|
807
|
-
result += `${env.indent}annotate ${this.renderArtifactName(ext.annotate, env)}`;
|
|
802
|
+
result += `${ env.indent }annotate ${ this.renderArtifactName(ext.annotate, env) }`;
|
|
808
803
|
|
|
809
804
|
if (ext.params)
|
|
810
805
|
result += this.renderAnnotateParamsInParentheses(ext, env);
|
|
811
806
|
|
|
812
807
|
// Element extensions and annotations (possibly nested)
|
|
813
808
|
if (ext.elements || ext.enum)
|
|
814
|
-
result += ` ${this.renderAnnotateStatementElements(ext, env)}`;
|
|
809
|
+
result += ` ${ this.renderAnnotateStatementElements(ext, env) }`;
|
|
815
810
|
|
|
816
811
|
else if (ext.returns)
|
|
817
812
|
result += this.renderAnnotateReturns(ext, env);
|
|
@@ -835,7 +830,7 @@ class CsnToCdl {
|
|
|
835
830
|
result += ';\n';
|
|
836
831
|
}
|
|
837
832
|
env.decreaseIndent();
|
|
838
|
-
result += `${env.indent}}`;
|
|
833
|
+
result += `${ env.indent }}`;
|
|
839
834
|
}
|
|
840
835
|
|
|
841
836
|
result = removeTrailingNewline(result);
|
|
@@ -864,12 +859,12 @@ class CsnToCdl {
|
|
|
864
859
|
result += env.indent + this.quoteNonIdentifierOrKeyword(name, env);
|
|
865
860
|
if (elem.elements) {
|
|
866
861
|
env.path.push('elements');
|
|
867
|
-
result += ` ${this.renderAnnotateStatementElements(elem, env)}`;
|
|
862
|
+
result += ` ${ this.renderAnnotateStatementElements(elem, env) }`;
|
|
868
863
|
env.path.pop();
|
|
869
864
|
}
|
|
870
865
|
else if (elem.enum) {
|
|
871
866
|
env.path.push('enum');
|
|
872
|
-
result += ` ${this.renderAnnotateStatementElements(elem, env)}`;
|
|
867
|
+
result += ` ${ this.renderAnnotateStatementElements(elem, env) }`;
|
|
873
868
|
env.path.pop();
|
|
874
869
|
}
|
|
875
870
|
|
|
@@ -877,7 +872,7 @@ class CsnToCdl {
|
|
|
877
872
|
}
|
|
878
873
|
env.path.length -= 2;
|
|
879
874
|
env.decreaseIndent();
|
|
880
|
-
result += `${env.indent}}`;
|
|
875
|
+
result += `${ env.indent }}`;
|
|
881
876
|
return result;
|
|
882
877
|
}
|
|
883
878
|
|
|
@@ -895,11 +890,11 @@ class CsnToCdl {
|
|
|
895
890
|
|
|
896
891
|
const returnAnnos = this.renderAnnotationAssignmentsAndDocComment(ext.returns, env.withIncreasedIndent());
|
|
897
892
|
if (returnAnnos)
|
|
898
|
-
result += `\n${returnAnnos}`;
|
|
893
|
+
result += `\n${ returnAnnos }`;
|
|
899
894
|
|
|
900
895
|
if (ext.returns.elements) {
|
|
901
896
|
// Annotations are on separate lines: Have it aligned nicely
|
|
902
|
-
result += returnAnnos ? `${env.indent}` : ' ';
|
|
897
|
+
result += returnAnnos ? `${ env.indent }` : ' ';
|
|
903
898
|
result += this.renderAnnotateStatementElements(ext.returns, env);
|
|
904
899
|
}
|
|
905
900
|
return result;
|
|
@@ -923,7 +918,7 @@ class CsnToCdl {
|
|
|
923
918
|
// const sub = (param.elements || param.enum) ? ` ${renderAnnotateStatementElements(param, childEnv)}` : '';
|
|
924
919
|
paramAnnotations.push( annos + childEnv.indent + name);
|
|
925
920
|
});
|
|
926
|
-
result += `${paramAnnotations.join(',\n')}\n${env.indent})`;
|
|
921
|
+
result += `${ paramAnnotations.join(',\n') }\n${ env.indent })`;
|
|
927
922
|
return result;
|
|
928
923
|
}
|
|
929
924
|
|
|
@@ -962,7 +957,7 @@ class CsnToCdl {
|
|
|
962
957
|
return this.renderArtifact(artifactName, art, env);
|
|
963
958
|
|
|
964
959
|
default:
|
|
965
|
-
throw new ModelError(`to.cdl: Unknown artifact kind: '${art.kind}' at ${JSON.stringify(env.path)}`);
|
|
960
|
+
throw new ModelError(`to.cdl: Unknown artifact kind: '${ art.kind }' at ${ JSON.stringify(env.path) }`);
|
|
966
961
|
}
|
|
967
962
|
}
|
|
968
963
|
|
|
@@ -981,7 +976,7 @@ class CsnToCdl {
|
|
|
981
976
|
const normalizedArtifactName = kind !== 'annotation'
|
|
982
977
|
? this.renderArtifactName(artifactName, env)
|
|
983
978
|
: this.quotePathIfRequired(artifactName, env);
|
|
984
|
-
result += `${env.indent}${kind} ${normalizedArtifactName}`;
|
|
979
|
+
result += `${ env.indent }${ kind } ${ normalizedArtifactName }`;
|
|
985
980
|
|
|
986
981
|
if (art.params)
|
|
987
982
|
result += this.renderParameters(art, env);
|
|
@@ -1006,7 +1001,7 @@ class CsnToCdl {
|
|
|
1006
1001
|
}
|
|
1007
1002
|
|
|
1008
1003
|
// For nicer output, no colon if unnamed structure is used.
|
|
1009
|
-
result += (!art.type && art.elements) ? ` ${type}` : ` : ${type}`;
|
|
1004
|
+
result += (!art.type && art.elements) ? ` ${ type }` : ` : ${ type }`;
|
|
1010
1005
|
}
|
|
1011
1006
|
else {
|
|
1012
1007
|
this.msg.warning('syntax-missing-type', env.path, { '#': art.kind, name: artifactName }, {
|
|
@@ -1043,8 +1038,8 @@ class CsnToCdl {
|
|
|
1043
1038
|
*/
|
|
1044
1039
|
renderContextOrService( artifactName, art, env ) {
|
|
1045
1040
|
let result = this.renderAnnotationAssignmentsAndDocComment(art, env);
|
|
1046
|
-
result += `${env.indent}${art.kind} ${this.renderArtifactName(artifactName, env)}`;
|
|
1047
|
-
return `${result} {};\n`;
|
|
1041
|
+
result += `${ env.indent }${ art.kind } ${ this.renderArtifactName(artifactName, env) }`;
|
|
1042
|
+
return `${ result } {};\n`;
|
|
1048
1043
|
}
|
|
1049
1044
|
|
|
1050
1045
|
/**
|
|
@@ -1059,17 +1054,17 @@ class CsnToCdl {
|
|
|
1059
1054
|
*/
|
|
1060
1055
|
renderAspect( artifactName, art, env ) {
|
|
1061
1056
|
let result = this.renderAnnotationAssignmentsAndDocComment(art, env);
|
|
1062
|
-
result += `${env.indent}aspect ${this.renderArtifactName(artifactName, env)}`;
|
|
1057
|
+
result += `${ env.indent }aspect ${ this.renderArtifactName(artifactName, env) }`;
|
|
1063
1058
|
if (art.includes)
|
|
1064
1059
|
result += this.renderIncludes(art.includes, env);
|
|
1065
1060
|
|
|
1066
1061
|
if (art.elements)
|
|
1067
|
-
result += ` ${this.renderElements(art, env)}`;
|
|
1062
|
+
result += ` ${ this.renderElements(art, env) }`;
|
|
1068
1063
|
else if (art.actions)
|
|
1069
1064
|
// if there are no elements, but actions, CDL syntax requires braces.
|
|
1070
1065
|
result += ' { }';
|
|
1071
1066
|
|
|
1072
|
-
result += `${this.renderBoundActionsAndFunctions(art, env)};\n`;
|
|
1067
|
+
result += `${ this.renderBoundActionsAndFunctions(art, env) };\n`;
|
|
1073
1068
|
return result;
|
|
1074
1069
|
}
|
|
1075
1070
|
|
|
@@ -1086,7 +1081,7 @@ class CsnToCdl {
|
|
|
1086
1081
|
for (const name in artifact.elements)
|
|
1087
1082
|
elements += this.renderElement(name, artifact.elements[name], childEnv.withSubPath([ 'elements', name ]));
|
|
1088
1083
|
|
|
1089
|
-
return (elements === '') ? '{ }' : `{\n${elements}${env.indent}}`;
|
|
1084
|
+
return (elements === '') ? '{ }' : `{\n${ elements }${ env.indent }}`;
|
|
1090
1085
|
}
|
|
1091
1086
|
|
|
1092
1087
|
/**
|
|
@@ -1107,10 +1102,10 @@ class CsnToCdl {
|
|
|
1107
1102
|
result += element.masked ? 'masked ' : '';
|
|
1108
1103
|
result += this.quoteNonIdentifierOrKeyword(elementName, env);
|
|
1109
1104
|
if (element['#'] !== undefined) { // enum symbol reference
|
|
1110
|
-
result += ` = #${element['#']}`;
|
|
1105
|
+
result += ` = #${ element['#'] }`;
|
|
1111
1106
|
}
|
|
1112
1107
|
else if (element.val !== undefined) { // enum value
|
|
1113
|
-
result += ` = ${this.exprRenderer.renderExpr(element, env)}`;
|
|
1108
|
+
result += ` = ${ this.exprRenderer.renderExpr(element, env) }`;
|
|
1114
1109
|
}
|
|
1115
1110
|
else if (!isCalcElement || !isDirectAssocOrComp(element.type) && !element.$filtered && !element.$enclosed) {
|
|
1116
1111
|
// If the element is a calculated element _and_ a direct association or
|
|
@@ -1120,7 +1115,7 @@ class CsnToCdl {
|
|
|
1120
1115
|
// we'd get a cast to an association.
|
|
1121
1116
|
const props = this.renderTypeReferenceAndProps(element, env);
|
|
1122
1117
|
if (props !== '')
|
|
1123
|
-
result += ` : ${props}`;
|
|
1118
|
+
result += ` : ${ props }`;
|
|
1124
1119
|
}
|
|
1125
1120
|
|
|
1126
1121
|
if (isCalcElement) { // calculated element // @ts-ignore
|
|
@@ -1135,7 +1130,7 @@ class CsnToCdl {
|
|
|
1135
1130
|
env.path.length -= 1;
|
|
1136
1131
|
}
|
|
1137
1132
|
|
|
1138
|
-
return `${result};\n`;
|
|
1133
|
+
return `${ result };\n`;
|
|
1139
1134
|
}
|
|
1140
1135
|
|
|
1141
1136
|
/**
|
|
@@ -1258,7 +1253,7 @@ class CsnToCdl {
|
|
|
1258
1253
|
// Sub-SELECT
|
|
1259
1254
|
if (source.SELECT || source.SET) {
|
|
1260
1255
|
const subEnv = env.withIncreasedIndent();
|
|
1261
|
-
let result = `(\n${subEnv.indent}${this.renderQuery(source, false, 'view', subEnv)}\n${env.indent})`;
|
|
1256
|
+
let result = `(\n${ subEnv.indent }${ this.renderQuery(source, false, 'view', subEnv) }\n${ env.indent })`;
|
|
1262
1257
|
if (source.as)
|
|
1263
1258
|
result += this.renderAlias(source.as, env);
|
|
1264
1259
|
|
|
@@ -1268,17 +1263,17 @@ class CsnToCdl {
|
|
|
1268
1263
|
else if (source.join) {
|
|
1269
1264
|
// One join operation, possibly with ON-condition
|
|
1270
1265
|
env.path.push('args', 0);
|
|
1271
|
-
let result = `(${this.renderViewSource(source.args[0], env)}`;
|
|
1266
|
+
let result = `(${ this.renderViewSource(source.args[0], env) }`;
|
|
1272
1267
|
for (let i = 1; i < source.args.length; i++) {
|
|
1273
1268
|
env.path[env.path.length - 1] = i;
|
|
1274
|
-
result += ` ${source.join} `;
|
|
1269
|
+
result += ` ${ source.join } `;
|
|
1275
1270
|
result += this.renderJoinCardinality(source.cardinality);
|
|
1276
|
-
result += `join ${this.renderViewSource(source.args[i], env)}`;
|
|
1271
|
+
result += `join ${ this.renderViewSource(source.args[i], env) }`;
|
|
1277
1272
|
}
|
|
1278
1273
|
env.path.length -= 2;
|
|
1279
1274
|
if (source.on) {
|
|
1280
1275
|
env.path.push('on');
|
|
1281
|
-
result += ` on ${this.exprRenderer.renderExpr(source.on, env.withSubPath([ 'on' ]))}`;
|
|
1276
|
+
result += ` on ${ this.exprRenderer.renderExpr(source.on, env.withSubPath([ 'on' ])) }`;
|
|
1282
1277
|
env.path.length -= 1;
|
|
1283
1278
|
}
|
|
1284
1279
|
result += ')';
|
|
@@ -1316,7 +1311,7 @@ class CsnToCdl {
|
|
|
1316
1311
|
renderAbsolutePath( path, env ) {
|
|
1317
1312
|
// Sanity checks
|
|
1318
1313
|
if (!path.ref)
|
|
1319
|
-
throw new ModelError(`Expecting ref in path: ${JSON.stringify(path)}`);
|
|
1314
|
+
throw new ModelError(`Expecting ref in path: ${ JSON.stringify(path) }`);
|
|
1320
1315
|
|
|
1321
1316
|
// Determine the absolute name of the first artifact on the path (before any associations or element traversals)
|
|
1322
1317
|
const firstArtifactName = path.ref[0].id || path.ref[0];
|
|
@@ -1327,14 +1322,14 @@ class CsnToCdl {
|
|
|
1327
1322
|
// Even the first step might have parameters and/or a filter
|
|
1328
1323
|
env.path.push('ref', 0);
|
|
1329
1324
|
if (path.ref[0].args)
|
|
1330
|
-
result += `(${this.renderArguments(path.ref[0], ':', env)})`;
|
|
1325
|
+
result += `(${ this.renderArguments(path.ref[0], ':', env) })`;
|
|
1331
1326
|
if (path.ref[0].where)
|
|
1332
1327
|
result += this.renderFilterAndCardinality(path.ref[0], env);
|
|
1333
1328
|
env.path.length -= 2;
|
|
1334
1329
|
|
|
1335
1330
|
// Add any path steps (possibly with parameters and filters) that may follow after that
|
|
1336
1331
|
if (path.ref.length > 1)
|
|
1337
|
-
result += `:${this.exprRenderer.renderExpr({ ref: path.ref.slice(1) }, env)}`;
|
|
1332
|
+
result += `:${ this.exprRenderer.renderExpr({ ref: path.ref.slice(1) }, env) }`;
|
|
1338
1333
|
|
|
1339
1334
|
return result;
|
|
1340
1335
|
}
|
|
@@ -1387,7 +1382,7 @@ class CsnToCdl {
|
|
|
1387
1382
|
return this.renderViewColumn(col, env, findElement(elements, col));
|
|
1388
1383
|
}).join(',\n');
|
|
1389
1384
|
env.path.length -= 2;
|
|
1390
|
-
return `${result}\n`;
|
|
1385
|
+
return `${ result }\n`;
|
|
1391
1386
|
}
|
|
1392
1387
|
|
|
1393
1388
|
/**
|
|
@@ -1414,28 +1409,37 @@ class CsnToCdl {
|
|
|
1414
1409
|
result += col.virtual ? 'virtual ' : '';
|
|
1415
1410
|
result += col.key ? 'key ' : '';
|
|
1416
1411
|
|
|
1412
|
+
let exprResult;
|
|
1417
1413
|
// Use special rendering for .expand/.inline - renderExpr cannot easily handle some cases
|
|
1418
1414
|
if (col.expand || col.inline)
|
|
1419
|
-
|
|
1415
|
+
exprResult = this.renderInlineExpand(col, env);
|
|
1420
1416
|
else if (col.xpr && xprContainsCondition(col.xpr))
|
|
1421
|
-
|
|
1417
|
+
exprResult = this.exprRenderer.renderSubExpr(withoutCast(col), env);
|
|
1422
1418
|
else
|
|
1423
|
-
|
|
1419
|
+
exprResult = this.exprRenderer.renderExpr(withoutCast(col), env);
|
|
1420
|
+
|
|
1421
|
+
result += exprResult;
|
|
1424
1422
|
|
|
1425
|
-
// Alias for inline/expand is already handled by renderInlineExpand
|
|
1426
1423
|
// A new association (cast with `type` and `target`) uses `as` as its primary name, not alias.
|
|
1427
|
-
|
|
1428
|
-
|
|
1424
|
+
// The same for `virtual <name>`, which is a new element definition instead of a reference.
|
|
1425
|
+
const isNewElementDefinition = exprResult === '';
|
|
1426
|
+
if (isNewElementDefinition && col.as) {
|
|
1427
|
+
result += this.quoteNonIdentifierOrKeyword(col.as, env);
|
|
1428
|
+
}
|
|
1429
|
+
else if (col.as && !col.inline && !col.expand) {
|
|
1430
|
+
// Alias for inline/expand is already handled by renderInlineExpand
|
|
1429
1431
|
result += this.renderAlias(col.as, env);
|
|
1432
|
+
}
|
|
1433
|
+
|
|
1430
1434
|
|
|
1431
1435
|
// Explicit type provided for the view element?
|
|
1432
1436
|
if (col.cast) {
|
|
1433
1437
|
env.path.push('cast');
|
|
1434
1438
|
// Special case: Explicit association type is actually a redirect
|
|
1435
1439
|
if (col.cast.target && !col.cast.type)
|
|
1436
|
-
result += ` : ${this.renderRedirectedTo(col.cast, env)}`;
|
|
1440
|
+
result += ` : ${ this.renderRedirectedTo(col.cast, env) }`;
|
|
1437
1441
|
else
|
|
1438
|
-
result += ` : ${this.renderTypeReferenceAndProps(col.cast, env, { typeRefOnly: true, noAnnoCollect: true })}`;
|
|
1442
|
+
result += ` : ${ this.renderTypeReferenceAndProps(col.cast, env, { typeRefOnly: true, noAnnoCollect: true }) }`;
|
|
1439
1443
|
env.path.length -= 1;
|
|
1440
1444
|
}
|
|
1441
1445
|
return result;
|
|
@@ -1463,9 +1467,9 @@ class CsnToCdl {
|
|
|
1463
1467
|
if (!obj.inline && !obj.expand) {
|
|
1464
1468
|
env.path.push('cast');
|
|
1465
1469
|
if (obj.cast && obj.cast.type)
|
|
1466
|
-
result += ` : ${this.renderTypeReferenceAndProps(obj.cast, env, { noAnnoCollect: true })}`;
|
|
1470
|
+
result += ` : ${ this.renderTypeReferenceAndProps(obj.cast, env, { noAnnoCollect: true }) }`;
|
|
1467
1471
|
else if (obj.cast && obj.cast.target) // test tbd
|
|
1468
|
-
result += ` : ${this.renderRedirectedTo(obj.cast, env)}`;
|
|
1472
|
+
result += ` : ${ this.renderRedirectedTo(obj.cast, env) }`;
|
|
1469
1473
|
env.path.length -= 1;
|
|
1470
1474
|
return result;
|
|
1471
1475
|
}
|
|
@@ -1481,11 +1485,11 @@ class CsnToCdl {
|
|
|
1481
1485
|
result += expandInline //
|
|
1482
1486
|
.map(elm => this.renderAnnotationAssignmentsAndDocComment(elm, childEnv) + childEnv.indent + this.renderInlineExpand(elm, childEnv))
|
|
1483
1487
|
.join(',\n');
|
|
1484
|
-
result += `\n${env.indent}}`;
|
|
1488
|
+
result += `\n${ env.indent }}`;
|
|
1485
1489
|
|
|
1486
1490
|
// Don't forget about the .excluding
|
|
1487
1491
|
if (obj.excluding)
|
|
1488
|
-
result += ` excluding { ${obj.excluding.join(',')} }`;
|
|
1492
|
+
result += ` excluding { ${ obj.excluding.join(',') } }`;
|
|
1489
1493
|
|
|
1490
1494
|
// { * } as expand
|
|
1491
1495
|
if (obj.as && isAnonymousExpand)
|
|
@@ -1505,7 +1509,7 @@ class CsnToCdl {
|
|
|
1505
1509
|
if (!obj || obj && obj.doc === undefined)
|
|
1506
1510
|
return '';
|
|
1507
1511
|
else if (obj && obj.doc === null) // empty doc comment needs to be rendered
|
|
1508
|
-
return `\n${env.indent}/** */\n`;
|
|
1512
|
+
return `\n${ env.indent }/** */\n`;
|
|
1509
1513
|
|
|
1510
1514
|
let { doc } = obj;
|
|
1511
1515
|
if (/[*]\//.test(doc)) // only escape sequence allowed in CDL for doc comments
|
|
@@ -1514,10 +1518,10 @@ class CsnToCdl {
|
|
|
1514
1518
|
// Smaller comment for single-line comments. If the comment starts or ends with whitespace
|
|
1515
1519
|
// we must use a block comment, or it will be lost when compiling the source again.
|
|
1516
1520
|
if (!obj.doc.includes('\n') && !/(^\s)|(\s$)/.test(obj.doc))
|
|
1517
|
-
return `${env.indent}/** ${doc} */\n`;
|
|
1521
|
+
return `${ env.indent }/** ${ doc } */\n`;
|
|
1518
1522
|
|
|
1519
|
-
const comment = doc.split('\n').map(l => `${env.indent} * ${l}`).join('\n');
|
|
1520
|
-
return `${env.indent}/**\n${comment}\n${env.indent} */\n`;
|
|
1523
|
+
const comment = doc.split('\n').map(l => `${ env.indent } * ${ l }`).join('\n');
|
|
1524
|
+
return `${ env.indent }/**\n${ comment }\n${ env.indent } */\n`;
|
|
1521
1525
|
}
|
|
1522
1526
|
|
|
1523
1527
|
/**
|
|
@@ -1528,7 +1532,7 @@ class CsnToCdl {
|
|
|
1528
1532
|
renderView( artifactName, art, env ) {
|
|
1529
1533
|
const syntax = (art.projection) ? 'projection' : 'entity';
|
|
1530
1534
|
let result = this.renderAnnotationAssignmentsAndDocComment(art, env);
|
|
1531
|
-
result += `${env.indent}entity ${this.renderArtifactName(artifactName, env)}`;
|
|
1535
|
+
result += `${ env.indent }entity ${ this.renderArtifactName(artifactName, env) }`;
|
|
1532
1536
|
if (art.params)
|
|
1533
1537
|
result += this.renderParameters(art, env);
|
|
1534
1538
|
result += ' as ';
|
|
@@ -1562,7 +1566,7 @@ class CsnToCdl {
|
|
|
1562
1566
|
}
|
|
1563
1567
|
else if (!query.SELECT) {
|
|
1564
1568
|
// ...otherwise must have a SELECT
|
|
1565
|
-
throw new ModelError(`Unexpected query operation ${JSON.stringify(query)}`);
|
|
1569
|
+
throw new ModelError(`Unexpected query operation ${ JSON.stringify(query) }`);
|
|
1566
1570
|
}
|
|
1567
1571
|
|
|
1568
1572
|
let result = '';
|
|
@@ -1588,7 +1592,7 @@ class CsnToCdl {
|
|
|
1588
1592
|
if (elems) {
|
|
1589
1593
|
result += ' mixin {\n';
|
|
1590
1594
|
result += elems;
|
|
1591
|
-
result += `${env.indent}} into`;
|
|
1595
|
+
result += `${ env.indent }} into`;
|
|
1592
1596
|
}
|
|
1593
1597
|
}
|
|
1594
1598
|
result += select.distinct ? ' distinct' : '';
|
|
@@ -1597,33 +1601,33 @@ class CsnToCdl {
|
|
|
1597
1601
|
env.increaseIndent();
|
|
1598
1602
|
result += this.renderViewColumns(select, env, elements);
|
|
1599
1603
|
env.decreaseIndent();
|
|
1600
|
-
result += `${env.indent}}`;
|
|
1604
|
+
result += `${ env.indent }}`;
|
|
1601
1605
|
}
|
|
1602
1606
|
|
|
1603
1607
|
const childEnv = env.withIncreasedIndent();
|
|
1604
1608
|
if (select.excluding) {
|
|
1605
|
-
const excludes = select.excluding.map(id => `${childEnv.indent}${this.quoteNonIdentifierOrKeyword(id, env)}`).join(',\n');
|
|
1606
|
-
result += ` excluding {\n${excludes}\n`;
|
|
1607
|
-
result += `${env.indent}}`;
|
|
1609
|
+
const excludes = select.excluding.map(id => `${ childEnv.indent }${ this.quoteNonIdentifierOrKeyword(id, env) }`).join(',\n');
|
|
1610
|
+
result += ` excluding {\n${ excludes }\n`;
|
|
1611
|
+
result += `${ env.indent }}`;
|
|
1608
1612
|
}
|
|
1609
1613
|
|
|
1610
1614
|
if (isLeadingQuery && query.actions)
|
|
1611
1615
|
result += this.renderBoundActionsAndFunctions(query, env);
|
|
1612
1616
|
|
|
1613
1617
|
if (select.where)
|
|
1614
|
-
result += `${continueIndent(result, env)}where ${this.exprRenderer.renderExpr(select.where, env.withSubPath([ 'where' ]))}`;
|
|
1618
|
+
result += `${ continueIndent(result, env) }where ${ this.exprRenderer.renderExpr(select.where, env.withSubPath([ 'where' ])) }`;
|
|
1615
1619
|
|
|
1616
1620
|
if (select.groupBy)
|
|
1617
|
-
result += `${continueIndent(result, env)}group by ${select.groupBy.map((expr, i) => this.exprRenderer.renderExpr(expr, env.withSubPath([ 'groupBy', i ]))).join(', ')}`;
|
|
1621
|
+
result += `${ continueIndent(result, env) }group by ${ select.groupBy.map((expr, i) => this.exprRenderer.renderExpr(expr, env.withSubPath([ 'groupBy', i ]))).join(', ') }`;
|
|
1618
1622
|
|
|
1619
1623
|
if (select.having)
|
|
1620
|
-
result += `${continueIndent(result, env)}having ${this.exprRenderer.renderExpr(select.having, env.withSubPath([ 'having' ]))}`;
|
|
1624
|
+
result += `${ continueIndent(result, env) }having ${ this.exprRenderer.renderExpr(select.having, env.withSubPath([ 'having' ])) }`;
|
|
1621
1625
|
|
|
1622
1626
|
if (select.orderBy)
|
|
1623
|
-
result += `${continueIndent(result, env)}order by ${select.orderBy.map((entry, i) => this.renderOrderByEntry(entry, env.withSubPath([ 'orderBy', i ]))).join(', ')}`;
|
|
1627
|
+
result += `${ continueIndent(result, env) }order by ${ select.orderBy.map((entry, i) => this.renderOrderByEntry(entry, env.withSubPath([ 'orderBy', i ]))).join(', ') }`;
|
|
1624
1628
|
|
|
1625
1629
|
if (select.limit)
|
|
1626
|
-
result += `${continueIndent(result, env)}${this.renderLimit(select.limit, env.withSubPath([ 'limit' ]))}`;
|
|
1630
|
+
result += `${ continueIndent(result, env) }${ this.renderLimit(select.limit, env.withSubPath([ 'limit' ])) }`;
|
|
1627
1631
|
|
|
1628
1632
|
return result;
|
|
1629
1633
|
|
|
@@ -1640,7 +1644,7 @@ class CsnToCdl {
|
|
|
1640
1644
|
return ' ';
|
|
1641
1645
|
}
|
|
1642
1646
|
// Otherwise, start new line and indent normally
|
|
1643
|
-
return `\n${indentEnv.withIncreasedIndent().indent}`;
|
|
1647
|
+
return `\n${ indentEnv.withIncreasedIndent().indent }`;
|
|
1644
1648
|
}
|
|
1645
1649
|
|
|
1646
1650
|
/**
|
|
@@ -1653,17 +1657,17 @@ class CsnToCdl {
|
|
|
1653
1657
|
// First arg may be leading query
|
|
1654
1658
|
const subEnv = env.withSubPath([ 'SET', 'args', i ]);
|
|
1655
1659
|
const subQuery = that.renderQuery(arg, isLeadingQuery && (i === 0), 'view', subEnv, elements);
|
|
1656
|
-
return `(${subQuery})`;
|
|
1660
|
+
return `(${ subQuery })`;
|
|
1657
1661
|
});
|
|
1658
1662
|
|
|
1659
|
-
let setResult = subQueries.join(`\n${env.indent}${query.SET.op}${query.SET.all ? ' all' : ''} `);
|
|
1663
|
+
let setResult = subQueries.join(`\n${ env.indent }${ query.SET.op }${ query.SET.all ? ' all' : '' } `);
|
|
1660
1664
|
// Set operation may also have an ORDER BY and LIMIT/OFFSET (in contrast to the ones belonging to
|
|
1661
1665
|
// each SELECT)
|
|
1662
1666
|
if (query.SET.orderBy)
|
|
1663
|
-
setResult += `${continueIndent(setResult, env)}order by ${query.SET.orderBy.map((entry, i) => that.renderOrderByEntry(entry, env.withSubPath([ 'SET', 'orderBy', i ]))).join(', ')}`;
|
|
1667
|
+
setResult += `${ continueIndent(setResult, env) }order by ${ query.SET.orderBy.map((entry, i) => that.renderOrderByEntry(entry, env.withSubPath([ 'SET', 'orderBy', i ]))).join(', ') }`;
|
|
1664
1668
|
|
|
1665
1669
|
if (query.SET.limit)
|
|
1666
|
-
setResult += `${continueIndent(setResult, env)}${that.renderLimit(query.SET.limit, env.withSubPath([ 'SET', 'limit' ]))}`;
|
|
1670
|
+
setResult += `${ continueIndent(setResult, env) }${ that.renderLimit(query.SET.limit, env.withSubPath([ 'SET', 'limit' ])) }`;
|
|
1667
1671
|
return setResult;
|
|
1668
1672
|
}
|
|
1669
1673
|
}
|
|
@@ -1679,10 +1683,10 @@ class CsnToCdl {
|
|
|
1679
1683
|
renderOrderByEntry( entry, env ) {
|
|
1680
1684
|
let result = this.renderAnnotationAssignmentsAndDocComment(entry, env) + this.exprRenderer.renderExpr(entry, env);
|
|
1681
1685
|
if (entry.sort)
|
|
1682
|
-
result += ` ${entry.sort}`;
|
|
1686
|
+
result += ` ${ entry.sort }`;
|
|
1683
1687
|
|
|
1684
1688
|
if (entry.nulls)
|
|
1685
|
-
result += ` nulls ${entry.nulls}`;
|
|
1689
|
+
result += ` nulls ${ entry.nulls }`;
|
|
1686
1690
|
|
|
1687
1691
|
return result;
|
|
1688
1692
|
}
|
|
@@ -1697,11 +1701,11 @@ class CsnToCdl {
|
|
|
1697
1701
|
renderLimit( limit, limitEnv ) {
|
|
1698
1702
|
let limitStr = '';
|
|
1699
1703
|
if (limit.rows !== undefined)
|
|
1700
|
-
limitStr += `limit ${this.exprRenderer.renderExpr(limit.rows, limitEnv.withSubPath([ 'rows' ]))}`;
|
|
1704
|
+
limitStr += `limit ${ this.exprRenderer.renderExpr(limit.rows, limitEnv.withSubPath([ 'rows' ])) }`;
|
|
1701
1705
|
|
|
1702
1706
|
if (limit.offset !== undefined) {
|
|
1703
|
-
const offsetIndent = (limitStr === '') ? '' : `\n${limitEnv.withIncreasedIndent().indent}`;
|
|
1704
|
-
limitStr += `${offsetIndent}offset ${this.exprRenderer.renderExpr(limit.offset, limitEnv.withSubPath([ 'offset' ]))}`;
|
|
1707
|
+
const offsetIndent = (limitStr === '') ? '' : `\n${ limitEnv.withIncreasedIndent().indent }`;
|
|
1708
|
+
limitStr += `${ offsetIndent }offset ${ this.exprRenderer.renderExpr(limit.offset, limitEnv.withSubPath([ 'offset' ])) }`;
|
|
1705
1709
|
}
|
|
1706
1710
|
return limitStr;
|
|
1707
1711
|
}
|
|
@@ -1724,7 +1728,7 @@ class CsnToCdl {
|
|
|
1724
1728
|
result += this.renderActionOrFunction(name, art.actions[name], childEnv.withSubPath([ 'actions', name ]), true);
|
|
1725
1729
|
result = (result === '')
|
|
1726
1730
|
? ' actions { }'
|
|
1727
|
-
: ` actions {\n${result}${env.indent}}`;
|
|
1731
|
+
: ` actions {\n${ result }${ env.indent }}`;
|
|
1728
1732
|
}
|
|
1729
1733
|
return result;
|
|
1730
1734
|
}
|
|
@@ -1742,10 +1746,10 @@ class CsnToCdl {
|
|
|
1742
1746
|
let result = this.renderAnnotationAssignmentsAndDocComment(act, env) + env.indent + act.kind;
|
|
1743
1747
|
if (isBound) {
|
|
1744
1748
|
// for bound actions, paths are not global
|
|
1745
|
-
result += ` ${this.quotePathIfRequired(actionName, env)}`;
|
|
1749
|
+
result += ` ${ this.quotePathIfRequired(actionName, env) }`;
|
|
1746
1750
|
}
|
|
1747
1751
|
else {
|
|
1748
|
-
result += ` ${this.renderArtifactName(actionName, env)}`;
|
|
1752
|
+
result += ` ${ this.renderArtifactName(actionName, env) }`;
|
|
1749
1753
|
}
|
|
1750
1754
|
result += this.renderParameters(act, env);
|
|
1751
1755
|
if (act.returns) {
|
|
@@ -1754,7 +1758,7 @@ class CsnToCdl {
|
|
|
1754
1758
|
if (annos) // if `returns` has annotations, increase indent for nicer aligned output
|
|
1755
1759
|
actEnv = actEnv.withIncreasedIndent();
|
|
1756
1760
|
const type = this.renderTypeReferenceAndProps(act.returns, actEnv);
|
|
1757
|
-
result += ` returns${annos ? '\n' : ' '}${annos}${annos ? actEnv.indent : ''}${type}`;
|
|
1761
|
+
result += ` returns${ annos ? '\n' : ' ' }${ annos }${ annos ? actEnv.indent : '' }${ type }`;
|
|
1758
1762
|
}
|
|
1759
1763
|
|
|
1760
1764
|
result += ';\n';
|
|
@@ -1775,7 +1779,7 @@ class CsnToCdl {
|
|
|
1775
1779
|
const parameters = Object.keys(art.params || {}).map(name => this.renderParameter(name, art.params[name], childEnv));
|
|
1776
1780
|
if (parameters.length === 0)
|
|
1777
1781
|
return '()';
|
|
1778
|
-
return `(\n${parameters.join(',\n')}\n${env.indent})`;
|
|
1782
|
+
return `(\n${ parameters.join(',\n') }\n${ env.indent })`;
|
|
1779
1783
|
}
|
|
1780
1784
|
|
|
1781
1785
|
/**
|
|
@@ -1788,8 +1792,8 @@ class CsnToCdl {
|
|
|
1788
1792
|
*/
|
|
1789
1793
|
renderParameter( parName, par, env ) {
|
|
1790
1794
|
env = env.withSubPath( [ 'params', parName ]);
|
|
1791
|
-
let result = `${this.renderAnnotationAssignmentsAndDocComment(par, env)}${env.indent}`;
|
|
1792
|
-
result += `${this.quoteNonIdentifierOrKeyword(parName, env)} : ${this.renderTypeReferenceAndProps(par, env)}`;
|
|
1795
|
+
let result = `${ this.renderAnnotationAssignmentsAndDocComment(par, env) }${ env.indent }`;
|
|
1796
|
+
result += `${ this.quoteNonIdentifierOrKeyword(parName, env) } : ${ this.renderTypeReferenceAndProps(par, env) }`;
|
|
1793
1797
|
return result;
|
|
1794
1798
|
}
|
|
1795
1799
|
|
|
@@ -1810,7 +1814,7 @@ class CsnToCdl {
|
|
|
1810
1814
|
const { typeRefOnly, noAnnoCollect } = config;
|
|
1811
1815
|
|
|
1812
1816
|
if (typeRefOnly && !artifact.type)
|
|
1813
|
-
throw new ModelError(`Expected artifact to have a type; in: ${JSON.stringify(env.path)}`);
|
|
1817
|
+
throw new ModelError(`Expected artifact to have a type; in: ${ JSON.stringify(env.path) }`);
|
|
1814
1818
|
|
|
1815
1819
|
if (artifact.localized) // works even for type definitions
|
|
1816
1820
|
result += 'localized ';
|
|
@@ -1863,7 +1867,7 @@ class CsnToCdl {
|
|
|
1863
1867
|
|
|
1864
1868
|
// ON-condition (if any)
|
|
1865
1869
|
if (artifact.on)
|
|
1866
|
-
result += ` on ${this.exprRenderer.renderExpr(artifact.on, env.withSubPath([ 'on' ]))}`;
|
|
1870
|
+
result += ` on ${ this.exprRenderer.renderExpr(artifact.on, env.withSubPath([ 'on' ])) }`;
|
|
1867
1871
|
|
|
1868
1872
|
// Foreign keys (if any, unless we also have an ON_condition (which means we have been transformed from managed to unmanaged)
|
|
1869
1873
|
if (artifact.keys && !artifact.on)
|
|
@@ -1918,9 +1922,9 @@ class CsnToCdl {
|
|
|
1918
1922
|
* @return {string}
|
|
1919
1923
|
*/
|
|
1920
1924
|
renderRedirectedTo( art, env ) {
|
|
1921
|
-
let result = `redirected to ${this.renderDefinitionReference(art.target, env)}`;
|
|
1925
|
+
let result = `redirected to ${ this.renderDefinitionReference(art.target, env) }`;
|
|
1922
1926
|
if (art.on)
|
|
1923
|
-
result += ` on ${this.exprRenderer.renderExpr(art.on, env.withSubPath([ 'on' ]))}`;
|
|
1927
|
+
result += ` on ${ this.exprRenderer.renderExpr(art.on, env.withSubPath([ 'on' ])) }`;
|
|
1924
1928
|
else if (art.keys)
|
|
1925
1929
|
result += ` ${ this.renderForeignKeys(art, env) }`;
|
|
1926
1930
|
return result;
|
|
@@ -1953,7 +1957,7 @@ class CsnToCdl {
|
|
|
1953
1957
|
const childEnv = env.withIncreasedIndent();
|
|
1954
1958
|
for (const name in enumPart)
|
|
1955
1959
|
result += this.renderElement(name, enumPart[name], childEnv.withSubPath([ 'enum', name ]));
|
|
1956
|
-
result += `${env.indent}}`;
|
|
1960
|
+
result += `${ env.indent }}`;
|
|
1957
1961
|
return result;
|
|
1958
1962
|
}
|
|
1959
1963
|
|
|
@@ -1969,7 +1973,7 @@ class CsnToCdl {
|
|
|
1969
1973
|
if (isAnnotationExpression(annoValue)) {
|
|
1970
1974
|
// Once inside an expression, we stay there.
|
|
1971
1975
|
const xpr = this.exprRenderer.renderExpr(annoValue, env);
|
|
1972
|
-
return `( ${xpr} )`;
|
|
1976
|
+
return `( ${ xpr } )`;
|
|
1973
1977
|
}
|
|
1974
1978
|
else if (Array.isArray(annoValue)) {
|
|
1975
1979
|
return this.renderAnnotationArrayValue( annoValue, env );
|
|
@@ -1977,7 +1981,7 @@ class CsnToCdl {
|
|
|
1977
1981
|
else if (typeof annoValue === 'object' && annoValue !== null) {
|
|
1978
1982
|
// Enum symbol
|
|
1979
1983
|
if (annoValue['#'] !== undefined) {
|
|
1980
|
-
return `#${annoValue['#']}`;
|
|
1984
|
+
return `#${ annoValue['#'] }`;
|
|
1981
1985
|
}
|
|
1982
1986
|
// Shorthand for absolute path (as string)
|
|
1983
1987
|
else if (annoValue['='] !== undefined) {
|
|
@@ -1989,7 +1993,7 @@ class CsnToCdl {
|
|
|
1989
1993
|
else if (annoValue['...'] !== undefined) {
|
|
1990
1994
|
if (annoValue['...'] === true)
|
|
1991
1995
|
return '...';
|
|
1992
|
-
return `... up to ${this.renderAnnotationValue(annoValue['...'], env)}`;
|
|
1996
|
+
return `... up to ${ this.renderAnnotationValue(annoValue['...'], env) }`;
|
|
1993
1997
|
}
|
|
1994
1998
|
|
|
1995
1999
|
// Struct value (can currently only occur within an array)
|
|
@@ -1997,7 +2001,7 @@ class CsnToCdl {
|
|
|
1997
2001
|
// struct if there are more and use nicer indentation.
|
|
1998
2002
|
const keys = Object.keys(annoValue);
|
|
1999
2003
|
const childEnv = env.withIncreasedIndent();
|
|
2000
|
-
const values = keys.map(key => `${this.quoteAnnotationPathIfRequired(key, env)}: ${this.renderAnnotationValue(annoValue[key], childEnv.withSubPath([ key ]))}`);
|
|
2004
|
+
const values = keys.map(key => `${ this.quoteAnnotationPathIfRequired(key, env) }: ${ this.renderAnnotationValue(annoValue[key], childEnv.withSubPath([ key ])) }`);
|
|
2001
2005
|
const result = joinDocuments(values, [ ',', line() ]);
|
|
2002
2006
|
return format(nestBy(env.indent.length, bracketBlock(INDENT_SIZE, '{', result, '}') ));
|
|
2003
2007
|
}
|
|
@@ -2050,17 +2054,17 @@ class CsnToCdl {
|
|
|
2050
2054
|
else if (typeof s === 'object') {
|
|
2051
2055
|
// Sanity check
|
|
2052
2056
|
if (!s.func && !s.id)
|
|
2053
|
-
throw new ModelError(`Unknown path step object: ${JSON.stringify(s)}`);
|
|
2057
|
+
throw new ModelError(`Unknown path step object: ${ JSON.stringify(s) }`);
|
|
2054
2058
|
|
|
2055
2059
|
// Not really a path step but an object-like function call
|
|
2056
2060
|
if (s.func)
|
|
2057
|
-
return `${s.func}(${this.renderArguments(s, '=>', env)})`;
|
|
2061
|
+
return `${ s.func }(${ this.renderArguments(s, '=>', env) })`;
|
|
2058
2062
|
|
|
2059
2063
|
// Path step, possibly with view parameters and/or filters
|
|
2060
|
-
let result = `${this.quoteNonIdentifierOrKeyword(s.id, env)}`;
|
|
2064
|
+
let result = `${ this.quoteNonIdentifierOrKeyword(s.id, env) }`;
|
|
2061
2065
|
if (s.args) {
|
|
2062
2066
|
// View parameters
|
|
2063
|
-
result += `(${this.renderArguments(s, ':', env)})`;
|
|
2067
|
+
result += `(${ this.renderArguments(s, ':', env) })`;
|
|
2064
2068
|
}
|
|
2065
2069
|
|
|
2066
2070
|
result += this.renderFilterAndCardinality(s, env);
|
|
@@ -2068,7 +2072,7 @@ class CsnToCdl {
|
|
|
2068
2072
|
return result;
|
|
2069
2073
|
}
|
|
2070
2074
|
|
|
2071
|
-
throw new ModelError(`Unknown path step: ${JSON.stringify(s)}`);
|
|
2075
|
+
throw new ModelError(`Unknown path step: ${ JSON.stringify(s) }`);
|
|
2072
2076
|
}
|
|
2073
2077
|
|
|
2074
2078
|
/**
|
|
@@ -2087,7 +2091,7 @@ class CsnToCdl {
|
|
|
2087
2091
|
return this.renderPositionalArguments(node, env);
|
|
2088
2092
|
else if (typeof node.args === 'object')
|
|
2089
2093
|
return this.renderNamedArguments(node, sep, env);
|
|
2090
|
-
throw new ModelError(`Unknown args: ${JSON.stringify(node.args)}; expected array/object`);
|
|
2094
|
+
throw new ModelError(`Unknown args: ${ JSON.stringify(node.args) }; expected array/object`);
|
|
2091
2095
|
}
|
|
2092
2096
|
|
|
2093
2097
|
/**
|
|
@@ -2102,7 +2106,7 @@ class CsnToCdl {
|
|
|
2102
2106
|
renderNamedArguments( node, separator, env ) {
|
|
2103
2107
|
const that = this;
|
|
2104
2108
|
return Object.keys(node.args).map(function renderNamedArgument(key) {
|
|
2105
|
-
return `${that.quoteNonIdentifierOrKeyword(key, env)} ${separator} ${that.renderArgument(node.args[key], env.withSubPath([ 'args', key ]))}`;
|
|
2109
|
+
return `${ that.quoteNonIdentifierOrKeyword(key, env) } ${ separator } ${ that.renderArgument(node.args[key], env.withSubPath([ 'args', key ])) }`;
|
|
2106
2110
|
}).join(', ');
|
|
2107
2111
|
}
|
|
2108
2112
|
|
|
@@ -2172,13 +2176,13 @@ class CsnToCdl {
|
|
|
2172
2176
|
|
|
2173
2177
|
let result = '[';
|
|
2174
2178
|
if (card.src !== undefined)
|
|
2175
|
-
result += `${card.src}, `;
|
|
2179
|
+
result += `${ card.src }, `;
|
|
2176
2180
|
if (card.min !== undefined)
|
|
2177
|
-
result += `${card.min}..`;
|
|
2181
|
+
result += `${ card.min }..`;
|
|
2178
2182
|
if (card.max !== undefined)
|
|
2179
2183
|
result += card.max;
|
|
2180
2184
|
// srcmin can't be represented in CDL
|
|
2181
|
-
return `${result}]${suffix}`;
|
|
2185
|
+
return `${ result }]${ suffix }`;
|
|
2182
2186
|
}
|
|
2183
2187
|
|
|
2184
2188
|
/**
|
|
@@ -2217,34 +2221,34 @@ class CsnToCdl {
|
|
|
2217
2221
|
|
|
2218
2222
|
renderFilterAndCardinality( s, env ) {
|
|
2219
2223
|
let result = '';
|
|
2220
|
-
const cardinality = s.cardinality ? (`${s.cardinality.max}: `) : '';
|
|
2224
|
+
const cardinality = s.cardinality ? (`${ s.cardinality.max }: `) : '';
|
|
2221
2225
|
let filter = '';
|
|
2222
2226
|
|
|
2223
2227
|
// TODO: Unify with other filter rendering for SELECT
|
|
2224
2228
|
if (s.groupBy)
|
|
2225
|
-
filter += ` group by ${s.groupBy.map((expr, i) => this.exprRenderer.renderExpr(expr, env.withSubPath([ 'groupBy', i ]))).join(', ')}`;
|
|
2229
|
+
filter += ` group by ${ s.groupBy.map((expr, i) => this.exprRenderer.renderExpr(expr, env.withSubPath([ 'groupBy', i ]))).join(', ') }`;
|
|
2226
2230
|
if (s.having)
|
|
2227
|
-
filter += ` having ${this.exprRenderer.renderExpr(s.having, env.withSubPath([ 'having' ]))}`;
|
|
2231
|
+
filter += ` having ${ this.exprRenderer.renderExpr(s.having, env.withSubPath([ 'having' ])) }`;
|
|
2228
2232
|
if (s.orderBy)
|
|
2229
|
-
filter += ` order by ${s.orderBy.map((entry, i) => this.renderOrderByEntry(entry, env.withSubPath([ 'orderBy', i ]))).join(', ')}`;
|
|
2233
|
+
filter += ` order by ${ s.orderBy.map((entry, i) => this.renderOrderByEntry(entry, env.withSubPath([ 'orderBy', i ]))).join(', ') }`;
|
|
2230
2234
|
if (s.limit)
|
|
2231
|
-
filter += ` ${this.renderLimit(s.limit, env.withSubPath([ 'limit' ]))}`;
|
|
2235
|
+
filter += ` ${ this.renderLimit(s.limit, env.withSubPath([ 'limit' ])) }`;
|
|
2232
2236
|
|
|
2233
2237
|
if (s.where) {
|
|
2234
2238
|
let where = this.exprRenderer.renderExpr(s.where, env.withSubPath([ 'where' ]));
|
|
2235
2239
|
// Special rules in CDS parser: If filter starts with one of these SQL keywords, WHERE is mandatory.
|
|
2236
2240
|
if (filter || /^(?:group|having|order|limit)\s/i.test(where))
|
|
2237
|
-
where = ` where ${where}`;
|
|
2238
|
-
filter = `${where} ${filter}`;
|
|
2241
|
+
where = ` where ${ where }`;
|
|
2242
|
+
filter = `${ where } ${ filter }`;
|
|
2239
2243
|
}
|
|
2240
2244
|
|
|
2241
2245
|
filter = filter.trim();
|
|
2242
2246
|
|
|
2243
2247
|
if (cardinality || filter) {
|
|
2244
2248
|
if (filter.endsWith(']')) // for cases such as [… ![id] ]
|
|
2245
|
-
result += `[ ${cardinality}${filter} ]`;
|
|
2249
|
+
result += `[ ${ cardinality }${ filter } ]`;
|
|
2246
2250
|
else
|
|
2247
|
-
result += `[${cardinality}${filter}]`;
|
|
2251
|
+
result += `[${ cardinality }${ filter }]`;
|
|
2248
2252
|
}
|
|
2249
2253
|
return result;
|
|
2250
2254
|
}
|
|
@@ -2294,13 +2298,13 @@ class CsnToCdl {
|
|
|
2294
2298
|
|
|
2295
2299
|
const alias = fKey.as ? this.renderAlias(fKey.as, env) : '';
|
|
2296
2300
|
const key = this.exprRenderer.renderExpr(fKey, env);
|
|
2297
|
-
renderedKeys.push(`${key}${alias},`);
|
|
2301
|
+
renderedKeys.push(`${ key }${ alias },`);
|
|
2298
2302
|
}
|
|
2299
2303
|
|
|
2300
2304
|
if (hasAnnotations) {
|
|
2301
|
-
const sep = `\n${env.indent}`;
|
|
2305
|
+
const sep = `\n${ env.indent }`;
|
|
2302
2306
|
env.decreaseIndent();
|
|
2303
|
-
return `{${sep}${renderedKeys.join(sep)}\n${env.indent}}`;
|
|
2307
|
+
return `{${ sep }${ renderedKeys.join(sep) }\n${ env.indent }}`;
|
|
2304
2308
|
}
|
|
2305
2309
|
|
|
2306
2310
|
let result = renderedKeys.join(' ');
|
|
@@ -2317,7 +2321,7 @@ class CsnToCdl {
|
|
|
2317
2321
|
* @return {string}
|
|
2318
2322
|
*/
|
|
2319
2323
|
renderAlias( alias, env ) {
|
|
2320
|
-
return ` as ${this.quoteNonIdentifierOrKeyword(alias, env)}`;
|
|
2324
|
+
return ` as ${ this.quoteNonIdentifierOrKeyword(alias, env) }`;
|
|
2321
2325
|
}
|
|
2322
2326
|
|
|
2323
2327
|
/**
|
|
@@ -2337,17 +2341,17 @@ class CsnToCdl {
|
|
|
2337
2341
|
if (!noShortVersion) {
|
|
2338
2342
|
// Special cases for 1 or 2 arguments.
|
|
2339
2343
|
if (params.length === 1 && artWithType.length !== undefined)
|
|
2340
|
-
return `(${artWithType.length})`;
|
|
2344
|
+
return `(${ artWithType.length })`;
|
|
2341
2345
|
if (params.length === 2 && artWithType.precision !== undefined && artWithType.scale !== undefined)
|
|
2342
|
-
return `(${artWithType.precision}, ${artWithType.scale})`;
|
|
2346
|
+
return `(${ artWithType.precision }, ${ artWithType.scale })`;
|
|
2343
2347
|
}
|
|
2344
2348
|
|
|
2345
2349
|
// Render named params
|
|
2346
2350
|
const renderedParams = [];
|
|
2347
2351
|
for (const param of params)
|
|
2348
|
-
renderedParams.push(`${param}: ${artWithType[param]}`);
|
|
2352
|
+
renderedParams.push(`${ param }: ${ artWithType[param] }`);
|
|
2349
2353
|
|
|
2350
|
-
return `(${renderedParams.join(', ')})`;
|
|
2354
|
+
return `(${ renderedParams.join(', ') })`;
|
|
2351
2355
|
}
|
|
2352
2356
|
|
|
2353
2357
|
/**
|
|
@@ -2386,7 +2390,7 @@ class CsnToCdl {
|
|
|
2386
2390
|
const variant = parts.length > 1 ? parts.slice(1).join('#') : undefined;
|
|
2387
2391
|
const { parentheses } = config;
|
|
2388
2392
|
|
|
2389
|
-
let result = `${env.indent}@`;
|
|
2393
|
+
let result = `${ env.indent }@`;
|
|
2390
2394
|
if (parentheses)
|
|
2391
2395
|
result += '(';
|
|
2392
2396
|
|
|
@@ -2399,13 +2403,13 @@ class CsnToCdl {
|
|
|
2399
2403
|
if (variant !== undefined && variant !== '') {
|
|
2400
2404
|
// Unfortunately, the compiler does not allow `.@` after the first variant identifier,
|
|
2401
2405
|
// nor multiple `#`, so we're back at simple paths that are possibly quoted.
|
|
2402
|
-
result += `#${this.quotePathIfRequired(variant, env)}`;
|
|
2406
|
+
result += `#${ this.quotePathIfRequired(variant, env) }`;
|
|
2403
2407
|
}
|
|
2404
|
-
result += ` : ${this.renderAnnotationValue(anno, env)}`;
|
|
2408
|
+
result += ` : ${ this.renderAnnotationValue(anno, env) }`;
|
|
2405
2409
|
|
|
2406
2410
|
if (parentheses)
|
|
2407
2411
|
result += ')';
|
|
2408
|
-
return `${result}\n`;
|
|
2412
|
+
return `${ result }\n`;
|
|
2409
2413
|
}
|
|
2410
2414
|
|
|
2411
2415
|
/**
|
|
@@ -2440,7 +2444,7 @@ class CsnToCdl {
|
|
|
2440
2444
|
* @return {string}
|
|
2441
2445
|
*/
|
|
2442
2446
|
renderIncludes( includes, env ) {
|
|
2443
|
-
return ` : ${includes.map((name, i) => this.renderDefinitionReference(name, env.withSubPath([ 'includes', i ]))).join(', ')}`;
|
|
2447
|
+
return ` : ${ includes.map((name, i) => this.renderDefinitionReference(name, env.withSubPath([ 'includes', i ]))).join(', ') }`;
|
|
2444
2448
|
}
|
|
2445
2449
|
|
|
2446
2450
|
createCdlExpressionRenderer() {
|
|
@@ -2450,7 +2454,7 @@ class CsnToCdl {
|
|
|
2450
2454
|
typeCast(x) {
|
|
2451
2455
|
const typeRef = that.renderTypeReferenceAndProps(x.cast, this.env.withSubPath([ 'cast' ]), { typeRefOnly: true, noAnnoCollect: true });
|
|
2452
2456
|
const arg = { ...x, cast: null }; // "arg" without cast to avoid recursion.
|
|
2453
|
-
return `cast(${that.renderArgument(arg, this.env)} as ${typeRef})`;
|
|
2457
|
+
return `cast(${ that.renderArgument(arg, this.env) } as ${ typeRef })`;
|
|
2454
2458
|
},
|
|
2455
2459
|
val(x) {
|
|
2456
2460
|
// Literal value, possibly with explicit 'literal' property
|
|
@@ -2463,7 +2467,7 @@ class CsnToCdl {
|
|
|
2463
2467
|
case 'date':
|
|
2464
2468
|
case 'time':
|
|
2465
2469
|
case 'timestamp':
|
|
2466
|
-
return `${x.literal}'${x.val}'`;
|
|
2470
|
+
return `${ x.literal }'${ x.val }'`;
|
|
2467
2471
|
case 'string':
|
|
2468
2472
|
return renderString(x.val, this.env);
|
|
2469
2473
|
case 'object':
|
|
@@ -2471,30 +2475,29 @@ class CsnToCdl {
|
|
|
2471
2475
|
return 'null';
|
|
2472
2476
|
// otherwise fall through to
|
|
2473
2477
|
default:
|
|
2474
|
-
throw new ModelError(`Unknown literal or type: ${JSON.stringify(x)}`);
|
|
2478
|
+
throw new ModelError(`Unknown literal or type: ${ JSON.stringify(x) }`);
|
|
2475
2479
|
}
|
|
2476
2480
|
},
|
|
2477
|
-
|
|
2478
|
-
enum: x => `#${x['#']}`,
|
|
2481
|
+
enum: x => `#${ x['#'] }`,
|
|
2479
2482
|
ref(x) {
|
|
2480
|
-
return `${x.param ? ':' : ''}${x.ref.map((step, index) => that.renderPathStep(step, index, this.env.withSubPath([ 'ref', index ]))).join('.')}`;
|
|
2483
|
+
return `${ x.param ? ':' : '' }${ x.ref.map((step, index) => that.renderPathStep(step, index, this.env.withSubPath([ 'ref', index ]))).join('.') }`;
|
|
2481
2484
|
},
|
|
2482
2485
|
windowFunction(x) {
|
|
2483
2486
|
const funcDef = this.func(x);
|
|
2484
|
-
return `${funcDef} ${this.renderExpr(x.xpr, this.env.withSubPath([ 'xpr' ]))}`; // xpr[0] is 'over'
|
|
2487
|
+
return `${ funcDef } ${ this.renderExpr(x.xpr, this.env.withSubPath([ 'xpr' ])) }`; // xpr[0] is 'over'
|
|
2485
2488
|
},
|
|
2486
2489
|
func(x) {
|
|
2487
2490
|
if (keywords.cdl_functions.includes(x.func.toUpperCase()) && !x.args)
|
|
2488
2491
|
return x.func;
|
|
2489
2492
|
const name = that.quoteFunctionIfRequired(x.func, this.env);
|
|
2490
2493
|
if (!x.args) // e.g. for methods without arguments, `args` is not set at all.
|
|
2491
|
-
return `${name}`;
|
|
2492
|
-
return `${name}(${that.renderArguments( x, '=>', this.env )})`;
|
|
2494
|
+
return `${ name }`;
|
|
2495
|
+
return `${ name }(${ that.renderArguments( x, '=>', this.env ) })`;
|
|
2493
2496
|
},
|
|
2494
2497
|
xpr(x) {
|
|
2495
2498
|
const xprEnv = this.env.withSubPath([ 'xpr' ]);
|
|
2496
2499
|
if (this.isNestedXpr && !x.cast)
|
|
2497
|
-
return `(${this.renderExpr(x.xpr, xprEnv)})`;
|
|
2500
|
+
return `(${ this.renderExpr(x.xpr, xprEnv) })`;
|
|
2498
2501
|
return this.renderExpr(x.xpr, xprEnv);
|
|
2499
2502
|
},
|
|
2500
2503
|
// Sub-queries in expressions need to be in parentheses, otherwise
|
|
@@ -2502,10 +2505,10 @@ class CsnToCdl {
|
|
|
2502
2505
|
// For example: `select from E where id in (select from E union select from E);`:
|
|
2503
2506
|
// Without parentheses, it would be different query.
|
|
2504
2507
|
SET(x) {
|
|
2505
|
-
return `(${that.renderQuery(x, false, 'view', this.env.withIncreasedIndent())})`;
|
|
2508
|
+
return `(${ that.renderQuery(x, false, 'view', this.env.withIncreasedIndent()) })`;
|
|
2506
2509
|
},
|
|
2507
2510
|
SELECT(x) {
|
|
2508
|
-
return `(${that.renderQuery(x, false, 'view', this.env.withIncreasedIndent())})`;
|
|
2511
|
+
return `(${ that.renderQuery(x, false, 'view', this.env.withIncreasedIndent()) })`;
|
|
2509
2512
|
},
|
|
2510
2513
|
});
|
|
2511
2514
|
}
|
|
@@ -2633,7 +2636,7 @@ class CsnToCdl {
|
|
|
2633
2636
|
quoteAnnotationPathIfRequired( anno, env ) {
|
|
2634
2637
|
return anno.split('.').map((segment) => {
|
|
2635
2638
|
if (segment.startsWith('@'))
|
|
2636
|
-
return `@${this.quoteNonIdentifier(segment.slice(1), env)}`;
|
|
2639
|
+
return `@${ this.quoteNonIdentifier(segment.slice(1), env) }`;
|
|
2637
2640
|
return this.quoteNonIdentifier(segment, env);
|
|
2638
2641
|
}).join('.');
|
|
2639
2642
|
}
|
|
@@ -2667,7 +2670,7 @@ class CdlRenderEnvironment {
|
|
|
2667
2670
|
}
|
|
2668
2671
|
|
|
2669
2672
|
increaseIndent() {
|
|
2670
|
-
this.indent = ` ${this.indent}`;
|
|
2673
|
+
this.indent = ` ${ this.indent }`;
|
|
2671
2674
|
}
|
|
2672
2675
|
decreaseIndent() {
|
|
2673
2676
|
this.indent = this.indent.substring(0, this.indent.length - INDENT_SIZE);
|
|
@@ -2711,7 +2714,7 @@ function removeTrailingNewline( str ) {
|
|
|
2711
2714
|
|
|
2712
2715
|
/**
|
|
2713
2716
|
* Returns true if 'id' requires quotes for CDL, i.e. if 'id'
|
|
2714
|
-
* does not match the first part of the `
|
|
2717
|
+
* does not match the first part of the `ident` rule of `lib/parsers/Lexer.js`
|
|
2715
2718
|
* or if 'id' is a reserved keyword.
|
|
2716
2719
|
*
|
|
2717
2720
|
* Set additionalKeywords to an array of UPPERCASE keywords
|
|
@@ -2857,7 +2860,7 @@ function getAllKeywordsForSpecialFunction( funcName ) {
|
|
|
2857
2860
|
*/
|
|
2858
2861
|
function renderString( str, env ) {
|
|
2859
2862
|
if (isSimpleString(str))
|
|
2860
|
-
return `'${str.replace(/'/g, '\'\'')}'`;
|
|
2863
|
+
return `'${ str.replace(/'/g, '\'\'') }'`;
|
|
2861
2864
|
|
|
2862
2865
|
// We try to work similar to how JavaScript implements JSON.stringify.
|
|
2863
2866
|
// JSON.stringify() also checks for unpaired unicode surrogates (see §25.5.2.2,
|
|
@@ -2892,17 +2895,17 @@ function renderString( str, env ) {
|
|
|
2892
2895
|
// are more than three lines, text blocks with indentation "look nicer".
|
|
2893
2896
|
// This value was chosen by personal taste.
|
|
2894
2897
|
if (lines.length > 3) {
|
|
2895
|
-
str = lines.join(`\n${env.indent}`);
|
|
2896
|
-
return `\`\`\`\n${env.indent}${str}\n${env.indent}\`\`\``;
|
|
2898
|
+
str = lines.join(`\n${ env.indent }`);
|
|
2899
|
+
return `\`\`\`\n${ env.indent }${ str }\n${ env.indent }\`\`\``;
|
|
2897
2900
|
}
|
|
2898
2901
|
|
|
2899
|
-
return `\`${str}\``;
|
|
2902
|
+
return `\`${ str }\``;
|
|
2900
2903
|
}
|
|
2901
2904
|
|
|
2902
2905
|
/** @param {number} codePoint */
|
|
2903
2906
|
function hexEscape( codePoint ) {
|
|
2904
2907
|
const hex = codePoint.toString(16);
|
|
2905
|
-
return `\\u{${hex}}`;
|
|
2908
|
+
return `\\u{${ hex }}`;
|
|
2906
2909
|
}
|
|
2907
2910
|
|
|
2908
2911
|
/**
|
|
@@ -2933,7 +2936,7 @@ function isSimpleString( str ) {
|
|
|
2933
2936
|
* @returns {string}
|
|
2934
2937
|
*/
|
|
2935
2938
|
function apiDelimitedId( id ) {
|
|
2936
|
-
return `![${id.replace(/]/g, ']]')}]`;
|
|
2939
|
+
return `![${ id.replace(/]/g, ']]') }]`;
|
|
2937
2940
|
}
|
|
2938
2941
|
|
|
2939
2942
|
/**
|