@sap/cds-compiler 3.0.0 → 3.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/CHANGELOG.md +29 -9
  2. package/bin/cdsc.js +9 -16
  3. package/lib/api/main.js +92 -40
  4. package/lib/base/keywords.js +64 -1
  5. package/lib/base/message-registry.js +17 -1
  6. package/lib/base/messages.js +38 -28
  7. package/lib/base/optionProcessorHelper.js +53 -21
  8. package/lib/compiler/assert-consistency.js +1 -1
  9. package/lib/compiler/builtins.js +40 -1
  10. package/lib/compiler/define.js +4 -2
  11. package/lib/compiler/extend.js +4 -1
  12. package/lib/compiler/populate.js +3 -1
  13. package/lib/compiler/resolve.js +1 -4
  14. package/lib/compiler/shared.js +9 -0
  15. package/lib/compiler/utils.js +2 -2
  16. package/lib/edm/annotations/preprocessAnnotations.js +10 -11
  17. package/lib/edm/csn2edm.js +15 -14
  18. package/lib/edm/edm.js +13 -12
  19. package/lib/edm/edmPreprocessor.js +30 -33
  20. package/lib/edm/edmUtils.js +3 -39
  21. package/lib/gen/language.checksum +1 -1
  22. package/lib/gen/language.interp +1 -1
  23. package/lib/gen/languageParser.js +3311 -3289
  24. package/lib/json/from-csn.js +17 -19
  25. package/lib/json/to-csn.js +3 -2
  26. package/lib/language/genericAntlrParser.js +42 -42
  27. package/lib/language/language.g4 +28 -17
  28. package/lib/model/csnRefs.js +1 -0
  29. package/lib/model/csnUtils.js +19 -8
  30. package/lib/model/revealInternalProperties.js +4 -1
  31. package/lib/optionProcessor.js +54 -38
  32. package/lib/render/toHdbcds.js +1 -1
  33. package/lib/render/toSql.js +7 -3
  34. package/lib/transform/forOdataNew.js +3 -3
  35. package/lib/transform/localized.js +15 -11
  36. package/lib/utils/file.js +28 -18
  37. package/package.json +2 -3
  38. package/share/messages/syntax-expected-integer.md +9 -8
@@ -19,10 +19,7 @@ optionProcessor
19
19
  .option(' --color <mode>', ['auto', 'always', 'never'])
20
20
  .option('-o, --out <dir>')
21
21
  .option(' --cds-home <dir>')
22
- .option(' --lint-mode')
23
22
  .option(' --fuzzy-csn-error')
24
- .option(' --trace-parser')
25
- .option(' --trace-parser-amb')
26
23
  .option(' --trace-fs')
27
24
  .option(' --error <id-list>')
28
25
  .option(' --warn <id-list>')
@@ -35,7 +32,6 @@ optionProcessor
35
32
  .option(' --beta <list>')
36
33
  .option(' --deprecated <list>')
37
34
  .option(' --direct-backend')
38
- .option(' --parse-only')
39
35
  .option(' --fallback-parser <type>', ['cdl', 'csn', 'csn!'])
40
36
  .option(' --test-mode')
41
37
  .option(' --test-sort-csn')
@@ -78,7 +74,6 @@ optionProcessor
78
74
  never:
79
75
  -o, --out <dir> Place generated files in directory <dir>, default is "-" for <stdout>
80
76
  --cds-home <dir> When set, modules starting with '@sap/cds/' are searched in <dir>
81
- --lint-mode Generate nothing, just produce messages if any (for use by editors)
82
77
  --fuzzy-csn-error Report free-style CSN properties as errors
83
78
  -- Indicate the end of options (helpful if source names start with "-")
84
79
 
@@ -87,8 +82,6 @@ optionProcessor
87
82
  --default-string-length <length> Default 'length' for 'cds.String'
88
83
 
89
84
  Diagnostic options
