@abaplint/core 2.93.98 → 2.94.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/build/src/abap/1_lexer/lexer.js +59 -43
- package/build/src/abap/2_statements/expressions/compare.js +1 -1
- package/build/src/abap/flow/flow_graph.js +18 -6
- package/build/src/abap/flow/statement_flow.js +1 -0
- package/build/src/registry.js +1 -1
- package/build/src/rules/if_in_if.js +22 -6
- package/build/src/rules/index.js +1 -0
- package/build/src/rules/unnecessary_return.js +63 -0
- package/package.json +2 -2
|
@@ -3,15 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.Lexer = void 0;
|
|
4
4
|
const position_1 = require("../../position");
|
|
5
5
|
const tokens_1 = require("./tokens");
|
|
6
|
-
var Mode;
|
|
7
|
-
(function (Mode) {
|
|
8
|
-
Mode[Mode["Normal"] = 0] = "Normal";
|
|
9
|
-
Mode[Mode["Ping"] = 1] = "Ping";
|
|
10
|
-
Mode[Mode["Str"] = 2] = "Str";
|
|
11
|
-
Mode[Mode["Template"] = 3] = "Template";
|
|
12
|
-
Mode[Mode["Comment"] = 4] = "Comment";
|
|
13
|
-
Mode[Mode["Pragma"] = 5] = "Pragma";
|
|
14
|
-
})(Mode || (Mode = {}));
|
|
15
6
|
class Buffer {
|
|
16
7
|
constructor() {
|
|
17
8
|
this.buf = "";
|
|
@@ -61,21 +52,36 @@ class Stream {
|
|
|
61
52
|
return this.row;
|
|
62
53
|
}
|
|
63
54
|
prevChar() {
|
|
55
|
+
if (this.offset - 1 < 0) {
|
|
56
|
+
return "";
|
|
57
|
+
}
|
|
64
58
|
return this.raw.substr(this.offset - 1, 1);
|
|
65
59
|
}
|
|
66
60
|
prevPrevChar() {
|
|
61
|
+
if (this.offset - 2 < 0) {
|
|
62
|
+
return "";
|
|
63
|
+
}
|
|
67
64
|
return this.raw.substr(this.offset - 2, 2);
|
|
68
65
|
}
|
|
69
66
|
currentChar() {
|
|
70
67
|
if (this.offset < 0) {
|
|
71
68
|
return "\n"; // simulate newline at start of file to handle star(*) comments
|
|
72
69
|
}
|
|
70
|
+
else if (this.offset >= this.raw.length) {
|
|
71
|
+
return "";
|
|
72
|
+
}
|
|
73
73
|
return this.raw.substr(this.offset, 1);
|
|
74
74
|
}
|
|
75
75
|
nextChar() {
|
|
76
|
+
if (this.offset + 2 > this.raw.length) {
|
|
77
|
+
return "";
|
|
78
|
+
}
|
|
76
79
|
return this.raw.substr(this.offset + 1, 1);
|
|
77
80
|
}
|
|
78
81
|
nextNextChar() {
|
|
82
|
+
if (this.offset + 3 > this.raw.length) {
|
|
83
|
+
return this.nextChar();
|
|
84
|
+
}
|
|
79
85
|
return this.raw.substr(this.offset + 1, 2);
|
|
80
86
|
}
|
|
81
87
|
getRaw() {
|
|
@@ -86,10 +92,18 @@ class Stream {
|
|
|
86
92
|
}
|
|
87
93
|
}
|
|
88
94
|
class Lexer {
|
|
95
|
+
constructor() {
|
|
96
|
+
this.ModeNormal = 1;
|
|
97
|
+
this.ModePing = 2;
|
|
98
|
+
this.ModeStr = 3;
|
|
99
|
+
this.ModeTemplate = 4;
|
|
100
|
+
this.ModeComment = 5;
|
|
101
|
+
this.ModePragma = 6;
|
|
102
|
+
}
|
|
89
103
|
run(file, virtual) {
|
|
90
104
|
this.virtual = virtual;
|
|
91
105
|
this.tokens = [];
|
|
92
|
-
this.m =
|
|
106
|
+
this.m = this.ModeNormal;
|
|
93
107
|
this.process(file.getRaw());
|
|
94
108
|
return { file, tokens: this.tokens };
|
|
95
109
|
}
|
|
@@ -99,9 +113,11 @@ class Lexer {
|
|
|
99
113
|
const col = this.stream.getCol();
|
|
100
114
|
const row = this.stream.getRow();
|
|
101
115
|
let whiteBefore = false;
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
116
|
+
if (this.stream.getOffset() - s.length >= 0) {
|
|
117
|
+
const prev = this.stream.getRaw().substr(this.stream.getOffset() - s.length, 1);
|
|
118
|
+
if (prev === " " || prev === "\n" || prev === "\t" || prev === ":") {
|
|
119
|
+
whiteBefore = true;
|
|
120
|
+
}
|
|
105
121
|
}
|
|
106
122
|
let whiteAfter = false;
|
|
107
123
|
const next = this.stream.nextChar();
|
|
@@ -113,13 +129,13 @@ class Lexer {
|
|
|
113
129
|
pos = new position_1.VirtualPosition(this.virtual, pos.getRow(), pos.getCol());
|
|
114
130
|
}
|
|
115
131
|
let tok = undefined;
|
|
116
|
-
if (this.m ===
|
|
132
|
+
if (this.m === this.ModeComment) {
|
|
117
133
|
tok = new tokens_1.Comment(pos, s);
|
|
118
134
|
}
|
|
119
|
-
else if (this.m ===
|
|
135
|
+
else if (this.m === this.ModePing || this.m === this.ModeStr) {
|
|
120
136
|
tok = new tokens_1.StringToken(pos, s);
|
|
121
137
|
}
|
|
122
|
-
else if (this.m ===
|
|
138
|
+
else if (this.m === this.ModeTemplate) {
|
|
123
139
|
const first = s.charAt(0);
|
|
124
140
|
const last = s.charAt(s.length - 1);
|
|
125
141
|
if (first === "|" && last === "|") {
|
|
@@ -138,7 +154,7 @@ class Lexer {
|
|
|
138
154
|
tok = new tokens_1.Identifier(pos, s);
|
|
139
155
|
}
|
|
140
156
|
}
|
|
141
|
-
else if (s.substr(0, 2) === "##") {
|
|
157
|
+
else if (s.length > 2 && s.substr(0, 2) === "##") {
|
|
142
158
|
tok = new tokens_1.Pragma(pos, s);
|
|
143
159
|
}
|
|
144
160
|
else if (s.length === 1) {
|
|
@@ -291,39 +307,39 @@ class Lexer {
|
|
|
291
307
|
const ahead = this.stream.nextChar();
|
|
292
308
|
const aahead = this.stream.nextNextChar();
|
|
293
309
|
const prev = this.stream.prevChar();
|
|
294
|
-
if (ahead === "'" && this.m ===
|
|
310
|
+
if (ahead === "'" && this.m === this.ModeNormal) {
|
|
295
311
|
// start string
|
|
296
312
|
this.add();
|
|
297
|
-
this.m =
|
|
313
|
+
this.m = this.ModeStr;
|
|
298
314
|
}
|
|
299
315
|
else if ((ahead === "|" || ahead === "}")
|
|
300
|
-
&& this.m ===
|
|
316
|
+
&& this.m === this.ModeNormal) {
|
|
301
317
|
// start template
|
|
302
318
|
this.add();
|
|
303
|
-
this.m =
|
|
319
|
+
this.m = this.ModeTemplate;
|
|
304
320
|
}
|
|
305
|
-
else if (ahead === "`" && this.m ===
|
|
321
|
+
else if (ahead === "`" && this.m === this.ModeNormal) {
|
|
306
322
|
// start ping
|
|
307
323
|
this.add();
|
|
308
|
-
this.m =
|
|
324
|
+
this.m = this.ModePing;
|
|
309
325
|
}
|
|
310
|
-
else if (aahead === "##" && this.m ===
|
|
326
|
+
else if (aahead === "##" && this.m === this.ModeNormal) {
|
|
311
327
|
// start pragma
|
|
312
328
|
this.add();
|
|
313
|
-
this.m =
|
|
329
|
+
this.m = this.ModePragma;
|
|
314
330
|
}
|
|
315
331
|
else if ((ahead === "\"" || (ahead === "*" && current === "\n"))
|
|
316
|
-
&& this.m ===
|
|
332
|
+
&& this.m === this.ModeNormal) {
|
|
317
333
|
// start comment
|
|
318
334
|
this.add();
|
|
319
|
-
this.m =
|
|
335
|
+
this.m = this.ModeComment;
|
|
320
336
|
}
|
|
321
|
-
else if (this.m ===
|
|
337
|
+
else if (this.m === this.ModePragma && (ahead === "," || ahead === ":" || ahead === "." || ahead === " " || ahead === "\n")) {
|
|
322
338
|
// end of pragma
|
|
323
339
|
this.add();
|
|
324
|
-
this.m =
|
|
340
|
+
this.m = this.ModeNormal;
|
|
325
341
|
}
|
|
326
|
-
else if (this.m ===
|
|
342
|
+
else if (this.m === this.ModePing
|
|
327
343
|
&& buf.length > 1
|
|
328
344
|
&& current === "`"
|
|
329
345
|
&& aahead !== "``"
|
|
@@ -332,21 +348,21 @@ class Lexer {
|
|
|
332
348
|
// end of ping
|
|
333
349
|
this.add();
|
|
334
350
|
if (ahead === `"`) {
|
|
335
|
-
this.m =
|
|
351
|
+
this.m = this.ModeComment;
|
|
336
352
|
}
|
|
337
353
|
else {
|
|
338
|
-
this.m =
|
|
354
|
+
this.m = this.ModeNormal;
|
|
339
355
|
}
|
|
340
356
|
}
|
|
341
|
-
else if (this.m ===
|
|
357
|
+
else if (this.m === this.ModeTemplate
|
|
342
358
|
&& buf.length > 1
|
|
343
359
|
&& (current === "|" || current === "{")
|
|
344
360
|
&& (prev !== "\\" || this.stream.prevPrevChar() === "\\\\")) {
|
|
345
361
|
// end of template
|
|
346
362
|
this.add();
|
|
347
|
-
this.m =
|
|
363
|
+
this.m = this.ModeNormal;
|
|
348
364
|
}
|
|
349
|
-
else if (this.m ===
|
|
365
|
+
else if (this.m === this.ModeStr
|
|
350
366
|
&& current === "'"
|
|
351
367
|
&& buf.length > 1
|
|
352
368
|
&& aahead !== "''"
|
|
@@ -355,13 +371,13 @@ class Lexer {
|
|
|
355
371
|
// end of string
|
|
356
372
|
this.add();
|
|
357
373
|
if (ahead === "\"") {
|
|
358
|
-
this.m =
|
|
374
|
+
this.m = this.ModeComment;
|
|
359
375
|
}
|
|
360
376
|
else {
|
|
361
|
-
this.m =
|
|
377
|
+
this.m = this.ModeNormal;
|
|
362
378
|
}
|
|
363
379
|
}
|
|
364
|
-
else if (this.m ===
|
|
380
|
+
else if (this.m === this.ModeNormal
|
|
365
381
|
&& (ahead === " "
|
|
366
382
|
|| ahead === ":"
|
|
367
383
|
|| ahead === "."
|
|
@@ -379,21 +395,21 @@ class Lexer {
|
|
|
379
395
|
|| ahead === "\n")) {
|
|
380
396
|
this.add();
|
|
381
397
|
}
|
|
382
|
-
else if (ahead === "\n" && this.m !==
|
|
398
|
+
else if (ahead === "\n" && this.m !== this.ModeTemplate) {
|
|
383
399
|
this.add();
|
|
384
|
-
this.m =
|
|
400
|
+
this.m = this.ModeNormal;
|
|
385
401
|
}
|
|
386
|
-
else if (this.m ===
|
|
402
|
+
else if (this.m === this.ModeTemplate && current === "\n") {
|
|
387
403
|
this.add();
|
|
388
404
|
}
|
|
389
405
|
else if (current === ">"
|
|
390
406
|
&& (prev === "-" || prev === "=")
|
|
391
407
|
&& ahead !== " "
|
|
392
|
-
&& this.m ===
|
|
408
|
+
&& this.m === this.ModeNormal) {
|
|
393
409
|
// arrows
|
|
394
410
|
this.add();
|
|
395
411
|
}
|
|
396
|
-
else if (this.m ===
|
|
412
|
+
else if (this.m === this.ModeNormal
|
|
397
413
|
&& (buf === "."
|
|
398
414
|
|| buf === ","
|
|
399
415
|
|| buf === ":"
|
|
@@ -10,7 +10,7 @@ class Compare extends combi_1.Expression {
|
|
|
10
10
|
const val = (0, combi_1.altPrio)(_1.FieldSub, _1.Constant);
|
|
11
11
|
const list = (0, combi_1.seq)((0, combi_1.tok)(tokens_1.WParenLeft), val, (0, combi_1.plus)((0, combi_1.seq)(",", val)), (0, combi_1.tok)(tokens_1.ParenRightW));
|
|
12
12
|
const inn = (0, combi_1.seq)((0, combi_1.optPrio)("NOT"), "IN", (0, combi_1.altPrio)(_1.Source, list));
|
|
13
|
-
const sopt = (0, combi_1.seq)("IS", (0, combi_1.optPrio)("NOT"), (0, combi_1.altPrio)("SUPPLIED", "BOUND", (0, combi_1.ver)(version_1.Version.v750, (0, combi_1.seq)("INSTANCE OF", _1.ClassName)), "REQUESTED", "INITIAL"));
|
|
13
|
+
const sopt = (0, combi_1.seq)("IS", (0, combi_1.optPrio)("NOT"), (0, combi_1.altPrio)("SUPPLIED", "BOUND", (0, combi_1.ver)(version_1.Version.v750, (0, combi_1.seq)("INSTANCE OF", _1.ClassName), version_1.Version.OpenABAP), "REQUESTED", "INITIAL"));
|
|
14
14
|
const between = (0, combi_1.seq)((0, combi_1.optPrio)("NOT"), "BETWEEN", _1.Source, "AND", _1.Source);
|
|
15
15
|
const predicate = (0, combi_1.ver)(version_1.Version.v740sp08, _1.MethodCallChain);
|
|
16
16
|
const rett = (0, combi_1.seq)(_1.Source, (0, combi_1.altPrio)((0, combi_1.seq)(_1.CompareOperator, _1.Source), inn, between, sopt));
|
|
@@ -3,16 +3,16 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.FlowGraph = void 0;
|
|
4
4
|
class FlowGraph {
|
|
5
5
|
constructor(counter) {
|
|
6
|
-
this.label = "undefined";
|
|
7
6
|
this.edges = {};
|
|
8
|
-
this.
|
|
9
|
-
this.
|
|
7
|
+
this.label = "undefined";
|
|
8
|
+
this.startNode = "start#" + counter;
|
|
9
|
+
this.endNode = "end#" + counter;
|
|
10
10
|
}
|
|
11
11
|
getStart() {
|
|
12
|
-
return this.
|
|
12
|
+
return this.startNode;
|
|
13
13
|
}
|
|
14
14
|
getEnd() {
|
|
15
|
-
return this.
|
|
15
|
+
return this.endNode;
|
|
16
16
|
}
|
|
17
17
|
addEdge(from, to) {
|
|
18
18
|
if (this.edges[from] === undefined) {
|
|
@@ -38,6 +38,18 @@ class FlowGraph {
|
|
|
38
38
|
}
|
|
39
39
|
return list;
|
|
40
40
|
}
|
|
41
|
+
listInto(to, skipStart = true) {
|
|
42
|
+
const ret = [];
|
|
43
|
+
for (const e of this.listEdges()) {
|
|
44
|
+
if (skipStart === true && e.from === this.getStart()) {
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
if (e.to === to) {
|
|
48
|
+
ret.push(e.from);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return ret;
|
|
52
|
+
}
|
|
41
53
|
listNodes() {
|
|
42
54
|
const set = new Set();
|
|
43
55
|
for (const l of this.listEdges()) {
|
|
@@ -99,7 +111,7 @@ ${this.toTextEdges()}
|
|
|
99
111
|
}
|
|
100
112
|
return Array.from(set.values());
|
|
101
113
|
}
|
|
102
|
-
/** removes all nodes containing "#" that have one
|
|
114
|
+
/** removes all nodes containing "#" that have one in-going and one out-going edge */
|
|
103
115
|
reduce() {
|
|
104
116
|
for (const node of this.listNodes()) {
|
|
105
117
|
if (node.includes("#") === false) {
|
package/build/src/registry.js
CHANGED
|
@@ -2,10 +2,12 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.IfInIf = exports.IfInIfConf = void 0;
|
|
4
4
|
const issue_1 = require("../issue");
|
|
5
|
+
const Statements = require("../abap/2_statements/statements");
|
|
5
6
|
const Structures = require("../abap/3_structures/structures");
|
|
6
7
|
const _abap_rule_1 = require("./_abap_rule");
|
|
7
8
|
const _basic_rule_config_1 = require("./_basic_rule_config");
|
|
8
9
|
const _irule_1 = require("./_irule");
|
|
10
|
+
const edit_helper_1 = require("../edit_helper");
|
|
9
11
|
class IfInIfConf extends _basic_rule_config_1.BasicRuleConfig {
|
|
10
12
|
}
|
|
11
13
|
exports.IfInIfConf = IfInIfConf;
|
|
@@ -22,7 +24,7 @@ class IfInIf extends _abap_rule_1.ABAPRule {
|
|
|
22
24
|
extendedInformation: `
|
|
23
25
|
Directly nested IFs without ELSE can be refactored to a single condition using AND.
|
|
24
26
|
|
|
25
|
-
ELSE condtions with directly nested IF refactored to ELSEIF.
|
|
27
|
+
ELSE condtions with directly nested IF refactored to ELSEIF, quickfixes are suggested for this case.
|
|
26
28
|
|
|
27
29
|
https://docs.abapopenchecks.org/checks/01/
|
|
28
30
|
https://github.com/SAP/styleguides/blob/main/clean-abap/CleanABAP.md#keep-the-nesting-depth-low`,
|
|
@@ -48,12 +50,9 @@ IF condition1.
|
|
|
48
50
|
ELSEIF condition2.
|
|
49
51
|
...
|
|
50
52
|
ENDIF.`,
|
|
51
|
-
tags: [_irule_1.RuleTag.Styleguide, _irule_1.RuleTag.SingleFile],
|
|
53
|
+
tags: [_irule_1.RuleTag.Styleguide, _irule_1.RuleTag.SingleFile, _irule_1.RuleTag.Quickfix],
|
|
52
54
|
};
|
|
53
55
|
}
|
|
54
|
-
getMessage() {
|
|
55
|
-
return "IF in IF. Use IF cond1 AND cond2 instead";
|
|
56
|
-
}
|
|
57
56
|
getConfig() {
|
|
58
57
|
return this.conf;
|
|
59
58
|
}
|
|
@@ -61,6 +60,7 @@ ENDIF.`,
|
|
|
61
60
|
this.conf = conf;
|
|
62
61
|
}
|
|
63
62
|
runParsed(file, obj) {
|
|
63
|
+
var _a, _b;
|
|
64
64
|
const issues = [];
|
|
65
65
|
if (obj.getType() === "INTF") {
|
|
66
66
|
return [];
|
|
@@ -69,6 +69,7 @@ ENDIF.`,
|
|
|
69
69
|
if (stru === undefined) {
|
|
70
70
|
return [];
|
|
71
71
|
}
|
|
72
|
+
let fixed = false;
|
|
72
73
|
let possible = stru.findAllStructures(Structures.If);
|
|
73
74
|
possible = possible.concat(stru.findAllStructures(Structures.Else));
|
|
74
75
|
for (const i of possible) {
|
|
@@ -94,8 +95,23 @@ ENDIF.`,
|
|
|
94
95
|
|| nestedIf.findDirectStructures(Structures.Else).length > 0)) {
|
|
95
96
|
continue;
|
|
96
97
|
}
|
|
98
|
+
let message = "IF in IF. Use IF cond1 AND cond2 instead";
|
|
99
|
+
let fix = undefined;
|
|
100
|
+
if (i.get() instanceof Structures.Else) {
|
|
101
|
+
message = "Change ELSE part to ELSEIF";
|
|
102
|
+
const els = i.findFirstStatement(Statements.Else);
|
|
103
|
+
const iff = (_a = i.findFirstStructure(Structures.If)) === null || _a === void 0 ? void 0 : _a.findDirectStatement(Statements.If);
|
|
104
|
+
const endif = (_b = i.findFirstStructure(Structures.If)) === null || _b === void 0 ? void 0 : _b.findDirectStatement(Statements.EndIf);
|
|
105
|
+
if (fixed === false && iff && els && endif) {
|
|
106
|
+
const fix1 = edit_helper_1.EditHelper.deleteRange(file, els.getLastToken().getStart(), iff === null || iff === void 0 ? void 0 : iff.getFirstToken().getStart());
|
|
107
|
+
const fix2 = edit_helper_1.EditHelper.deleteStatement(file, endif);
|
|
108
|
+
fix = edit_helper_1.EditHelper.merge(fix1, fix2);
|
|
109
|
+
// max one fix per file at a time
|
|
110
|
+
fixed = true;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
97
113
|
const token = i.getFirstToken();
|
|
98
|
-
const issue = issue_1.Issue.atToken(file, token,
|
|
114
|
+
const issue = issue_1.Issue.atToken(file, token, message, this.getMetadata().key, this.conf.severity, fix);
|
|
99
115
|
issues.push(issue);
|
|
100
116
|
}
|
|
101
117
|
return issues;
|
package/build/src/rules/index.js
CHANGED
|
@@ -151,6 +151,7 @@ __exportStar(require("./uncaught_exception"), exports);
|
|
|
151
151
|
__exportStar(require("./unknown_types"), exports);
|
|
152
152
|
__exportStar(require("./unnecessary_chaining"), exports);
|
|
153
153
|
__exportStar(require("./unnecessary_pragma"), exports);
|
|
154
|
+
__exportStar(require("./unnecessary_return"), exports);
|
|
154
155
|
__exportStar(require("./unreachable_code"), exports);
|
|
155
156
|
__exportStar(require("./unsecure_fae"), exports);
|
|
156
157
|
__exportStar(require("./unused_ddic"), exports);
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.UnnecessaryReturn = exports.UnnecessaryReturnConf = void 0;
|
|
4
|
+
const issue_1 = require("../issue");
|
|
5
|
+
const _abap_rule_1 = require("./_abap_rule");
|
|
6
|
+
const _basic_rule_config_1 = require("./_basic_rule_config");
|
|
7
|
+
const _irule_1 = require("./_irule");
|
|
8
|
+
const Statements = require("../abap/2_statements/statements");
|
|
9
|
+
const edit_helper_1 = require("../edit_helper");
|
|
10
|
+
class UnnecessaryReturnConf extends _basic_rule_config_1.BasicRuleConfig {
|
|
11
|
+
}
|
|
12
|
+
exports.UnnecessaryReturnConf = UnnecessaryReturnConf;
|
|
13
|
+
class UnnecessaryReturn extends _abap_rule_1.ABAPRule {
|
|
14
|
+
constructor() {
|
|
15
|
+
super(...arguments);
|
|
16
|
+
this.conf = new UnnecessaryReturnConf();
|
|
17
|
+
}
|
|
18
|
+
getMetadata() {
|
|
19
|
+
return {
|
|
20
|
+
key: "unnecessary_return",
|
|
21
|
+
title: "Unnecessary Return",
|
|
22
|
+
shortDescription: `Finds unnecessary RETURN statements`,
|
|
23
|
+
extendedInformation: `Finds unnecessary RETURN statements`,
|
|
24
|
+
tags: [_irule_1.RuleTag.SingleFile, _irule_1.RuleTag.Quickfix],
|
|
25
|
+
badExample: `METHOD hello.
|
|
26
|
+
...
|
|
27
|
+
RETURN.
|
|
28
|
+
ENDMETHOD.`,
|
|
29
|
+
goodExample: `METHOD hello.
|
|
30
|
+
...
|
|
31
|
+
ENDMETHOD.`,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
getConfig() {
|
|
35
|
+
return this.conf;
|
|
36
|
+
}
|
|
37
|
+
setConfig(conf) {
|
|
38
|
+
this.conf = conf;
|
|
39
|
+
}
|
|
40
|
+
runParsed(file) {
|
|
41
|
+
const issues = [];
|
|
42
|
+
const structure = file.getStructure();
|
|
43
|
+
if (structure === undefined) {
|
|
44
|
+
return [];
|
|
45
|
+
}
|
|
46
|
+
const statements = file.getStatements();
|
|
47
|
+
for (let i = 0; i < statements.length - 1; i++) {
|
|
48
|
+
const node = statements[i];
|
|
49
|
+
const next = statements[i + 1];
|
|
50
|
+
if (node.get() instanceof Statements.Return
|
|
51
|
+
&& (next.get() instanceof Statements.EndMethod
|
|
52
|
+
|| next.get() instanceof Statements.EndForm
|
|
53
|
+
|| next.get() instanceof Statements.EndFunction)) {
|
|
54
|
+
const message = "Unnecessary RETURN";
|
|
55
|
+
const fix = edit_helper_1.EditHelper.deleteStatement(file, node);
|
|
56
|
+
issues.push(issue_1.Issue.atStatement(file, node, message, this.getMetadata().key, this.getConfig().severity, fix));
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return issues;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
exports.UnnecessaryReturn = UnnecessaryReturn;
|
|
63
|
+
//# sourceMappingURL=unnecessary_return.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@abaplint/core",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.94.0",
|
|
4
4
|
"description": "abaplint - Core API",
|
|
5
5
|
"main": "build/src/index.js",
|
|
6
6
|
"typings": "build/abaplint.d.ts",
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
"devDependencies": {
|
|
49
49
|
"@microsoft/api-extractor": "^7.33.6",
|
|
50
50
|
"@types/chai": "^4.3.4",
|
|
51
|
-
"@types/mocha": "^10.0.
|
|
51
|
+
"@types/mocha": "^10.0.1",
|
|
52
52
|
"@types/node": "^18.11.9",
|
|
53
53
|
"chai": "^4.3.7",
|
|
54
54
|
"eslint": "^8.28.0",
|