@abaplint/core 2.112.17 → 2.112.19
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/README.md +6 -6
- package/build/abaplint.d.ts +25 -6
- package/build/src/abap/2_statements/expressions/index.js +3 -2
- package/build/src/abap/2_statements/expressions/lob_handle.js +12 -0
- package/build/src/abap/2_statements/expressions/type.js +1 -1
- package/build/src/abap/flow/flow_graph.js +42 -25
- package/build/src/abap/flow/statement_flow.js +65 -56
- package/build/src/index.js +3 -2
- package/build/src/lsp/help.js +7 -7
- package/build/src/registry.js +1 -1
- package/build/src/rules/7bit_ascii.js +4 -4
- package/build/src/rules/abapdoc.js +4 -4
- package/build/src/rules/align_parameters.js +40 -40
- package/build/src/rules/align_type_expressions.js +28 -28
- package/build/src/rules/ambiguous_statement.js +6 -6
- package/build/src/rules/avoid_use.js +10 -10
- package/build/src/rules/begin_end_names.js +4 -4
- package/build/src/rules/begin_single_include.js +13 -13
- package/build/src/rules/call_transaction_authority_check.js +3 -3
- package/build/src/rules/cds_comment_style.js +4 -4
- package/build/src/rules/cds_legacy_view.js +4 -4
- package/build/src/rules/chain_mainly_declarations.js +4 -4
- package/build/src/rules/change_if_to_case.js +8 -8
- package/build/src/rules/check_abstract.js +2 -2
- package/build/src/rules/check_comments.js +4 -4
- package/build/src/rules/check_include.js +3 -3
- package/build/src/rules/check_subrc.js +8 -8
- package/build/src/rules/classic_exceptions_overlap.js +10 -10
- package/build/src/rules/commented_code.js +1 -1
- package/build/src/rules/constructor_visibility_public.js +4 -4
- package/build/src/rules/contains_tab.js +2 -2
- package/build/src/rules/cyclic_oo.js +4 -4
- package/build/src/rules/dangerous_statement.js +1 -1
- package/build/src/rules/definitions_top.js +6 -6
- package/build/src/rules/downport.js +82 -82
- package/build/src/rules/easy_to_find_messages.js +6 -6
- package/build/src/rules/empty_line_in_statement.js +2 -2
- package/build/src/rules/empty_structure.js +6 -6
- package/build/src/rules/exit_or_check.js +3 -3
- package/build/src/rules/expand_macros.js +5 -5
- package/build/src/rules/exporting.js +1 -1
- package/build/src/rules/forbidden_identifier.js +1 -1
- package/build/src/rules/forbidden_void_type.js +2 -2
- package/build/src/rules/fully_type_itabs.js +1 -1
- package/build/src/rules/functional_writing.js +17 -17
- package/build/src/rules/global_class.js +8 -8
- package/build/src/rules/identical_conditions.js +12 -12
- package/build/src/rules/identical_contents.js +14 -14
- package/build/src/rules/identical_descriptions.js +6 -6
- package/build/src/rules/if_in_if.js +35 -35
- package/build/src/rules/implement_methods.js +3 -3
- package/build/src/rules/in_statement_indentation.js +11 -11
- package/build/src/rules/indentation.js +16 -16
- package/build/src/rules/intf_referencing_clas.js +3 -3
- package/build/src/rules/invalid_table_index.js +2 -2
- package/build/src/rules/line_break_style.js +2 -2
- package/build/src/rules/line_length.js +1 -1
- package/build/src/rules/line_only_punc.js +1 -1
- package/build/src/rules/local_variable_names.js +6 -6
- package/build/src/rules/macro_naming.js +2 -2
- package/build/src/rules/main_file_contents.js +4 -4
- package/build/src/rules/many_parentheses.js +10 -10
- package/build/src/rules/max_one_method_parameter_per_line.js +7 -7
- package/build/src/rules/max_one_statement.js +5 -5
- package/build/src/rules/method_length.js +2 -2
- package/build/src/rules/method_overwrites_builtin.js +12 -12
- package/build/src/rules/mix_returning.js +6 -6
- package/build/src/rules/nesting.js +1 -1
- package/build/src/rules/no_chained_assignment.js +1 -1
- package/build/src/rules/no_external_form_calls.js +2 -2
- package/build/src/rules/no_inline_in_optional_branches.js +11 -11
- package/build/src/rules/no_prefixes.js +6 -6
- package/build/src/rules/no_public_attributes.js +1 -1
- package/build/src/rules/no_yoda_conditions.js +4 -4
- package/build/src/rules/nrob_consistency.js +2 -2
- package/build/src/rules/obsolete_statement.js +51 -51
- package/build/src/rules/omit_parameter_name.js +3 -3
- package/build/src/rules/omit_receiving.js +13 -13
- package/build/src/rules/parser_702_chaining.js +2 -2
- package/build/src/rules/parser_error.js +2 -2
- package/build/src/rules/parser_missing_space.js +1 -1
- package/build/src/rules/prefer_inline.js +16 -16
- package/build/src/rules/prefer_is_not.js +9 -9
- package/build/src/rules/prefer_raise_exception_new.js +5 -5
- package/build/src/rules/prefer_returning_to_exporting.js +4 -4
- package/build/src/rules/prefer_xsdbool.js +2 -2
- package/build/src/rules/preferred_compare_operator.js +2 -2
- package/build/src/rules/reduce_procedural_code.js +17 -17
- package/build/src/rules/remove_descriptions.js +4 -4
- package/build/src/rules/rfc_error_handling.js +7 -7
- package/build/src/rules/select_add_order_by.js +5 -5
- package/build/src/rules/select_performance.js +5 -5
- package/build/src/rules/select_single_full_key.js +2 -2
- package/build/src/rules/sicf_consistency.js +2 -2
- package/build/src/rules/slow_parameter_passing.js +16 -16
- package/build/src/rules/space_before_dot.js +2 -2
- package/build/src/rules/sql_value_conversion.js +6 -6
- package/build/src/rules/start_at_tab.js +1 -1
- package/build/src/rules/strict_sql.js +6 -6
- package/build/src/rules/sy_modification.js +3 -3
- package/build/src/rules/tabl_enhancement_category.js +2 -2
- package/build/src/rules/tables_declared_locally.js +2 -2
- package/build/src/rules/type_form_parameters.js +2 -2
- package/build/src/rules/unnecessary_pragma.js +29 -29
- package/build/src/rules/unnecessary_return.js +11 -11
- package/build/src/rules/unused_macros.js +6 -6
- package/build/src/rules/unused_methods.js +11 -11
- package/build/src/rules/unused_variables.js +12 -12
- package/build/src/rules/use_bool_expression.js +8 -8
- package/build/src/rules/use_class_based_exceptions.js +8 -8
- package/build/src/rules/use_line_exists.js +6 -6
- package/build/src/rules/use_new.js +4 -4
- package/build/src/rules/when_others_last.js +6 -6
- package/package.json +70 -70
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
# @abaplint/core
|
|
2
|
-
|
|
3
|
-
[abaplint](https://abaplint.org) core library
|
|
4
|
-
|
|
5
|
-
Exposes functionality like the parser and rules, which can be used in other projects.
|
|
6
|
-
|
|
1
|
+
# @abaplint/core
|
|
2
|
+
|
|
3
|
+
[abaplint](https://abaplint.org) core library
|
|
4
|
+
|
|
5
|
+
Exposes functionality like the parser and rules, which can be used in other projects.
|
|
6
|
+
|
|
7
7
|
For more information see https://github.com/abaplint/abaplint
|
package/build/abaplint.d.ts
CHANGED
|
@@ -2225,6 +2225,7 @@ declare namespace Expressions {
|
|
|
2225
2225
|
Language,
|
|
2226
2226
|
Length,
|
|
2227
2227
|
Let,
|
|
2228
|
+
LOBHandle,
|
|
2228
2229
|
LoopGroupByComponent,
|
|
2229
2230
|
LoopGroupByTarget,
|
|
2230
2231
|
LoopGroupBy,
|
|
@@ -2318,16 +2319,15 @@ declare namespace Expressions {
|
|
|
2318
2319
|
SQLJoin,
|
|
2319
2320
|
SQLOrderBy,
|
|
2320
2321
|
SQLPath,
|
|
2322
|
+
SQLSourceNoSpace,
|
|
2321
2323
|
SQLSourceSimple,
|
|
2322
2324
|
SQLSource,
|
|
2323
|
-
SQLSourceNoSpace,
|
|
2324
2325
|
SQLTarget,
|
|
2325
2326
|
SQLUpTo,
|
|
2326
2327
|
StringTemplateFormatting,
|
|
2327
2328
|
StringTemplateSource,
|
|
2328
2329
|
StringTemplate,
|
|
2329
2330
|
SuperClassName,
|
|
2330
|
-
TypeStructure,
|
|
2331
2331
|
SwitchBody,
|
|
2332
2332
|
TableBody,
|
|
2333
2333
|
TableExpression,
|
|
@@ -2343,6 +2343,7 @@ declare namespace Expressions {
|
|
|
2343
2343
|
TypeNameOrInfer,
|
|
2344
2344
|
TypeName,
|
|
2345
2345
|
TypeParam,
|
|
2346
|
+
TypeStructure,
|
|
2346
2347
|
TypeTableKey,
|
|
2347
2348
|
TypeTable,
|
|
2348
2349
|
Type_2 as Type,
|
|
@@ -2515,6 +2516,12 @@ declare class FloatType extends AbstractType {
|
|
|
2515
2516
|
toCDS(): string;
|
|
2516
2517
|
}
|
|
2517
2518
|
|
|
2519
|
+
export declare enum FLOW_EDGE_TYPE {
|
|
2520
|
+
true = "true",
|
|
2521
|
+
false = "false",
|
|
2522
|
+
undefined = "undefined"
|
|
2523
|
+
}
|
|
2524
|
+
|
|
2518
2525
|
export declare class FlowGraph {
|
|
2519
2526
|
private edges;
|
|
2520
2527
|
private readonly startNode;
|
|
@@ -2524,23 +2531,30 @@ export declare class FlowGraph {
|
|
|
2524
2531
|
getStart(): string;
|
|
2525
2532
|
getLabel(): string;
|
|
2526
2533
|
getEnd(): string;
|
|
2527
|
-
addEdge(from: string, to: string): void;
|
|
2534
|
+
addEdge(from: string, to: string, type: FLOW_EDGE_TYPE): void;
|
|
2528
2535
|
removeEdge(from: string, to: string): void;
|
|
2529
2536
|
listEdges(): {
|
|
2530
2537
|
from: string;
|
|
2531
2538
|
to: string;
|
|
2539
|
+
type: FLOW_EDGE_TYPE;
|
|
2532
2540
|
}[];
|
|
2533
2541
|
listInto(to: string, skipStart?: boolean): string[];
|
|
2534
2542
|
listNodes(): string[];
|
|
2535
2543
|
hasEdges(): boolean;
|
|
2536
2544
|
/** return value: end node of to graph */
|
|
2537
|
-
addGraph(from: string, to: FlowGraph): string;
|
|
2545
|
+
addGraph(from: string, to: FlowGraph, type: FLOW_EDGE_TYPE): string;
|
|
2538
2546
|
toJSON(): string;
|
|
2539
2547
|
toTextEdges(): string;
|
|
2540
2548
|
setLabel(label: string): void;
|
|
2541
2549
|
toDigraph(): string;
|
|
2542
|
-
listSources(node: string):
|
|
2543
|
-
|
|
2550
|
+
listSources(node: string): {
|
|
2551
|
+
name: string;
|
|
2552
|
+
type: FLOW_EDGE_TYPE;
|
|
2553
|
+
}[];
|
|
2554
|
+
listTargets(node: string): {
|
|
2555
|
+
name: string;
|
|
2556
|
+
type: FLOW_EDGE_TYPE;
|
|
2557
|
+
}[];
|
|
2544
2558
|
/** removes all nodes containing "#" that have one in-going and one out-going edge */
|
|
2545
2559
|
reduce(): this;
|
|
2546
2560
|
}
|
|
@@ -4079,6 +4093,10 @@ declare class LoadReport implements IStatement {
|
|
|
4079
4093
|
getMatcher(): IStatementRunnable;
|
|
4080
4094
|
}
|
|
4081
4095
|
|
|
4096
|
+
declare class LOBHandle extends Expression {
|
|
4097
|
+
getRunnable(): IStatementRunnable;
|
|
4098
|
+
}
|
|
4099
|
+
|
|
4082
4100
|
declare class Local implements IStatement {
|
|
4083
4101
|
getMatcher(): IStatementRunnable;
|
|
4084
4102
|
}
|
|
@@ -6036,6 +6054,7 @@ declare class StartOfSelection implements IStatement {
|
|
|
6036
6054
|
export declare class StatementFlow {
|
|
6037
6055
|
private counter;
|
|
6038
6056
|
build(stru: StructureNode): FlowGraph[];
|
|
6057
|
+
private run;
|
|
6039
6058
|
private findBody;
|
|
6040
6059
|
private buildName;
|
|
6041
6060
|
private traverseBody;
|
|
@@ -104,6 +104,7 @@ __exportStar(require("./kernel_id"), exports);
|
|
|
104
104
|
__exportStar(require("./language"), exports);
|
|
105
105
|
__exportStar(require("./length"), exports);
|
|
106
106
|
__exportStar(require("./let"), exports);
|
|
107
|
+
__exportStar(require("./lob_handle"), exports);
|
|
107
108
|
__exportStar(require("./loop_group_by_component"), exports);
|
|
108
109
|
__exportStar(require("./loop_group_by_target"), exports);
|
|
109
110
|
__exportStar(require("./loop_group_by"), exports);
|
|
@@ -197,16 +198,15 @@ __exportStar(require("./sql_into_table"), exports);
|
|
|
197
198
|
__exportStar(require("./sql_join"), exports);
|
|
198
199
|
__exportStar(require("./sql_order_by"), exports);
|
|
199
200
|
__exportStar(require("./sql_path"), exports);
|
|
201
|
+
__exportStar(require("./sql_source_no_space"), exports);
|
|
200
202
|
__exportStar(require("./sql_source_simple"), exports);
|
|
201
203
|
__exportStar(require("./sql_source"), exports);
|
|
202
|
-
__exportStar(require("./sql_source_no_space"), exports);
|
|
203
204
|
__exportStar(require("./sql_target"), exports);
|
|
204
205
|
__exportStar(require("./sql_up_to"), exports);
|
|
205
206
|
__exportStar(require("./string_template_formatting"), exports);
|
|
206
207
|
__exportStar(require("./string_template_source"), exports);
|
|
207
208
|
__exportStar(require("./string_template"), exports);
|
|
208
209
|
__exportStar(require("./super_class_name"), exports);
|
|
209
|
-
__exportStar(require("./type_structure"), exports);
|
|
210
210
|
__exportStar(require("./switch_body"), exports);
|
|
211
211
|
__exportStar(require("./table_body"), exports);
|
|
212
212
|
__exportStar(require("./table_expression"), exports);
|
|
@@ -222,6 +222,7 @@ __exportStar(require("./transporting_fields"), exports);
|
|
|
222
222
|
__exportStar(require("./type_name_or_infer"), exports);
|
|
223
223
|
__exportStar(require("./type_name"), exports);
|
|
224
224
|
__exportStar(require("./type_param"), exports);
|
|
225
|
+
__exportStar(require("./type_structure"), exports);
|
|
225
226
|
__exportStar(require("./type_table_key"), exports);
|
|
226
227
|
__exportStar(require("./type_table"), exports);
|
|
227
228
|
__exportStar(require("./type"), exports);
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.LOBHandle = void 0;
|
|
4
|
+
const combi_1 = require("../combi");
|
|
5
|
+
const Expressions = require(".");
|
|
6
|
+
class LOBHandle extends combi_1.Expression {
|
|
7
|
+
getRunnable() {
|
|
8
|
+
return (0, combi_1.seq)("WRITER FOR COLUMNS", Expressions.Field);
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
exports.LOBHandle = LOBHandle;
|
|
12
|
+
//# sourceMappingURL=lob_handle.js.map
|
|
@@ -7,7 +7,7 @@ class Type extends combi_1.Expression {
|
|
|
7
7
|
getRunnable() {
|
|
8
8
|
const typeType = (0, combi_1.seq)(_1.TypeName, (0, combi_1.optPrio)(_1.Default));
|
|
9
9
|
const like = (0, combi_1.altPrio)((0, combi_1.seq)("LINE OF", _1.FieldChain), (0, combi_1.seq)("REF TO", _1.FieldChain), _1.FieldChain);
|
|
10
|
-
const type = (0, combi_1.altPrio)((0, combi_1.seq)("LINE OF", typeType), (0, combi_1.seq)("REF TO", typeType), typeType);
|
|
10
|
+
const type = (0, combi_1.altPrio)((0, combi_1.seq)("LINE OF", typeType), (0, combi_1.seq)("REF TO", typeType), (0, combi_1.seq)(typeType, (0, combi_1.optPrio)(_1.LOBHandle)));
|
|
11
11
|
const ret = (0, combi_1.altPrio)((0, combi_1.seq)("LIKE", like), (0, combi_1.seq)("TYPE", type));
|
|
12
12
|
return ret;
|
|
13
13
|
}
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.FlowGraph = void 0;
|
|
3
|
+
exports.FlowGraph = exports.FLOW_EDGE_TYPE = void 0;
|
|
4
|
+
var FLOW_EDGE_TYPE;
|
|
5
|
+
(function (FLOW_EDGE_TYPE) {
|
|
6
|
+
FLOW_EDGE_TYPE["true"] = "true";
|
|
7
|
+
FLOW_EDGE_TYPE["false"] = "false";
|
|
8
|
+
FLOW_EDGE_TYPE["undefined"] = "undefined";
|
|
9
|
+
})(FLOW_EDGE_TYPE || (exports.FLOW_EDGE_TYPE = FLOW_EDGE_TYPE = {}));
|
|
4
10
|
class FlowGraph {
|
|
5
11
|
constructor(counter) {
|
|
6
12
|
this.edges = {};
|
|
@@ -17,11 +23,11 @@ class FlowGraph {
|
|
|
17
23
|
getEnd() {
|
|
18
24
|
return this.endNode;
|
|
19
25
|
}
|
|
20
|
-
addEdge(from, to) {
|
|
26
|
+
addEdge(from, to, type) {
|
|
21
27
|
if (this.edges[from] === undefined) {
|
|
22
28
|
this.edges[from] = {};
|
|
23
29
|
}
|
|
24
|
-
this.edges[from][to] =
|
|
30
|
+
this.edges[from][to] = type;
|
|
25
31
|
}
|
|
26
32
|
removeEdge(from, to) {
|
|
27
33
|
if (this.edges[from] === undefined) {
|
|
@@ -36,7 +42,7 @@ class FlowGraph {
|
|
|
36
42
|
const list = [];
|
|
37
43
|
for (const from of Object.keys(this.edges)) {
|
|
38
44
|
for (const to of Object.keys(this.edges[from])) {
|
|
39
|
-
list.push({ from, to });
|
|
45
|
+
list.push({ from, to, type: this.edges[from][to] });
|
|
40
46
|
}
|
|
41
47
|
}
|
|
42
48
|
return list;
|
|
@@ -65,12 +71,12 @@ class FlowGraph {
|
|
|
65
71
|
return Object.keys(this.edges).length > 0;
|
|
66
72
|
}
|
|
67
73
|
/** return value: end node of to graph */
|
|
68
|
-
addGraph(from, to) {
|
|
74
|
+
addGraph(from, to, type) {
|
|
69
75
|
if (to.hasEdges() === false) {
|
|
70
76
|
return from;
|
|
71
77
|
}
|
|
72
|
-
this.addEdge(from, to.getStart());
|
|
73
|
-
to.listEdges().forEach(e => this.addEdge(e.from, e.to));
|
|
78
|
+
this.addEdge(from, to.getStart(), type);
|
|
79
|
+
to.listEdges().forEach(e => this.addEdge(e.from, e.to, e.type));
|
|
74
80
|
return to.getEnd();
|
|
75
81
|
}
|
|
76
82
|
toJSON() {
|
|
@@ -79,7 +85,8 @@ class FlowGraph {
|
|
|
79
85
|
toTextEdges() {
|
|
80
86
|
let graph = "";
|
|
81
87
|
for (const l of this.listEdges()) {
|
|
82
|
-
|
|
88
|
+
const label = l.type === FLOW_EDGE_TYPE.undefined ? "" : ` [label="${l.type}"]`;
|
|
89
|
+
graph += `"${l.from}" -> "${l.to}"${label};\n`;
|
|
83
90
|
}
|
|
84
91
|
return graph.trim();
|
|
85
92
|
}
|
|
@@ -87,32 +94,32 @@ class FlowGraph {
|
|
|
87
94
|
this.label = label;
|
|
88
95
|
}
|
|
89
96
|
toDigraph() {
|
|
90
|
-
return `digraph G {
|
|
91
|
-
labelloc="t";
|
|
92
|
-
label="${this.label}";
|
|
93
|
-
graph [fontname = "helvetica"];
|
|
94
|
-
node [fontname = "helvetica", shape="box"];
|
|
95
|
-
edge [fontname = "helvetica"];
|
|
96
|
-
${this.toTextEdges()}
|
|
97
|
+
return `digraph G {
|
|
98
|
+
labelloc="t";
|
|
99
|
+
label="${this.label}";
|
|
100
|
+
graph [fontname = "helvetica"];
|
|
101
|
+
node [fontname = "helvetica", shape="box"];
|
|
102
|
+
edge [fontname = "helvetica"];
|
|
103
|
+
${this.toTextEdges()}
|
|
97
104
|
}`;
|
|
98
105
|
}
|
|
99
106
|
listSources(node) {
|
|
100
|
-
const set =
|
|
107
|
+
const set = [];
|
|
101
108
|
for (const l of this.listEdges()) {
|
|
102
109
|
if (node === l.to) {
|
|
103
|
-
set.
|
|
110
|
+
set.push({ name: l.from, type: l.type });
|
|
104
111
|
}
|
|
105
112
|
}
|
|
106
|
-
return
|
|
113
|
+
return set;
|
|
107
114
|
}
|
|
108
115
|
listTargets(node) {
|
|
109
|
-
const set =
|
|
116
|
+
const set = [];
|
|
110
117
|
for (const l of this.listEdges()) {
|
|
111
118
|
if (node === l.from) {
|
|
112
|
-
set.
|
|
119
|
+
set.push({ name: l.to, type: l.type });
|
|
113
120
|
}
|
|
114
121
|
}
|
|
115
|
-
return
|
|
122
|
+
return set;
|
|
116
123
|
}
|
|
117
124
|
/** removes all nodes containing "#" that have one in-going and one out-going edge */
|
|
118
125
|
reduce() {
|
|
@@ -125,20 +132,30 @@ ${this.toTextEdges()}
|
|
|
125
132
|
if (sources.length > 0 && targets.length > 0) {
|
|
126
133
|
// hash node in the middle of the graph
|
|
127
134
|
for (const s of sources) {
|
|
128
|
-
this.removeEdge(s, node);
|
|
135
|
+
this.removeEdge(s.name, node);
|
|
129
136
|
}
|
|
130
137
|
for (const t of targets) {
|
|
131
|
-
this.removeEdge(node, t);
|
|
138
|
+
this.removeEdge(node, t.name);
|
|
132
139
|
}
|
|
133
140
|
for (const s of sources) {
|
|
134
141
|
for (const t of targets) {
|
|
135
|
-
|
|
142
|
+
let type = FLOW_EDGE_TYPE.undefined;
|
|
143
|
+
if (s.type !== FLOW_EDGE_TYPE.undefined) {
|
|
144
|
+
type = s.type;
|
|
145
|
+
}
|
|
146
|
+
if (t.type !== FLOW_EDGE_TYPE.undefined) {
|
|
147
|
+
if (type !== FLOW_EDGE_TYPE.undefined) {
|
|
148
|
+
throw new Error("reduce: cannot merge, different edge types");
|
|
149
|
+
}
|
|
150
|
+
type = t.type;
|
|
151
|
+
}
|
|
152
|
+
this.addEdge(s.name, t.name, type);
|
|
136
153
|
}
|
|
137
154
|
}
|
|
138
155
|
}
|
|
139
156
|
if (node.startsWith("end#") && sources.length === 0) {
|
|
140
157
|
for (const t of targets) {
|
|
141
|
-
this.removeEdge(node, t);
|
|
158
|
+
this.removeEdge(node, t.name);
|
|
142
159
|
}
|
|
143
160
|
}
|
|
144
161
|
}
|
|
@@ -11,31 +11,40 @@ class StatementFlow {
|
|
|
11
11
|
this.counter = 0;
|
|
12
12
|
}
|
|
13
13
|
build(stru) {
|
|
14
|
-
var _a, _b, _c;
|
|
14
|
+
var _a, _b, _c, _d;
|
|
15
15
|
const ret = [];
|
|
16
|
-
const structures = stru.findAllStructuresMulti([Structures.Form, Structures.
|
|
16
|
+
const structures = stru.findAllStructuresMulti([Structures.Form, Structures.ClassImplementation, Structures.FunctionModule]);
|
|
17
17
|
for (const s of structures) {
|
|
18
18
|
let name = "";
|
|
19
19
|
if (s.get() instanceof Structures.Form) {
|
|
20
20
|
name = "FORM " + ((_a = s.findFirstExpression(Expressions.FormName)) === null || _a === void 0 ? void 0 : _a.concatTokens());
|
|
21
|
+
ret.push(this.run(s, name));
|
|
21
22
|
}
|
|
22
|
-
else if (s.get() instanceof Structures.
|
|
23
|
-
|
|
23
|
+
else if (s.get() instanceof Structures.ClassImplementation) {
|
|
24
|
+
const className = (_b = s.findFirstExpression(Expressions.ClassName)) === null || _b === void 0 ? void 0 : _b.concatTokens();
|
|
25
|
+
for (const method of s.findDirectStructures(Structures.Method)) {
|
|
26
|
+
const methodName = (_c = method.findFirstExpression(Expressions.MethodName)) === null || _c === void 0 ? void 0 : _c.concatTokens();
|
|
27
|
+
name = "METHOD " + methodName + ", CLASS " + className;
|
|
28
|
+
ret.push(this.run(method, name));
|
|
29
|
+
}
|
|
24
30
|
}
|
|
25
31
|
else if (s.get() instanceof Structures.FunctionModule) {
|
|
26
|
-
name = "FUNCTION " + ((
|
|
32
|
+
name = "FUNCTION " + ((_d = s.findFirstExpression(Expressions.Field)) === null || _d === void 0 ? void 0 : _d.concatTokens());
|
|
33
|
+
ret.push(this.run(s, name));
|
|
27
34
|
}
|
|
28
35
|
else {
|
|
29
36
|
throw new Error("StatementFlow, unknown structure");
|
|
30
37
|
}
|
|
31
|
-
this.counter = 1;
|
|
32
|
-
const graph = this.traverseBody(this.findBody(s), { procedureEnd: "end#1" });
|
|
33
|
-
graph.setLabel(name);
|
|
34
|
-
ret.push(graph);
|
|
35
38
|
}
|
|
36
39
|
return ret.map(f => f.reduce());
|
|
37
40
|
}
|
|
38
41
|
////////////////////
|
|
42
|
+
run(s, name) {
|
|
43
|
+
this.counter = 1;
|
|
44
|
+
const graph = this.traverseBody(this.findBody(s), { procedureEnd: "end#1" });
|
|
45
|
+
graph.setLabel(name);
|
|
46
|
+
return graph;
|
|
47
|
+
}
|
|
39
48
|
findBody(f) {
|
|
40
49
|
var _a;
|
|
41
50
|
return ((_a = f.findDirectStructure(Structures.Body)) === null || _a === void 0 ? void 0 : _a.getChildren()) || [];
|
|
@@ -64,7 +73,7 @@ class StatementFlow {
|
|
|
64
73
|
traverseBody(children, context) {
|
|
65
74
|
const graph = new flow_graph_1.FlowGraph(this.counter++);
|
|
66
75
|
if (children.length === 0) {
|
|
67
|
-
graph.addEdge(graph.getStart(), graph.getEnd());
|
|
76
|
+
graph.addEdge(graph.getStart(), graph.getEnd(), flow_graph_1.FLOW_EDGE_TYPE.undefined);
|
|
68
77
|
return graph;
|
|
69
78
|
}
|
|
70
79
|
let current = graph.getStart();
|
|
@@ -73,44 +82,44 @@ class StatementFlow {
|
|
|
73
82
|
const firstChild = c.getFirstChild(); // "Normal" only has one child
|
|
74
83
|
if (firstChild instanceof nodes_1.StatementNode) {
|
|
75
84
|
const name = this.buildName(firstChild);
|
|
76
|
-
graph.addEdge(current, name);
|
|
85
|
+
graph.addEdge(current, name, flow_graph_1.FLOW_EDGE_TYPE.undefined);
|
|
77
86
|
current = name;
|
|
78
87
|
if (firstChild.get() instanceof Statements.Check) {
|
|
79
88
|
if (context.loopStart) {
|
|
80
|
-
graph.addEdge(name, context.loopStart);
|
|
89
|
+
graph.addEdge(name, context.loopStart, flow_graph_1.FLOW_EDGE_TYPE.false);
|
|
81
90
|
}
|
|
82
91
|
else {
|
|
83
|
-
graph.addEdge(name, context.procedureEnd);
|
|
92
|
+
graph.addEdge(name, context.procedureEnd, flow_graph_1.FLOW_EDGE_TYPE.false);
|
|
84
93
|
}
|
|
85
94
|
}
|
|
86
95
|
else if (firstChild.get() instanceof Statements.Assert) {
|
|
87
|
-
graph.addEdge(name, context.procedureEnd);
|
|
96
|
+
graph.addEdge(name, context.procedureEnd, flow_graph_1.FLOW_EDGE_TYPE.false);
|
|
88
97
|
}
|
|
89
98
|
else if (firstChild.get() instanceof Statements.Continue && context.loopStart) {
|
|
90
|
-
graph.addEdge(name, context.loopStart);
|
|
99
|
+
graph.addEdge(name, context.loopStart, flow_graph_1.FLOW_EDGE_TYPE.undefined);
|
|
91
100
|
return graph;
|
|
92
101
|
}
|
|
93
102
|
else if (firstChild.get() instanceof Statements.Exit) {
|
|
94
103
|
if (context.loopEnd) {
|
|
95
|
-
graph.addEdge(name, context.loopEnd);
|
|
104
|
+
graph.addEdge(name, context.loopEnd, flow_graph_1.FLOW_EDGE_TYPE.undefined);
|
|
96
105
|
}
|
|
97
106
|
else {
|
|
98
|
-
graph.addEdge(name, context.procedureEnd);
|
|
107
|
+
graph.addEdge(name, context.procedureEnd, flow_graph_1.FLOW_EDGE_TYPE.undefined);
|
|
99
108
|
}
|
|
100
109
|
return graph;
|
|
101
110
|
}
|
|
102
111
|
else if (firstChild.get() instanceof Statements.Return) {
|
|
103
|
-
graph.addEdge(name, context.procedureEnd);
|
|
112
|
+
graph.addEdge(name, context.procedureEnd, flow_graph_1.FLOW_EDGE_TYPE.undefined);
|
|
104
113
|
return graph;
|
|
105
114
|
}
|
|
106
115
|
}
|
|
107
116
|
else if (firstChild instanceof nodes_1.StructureNode) {
|
|
108
117
|
const sub = this.traverseStructure(firstChild, context);
|
|
109
|
-
current = graph.addGraph(current, sub);
|
|
118
|
+
current = graph.addGraph(current, sub, flow_graph_1.FLOW_EDGE_TYPE.undefined);
|
|
110
119
|
}
|
|
111
120
|
}
|
|
112
121
|
}
|
|
113
|
-
graph.addEdge(current, graph.getEnd());
|
|
122
|
+
graph.addEdge(current, graph.getEnd(), flow_graph_1.FLOW_EDGE_TYPE.undefined);
|
|
114
123
|
return graph;
|
|
115
124
|
}
|
|
116
125
|
traverseStructure(n, context) {
|
|
@@ -123,9 +132,9 @@ class StatementFlow {
|
|
|
123
132
|
if (type instanceof Structures.If) {
|
|
124
133
|
const ifName = this.buildName(n.findDirectStatement(Statements.If));
|
|
125
134
|
const sub = this.traverseBody(this.findBody(n), context);
|
|
126
|
-
graph.addEdge(current, ifName);
|
|
127
|
-
graph.addGraph(ifName, sub);
|
|
128
|
-
graph.addEdge(sub.getEnd(), graph.getEnd());
|
|
135
|
+
graph.addEdge(current, ifName, flow_graph_1.FLOW_EDGE_TYPE.undefined);
|
|
136
|
+
graph.addGraph(ifName, sub, flow_graph_1.FLOW_EDGE_TYPE.true);
|
|
137
|
+
graph.addEdge(sub.getEnd(), graph.getEnd(), flow_graph_1.FLOW_EDGE_TYPE.undefined);
|
|
129
138
|
current = ifName;
|
|
130
139
|
for (const e of n.findDirectStructures(Structures.ElseIf)) {
|
|
131
140
|
const elseifst = e.findDirectStatement(Statements.ElseIf);
|
|
@@ -134,9 +143,9 @@ class StatementFlow {
|
|
|
134
143
|
}
|
|
135
144
|
const elseIfName = this.buildName(elseifst);
|
|
136
145
|
const sub = this.traverseBody(this.findBody(e), context);
|
|
137
|
-
graph.addEdge(current, elseIfName);
|
|
138
|
-
graph.addGraph(elseIfName, sub);
|
|
139
|
-
graph.addEdge(sub.getEnd(), graph.getEnd());
|
|
146
|
+
graph.addEdge(current, elseIfName, flow_graph_1.FLOW_EDGE_TYPE.false);
|
|
147
|
+
graph.addGraph(elseIfName, sub, flow_graph_1.FLOW_EDGE_TYPE.true);
|
|
148
|
+
graph.addEdge(sub.getEnd(), graph.getEnd(), flow_graph_1.FLOW_EDGE_TYPE.undefined);
|
|
140
149
|
current = elseIfName;
|
|
141
150
|
}
|
|
142
151
|
const els = n.findDirectStructure(Structures.Else);
|
|
@@ -144,12 +153,12 @@ class StatementFlow {
|
|
|
144
153
|
if (els && elsest) {
|
|
145
154
|
const elseName = this.buildName(elsest);
|
|
146
155
|
const sub = this.traverseBody(this.findBody(els), context);
|
|
147
|
-
graph.addEdge(current, elseName);
|
|
148
|
-
graph.addGraph(elseName, sub);
|
|
149
|
-
graph.addEdge(sub.getEnd(), graph.getEnd());
|
|
156
|
+
graph.addEdge(current, elseName, flow_graph_1.FLOW_EDGE_TYPE.false);
|
|
157
|
+
graph.addGraph(elseName, sub, flow_graph_1.FLOW_EDGE_TYPE.undefined);
|
|
158
|
+
graph.addEdge(sub.getEnd(), graph.getEnd(), flow_graph_1.FLOW_EDGE_TYPE.undefined);
|
|
150
159
|
}
|
|
151
160
|
else {
|
|
152
|
-
graph.addEdge(ifName, graph.getEnd());
|
|
161
|
+
graph.addEdge(ifName, graph.getEnd(), flow_graph_1.FLOW_EDGE_TYPE.false);
|
|
153
162
|
}
|
|
154
163
|
}
|
|
155
164
|
else if (type instanceof Structures.Loop
|
|
@@ -161,18 +170,18 @@ class StatementFlow {
|
|
|
161
170
|
|| type instanceof Structures.Do) {
|
|
162
171
|
const loopName = this.buildName(n.getFirstStatement());
|
|
163
172
|
const sub = this.traverseBody(this.findBody(n), Object.assign(Object.assign({}, context), { loopStart: loopName, loopEnd: graph.getEnd() }));
|
|
164
|
-
graph.addEdge(current, loopName);
|
|
165
|
-
graph.addGraph(loopName, sub);
|
|
166
|
-
graph.addEdge(sub.getEnd(), loopName);
|
|
167
|
-
graph.addEdge(loopName, graph.getEnd());
|
|
173
|
+
graph.addEdge(current, loopName, flow_graph_1.FLOW_EDGE_TYPE.undefined);
|
|
174
|
+
graph.addGraph(loopName, sub, flow_graph_1.FLOW_EDGE_TYPE.true);
|
|
175
|
+
graph.addEdge(sub.getEnd(), loopName, flow_graph_1.FLOW_EDGE_TYPE.undefined);
|
|
176
|
+
graph.addEdge(loopName, graph.getEnd(), flow_graph_1.FLOW_EDGE_TYPE.false);
|
|
168
177
|
}
|
|
169
178
|
else if (type instanceof Structures.Data
|
|
170
179
|
|| type instanceof Structures.Types) {
|
|
171
180
|
// these doesnt affect control flow, so just take the first statement
|
|
172
181
|
const statement = n.getFirstStatement();
|
|
173
182
|
const name = this.buildName(statement);
|
|
174
|
-
graph.addEdge(current, name);
|
|
175
|
-
graph.addEdge(name, graph.getEnd());
|
|
183
|
+
graph.addEdge(current, name, flow_graph_1.FLOW_EDGE_TYPE.undefined);
|
|
184
|
+
graph.addEdge(name, graph.getEnd(), flow_graph_1.FLOW_EDGE_TYPE.undefined);
|
|
176
185
|
}
|
|
177
186
|
else if (type instanceof Structures.AtFirst
|
|
178
187
|
|| type instanceof Structures.AtLast
|
|
@@ -180,30 +189,30 @@ class StatementFlow {
|
|
|
180
189
|
|| type instanceof Structures.OnChange) {
|
|
181
190
|
const name = this.buildName(n.getFirstStatement());
|
|
182
191
|
const body = this.traverseBody(this.findBody(n), context);
|
|
183
|
-
graph.addEdge(current, name);
|
|
184
|
-
graph.addGraph(name, body);
|
|
185
|
-
graph.addEdge(body.getEnd(), graph.getEnd());
|
|
186
|
-
graph.addEdge(current, graph.getEnd());
|
|
192
|
+
graph.addEdge(current, name, flow_graph_1.FLOW_EDGE_TYPE.undefined);
|
|
193
|
+
graph.addGraph(name, body, flow_graph_1.FLOW_EDGE_TYPE.undefined);
|
|
194
|
+
graph.addEdge(body.getEnd(), graph.getEnd(), flow_graph_1.FLOW_EDGE_TYPE.undefined);
|
|
195
|
+
graph.addEdge(current, graph.getEnd(), flow_graph_1.FLOW_EDGE_TYPE.undefined);
|
|
187
196
|
}
|
|
188
197
|
else if (type instanceof Structures.Try) {
|
|
189
198
|
const tryName = this.buildName(n.getFirstStatement());
|
|
190
199
|
const body = this.traverseBody(this.findBody(n), context);
|
|
191
|
-
graph.addEdge(current, tryName);
|
|
192
|
-
graph.addGraph(tryName, body);
|
|
193
|
-
graph.addEdge(body.getEnd(), graph.getEnd());
|
|
200
|
+
graph.addEdge(current, tryName, flow_graph_1.FLOW_EDGE_TYPE.undefined);
|
|
201
|
+
graph.addGraph(tryName, body, flow_graph_1.FLOW_EDGE_TYPE.undefined);
|
|
202
|
+
graph.addEdge(body.getEnd(), graph.getEnd(), flow_graph_1.FLOW_EDGE_TYPE.undefined);
|
|
194
203
|
for (const c of n.findDirectStructures(Structures.Catch)) {
|
|
195
204
|
const catchName = this.buildName(c.getFirstStatement());
|
|
196
205
|
const catchBody = this.traverseBody(this.findBody(c), context);
|
|
197
206
|
// TODO: this does not take exceptions into account
|
|
198
|
-
graph.addEdge(body.getEnd(), catchName);
|
|
199
|
-
graph.addGraph(catchName, catchBody);
|
|
200
|
-
graph.addEdge(catchBody.getEnd(), graph.getEnd());
|
|
207
|
+
graph.addEdge(body.getEnd(), catchName, flow_graph_1.FLOW_EDGE_TYPE.undefined);
|
|
208
|
+
graph.addGraph(catchName, catchBody, flow_graph_1.FLOW_EDGE_TYPE.undefined);
|
|
209
|
+
graph.addEdge(catchBody.getEnd(), graph.getEnd(), flow_graph_1.FLOW_EDGE_TYPE.undefined);
|
|
201
210
|
}
|
|
202
211
|
// TODO, handle CLEANUP
|
|
203
212
|
}
|
|
204
213
|
else if (type instanceof Structures.Case) {
|
|
205
214
|
const caseName = this.buildName(n.getFirstStatement());
|
|
206
|
-
graph.addEdge(current, caseName);
|
|
215
|
+
graph.addEdge(current, caseName, flow_graph_1.FLOW_EDGE_TYPE.undefined);
|
|
207
216
|
let othersFound = false;
|
|
208
217
|
for (const w of n.findDirectStructures(Structures.When)) {
|
|
209
218
|
const first = w.getFirstStatement();
|
|
@@ -215,17 +224,17 @@ class StatementFlow {
|
|
|
215
224
|
}
|
|
216
225
|
const firstName = this.buildName(first);
|
|
217
226
|
const sub = this.traverseBody(this.findBody(w), context);
|
|
218
|
-
graph.addEdge(caseName, firstName);
|
|
219
|
-
graph.addGraph(firstName, sub);
|
|
220
|
-
graph.addEdge(sub.getEnd(), graph.getEnd());
|
|
227
|
+
graph.addEdge(caseName, firstName, flow_graph_1.FLOW_EDGE_TYPE.undefined);
|
|
228
|
+
graph.addGraph(firstName, sub, flow_graph_1.FLOW_EDGE_TYPE.undefined);
|
|
229
|
+
graph.addEdge(sub.getEnd(), graph.getEnd(), flow_graph_1.FLOW_EDGE_TYPE.undefined);
|
|
221
230
|
}
|
|
222
231
|
if (othersFound === false) {
|
|
223
|
-
graph.addEdge(caseName, graph.getEnd());
|
|
232
|
+
graph.addEdge(caseName, graph.getEnd(), flow_graph_1.FLOW_EDGE_TYPE.undefined);
|
|
224
233
|
}
|
|
225
234
|
}
|
|
226
235
|
else if (type instanceof Structures.CaseType) {
|
|
227
236
|
const caseName = this.buildName(n.getFirstStatement());
|
|
228
|
-
graph.addEdge(current, caseName);
|
|
237
|
+
graph.addEdge(current, caseName, flow_graph_1.FLOW_EDGE_TYPE.undefined);
|
|
229
238
|
let othersFound = false;
|
|
230
239
|
for (const w of n.findDirectStructures(Structures.WhenType)) {
|
|
231
240
|
const first = w.getFirstStatement();
|
|
@@ -237,12 +246,12 @@ class StatementFlow {
|
|
|
237
246
|
}
|
|
238
247
|
const firstName = this.buildName(first);
|
|
239
248
|
const sub = this.traverseBody(this.findBody(w), context);
|
|
240
|
-
graph.addEdge(caseName, firstName);
|
|
241
|
-
graph.addGraph(firstName, sub);
|
|
242
|
-
graph.addEdge(sub.getEnd(), graph.getEnd());
|
|
249
|
+
graph.addEdge(caseName, firstName, flow_graph_1.FLOW_EDGE_TYPE.undefined);
|
|
250
|
+
graph.addGraph(firstName, sub, flow_graph_1.FLOW_EDGE_TYPE.undefined);
|
|
251
|
+
graph.addEdge(sub.getEnd(), graph.getEnd(), flow_graph_1.FLOW_EDGE_TYPE.undefined);
|
|
243
252
|
}
|
|
244
253
|
if (othersFound === false) {
|
|
245
|
-
graph.addEdge(caseName, graph.getEnd());
|
|
254
|
+
graph.addEdge(caseName, graph.getEnd(), flow_graph_1.FLOW_EDGE_TYPE.undefined);
|
|
246
255
|
}
|
|
247
256
|
}
|
|
248
257
|
else {
|
package/build/src/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
exports.LSPEdit = exports.RuleTag = exports.Severity = exports.Visibility = exports.Info = exports.Diagnostics = exports.Rename = exports.PrettyPrinter = exports.Position = void 0;
|
|
3
|
+
exports.ABAPFile = exports.RulesRunner = exports.SpaghettiScope = exports.SyntaxLogic = exports.ABAPObject = exports.Tokens = exports.ExpressionsCDS = exports.CDSParser = exports.LanguageServerTypes = exports.DDLParser = exports.FLOW_EDGE_TYPE = exports.FlowGraph = exports.StatementFlow = exports.NativeSQL = exports.MacroContent = exports.MacroCall = exports.applyEditList = exports.applyEditSingle = exports.SpaghettiScopeNode = exports.AbstractFile = exports.Token = exports.ScopeType = exports.BasicTypes = exports.TypedIdentifier = exports.AbstractType = exports.VirtualPosition = exports.Comment = exports.Unknown = exports.Empty = exports.Identifier = exports.Nodes = exports.Types = exports.Expressions = exports.Statements = exports.Structures = exports.SkipLogic = exports.Objects = exports.ArtifactsRules = exports.ArtifactsObjects = exports.ArtifactsABAP = exports.BuiltIn = exports.MethodLengthStats = exports.LanguageServer = exports.Registry = exports.CyclomaticComplexityStats = exports.ReferenceType = exports.Version = exports.Config = exports.Issue = exports.MemoryFile = void 0;
|
|
4
|
+
exports.LSPEdit = exports.RuleTag = exports.Severity = exports.Visibility = exports.Info = exports.Diagnostics = exports.Rename = exports.PrettyPrinter = exports.Position = exports.CurrentScope = void 0;
|
|
5
5
|
const issue_1 = require("./issue");
|
|
6
6
|
Object.defineProperty(exports, "Issue", { enumerable: true, get: function () { return issue_1.Issue; } });
|
|
7
7
|
const config_1 = require("./config");
|
|
@@ -113,4 +113,5 @@ const statement_flow_1 = require("./abap/flow/statement_flow");
|
|
|
113
113
|
Object.defineProperty(exports, "StatementFlow", { enumerable: true, get: function () { return statement_flow_1.StatementFlow; } });
|
|
114
114
|
const flow_graph_1 = require("./abap/flow/flow_graph");
|
|
115
115
|
Object.defineProperty(exports, "FlowGraph", { enumerable: true, get: function () { return flow_graph_1.FlowGraph; } });
|
|
116
|
+
Object.defineProperty(exports, "FLOW_EDGE_TYPE", { enumerable: true, get: function () { return flow_graph_1.FLOW_EDGE_TYPE; } });
|
|
116
117
|
//# sourceMappingURL=index.js.map
|
package/build/src/lsp/help.js
CHANGED
|
@@ -19,13 +19,13 @@ class Help {
|
|
|
19
19
|
/////////////////////////////////////////////////
|
|
20
20
|
static dumpABAP(file, reg, textDocument, position) {
|
|
21
21
|
let content = "";
|
|
22
|
-
content = `
|
|
23
|
-
<a href="#_tokens" rel="no-refresh">Tokens</a> |
|
|
24
|
-
<a href="#_statements" rel="no-refresh">Statements</a> |
|
|
25
|
-
<a href="#_structure" rel="no-refresh">Structure</a> |
|
|
26
|
-
<a href="#_files" rel="no-refresh">Files</a> |
|
|
27
|
-
<a href="#_info" rel="no-refresh">Info Dump</a>
|
|
28
|
-
<hr>
|
|
22
|
+
content = `
|
|
23
|
+
<a href="#_tokens" rel="no-refresh">Tokens</a> |
|
|
24
|
+
<a href="#_statements" rel="no-refresh">Statements</a> |
|
|
25
|
+
<a href="#_structure" rel="no-refresh">Structure</a> |
|
|
26
|
+
<a href="#_files" rel="no-refresh">Files</a> |
|
|
27
|
+
<a href="#_info" rel="no-refresh">Info Dump</a>
|
|
28
|
+
<hr>
|
|
29
29
|
` +
|
|
30
30
|
"<tt>" + textDocument.uri + " (" +
|
|
31
31
|
(position.line + 1) + ", " +
|
package/build/src/registry.js
CHANGED
|
@@ -17,10 +17,10 @@ class SevenBitAscii {
|
|
|
17
17
|
key: "7bit_ascii",
|
|
18
18
|
title: "Check for 7bit ascii",
|
|
19
19
|
shortDescription: `Only allow characters from the 7bit ASCII set.`,
|
|
20
|
-
extendedInformation: `https://docs.abapopenchecks.org/checks/05/
|
|
21
|
-
|
|
22
|
-
https://help.sap.com/doc/abapdocu_750_index_htm/7.50/en-US/abencharacter_set_guidl.htm
|
|
23
|
-
|
|
20
|
+
extendedInformation: `https://docs.abapopenchecks.org/checks/05/
|
|
21
|
+
|
|
22
|
+
https://help.sap.com/doc/abapdocu_750_index_htm/7.50/en-US/abencharacter_set_guidl.htm
|
|
23
|
+
|
|
24
24
|
Checkes files with extensions ".abap" and ".asddls"`,
|
|
25
25
|
tags: [_irule_1.RuleTag.SingleFile],
|
|
26
26
|
badExample: `WRITE '뽑'.`,
|