90
- --trace-parser Trace parser
91
- --trace-parser-amb Trace parser ambiguities
92
85
  --trace-fs Trace file system access caused by "using from"
93
86
 
94
87
  Severity options
@@ -112,7 +105,6 @@ optionProcessor
112
105
  --deprecated <list> Comma separated list of deprecated options.
113
106
  Valid values are:
114
107
  eagerPersistenceForGeneratedEntities
115
- --parse-only Stop compilation after parsing and write result to <stdout>
116
108
  --fallback-parser <type> If the language cannot be deduced by the file's extensions, use this
117
109
  parser as a fallback. Valid values are:
118
110
  cdl : Use CDL parser
@@ -141,6 +133,8 @@ optionProcessor
141
133
  toCsn [options] <files...> (default) Generate original model as CSN
142
134
  parseCdl [options] <file> Generate a CSN that is close to the CDL source.
143
135
  explain <message-id> Explain a compiler message.
136
+ parseOnly [options] <files...> (internal) Stop compilation after parsing, write messages to <stderr>,
137
+ per default no output.
144
138
  toRename [options] <files...> (internal) Generate SQL DDL rename statements
145
139
  manageConstraints [options] <files...> (internal) Generate ALTER TABLE statements to
146
140
  add / modify referential constraints.
@@ -149,7 +143,7 @@ optionProcessor
149
143
  // ----------- toHana -----------
150
144
  optionProcessor.command('H, toHana')
151
145
  .option('-h, --help')
152
- .option('-n, --names <style>', ['plain', 'quoted', 'hdbcds'])
146
+ .option('-n, --sql-mapping <style>', ['plain', 'quoted', 'hdbcds'], { aliases: ['--names'] })
153
147
  .option(' --render-virtual')
154
148
  .option(' --joinfk')
155
149
  .option('-u, --user <user>')
@@ -166,7 +160,7 @@ optionProcessor.command('H, toHana')
166
160
 
167
161
  Options
168
162
  -h, --help Show this help text
169
- -n, --names <style> Naming style for generated entity and element names:
163
+ -n, --sql-mapping <style> Naming style for generated entity and element names:
170
164
  plain : (default) Produce HANA entity and element names in
171
165
  uppercase and flattened with underscores. Do not generate
172
166
  structured types.
@@ -197,7 +191,7 @@ optionProcessor.command('H, toHana')
197
191
 
198
192
  optionProcessor.command('O, toOdata')
199
193
  .option('-h, --help')
200
- .option('-v, --odata-version <version>', ['v2', 'v4', 'v4x'])
194
+ .option('-v, --odata-version <version>', ['v2', 'v4', 'v4x'], { aliases: ['--version'] })
201
195
  .option('-x, --xml')
202
196
  .option('-j, --json')
203
197
  .option(' --odata-containment')
@@ -207,7 +201,7 @@ optionProcessor.command('O, toOdata')
207
201
  .option(' --odata-v2-partial-constr')
208
202
  .option('-c, --csn')
209
203
  .option('-f, --odata-format <format>', ['flat', 'structured'])
210
- .option('-n, --names <style>', ['plain', 'quoted', 'hdbcds'])
204
+ .option('-n, --sql-mapping <style>', ['plain', 'quoted', 'hdbcds'], { aliases: [ '--names' ] })
211
205
  .option('-s, --service-names <list>')
