@sap/cds-compiler 2.11.2 → 2.13.6
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 +175 -2
- package/bin/.eslintrc.json +1 -2
- package/bin/cds_update_identifiers.js +10 -8
- package/bin/cdsc.js +23 -17
- package/bin/cdsse.js +2 -2
- package/bin/cdsv2m.js +3 -2
- package/doc/CHANGELOG_ARCHIVE.md +1 -1
- package/doc/CHANGELOG_BETA.md +25 -6
- package/doc/CHANGELOG_DEPRECATED.md +22 -6
- package/doc/NameResolution.md +21 -16
- package/lib/api/main.js +32 -79
- package/lib/api/options.js +3 -2
- package/lib/api/validate.js +2 -1
- package/lib/backends.js +16 -26
- package/lib/base/dictionaries.js +0 -8
- package/lib/base/error.js +26 -0
- package/lib/base/keywords.js +10 -19
- package/lib/base/location.js +9 -4
- package/lib/base/message-registry.js +75 -9
- package/lib/base/messages.js +31 -35
- package/lib/base/model.js +2 -62
- package/lib/base/optionProcessorHelper.js +246 -183
- package/lib/checks/.eslintrc.json +2 -0
- package/lib/checks/actionsFunctions.js +2 -1
- package/lib/checks/annotationsOData.js +1 -1
- package/lib/checks/cdsPersistence.js +2 -1
- package/lib/checks/emptyOrOnlyVirtual.js +2 -2
- package/lib/checks/enricher.js +17 -1
- package/lib/checks/foreignKeys.js +4 -4
- package/lib/checks/invalidTarget.js +3 -1
- package/lib/checks/managedInType.js +4 -4
- package/lib/checks/managedWithoutKeys.js +3 -1
- package/lib/checks/queryNoDbArtifacts.js +1 -3
- package/lib/checks/selectItems.js +4 -4
- package/lib/checks/sql-snippets.js +94 -0
- package/lib/checks/types.js +1 -1
- package/lib/checks/unknownMagic.js +1 -1
- package/lib/checks/validator.js +12 -7
- package/lib/compiler/assert-consistency.js +12 -8
- package/lib/compiler/base.js +0 -1
- package/lib/compiler/builtins.js +42 -21
- package/lib/compiler/checks.js +46 -12
- package/lib/compiler/cycle-detector.js +1 -1
- package/lib/compiler/define.js +1103 -0
- package/lib/compiler/extend.js +983 -0
- package/lib/compiler/finalize-parse-cdl.js +231 -0
- package/lib/compiler/index.js +46 -39
- package/lib/compiler/kick-start.js +190 -0
- package/lib/compiler/moduleLayers.js +4 -4
- package/lib/compiler/populate.js +1226 -0
- package/lib/compiler/propagator.js +113 -47
- package/lib/compiler/resolve.js +1433 -0
- package/lib/compiler/shared.js +100 -65
- package/lib/compiler/tweak-assocs.js +529 -0
- package/lib/compiler/utils.js +215 -33
- package/lib/edm/.eslintrc.json +5 -0
- package/lib/edm/annotations/genericTranslation.js +38 -25
- package/lib/edm/annotations/preprocessAnnotations.js +3 -3
- package/lib/edm/csn2edm.js +10 -9
- package/lib/edm/edm.js +19 -20
- package/lib/edm/edmPreprocessor.js +166 -95
- package/lib/edm/edmUtils.js +127 -34
- package/lib/gen/Dictionary.json +92 -43
- package/lib/gen/language.checksum +1 -1
- package/lib/gen/language.interp +11 -1
- package/lib/gen/language.tokens +86 -82
- package/lib/gen/languageLexer.interp +18 -1
- package/lib/gen/languageLexer.js +925 -847
- package/lib/gen/languageLexer.tokens +78 -74
- package/lib/gen/languageParser.js +5434 -4298
- package/lib/json/from-csn.js +59 -17
- package/lib/json/to-csn.js +189 -71
- package/lib/language/antlrParser.js +3 -3
- package/lib/language/docCommentParser.js +3 -3
- package/lib/language/errorStrategy.js +26 -8
- package/lib/language/genericAntlrParser.js +144 -53
- package/lib/language/language.g4 +424 -200
- package/lib/language/multiLineStringParser.js +536 -0
- package/lib/main.d.ts +550 -61
- package/lib/main.js +38 -11
- package/lib/model/api.js +3 -1
- package/lib/model/csnRefs.js +322 -198
- package/lib/model/csnUtils.js +226 -370
- package/lib/model/enrichCsn.js +124 -69
- package/lib/model/revealInternalProperties.js +29 -7
- package/lib/model/sortViews.js +10 -2
- package/lib/modelCompare/compare.js +17 -12
- package/lib/optionProcessor.js +8 -3
- package/lib/render/.eslintrc.json +1 -2
- package/lib/render/DuplicateChecker.js +1 -1
- package/lib/render/manageConstraints.js +36 -33
- package/lib/render/toCdl.js +174 -275
- package/lib/render/toHdbcds.js +203 -122
- package/lib/render/toRename.js +7 -10
- package/lib/render/toSql.js +161 -82
- package/lib/render/utils/common.js +22 -8
- package/lib/render/utils/sql.js +10 -7
- package/lib/render/utils/stringEscapes.js +111 -0
- package/lib/sql-identifier.js +1 -1
- package/lib/transform/.eslintrc.json +5 -0
- package/lib/transform/braceExpression.js +4 -2
- package/lib/transform/db/.eslintrc.json +2 -0
- package/lib/transform/db/applyTransformations.js +212 -0
- package/lib/transform/db/assertUnique.js +1 -1
- package/lib/transform/db/associations.js +187 -0
- package/lib/transform/db/cdsPersistence.js +150 -0
- package/lib/transform/db/constraints.js +61 -56
- package/lib/transform/db/expansion.js +50 -29
- package/lib/transform/db/flattening.js +556 -106
- package/lib/transform/db/groupByOrderBy.js +3 -1
- package/lib/transform/db/temporal.js +236 -0
- package/lib/transform/db/transformExists.js +103 -28
- package/lib/transform/db/views.js +92 -44
- package/lib/transform/draft/.eslintrc.json +38 -0
- package/lib/transform/{db/draft.js → draft/db.js} +9 -7
- package/lib/transform/draft/odata.js +227 -0
- package/lib/transform/forHanaNew.js +98 -783
- package/lib/transform/forOdataNew.js +22 -175
- package/lib/transform/localized.js +36 -32
- package/lib/transform/odata/generateForeignKeyElements.js +3 -3
- package/lib/transform/odata/referenceFlattener.js +95 -89
- package/lib/transform/odata/structureFlattener.js +1 -1
- package/lib/transform/odata/toFinalBaseType.js +86 -12
- package/lib/transform/odata/typesExposure.js +5 -5
- package/lib/transform/odata/utils.js +2 -2
- package/lib/transform/transformUtilsNew.js +47 -33
- package/lib/transform/translateAssocsToJoins.js +13 -30
- package/lib/transform/universalCsn/.eslintrc.json +36 -0
- package/lib/transform/universalCsn/coreComputed.js +170 -0
- package/lib/transform/universalCsn/universalCsnEnricher.js +715 -0
- package/lib/transform/universalCsn/utils.js +63 -0
- package/lib/utils/file.js +8 -3
- package/lib/utils/objectUtils.js +30 -0
- package/lib/utils/timetrace.js +8 -2
- package/package.json +1 -1
- package/share/messages/README.md +26 -0
- package/lib/compiler/definer.js +0 -2349
- package/lib/compiler/resolver.js +0 -2922
- package/lib/transform/db/helpers.js +0 -58
- package/lib/transform/universalCsnEnricher.js +0 -67
|
@@ -11,14 +11,18 @@ const { ATNState } = require('antlr4/atn/ATNState');
|
|
|
11
11
|
const { dictAdd, dictAddArray } = require('../base/dictionaries');
|
|
12
12
|
const locUtils = require('../base/location');
|
|
13
13
|
const { parseDocComment } = require('./docCommentParser');
|
|
14
|
+
const { parseMultiLineStringLiteral } = require('./multiLineStringParser');
|
|
14
15
|
const { functionsWithoutParens, specialFunctions } = require('../compiler/builtins');
|
|
15
16
|
|
|
17
|
+
const $location = Symbol.for('cds.$location');
|
|
16
18
|
|
|
17
19
|
// Push message `msg` with location `loc` to array of errors:
|
|
18
20
|
function _message( parser, severity, id, loc, ...args ) {
|
|
19
21
|
const msg = parser.$messageFunctions[severity]; // set in antlrParser.js
|
|
20
|
-
|
|
21
|
-
|
|
22
|
+
if (loc instanceof antlr4.CommonToken) {
|
|
23
|
+
loc = parser.tokenLocation(loc);
|
|
24
|
+
}
|
|
25
|
+
return msg( id, loc, ...args );
|
|
22
26
|
}
|
|
23
27
|
|
|
24
28
|
// Class which is to be used as grammar option with
|
|
@@ -32,6 +36,19 @@ function GenericAntlrParser( ...args ) {
|
|
|
32
36
|
// ANTLR restriction: we cannot add parameters to the constructor.
|
|
33
37
|
antlr4.Parser.call( this, ...args );
|
|
34
38
|
this.buildParseTrees = false;
|
|
39
|
+
|
|
40
|
+
// Common properties.
|
|
41
|
+
// We set them here so that they are available in the prototype.
|
|
42
|
+
// This improved performance by 25% for certain scenario tests.
|
|
43
|
+
// Probably because there was no need to look up the prototype chain anymore.
|
|
44
|
+
this.$adaptExpectedToken = null;
|
|
45
|
+
this.$adaptExpectedExcludes = [ ];
|
|
46
|
+
this.$nextTokensToken = null;
|
|
47
|
+
this.$nextTokensContext = null;
|
|
48
|
+
|
|
49
|
+
this.prepareGenericKeywords();
|
|
50
|
+
this.options = {};
|
|
51
|
+
|
|
35
52
|
return this;
|
|
36
53
|
}
|
|
37
54
|
|
|
@@ -49,9 +66,11 @@ GenericAntlrParser.prototype = Object.assign(
|
|
|
49
66
|
attachLocation,
|
|
50
67
|
startLocation,
|
|
51
68
|
tokenLocation,
|
|
52
|
-
|
|
69
|
+
valueWithTokenLocation,
|
|
53
70
|
previousTokenAtLocation,
|
|
54
71
|
combinedLocation,
|
|
72
|
+
createDict,
|
|
73
|
+
setDictEndLocation,
|
|
55
74
|
surroundByParens,
|
|
56
75
|
unaryOpForParens,
|
|
57
76
|
leftAssocBinaryOp,
|
|
@@ -67,6 +86,7 @@ GenericAntlrParser.prototype = Object.assign(
|
|
|
67
86
|
docComment,
|
|
68
87
|
addDef,
|
|
69
88
|
addItem,
|
|
89
|
+
artifactForElementAnnotateOrExtend,
|
|
70
90
|
assignProps,
|
|
71
91
|
createPrefixOp,
|
|
72
92
|
setOnce,
|
|
@@ -76,6 +96,7 @@ GenericAntlrParser.prototype = Object.assign(
|
|
|
76
96
|
reportExpandInline,
|
|
77
97
|
notSupportedYet,
|
|
78
98
|
csnParseOnly,
|
|
99
|
+
disallowElementExtension,
|
|
79
100
|
noAssignmentInSameLine,
|
|
80
101
|
noSemicolonHere,
|
|
81
102
|
setLocalToken,
|
|
@@ -84,6 +105,7 @@ GenericAntlrParser.prototype = Object.assign(
|
|
|
84
105
|
isStraightBefore,
|
|
85
106
|
meltKeywordToIdentifier,
|
|
86
107
|
prepareGenericKeywords,
|
|
108
|
+
parseMultiLineStringLiteral,
|
|
87
109
|
constructor: GenericAntlrParser, // keep this last
|
|
88
110
|
}
|
|
89
111
|
);
|
|
@@ -209,6 +231,22 @@ function setLocalTokenIfBefore( string, tokenName, before, inSameLine ) {
|
|
|
209
231
|
// // throw new antlr4.error.InputMismatchException(this);
|
|
210
232
|
// }
|
|
211
233
|
|
|
234
|
+
/**
|
|
235
|
+
* For element extensions (`extend E:elem` syntax).
|
|
236
|
+
* If `elemName.path` is set, remove the last extension from `$outer` and
|
|
237
|
+
* emit an error that the extension is invalid.
|
|
238
|
+
*
|
|
239
|
+
* @param {object} elemName
|
|
240
|
+
* @param {object} outer
|
|
241
|
+
* @param {string} extensionVariant
|
|
242
|
+
*/
|
|
243
|
+
function disallowElementExtension(elemName, outer, extensionVariant) {
|
|
244
|
+
if (elemName.path) {
|
|
245
|
+
this.message( 'syntax-invalid-extend', this.tokenLocation(this.getCurrentToken()), { 'kind': extensionVariant } );
|
|
246
|
+
outer.extensions.length = outer.extensions.length - 1; // remove last, i.e. new extension
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
212
250
|
function noAssignmentInSameLine() {
|
|
213
251
|
const t = this.getCurrentToken();
|
|
214
252
|
if (t.text === '@' && t.line <= this._input.LT(-1).line) {
|
|
@@ -290,61 +328,66 @@ function startLocation( token = this._ctx.start ) {
|
|
|
290
328
|
*
|
|
291
329
|
* @param {object} token
|
|
292
330
|
* @param {object} endToken
|
|
293
|
-
* @
|
|
331
|
+
* @return {CSN.Location}
|
|
294
332
|
*/
|
|
295
|
-
function tokenLocation( token, endToken
|
|
333
|
+
function tokenLocation( token, endToken = null ) {
|
|
296
334
|
if (!token)
|
|
297
335
|
return undefined;
|
|
298
336
|
if (!endToken) // including null
|
|
299
337
|
endToken = token;
|
|
338
|
+
|
|
300
339
|
/** @type {CSN.Location} */
|
|
301
|
-
const
|
|
340
|
+
const loc = {
|
|
302
341
|
file: this.filename,
|
|
303
342
|
line: token.line,
|
|
304
343
|
col: token.column + 1,
|
|
305
|
-
//
|
|
344
|
+
// Default for single line tokens
|
|
306
345
|
endLine: endToken.line,
|
|
307
346
|
endCol: endToken.stop - endToken.start + endToken.column + 2, // after the last char (special for EOF?)
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
// This check is done for performance reason. No need to access a token's
|
|
350
|
+
// data if we know that it spans only one single line.
|
|
351
|
+
const isMultiLineToken = (
|
|
352
|
+
endToken.type === this.constructor.DocComment ||
|
|
353
|
+
endToken.type === this.constructor.String ||
|
|
354
|
+
endToken.type === this.constructor.UnterminatedLiteral
|
|
355
|
+
);
|
|
356
|
+
if (isMultiLineToken) {
|
|
357
|
+
// Count the number of newlines in the token.
|
|
358
|
+
const source = endToken.source[1].data;
|
|
359
|
+
let newLineCount = 0;
|
|
360
|
+
let lastNewlineIndex = endToken.start;
|
|
361
|
+
for (let i = endToken.start; i < endToken.stop; i++) {
|
|
362
|
+
// Note: We do NOT check for CR, LS, and PS (/[\r\u2028\u2029]/)
|
|
363
|
+
// because ANTLR only uses LF for line break detection.
|
|
364
|
+
if (source[i] === 10) { // code point of '\n'
|
|
365
|
+
newLineCount++;
|
|
366
|
+
lastNewlineIndex = i;
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
if (newLineCount > 0) {
|
|
370
|
+
loc.endLine = endToken.line + newLineCount;
|
|
371
|
+
loc.endCol = endToken.stop - lastNewlineIndex + 1;
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
return loc;
|
|
312
376
|
}
|
|
313
377
|
|
|
314
378
|
/**
|
|
315
|
-
* Return location of `token`.
|
|
316
|
-
*
|
|
379
|
+
* Return `val` with the location of `token`. If `endToken` is provided, use its end
|
|
380
|
+
* location as end location in the result.
|
|
381
|
+
*
|
|
382
|
+
* @param {object} startToken
|
|
383
|
+
* @param {object} endToken
|
|
384
|
+
* @param {any} val
|
|
317
385
|
*/
|
|
318
|
-
function
|
|
319
|
-
if (!
|
|
386
|
+
function valueWithTokenLocation( val, startToken, endToken = null ) {
|
|
387
|
+
if (!startToken)
|
|
320
388
|
return undefined;
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
// TODO: I want to avoid a substring, that's why I don't use RegEx here
|
|
324
|
-
const source = token.source[1].data;
|
|
325
|
-
let newLineCount = 0;
|
|
326
|
-
let lastNewlineIndex = token.start;
|
|
327
|
-
for (let i = token.start; i < token.stop; i++) {
|
|
328
|
-
if (source[i] === 10) { // ASCII code for '\n'
|
|
329
|
-
newLineCount++;
|
|
330
|
-
lastNewlineIndex = i;
|
|
331
|
-
}
|
|
332
|
-
}
|
|
333
|
-
if (newLineCount === 0)
|
|
334
|
-
// endCol calculation below requires at least one newLine.
|
|
335
|
-
return this.tokenLocation(token, token, val);
|
|
336
|
-
|
|
337
|
-
/** @type {CSN.Location} */
|
|
338
|
-
const r = {
|
|
339
|
-
file: this.filename,
|
|
340
|
-
line: token.line,
|
|
341
|
-
col: token.column + 1,
|
|
342
|
-
endLine: token.line + newLineCount,
|
|
343
|
-
endCol: token.stop - lastNewlineIndex + 1, // after the last char (special for EOF?)
|
|
344
|
-
};
|
|
345
|
-
if (val !== undefined)
|
|
346
|
-
return { location: r, val };
|
|
347
|
-
return r;
|
|
389
|
+
const loc = this.tokenLocation( startToken, endToken );
|
|
390
|
+
return { location: loc, val };
|
|
348
391
|
}
|
|
349
392
|
|
|
350
393
|
function previousTokenAtLocation( location ) {
|
|
@@ -364,6 +407,20 @@ function combinedLocation( start, end ) {
|
|
|
364
407
|
return locUtils.combinedLocation( start, end );
|
|
365
408
|
}
|
|
366
409
|
|
|
410
|
+
function createDict( location = null ) {
|
|
411
|
+
const dict = Object.create(null);
|
|
412
|
+
dict[$location] = location || this.startLocation( this._input.LT(-1) );
|
|
413
|
+
return dict;
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
function setDictEndLocation( dict ) {
|
|
417
|
+
const stop = this._input.LT(-1);
|
|
418
|
+
Object.assign( dict[$location], {
|
|
419
|
+
endLine: stop.line,
|
|
420
|
+
endCol: stop.stop - stop.start + stop.column + 2,
|
|
421
|
+
} );
|
|
422
|
+
}
|
|
423
|
+
|
|
367
424
|
function surroundByParens( expr, open, close, asQuery = false ) {
|
|
368
425
|
if (!expr)
|
|
369
426
|
return expr;
|
|
@@ -405,7 +462,7 @@ function docComment( node ) {
|
|
|
405
462
|
this.warning( 'syntax-duplicate-doc-comment', token, {},
|
|
406
463
|
'Repeated doc comment - previous doc is replaced' );
|
|
407
464
|
}
|
|
408
|
-
node.doc = this.
|
|
465
|
+
node.doc = this.valueWithTokenLocation( parseDocComment( token.text ), token );
|
|
409
466
|
}
|
|
410
467
|
|
|
411
468
|
// Classify token (identifier category) for implicit names,
|
|
@@ -506,7 +563,7 @@ function valuePathAst( ref ) {
|
|
|
506
563
|
// If a '-' is directly before an unsigned number, consider it part of the number;
|
|
507
564
|
// otherwise (including for '+'), represent it as extra unary prefix operator.
|
|
508
565
|
function signedExpression( signToken, expr ) {
|
|
509
|
-
const sign = this.
|
|
566
|
+
const sign = this.valueWithTokenLocation( signToken.text, signToken );
|
|
510
567
|
const nval =
|
|
511
568
|
(signToken.text === '-' &&
|
|
512
569
|
expr && // expr may be null if `-` rule can't be parsed
|
|
@@ -556,8 +613,16 @@ function numberLiteral( token, sign, text = token.text ) {
|
|
|
556
613
|
function quotedLiteral( token, literal ) {
|
|
557
614
|
/** @type {CSN.Location} */
|
|
558
615
|
const location = this.tokenLocation( token );
|
|
559
|
-
|
|
560
|
-
|
|
616
|
+
let pos;
|
|
617
|
+
let val;
|
|
618
|
+
|
|
619
|
+
if (token.text.startsWith('`')) {
|
|
620
|
+
val = this.parseMultiLineStringLiteral(token);
|
|
621
|
+
literal = 'string';
|
|
622
|
+
} else {
|
|
623
|
+
pos = token.text.search( '\'' ) + 1; // pos of char after quote
|
|
624
|
+
val = token.text.slice( pos, -1 ).replace( /''/g, '\'' );
|
|
625
|
+
}
|
|
561
626
|
|
|
562
627
|
if (!literal)
|
|
563
628
|
literal = token.text.slice( 0, pos - 1 ).toLowerCase();
|
|
@@ -587,6 +652,7 @@ function quotedLiteral( token, literal ) {
|
|
|
587
652
|
};
|
|
588
653
|
|
|
589
654
|
function atChar(i) {
|
|
655
|
+
// Is only used with single-line strings.
|
|
590
656
|
return location.col + pos + i;
|
|
591
657
|
}
|
|
592
658
|
}
|
|
@@ -646,13 +712,13 @@ function addDef( parent, env, kind, name, annos, props, location ) {
|
|
|
646
712
|
}
|
|
647
713
|
}
|
|
648
714
|
else if (name && name.id == null) {
|
|
649
|
-
name.id = pathName(name.path ); // A.B.C -> 'A.B.C'
|
|
715
|
+
name.id = pathName( name.path ); // A.B.C -> 'A.B.C'
|
|
650
716
|
}
|
|
651
717
|
const art = this.assignProps( { name }, annos, props, location );
|
|
652
718
|
if (kind)
|
|
653
719
|
art.kind = kind;
|
|
654
|
-
if (!parent[env])
|
|
655
|
-
parent[env] = Object.create(null);
|
|
720
|
+
if (!parent[env]) // TODO: dump with --test-mode, env !== 'artifacts'
|
|
721
|
+
parent[env] = env === 'args' ? Object.create(null) : this.createDict( { ...location } );
|
|
656
722
|
if (!art.name || art.name.id == null) {
|
|
657
723
|
// no id was parsed, but with error recovery: no further error
|
|
658
724
|
// TODO: add to parent[env]['']
|
|
@@ -709,6 +775,31 @@ function addItem( parent, env, kind, annos, props, location ) {
|
|
|
709
775
|
return art;
|
|
710
776
|
}
|
|
711
777
|
|
|
778
|
+
/**
|
|
779
|
+
* For `annotate/extend E:elem.sub`, create the `elements` structure
|
|
780
|
+
* that can be used by the core compiler to annotate/extend elements.
|
|
781
|
+
*
|
|
782
|
+
* @param {string} kind Either `annotate` or `extend`
|
|
783
|
+
* @param {object} artifact Main artifact that shall have `elements`.
|
|
784
|
+
* @param {XSN.Path} elementPath Path as returned by `simplePath` token.
|
|
785
|
+
* @param {object[]} annos Existing annotations that shall be added to the _last_ path step.
|
|
786
|
+
* @param {XSN.Location} artifactLocation Start location of the `annotate` statement.
|
|
787
|
+
* @returns {object} Deepest element
|
|
788
|
+
*/
|
|
789
|
+
function artifactForElementAnnotateOrExtend(kind, artifact, elementPath, annos, artifactLocation ) {
|
|
790
|
+
if (!Array.isArray(elementPath) || elementPath.broken || elementPath.length < 1)
|
|
791
|
+
return artifact;
|
|
792
|
+
|
|
793
|
+
for (const seg of elementPath.slice(0, -1)) {
|
|
794
|
+
artifact = this.addDef( artifact, 'elements', kind,
|
|
795
|
+
{ path: [seg], location: seg.location }, null, {}, artifactLocation );
|
|
796
|
+
}
|
|
797
|
+
const last = elementPath[elementPath.length - 1];
|
|
798
|
+
artifact = this.addDef( artifact, 'elements', kind,
|
|
799
|
+
{ path: [ last ], location: last.location }, annos, {}, artifactLocation );
|
|
800
|
+
return artifact;
|
|
801
|
+
}
|
|
802
|
+
|
|
712
803
|
/** Assign all non-empty (undefined, null, {}, []) properties in argument
|
|
713
804
|
* `props` and argument `annos` as property `$annotations` to `target`
|
|
714
805
|
* and return it. Hack: if argument `annos` is exactly `true`, return
|
|
@@ -729,7 +820,7 @@ function assignProps( target, annos = [], props = null, location = null) {
|
|
|
729
820
|
for (const key in props) {
|
|
730
821
|
let val = props[key];
|
|
731
822
|
if (val instanceof antlr4.CommonToken)
|
|
732
|
-
val = this.
|
|
823
|
+
val = this.valueWithTokenLocation( true, val);
|
|
733
824
|
// only copy properties which are not undefined, null, {} or []
|
|
734
825
|
if (val != null &&
|
|
735
826
|
(typeof val !== 'object' ||
|
|
@@ -743,15 +834,15 @@ function assignProps( target, annos = [], props = null, location = null) {
|
|
|
743
834
|
|
|
744
835
|
// Create AST node for prefix operator `op` and arguments `args`
|
|
745
836
|
function createPrefixOp( token, args ) {
|
|
746
|
-
const op = this.
|
|
837
|
+
const op = this.valueWithTokenLocation( token.text.toLowerCase(), token );
|
|
747
838
|
return { op, args, location: this.combinedLocation( op, args[args.length - 1] ) };
|
|
748
839
|
}
|
|
749
840
|
|
|
750
841
|
// Create AST node for binary operator `op` and arguments `args`
|
|
751
842
|
function leftAssocBinaryOp( left, opToken, eToken, right, extraProp = 'quantifier' ) {
|
|
752
|
-
const op = this.
|
|
843
|
+
const op = this.valueWithTokenLocation( opToken.text.toLowerCase() , opToken);
|
|
753
844
|
const extra = eToken
|
|
754
|
-
? this.
|
|
845
|
+
? this.valueWithTokenLocation( eToken.text.toLowerCase(), eToken )
|
|
755
846
|
: undefined;
|
|
756
847
|
if (!left.$parens &&
|
|
757
848
|
(left.op && left.op.val) === (op && op.val) &&
|