@sap/cds-compiler 2.13.8 → 3.0.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 +155 -1594
- package/bin/cdsc.js +144 -66
- package/doc/CHANGELOG_ARCHIVE.md +1592 -0
- package/doc/CHANGELOG_BETA.md +3 -4
- package/doc/CHANGELOG_DEPRECATED.md +35 -1
- package/doc/{DeprecatedOptions.md → DeprecatedOptions_v2.md} +3 -1
- package/doc/Versioning.md +20 -1
- package/lib/api/.eslintrc.json +2 -2
- package/lib/api/main.js +237 -122
- package/lib/api/options.js +17 -88
- package/lib/api/validate.js +12 -16
- package/lib/base/keywords.js +216 -109
- package/lib/base/message-registry.js +152 -37
- package/lib/base/messages.js +145 -83
- package/lib/base/model.js +44 -2
- package/lib/base/optionProcessorHelper.js +19 -0
- package/lib/checks/actionsFunctions.js +7 -5
- package/lib/checks/annotationsOData.js +11 -32
- package/lib/checks/arrayOfs.js +1 -34
- package/lib/checks/cdsPersistence.js +1 -0
- package/lib/checks/elements.js +6 -6
- package/lib/checks/invalidTarget.js +1 -1
- package/lib/checks/nonexpandableStructured.js +1 -1
- package/lib/checks/queryNoDbArtifacts.js +2 -1
- package/lib/checks/selectItems.js +5 -1
- package/lib/checks/types.js +4 -2
- package/lib/checks/utils.js +2 -2
- package/lib/checks/validator.js +4 -5
- package/lib/compiler/assert-consistency.js +16 -10
- package/lib/compiler/base.js +1 -0
- package/lib/compiler/builtins.js +98 -9
- package/lib/compiler/checks.js +22 -70
- package/lib/compiler/define.js +61 -13
- package/lib/compiler/extend.js +79 -14
- package/lib/compiler/finalize-parse-cdl.js +46 -29
- package/lib/compiler/index.js +100 -37
- package/lib/compiler/moduleLayers.js +7 -0
- package/lib/compiler/populate.js +19 -18
- package/lib/compiler/propagator.js +7 -4
- package/lib/compiler/resolve.js +297 -234
- package/lib/compiler/shared.js +107 -102
- package/lib/compiler/tweak-assocs.js +16 -11
- package/lib/compiler/utils.js +5 -0
- package/lib/edm/annotations/genericTranslation.js +93 -21
- package/lib/edm/csn2edm.js +230 -115
- package/lib/edm/edm.js +305 -226
- package/lib/edm/edmPreprocessor.js +509 -438
- package/lib/edm/edmUtils.js +31 -45
- package/lib/gen/Dictionary.json +98 -22
- package/lib/gen/language.checksum +1 -1
- package/lib/gen/language.interp +10 -30
- package/lib/gen/language.tokens +105 -114
- package/lib/gen/languageLexer.interp +1 -34
- package/lib/gen/languageLexer.js +889 -1007
- package/lib/gen/languageLexer.tokens +95 -106
- package/lib/gen/languageParser.js +20786 -22199
- package/lib/json/csnVersion.js +10 -11
- package/lib/json/from-csn.js +59 -51
- package/lib/json/to-csn.js +10 -10
- package/lib/language/antlrParser.js +2 -2
- package/lib/language/docCommentParser.js +62 -39
- package/lib/language/errorStrategy.js +52 -40
- package/lib/language/genericAntlrParser.js +348 -229
- package/lib/language/language.g4 +629 -653
- package/lib/language/multiLineStringParser.js +14 -42
- package/lib/language/textUtils.js +44 -0
- package/lib/main.d.ts +46 -43
- package/lib/main.js +108 -79
- package/lib/model/csnRefs.js +34 -7
- package/lib/model/csnUtils.js +337 -332
- package/lib/model/enrichCsn.js +1 -0
- package/lib/model/revealInternalProperties.js +30 -10
- package/lib/model/sortViews.js +32 -31
- package/lib/modelCompare/compare.js +6 -6
- package/lib/optionProcessor.js +73 -46
- package/lib/render/.eslintrc.json +1 -1
- package/lib/render/DuplicateChecker.js +4 -7
- package/lib/render/manageConstraints.js +70 -2
- package/lib/render/toCdl.js +1042 -882
- package/lib/render/toHdbcds.js +195 -245
- package/lib/render/toRename.js +44 -22
- package/lib/render/toSql.js +225 -241
- package/lib/render/utils/common.js +145 -15
- package/lib/render/utils/sql.js +20 -19
- package/lib/sql-identifier.js +6 -0
- package/lib/transform/db/.eslintrc.json +4 -3
- package/lib/transform/db/associations.js +2 -2
- package/lib/transform/db/cdsPersistence.js +5 -15
- package/lib/transform/db/constraints.js +4 -2
- package/lib/transform/db/expansion.js +22 -16
- package/lib/transform/db/flattening.js +109 -80
- package/lib/transform/db/transformExists.js +7 -7
- package/lib/transform/db/views.js +9 -6
- package/lib/transform/draft/.eslintrc.json +2 -2
- package/lib/transform/draft/db.js +6 -6
- package/lib/transform/draft/odata.js +6 -7
- package/lib/transform/forHanaNew.js +62 -48
- package/lib/transform/forOdataNew.js +49 -50
- package/lib/transform/localized.js +31 -20
- package/lib/transform/odata/toFinalBaseType.js +16 -14
- package/lib/transform/odata/typesExposure.js +146 -198
- package/lib/transform/odata/utils.js +1 -38
- package/lib/transform/transformUtilsNew.js +67 -84
- package/lib/transform/translateAssocsToJoins.js +7 -3
- package/lib/transform/universalCsn/.eslintrc.json +2 -2
- package/lib/transform/universalCsn/coreComputed.js +16 -9
- package/lib/transform/universalCsn/universalCsnEnricher.js +60 -10
- package/lib/utils/file.js +3 -3
- package/lib/utils/moduleResolve.js +13 -6
- package/lib/utils/timetrace.js +20 -21
- package/package.json +35 -4
- package/share/messages/message-explanations.json +2 -1
- package/share/messages/syntax-expected-integer.md +37 -0
- package/doc/ApiMigration.md +0 -237
- package/doc/CommandLineMigration.md +0 -58
- package/doc/ErrorMessages.md +0 -175
- package/doc/FioriAnnotations.md +0 -94
- package/doc/ODataTransformation.md +0 -273
- package/lib/backends.js +0 -529
- package/lib/fix_antlr4-8_warning.js +0 -56
- package/lib/transform/odata/attachPath.js +0 -96
- package/lib/transform/odata/expandStructKeysInAssociations.js +0 -59
- package/lib/transform/odata/generateForeignKeyElements.js +0 -261
- package/lib/transform/odata/referenceFlattener.js +0 -296
- package/lib/transform/odata/sortByAssociationDependency.js +0 -105
- package/lib/transform/odata/structuralPath.js +0 -72
- package/lib/transform/odata/structureFlattener.js +0 -171
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const {
|
|
3
|
+
const {
|
|
4
|
+
isWhitespaceOrNewLineOnly,
|
|
5
|
+
isWhitespaceCharacterNoNewline,
|
|
6
|
+
cdlNewLineRegEx,
|
|
7
|
+
} = require('./textUtils');
|
|
4
8
|
|
|
5
9
|
/**
|
|
6
10
|
* Get the content of a JSDoc-like comment and remove all surrounding asterisks, etc.
|
|
@@ -18,39 +22,40 @@ function parseDocComment(comment) {
|
|
|
18
22
|
if (comment.length <= 5) // at least "/***/"
|
|
19
23
|
return null;
|
|
20
24
|
|
|
21
|
-
let lines =
|
|
25
|
+
let lines = comment.split(cdlNewLineRegEx);
|
|
22
26
|
|
|
23
27
|
if (lines.length === 1) {
|
|
24
|
-
//
|
|
25
|
-
//
|
|
26
|
-
const content = lines[0]
|
|
27
|
-
|
|
28
|
+
// Special case for one-liners.
|
|
29
|
+
// Remove "/***/" and trim white space and asterisks.
|
|
30
|
+
const content = lines[0]
|
|
31
|
+
.replace(/^\/[*]{2,}/, '')
|
|
32
|
+
.replace(/\*+\/$/, '')
|
|
33
|
+
.trim();
|
|
34
|
+
return isWhitespaceOrNewLineOnly(content) ? null : content;
|
|
28
35
|
}
|
|
29
36
|
|
|
30
|
-
|
|
37
|
+
// If the comment already has content on the first line, i.e. after `/**`,
|
|
38
|
+
// its leading whitespace is ignored for whitespace trimming.
|
|
39
|
+
const hasContentOnFirstLine = /\/\*+\s*\S/.test(lines[0]);
|
|
40
|
+
|
|
41
|
+
// First line, i.e. header, is always trimmed from left.
|
|
42
|
+
lines[0] = removeHeaderFence(lines[0]).trimStart();
|
|
31
43
|
lines[lines.length - 1] = removeFooterFence(lines[lines.length - 1]);
|
|
32
44
|
|
|
33
|
-
if (
|
|
34
|
-
lines = lines.map((line, index) => ((index === 0) ? line : removeFence(line)));
|
|
35
|
-
}
|
|
36
|
-
else if (lines.length === 2) {
|
|
45
|
+
if (lines.length === 2) {
|
|
37
46
|
// Comment that is essentially just a header + footer.
|
|
38
|
-
// First line, i.e. header, is always trimmed from left.
|
|
39
|
-
lines[0] = lines[0].trimLeft();
|
|
40
|
-
|
|
41
47
|
// If the second line starts with an asterisk then remove it.
|
|
42
|
-
// Otherwise trim all whitespace.
|
|
48
|
+
// Otherwise, trim all left whitespace.
|
|
43
49
|
if ((/^\s*[*]/.test(lines[1])))
|
|
44
50
|
lines[1] = removeFence(lines[1]);
|
|
45
51
|
else
|
|
46
|
-
lines[1] = lines[1].
|
|
52
|
+
lines[1] = lines[1].trimStart();
|
|
53
|
+
}
|
|
54
|
+
else if (isFencedComment(lines)) {
|
|
55
|
+
lines = lines.map((line, index) => ((index === 0) ? line : removeFence(line)));
|
|
47
56
|
}
|
|
48
57
|
else {
|
|
49
|
-
|
|
50
|
-
// Tabs are regarded as one space.
|
|
51
|
-
const spacesAtBeginning = firstNonEmptyLine.match(/^\s*/)[0].length;
|
|
52
|
-
if (spacesAtBeginning > 0)
|
|
53
|
-
lines = lines.map(line => removeWhitespace(line, spacesAtBeginning));
|
|
58
|
+
stripCommentIndentation(lines, hasContentOnFirstLine);
|
|
54
59
|
}
|
|
55
60
|
|
|
56
61
|
// Remove empty header and footer.
|
|
@@ -58,18 +63,47 @@ function parseDocComment(comment) {
|
|
|
58
63
|
const endIndex = (lines[lines.length - 1] === '') ? lines.length - 1 : lines.length;
|
|
59
64
|
|
|
60
65
|
const content = lines.slice(startIndex, endIndex).join('\n');
|
|
61
|
-
|
|
62
|
-
return isWhiteSpaceOnly(content) ? null : content;
|
|
66
|
+
return isWhitespaceOrNewLineOnly(content) ? null : content;
|
|
63
67
|
}
|
|
64
68
|
|
|
65
69
|
/**
|
|
66
|
-
*
|
|
67
|
-
*
|
|
70
|
+
* Strips and counts the indentation from the given comment string.
|
|
71
|
+
* This function is similar to the one in multiLineStringParser.js, but does not
|
|
72
|
+
* have special handling for the first and last line of the string.
|
|
73
|
+
*
|
|
74
|
+
* @example
|
|
75
|
+
* | hello
|
|
76
|
+
* | world
|
|
77
|
+
* | foo bar
|
|
78
|
+
* becomes
|
|
79
|
+
* | hello
|
|
80
|
+
* | world
|
|
81
|
+
* | foo bar
|
|
68
82
|
*
|
|
69
|
-
* @param {string}
|
|
83
|
+
* @param {string[]} lines String split into lines.
|
|
84
|
+
* @param {boolean} ignoreFirstLine Whether to ignore the first line for indentation counting.
|
|
70
85
|
*/
|
|
71
|
-
function
|
|
72
|
-
|
|
86
|
+
function stripCommentIndentation(lines, ignoreFirstLine) {
|
|
87
|
+
const n = lines.length;
|
|
88
|
+
|
|
89
|
+
const minIndent = lines.reduce((min, line, index) => {
|
|
90
|
+
// Blank lines are ignored.
|
|
91
|
+
if (isWhitespaceOrNewLineOnly(line) || (index === 0 && ignoreFirstLine))
|
|
92
|
+
return min;
|
|
93
|
+
|
|
94
|
+
let count = 0;
|
|
95
|
+
const length = Math.min(min, line.length);
|
|
96
|
+
while (count < length && isWhitespaceCharacterNoNewline(line[count])) {
|
|
97
|
+
count++;
|
|
98
|
+
}
|
|
99
|
+
return Math.min(min, count);
|
|
100
|
+
}, Number.MAX_SAFE_INTEGER);
|
|
101
|
+
|
|
102
|
+
for (let i = (ignoreFirstLine ? 1 : 0); i < n; ++i) {
|
|
103
|
+
// Note: Line may be empty and have fewer characters than `min`.
|
|
104
|
+
// In that case, slice() returns an empty string.
|
|
105
|
+
lines[i] = lines[i].slice(minIndent);
|
|
106
|
+
}
|
|
73
107
|
}
|
|
74
108
|
|
|
75
109
|
/**
|
|
@@ -85,17 +119,6 @@ function removeFence(line) {
|
|
|
85
119
|
return line.replace(/^\s*[*]\s?/, '');
|
|
86
120
|
}
|
|
87
121
|
|
|
88
|
-
/**
|
|
89
|
-
* Remove the TODO
|
|
90
|
-
*
|
|
91
|
-
* @param {string} line
|
|
92
|
-
* @param {number} spaces Number of whitespace to remove at the beginning of the line
|
|
93
|
-
* @returns {string} line without fence
|
|
94
|
-
*/
|
|
95
|
-
function removeWhitespace(line, spaces) {
|
|
96
|
-
return line.replace(new RegExp(`^\\s{0,${ spaces }}`), ''); // Trailing spaces with '*'? => .replace(/\s+[*]$/, '');
|
|
97
|
-
}
|
|
98
|
-
|
|
99
122
|
/**
|
|
100
123
|
* Removes a header fence, i.e. '/**'.
|
|
101
124
|
* May remove more than two asterisks e.g. '/*******'
|
|
@@ -29,12 +29,12 @@
|
|
|
29
29
|
'use strict';
|
|
30
30
|
|
|
31
31
|
const antlr4 = require('antlr4');
|
|
32
|
-
const
|
|
33
|
-
const
|
|
34
|
-
const
|
|
35
|
-
const predictionContext = require('antlr4/PredictionContext')
|
|
36
|
-
const { ATNState } = require('antlr4/atn/ATNState');
|
|
37
|
-
const {
|
|
32
|
+
const antlr4_LL1Analyzer = require('antlr4/src/antlr4/LL1Analyzer');
|
|
33
|
+
const { DefaultErrorStrategy } = require('antlr4/src/antlr4/error/ErrorStrategy');
|
|
34
|
+
const { InputMismatchException } = require('antlr4/src/antlr4/error/Errors');
|
|
35
|
+
const { predictionContextFromRuleContext: predictionContext } = require('antlr4/src/antlr4/PredictionContext');
|
|
36
|
+
const { ATNState } = require('antlr4/src/antlr4/atn/ATNState');
|
|
37
|
+
const { IntervalSet, Interval } = require('antlr4/src/antlr4/IntervalSet');
|
|
38
38
|
|
|
39
39
|
const keywordRegexp = /^[a-zA-Z]+$/; // we don't have keywords with underscore
|
|
40
40
|
|
|
@@ -65,30 +65,35 @@ function match( ttype ) {
|
|
|
65
65
|
//
|
|
66
66
|
// An instance of this class should be set as property `_errHandler` to the
|
|
67
67
|
// parser (prototype).
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
reportInputMismatch,
|
|
78
|
-
reportUnwantedToken,
|
|
79
|
-
reportMissingToken,
|
|
80
|
-
reportIgnoredWith,
|
|
81
|
-
// getErrorRecoverySet,
|
|
82
|
-
consumeUntil,
|
|
83
|
-
recoverInline,
|
|
84
|
-
getMissingSymbol,
|
|
85
|
-
getExpectedTokensForMessage,
|
|
86
|
-
getTokenDisplay,
|
|
87
|
-
constructor: KeywordErrorStrategy,
|
|
68
|
+
class KeywordErrorStrategy extends DefaultErrorStrategy {
|
|
69
|
+
constructor( ...args ) {
|
|
70
|
+
super( ...args );
|
|
71
|
+
|
|
72
|
+
this._super = {
|
|
73
|
+
consumeUntil: super.consumeUntil,
|
|
74
|
+
recoverInline: super.recoverInline,
|
|
75
|
+
getExpectedTokens: super.getExpectedTokens,
|
|
76
|
+
};
|
|
88
77
|
}
|
|
89
|
-
|
|
78
|
+
}
|
|
90
79
|
|
|
91
|
-
//
|
|
80
|
+
// TODO: Use actual methods
|
|
81
|
+
Object.assign( KeywordErrorStrategy.prototype, {
|
|
82
|
+
sync,
|
|
83
|
+
reportNoViableAlternative,
|
|
84
|
+
reportInputMismatch,
|
|
85
|
+
reportUnwantedToken,
|
|
86
|
+
reportMissingToken,
|
|
87
|
+
reportIgnoredWith,
|
|
88
|
+
// getErrorRecoverySet,
|
|
89
|
+
consumeUntil,
|
|
90
|
+
recoverInline,
|
|
91
|
+
getMissingSymbol,
|
|
92
|
+
getExpectedTokensForMessage,
|
|
93
|
+
getTokenDisplay,
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
// Attempt to recover from problems in subrules, except if rule has defined a
|
|
92
97
|
// local variable `_sync` with value 'nop'
|
|
93
98
|
function sync( recognizer ) {
|
|
94
99
|
// If already recovering, don't try to sync
|
|
@@ -166,7 +171,7 @@ function sync( recognizer ) {
|
|
|
166
171
|
case ATNState.STAR_LOOP_BACK: { // 9
|
|
167
172
|
// TODO: do not delete a '}'
|
|
168
173
|
this.reportUnwantedToken(recognizer);
|
|
169
|
-
const expecting = new IntervalSet
|
|
174
|
+
const expecting = new IntervalSet();
|
|
170
175
|
expecting.addSet(recognizer.getExpectedTokens());
|
|
171
176
|
const whatFollowsLoopIterationOrRule = expecting.addSet(this.getErrorRecoverySet(recognizer));
|
|
172
177
|
this.consumeUntil(recognizer, whatFollowsLoopIterationOrRule);
|
|
@@ -270,21 +275,21 @@ function consumeUntil( recognizer, set ) {
|
|
|
270
275
|
|
|
271
276
|
// let s=this.getTokenDisplay( recognizer.getCurrentToken(), recognizer );
|
|
272
277
|
if (SEMI < 1 || RBRACE < 1) {
|
|
273
|
-
|
|
278
|
+
this._super.consumeUntil.call( this, recognizer, set );
|
|
274
279
|
}
|
|
275
280
|
else if (set.contains(SEMI)) { // do not check for RBRACE here!
|
|
276
|
-
|
|
281
|
+
this._super.consumeUntil.call( this, recognizer, set );
|
|
277
282
|
// console.log('CONSUMED-ORIG:',s,this.getTokenDisplay( recognizer.getCurrentToken(), recognizer ),recognizer.getCurrentToken().line,intervalSetToArray( recognizer, set ));
|
|
278
283
|
}
|
|
279
284
|
else {
|
|
280
285
|
// DO NOT modify input param `set`, as the set might be cached in the ATN
|
|
281
|
-
const stop = new IntervalSet
|
|
286
|
+
const stop = new IntervalSet();
|
|
282
287
|
stop.addSet( set );
|
|
283
288
|
stop.removeOne( recognizer.constructor.Identifier );
|
|
284
289
|
stop.addOne( SEMI );
|
|
285
290
|
// I am not that sure whether to add RBRACE...
|
|
286
291
|
stop.addOne( RBRACE );
|
|
287
|
-
|
|
292
|
+
this._super.consumeUntil.call( this, recognizer, stop );
|
|
288
293
|
if (recognizer.getTokenStream().LA(1) === SEMI ||
|
|
289
294
|
recognizer.getTokenStream().LA(1) === RBRACE && !set.contains(RBRACE)) {
|
|
290
295
|
recognizer.consume();
|
|
@@ -310,11 +315,11 @@ function consumeUntil( recognizer, set ) {
|
|
|
310
315
|
function recoverInline( recognizer ) {
|
|
311
316
|
const identType = recognizer.constructor.Identifier;
|
|
312
317
|
if (!identType || !recognizer.isExpectedToken( identType ))
|
|
313
|
-
return
|
|
318
|
+
return this._super.recoverInline.call( this, recognizer );
|
|
314
319
|
|
|
315
320
|
const token = recognizer.getCurrentToken();
|
|
316
321
|
if (!keywordRegexp.test( token.text ))
|
|
317
|
-
return
|
|
322
|
+
return this._super.recoverInline.call( this, recognizer );
|
|
318
323
|
|
|
319
324
|
recognizer.message( 'syntax-fragile-ident', token, { id: token.text, delimited: token.text },
|
|
320
325
|
'$(ID) is a reserved name here - write $(DELIMITED) instead if you want to use it' );
|
|
@@ -344,8 +349,12 @@ function intervalSetToArray( recognizer, expected, excludesForNextToken ) {
|
|
|
344
349
|
for (let j = v.start; j < v.stop; j++) {
|
|
345
350
|
// a generic keyword as such does not appear in messages, only its replacements,
|
|
346
351
|
// which are function name and argument position dependent:
|
|
347
|
-
if (j === pc.
|
|
348
|
-
names.push( ...recognizer.$genericKeywords.
|
|
352
|
+
if (j === pc.GenericExpr)
|
|
353
|
+
names.push( ...recognizer.$genericKeywords.expr );
|
|
354
|
+
else if (j === pc.GenericSeparator)
|
|
355
|
+
names.push( ...recognizer.$genericKeywords.separator );
|
|
356
|
+
else if (j === pc.GenericIntro)
|
|
357
|
+
names.push( ...recognizer.$genericKeywords.introMsg );
|
|
349
358
|
// other expected tokens usually appear in messages, except the helper tokens
|
|
350
359
|
// which are used to solve ambiguities via the parser method setLocalToken():
|
|
351
360
|
else if (j !== pc.HelperToken1 && j !== pc.HelperToken2)
|
|
@@ -362,6 +371,9 @@ function intervalSetToArray( recognizer, expected, excludesForNextToken ) {
|
|
|
362
371
|
else if (names.includes("';'")) {
|
|
363
372
|
names = names.filter( n => n !== "'}'" );
|
|
364
373
|
}
|
|
374
|
+
else if (names.includes("'?'")) {
|
|
375
|
+
names = names.filter( n => n !== "'?'" );
|
|
376
|
+
}
|
|
365
377
|
names.sort( (a, b) => (tokenPrecedence(a) < tokenPrecedence(b) ? -1 : 1) );
|
|
366
378
|
return names;
|
|
367
379
|
}
|
|
@@ -421,10 +433,10 @@ function getExpectedTokensForMessage( recognizer, offendingToken, deadEnds ) {
|
|
|
421
433
|
const hideAltsType = recognizer.constructor.HideAlternatives;
|
|
422
434
|
const beforeUnreserved = recognizer.constructor.Number;
|
|
423
435
|
if (!identType || !beforeUnreserved || beforeUnreserved + 2 > identType)
|
|
424
|
-
return intervalSetToArray( recognizer,
|
|
436
|
+
return intervalSetToArray( recognizer, this._super.getExpectedTokens.call( this, recognizer ) );
|
|
425
437
|
|
|
426
438
|
const ll1 = new antlr4_LL1Analyzer(atn);
|
|
427
|
-
const expected = new IntervalSet
|
|
439
|
+
const expected = new IntervalSet();
|
|
428
440
|
const orig_addInterval = expected.addInterval;
|
|
429
441
|
const orig_addSet = expected.addSet;
|
|
430
442
|
expected.addInterval = addInterval;
|
|
@@ -485,7 +497,7 @@ function getExpectedTokensForMessage( recognizer, offendingToken, deadEnds ) {
|
|
|
485
497
|
}
|
|
486
498
|
|
|
487
499
|
function addRange( interval, start, stop ) {
|
|
488
|
-
orig_addInterval.call( interval, new
|
|
500
|
+
orig_addInterval.call( interval, new Interval( start, stop || start + 1 ) );
|
|
489
501
|
}
|
|
490
502
|
}
|
|
491
503
|
|