@sap/cds-compiler 3.8.0 → 3.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/lib/compiler/assert-consistency.js +1 -1
- package/lib/compiler/base.js +14 -12
- package/lib/compiler/extend.js +17 -1
- package/lib/compiler/shared.js +8 -5
- package/lib/gen/language.checksum +1 -1
- package/lib/gen/language.interp +1 -1
- package/lib/gen/languageParser.js +948 -940
- package/lib/json/from-csn.js +1 -2
- package/lib/language/genericAntlrParser.js +2 -1
- package/lib/language/language.g4 +18 -21
- package/lib/model/csnRefs.js +5 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,14 @@
|
|
|
7
7
|
Note: `beta` fixes, changes and features are usually not listed in this ChangeLog but [here](doc/CHANGELOG_BETA.md).
|
|
8
8
|
The compiler behavior concerning `beta` features can change at any time without notice.
|
|
9
9
|
|
|
10
|
+
## Version 3.8.2 - 2023-03-30
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- parser: Identifiers that are keywords were not allowed in annotation values inside arrays
|
|
15
|
+
- compiler: Compatibility against cds-lsp was restored.
|
|
16
|
+
- to.sql/hdbcds/hdi/edm(x): Fix a crash for sub-queries inside nested expressions of on-conditions of JOINs.
|
|
17
|
+
|
|
10
18
|
## Version 3.8.0 - 2023-03-27
|
|
11
19
|
|
|
12
20
|
### Added
|
|
@@ -504,7 +504,7 @@ function assertConsistency( model, stage ) {
|
|
|
504
504
|
],
|
|
505
505
|
},
|
|
506
506
|
absolute: { test: isString },
|
|
507
|
-
variant: {
|
|
507
|
+
variant: { requires: [ 'location', 'path' ] },
|
|
508
508
|
element: { test: TODO }, // TODO: { test: isString },
|
|
509
509
|
action: { test: isString },
|
|
510
510
|
param: { test: TODO },
|
package/lib/compiler/base.js
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
'use strict';
|
|
4
4
|
|
|
5
|
+
const { CompilerAssertion } = require( '../base/error' );
|
|
6
|
+
|
|
5
7
|
const dictKinds = {
|
|
6
8
|
definitions: 'absolute',
|
|
7
9
|
elements: 'element',
|
|
@@ -65,26 +67,26 @@ function propExists( prop, parent ) {
|
|
|
65
67
|
}
|
|
66
68
|
|
|
67
69
|
// Return the "old style" name structure with `absolute`, `action`, `param`,
|
|
68
|
-
// `element`.
|
|
69
|
-
//
|
|
70
|
+
// `element`. The following code makes use of the fact that only member extensions
|
|
71
|
+
// have a "sparse" name structure.
|
|
70
72
|
function getArtifactName( art ) {
|
|
71
|
-
if (!art.name || art.name.absolute)
|
|
73
|
+
if (!art.name || art.name.absolute) // no name or “old style”
|
|
72
74
|
return art.name;
|
|
73
|
-
// extend and annotate
|
|
74
|
-
const link = art.name._artifact;
|
|
75
|
+
// extend and annotate statements as members already have "sparse" names → calculate old one
|
|
75
76
|
const namePath = [];
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
77
|
+
let parent = art;
|
|
78
|
+
while (parent._main) { // until we hit the main artifact
|
|
79
|
+
namePath.push( parent );
|
|
80
|
+
parent = parent._parent;
|
|
79
81
|
}
|
|
80
82
|
namePath.reverse();
|
|
81
|
-
|
|
83
|
+
// start with id/location of art.name, and absolute of art._main
|
|
84
|
+
const name = { id: art.name.id, location: art.name.location, absolute: parent.name.absolute };
|
|
82
85
|
for (const np of namePath) {
|
|
83
86
|
const prop = getMemberNameProp( np, np.kind );
|
|
84
87
|
name[prop] = (name[prop]) ? `${ name[prop] }.${ np.name.id }` : np.name.id;
|
|
85
|
-
name.id = np.name.id;
|
|
86
|
-
name.location = np.name.location;
|
|
87
88
|
}
|
|
89
|
+
const link = art.name._artifact;
|
|
88
90
|
if (link !== undefined)
|
|
89
91
|
Object.defineProperty( name, '_artifact', { value: link, configurable: true, writable: true } );
|
|
90
92
|
return name;
|
|
@@ -103,7 +105,7 @@ function getMemberNameProp( elem, kind ) {
|
|
|
103
105
|
obj = obj.items;
|
|
104
106
|
if (obj.elements || obj.enum)
|
|
105
107
|
return 'element';
|
|
106
|
-
|
|
108
|
+
throw CompilerAssertion( `Member not found in parent properties ${ Object.keys( obj ).join('+') }` );
|
|
107
109
|
}
|
|
108
110
|
|
|
109
111
|
module.exports = {
|
package/lib/compiler/extend.js
CHANGED
|
@@ -188,6 +188,22 @@ function extend( model ) {
|
|
|
188
188
|
model.extensions = Object.values( model.$lateExtensions );
|
|
189
189
|
// TODO: testMode sort?
|
|
190
190
|
model.extensions.forEach( createSuperAnnotate );
|
|
191
|
+
// set _artifact links for “main extensions” late as it would disturb the
|
|
192
|
+
// still existing old extend mechanism, see chooseAnnotationsInArtifact(),
|
|
193
|
+
// needed for LSP and friends:
|
|
194
|
+
Object.values( model.sources ).forEach( setArtifactLinkForExtensions );
|
|
195
|
+
Object.values( model.definitions ).forEach( setArtifactLinkForExtensions );
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// TODO: delete again
|
|
199
|
+
function setArtifactLinkForExtensions( source ) {
|
|
200
|
+
if (!source.extensions)
|
|
201
|
+
return;
|
|
202
|
+
for (const ext of source.extensions ) {
|
|
203
|
+
const { name } = ext;
|
|
204
|
+
if (name?.absolute && name._artifact === undefined) // no link set yet
|
|
205
|
+
resolvePath( name, ext.kind, ext ); // for LSP
|
|
206
|
+
}
|
|
191
207
|
}
|
|
192
208
|
|
|
193
209
|
// For extendArtifactAfter(): -------------------------------------------------
|
|
@@ -1604,7 +1620,7 @@ function extend( model ) {
|
|
|
1604
1620
|
delete model.$lateExtensions[absolute];
|
|
1605
1621
|
// TODO: if the extension mechanism has been completed, we could uncomment:
|
|
1606
1622
|
// art._extensions.forEach( ext => resolvePath( ext.name, ext.kind, ext )); // for LSP
|
|
1607
|
-
//
|
|
1623
|
+
// for now, we do that at the end of lateExtensions()
|
|
1608
1624
|
}
|
|
1609
1625
|
}
|
|
1610
1626
|
if (art._extensions) {
|
package/lib/compiler/shared.js
CHANGED
|
@@ -57,7 +57,8 @@ function fns( model ) {
|
|
|
57
57
|
artItemsCount: Number.MAX_SAFE_INTEGER,
|
|
58
58
|
undefinedDef: 'anno-undefined-def',
|
|
59
59
|
undefinedArt: 'anno-undefined-art',
|
|
60
|
-
allowAutoexposed: true,
|
|
60
|
+
allowAutoexposed: true, // TODO: think about Info/Warning
|
|
61
|
+
noMessageForLocalized: true, // TODO: should we issue a Debug message for code completion?
|
|
61
62
|
},
|
|
62
63
|
type: { // TODO: more detailed later (e.g. for enum base type?)
|
|
63
64
|
envFn: artifactsEnv,
|
|
@@ -735,10 +736,12 @@ function fns( model ) {
|
|
|
735
736
|
}
|
|
736
737
|
else if (env.$frontend && env.$frontend !== 'cdl' || spec.global) {
|
|
737
738
|
// IDE can inspect <model>.definitions - provide null for valid
|
|
738
|
-
|
|
739
|
-
|
|
739
|
+
if (!spec.noMessageForLocalized || !head.id.startsWith( 'localized.' )) {
|
|
740
|
+
signalNotFound( spec.undefinedDef || 'ref-undefined-def', [ head.location, user ],
|
|
741
|
+
valid, { art: head.id } );
|
|
742
|
+
}
|
|
740
743
|
}
|
|
741
|
-
else {
|
|
744
|
+
else if (!spec.noMessageForLocalized || head.id !== 'localized') {
|
|
742
745
|
signalNotFound( spec.undefinedArt || 'ref-undefined-art', [ head.location, user ],
|
|
743
746
|
valid, { name: head.id } );
|
|
744
747
|
}
|
|
@@ -817,7 +820,7 @@ function fns( model ) {
|
|
|
817
820
|
setTargetReferenceKey( orig.name.id, item );
|
|
818
821
|
}
|
|
819
822
|
art = sub;
|
|
820
|
-
if (spec.envFn && (!artItemsCount || item === last) &&
|
|
823
|
+
if (spec.envFn && !spec.allowAutoexposed && (!artItemsCount || item === last) &&
|
|
821
824
|
art && art.$inferred === 'autoexposed' && !user.$inferred) {
|
|
822
825
|
// Depending on the processing sequence, the following could be a
|
|
823
826
|
// simple 'ref-undefined-art'/'ref-undefined-def' - TODO: which we
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
7b8ead4c652cf564b5ba45f94d2c45af
|