212
206
  .help(`
213
207
  Usage: cdsc toOdata [options] <files...>
@@ -232,13 +226,13 @@ optionProcessor.command('O, toOdata')
232
226
  --odata-foreign-keys Render foreign keys in structured format (V4 only)
233
227
  --odata-v2-partial-constr Render referential constraints also for partial principal key tuple
234
228
  (Not spec compliant and V2 only)
235
- -n, --names <style> Annotate artifacts and elements with "@cds.persistence.name", which is
236
- the corresponding database name (see "--names" for "toHana or "toSql")
237
- plain : (default) Names in uppercase and flattened with underscores
238
- quoted : Names in original case as in CDL. Entity names with dots,
239
- but element names flattened with underscores
240
- hdbcds : Names as HANA CDS would generate them from the same CDS
241
- source (like "quoted", but using element names with dots)
229
+ -n, --sql-mapping <style> Annotate artifacts and elements with "@cds.persistence.name", which is
230
+ the corresponding database name (see "--sql-mapping" for "toHana or "toSql")
231
+ plain : (default) Names in uppercase and flattened with underscores
232
+ quoted : Names in original case as in CDL. Entity names with dots,
233
+ but element names flattened with underscores
234
+ hdbcds : Names as HANA CDS would generate them from the same CDS
235
+ source (like "quoted", but using element names with dots)
242
236
  -s, --service-names <list> List of comma-separated service names to be rendered
243
237
  (default) empty, all services are rendered
244
238
  `);
@@ -256,10 +250,10 @@ optionProcessor.command('C, toCdl')
256
250
 
257
251
  optionProcessor.command('Q, toSql')
258
252
  .option('-h, --help')
259
- .option('-n, --names <style>', ['plain', 'quoted', 'hdbcds'])
253
+ .option('-n, --sql-mapping <style>', ['plain', 'quoted', 'hdbcds'], { aliases: [ '--names' ] })
254
+ .option('-d, --sql-dialect <dialect>', ['hana', 'sqlite', 'plain', 'postgres'], { aliases: [ '--dialect' ] })
260
255
  .option(' --render-virtual')
261
256
  .option(' --joinfk')
262
- .option('-d, --dialect <dialect>', ['hana', 'sqlite', 'plain', 'postgres'])
263
257
  .option('-u, --user <user>')
264
258
  .option('-l, --locale <locale>')
265
259
  .option('-s, --src <style>', ['sql', 'hdi'])
@@ -276,7 +270,7 @@ optionProcessor.command('Q, toSql')
276
270
 
277
271
  Options
278
272
  -h, --help Show this help text
279
- -n, --names <style> Naming style for generated entity and element names:
273
+ -n, --sql-mapping <style> Naming style for generated entity and element names:
280
274
  plain : (default) Produce SQL table and view names in
281
275
  flattened with underscores format (no quotes required)
282
276
  quoted : Produce SQL table and view names in original case as in
@@ -289,7 +283,7 @@ optionProcessor.command('Q, toSql')
289
283
  combination with "hana" dialect.
290
284
  --render-virtual Render virtual elements in views and draft tables
291
285
  --joinfk Create JOINs for foreign key accesses
292
- -d, --dialect <dialect> SQL dialect to be generated:
286
+ -d, --sql-dialect <dialect> SQL dialect to be generated:
293
287
  plain : (default) Common SQL - no assumptions about DB restrictions
294
288
  hana : SQL with HANA specific language features
295
289
  sqlite : Common SQL for sqlite
@@ -320,28 +314,29 @@ optionProcessor.command('Q, toSql')
320
314
 
321
315
  optionProcessor.command('toRename')
322
316
  .option('-h, --help')
323
- .option('-n, --names <style>', ['quoted', 'hdbcds'])
317
+ .option('-n, --sql-mapping <style>', ['quoted', 'hdbcds'], { aliases: ['--names'] })
324
318
  .help(`
325
319
  Usage: cdsc toRename [options] <files...>
326
320
 
327
321
  (internal, subject to change): Generate SQL stored procedure containing DDL statements to
328
322
  "storedProcedure.sql" that allows to rename existing tables and their columns so that they
329
- match the result of "toHana" or "toSql" with the "--names plain" option.
323
+ match the result of "toHana" or "toSql" with the "--sql-mapping plain" option.
330
324
 
331
325
  Options
332
326
  -h, --help Display this help text
333
- -n, --names <style> Assume existing tables were generated with "--names <style>":
327
+ -n, --sql-mapping <style>
328
+ Assume existing tables were generated with "--sql-mapping <style>":
334
329
  quoted : Assume existing SQL tables and views were named in original
335
330
  case as in CDL (with dots), but column names were flattened
336
- with underscores (e.g. resulting from "toHana --names quoted")
331
+ with underscores (e.g. resulting from "toHana --sql-mapping quoted")
337
332
  hdbcds : (default) Assume existing SQL tables, views and columns were
338
333
  generated by HANA CDS from the same CDS source (or resulting
339
- from "toHana --names hdbcds")
334
+ from "toHana --sql-mapping hdbcds")
340
335
  `);
