@abaplint/core 2.92.2 → 2.93.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/abaplint.d.ts +15 -0
- package/build/src/abap/5_syntax/expressions/field_chain.js +4 -1
- package/build/src/cds/cds_lexer.js +27 -18
- package/build/src/cds/cds_parser.js +6 -1
- package/build/src/cds/expressions/cds_annotate.js +12 -0
- package/build/src/cds/expressions/index.js +1 -0
- package/build/src/objects/cds_metadata_extension.js +27 -0
- package/build/src/objects/data_definition.js +1 -1
- package/build/src/registry.js +1 -1
- package/build/src/rules/cds_comment_style.js +58 -0
- package/build/src/rules/cds_parser_error.js +7 -6
- package/build/src/rules/change_if_to_case.js +125 -0
- package/build/src/rules/constant_classes.js +1 -1
- package/build/src/rules/index.js +6 -4
- package/package.json +2 -2
package/build/abaplint.d.ts
CHANGED
|
@@ -572,6 +572,10 @@ declare class CDSAggregate extends Expression {
|
|
|
572
572
|
getRunnable(): IStatementRunnable;
|
|
573
573
|
}
|
|
574
574
|
|
|
575
|
+
declare class CDSAnnotate extends Expression {
|
|
576
|
+
getRunnable(): IStatementRunnable;
|
|
577
|
+
}
|
|
578
|
+
|
|
575
579
|
declare class CDSAnnotation extends Expression {
|
|
576
580
|
getRunnable(): IStatementRunnable;
|
|
577
581
|
}
|
|
@@ -649,12 +653,17 @@ declare class CDSJoin extends Expression {
|
|
|
649
653
|
}
|
|
650
654
|
|
|
651
655
|
declare class CDSMetadataExtension extends AbstractObject {
|
|
656
|
+
private parserError;
|
|
657
|
+
private parsedData;
|
|
652
658
|
getType(): string;
|
|
653
659
|
getAllowedNaming(): {
|
|
654
660
|
maxLength: number;
|
|
655
661
|
allowNamespace: boolean;
|
|
656
662
|
};
|
|
663
|
+
hasParserError(): boolean | undefined;
|
|
664
|
+
parse(): IParseResult;
|
|
657
665
|
getDescription(): string | undefined;
|
|
666
|
+
findSourceFile(): IFile | undefined;
|
|
658
667
|
}
|
|
659
668
|
|
|
660
669
|
declare class CDSName extends Expression {
|
|
@@ -2015,6 +2024,7 @@ export { Expressions }
|
|
|
2015
2024
|
declare namespace ExpressionsCDS {
|
|
2016
2025
|
export {
|
|
2017
2026
|
CDSAggregate,
|
|
2027
|
+
CDSAnnotate,
|
|
2018
2028
|
CDSAnnotationArray,
|
|
2019
2029
|
CDSAnnotationObject,
|
|
2020
2030
|
CDSAnnotationSimple,
|
|
@@ -3985,6 +3995,7 @@ declare namespace Objects {
|
|
|
3985
3995
|
BusinessFunctionAssignment,
|
|
3986
3996
|
BusinessFunctionSetAssignment,
|
|
3987
3997
|
BusinessObjectModel,
|
|
3998
|
+
ParsedMetadataExtension,
|
|
3988
3999
|
CDSMetadataExtension,
|
|
3989
4000
|
ChangeDocument,
|
|
3990
4001
|
ChapterOfBookStructure,
|
|
@@ -4229,6 +4240,10 @@ declare type ParsedDataDefinition = {
|
|
|
4229
4240
|
tree: ExpressionNode | undefined;
|
|
4230
4241
|
};
|
|
4231
4242
|
|
|
4243
|
+
declare type ParsedMetadataExtension = {
|
|
4244
|
+
tree: ExpressionNode | undefined;
|
|
4245
|
+
};
|
|
4246
|
+
|
|
4232
4247
|
declare class PassByValue extends Expression {
|
|
4233
4248
|
getRunnable(): IStatementRunnable;
|
|
4234
4249
|
}
|
|
@@ -36,7 +36,10 @@ class FieldChain {
|
|
|
36
36
|
if (current === undefined) {
|
|
37
37
|
break;
|
|
38
38
|
}
|
|
39
|
-
if (current.get() instanceof tokens_1.
|
|
39
|
+
if (current.get() instanceof tokens_1.DashW) {
|
|
40
|
+
throw new Error("Ending with dash");
|
|
41
|
+
}
|
|
42
|
+
else if (current.get() instanceof tokens_1.Dash) {
|
|
40
43
|
if (context instanceof basic_1.UnknownType) {
|
|
41
44
|
throw new Error("Not a structure, type unknown, FieldChain");
|
|
42
45
|
}
|
|
@@ -22,13 +22,25 @@ class Stream {
|
|
|
22
22
|
return this.buffer.length;
|
|
23
23
|
}
|
|
24
24
|
}
|
|
25
|
+
var Mode;
|
|
26
|
+
(function (Mode) {
|
|
27
|
+
Mode[Mode["Default"] = 0] = "Default";
|
|
28
|
+
Mode[Mode["String"] = 1] = "String";
|
|
29
|
+
Mode[Mode["SingleLineComment"] = 2] = "SingleLineComment";
|
|
30
|
+
Mode[Mode["MultiLineComment"] = 3] = "MultiLineComment";
|
|
31
|
+
})(Mode || (Mode = {}));
|
|
25
32
|
class Result {
|
|
26
33
|
constructor() {
|
|
27
34
|
this.result = [];
|
|
28
35
|
}
|
|
29
|
-
add(text, row, col) {
|
|
36
|
+
add(text, row, col, mode) {
|
|
30
37
|
if (text.length > 0) {
|
|
31
|
-
|
|
38
|
+
if (mode === Mode.SingleLineComment) {
|
|
39
|
+
this.result.push(new tokens_1.Comment(new position_1.Position(row, col), text));
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
this.result.push(new tokens_1.Identifier(new position_1.Position(row, col), text));
|
|
43
|
+
}
|
|
32
44
|
}
|
|
33
45
|
return "";
|
|
34
46
|
}
|
|
@@ -36,13 +48,6 @@ class Result {
|
|
|
36
48
|
return this.result;
|
|
37
49
|
}
|
|
38
50
|
}
|
|
39
|
-
var Mode;
|
|
40
|
-
(function (Mode) {
|
|
41
|
-
Mode[Mode["Default"] = 0] = "Default";
|
|
42
|
-
Mode[Mode["String"] = 1] = "String";
|
|
43
|
-
Mode[Mode["SingleLineComment"] = 2] = "SingleLineComment";
|
|
44
|
-
Mode[Mode["MultiLineComment"] = 3] = "MultiLineComment";
|
|
45
|
-
})(Mode || (Mode = {}));
|
|
46
51
|
class CDSLexer {
|
|
47
52
|
static run(file) {
|
|
48
53
|
const result = new Result();
|
|
@@ -61,7 +66,7 @@ class CDSLexer {
|
|
|
61
66
|
if (mode === Mode.String) {
|
|
62
67
|
build += next;
|
|
63
68
|
if (next === "'") {
|
|
64
|
-
build = result.add(build, row, col);
|
|
69
|
+
build = result.add(build, row, col, mode);
|
|
65
70
|
mode = Mode.Default;
|
|
66
71
|
}
|
|
67
72
|
continue;
|
|
@@ -69,20 +74,24 @@ class CDSLexer {
|
|
|
69
74
|
// single line comment handling
|
|
70
75
|
if (mode === Mode.SingleLineComment) {
|
|
71
76
|
if (next === "\n") {
|
|
77
|
+
build = result.add(build, row, col, mode);
|
|
72
78
|
mode = Mode.Default;
|
|
73
79
|
}
|
|
74
80
|
else {
|
|
81
|
+
build += next;
|
|
75
82
|
continue;
|
|
76
83
|
}
|
|
77
84
|
}
|
|
78
85
|
else if (mode === Mode.Default && next === "/" && nextNext === "/") {
|
|
79
86
|
mode = Mode.SingleLineComment;
|
|
80
|
-
build = result.add(build, row, col);
|
|
87
|
+
build = result.add(build, row, col, mode);
|
|
88
|
+
build += next;
|
|
81
89
|
continue;
|
|
82
90
|
}
|
|
83
91
|
else if (mode === Mode.Default && next === "-" && nextNext === "-") {
|
|
84
92
|
mode = Mode.SingleLineComment;
|
|
85
|
-
build = result.add(build, row, col);
|
|
93
|
+
build = result.add(build, row, col, mode);
|
|
94
|
+
build += next;
|
|
86
95
|
continue;
|
|
87
96
|
}
|
|
88
97
|
// multi line comment handling
|
|
@@ -97,7 +106,7 @@ class CDSLexer {
|
|
|
97
106
|
}
|
|
98
107
|
else if (mode === Mode.Default && next === "/" && nextNext === "*") {
|
|
99
108
|
mode = Mode.MultiLineComment;
|
|
100
|
-
build = result.add(build, row, col);
|
|
109
|
+
build = result.add(build, row, col, mode);
|
|
101
110
|
continue;
|
|
102
111
|
}
|
|
103
112
|
switch (next) {
|
|
@@ -106,10 +115,10 @@ class CDSLexer {
|
|
|
106
115
|
build += next;
|
|
107
116
|
break;
|
|
108
117
|
case " ":
|
|
109
|
-
build = result.add(build, row, col);
|
|
118
|
+
build = result.add(build, row, col, mode);
|
|
110
119
|
break;
|
|
111
120
|
case "\n":
|
|
112
|
-
build = result.add(build, row, col);
|
|
121
|
+
build = result.add(build, row, col, mode);
|
|
113
122
|
row++;
|
|
114
123
|
col = 0;
|
|
115
124
|
break;
|
|
@@ -130,15 +139,15 @@ class CDSLexer {
|
|
|
130
139
|
case "-":
|
|
131
140
|
case "*":
|
|
132
141
|
case "/":
|
|
133
|
-
build = result.add(build, row, col);
|
|
134
|
-
result.add(next, row, col);
|
|
142
|
+
build = result.add(build, row, col, mode);
|
|
143
|
+
result.add(next, row, col, mode);
|
|
135
144
|
break;
|
|
136
145
|
default:
|
|
137
146
|
build += next;
|
|
138
147
|
break;
|
|
139
148
|
}
|
|
140
149
|
}
|
|
141
|
-
result.add(build, row, col);
|
|
150
|
+
result.add(build, row, col, mode);
|
|
142
151
|
return result.get();
|
|
143
152
|
}
|
|
144
153
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.CDSParser = void 0;
|
|
4
|
+
const tokens_1 = require("../abap/1_lexer/tokens");
|
|
4
5
|
const combi_1 = require("../abap/2_statements/combi");
|
|
5
6
|
const nodes_1 = require("../abap/nodes");
|
|
6
7
|
const version_1 = require("../version");
|
|
@@ -12,7 +13,8 @@ class CDSParser {
|
|
|
12
13
|
if (file === undefined) {
|
|
13
14
|
return undefined;
|
|
14
15
|
}
|
|
15
|
-
|
|
16
|
+
let tokens = cds_lexer_1.CDSLexer.run(file);
|
|
17
|
+
tokens = tokens.filter(t => !(t instanceof tokens_1.Comment));
|
|
16
18
|
// console.dir(tokens);
|
|
17
19
|
let res = combi_1.Combi.run(new Expressions.CDSDefineView(), tokens, version_1.defaultVersion);
|
|
18
20
|
if (res === undefined || !(res[0] instanceof nodes_1.ExpressionNode)) {
|
|
@@ -21,6 +23,9 @@ class CDSParser {
|
|
|
21
23
|
if (res === undefined || !(res[0] instanceof nodes_1.ExpressionNode)) {
|
|
22
24
|
res = combi_1.Combi.run(new Expressions.CDSDefineProjection(), tokens, version_1.defaultVersion);
|
|
23
25
|
}
|
|
26
|
+
if (res === undefined || !(res[0] instanceof nodes_1.ExpressionNode)) {
|
|
27
|
+
res = combi_1.Combi.run(new Expressions.CDSAnnotate(), tokens, version_1.defaultVersion);
|
|
28
|
+
}
|
|
24
29
|
if (res === undefined || !(res[0] instanceof nodes_1.ExpressionNode)) {
|
|
25
30
|
return undefined;
|
|
26
31
|
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CDSAnnotate = void 0;
|
|
4
|
+
const _1 = require(".");
|
|
5
|
+
const combi_1 = require("../../abap/2_statements/combi");
|
|
6
|
+
class CDSAnnotate extends combi_1.Expression {
|
|
7
|
+
getRunnable() {
|
|
8
|
+
return (0, combi_1.seq)((0, combi_1.star)(_1.CDSAnnotation), "ANNOTATE", (0, combi_1.alt)("ENTITY", "VIEW"), _1.CDSName, "WITH", (0, combi_1.str)("{"), (0, combi_1.plus)((0, combi_1.seq)(_1.CDSElement, ";")), (0, combi_1.str)("}"), (0, combi_1.opt)(";"));
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
exports.CDSAnnotate = CDSAnnotate;
|
|
12
|
+
//# sourceMappingURL=cds_annotate.js.map
|
|
@@ -16,6 +16,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
__exportStar(require("./cds_aggregate"), exports);
|
|
18
18
|
__exportStar(require("./cds_aggregate"), exports);
|
|
19
|
+
__exportStar(require("./cds_annotate"), exports);
|
|
19
20
|
__exportStar(require("./cds_annotation_array"), exports);
|
|
20
21
|
__exportStar(require("./cds_annotation_object"), exports);
|
|
21
22
|
__exportStar(require("./cds_annotation_simple"), exports);
|
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.CDSMetadataExtension = void 0;
|
|
4
|
+
const cds_parser_1 = require("../cds/cds_parser");
|
|
4
5
|
const _abstract_object_1 = require("./_abstract_object");
|
|
5
6
|
class CDSMetadataExtension extends _abstract_object_1.AbstractObject {
|
|
7
|
+
constructor() {
|
|
8
|
+
super(...arguments);
|
|
9
|
+
this.parserError = undefined;
|
|
10
|
+
this.parsedData = undefined;
|
|
11
|
+
}
|
|
6
12
|
getType() {
|
|
7
13
|
return "DDLX";
|
|
8
14
|
}
|
|
@@ -12,10 +18,31 @@ class CDSMetadataExtension extends _abstract_object_1.AbstractObject {
|
|
|
12
18
|
allowNamespace: true,
|
|
13
19
|
};
|
|
14
20
|
}
|
|
21
|
+
hasParserError() {
|
|
22
|
+
return this.parserError;
|
|
23
|
+
}
|
|
24
|
+
parse() {
|
|
25
|
+
if (this.isDirty() === false) {
|
|
26
|
+
return { updated: false, runtime: 0 };
|
|
27
|
+
}
|
|
28
|
+
const start = Date.now();
|
|
29
|
+
this.parsedData = {
|
|
30
|
+
tree: undefined,
|
|
31
|
+
};
|
|
32
|
+
this.parsedData.tree = new cds_parser_1.CDSParser().parse(this.findSourceFile());
|
|
33
|
+
if (this.parsedData.tree === undefined) {
|
|
34
|
+
this.parserError = true;
|
|
35
|
+
}
|
|
36
|
+
this.dirty = false;
|
|
37
|
+
return { updated: true, runtime: Date.now() - start };
|
|
38
|
+
}
|
|
15
39
|
getDescription() {
|
|
16
40
|
// todo
|
|
17
41
|
return undefined;
|
|
18
42
|
}
|
|
43
|
+
findSourceFile() {
|
|
44
|
+
return this.getFiles().find(f => f.getFilename().endsWith(".asddlxs") || f.getFilename().endsWith(".acds"));
|
|
45
|
+
}
|
|
19
46
|
}
|
|
20
47
|
exports.CDSMetadataExtension = CDSMetadataExtension;
|
|
21
48
|
//# sourceMappingURL=cds_metadata_extension.js.map
|
|
@@ -52,7 +52,7 @@ class DataDefinition extends _abstract_object_1.AbstractObject {
|
|
|
52
52
|
super.setDirty();
|
|
53
53
|
}
|
|
54
54
|
findSourceFile() {
|
|
55
|
-
return this.getFiles().find(f => f.getFilename().endsWith(".asddls"));
|
|
55
|
+
return this.getFiles().find(f => f.getFilename().endsWith(".asddls") || f.getFilename().endsWith(".acds"));
|
|
56
56
|
}
|
|
57
57
|
hasParserError() {
|
|
58
58
|
return this.parserError;
|
package/build/src/registry.js
CHANGED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CDSCommentStyle = exports.CDSCommentStyleConf = void 0;
|
|
4
|
+
const issue_1 = require("../issue");
|
|
5
|
+
const _irule_1 = require("./_irule");
|
|
6
|
+
const _basic_rule_config_1 = require("./_basic_rule_config");
|
|
7
|
+
const objects_1 = require("../objects");
|
|
8
|
+
const cds_lexer_1 = require("../cds/cds_lexer");
|
|
9
|
+
const tokens_1 = require("../abap/1_lexer/tokens");
|
|
10
|
+
class CDSCommentStyleConf extends _basic_rule_config_1.BasicRuleConfig {
|
|
11
|
+
}
|
|
12
|
+
exports.CDSCommentStyleConf = CDSCommentStyleConf;
|
|
13
|
+
class CDSCommentStyle {
|
|
14
|
+
constructor() {
|
|
15
|
+
this.conf = new CDSCommentStyleConf();
|
|
16
|
+
}
|
|
17
|
+
getMetadata() {
|
|
18
|
+
return {
|
|
19
|
+
key: "cds_comment_style",
|
|
20
|
+
title: "CDS Comment Style",
|
|
21
|
+
shortDescription: `Check for obsolete comment style`,
|
|
22
|
+
extendedInformation: `Check for obsolete comment style
|
|
23
|
+
|
|
24
|
+
https://help.sap.com/doc/abapdocu_752_index_htm/7.52/en-us/abencds_general_syntax_rules.htm`,
|
|
25
|
+
tags: [_irule_1.RuleTag.SingleFile],
|
|
26
|
+
badExample: "-- this is a comment",
|
|
27
|
+
goodExample: "// this is a comment",
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
getConfig() {
|
|
31
|
+
return this.conf;
|
|
32
|
+
}
|
|
33
|
+
setConfig(conf) {
|
|
34
|
+
this.conf = conf;
|
|
35
|
+
}
|
|
36
|
+
initialize(_reg) {
|
|
37
|
+
return this;
|
|
38
|
+
}
|
|
39
|
+
run(object) {
|
|
40
|
+
const issues = [];
|
|
41
|
+
if ((object.getType() === "DDLS" && object instanceof objects_1.DataDefinition) ||
|
|
42
|
+
(object.getType() === "DDLX" && object instanceof objects_1.CDSMetadataExtension)) {
|
|
43
|
+
const file = object.findSourceFile();
|
|
44
|
+
if (file === undefined) {
|
|
45
|
+
return issues;
|
|
46
|
+
}
|
|
47
|
+
const tokens = cds_lexer_1.CDSLexer.run(file);
|
|
48
|
+
for (const t of tokens) {
|
|
49
|
+
if (t instanceof tokens_1.Comment && t.getStr().startsWith("--")) {
|
|
50
|
+
issues.push(issue_1.Issue.atToken(file, t, `Use "//" for comments instead of "--"`, this.getMetadata().key, this.getConfig().severity));
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return issues;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
exports.CDSCommentStyle = CDSCommentStyle;
|
|
58
|
+
//# sourceMappingURL=cds_comment_style.js.map
|
|
@@ -16,8 +16,8 @@ class CDSParserError {
|
|
|
16
16
|
return {
|
|
17
17
|
key: "cds_parser_error",
|
|
18
18
|
title: "CDS Parser Error",
|
|
19
|
-
shortDescription: `CDS parsing
|
|
20
|
-
extendedInformation:
|
|
19
|
+
shortDescription: `CDS parsing`,
|
|
20
|
+
extendedInformation: `Parses CDS and issues parser errors`,
|
|
21
21
|
tags: [_irule_1.RuleTag.Syntax],
|
|
22
22
|
};
|
|
23
23
|
}
|
|
@@ -30,11 +30,12 @@ class CDSParserError {
|
|
|
30
30
|
initialize(_reg) {
|
|
31
31
|
return this;
|
|
32
32
|
}
|
|
33
|
-
run(
|
|
33
|
+
run(object) {
|
|
34
34
|
const issues = [];
|
|
35
|
-
if (
|
|
36
|
-
|
|
37
|
-
const
|
|
35
|
+
if ((object.getType() === "DDLS" && object instanceof objects_1.DataDefinition) ||
|
|
36
|
+
(object.getType() === "DDLX" && object instanceof objects_1.CDSMetadataExtension)) {
|
|
37
|
+
const hasError = object.hasParserError();
|
|
38
|
+
const file = object.findSourceFile();
|
|
38
39
|
if (hasError === true && file) {
|
|
39
40
|
issues.push(issue_1.Issue.atRow(file, 1, "CDS Parser error", this.getMetadata().key, this.getConfig().severity));
|
|
40
41
|
}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ChangeIfToCase = exports.ChangeIfToCaseConf = void 0;
|
|
4
|
+
const issue_1 = require("../issue");
|
|
5
|
+
const Expressions = require("../abap/2_statements/expressions");
|
|
6
|
+
const Statements = require("../abap/2_statements/statements");
|
|
7
|
+
const Structures = require("../abap/3_structures/structures");
|
|
8
|
+
const _abap_rule_1 = require("./_abap_rule");
|
|
9
|
+
const _basic_rule_config_1 = require("./_basic_rule_config");
|
|
10
|
+
const _irule_1 = require("./_irule");
|
|
11
|
+
class ChangeIfToCaseConf extends _basic_rule_config_1.BasicRuleConfig {
|
|
12
|
+
}
|
|
13
|
+
exports.ChangeIfToCaseConf = ChangeIfToCaseConf;
|
|
14
|
+
class ChangeIfToCase extends _abap_rule_1.ABAPRule {
|
|
15
|
+
constructor() {
|
|
16
|
+
super(...arguments);
|
|
17
|
+
this.conf = new ChangeIfToCaseConf();
|
|
18
|
+
}
|
|
19
|
+
getMetadata() {
|
|
20
|
+
return {
|
|
21
|
+
key: "change_if_to_case",
|
|
22
|
+
title: "Change IF to CASE",
|
|
23
|
+
shortDescription: `Finds IF constructs that can be changed to CASE`,
|
|
24
|
+
// eslint-disable-next-line max-len
|
|
25
|
+
extendedInformation: `https://github.com/SAP/styleguides/blob/main/clean-abap/CleanABAP.md#prefer-case-to-else-if-for-multiple-alternative-conditions`,
|
|
26
|
+
tags: [_irule_1.RuleTag.SingleFile, _irule_1.RuleTag.Styleguide],
|
|
27
|
+
badExample: `IF l_fcat-fieldname EQ 'FOO'.
|
|
28
|
+
ELSEIF l_fcat-fieldname = 'BAR'
|
|
29
|
+
OR l_fcat-fieldname = 'MOO'.
|
|
30
|
+
ENDIF.`,
|
|
31
|
+
goodExample: `CASE l_fcat-fieldname.
|
|
32
|
+
WHEN 'FOO.
|
|
33
|
+
WHEN 'BAR' OR MOO.
|
|
34
|
+
ENDCASE.`,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
getConfig() {
|
|
38
|
+
return this.conf;
|
|
39
|
+
}
|
|
40
|
+
setConfig(conf) {
|
|
41
|
+
this.conf = conf;
|
|
42
|
+
}
|
|
43
|
+
runParsed(file) {
|
|
44
|
+
var _a;
|
|
45
|
+
const issues = [];
|
|
46
|
+
const stru = file.getStructure();
|
|
47
|
+
if (stru === undefined) {
|
|
48
|
+
return issues;
|
|
49
|
+
}
|
|
50
|
+
for (const i of stru.findAllStructuresRecursive(Structures.If)) {
|
|
51
|
+
const conds = [];
|
|
52
|
+
const ifStatement = i.findDirectStatement(Statements.If);
|
|
53
|
+
if (ifStatement === undefined) {
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
conds.push(ifStatement === null || ifStatement === void 0 ? void 0 : ifStatement.findDirectExpression(Expressions.Cond));
|
|
57
|
+
for (const ei of i.findDirectStructures(Structures.ElseIf)) {
|
|
58
|
+
conds.push((_a = ei.findDirectStatement(Statements.ElseIf)) === null || _a === void 0 ? void 0 : _a.findDirectExpression(Expressions.Cond));
|
|
59
|
+
}
|
|
60
|
+
if (conds.length === 1) {
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
const issue = this.analyze(conds);
|
|
64
|
+
if (issue === true) {
|
|
65
|
+
const message = "Change IF to CASE";
|
|
66
|
+
issues.push(issue_1.Issue.atStatement(file, ifStatement, message, this.getMetadata().key, this.getConfig().severity));
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return issues;
|
|
70
|
+
}
|
|
71
|
+
analyze(conds) {
|
|
72
|
+
var _a, _b, _c, _d, _e;
|
|
73
|
+
const tuples = [];
|
|
74
|
+
for (const c of conds) {
|
|
75
|
+
if (c === undefined) {
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
if (c.findFirstExpression(Expressions.CondSub)) {
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
else if (c.findDirectTokenByText("AND") || c.findDirectTokenByText("EQUIV")) {
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
for (const compare of c.findAllExpressions(Expressions.Compare)) {
|
|
85
|
+
const op = (_a = compare.findDirectExpression(Expressions.CompareOperator)) === null || _a === void 0 ? void 0 : _a.concatTokens().toUpperCase();
|
|
86
|
+
if (compare.getChildren().length !== 3) {
|
|
87
|
+
return false;
|
|
88
|
+
}
|
|
89
|
+
else if (op !== "=" && op !== "EQ") {
|
|
90
|
+
return false;
|
|
91
|
+
}
|
|
92
|
+
const left = (_c = (_b = compare.getChildren()[0]) === null || _b === void 0 ? void 0 : _b.concatTokens()) === null || _c === void 0 ? void 0 : _c.toUpperCase();
|
|
93
|
+
const right = (_e = (_d = compare.getChildren()[2]) === null || _d === void 0 ? void 0 : _d.concatTokens()) === null || _e === void 0 ? void 0 : _e.toUpperCase();
|
|
94
|
+
tuples.push({ left, right });
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
if (tuples.length === 1) {
|
|
98
|
+
return false;
|
|
99
|
+
}
|
|
100
|
+
let chain = "";
|
|
101
|
+
if (tuples[0].left === tuples[1].left) {
|
|
102
|
+
chain = tuples[0].left;
|
|
103
|
+
}
|
|
104
|
+
else if (tuples[0].left === tuples[1].right) {
|
|
105
|
+
chain = tuples[0].left;
|
|
106
|
+
}
|
|
107
|
+
else if (tuples[0].right === tuples[1].right) {
|
|
108
|
+
chain = tuples[0].right;
|
|
109
|
+
}
|
|
110
|
+
else if (tuples[0].right === tuples[1].left) {
|
|
111
|
+
chain = tuples[0].right;
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
return false;
|
|
115
|
+
}
|
|
116
|
+
for (const t of tuples) {
|
|
117
|
+
if (t.left !== chain && t.right !== chain) {
|
|
118
|
+
return false;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return true;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
exports.ChangeIfToCase = ChangeIfToCase;
|
|
125
|
+
//# sourceMappingURL=change_if_to_case.js.map
|
|
@@ -24,7 +24,7 @@ class ConstantClasses {
|
|
|
24
24
|
title: "Validate constant classes",
|
|
25
25
|
shortDescription: `Checks that a class contains exactly the constants corresponding to a domain's fixed values.`,
|
|
26
26
|
extendedInformation: `https://github.com/SAP/styleguides/blob/main/clean-abap/CleanABAP.md#prefer-enumeration-classes-to-constants-interfaces`,
|
|
27
|
-
tags: [_irule_1.RuleTag.
|
|
27
|
+
tags: [_irule_1.RuleTag.Styleguide, _irule_1.RuleTag.Experimental],
|
|
28
28
|
};
|
|
29
29
|
}
|
|
30
30
|
initialize(reg) {
|
package/build/src/rules/index.js
CHANGED
|
@@ -24,21 +24,21 @@ __exportStar(require("./avoid_use"), exports);
|
|
|
24
24
|
__exportStar(require("./begin_end_names"), exports);
|
|
25
25
|
__exportStar(require("./begin_single_include"), exports);
|
|
26
26
|
__exportStar(require("./call_transaction_authority_check"), exports);
|
|
27
|
-
__exportStar(require("./
|
|
27
|
+
__exportStar(require("./cds_comment_style"), exports);
|
|
28
28
|
__exportStar(require("./cds_legacy_view"), exports);
|
|
29
|
+
__exportStar(require("./cds_parser_error"), exports);
|
|
29
30
|
__exportStar(require("./chain_mainly_declarations"), exports);
|
|
31
|
+
__exportStar(require("./change_if_to_case"), exports);
|
|
30
32
|
__exportStar(require("./check_abstract"), exports);
|
|
31
33
|
__exportStar(require("./check_comments"), exports);
|
|
32
34
|
__exportStar(require("./check_ddic"), exports);
|
|
33
35
|
__exportStar(require("./check_include"), exports);
|
|
34
36
|
__exportStar(require("./check_subrc"), exports);
|
|
35
|
-
__exportStar(require("./no_external_form_calls"), exports);
|
|
36
37
|
__exportStar(require("./check_syntax"), exports);
|
|
37
|
-
__exportStar(require("./classic_exceptions_overlap"), exports);
|
|
38
38
|
__exportStar(require("./check_text_elements"), exports);
|
|
39
39
|
__exportStar(require("./check_transformation_exists"), exports);
|
|
40
|
-
__exportStar(require("./superfluous_value"), exports);
|
|
41
40
|
__exportStar(require("./class_attribute_names"), exports);
|
|
41
|
+
__exportStar(require("./classic_exceptions_overlap"), exports);
|
|
42
42
|
__exportStar(require("./cloud_types"), exports);
|
|
43
43
|
__exportStar(require("./colon_missing_space"), exports);
|
|
44
44
|
__exportStar(require("./commented_code"), exports);
|
|
@@ -102,6 +102,7 @@ __exportStar(require("./nesting"), exports);
|
|
|
102
102
|
__exportStar(require("./newline_between_methods"), exports);
|
|
103
103
|
__exportStar(require("./no_aliases"), exports);
|
|
104
104
|
__exportStar(require("./no_chained_assignment"), exports);
|
|
105
|
+
__exportStar(require("./no_external_form_calls"), exports);
|
|
105
106
|
__exportStar(require("./no_inline_in_optional_branches"), exports);
|
|
106
107
|
__exportStar(require("./no_public_attributes"), exports);
|
|
107
108
|
__exportStar(require("./no_yoda_conditions"), exports);
|
|
@@ -140,6 +141,7 @@ __exportStar(require("./sql_escape_host_variables"), exports);
|
|
|
140
141
|
__exportStar(require("./start_at_tab"), exports);
|
|
141
142
|
__exportStar(require("./static_call_via_instance"), exports);
|
|
142
143
|
__exportStar(require("./superclass_final"), exports);
|
|
144
|
+
__exportStar(require("./superfluous_value"), exports);
|
|
143
145
|
__exportStar(require("./sy_modification"), exports);
|
|
144
146
|
__exportStar(require("./tabl_enhancement_category"), exports);
|
|
145
147
|
__exportStar(require("./try_without_catch"), exports);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@abaplint/core",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.93.0",
|
|
4
4
|
"description": "abaplint - Core API",
|
|
5
5
|
"main": "build/src/index.js",
|
|
6
6
|
"typings": "build/abaplint.d.ts",
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
"@types/mocha": "^9.1.1",
|
|
51
51
|
"@types/node": "^18.7.13",
|
|
52
52
|
"chai": "^4.3.6",
|
|
53
|
-
"eslint": "^8.
|
|
53
|
+
"eslint": "^8.23.0",
|
|
54
54
|
"mocha": "^10.0.0",
|
|
55
55
|
"c8": "^7.12.0",
|
|
56
56
|
"source-map-support": "^0.5.21",
|