@sap/cds-compiler 2.11.4 → 2.13.8
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 +159 -1
- package/bin/cds_update_identifiers.js +7 -7
- package/bin/cdsc.js +22 -23
- package/bin/cdsse.js +2 -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 +30 -63
- package/lib/api/options.js +5 -5
- package/lib/api/validate.js +0 -5
- package/lib/backends.js +15 -23
- package/lib/base/dictionaries.js +0 -8
- package/lib/base/error.js +26 -0
- package/lib/base/keywords.js +7 -17
- package/lib/base/location.js +9 -4
- package/lib/base/message-registry.js +52 -2
- package/lib/base/messages.js +16 -26
- 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/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/validator.js +12 -7
- package/lib/compiler/assert-consistency.js +10 -6
- package/lib/compiler/base.js +0 -1
- package/lib/compiler/builtins.js +8 -6
- 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 +33 -14
- 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 +76 -38
- package/lib/compiler/tweak-assocs.js +529 -0
- package/lib/compiler/utils.js +204 -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 +143 -71
- package/lib/language/antlrParser.js +3 -3
- package/lib/language/docCommentParser.js +3 -3
- package/lib/language/genericAntlrParser.js +144 -54
- package/lib/language/language.g4 +424 -203
- package/lib/language/multiLineStringParser.js +536 -0
- package/lib/main.d.ts +472 -61
- package/lib/main.js +38 -11
- package/lib/model/api.js +3 -1
- package/lib/model/csnRefs.js +321 -204
- package/lib/model/csnUtils.js +224 -263
- package/lib/model/enrichCsn.js +97 -40
- package/lib/model/revealInternalProperties.js +27 -6
- package/lib/model/sortViews.js +2 -1
- package/lib/modelCompare/compare.js +17 -12
- package/lib/optionProcessor.js +7 -6
- 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 +201 -115
- package/lib/render/toRename.js +7 -10
- package/lib/render/toSql.js +149 -75
- 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 +35 -12
- 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 +552 -105
- package/lib/transform/db/groupByOrderBy.js +3 -1
- package/lib/transform/db/temporal.js +236 -0
- package/lib/transform/db/transformExists.js +94 -28
- package/lib/transform/db/views.js +5 -4
- 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 +94 -801
- 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 +10 -27
- 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 +2 -1
- 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 -2340
- package/lib/compiler/resolver.js +0 -2988
- 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,62 +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
|
-
const source = token.source[1].data;
|
|
324
|
-
let newLineCount = 0;
|
|
325
|
-
let lastNewlineIndex = token.start;
|
|
326
|
-
for (let i = token.start; i < token.stop; i++) {
|
|
327
|
-
// Note: We do NOT check for CR, LS, and PS (/[\r\u2028\u2029]/)
|
|
328
|
-
// because ANTLR only uses LF for line break detection.
|
|
329
|
-
if (source[i] === 10) { // ASCII code for '\n'
|
|
330
|
-
newLineCount++;
|
|
331
|
-
lastNewlineIndex = i;
|
|
332
|
-
}
|
|
333
|
-
}
|
|
334
|
-
if (newLineCount === 0)
|
|
335
|
-
// endCol calculation below requires at least one newLine.
|
|
336
|
-
return this.tokenLocation(token, token, val);
|
|
337
|
-
|
|
338
|
-
/** @type {CSN.Location} */
|
|
339
|
-
const r = {
|
|
340
|
-
file: this.filename,
|
|
341
|
-
line: token.line,
|
|
342
|
-
col: token.column + 1,
|
|
343
|
-
endLine: token.line + newLineCount,
|
|
344
|
-
endCol: token.stop - lastNewlineIndex + 1, // after the last char (special for EOF?)
|
|
345
|
-
};
|
|
346
|
-
if (val !== undefined)
|
|
347
|
-
return { location: r, val };
|
|
348
|
-
return r;
|
|
389
|
+
const loc = this.tokenLocation( startToken, endToken );
|
|
390
|
+
return { location: loc, val };
|
|
349
391
|
}
|
|
350
392
|
|
|
351
393
|
function previousTokenAtLocation( location ) {
|
|
@@ -365,6 +407,20 @@ function combinedLocation( start, end ) {
|
|
|
365
407
|
return locUtils.combinedLocation( start, end );
|
|
366
408
|
}
|
|
367
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
|
+
|
|
368
424
|
function surroundByParens( expr, open, close, asQuery = false ) {
|
|
369
425
|
if (!expr)
|
|
370
426
|
return expr;
|
|
@@ -406,7 +462,7 @@ function docComment( node ) {
|
|
|
406
462
|
this.warning( 'syntax-duplicate-doc-comment', token, {},
|
|
407
463
|
'Repeated doc comment - previous doc is replaced' );
|
|
408
464
|
}
|
|
409
|
-
node.doc = this.
|
|
465
|
+
node.doc = this.valueWithTokenLocation( parseDocComment( token.text ), token );
|
|
410
466
|
}
|
|
411
467
|
|
|
412
468
|
// Classify token (identifier category) for implicit names,
|
|
@@ -507,7 +563,7 @@ function valuePathAst( ref ) {
|
|
|
507
563
|
// If a '-' is directly before an unsigned number, consider it part of the number;
|
|
508
564
|
// otherwise (including for '+'), represent it as extra unary prefix operator.
|
|
509
565
|
function signedExpression( signToken, expr ) {
|
|
510
|
-
const sign = this.
|
|
566
|
+
const sign = this.valueWithTokenLocation( signToken.text, signToken );
|
|
511
567
|
const nval =
|
|
512
568
|
(signToken.text === '-' &&
|
|
513
569
|
expr && // expr may be null if `-` rule can't be parsed
|
|
@@ -557,8 +613,16 @@ function numberLiteral( token, sign, text = token.text ) {
|
|
|
557
613
|
function quotedLiteral( token, literal ) {
|
|
558
614
|
/** @type {CSN.Location} */
|
|
559
615
|
const location = this.tokenLocation( token );
|
|
560
|
-
|
|
561
|
-
|
|
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
|
+
}
|
|
562
626
|
|
|
563
627
|
if (!literal)
|
|
564
628
|
literal = token.text.slice( 0, pos - 1 ).toLowerCase();
|
|
@@ -588,6 +652,7 @@ function quotedLiteral( token, literal ) {
|
|
|
588
652
|
};
|
|
589
653
|
|
|
590
654
|
function atChar(i) {
|
|
655
|
+
// Is only used with single-line strings.
|
|
591
656
|
return location.col + pos + i;
|
|
592
657
|
}
|
|
593
658
|
}
|
|
@@ -647,13 +712,13 @@ function addDef( parent, env, kind, name, annos, props, location ) {
|
|
|
647
712
|
}
|
|
648
713
|
}
|
|
649
714
|
else if (name && name.id == null) {
|
|
650
|
-
name.id = pathName(name.path ); // A.B.C -> 'A.B.C'
|
|
715
|
+
name.id = pathName( name.path ); // A.B.C -> 'A.B.C'
|
|
651
716
|
}
|
|
652
717
|
const art = this.assignProps( { name }, annos, props, location );
|
|
653
718
|
if (kind)
|
|
654
719
|
art.kind = kind;
|
|
655
|
-
if (!parent[env])
|
|
656
|
-
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 } );
|
|
657
722
|
if (!art.name || art.name.id == null) {
|
|
658
723
|
// no id was parsed, but with error recovery: no further error
|
|
659
724
|
// TODO: add to parent[env]['']
|
|
@@ -710,6 +775,31 @@ function addItem( parent, env, kind, annos, props, location ) {
|
|
|
710
775
|
return art;
|
|
711
776
|
}
|
|
712
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
|
+
|
|
713
803
|
/** Assign all non-empty (undefined, null, {}, []) properties in argument
|
|
714
804
|
* `props` and argument `annos` as property `$annotations` to `target`
|
|
715
805
|
* and return it. Hack: if argument `annos` is exactly `true`, return
|
|
@@ -730,7 +820,7 @@ function assignProps( target, annos = [], props = null, location = null) {
|
|
|
730
820
|
for (const key in props) {
|
|
731
821
|
let val = props[key];
|
|
732
822
|
if (val instanceof antlr4.CommonToken)
|
|
733
|
-
val = this.
|
|
823
|
+
val = this.valueWithTokenLocation( true, val);
|
|
734
824
|
// only copy properties which are not undefined, null, {} or []
|
|
735
825
|
if (val != null &&
|
|
736
826
|
(typeof val !== 'object' ||
|
|
@@ -744,15 +834,15 @@ function assignProps( target, annos = [], props = null, location = null) {
|
|
|
744
834
|
|
|
745
835
|
// Create AST node for prefix operator `op` and arguments `args`
|
|
746
836
|
function createPrefixOp( token, args ) {
|
|
747
|
-
const op = this.
|
|
837
|
+
const op = this.valueWithTokenLocation( token.text.toLowerCase(), token );
|
|
748
838
|
return { op, args, location: this.combinedLocation( op, args[args.length - 1] ) };
|
|
749
839
|
}
|
|
750
840
|
|
|
751
841
|
// Create AST node for binary operator `op` and arguments `args`
|
|
752
842
|
function leftAssocBinaryOp( left, opToken, eToken, right, extraProp = 'quantifier' ) {
|
|
753
|
-
const op = this.
|
|
843
|
+
const op = this.valueWithTokenLocation( opToken.text.toLowerCase() , opToken);
|
|
754
844
|
const extra = eToken
|
|
755
|
-
? this.
|
|
845
|
+
? this.valueWithTokenLocation( eToken.text.toLowerCase(), eToken )
|
|
756
846
|
: undefined;
|
|
757
847
|
if (!left.$parens &&
|
|
758
848
|
(left.op && left.op.val) === (op && op.val) &&
|