@abaplint/core 2.120.74 → 2.120.76
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/abaplint.d.ts +5 -1
- package/build/src/abap/2_statements/combi.js +143 -51
- package/build/src/abap/5_syntax/_builtin.js +8 -0
- package/build/src/abap/5_syntax/_loop_table_change.js +126 -0
- package/build/src/abap/5_syntax/expressions/_substring.js +83 -0
- package/build/src/abap/5_syntax/expressions/attribute_chain.js +3 -16
- package/build/src/abap/5_syntax/expressions/compare.js +33 -8
- package/build/src/abap/5_syntax/expressions/field_chain.js +5 -14
- package/build/src/abap/5_syntax/expressions/method_call_chain.js +16 -1
- package/build/src/abap/5_syntax/expressions/method_call_param.js +3 -0
- package/build/src/abap/5_syntax/expressions/target.js +14 -2
- package/build/src/abap/5_syntax/statements/append.js +6 -0
- package/build/src/abap/5_syntax/statements/read_table.js +39 -0
- package/build/src/abap/5_syntax/structures/cleanup.js +105 -0
- package/build/src/abap/5_syntax/syntax.js +13 -0
- package/build/src/ddic.js +1 -1
- package/build/src/objects/domain.js +4 -1
- package/build/src/registry.js +1 -1
- package/build/src/rules/abapdoc_html_tag.js +123 -0
- package/build/src/rules/abapdoc_leading_at.js +117 -0
- package/build/src/rules/abapdoc_parameter_names.js +149 -0
- package/build/src/rules/cds_check_syntax.js +4 -4
- package/build/src/rules/change_if_to_case.js +3 -2
- package/build/src/rules/changing_sorted_line.js +235 -0
- package/build/src/rules/class_attribute_names.js +15 -6
- package/build/src/rules/delete_index_in_loop.js +163 -0
- package/build/src/rules/final_newline.js +78 -0
- package/build/src/rules/forbidden_identifier.js +4 -3
- package/build/src/rules/forbidden_void_type.js +4 -9
- package/build/src/rules/index.js +11 -0
- package/build/src/rules/inline_packed_computation.js +220 -0
- package/build/src/rules/intf_referencing_clas.js +3 -1
- package/build/src/rules/line_only_punc.js +1 -1
- package/build/src/rules/local_class_naming.js +15 -2
- package/build/src/rules/local_variable_names.js +18 -9
- package/build/src/rules/macro_naming.js +3 -2
- package/build/src/rules/method_parameter_names.js +17 -7
- package/build/src/rules/modify_only_own_db_tables.js +3 -2
- package/build/src/rules/no_prefixes.js +25 -12
- package/build/src/rules/object_naming.js +18 -3
- package/build/src/rules/prefer_inline_cast.js +276 -0
- package/build/src/rules/range_row_values.js +200 -0
- package/build/src/rules/redundant_conversion.js +3 -0
- package/build/src/rules/selection_screen_naming.js +21 -2
- package/build/src/rules/sicf_consistency.js +1 -2
- package/build/src/rules/sort_empty_key.js +188 -0
- package/build/src/rules/subrc_after_assign.js +220 -0
- package/build/src/rules/types_naming.js +3 -2
- package/build/src/rules/use_message_class.js +64 -1
- package/build/src/rules/wrong_abapdoc_position.js +58 -11
- package/build/src/rules/xml_consistency.js +6 -2
- package/build/src/utils/name_validator.js +7 -3
- package/package.json +1 -1
package/build/abaplint.d.ts
CHANGED
|
@@ -624,6 +624,8 @@ export declare class BuiltIn {
|
|
|
624
624
|
static searchBuiltin(name: string | undefined): IMethodDefinition | undefined;
|
|
625
625
|
private static readonly unnamedArgument;
|
|
626
626
|
static hasUnnamedArgument(name: string | undefined): boolean;
|
|
627
|
+
private static readonly argumentTypedReturn;
|
|
628
|
+
static returnsArgumentType(name: string | undefined): boolean;
|
|
627
629
|
static isPredicate(name: string | undefined): boolean | undefined;
|
|
628
630
|
getTypes(): TypedIdentifier[];
|
|
629
631
|
get(extras: string[]): TypedIdentifier[];
|
|
@@ -2038,7 +2040,8 @@ declare class Domain extends AbstractObject {
|
|
|
2038
2040
|
};
|
|
2039
2041
|
getIdentifier(): Identifier | undefined;
|
|
2040
2042
|
setDirty(): void;
|
|
2041
|
-
parseType(reg: IRegistry
|
|
2043
|
+
parseType(reg: IRegistry): AbstractType;
|
|
2044
|
+
parseDomainType(reg: IRegistry, dataElement?: string, description?: string): AbstractType;
|
|
2042
2045
|
parse(): {
|
|
2043
2046
|
updated: boolean;
|
|
2044
2047
|
runtime: number;
|
|
@@ -7810,6 +7813,7 @@ export declare class SyntaxLogic {
|
|
|
7810
7813
|
private readonly object;
|
|
7811
7814
|
private readonly reg;
|
|
7812
7815
|
private scope;
|
|
7816
|
+
private loopTables;
|
|
7813
7817
|
private helpers;
|
|
7814
7818
|
constructor(reg: IRegistry, object: ABAPObject);
|
|
7815
7819
|
run(): ISyntaxResult;
|
|
@@ -58,6 +58,9 @@ const Tokens = __importStar(require("../1_lexer/tokens"));
|
|
|
58
58
|
const nodes_1 = require("../nodes");
|
|
59
59
|
const version_1 = require("../../version");
|
|
60
60
|
const result_1 = require("./result");
|
|
61
|
+
// shared result for "nothing matched", frozen so accidental mutation throws instead of leaking between calls.
|
|
62
|
+
// Returned arrays are never mutated by callers, which allows returning shared/input arrays as is
|
|
63
|
+
const EMPTY = Object.freeze([]);
|
|
61
64
|
class Regex {
|
|
62
65
|
constructor(r) {
|
|
63
66
|
this.regexp = r;
|
|
@@ -69,17 +72,23 @@ class Regex {
|
|
|
69
72
|
return [];
|
|
70
73
|
}
|
|
71
74
|
run(r) {
|
|
72
|
-
|
|
75
|
+
let result = undefined;
|
|
73
76
|
for (const input of r) {
|
|
74
77
|
if (input.remainingLength() === 0) {
|
|
75
78
|
continue;
|
|
76
79
|
}
|
|
77
80
|
const token = input.peek();
|
|
78
81
|
if (this.regexp.test(token.getStr()) === true) {
|
|
79
|
-
|
|
82
|
+
const shifted = input.shift(new nodes_1.TokenNodeRegex(token));
|
|
83
|
+
if (result === undefined) {
|
|
84
|
+
result = [shifted];
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
result.push(shifted);
|
|
88
|
+
}
|
|
80
89
|
}
|
|
81
90
|
}
|
|
82
|
-
return result;
|
|
91
|
+
return result !== null && result !== void 0 ? result : EMPTY;
|
|
83
92
|
}
|
|
84
93
|
railroad() {
|
|
85
94
|
return "Railroad.Terminal(\"" + this.regexp.source.replace(/\\/g, "\\\\").replace(/"/g, "\\\"") + "\")";
|
|
@@ -102,15 +111,20 @@ class Word {
|
|
|
102
111
|
return [];
|
|
103
112
|
}
|
|
104
113
|
run(r) {
|
|
105
|
-
|
|
114
|
+
let result = undefined;
|
|
106
115
|
for (const input of r) {
|
|
107
116
|
if (input.remainingLength() !== 0
|
|
108
117
|
&& input.peek().getUpperStr() === this.s) {
|
|
109
|
-
|
|
110
|
-
result
|
|
118
|
+
const shifted = input.shift(new nodes_1.TokenNode(input.peek()));
|
|
119
|
+
if (result === undefined) {
|
|
120
|
+
result = [shifted];
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
result.push(shifted);
|
|
124
|
+
}
|
|
111
125
|
}
|
|
112
126
|
}
|
|
113
|
-
return result;
|
|
127
|
+
return result !== null && result !== void 0 ? result : EMPTY;
|
|
114
128
|
}
|
|
115
129
|
railroad() {
|
|
116
130
|
return "Railroad.Terminal('\"" + this.s + "\"')";
|
|
@@ -134,14 +148,20 @@ class Token {
|
|
|
134
148
|
return [];
|
|
135
149
|
}
|
|
136
150
|
run(r) {
|
|
137
|
-
|
|
151
|
+
let result = undefined;
|
|
138
152
|
for (const input of r) {
|
|
139
153
|
if (input.remainingLength() !== 0
|
|
140
154
|
&& input.peek().constructor === this.tokenType) {
|
|
141
|
-
|
|
155
|
+
const shifted = input.shift(new nodes_1.TokenNode(input.peek()));
|
|
156
|
+
if (result === undefined) {
|
|
157
|
+
result = [shifted];
|
|
158
|
+
}
|
|
159
|
+
else {
|
|
160
|
+
result.push(shifted);
|
|
161
|
+
}
|
|
142
162
|
}
|
|
143
163
|
}
|
|
144
|
-
return result;
|
|
164
|
+
return result !== null && result !== void 0 ? result : EMPTY;
|
|
145
165
|
}
|
|
146
166
|
railroad() {
|
|
147
167
|
let text = this.name;
|
|
@@ -179,9 +199,9 @@ class Vers {
|
|
|
179
199
|
if (this.also === AlsoIn.OpenABAP) {
|
|
180
200
|
return this.runnable.run(r);
|
|
181
201
|
}
|
|
182
|
-
return (0, version_1.releaseAtLeast)(version_1.Release.v702, this.release) ? this.runnable.run(r) :
|
|
202
|
+
return (0, version_1.releaseAtLeast)(version_1.Release.v702, this.release) ? this.runnable.run(r) : EMPTY;
|
|
183
203
|
}
|
|
184
|
-
return (0, version_1.releaseAtLeast)(Combi.getRelease(), this.release) ? this.runnable.run(r) :
|
|
204
|
+
return (0, version_1.releaseAtLeast)(Combi.getRelease(), this.release) ? this.runnable.run(r) : EMPTY;
|
|
185
205
|
}
|
|
186
206
|
getUsing() {
|
|
187
207
|
return this.runnable.getUsing();
|
|
@@ -229,7 +249,7 @@ class LangVers {
|
|
|
229
249
|
return this.runnable.run(r);
|
|
230
250
|
}
|
|
231
251
|
else {
|
|
232
|
-
return
|
|
252
|
+
return EMPTY;
|
|
233
253
|
}
|
|
234
254
|
}
|
|
235
255
|
railroad() {
|
|
@@ -262,7 +282,7 @@ class LangVersNot {
|
|
|
262
282
|
return this.runnable.run(r);
|
|
263
283
|
}
|
|
264
284
|
else {
|
|
265
|
-
return
|
|
285
|
+
return EMPTY;
|
|
266
286
|
}
|
|
267
287
|
}
|
|
268
288
|
railroad() {
|
|
@@ -290,6 +310,22 @@ class OptionalPriority {
|
|
|
290
310
|
return this.optional.getUsing();
|
|
291
311
|
}
|
|
292
312
|
run(r) {
|
|
313
|
+
if (r.length === 1) {
|
|
314
|
+
// single input, pass and return the input array without wrapping
|
|
315
|
+
const res = this.optional.run(r);
|
|
316
|
+
if (res.length > 1) {
|
|
317
|
+
return res;
|
|
318
|
+
}
|
|
319
|
+
else if (res.length === 0) {
|
|
320
|
+
return r;
|
|
321
|
+
}
|
|
322
|
+
else if (res[0].remainingLength() < r[0].remainingLength()) {
|
|
323
|
+
return res;
|
|
324
|
+
}
|
|
325
|
+
else {
|
|
326
|
+
return r;
|
|
327
|
+
}
|
|
328
|
+
}
|
|
293
329
|
const result = [];
|
|
294
330
|
for (const input of r) {
|
|
295
331
|
const res = this.optional.run([input]);
|
|
@@ -329,6 +365,11 @@ class Optional {
|
|
|
329
365
|
return this.optional.getUsing();
|
|
330
366
|
}
|
|
331
367
|
run(r) {
|
|
368
|
+
if (r.length === 1) {
|
|
369
|
+
// single input, pass and return the input array without wrapping
|
|
370
|
+
const res = this.optional.run(r);
|
|
371
|
+
return res.length === 0 ? r : r.concat(res);
|
|
372
|
+
}
|
|
332
373
|
const result = [];
|
|
333
374
|
for (const input of r) {
|
|
334
375
|
result.push(input);
|
|
@@ -366,14 +407,16 @@ class Star {
|
|
|
366
407
|
let result = r;
|
|
367
408
|
try {
|
|
368
409
|
let res = r;
|
|
369
|
-
let input = [];
|
|
370
410
|
for (;;) {
|
|
371
|
-
|
|
372
|
-
res = this.sta.run(input);
|
|
411
|
+
res = this.sta.run(res);
|
|
373
412
|
if (res.length === 0) {
|
|
374
413
|
break;
|
|
375
414
|
}
|
|
376
|
-
if (
|
|
415
|
+
if (result === r) {
|
|
416
|
+
// copy on first match, the input array must not be mutated
|
|
417
|
+
result = r.concat(res);
|
|
418
|
+
}
|
|
419
|
+
else if (res.length > 1000) {
|
|
377
420
|
// avoid stack overflow
|
|
378
421
|
result = result.concat(res);
|
|
379
422
|
}
|
|
@@ -515,6 +558,17 @@ class Sequence {
|
|
|
515
558
|
return this.list.reduce((a, c) => { return a.concat(c.getUsing()); }, []);
|
|
516
559
|
}
|
|
517
560
|
run(r) {
|
|
561
|
+
if (r.length === 1) {
|
|
562
|
+
// single input, pass it down without wrapping and return the last result as is
|
|
563
|
+
let temp = r;
|
|
564
|
+
for (const sequence of this.list) {
|
|
565
|
+
temp = sequence.run(temp);
|
|
566
|
+
if (temp.length === 0) {
|
|
567
|
+
return EMPTY;
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
return temp;
|
|
571
|
+
}
|
|
518
572
|
let result = [];
|
|
519
573
|
for (const input of r) {
|
|
520
574
|
let temp = [input];
|
|
@@ -592,12 +646,33 @@ class Expression {
|
|
|
592
646
|
this.runnable = undefined;
|
|
593
647
|
}
|
|
594
648
|
run(r) {
|
|
595
|
-
const results = [];
|
|
596
649
|
if (this.runnable === undefined) {
|
|
597
650
|
this.runnable = this.getRunnable();
|
|
598
651
|
}
|
|
652
|
+
if (r.length === 1) {
|
|
653
|
+
// single input, pass it down without wrapping
|
|
654
|
+
const input = r[0];
|
|
655
|
+
const temp = this.runnable.run(r);
|
|
656
|
+
if (temp.length === 0) {
|
|
657
|
+
return EMPTY;
|
|
658
|
+
}
|
|
659
|
+
const results = new Array(temp.length);
|
|
660
|
+
for (let i = 0; i < temp.length; i++) {
|
|
661
|
+
const t = temp[i];
|
|
662
|
+
const consumed = input.remainingLength() - t.remainingLength();
|
|
663
|
+
results[i] = consumed > 0 ? t.wrapConsumed(consumed, new nodes_1.ExpressionNode(this)) : t;
|
|
664
|
+
}
|
|
665
|
+
return results;
|
|
666
|
+
}
|
|
667
|
+
let results = undefined;
|
|
599
668
|
for (const input of r) {
|
|
600
669
|
const temp = this.runnable.run([input]);
|
|
670
|
+
if (temp.length === 0) {
|
|
671
|
+
continue;
|
|
672
|
+
}
|
|
673
|
+
else if (results === undefined) {
|
|
674
|
+
results = [];
|
|
675
|
+
}
|
|
601
676
|
for (const t of temp) {
|
|
602
677
|
const consumed = input.remainingLength() - t.remainingLength();
|
|
603
678
|
if (consumed > 0) {
|
|
@@ -609,8 +684,7 @@ class Expression {
|
|
|
609
684
|
}
|
|
610
685
|
}
|
|
611
686
|
}
|
|
612
|
-
|
|
613
|
-
return results;
|
|
687
|
+
return results !== null && results !== void 0 ? results : EMPTY;
|
|
614
688
|
}
|
|
615
689
|
listKeywords() {
|
|
616
690
|
// do not recurse, all Expressions are evaluated only on first level
|
|
@@ -651,12 +725,16 @@ class Permutation {
|
|
|
651
725
|
return this.list.reduce((a, c) => { return a.concat(c.getUsing()); }, []);
|
|
652
726
|
}
|
|
653
727
|
run(r) {
|
|
654
|
-
|
|
655
|
-
|
|
728
|
+
let result = undefined;
|
|
729
|
+
let copy = undefined;
|
|
656
730
|
for (let index = 0; index < this.list.length; index++) {
|
|
657
731
|
const temp = this.list[index].run(r);
|
|
658
732
|
if (temp.length !== 0) {
|
|
659
733
|
// match
|
|
734
|
+
if (result === undefined || copy === undefined) {
|
|
735
|
+
result = [];
|
|
736
|
+
copy = this.list.slice();
|
|
737
|
+
}
|
|
660
738
|
result.push(...temp);
|
|
661
739
|
const left = copy;
|
|
662
740
|
left.splice(index, 1);
|
|
@@ -668,7 +746,7 @@ class Permutation {
|
|
|
668
746
|
}
|
|
669
747
|
}
|
|
670
748
|
}
|
|
671
|
-
return result;
|
|
749
|
+
return result !== null && result !== void 0 ? result : EMPTY;
|
|
672
750
|
}
|
|
673
751
|
railroad() {
|
|
674
752
|
const children = this.list.map((e) => { return e.railroad(); });
|
|
@@ -745,17 +823,31 @@ class Alternative {
|
|
|
745
823
|
return this.list.reduce((a, c) => { return a.concat(c.getUsing()); }, []);
|
|
746
824
|
}
|
|
747
825
|
run(r) {
|
|
748
|
-
|
|
826
|
+
var _a;
|
|
827
|
+
// only allocate a new array when more than one alternative matches
|
|
828
|
+
let single = undefined;
|
|
829
|
+
let result = undefined;
|
|
749
830
|
for (const sequ of this.list) {
|
|
750
831
|
const temp = sequ.run(r);
|
|
751
|
-
if (temp.length ===
|
|
752
|
-
|
|
832
|
+
if (temp.length === 0) {
|
|
833
|
+
continue;
|
|
834
|
+
}
|
|
835
|
+
else if (result !== undefined) {
|
|
836
|
+
if (temp.length === 1) {
|
|
837
|
+
result.push(temp[0]);
|
|
838
|
+
}
|
|
839
|
+
else {
|
|
840
|
+
result.push(...temp);
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
else if (single !== undefined) {
|
|
844
|
+
result = single.concat(temp);
|
|
753
845
|
}
|
|
754
846
|
else {
|
|
755
|
-
|
|
847
|
+
single = temp;
|
|
756
848
|
}
|
|
757
849
|
}
|
|
758
|
-
return result;
|
|
850
|
+
return (_a = result !== null && result !== void 0 ? result : single) !== null && _a !== void 0 ? _a : EMPTY;
|
|
759
851
|
}
|
|
760
852
|
railroad() {
|
|
761
853
|
const children = this.list.map((e) => { return e.railroad(); });
|
|
@@ -806,21 +898,13 @@ class AlternativePriority {
|
|
|
806
898
|
return this.list.reduce((a, c) => { return a.concat(c.getUsing()); }, []);
|
|
807
899
|
}
|
|
808
900
|
run(r) {
|
|
809
|
-
const result = [];
|
|
810
901
|
for (const sequ of this.list) {
|
|
811
|
-
// console.log(seq.toStr());
|
|
812
902
|
const temp = sequ.run(r);
|
|
813
903
|
if (temp.length > 0) {
|
|
814
|
-
|
|
815
|
-
result.push(temp[0]);
|
|
816
|
-
}
|
|
817
|
-
else {
|
|
818
|
-
result.push(...temp);
|
|
819
|
-
}
|
|
820
|
-
break;
|
|
904
|
+
return temp;
|
|
821
905
|
}
|
|
822
906
|
}
|
|
823
|
-
return
|
|
907
|
+
return EMPTY;
|
|
824
908
|
}
|
|
825
909
|
railroad() {
|
|
826
910
|
const children = this.list.map((e) => { return e.railroad(); });
|
|
@@ -1026,18 +1110,21 @@ class StopBefore2 {
|
|
|
1026
1110
|
getUsing() { return []; }
|
|
1027
1111
|
run(r) {
|
|
1028
1112
|
var _a;
|
|
1029
|
-
|
|
1030
|
-
|
|
1113
|
+
// only copy when something is filtered out
|
|
1114
|
+
let result = undefined;
|
|
1115
|
+
for (let i = 0; i < r.length; i++) {
|
|
1116
|
+
const input = r[i];
|
|
1031
1117
|
const next = input.peek();
|
|
1032
|
-
if (next === undefined
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1118
|
+
if (next === undefined
|
|
1119
|
+
|| (next.getUpperStr() === this.t1 && ((_a = input.peekAt(1)) === null || _a === void 0 ? void 0 : _a.getUpperStr()) === this.t2)) {
|
|
1120
|
+
if (result === undefined) {
|
|
1121
|
+
result = r.slice(0, i);
|
|
1122
|
+
}
|
|
1036
1123
|
continue;
|
|
1037
1124
|
}
|
|
1038
|
-
result.push(input);
|
|
1125
|
+
result === null || result === void 0 ? void 0 : result.push(input);
|
|
1039
1126
|
}
|
|
1040
|
-
return result;
|
|
1127
|
+
return result !== null && result !== void 0 ? result : r;
|
|
1041
1128
|
}
|
|
1042
1129
|
railroad() { return "Railroad.Terminal('stopBefore(" + this.t1 + " " + this.t2 + ")')"; }
|
|
1043
1130
|
toStr() { return "stopBefore(" + this.t1 + "," + this.t2 + ")"; }
|
|
@@ -1052,15 +1139,20 @@ class StopBefore1 {
|
|
|
1052
1139
|
getUsing() { return []; }
|
|
1053
1140
|
run(r) {
|
|
1054
1141
|
var _a;
|
|
1055
|
-
|
|
1056
|
-
|
|
1142
|
+
// only copy when something is filtered out
|
|
1143
|
+
let result = undefined;
|
|
1144
|
+
for (let i = 0; i < r.length; i++) {
|
|
1145
|
+
const input = r[i];
|
|
1057
1146
|
const next = (_a = input.peek()) === null || _a === void 0 ? void 0 : _a.getUpperStr();
|
|
1058
1147
|
if (next !== undefined && this.words.includes(next)) {
|
|
1148
|
+
if (result === undefined) {
|
|
1149
|
+
result = r.slice(0, i);
|
|
1150
|
+
}
|
|
1059
1151
|
continue;
|
|
1060
1152
|
}
|
|
1061
|
-
result.push(input);
|
|
1153
|
+
result === null || result === void 0 ? void 0 : result.push(input);
|
|
1062
1154
|
}
|
|
1063
|
-
return result;
|
|
1155
|
+
return result !== null && result !== void 0 ? result : r;
|
|
1064
1156
|
}
|
|
1065
1157
|
railroad() { return "Railroad.Terminal('stopBefore(" + this.words.join("|") + ")')"; }
|
|
1066
1158
|
toStr() { return "stopBefore(" + this.words.join(",") + ")"; }
|
|
@@ -124,6 +124,12 @@ class BuiltIn {
|
|
|
124
124
|
}
|
|
125
125
|
return BuiltIn.unnamedArgument.has(name.toUpperCase());
|
|
126
126
|
}
|
|
127
|
+
static returnsArgumentType(name) {
|
|
128
|
+
if (name === undefined) {
|
|
129
|
+
return false;
|
|
130
|
+
}
|
|
131
|
+
return BuiltIn.argumentTypedReturn.has(name.toUpperCase());
|
|
132
|
+
}
|
|
127
133
|
static isPredicate(name) {
|
|
128
134
|
if (name === undefined) {
|
|
129
135
|
return undefined;
|
|
@@ -1231,4 +1237,6 @@ BuiltIn.unnamedArgument = new Set([
|
|
|
1231
1237
|
"FRAC", "LINES", "LOG", "LOG10", "NUMOFCHAR", "SIGN", "SIN", "SINH", "SQRT", "STRLEN", "TAN", "TANH",
|
|
1232
1238
|
"TRUNC", "XSTRLEN"
|
|
1233
1239
|
]);
|
|
1240
|
+
// numeric functions returning a value of the type of the argument
|
|
1241
|
+
BuiltIn.argumentTypedReturn = new Set(["ABS", "CEIL", "FLOOR", "FRAC", "SIGN", "TRUNC"]);
|
|
1234
1242
|
//# sourceMappingURL=_builtin.js.map
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.LoopTableChange = void 0;
|
|
37
|
+
const Expressions = __importStar(require("../2_statements/expressions"));
|
|
38
|
+
const Statements = __importStar(require("../2_statements/statements"));
|
|
39
|
+
const nodes_1 = require("../nodes");
|
|
40
|
+
const basic_1 = require("../types/basic");
|
|
41
|
+
const _scope_type_1 = require("./_scope_type");
|
|
42
|
+
const _syntax_input_1 = require("./_syntax_input");
|
|
43
|
+
/** In a method, the body of the table an enclosing LOOP AT walks cannot be replaced or freed,
|
|
44
|
+
* "you cannot access the entire table body in change mode in a loop. If this is known statically,
|
|
45
|
+
* a syntax error occurs in classes", see the ABAP keyword documentation for LOOP AT itab.
|
|
46
|
+
* Only tables named directly are handled, a field symbol or a reference is a runtime matter. */
|
|
47
|
+
class LoopTableChange {
|
|
48
|
+
constructor() {
|
|
49
|
+
this.tables = [];
|
|
50
|
+
}
|
|
51
|
+
/** returns true if the LOOP structure was pushed, then pop() must be called after it */
|
|
52
|
+
push(node, scope) {
|
|
53
|
+
var _a, _b;
|
|
54
|
+
if (scope.getType() !== _scope_type_1.ScopeType.Method) {
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
const loop = node.findDirectStatement(Statements.Loop);
|
|
58
|
+
if (loop === undefined || loop.findDirectExpression(Expressions.LoopGroupBy) !== undefined) {
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
const chain = (_b = (_a = loop.findDirectExpression(Expressions.LoopSource)) === null || _a === void 0 ? void 0 : _a.findDirectExpression(Expressions.SimpleSource2)) === null || _b === void 0 ? void 0 : _b.findDirectExpression(Expressions.FieldChain);
|
|
62
|
+
const children = (chain === null || chain === void 0 ? void 0 : chain.getChildren()) || [];
|
|
63
|
+
if (children.length !== 1 && !(children.length === 2 && children[1].get() instanceof Expressions.TableBody)) {
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
const found = LoopTableChange.findTable(children[0], scope);
|
|
67
|
+
if (found === undefined) {
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
this.tables.push(found);
|
|
71
|
+
return true;
|
|
72
|
+
}
|
|
73
|
+
pop() {
|
|
74
|
+
this.tables.pop();
|
|
75
|
+
}
|
|
76
|
+
check(node, input) {
|
|
77
|
+
if (this.tables.length === 0 || input.scope.getType() !== _scope_type_1.ScopeType.Method) {
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
// DELETE itab WHERE is not refused, abapGit does it in zcl_abapgit_syntax_xml->order_matches,
|
|
81
|
+
// SORT is left out, it is not certain that it is checked statically
|
|
82
|
+
const s = node.get();
|
|
83
|
+
if (!(s instanceof Statements.Clear)
|
|
84
|
+
&& !(s instanceof Statements.Free)
|
|
85
|
+
&& !(s instanceof Statements.Refresh)
|
|
86
|
+
&& !(s instanceof Statements.Move)) {
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
for (const target of node.findDirectExpressions(Expressions.Target)) {
|
|
90
|
+
const children = target.getChildren();
|
|
91
|
+
const body = children.length === 2 && children[1].get() instanceof Expressions.TableBody;
|
|
92
|
+
if (children.length !== 1 && body === false) {
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
else if (!(children[0].get() instanceof Expressions.TargetField)) {
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
const found = LoopTableChange.findTable(children[0], input.scope);
|
|
99
|
+
if (found === undefined || this.tables.includes(found) === false) {
|
|
100
|
+
continue;
|
|
101
|
+
}
|
|
102
|
+
else if (found.getType().isWithHeader() === true && body === false) {
|
|
103
|
+
// without [] the statement works on the header line
|
|
104
|
+
continue;
|
|
105
|
+
}
|
|
106
|
+
const message = `"${found.getName()}" cannot be changed as a whole inside a LOOP over it`;
|
|
107
|
+
input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message));
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
static findTable(node, scope) {
|
|
112
|
+
var _a;
|
|
113
|
+
if (!(node instanceof nodes_1.ExpressionNode)
|
|
114
|
+
|| node.getChildren().length !== 1
|
|
115
|
+
|| !(((_a = node.getFirstChild()) === null || _a === void 0 ? void 0 : _a.get()) instanceof Expressions.Field)) {
|
|
116
|
+
return undefined;
|
|
117
|
+
}
|
|
118
|
+
const found = scope.findVariable(node.concatTokens());
|
|
119
|
+
if (found === undefined || !(found.getType() instanceof basic_1.TableType)) {
|
|
120
|
+
return undefined;
|
|
121
|
+
}
|
|
122
|
+
return found;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
exports.LoopTableChange = LoopTableChange;
|
|
126
|
+
//# sourceMappingURL=_loop_table_change.js.map
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.substringType = substringType;
|
|
37
|
+
exports.isFieldSymbolItself = isFieldSymbolItself;
|
|
38
|
+
const Expressions = __importStar(require("../../2_statements/expressions"));
|
|
39
|
+
const basic_1 = require("../../types/basic");
|
|
40
|
+
const _syntax_input_1 = require("../_syntax_input");
|
|
41
|
+
// The type of a substring with a static offset or length, used for reading and writing positions.
|
|
42
|
+
// On a character or byte field of fixed length the substring must lie inside the field, else it is
|
|
43
|
+
// a syntax error. Other types, a dynamic offset or length and "*" (undefined) are left alone, as is
|
|
44
|
+
// length 0. The offset is applied first, so the length is compared to what remains after the offset.
|
|
45
|
+
function substringType(context, offset, length, node, input) {
|
|
46
|
+
if (!(context instanceof basic_1.CharacterType) && !(context instanceof basic_1.HexType)) {
|
|
47
|
+
return context;
|
|
48
|
+
}
|
|
49
|
+
const fieldLength = context.getLength();
|
|
50
|
+
if (offset !== undefined && offset > 0) {
|
|
51
|
+
if (offset >= fieldLength) {
|
|
52
|
+
const message = `Offset ${offset} is outside the field of length ${fieldLength}`;
|
|
53
|
+
input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message));
|
|
54
|
+
return basic_1.VoidType.get(_syntax_input_1.CheckSyntaxKey);
|
|
55
|
+
}
|
|
56
|
+
return context instanceof basic_1.CharacterType ? new basic_1.CharacterType(fieldLength - offset) : new basic_1.HexType(fieldLength - offset);
|
|
57
|
+
}
|
|
58
|
+
if (length !== undefined && length > 0) {
|
|
59
|
+
if (length > fieldLength) {
|
|
60
|
+
const message = `Length ${length} exceeds the remaining length ${fieldLength} of the field`;
|
|
61
|
+
input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message));
|
|
62
|
+
return basic_1.VoidType.get(_syntax_input_1.CheckSyntaxKey);
|
|
63
|
+
}
|
|
64
|
+
return context instanceof basic_1.CharacterType ? new basic_1.CharacterType(length) : new basic_1.HexType(length);
|
|
65
|
+
}
|
|
66
|
+
return context;
|
|
67
|
+
}
|
|
68
|
+
// A field symbol typed "c" or "x" is generic, but its type is represented with length 1, so the
|
|
69
|
+
// offset or length at "index" is not checked when it directly follows the field symbol
|
|
70
|
+
function isFieldSymbolItself(children, index) {
|
|
71
|
+
var _a;
|
|
72
|
+
const first = (_a = children[0]) === null || _a === void 0 ? void 0 : _a.get();
|
|
73
|
+
if (!(first instanceof Expressions.SourceFieldSymbol) && !(first instanceof Expressions.TargetFieldSymbol)) {
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
for (let i = 1; i < index; i++) {
|
|
77
|
+
if (!(children[i].get() instanceof Expressions.FieldOffset)) {
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return true;
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=_substring.js.map
|
|
@@ -46,6 +46,7 @@ const attribute_name_1 = require("./attribute_name");
|
|
|
46
46
|
const table_expression_1 = require("./table_expression");
|
|
47
47
|
const field_offset_1 = require("./field_offset");
|
|
48
48
|
const field_length_1 = require("./field_length");
|
|
49
|
+
const _substring_1 = require("./_substring");
|
|
49
50
|
class AttributeChain {
|
|
50
51
|
static runSyntax(inputContext, node, input, type) {
|
|
51
52
|
if (inputContext instanceof void_type_1.VoidType) {
|
|
@@ -122,25 +123,11 @@ class AttributeChain {
|
|
|
122
123
|
}
|
|
123
124
|
else if (child instanceof nodes_1.ExpressionNode && child.get() instanceof Expressions.FieldOffset) {
|
|
124
125
|
const offset = field_offset_1.FieldOffset.runSyntax(child, input);
|
|
125
|
-
|
|
126
|
-
if (contextType instanceof basic_1.CharacterType) {
|
|
127
|
-
contextType = new basic_1.CharacterType(contextType.getLength() - offset);
|
|
128
|
-
}
|
|
129
|
-
else if (contextType instanceof basic_1.HexType) {
|
|
130
|
-
contextType = new basic_1.HexType(contextType.getLength() - offset);
|
|
131
|
-
}
|
|
132
|
-
}
|
|
126
|
+
contextType = (0, _substring_1.substringType)(contextType, offset, undefined, child, input);
|
|
133
127
|
}
|
|
134
128
|
else if (child instanceof nodes_1.ExpressionNode && child.get() instanceof Expressions.FieldLength) {
|
|
135
129
|
const length = field_length_1.FieldLength.runSyntax(child, input);
|
|
136
|
-
|
|
137
|
-
if (contextType instanceof basic_1.CharacterType) {
|
|
138
|
-
contextType = new basic_1.CharacterType(length);
|
|
139
|
-
}
|
|
140
|
-
else if (contextType instanceof basic_1.HexType) {
|
|
141
|
-
contextType = new basic_1.HexType(length);
|
|
142
|
-
}
|
|
143
|
-
}
|
|
130
|
+
contextType = (0, _substring_1.substringType)(contextType, undefined, length, child, input);
|
|
144
131
|
}
|
|
145
132
|
}
|
|
146
133
|
return contextType;
|