@abaplint/cli 2.119.58 → 2.119.60
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/build/cli.js +207 -117
- package/package.json +2 -2
package/build/cli.js
CHANGED
|
@@ -22,6 +22,37 @@ const ModeStr = 3;
|
|
|
22
22
|
const ModeTemplate = 4;
|
|
23
23
|
const ModeComment = 5;
|
|
24
24
|
const ModePragma = 6;
|
|
25
|
+
// character codes, used for integer comparisons in the hot loop
|
|
26
|
+
const EOF = -1; // no character (start/end of file)
|
|
27
|
+
const CH_TAB = 9; // "\t"
|
|
28
|
+
const CH_NL = 10; // "\n"
|
|
29
|
+
const CH_SPACE = 32; // " "
|
|
30
|
+
const CH_DQUOTE = 34; // "\""
|
|
31
|
+
const CH_HASH = 35; // "#"
|
|
32
|
+
const CH_QUOTE = 39; // "'"
|
|
33
|
+
const CH_STAR = 42; // "*"
|
|
34
|
+
const CH_DASH = 45; // "-"
|
|
35
|
+
const CH_COMMA = 44; // ","
|
|
36
|
+
const CH_DOT = 46; // "."
|
|
37
|
+
const CH_COLON = 58; // ":"
|
|
38
|
+
const CH_EQUALS = 61; // "="
|
|
39
|
+
const CH_GT = 62; // ">"
|
|
40
|
+
const CH_AT = 64; // "@"
|
|
41
|
+
const CH_BACKSLASH = 92; // "\\"
|
|
42
|
+
const CH_BACKTICK = 96; // "`"
|
|
43
|
+
const CH_LBRACE = 123; // "{"
|
|
44
|
+
const CH_PIPE = 124; // "|"
|
|
45
|
+
const CH_RBRACE = 125; // "}"
|
|
46
|
+
// characters that terminate the current token
|
|
47
|
+
const SPLITS = new Set([
|
|
48
|
+
CH_SPACE, CH_COLON, CH_DOT, CH_COMMA, CH_DASH, 43 /* + */, 40 /* ( */,
|
|
49
|
+
41 /* ) */, 91 /* [ */, 93 /* ] */, CH_BACKSLASH, CH_TAB, CH_NL
|
|
50
|
+
]);
|
|
51
|
+
// single characters that are emitted as their own token
|
|
52
|
+
const BUFS = new Set([
|
|
53
|
+
CH_DOT, CH_COMMA, CH_COLON, 40 /* ( */, 41 /* ) */, 91 /* [ */,
|
|
54
|
+
93 /* ] */, 43 /* + */, CH_AT
|
|
55
|
+
]);
|
|
25
56
|
class Lexer {
|
|
26
57
|
run(file, virtual) {
|
|
27
58
|
this.virtual = virtual;
|
|
@@ -36,15 +67,17 @@ class Lexer {
|
|
|
36
67
|
const col = this.stream.getCol();
|
|
37
68
|
const row = this.stream.getRow();
|
|
38
69
|
let whiteBefore = false;
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
70
|
+
const beforeOffset = this.stream.getOffset() - s.length;
|
|
71
|
+
if (beforeOffset >= 0) {
|
|
72
|
+
const prev = this.stream.charCodeAt(beforeOffset);
|
|
73
|
+
if (prev === CH_SPACE || prev === CH_NL || prev === CH_TAB || prev === CH_COLON) {
|
|
42
74
|
whiteBefore = true;
|
|
43
75
|
}
|
|
44
76
|
}
|
|
45
77
|
let whiteAfter = false;
|
|
46
78
|
const next = this.stream.nextChar();
|
|
47
|
-
if (next ===
|
|
79
|
+
if (next === CH_SPACE || next === CH_NL || next === CH_TAB || next === CH_COLON
|
|
80
|
+
|| next === CH_COMMA || next === CH_DOT || next === EOF || next === CH_DQUOTE) {
|
|
48
81
|
whiteAfter = true;
|
|
49
82
|
}
|
|
50
83
|
let pos = new position_1.Position(row, col - s.length);
|
|
@@ -214,10 +247,10 @@ class Lexer {
|
|
|
214
247
|
}
|
|
215
248
|
}
|
|
216
249
|
if (tok === undefined && this.m === ModeNormal && s.charAt(0) === "\\") {
|
|
217
|
-
const adj = this.stream.nextChar() ===
|
|
250
|
+
const adj = this.stream.nextChar() === EOF ? 1 : 0;
|
|
218
251
|
const prevOffset = this.stream.getOffset() - s.length - adj;
|
|
219
|
-
const prevChar =
|
|
220
|
-
const whiteBeforeBackslash = prevChar ===
|
|
252
|
+
const prevChar = this.stream.charCodeAt(prevOffset);
|
|
253
|
+
const whiteBeforeBackslash = prevChar === CH_SPACE || prevChar === CH_NL || prevChar === CH_TAB || prevChar === CH_COLON;
|
|
221
254
|
if (!whiteBeforeBackslash) {
|
|
222
255
|
tok = new tokens_1.AssociationName(pos, s);
|
|
223
256
|
}
|
|
@@ -230,100 +263,77 @@ class Lexer {
|
|
|
230
263
|
this.buffer.clear();
|
|
231
264
|
}
|
|
232
265
|
process(raw) {
|
|
233
|
-
|
|
234
|
-
this.
|
|
235
|
-
|
|
236
|
-
splits[" "] = true;
|
|
237
|
-
splits[":"] = true;
|
|
238
|
-
splits["."] = true;
|
|
239
|
-
splits[","] = true;
|
|
240
|
-
splits["-"] = true;
|
|
241
|
-
splits["+"] = true;
|
|
242
|
-
splits["("] = true;
|
|
243
|
-
splits[")"] = true;
|
|
244
|
-
splits["["] = true;
|
|
245
|
-
splits["]"] = true;
|
|
246
|
-
splits["\\"] = true;
|
|
247
|
-
splits["\t"] = true;
|
|
248
|
-
splits["\n"] = true;
|
|
249
|
-
const bufs = {};
|
|
250
|
-
bufs["."] = true;
|
|
251
|
-
bufs[","] = true;
|
|
252
|
-
bufs[":"] = true;
|
|
253
|
-
bufs["("] = true;
|
|
254
|
-
bufs[")"] = true;
|
|
255
|
-
bufs["["] = true;
|
|
256
|
-
bufs["]"] = true;
|
|
257
|
-
bufs["+"] = true;
|
|
258
|
-
bufs["@"] = true;
|
|
266
|
+
const stream = new lexer_stream_1.LexerStream(raw.replace(/\r/g, ""));
|
|
267
|
+
this.stream = stream;
|
|
268
|
+
this.buffer = new lexer_buffer_1.LexerBuffer(stream.getRaw());
|
|
259
269
|
for (;;) {
|
|
260
|
-
const current =
|
|
261
|
-
|
|
262
|
-
const ahead =
|
|
263
|
-
const aahead =
|
|
270
|
+
const current = stream.currentChar();
|
|
271
|
+
this.buffer.add(stream.getOffset());
|
|
272
|
+
const ahead = stream.nextChar();
|
|
273
|
+
const aahead = stream.nextNextChar();
|
|
264
274
|
if (this.m === ModeNormal) {
|
|
265
|
-
if (
|
|
275
|
+
if (SPLITS.has(ahead)) {
|
|
266
276
|
this.add();
|
|
267
277
|
}
|
|
268
|
-
else if (ahead ===
|
|
278
|
+
else if (ahead === CH_QUOTE) {
|
|
269
279
|
// start string
|
|
270
280
|
this.add();
|
|
271
281
|
this.m = ModeStr;
|
|
272
282
|
}
|
|
273
|
-
else if (ahead ===
|
|
283
|
+
else if (ahead === CH_PIPE || ahead === CH_RBRACE) {
|
|
274
284
|
// start template
|
|
275
285
|
this.add();
|
|
276
286
|
this.m = ModeTemplate;
|
|
277
287
|
}
|
|
278
|
-
else if (ahead ===
|
|
288
|
+
else if (ahead === CH_BACKTICK) {
|
|
279
289
|
// start ping
|
|
280
290
|
this.add();
|
|
281
291
|
this.m = ModePing;
|
|
282
292
|
}
|
|
283
|
-
else if (aahead ===
|
|
293
|
+
else if (ahead === CH_HASH && aahead === CH_HASH) {
|
|
284
294
|
// start pragma
|
|
285
295
|
this.add();
|
|
286
296
|
this.m = ModePragma;
|
|
287
297
|
}
|
|
288
|
-
else if (ahead ===
|
|
289
|
-
|| (ahead ===
|
|
298
|
+
else if (ahead === CH_DQUOTE
|
|
299
|
+
|| (ahead === CH_STAR && current === CH_NL)) {
|
|
290
300
|
// start comment
|
|
291
301
|
this.add();
|
|
292
302
|
this.m = ModeComment;
|
|
293
303
|
}
|
|
294
|
-
else if (ahead ===
|
|
304
|
+
else if (ahead === CH_AT && this.buffer.get().trim().length === 0) {
|
|
295
305
|
this.add();
|
|
296
306
|
}
|
|
297
|
-
else if (aahead ===
|
|
298
|
-
|| aahead === "=>") {
|
|
307
|
+
else if ((ahead === CH_DASH || ahead === CH_EQUALS) && aahead === CH_GT) {
|
|
299
308
|
this.add();
|
|
300
309
|
}
|
|
301
|
-
else if (current ===
|
|
302
|
-
&& ahead !==
|
|
303
|
-
&& (
|
|
310
|
+
else if (current === CH_GT
|
|
311
|
+
&& ahead !== CH_SPACE
|
|
312
|
+
&& (stream.prevChar() === CH_DASH || stream.prevChar() === CH_EQUALS)) {
|
|
304
313
|
// arrows
|
|
305
314
|
this.add();
|
|
306
315
|
}
|
|
307
|
-
else if (
|
|
308
|
-
&& (
|
|
309
|
-
|| (
|
|
316
|
+
else if (this.buffer.length() === 1
|
|
317
|
+
&& (BUFS.has(current)
|
|
318
|
+
|| (current === CH_DASH && ahead !== CH_GT))) {
|
|
310
319
|
this.add();
|
|
311
320
|
}
|
|
312
321
|
}
|
|
313
|
-
else if (this.m === ModePragma && (ahead ===
|
|
322
|
+
else if (this.m === ModePragma && (ahead === CH_COMMA || ahead === CH_COLON
|
|
323
|
+
|| ahead === CH_DOT || ahead === CH_SPACE || ahead === CH_NL)) {
|
|
314
324
|
// end of pragma
|
|
315
325
|
this.add();
|
|
316
326
|
this.m = ModeNormal;
|
|
317
327
|
}
|
|
318
328
|
else if (this.m === ModePing
|
|
319
|
-
&&
|
|
320
|
-
&& current ===
|
|
321
|
-
&& aahead
|
|
322
|
-
&& ahead !==
|
|
323
|
-
&& this.buffer.countIsEven(
|
|
329
|
+
&& this.buffer.length() > 1
|
|
330
|
+
&& current === CH_BACKTICK
|
|
331
|
+
&& !(ahead === CH_BACKTICK && aahead === CH_BACKTICK)
|
|
332
|
+
&& ahead !== CH_BACKTICK
|
|
333
|
+
&& this.buffer.countIsEven(CH_BACKTICK)) {
|
|
324
334
|
// end of ping
|
|
325
335
|
this.add();
|
|
326
|
-
if (ahead ===
|
|
336
|
+
if (ahead === CH_DQUOTE) {
|
|
327
337
|
this.m = ModeComment;
|
|
328
338
|
}
|
|
329
339
|
else {
|
|
@@ -331,41 +341,41 @@ class Lexer {
|
|
|
331
341
|
}
|
|
332
342
|
}
|
|
333
343
|
else if (this.m === ModeTemplate
|
|
334
|
-
&&
|
|
335
|
-
&& (current ===
|
|
336
|
-
&& (
|
|
344
|
+
&& this.buffer.length() > 1
|
|
345
|
+
&& (current === CH_PIPE || current === CH_LBRACE)
|
|
346
|
+
&& (stream.prevChar() !== CH_BACKSLASH || (stream.prevPrevChar() === CH_BACKSLASH && stream.prevChar() === CH_BACKSLASH))) {
|
|
337
347
|
// end of template
|
|
338
348
|
this.add();
|
|
339
349
|
this.m = ModeNormal;
|
|
340
350
|
}
|
|
341
351
|
else if (this.m === ModeTemplate
|
|
342
|
-
&& ahead ===
|
|
343
|
-
&& current !==
|
|
352
|
+
&& ahead === CH_RBRACE
|
|
353
|
+
&& current !== CH_BACKSLASH) {
|
|
344
354
|
this.add();
|
|
345
355
|
}
|
|
346
356
|
else if (this.m === ModeStr
|
|
347
|
-
&& current ===
|
|
348
|
-
&&
|
|
349
|
-
&& aahead
|
|
350
|
-
&& ahead !==
|
|
351
|
-
&& this.buffer.countIsEven(
|
|
357
|
+
&& current === CH_QUOTE
|
|
358
|
+
&& this.buffer.length() > 1
|
|
359
|
+
&& !(ahead === CH_QUOTE && aahead === CH_QUOTE)
|
|
360
|
+
&& ahead !== CH_QUOTE
|
|
361
|
+
&& this.buffer.countIsEven(CH_QUOTE)) {
|
|
352
362
|
// end of string
|
|
353
363
|
this.add();
|
|
354
|
-
if (ahead ===
|
|
364
|
+
if (ahead === CH_DQUOTE) {
|
|
355
365
|
this.m = ModeComment;
|
|
356
366
|
}
|
|
357
367
|
else {
|
|
358
368
|
this.m = ModeNormal;
|
|
359
369
|
}
|
|
360
370
|
}
|
|
361
|
-
else if (ahead ===
|
|
371
|
+
else if (ahead === CH_NL && this.m !== ModeTemplate) {
|
|
362
372
|
this.add();
|
|
363
373
|
this.m = ModeNormal;
|
|
364
374
|
}
|
|
365
|
-
else if (this.m === ModeTemplate && current ===
|
|
375
|
+
else if (this.m === ModeTemplate && current === CH_NL) {
|
|
366
376
|
this.add();
|
|
367
377
|
}
|
|
368
|
-
if (!
|
|
378
|
+
if (!stream.advance()) {
|
|
369
379
|
break;
|
|
370
380
|
}
|
|
371
381
|
}
|
|
@@ -387,24 +397,38 @@ exports.Lexer = Lexer;
|
|
|
387
397
|
|
|
388
398
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
389
399
|
exports.LexerBuffer = void 0;
|
|
400
|
+
// The buffer holds a reference to the raw input and tracks the [start, end)
|
|
401
|
+
// offset range of the current token, so the token string can be sliced out with
|
|
402
|
+
// a single substring() instead of being concatenated one character at a time.
|
|
390
403
|
class LexerBuffer {
|
|
391
|
-
constructor() {
|
|
392
|
-
this.
|
|
404
|
+
constructor(raw) {
|
|
405
|
+
this.raw = raw;
|
|
406
|
+
this.start = 0;
|
|
407
|
+
this.end = 0;
|
|
408
|
+
this.empty = true;
|
|
393
409
|
}
|
|
394
|
-
add(
|
|
395
|
-
this.
|
|
396
|
-
|
|
410
|
+
add(offset) {
|
|
411
|
+
if (this.empty === true) {
|
|
412
|
+
this.start = offset < 0 ? 0 : offset;
|
|
413
|
+
this.empty = false;
|
|
414
|
+
}
|
|
415
|
+
this.end = offset + 1;
|
|
397
416
|
}
|
|
398
417
|
get() {
|
|
399
|
-
return this.
|
|
418
|
+
return this.raw.substring(this.start, this.end);
|
|
419
|
+
}
|
|
420
|
+
length() {
|
|
421
|
+
return this.end - this.start;
|
|
400
422
|
}
|
|
401
423
|
clear() {
|
|
402
|
-
this.
|
|
424
|
+
this.start = 0;
|
|
425
|
+
this.end = 0;
|
|
426
|
+
this.empty = true;
|
|
403
427
|
}
|
|
404
428
|
countIsEven(char) {
|
|
405
429
|
let count = 0;
|
|
406
|
-
for (let i =
|
|
407
|
-
if (this.
|
|
430
|
+
for (let i = this.start; i < this.end; i += 1) {
|
|
431
|
+
if (this.raw.charCodeAt(i) === char) {
|
|
408
432
|
count += 1;
|
|
409
433
|
}
|
|
410
434
|
}
|
|
@@ -426,6 +450,8 @@ exports.LexerBuffer = LexerBuffer;
|
|
|
426
450
|
|
|
427
451
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
428
452
|
exports.LexerStream = void 0;
|
|
453
|
+
const NL = 10; // "\n"
|
|
454
|
+
const EOF = -1; // no character (start/end of file)
|
|
429
455
|
class LexerStream {
|
|
430
456
|
constructor(raw) {
|
|
431
457
|
this.offset = -1;
|
|
@@ -434,7 +460,7 @@ class LexerStream {
|
|
|
434
460
|
this.col = 0;
|
|
435
461
|
}
|
|
436
462
|
advance() {
|
|
437
|
-
if (this.currentChar() ===
|
|
463
|
+
if (this.currentChar() === NL) {
|
|
438
464
|
this.col = 1;
|
|
439
465
|
this.row = this.row + 1;
|
|
440
466
|
}
|
|
@@ -452,38 +478,51 @@ class LexerStream {
|
|
|
452
478
|
getRow() {
|
|
453
479
|
return this.row;
|
|
454
480
|
}
|
|
481
|
+
// the *Char() accessors return character codes (charCodeAt) rather than
|
|
482
|
+
// single character strings, to avoid allocating a string per input character
|
|
483
|
+
// in the lexer hot loop. EOF (-1) is returned when the offset is out of range.
|
|
455
484
|
prevChar() {
|
|
456
|
-
|
|
457
|
-
|
|
485
|
+
const o = this.offset - 1;
|
|
486
|
+
if (o < 0) {
|
|
487
|
+
return EOF;
|
|
458
488
|
}
|
|
459
|
-
return this.raw.
|
|
489
|
+
return this.raw.charCodeAt(o);
|
|
460
490
|
}
|
|
461
491
|
prevPrevChar() {
|
|
462
|
-
|
|
463
|
-
|
|
492
|
+
const o = this.offset - 2;
|
|
493
|
+
if (o < 0) {
|
|
494
|
+
return EOF;
|
|
464
495
|
}
|
|
465
|
-
return this.raw.
|
|
496
|
+
return this.raw.charCodeAt(o);
|
|
466
497
|
}
|
|
467
498
|
currentChar() {
|
|
468
499
|
if (this.offset < 0) {
|
|
469
|
-
return
|
|
500
|
+
return NL; // simulate newline at start of file to handle star(*) comments
|
|
470
501
|
}
|
|
471
502
|
else if (this.offset >= this.raw.length) {
|
|
472
|
-
return
|
|
503
|
+
return EOF;
|
|
473
504
|
}
|
|
474
|
-
return this.raw.
|
|
505
|
+
return this.raw.charCodeAt(this.offset);
|
|
475
506
|
}
|
|
476
507
|
nextChar() {
|
|
477
|
-
|
|
478
|
-
|
|
508
|
+
const o = this.offset + 1;
|
|
509
|
+
if (o >= this.raw.length) {
|
|
510
|
+
return EOF;
|
|
479
511
|
}
|
|
480
|
-
return this.raw.
|
|
512
|
+
return this.raw.charCodeAt(o);
|
|
481
513
|
}
|
|
482
514
|
nextNextChar() {
|
|
483
|
-
|
|
484
|
-
|
|
515
|
+
const o = this.offset + 2;
|
|
516
|
+
if (o >= this.raw.length) {
|
|
517
|
+
return EOF;
|
|
518
|
+
}
|
|
519
|
+
return this.raw.charCodeAt(o);
|
|
520
|
+
}
|
|
521
|
+
charCodeAt(o) {
|
|
522
|
+
if (o < 0 || o >= this.raw.length) {
|
|
523
|
+
return EOF;
|
|
485
524
|
}
|
|
486
|
-
return this.raw.
|
|
525
|
+
return this.raw.charCodeAt(o);
|
|
487
526
|
}
|
|
488
527
|
getRaw() {
|
|
489
528
|
return this.raw;
|
|
@@ -1881,8 +1920,9 @@ class Word {
|
|
|
1881
1920
|
}
|
|
1882
1921
|
}
|
|
1883
1922
|
class Token {
|
|
1884
|
-
constructor(
|
|
1885
|
-
this.
|
|
1923
|
+
constructor(t) {
|
|
1924
|
+
this.tokenType = t;
|
|
1925
|
+
this.name = t.name;
|
|
1886
1926
|
}
|
|
1887
1927
|
listKeywords() {
|
|
1888
1928
|
return [];
|
|
@@ -1894,7 +1934,7 @@ class Token {
|
|
|
1894
1934
|
const result = [];
|
|
1895
1935
|
for (const input of r) {
|
|
1896
1936
|
if (input.remainingLength() !== 0
|
|
1897
|
-
&& input.peek().constructor
|
|
1937
|
+
&& input.peek().constructor === this.tokenType) {
|
|
1898
1938
|
result.push(input.shift(new nodes_1.TokenNode(input.peek())));
|
|
1899
1939
|
}
|
|
1900
1940
|
}
|
|
@@ -2090,7 +2130,12 @@ class Optional {
|
|
|
2090
2130
|
for (const input of r) {
|
|
2091
2131
|
result.push(input);
|
|
2092
2132
|
const res = this.optional.run([input]);
|
|
2093
|
-
|
|
2133
|
+
if (res.length === 1) {
|
|
2134
|
+
result.push(res[0]);
|
|
2135
|
+
}
|
|
2136
|
+
else {
|
|
2137
|
+
result.push(...res);
|
|
2138
|
+
}
|
|
2094
2139
|
}
|
|
2095
2140
|
return result;
|
|
2096
2141
|
}
|
|
@@ -2129,6 +2174,9 @@ class Star {
|
|
|
2129
2174
|
// avoid stack overflow
|
|
2130
2175
|
result = result.concat(res);
|
|
2131
2176
|
}
|
|
2177
|
+
else if (res.length === 1) {
|
|
2178
|
+
result.push(res[0]);
|
|
2179
|
+
}
|
|
2132
2180
|
else {
|
|
2133
2181
|
result.push(...res);
|
|
2134
2182
|
}
|
|
@@ -2280,6 +2328,9 @@ class Sequence {
|
|
|
2280
2328
|
// avoid stack overflow
|
|
2281
2329
|
result = result.concat(temp);
|
|
2282
2330
|
}
|
|
2331
|
+
else if (temp.length === 1) {
|
|
2332
|
+
result.push(temp[0]);
|
|
2333
|
+
}
|
|
2283
2334
|
else {
|
|
2284
2335
|
result.push(...temp);
|
|
2285
2336
|
}
|
|
@@ -2504,7 +2555,12 @@ class Alternative {
|
|
|
2504
2555
|
const result = [];
|
|
2505
2556
|
for (const sequ of this.list) {
|
|
2506
2557
|
const temp = sequ.run(r);
|
|
2507
|
-
|
|
2558
|
+
if (temp.length === 1) {
|
|
2559
|
+
result.push(temp[0]);
|
|
2560
|
+
}
|
|
2561
|
+
else {
|
|
2562
|
+
result.push(...temp);
|
|
2563
|
+
}
|
|
2508
2564
|
}
|
|
2509
2565
|
return result;
|
|
2510
2566
|
}
|
|
@@ -2562,7 +2618,12 @@ class AlternativePriority {
|
|
|
2562
2618
|
// console.log(seq.toStr());
|
|
2563
2619
|
const temp = sequ.run(r);
|
|
2564
2620
|
if (temp.length > 0) {
|
|
2565
|
-
|
|
2621
|
+
if (temp.length === 1) {
|
|
2622
|
+
result.push(temp[0]);
|
|
2623
|
+
}
|
|
2624
|
+
else {
|
|
2625
|
+
result.push(...temp);
|
|
2626
|
+
}
|
|
2566
2627
|
break;
|
|
2567
2628
|
}
|
|
2568
2629
|
}
|
|
@@ -2678,7 +2739,7 @@ function regex(r) {
|
|
|
2678
2739
|
return new Regex(r);
|
|
2679
2740
|
}
|
|
2680
2741
|
function tok(t) {
|
|
2681
|
-
return new Token(t
|
|
2742
|
+
return new Token(t);
|
|
2682
2743
|
}
|
|
2683
2744
|
const expressionSingletons = {};
|
|
2684
2745
|
const stringSingletons = {};
|
|
@@ -11174,6 +11235,7 @@ const expand_macros_1 = __webpack_require__(/*! ./expand_macros */ "../core/buil
|
|
|
11174
11235
|
const tokens_1 = __webpack_require__(/*! ../1_lexer/tokens */ "../core/build/src/abap/1_lexer/tokens/index.js");
|
|
11175
11236
|
const _select_reclassify_1 = __webpack_require__(/*! ./_select_reclassify */ "../core/build/src/abap/2_statements/_select_reclassify.js");
|
|
11176
11237
|
exports.STATEMENT_MAX_TOKENS = 20000;
|
|
11238
|
+
const EMPTY_PRAGMAS = Object.freeze([]);
|
|
11177
11239
|
class StatementMap {
|
|
11178
11240
|
constructor() {
|
|
11179
11241
|
this.map = {};
|
|
@@ -11372,9 +11434,19 @@ class StatementParser {
|
|
|
11372
11434
|
return statement;
|
|
11373
11435
|
}
|
|
11374
11436
|
removePragma(tokens) {
|
|
11437
|
+
let hasPragma = false;
|
|
11438
|
+
// skip the last token as it is the punctuation
|
|
11439
|
+
for (let i = 0; i < tokens.length - 1; i++) {
|
|
11440
|
+
if (tokens[i] instanceof Tokens.Pragma) {
|
|
11441
|
+
hasPragma = true;
|
|
11442
|
+
break;
|
|
11443
|
+
}
|
|
11444
|
+
}
|
|
11445
|
+
if (hasPragma === false) {
|
|
11446
|
+
return { tokens: tokens.slice(0, tokens.length - 1), pragmas: EMPTY_PRAGMAS };
|
|
11447
|
+
}
|
|
11375
11448
|
const result = [];
|
|
11376
11449
|
const pragmas = [];
|
|
11377
|
-
// skip the last token as it is the punctuation
|
|
11378
11450
|
for (let i = 0; i < tokens.length - 1; i++) {
|
|
11379
11451
|
const t = tokens[i];
|
|
11380
11452
|
if (t instanceof Tokens.Pragma) {
|
|
@@ -47928,6 +48000,7 @@ const _abstract_node_1 = __webpack_require__(/*! ./_abstract_node */ "../core/bu
|
|
|
47928
48000
|
class ExpressionNode extends _abstract_node_1.AbstractNode {
|
|
47929
48001
|
constructor(expression) {
|
|
47930
48002
|
super();
|
|
48003
|
+
this.tokenCount = 0;
|
|
47931
48004
|
this.expression = expression;
|
|
47932
48005
|
}
|
|
47933
48006
|
addChild(_n) {
|
|
@@ -47936,12 +48009,15 @@ class ExpressionNode extends _abstract_node_1.AbstractNode {
|
|
|
47936
48009
|
get() {
|
|
47937
48010
|
return this.expression;
|
|
47938
48011
|
}
|
|
47939
|
-
|
|
47940
|
-
|
|
47941
|
-
for (const
|
|
47942
|
-
|
|
48012
|
+
setChildren(children) {
|
|
48013
|
+
super.setChildren(children);
|
|
48014
|
+
for (const child of this.getChildren()) {
|
|
48015
|
+
this.tokenCount = this.tokenCount + child.countTokens();
|
|
47943
48016
|
}
|
|
47944
|
-
return
|
|
48017
|
+
return this;
|
|
48018
|
+
}
|
|
48019
|
+
countTokens() {
|
|
48020
|
+
return this.tokenCount;
|
|
47945
48021
|
}
|
|
47946
48022
|
getFirstToken() {
|
|
47947
48023
|
for (const child of this.getChildren()) {
|
|
@@ -50944,6 +51020,7 @@ class ClassDefinition extends _identifier_1.Identifier {
|
|
|
50944
51020
|
// perform checks after everything has been initialized
|
|
50945
51021
|
this.checkMethodsFromSuperClasses(input);
|
|
50946
51022
|
this.checkMethodNameLength(input);
|
|
51023
|
+
this.checkClassConstructorStatic(input);
|
|
50947
51024
|
}
|
|
50948
51025
|
getFriends() {
|
|
50949
51026
|
return this.friends;
|
|
@@ -51007,6 +51084,13 @@ class ClassDefinition extends _identifier_1.Identifier {
|
|
|
51007
51084
|
}
|
|
51008
51085
|
}
|
|
51009
51086
|
}
|
|
51087
|
+
checkClassConstructorStatic(input) {
|
|
51088
|
+
for (const m of this.methodDefs.getAll()) {
|
|
51089
|
+
if (m.getName().toUpperCase() === "CLASS_CONSTRUCTOR" && m.isStatic() === false) {
|
|
51090
|
+
input.issues.push((0, _syntax_input_1.syntaxIssue)(input, m.getToken(), "CLASS_CONSTRUCTOR must be static"));
|
|
51091
|
+
}
|
|
51092
|
+
}
|
|
51093
|
+
}
|
|
51010
51094
|
checkMethodsFromSuperClasses(input) {
|
|
51011
51095
|
var _a;
|
|
51012
51096
|
const scope = input.scope;
|
|
@@ -53634,7 +53718,7 @@ const cds_name_1 = __webpack_require__(/*! ./cds_name */ "../core/build/src/cds/
|
|
|
53634
53718
|
class CDSDefineTableFunction extends combi_1.Expression {
|
|
53635
53719
|
getRunnable() {
|
|
53636
53720
|
const methodName = (0, combi_1.seq)(cds_name_1.CDSName, "=", ">", cds_name_1.CDSName);
|
|
53637
|
-
return (0, combi_1.seq)((0, combi_1.star)(_1.CDSAnnotation), (0, combi_1.str)("DEFINE TABLE FUNCTION"), cds_name_1.CDSName, (0, combi_1.optPrio)(_1.CDSWithParameters), (0, combi_1.str)("RETURNS {"), (0, combi_1.plus)((0, combi_1.seq)((0, combi_1.star)(_1.CDSAnnotation), (0, combi_1.optPrio)("KEY"), cds_name_1.CDSName, ":", _1.CDSType, ";")), (0, combi_1.str)("} IMPLEMENTED BY METHOD"), methodName, (0, combi_1.opt)(";"));
|
|
53721
|
+
return (0, combi_1.seq)((0, combi_1.star)(_1.CDSAnnotation), (0, combi_1.str)("DEFINE TABLE FUNCTION"), cds_name_1.CDSName, (0, combi_1.optPrio)(_1.CDSWithParameters), (0, combi_1.str)("RETURNS {"), (0, combi_1.plus)((0, combi_1.seq)((0, combi_1.star)(_1.CDSAnnotation), (0, combi_1.optPrio)("KEY"), cds_name_1.CDSName, ":", _1.CDSType, (0, combi_1.star)(_1.CDSAnnotation), ";")), (0, combi_1.str)("} IMPLEMENTED BY METHOD"), methodName, (0, combi_1.opt)(";"));
|
|
53638
53722
|
}
|
|
53639
53723
|
}
|
|
53640
53724
|
exports.CDSDefineTableFunction = CDSDefineTableFunction;
|
|
@@ -53699,7 +53783,7 @@ class CDSElement extends combi_1.Expression {
|
|
|
53699
53783
|
const funcWithPath = (0, combi_1.seq)(_1.CDSFunction, (0, combi_1.plusPrio)(pathSegment));
|
|
53700
53784
|
const body = (0, combi_1.altPrio)(extensionWildcard, includeElement, _1.CDSArithmetics, _1.CDSAggregate, _1.CDSString, _1.CDSArithParen, funcWithPath, _1.CDSFunction, cds_cast_1.CDSCast, _1.CDSCase, (0, combi_1.seq)("(", _1.CDSCase, ")"), (0, combi_1.seq)(_1.CDSPrefixedName, (0, combi_1.optPrio)(cds_as_1.CDSAs), (0, combi_1.optPrio)((0, combi_1.altPrio)(redirected, colonThing))), _1.CDSInteger);
|
|
53701
53785
|
const elementBody = (0, combi_1.altPrio)(typedVirtual, (0, combi_1.seq)((0, combi_1.altPrio)("KEY", "VIRTUAL"), body), body);
|
|
53702
|
-
return (0, combi_1.seq)((0, combi_1.starPrio)(_1.CDSAnnotation), elementBody, (0, combi_1.optPrio)(cds_as_1.CDSAs));
|
|
53786
|
+
return (0, combi_1.seq)((0, combi_1.starPrio)(_1.CDSAnnotation), elementBody, (0, combi_1.optPrio)(cds_as_1.CDSAs), (0, combi_1.starPrio)(_1.CDSAnnotation));
|
|
53703
53787
|
}
|
|
53704
53788
|
}
|
|
53705
53789
|
exports.CDSElement = CDSElement;
|
|
@@ -53968,7 +54052,7 @@ const combi_1 = __webpack_require__(/*! ../../abap/2_statements/combi */ "../cor
|
|
|
53968
54052
|
class CDSName extends combi_1.Expression {
|
|
53969
54053
|
getRunnable() {
|
|
53970
54054
|
const pre = (0, combi_1.seq)("/", (0, combi_1.regex)(/^[\w_]+$/), "/");
|
|
53971
|
-
return (0, combi_1.seq)((0, combi_1.optPrio)(":"), (0, combi_1.optPrio)(pre), (0, combi_1.regex)(/^\$?#?[\w_]+$/));
|
|
54055
|
+
return (0, combi_1.altPrio)((0, combi_1.regex)(/^"(?:[^"]|"")*"$/), (0, combi_1.seq)((0, combi_1.optPrio)(":"), (0, combi_1.optPrio)(pre), (0, combi_1.regex)(/^\$?#?[\w_]+$/)));
|
|
53972
54056
|
}
|
|
53973
54057
|
}
|
|
53974
54058
|
exports.CDSName = CDSName;
|
|
@@ -54183,7 +54267,7 @@ exports.CDSString = void 0;
|
|
|
54183
54267
|
const combi_1 = __webpack_require__(/*! ../../abap/2_statements/combi */ "../core/build/src/abap/2_statements/combi.js");
|
|
54184
54268
|
class CDSString extends combi_1.Expression {
|
|
54185
54269
|
getRunnable() {
|
|
54186
|
-
const reg = (0, combi_1.regex)(/^
|
|
54270
|
+
const reg = (0, combi_1.regex)(/^'(?:[^'\\]|''|\\'|\\\\|\\(?!'))*'$/);
|
|
54187
54271
|
const abapTypeName = (0, combi_1.regex)(/^(?:int[1-9]|int8|sstring|sstr|char|numc|dats|datn|tims|timn|utcl|utclong|fltp|decfloat\d+|dec|string|rawstring|rstr|raw|xstring|clnt|lang|unit|cuky|curr|quan|geom_ewkb|d34n|d16n|d34d|d16d|d34s|d16s|d34r|d16r|d|t|p|n|c|x|f)$/i);
|
|
54188
54272
|
const abap = (0, combi_1.seq)("abap", ".", abapTypeName, (0, combi_1.optPrio)((0, combi_1.seq)("(", (0, combi_1.regex)(/^\d+$/), ")")), reg);
|
|
54189
54273
|
return (0, combi_1.altPrio)(abap, reg);
|
|
@@ -68684,7 +68768,7 @@ class Registry {
|
|
|
68684
68768
|
}
|
|
68685
68769
|
static abaplintVersion() {
|
|
68686
68770
|
// magic, see build script "version.js"
|
|
68687
|
-
return "2.119.
|
|
68771
|
+
return "2.119.60";
|
|
68688
68772
|
}
|
|
68689
68773
|
getDDICReferences() {
|
|
68690
68774
|
return this.ddicReferences;
|
|
@@ -74344,6 +74428,7 @@ class DangerousStatementConf extends _basic_rule_config_1.BasicRuleConfig {
|
|
|
74344
74428
|
this.insertTextpool = true;
|
|
74345
74429
|
this.deleteDynpro = true;
|
|
74346
74430
|
this.exportDynpro = true;
|
|
74431
|
+
this.editorCallForReport = true;
|
|
74347
74432
|
/** Finds instances of dynamic SQL: SELECT, UPDATE, DELETE, INSERT, MODIFY */
|
|
74348
74433
|
this.dynamicSQL = true;
|
|
74349
74434
|
/** Ignore dynamic SQL in IF_RAP_QUERY_PROVIDER~SELECT implementations */
|
|
@@ -74428,6 +74513,11 @@ dynamic SQL can potentially create SQL injection problems`,
|
|
|
74428
74513
|
else if (this.conf.exportDynpro && statement instanceof Statements.ExportDynpro) {
|
|
74429
74514
|
message = "EXPORT DYNPRO";
|
|
74430
74515
|
}
|
|
74516
|
+
else if (this.conf.editorCallForReport
|
|
74517
|
+
&& statement instanceof Statements.EditorCall
|
|
74518
|
+
&& statementNode.findDirectTokenByText("REPORT")) {
|
|
74519
|
+
message = "EDITOR-CALL FOR REPORT";
|
|
74520
|
+
}
|
|
74431
74521
|
if (message) {
|
|
74432
74522
|
issues.push(issue_1.Issue.atStatement(file, statementNode, this.getDescription(message), this.getMetadata().key, this.conf.severity));
|
|
74433
74523
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@abaplint/cli",
|
|
3
|
-
"version": "2.119.
|
|
3
|
+
"version": "2.119.60",
|
|
4
4
|
"description": "abaplint - Command Line Interface",
|
|
5
5
|
"funding": "https://github.com/sponsors/larshp",
|
|
6
6
|
"bin": {
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
},
|
|
40
40
|
"homepage": "https://abaplint.org",
|
|
41
41
|
"devDependencies": {
|
|
42
|
-
"@abaplint/core": "^2.119.
|
|
42
|
+
"@abaplint/core": "^2.119.60",
|
|
43
43
|
"@types/chai": "^4.3.20",
|
|
44
44
|
"@types/minimist": "^1.2.5",
|
|
45
45
|
"@types/mocha": "^10.0.10",
|