@sap/cds-compiler 5.1.0 → 5.2.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 +32 -0
- package/bin/cdsc.js +2 -2
- package/bin/cdshi.js +24 -17
- package/bin/cdsse.js +17 -18
- package/lib/api/main.js +19 -2
- package/lib/api/options.js +4 -1
- package/lib/base/builtins.js +1 -0
- package/lib/base/message-registry.js +16 -3
- package/lib/base/model.js +0 -10
- package/lib/checks/actionsFunctions.js +0 -12
- package/lib/checks/structuredAnnoExpressions.js +10 -14
- package/lib/compiler/assert-consistency.js +19 -11
- package/lib/compiler/builtins.js +1 -1
- package/lib/compiler/define.js +6 -4
- package/lib/compiler/extend.js +5 -5
- package/lib/compiler/populate.js +9 -9
- package/lib/compiler/propagator.js +1 -0
- package/lib/compiler/resolve.js +29 -34
- package/lib/compiler/shared.js +7 -8
- package/lib/compiler/tweak-assocs.js +155 -64
- package/lib/compiler/utils.js +1 -1
- package/lib/compiler/xpr-rewrite.js +4 -3
- package/lib/edm/annotations/genericTranslation.js +13 -9
- package/lib/edm/csn2edm.js +26 -2
- package/lib/edm/edm.js +23 -8
- package/lib/edm/edmInboundChecks.js +5 -7
- package/lib/edm/edmPreprocessor.js +43 -30
- package/lib/gen/BaseParser.js +720 -0
- package/lib/gen/CdlParser.js +4421 -0
- package/lib/gen/language.checksum +1 -1
- package/lib/gen/language.interp +1 -1
- package/lib/gen/languageParser.js +4006 -4001
- package/lib/language/antlrParser.js +62 -0
- package/lib/language/genericAntlrParser.js +28 -0
- package/lib/model/csnUtils.js +2 -0
- package/lib/model/revealInternalProperties.js +2 -0
- package/lib/modelCompare/utils/filter.js +70 -42
- package/lib/optionProcessor.js +9 -3
- package/lib/parsers/AstBuildingParser.js +1172 -0
- package/lib/parsers/CdlGrammar.g4 +1940 -0
- package/lib/parsers/Lexer.js +239 -0
- package/lib/render/toCdl.js +23 -27
- package/lib/render/toSql.js +5 -5
- package/lib/transform/db/applyTransformations.js +54 -16
- package/lib/transform/draft/odata.js +10 -11
- package/lib/transform/effective/flattening.js +10 -14
- package/lib/transform/odata/flattening.js +42 -31
- package/lib/transform/odata/toFinalBaseType.js +7 -6
- package/lib/transform/universalCsn/universalCsnEnricher.js +1 -0
- package/package.json +2 -2
- package/share/messages/redirected-to-ambiguous.md +5 -4
|
@@ -17,6 +17,10 @@ const { XsnSource } = require('../compiler/xsn-model');
|
|
|
17
17
|
const Parser = require('../gen/languageParser').default;
|
|
18
18
|
const Lexer = require('../gen/languageLexer').default;
|
|
19
19
|
|
|
20
|
+
const CdlLexer = require( '../parsers/Lexer' );
|
|
21
|
+
const CdlParser = require( '../gen/CdlParser' );
|
|
22
|
+
const { createMessageFunctions } = require( '../base/messages' );
|
|
23
|
+
|
|
20
24
|
// Error listener used for ANTLR4-generated parser
|
|
21
25
|
class ErrorListener extends antlr4.error.ErrorListener {
|
|
22
26
|
// method which is called by generated parser with --trace-parser[-amg]:
|
|
@@ -129,6 +133,9 @@ const rules = {
|
|
|
129
133
|
function parse( source, filename = '<undefined>.cds',
|
|
130
134
|
options = {}, messageFunctions = null,
|
|
131
135
|
rule = 'cdl' ) {
|
|
136
|
+
if (options.newParser)
|
|
137
|
+
return parseWithNewParser( source, filename, options, messageFunctions, rule );
|
|
138
|
+
|
|
132
139
|
const lexer = new Lexer( new antlr4.InputStream(source) );
|
|
133
140
|
const tokenStream = new RewriteTypeTokenStream(lexer);
|
|
134
141
|
/** @type {object} */
|
|
@@ -211,4 +218,59 @@ function parse( source, filename = '<undefined>.cds',
|
|
|
211
218
|
return ast;
|
|
212
219
|
}
|
|
213
220
|
|
|
221
|
+
function parseWithNewParser( source, filename, options, messageFunctions, rule ) {
|
|
222
|
+
if (CdlParser.tracingParser) // tracing → direct console output of message
|
|
223
|
+
messageFunctions = createMessageFunctions( {}, 'parse', {} );
|
|
224
|
+
const lexer = new CdlLexer( filename, source );
|
|
225
|
+
const parser = new CdlParser( lexer, options, messageFunctions ).init();
|
|
226
|
+
parser.filename = filename; // LSP compatibility
|
|
227
|
+
parser.tokenStream = parser; // LSP compatibility: object with property `tokens`
|
|
228
|
+
|
|
229
|
+
// LSP feature: provide parse listener with ANTLR-like context:
|
|
230
|
+
const { parseListener } = options;
|
|
231
|
+
if (parseListener) {
|
|
232
|
+
// TODO LSP: we could also call different listener methods: then LSP could
|
|
233
|
+
// have dedicated methods for ANTLR-based and new parser
|
|
234
|
+
parser.rule_ = function rule_( ...args ) {
|
|
235
|
+
CdlParser.prototype.rule_.apply( this, args );
|
|
236
|
+
let state = this.s;
|
|
237
|
+
while (typeof this.table[--state] !== 'string')
|
|
238
|
+
;
|
|
239
|
+
const $ctx = { // TODO LSP: more to add?
|
|
240
|
+
parser: this, // set in generated ANTLR parser for each rule context
|
|
241
|
+
ruleName: this.table[state], // instead of ruleIndex
|
|
242
|
+
start: this.la(), // set in Parser#enterRule
|
|
243
|
+
stop: null,
|
|
244
|
+
};
|
|
245
|
+
parser.stack.at( -1 ).$ctx = $ctx;
|
|
246
|
+
parseListener.enterEveryRule( $ctx );
|
|
247
|
+
};
|
|
248
|
+
parser.exit_ = function exit_( ...args ) {
|
|
249
|
+
const { $ctx } = parser.stack.at( -1 );
|
|
250
|
+
// TODO: what should we do in case of errors?
|
|
251
|
+
$ctx.stop = this.lb();
|
|
252
|
+
parseListener.exitEveryRule( $ctx );
|
|
253
|
+
CdlParser.prototype.exit_.apply( this, args );
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
const result = {};
|
|
257
|
+
const rulespec = rules[rule];
|
|
258
|
+
if (rulespec) {
|
|
259
|
+
try {
|
|
260
|
+
parser[rulespec.func]( result );
|
|
261
|
+
}
|
|
262
|
+
catch (e) {
|
|
263
|
+
if (!(e instanceof RangeError && /Maximum.*exceeded$/i.test( e.message )))
|
|
264
|
+
throw e;
|
|
265
|
+
messageFunctions.error('syntax-invalid-source', { file: filename },
|
|
266
|
+
{ '#': 'cdl-stackoverflow' } );
|
|
267
|
+
result[rulespec.returns] = undefined;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
const ast = result[rulespec?.returns] || (rule === 'cdl' ? new XsnSource( 'cdl' ) : {} );
|
|
271
|
+
if (options.attachTokens === true || options.attachTokens === filename)
|
|
272
|
+
ast.tokenStream = parser; // with property tokens
|
|
273
|
+
return ast;
|
|
274
|
+
}
|
|
275
|
+
|
|
214
276
|
module.exports = parse;
|
|
@@ -101,6 +101,8 @@ Object.assign(GenericAntlrParser.prototype, {
|
|
|
101
101
|
warnIfColonFollows,
|
|
102
102
|
fragileAlias,
|
|
103
103
|
identAst,
|
|
104
|
+
reportPathNamedManyOrOne,
|
|
105
|
+
reportMissingSemicolon,
|
|
104
106
|
pushXprToken,
|
|
105
107
|
pushOpToken,
|
|
106
108
|
argsExpression,
|
|
@@ -276,6 +278,7 @@ function markAsSkippedUntilEOF() {
|
|
|
276
278
|
function noAssignmentInSameLine() {
|
|
277
279
|
const t = this.getCurrentToken();
|
|
278
280
|
if (t.text === '@' && t.line <= this._input.LT(-1).line) {
|
|
281
|
+
// TODO: use 'syntax-missing-newline'
|
|
279
282
|
this.warning( 'syntax-missing-semicolon', t, { code: ';' },
|
|
280
283
|
// eslint-disable-next-line max-len
|
|
281
284
|
'Add a $(CODE) and/or newline before the annotation assignment to indicate that it belongs to the next statement' );
|
|
@@ -801,6 +804,31 @@ function identAst( token, category, noTokenTypeCheck = false ) {
|
|
|
801
804
|
return ast;
|
|
802
805
|
}
|
|
803
806
|
|
|
807
|
+
function reportPathNamedManyOrOne( { path } ) {
|
|
808
|
+
if (path.length === 1 && !path[0].$delimited &&
|
|
809
|
+
[ 'many', 'one' ].includes( path[0].id.toLowerCase() )) {
|
|
810
|
+
this.message( 'syntax-unexpected-many-one', path[0].location,
|
|
811
|
+
{ code: path[0].id, delimited: path[0].id } );
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
|
|
815
|
+
function reportMissingSemicolon() {
|
|
816
|
+
const next = this._input.LT(1);
|
|
817
|
+
if (next.text !== ';' && next.text !== '' && // ';' by insertSemicolon()
|
|
818
|
+
next.text !== '}' && next.type !== antlr4.Token.EOF &&
|
|
819
|
+
this._input.LT(-1).text !== '}') {
|
|
820
|
+
const offending = this.literalNames[next.type] || this.symbolicNames[next.type];
|
|
821
|
+
const loc = this.tokenLocation( this._input.LT(-1) );
|
|
822
|
+
// better location after the previous token:
|
|
823
|
+
const location = new Location( loc.file, loc.endLine, loc.endCol );
|
|
824
|
+
// it would be nicer to mention the doc comment if present, but not worth the
|
|
825
|
+
// effort; 'syntax-missing-semicolon' already used
|
|
826
|
+
this.warning( 'syntax-missing-proj-semicolon', location,
|
|
827
|
+
{ expecting: [ "';'" ], offending },
|
|
828
|
+
'Missing $(EXPECTING) before $(OFFENDING)');
|
|
829
|
+
}
|
|
830
|
+
}
|
|
831
|
+
|
|
804
832
|
function pushXprToken( args ) {
|
|
805
833
|
const token = this._input.LT(-1);
|
|
806
834
|
args.push( {
|
package/lib/model/csnUtils.js
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
const { csnRefs, implicitAs, pathId } = require('./csnRefs');
|
|
4
4
|
const {
|
|
5
5
|
transformExpression,
|
|
6
|
+
transformAnnotationExpression,
|
|
6
7
|
applyTransformations,
|
|
7
8
|
applyTransformationsOnNonDictionary,
|
|
8
9
|
applyTransformationsOnDictionary,
|
|
@@ -1419,6 +1420,7 @@ module.exports = {
|
|
|
1419
1420
|
getUnderscoredName,
|
|
1420
1421
|
getElementDatabaseNameOf,
|
|
1421
1422
|
transformExpression,
|
|
1423
|
+
transformAnnotationExpression,
|
|
1422
1424
|
applyTransformations,
|
|
1423
1425
|
applyTransformationsOnNonDictionary,
|
|
1424
1426
|
applyTransformationsOnDictionary,
|
|
@@ -306,6 +306,8 @@ function revealInternalProperties( model, nameOrPath ) {
|
|
|
306
306
|
}
|
|
307
307
|
|
|
308
308
|
function array( node, fn ) {
|
|
309
|
+
if (!Array.isArray( node ))
|
|
310
|
+
return node;
|
|
309
311
|
const r = node.map( n => fn( n, node ) );
|
|
310
312
|
if (node[$location])
|
|
311
313
|
r.push( { '[$location]': locationString( node[$location] ) } );
|
|
@@ -10,46 +10,57 @@ function isKey( element ) {
|
|
|
10
10
|
return element.key;
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
13
|
+
function getFilter(options) {
|
|
14
|
+
const filters = {
|
|
15
|
+
sqlite: getFilterObject(
|
|
16
|
+
options,
|
|
17
|
+
'sqlite',
|
|
18
|
+
function forEachExtension(extend, name, elementOrConstraint, { error, warning }) {
|
|
19
|
+
if (isKey(elementOrConstraint)) { // Key must not be extended
|
|
20
|
+
error('type-unsupported-key-sqlite', [ 'definitions', extend, 'elements', name ], { id: name, name: 'sqlite', '#': 'std' } );
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
else if (elementOrConstraint.parentTable) { // constraints have a .parentTable
|
|
24
|
+
warning('def-unsupported-constraint-add', [ 'definitions', elementOrConstraint.parentTable, 'elements', elementOrConstraint.paths ? name : name.slice(elementOrConstraint.parentTable.length + 1) ], { id: elementOrConstraint.identifier || name, name: 'sqlite' },
|
|
25
|
+
'Ignoring add of constraint $(ID), as this is not supported for dialect $(NAME); you need to manually resolve this via shadow tables and data copy');
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return true;
|
|
30
|
+
},
|
|
31
|
+
function forEachMigration(migrate, name, migration, change, error) {
|
|
32
|
+
const newIsKey = isKey(migration.new);
|
|
33
|
+
const oldIsKey = isKey(migration.old);
|
|
34
|
+
if ((newIsKey || oldIsKey) && oldIsKey !== newIsKey) // Turned into key or key was removed
|
|
35
|
+
error('type-unsupported-key-sqlite', [ 'definitions', migrate, 'elements', name ], { id: name, name: 'sqlite', '#': 'changed' } );
|
|
36
|
+
else
|
|
37
|
+
delete change[name];
|
|
38
|
+
},
|
|
39
|
+
function forEachConstraintRemoval(constraintRemovals, name, constraint, warning) {
|
|
40
|
+
warning('def-unsupported-constraint-drop', [ 'definitions', constraint.parentTable, 'elements', constraint.paths ? name : name.slice(constraint.parentTable.length + 1) ], { id: constraint.identifier || name, name: 'sqlite' },
|
|
41
|
+
'Ignoring drop of constraint $(ID), as this is not supported for dialect $(NAME); you need to manually resolve this via shadow tables and data copy');
|
|
42
|
+
delete constraintRemovals[name];
|
|
43
|
+
},
|
|
44
|
+
function primaryKey() {
|
|
24
45
|
return false;
|
|
25
46
|
}
|
|
47
|
+
),
|
|
48
|
+
postgres: getFilterObject(options, 'postgres'),
|
|
49
|
+
h2: getFilterObject(options, 'h2'),
|
|
50
|
+
hana: getFilterObject(options, 'hana'),
|
|
51
|
+
};
|
|
26
52
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
const oldIsKey = isKey(migration.old);
|
|
32
|
-
if ((newIsKey || oldIsKey) && oldIsKey !== newIsKey) // Turned into key or key was removed
|
|
33
|
-
error('type-unsupported-key-sqlite', [ 'definitions', migrate, 'elements', name ], { id: name, name: 'sqlite', '#': 'changed' } );
|
|
34
|
-
else
|
|
35
|
-
delete change[name];
|
|
36
|
-
},
|
|
37
|
-
function forEachConstraintRemoval(constraintRemovals, name, constraint, warning) {
|
|
38
|
-
warning('def-unsupported-constraint-drop', [ 'definitions', constraint.parentTable, 'elements', constraint.paths ? name : name.slice(constraint.parentTable.length + 1) ], { id: constraint.identifier || name, name: 'sqlite' },
|
|
39
|
-
'Ignoring drop of constraint $(ID), as this is not supported for dialect $(NAME); you need to manually resolve this via shadow tables and data copy');
|
|
40
|
-
delete constraintRemovals[name];
|
|
41
|
-
},
|
|
42
|
-
function primaryKey() {
|
|
43
|
-
return false;
|
|
44
|
-
}
|
|
45
|
-
),
|
|
46
|
-
postgres: getFilterObject('postgres'),
|
|
47
|
-
h2: getFilterObject('h2'),
|
|
48
|
-
hana: getFilterObject('hana'),
|
|
53
|
+
return filters[options.sqlDialect];
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
module.exports = {
|
|
49
57
|
csn: filterCsn,
|
|
58
|
+
getFilter,
|
|
50
59
|
};
|
|
51
60
|
|
|
52
|
-
function getFilterObject( dialect, extensionCallback, migrationCallback, removeConstraintsCallback, primaryKeyCallback ) {
|
|
61
|
+
function getFilterObject( options, dialect, extensionCallback, migrationCallback, removeConstraintsCallback, primaryKeyCallback ) {
|
|
62
|
+
const context = { hasLossyChanges: false };
|
|
63
|
+
const raiseErrorOrMarkAsLossy = getSafeguardManager(context, options);
|
|
53
64
|
return {
|
|
54
65
|
// will be called with a simple Array.filter, as we need to filter constraint `ADD` for SQLite
|
|
55
66
|
extension: ({
|
|
@@ -70,24 +81,28 @@ function getFilterObject( dialect, extensionCallback, migrationCallback, removeC
|
|
|
70
81
|
},
|
|
71
82
|
// will be called with a Array.forEach
|
|
72
83
|
migration: (migrations, { error, warning, message }) => {
|
|
73
|
-
forEach(migrations.remove, (name) => {
|
|
74
|
-
error('def-unsupported-element-drop', [ 'definitions', migrations.migrate, 'elements', name ], {}, 'Dropping elements is not supported');
|
|
84
|
+
forEach(migrations.remove, (name, migration) => {
|
|
85
|
+
raiseErrorOrMarkAsLossy(migration, () => error('def-unsupported-element-drop', [ 'definitions', migrations.migrate, 'elements', name ], {}, 'Dropping elements is not supported'));
|
|
75
86
|
});
|
|
87
|
+
|
|
76
88
|
forEach(migrations.change, (name, migration) => {
|
|
77
89
|
const loc = [ 'definitions', migrations.migrate, 'elements', name ];
|
|
78
90
|
if (migration.new.type === migration.old.type && migration.new.length < migration.old.length)
|
|
79
|
-
error('type-unsupported-length-change', loc, { id: name }, 'Changed element $(ID) is a length reduction and is not supported');
|
|
91
|
+
raiseErrorOrMarkAsLossy(migration, () => error('type-unsupported-length-change', loc, { id: name }, 'Changed element $(ID) is a length reduction and is not supported'));
|
|
80
92
|
else if (migration.new.type === migration.old.type && migration.new.scale !== migration.old.scale)
|
|
81
|
-
error('type-unsupported-scale-change', loc, { id: name }, 'Changed element $(ID) is a scale change and is not supported');
|
|
93
|
+
raiseErrorOrMarkAsLossy(migration, () => error('type-unsupported-scale-change', loc, { id: name }, 'Changed element $(ID) is a scale change and is not supported'));
|
|
82
94
|
else if (migration.new.type === migration.old.type && migration.new.precision !== migration.old.scale)
|
|
83
|
-
error('type-unsupported-precision-change', loc, { id: name }, 'Changed element $(ID) is a precision change and is not supported');
|
|
95
|
+
raiseErrorOrMarkAsLossy(migration, () => error('type-unsupported-precision-change', loc, { id: name }, 'Changed element $(ID) is a precision change and is not supported'));
|
|
84
96
|
else if (migration.new.type !== migration.old.type && typeChangeIsNotCompatible(dialect, migration.old.type, migration.new.type))
|
|
85
|
-
error('type-unsupported-change', loc, { id: name, name: migration.old.type, type: migration.new.type }, 'Changed element $(ID) is a lossy type change from $(NAME) to $(TYPE) and is not supported');
|
|
97
|
+
raiseErrorOrMarkAsLossy(migration, () => error('type-unsupported-change', loc, { id: name, name: migration.old.type, type: migration.new.type }, 'Changed element $(ID) is a lossy type change from $(NAME) to $(TYPE) and is not supported'));
|
|
86
98
|
else if (dialect !== 'sqlite' && isKey(migration.new) && !isKey(migration.old)) // key added/changed - pg, hana and sqlite do not support it, h2 probably also - issues when data is in the table already
|
|
87
|
-
message('type-unsupported-key-change', [ 'definitions', migrations.migrate, 'elements', name ], { id: name, '#': 'changed' } );
|
|
99
|
+
raiseErrorOrMarkAsLossy(migration, () => message('type-unsupported-key-change', [ 'definitions', migrations.migrate, 'elements', name ], { id: name, '#': 'changed' } ));
|
|
88
100
|
else if (migrationCallback)
|
|
89
101
|
migrationCallback(migrations.migrate, name, migration, migrations.change, error);
|
|
90
102
|
|
|
103
|
+
if (options.script && migration.lossy && migrationCallback)
|
|
104
|
+
migrationCallback(migrations.migrate, name, migration, migrations.change, error);
|
|
105
|
+
|
|
91
106
|
// TODO: precision/scale growth
|
|
92
107
|
});
|
|
93
108
|
|
|
@@ -102,7 +117,7 @@ function getFilterObject( dialect, extensionCallback, migrationCallback, removeC
|
|
|
102
117
|
},
|
|
103
118
|
deletion: ([ artifactName, artifact ], error) => {
|
|
104
119
|
if (isPersistedAsTable(artifact))
|
|
105
|
-
error('def-unsupported-table-drop', [ 'definitions', artifactName ], 'Dropping tables is not supported');
|
|
120
|
+
raiseErrorOrMarkAsLossy(artifact, () => error('def-unsupported-table-drop', [ 'definitions', artifactName ], 'Dropping tables is not supported'));
|
|
106
121
|
},
|
|
107
122
|
changedPrimaryKeys: (changedPrimaryKeyArtifactName) => {
|
|
108
123
|
if (primaryKeyCallback)
|
|
@@ -110,6 +125,7 @@ function getFilterObject( dialect, extensionCallback, migrationCallback, removeC
|
|
|
110
125
|
|
|
111
126
|
return true;
|
|
112
127
|
},
|
|
128
|
+
hasLossyChanges: () => context.hasLossyChanges,
|
|
113
129
|
};
|
|
114
130
|
}
|
|
115
131
|
|
|
@@ -173,3 +189,15 @@ function filterCsn( csn ) {
|
|
|
173
189
|
|
|
174
190
|
return csn;
|
|
175
191
|
}
|
|
192
|
+
|
|
193
|
+
function getSafeguardManager( context, options ) {
|
|
194
|
+
return function raiseErrorOrMarkAsLossy(migration, raiseError) {
|
|
195
|
+
if (!options.script) {
|
|
196
|
+
raiseError();
|
|
197
|
+
}
|
|
198
|
+
else {
|
|
199
|
+
migration.lossy = true;
|
|
200
|
+
context.hasLossyChanges = true;
|
|
201
|
+
}
|
|
202
|
+
};
|
|
203
|
+
}
|
package/lib/optionProcessor.js
CHANGED
|
@@ -38,6 +38,7 @@ optionProcessor
|
|
|
38
38
|
.option(' --debug <id-list>')
|
|
39
39
|
.option('-E, --enrich-csn')
|
|
40
40
|
.option('-R, --raw-output <name>')
|
|
41
|
+
.option(' --new-parser')
|
|
41
42
|
.option(' --internal-msg')
|
|
42
43
|
.option(' --beta-mode')
|
|
43
44
|
.option(' --beta <list>')
|
|
@@ -54,6 +55,7 @@ optionProcessor
|
|
|
54
55
|
.option(' --default-binary-length <length>')
|
|
55
56
|
.option(' --default-string-length <length>')
|
|
56
57
|
.option(' --no-recompile')
|
|
58
|
+
.option(' --skip-name-check', { optionName: '$skipNameCheck' })
|
|
57
59
|
.positionalArgument('<files...>')
|
|
58
60
|
.help(`
|
|
59
61
|
Usage: cdsc <command> [options] <files...>
|
|
@@ -113,6 +115,7 @@ optionProcessor
|
|
|
113
115
|
with name = "+", write complete XSN, long!
|
|
114
116
|
--tenant-discriminator Add tenant fields to entities
|
|
115
117
|
--internal-msg Write raw messages with call stack to <stdout>/<stderr>
|
|
118
|
+
--new-parser Use the new CDL parser
|
|
116
119
|
--beta-mode Enable all unsupported, incomplete (beta) features
|
|
117
120
|
--beta <list> Comma separated list of unsupported, incomplete (beta) features to use.
|
|
118
121
|
Valid values are:
|
|
@@ -150,6 +153,7 @@ optionProcessor
|
|
|
150
153
|
to "sap.common.Languages" if it exists
|
|
151
154
|
--localized-without-coalesce Omit coalesce in localized convenience views
|
|
152
155
|
--no-recompile Don't recompile in case of internal errors
|
|
156
|
+
--skip-name-check Skip certain name checks, e.g. that there must be no '.' in element names.
|
|
153
157
|
|
|
154
158
|
Commands
|
|
155
159
|
H, toHana [options] <files...> Generate HANA CDS source files
|
|
@@ -166,7 +170,7 @@ optionProcessor
|
|
|
166
170
|
manageConstraints [options] <files...> (internal) Generate ALTER TABLE statements to
|
|
167
171
|
add / modify referential constraints.
|
|
168
172
|
inspect [options] <files...> (internal) Inspect the given CDS files.
|
|
169
|
-
|
|
173
|
+
forEffective [options] <files...> (internal) Get an effective CSN; requires beta mode
|
|
170
174
|
forSeal [options] <files...> (internal) Get a SEAL CSN
|
|
171
175
|
|
|
172
176
|
Environment variables
|
|
@@ -245,6 +249,7 @@ optionProcessor.command('O, toOdata')
|
|
|
245
249
|
.option(' --odata-foreign-keys')
|
|
246
250
|
.option(' --odata-v2-partial-constr')
|
|
247
251
|
.option(' --odata-vocabularies <list>')
|
|
252
|
+
.option(' --odata-no-creator')
|
|
248
253
|
.option('-c, --csn')
|
|
249
254
|
.option('-f, --odata-format <format>', { valid: ['flat', 'structured'] })
|
|
250
255
|
.option('-n, --sql-mapping <style>', { valid: ['plain', 'quoted', 'hdbcds'], aliases: [ '--names' ] })
|
|
@@ -278,6 +283,7 @@ optionProcessor.command('O, toOdata')
|
|
|
278
283
|
(Not spec compliant and V2 only)
|
|
279
284
|
--odata-vocabularies <list> JSON array of adhoc vocabulary definitions
|
|
280
285
|
{ prefix: { alias, ns, uri }, ... }
|
|
286
|
+
--odata-no-creator Omit creator identification in API
|
|
281
287
|
-n, --sql-mapping <style> Annotate artifacts and elements with "@cds.persistence.name", which is
|
|
282
288
|
the corresponding database name (see "--sql-mapping" for "toHana or "toSql")
|
|
283
289
|
plain : (default) Names in uppercase and flattened with underscores
|
|
@@ -564,7 +570,7 @@ optionProcessor.command('inspect')
|
|
|
564
570
|
--propagation <art> Show propagation sources for <art>
|
|
565
571
|
`);
|
|
566
572
|
|
|
567
|
-
optionProcessor.command('
|
|
573
|
+
optionProcessor.command('forEffective')
|
|
568
574
|
.option('-h, --help')
|
|
569
575
|
.option('--resolve-simple-types <val>', { valid: ['true', 'false'] } )
|
|
570
576
|
.option('--resolve-projections <val>', { valid: ['true', 'false'] } )
|
|
@@ -572,7 +578,7 @@ optionProcessor.command('toEffectiveCsn')
|
|
|
572
578
|
.option('--keep-localized <val>', { valid: ['true', 'false'] } )
|
|
573
579
|
.positionalArgument('<files...>')
|
|
574
580
|
.help(`
|
|
575
|
-
Usage: cdsc
|
|
581
|
+
Usage: cdsc forEffective [options] <files...>
|
|
576
582
|
|
|
577
583
|
(internal): Get the effective CSN model compiled from the provided CDS files.
|
|
578
584
|
This command may change any time, including its name.
|