341
336
 
342
337
  optionProcessor.command('manageConstraints')
343
338
  .option('-h, --help')
344
- .option('-n, --names <style>', ['plain', 'quoted', 'hdbcds'])
339
+ .option('-n, --sql-mapping <style>', ['plain', 'quoted', 'hdbcds'], { aliases: ['--names'] })
345
340
  .option('-s, --src <style>', ['sql', 'hdi'])
346
341
  .option(' --drop')
347
342
  .option(' --alter')
@@ -357,7 +352,8 @@ optionProcessor.command('manageConstraints')
357
352
 
358
353
  Options
359
354
  -h, --help Display this help text
360
- -n, --names <style> Assume existing tables were generated with "--names <style>":
355
+ -n, --sql-mapping <style>
356
+ Assume existing tables were generated with "--sql-mapping <style>":
361
357
  plain : (default) Assume SQL tables were flattened and dots were
362
358
  replaced by underscores
363
359
  quoted : Assume existing SQL tables and views were named in original
@@ -379,7 +375,7 @@ optionProcessor.command('manageConstraints')
379
375
 
380
376
  optionProcessor.command('toCsn')
381
377
  .option('-h, --help')
382
- .option('-f, --flavor <flavor>', ['client', 'gensrc', 'universal'])
378
+ .option('-f, --csn-flavor <flavor>', ['client', 'gensrc', 'universal'], { aliases: ['--flavor'] })
383
379
  .option(' --with-localized')
384
380
  .help(`
385
381
  Usage: cdsc toCsn [options] <files...>
@@ -388,13 +384,13 @@ optionProcessor.command('toCsn')
388
384
 
389
385
  Options
390
386
  -h, --help Show this help text
391
- -f, --flavor <flavor> Generate CSN in one of two flavors:
392
- client : (default) Standard CSN consumable by clients and backends
393
- gensrc : CSN specifically for use as a source, e.g. for
394
- combination with additional "extend" or "annotate"
395
- statements, but not suitable for consumption by clients or
396
- backends
397
- universal: in development (BETA)
387
+ -f, --csn-flavor <flavor> Generate CSN in one of two flavors:
388
+ client : (default) Standard CSN consumable by clients and backends
389
+ gensrc : CSN specifically for use as a source, e.g. for
390
+ combination with additional "extend" or "annotate"
391
+ statements, but not suitable for consumption by clients or
392
+ backends
393
+ universal: in development (BETA)
398
394
 
399
395
  Internal options (for testing only, may be changed/removed at any time)
400
396
  --with-localized Add localized convenience views to the CSN output.
@@ -413,6 +409,26 @@ optionProcessor.command('parseCdl')
413
409
  -h, --help Show this help text
414
410
  `);
415
411
 
412
+ optionProcessor.command('parseOnly')
413
+ .option('-h, --help')
414
+ .option(' --trace-parser')
415
+ .option(' --trace-parser-amb')
416
+ .positionalArgument('<file>')
417
+ .help(`
418
+ Usage: cdsc parseOnly [options] <files...>
419
+
420
+ (internal): Stop compilation after parsing and write messages to <stderr>.
421
+ Per default, nothing is printed. With \`--raw-output +\`, XSN is printed
422
+ to <stdout>.
423
+
424
+ Options
425
+ -h, --help Show this help text
426
+
427
+ Diagnostic options
428
+ --trace-parser Trace parser
429
+ --trace-parser-amb Trace parser ambiguities
430
+ `);
431
+
416
432
  optionProcessor.command('explain')
417
433
  .option('-h, --help')
418
434
  .positionalArgument('<message-id>')
@@ -839,7 +839,7 @@ function toHdbcdsSource(csn, options) {
839
839
  * @param {object} [elements] For leading query, the elements of the artifact
840
840
  * @returns {string} The rendered query
841
841
  */
842
- function renderQuery(query, isLeadingQuery, env, path = [], elements) {
842
+ function renderQuery(query, isLeadingQuery, env, path = [], elements = null) {
843
843
  let result = '';
844
844
  env.skipKeys = !isLeadingQuery;
845
845
  // Set operator, like UNION, INTERSECT, ...
@@ -117,6 +117,9 @@ function toSqlDdl(csn, options) {
117
117
  */
118
118
  addColumns: {
119
119
  fromElementStrings(tableName, eltStrings) {
120
+ if (options.sqlDialect === 'sqlite') // SQLite can only alter one column at a time
121
+ return eltStrings.map(eltString => `ALTER TABLE ${tableName} ADD ${eltString};`);
122
+
120
123
  const elts = options.sqlDialect === 'hana' ? `(${eltStrings.join(', ')})` : `${eltStrings.join(', ')}`;
121
124
  return [ `ALTER TABLE ${tableName} ADD ${elts};` ];
122
125
  },
@@ -138,10 +141,10 @@ function toSqlDdl(csn, options) {
138
141
  TODO duplicity check
139
142
  */
140
143
  addAssociations(artifactName, tableName, elementsObj, env) {
141
- return Object.entries(elementsObj)
144
+ return options.sqlDialect === 'hana' ? Object.entries(elementsObj)
142
145
  .map(([ name, elt ]) => renderAssociationElement(name, elt, env))
143
146
  .filter(s => s !== '')
144
- .map(eltStr => `ALTER TABLE ${tableName} ADD ASSOCIATION (${eltStr});`);
147
+ .map(eltStr => `ALTER TABLE ${tableName} ADD ASSOCIATION (${eltStr});`) : [];
145
148
  },
146
149
  /*
147
150
  Render key addition as HANA SQL.
@@ -159,7 +162,7 @@ function toSqlDdl(csn, options) {
159
162
  Render association removals as HANA SQL.
160
163
  */
161
164
  dropAssociation(tableName, sqlId) {
162
- return [ `ALTER TABLE ${tableName} DROP ASSOCIATION ${sqlId};` ];
165
+ return options.sqlDialect === 'hana' ? [ `ALTER TABLE ${tableName} DROP ASSOCIATION ${sqlId};` ] : [];
163
166
  },
164
167
  /*
165
168
  Render primary-key removals as HANA SQL.
@@ -1492,6 +1495,7 @@ function toSqlDdl(csn, options) {
1492
1495
  }
1493
1496
  else if (x.ref[0] === '$now') { // TODO: Can there be cases where $now is followed by something?
1494
1497
  switch (options.sqlDialect) {
1498
+ case 'plain':
1495
1499
  case 'sqlite':
1496
1500
  case 'hana':
1497
1501
  return 'CURRENT_TIMESTAMP';
@@ -120,7 +120,7 @@ function transform4odataWithCsn(inputModel, options) {
120
120
  return keepLocalizedViews && !isExternalServiceMember(undefined, parent);
121
121
  }
122
122
 
123
- addLocalizationViews(csn, options, acceptLocalizedView);
123
+ addLocalizationViews(csn, options, { acceptLocalizedView, ignoreUnknownExtensions: true });
124
124
 
125
125
  const cleanup = validate.forOdata(csn, {
126
126
  message, error, warning, info, inspectRef, effectiveType, artifactRef, csn, options, csnUtils, services, isAspect, isExternalServiceMember
@@ -324,7 +324,7 @@ function transform4odataWithCsn(inputModel, options) {
324
324
  // but '@Core.Immutable' for everything else.
325
325
  if (!(node['@readonly'] && node['@insertonly'])) {
326
326
  if (name === '@readonly' && node[name] !== null) {
327
- if (node.kind === 'entity') {
327
+ if (node.kind === 'entity' || node.kind === 'aspect') {
328
328
  setAnnotation(node, '@Capabilities.DeleteRestrictions.Deletable', false);
329
329
  setAnnotation(node, '@Capabilities.InsertRestrictions.Insertable', false);
330
330
  setAnnotation(node, '@Capabilities.UpdateRestrictions.Updatable', false);
@@ -334,7 +334,7 @@ function transform4odataWithCsn(inputModel, options) {
334
334
  }
335
335
  // @insertonly is effective on entities/queries only
336
336
  else if (name === '@insertonly' && node[name] !== null) {
337
- if (node.kind === 'entity') {
337
+ if (node.kind === 'entity' || node.kind === 'aspect') {
338
338
  setAnnotation(node, '@Capabilities.DeleteRestrictions.Deletable', false);
339
339
  setAnnotation(node, '@Capabilities.ReadRestrictions.Readable', false);
340
340
  setAnnotation(node, '@Capabilities.UpdateRestrictions.Updatable', false);
@@ -69,10 +69,9 @@ const _targetFor = Symbol('_targetFor');
69
69
  * @param {CSN.Options} options
70
70
  * @param {boolean} useJoins If true, rewrite the "localized" association to a
71
71
  * join in direct convenience views.
72
- * @param {acceptLocalizedView} [acceptLocalizedView] optional callback function returning true if the localized view
73
- * name and its parent name provided as parameter should be created
72
+ * @param {object} config
74
73
  */
75
- function _addLocalizationViews(csn, options, useJoins, acceptLocalizedView = null) {
74
+ function _addLocalizationViews(csn, options, useJoins, config) {
76
75
  // Don't try to create convenience views with errors.
77
76
  if (hasErrors(options.messages))
78
77
  return csn;
@@ -81,6 +80,7 @@ function _addLocalizationViews(csn, options, useJoins, acceptLocalizedView = nul
81
80
  if (hasExistingLocalizationViews(csn, options, messageFunctions))
82
81
  return csn;
83
82
 
83
+ const { acceptLocalizedView, ignoreUnknownExtensions } = config;
84
84
  const noCoalesce = (options.localizedLanguageFallback === 'none' ||
85
85
  options.localizedWithoutCoalesce);
86
86
 
@@ -91,8 +91,12 @@ function _addLocalizationViews(csn, options, useJoins, acceptLocalizedView = nul
91
91
 
92
92
  // In case that the user tried to annotate `localized.*` artifacts, apply them.
93
93
  applyAnnotationsFromExtensions(csn, {
94
- overwrite: true,
95
- filter: (name) => name.startsWith('localized.')
94
+ override: true,
95
+ filter: (name) => name.startsWith('localized.'),
96
+ notFound(name, index) {
97
+ if (!ignoreUnknownExtensions)
98
+ messageFunctions.message('anno-undefined-art', [ 'extensions', index ], { name })
99
+ },
96
100
  });
97
101
 
98
102
  sortCsnDefinitionsForTests(csn, options);
@@ -608,10 +612,10 @@ function _addLocalizationViews(csn, options, useJoins, acceptLocalizedView = nul
608
612
  *
609
613
  * @param {CSN.Model} csn
610
614
  * @param {CSN.Options} options
611
- * @param [acceptLocalizedView] optional callback function returning true if the localized view name and its parent name provided as parameter should be created
615
+ * @param [config] config.acceptLocalizedView: optional callback function returning true if the localized view name and its parent name provided as parameter should be created
612
616
  */
613
- function addLocalizationViews(csn, options, acceptLocalizedView = null) {
614
- return _addLocalizationViews(csn, options, false, acceptLocalizedView);
617
+ function addLocalizationViews(csn, options, config = {}) {
618
+ return _addLocalizationViews(csn, options, false, config);
615
619
  }
616
620
 
617
621
  /**
@@ -621,10 +625,10 @@ function addLocalizationViews(csn, options, acceptLocalizedView = null) {
621
625
  *
622
626
  * @param {CSN.Model} csn
623
627
  * @param {CSN.Options} options
624
- * @param [acceptLocalizedView] optional callback function returning true if the localized view name and its parent name provided as parameter should be created
628
+ * @param [config] config.acceptLocalizedView: optional callback function returning true if the localized view name and its parent name provided as parameter should be created
625
629
  */
626
- function addLocalizationViewsWithJoins(csn, options, acceptLocalizedView = null) {
627
- return _addLocalizationViews(csn, options, true, acceptLocalizedView);
630
+ function addLocalizationViewsWithJoins(csn, options, config = {}) {
631
+ return _addLocalizationViews(csn, options, true, config);
628
632
  }
629
633
 
630
634
  /**
package/lib/utils/file.js CHANGED
@@ -113,11 +113,16 @@ function cdsFs(fileCache, enableTrace) {
113
113
  traceFS( 'READFILE:start:', filename );
114
114
  // TODO: set cache directly to some "delay" - store error differently?
115
115
  // e.g. an error of callback functions!
116
- reader(filename, enc, ( err, data ) => {
117
- fileCache[filename] = err || data;
118
- traceFS( 'READFILE:data:', filename, err || data );
119
- cb( err, data );
120
- });
116
+ try {
117
+ reader(filename, enc, (err, data) => {
118
+ fileCache[filename] = err || data;
119
+ traceFS('READFILE:data:', filename, err || data);
120
+ cb(err, data);
121
+ });
122
+ }
123
+ catch (err) {
124
+ cb(err); // if filename is not a valid (e.g. contains NUL byte), readFile() may throw
125
+ }
121
126
  }
122
127
  };
123
128
  }
@@ -143,19 +148,24 @@ function cdsFs(fileCache, enableTrace) {
143
148
  // in the future (if we do module resolve ourself with just readFile),
144
149
  // we avoid parallel readFile by storing having an array of `cb`s in
145
150
  // fileCache[ filename ] before starting fs.readFile().
146
- fsStat( filename, ( err, stat ) => {
147
- if (err)
148
- body = (err.code === 'ENOENT' || err.code === 'ENOTDIR') ? false : err;
149
- else
150
- body = !!(stat.isFile() || stat.isFIFO());
151
- if (fileCache[filename] === undefined) // parallel readFile() has been processed
152
- fileCache[filename] = body;
153
- traceFS( 'ISFILE:data:', filename, body );
154
- if (body instanceof Error)
155
- cb( err );
156
- else
157
- cb( null, body );
158
- });
151
+ try {
152
+ fsStat(filename, (err, stat) => {
153
+ if (err)
154
+ body = (err.code === 'ENOENT' || err.code === 'ENOTDIR') ? false : err;
155
+ else
156
+ body = !!(stat.isFile() || stat.isFIFO());
157
+ if (fileCache[filename] === undefined) // parallel readFile() has been processed
158
+ fileCache[filename] = body;
159
+ traceFS('ISFILE:data:', filename, body);
160
+ if (body instanceof Error)
161
+ cb(err);
162
+ else
163
+ cb(null, body);
164
+ });
165
+ }
166
+ catch (err) {
167
+ cb(err); // if filename is not a valid (e.g. contains NUL byte), fsStat() may throw
168
+ }
159
169
  }
160
170
  };
161
171
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sap/cds-compiler",
3
- "version": "3.0.0",
3
+ "version": "3.0.2",
4
4
  "description": "CDS (Core Data Services) compiler and backends",
5
5
  "homepage": "https://cap.cloud.sap/",
6
6
  "author": "SAP SE (https://www.sap.com)",
@@ -19,9 +19,8 @@
19
19
  "xmakeBeforeInstall": "echo \"Due to binary mirror, use sqlite 5.0.8 explicitly\" && npm install --save --save-exact --no-package-lock sqlite3@5.0.8",
20
20
  "xmakeAfterInstall": "npm run gen",
21
21
  "xmakePrepareRelease": "echo \"$(node scripts/stripReadme.js README.md)\" > README.md && node scripts/assertSnapshotVersioning.js && node scripts/assertChangelog.js && node scripts/cleanup.js --remove-dev",
22
- "test": "node scripts/verifyGrammarChecksum.js && mocha --parallel --reporter min --reporter-option maxDiffSize=0 test/ test3/ && mocha scripts/testLazyLoading.js",
22
+ "test": "node scripts/verifyGrammarChecksum.js && mocha --reporter min --reporter-option maxDiffSize=0 scripts/testLazyLoading.js && mocha --parallel --reporter min --reporter-option maxDiffSize=0 test/ test3/",
23
23
  "testverbose": "node scripts/verifyGrammarChecksum.js && mocha --parallel test/ test3/",
24
- "testdot": "node scripts/verifyGrammarChecksum.js && mocha --parallel --reporter dot --reporter-option maxDiffSize=0 --full-trace scripts/linter/lintMessages.js test/ test3/",
25
24
  "test3": "node scripts/verifyGrammarChecksum.js && node scripts/linter/lintTests.js test3/ && mocha --reporter-option maxDiffSize=0 scripts/linter/lintMessages.js test3/",
26
25
  "deployTest3SQL": "deployRefs=true mocha --reporter-option maxDiffSize=0 test3/testHANASQLDeployment.js",
27
26
  "deployTest3": "deployRefs=true mocha --reporter-option maxDiffSize=0 test3/testDeployment.js",
@@ -1,12 +1,12 @@
1
1
  # syntax-expected-integer
2
2
 
3
3
  The compiler expects a safe integer here.
4
- The last safe Integer is `2^53 - 1` or `9007199254740991`.
4
+ The last safe integer is `2^53 - 1` or `9007199254740991`.
5
5
 
6
- A safe integer is an integer that
6
+ A safe integer is an integer that fulfills all of the following:
7
7
 
8
- - can be exactly represented as an IEEE-754 double precision number, and
9
- - whose IEEE-754 representation cannot be the result of rounding any
8
+ - Can be exactly represented as an IEEE-754 double precision number.
9
+ - The IEEE-754 representation cannot be the result of rounding any
10
10
  other integer to fit the IEEE-754 representation.
11
11
 
12
12
  The message's severity is `Error`.
@@ -15,13 +15,14 @@ The message's severity is `Error`.
15
15
 
16
16
  Erroneous code example:
17
17
 
18
+ <!-- cds-mode: ignore -->
18
19
  ```cdl
19
20
  type LengthIsUnsafe : String(9007199254740992);
20
21
  type NotAnInteger : String(42.1);
21
22
  ```
22
23
 
23
- In the above example, the string length for the type `LengthIsUnsafe` is not a
24
- safe Integer. It is too large.
24
+ In the erroneous example, the string length for the type `LengthIsUnsafe` is
25
+ not a safe integer. It is too large.
25
26
  Likewise, the string length for the type `NotAnInteger` is a decimal.
26
27
 
27
28
  ## How to Fix
@@ -33,5 +34,5 @@ type LengthIsSafe : String(9007199254740991);
33
34
  type AnInteger : String(42);
34
35
  ```
35
36
 
36
- If not feasible, a string representation of the number needs to be used,
37
- e.g. in annotation values.
37
+ If it's not feasible to use a safe integer, a string representation of the
38
+ number needs to be used, for example, in annotation values.