@abaplint/core 2.85.34 → 2.85.37
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/src/abap/flow/flow_graph.js +7 -7
- package/build/src/lsp/help.js +7 -7
- package/build/src/registry.js +1 -1
- package/build/src/rules/7bit_ascii.js +2 -2
- package/build/src/rules/abapdoc.js +1 -1
- package/build/src/rules/align_parameters.js +33 -33
- package/build/src/rules/ambiguous_statement.js +5 -5
- package/build/src/rules/avoid_use.js +6 -6
- package/build/src/rules/begin_end_names.js +4 -4
- package/build/src/rules/begin_single_include.js +12 -12
- package/build/src/rules/call_transaction_authority_check.js +3 -3
- package/build/src/rules/chain_mainly_declarations.js +4 -4
- 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_no_handler_pragma.js +8 -8
- package/build/src/rules/check_subrc.js +8 -8
- 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/dangerous_statement.js +1 -1
- package/build/src/rules/downport.js +95 -65
- package/build/src/rules/exit_or_check.js +3 -3
- 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/functional_writing.js +17 -17
- package/build/src/rules/global_class.js +10 -10
- package/build/src/rules/identical_conditions.js +2 -2
- package/build/src/rules/identical_contents.js +14 -14
- package/build/src/rules/identical_descriptions.js +4 -4
- package/build/src/rules/if_in_if.js +7 -7
- package/build/src/rules/implement_methods.js +3 -3
- package/build/src/rules/in_statement_indentation.js +11 -11
- package/build/src/rules/intf_referencing_clas.js +3 -3
- 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 +2 -2
- 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 +3 -3
- package/build/src/rules/nesting.js +1 -1
- package/build/src/rules/no_chained_assignment.js +1 -1
- package/build/src/rules/no_public_attributes.js +1 -1
- package/build/src/rules/no_yoda_conditions.js +4 -4
- package/build/src/rules/obsolete_statement.js +40 -40
- 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 +7 -7
- package/build/src/rules/prefer_raise_exception_new.js +3 -3
- package/build/src/rules/prefer_returning_to_exporting.js +1 -1
- package/build/src/rules/prefer_xsdbool.js +2 -2
- package/build/src/rules/remove_descriptions.js +4 -4
- package/build/src/rules/rfc_error_handling.js +9 -9
- package/build/src/rules/select_add_order_by.js +5 -5
- package/build/src/rules/select_performance.js +2 -2
- package/build/src/rules/sicf_consistency.js +4 -4
- package/build/src/rules/space_before_dot.js +2 -2
- package/build/src/rules/start_at_tab.js +1 -1
- package/build/src/rules/sy_modification.js +2 -2
- package/build/src/rules/tabl_enhancement_category.js +2 -2
- package/build/src/rules/unused_methods.js +9 -9
- package/build/src/rules/unused_variables.js +6 -6
- package/build/src/rules/use_bool_expression.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/build/src/utils/include_graph.js +3 -0
- package/package.json +66 -66
|
@@ -19,6 +19,8 @@ const _typed_identifier_1 = require("../abap/types/_typed_identifier");
|
|
|
19
19
|
const basic_1 = require("../abap/types/basic");
|
|
20
20
|
const config_1 = require("../config");
|
|
21
21
|
const tokens_1 = require("../abap/1_lexer/tokens");
|
|
22
|
+
const include_graph_1 = require("../utils/include_graph");
|
|
23
|
+
const objects_1 = require("../objects");
|
|
22
24
|
// todo: refactor each sub-rule to new classes?
|
|
23
25
|
// todo: add configuration
|
|
24
26
|
class DownportConf extends _basic_rule_config_1.BasicRuleConfig {
|
|
@@ -33,33 +35,33 @@ class Downport {
|
|
|
33
35
|
key: "downport",
|
|
34
36
|
title: "Downport statement",
|
|
35
37
|
shortDescription: `Experimental downport functionality`,
|
|
36
|
-
extendedInformation: `Much like the 'commented_code' rule this rule loops through unknown statements and tries parsing with
|
|
37
|
-
a higher level language version. If successful, various rules are applied to downport the statement.
|
|
38
|
-
Target downport version is always v702, thus rule is only enabled if target version is v702.
|
|
39
|
-
|
|
40
|
-
Current rules:
|
|
41
|
-
* NEW transformed to CREATE OBJECT, opposite of https://rules.abaplint.org/use_new/
|
|
42
|
-
* DATA() definitions are outlined, opposite of https://rules.abaplint.org/prefer_inline/
|
|
43
|
-
* FIELD-SYMBOL() definitions are outlined
|
|
44
|
-
* CONV is outlined
|
|
45
|
-
* COND is outlined
|
|
46
|
-
* REDUCE is outlined
|
|
47
|
-
* SWITCH is outlined
|
|
48
|
-
* APPEND expression is outlined
|
|
49
|
-
* EMPTY KEY is changed to DEFAULT KEY, opposite of DEFAULT KEY in https://rules.abaplint.org/avoid_use/
|
|
50
|
-
* CAST changed to ?=
|
|
51
|
-
* LOOP AT method_call( ) is outlined
|
|
52
|
-
* VALUE # with structure fields
|
|
53
|
-
* VALUE # with internal table lines
|
|
54
|
-
* Table Expressions are outlined
|
|
55
|
-
* SELECT INTO @DATA definitions are outlined
|
|
56
|
-
* Some occurrences of string template formatting option ALPHA changed to function module call
|
|
57
|
-
* SELECT/INSERT/MODIFY/DELETE/UPDATE "," in field list removed, "@" in source/targets removed
|
|
58
|
-
* PARTIALLY IMPLEMENTED removed, it can be quick fixed via rule implement_methods
|
|
59
|
-
* RAISE EXCEPTION ... MESSAGE
|
|
60
|
-
* Moving with +=, -=, /=, *=, &&= is expanded
|
|
61
|
-
* line_exists and line_index is downported to READ TABLE
|
|
62
|
-
|
|
38
|
+
extendedInformation: `Much like the 'commented_code' rule this rule loops through unknown statements and tries parsing with
|
|
39
|
+
a higher level language version. If successful, various rules are applied to downport the statement.
|
|
40
|
+
Target downport version is always v702, thus rule is only enabled if target version is v702.
|
|
41
|
+
|
|
42
|
+
Current rules:
|
|
43
|
+
* NEW transformed to CREATE OBJECT, opposite of https://rules.abaplint.org/use_new/
|
|
44
|
+
* DATA() definitions are outlined, opposite of https://rules.abaplint.org/prefer_inline/
|
|
45
|
+
* FIELD-SYMBOL() definitions are outlined
|
|
46
|
+
* CONV is outlined
|
|
47
|
+
* COND is outlined
|
|
48
|
+
* REDUCE is outlined
|
|
49
|
+
* SWITCH is outlined
|
|
50
|
+
* APPEND expression is outlined
|
|
51
|
+
* EMPTY KEY is changed to DEFAULT KEY, opposite of DEFAULT KEY in https://rules.abaplint.org/avoid_use/
|
|
52
|
+
* CAST changed to ?=
|
|
53
|
+
* LOOP AT method_call( ) is outlined
|
|
54
|
+
* VALUE # with structure fields
|
|
55
|
+
* VALUE # with internal table lines
|
|
56
|
+
* Table Expressions are outlined
|
|
57
|
+
* SELECT INTO @DATA definitions are outlined
|
|
58
|
+
* Some occurrences of string template formatting option ALPHA changed to function module call
|
|
59
|
+
* SELECT/INSERT/MODIFY/DELETE/UPDATE "," in field list removed, "@" in source/targets removed
|
|
60
|
+
* PARTIALLY IMPLEMENTED removed, it can be quick fixed via rule implement_methods
|
|
61
|
+
* RAISE EXCEPTION ... MESSAGE
|
|
62
|
+
* Moving with +=, -=, /=, *=, &&= is expanded
|
|
63
|
+
* line_exists and line_index is downported to READ TABLE
|
|
64
|
+
|
|
63
65
|
Only one transformation is applied to a statement at a time, so multiple steps might be required to do the full downport.`,
|
|
64
66
|
tags: [_irule_1.RuleTag.Experimental, _irule_1.RuleTag.Downport, _irule_1.RuleTag.Quickfix],
|
|
65
67
|
};
|
|
@@ -75,10 +77,12 @@ Only one transformation is applied to a statement at a time, so multiple steps m
|
|
|
75
77
|
const version = this.lowReg.getConfig().getVersion();
|
|
76
78
|
if (version === version_1.Version.v702 || version === version_1.Version.OpenABAP) {
|
|
77
79
|
this.initHighReg();
|
|
80
|
+
this.graph = new include_graph_1.IncludeGraph(reg);
|
|
78
81
|
}
|
|
79
82
|
return this;
|
|
80
83
|
}
|
|
81
84
|
run(lowObj) {
|
|
85
|
+
var _a;
|
|
82
86
|
const ret = [];
|
|
83
87
|
this.counter = 1;
|
|
84
88
|
const version = this.lowReg.getConfig().getVersion();
|
|
@@ -92,7 +96,20 @@ Only one transformation is applied to a statement at a time, so multiple steps m
|
|
|
92
96
|
if (highObj === undefined || !(highObj instanceof _abap_object_1.ABAPObject)) {
|
|
93
97
|
return ret;
|
|
94
98
|
}
|
|
95
|
-
|
|
99
|
+
let highSyntaxObj = highObj;
|
|
100
|
+
// for includes do the syntax check via a main program
|
|
101
|
+
if (lowObj instanceof objects_1.Program && lowObj.isInclude()) {
|
|
102
|
+
const mains = this.graph.listMainForInclude((_a = lowObj.getMainABAPFile()) === null || _a === void 0 ? void 0 : _a.getFilename());
|
|
103
|
+
if (mains.length <= 0) {
|
|
104
|
+
return [];
|
|
105
|
+
}
|
|
106
|
+
const f = this.highReg.getFileByName(mains[0]);
|
|
107
|
+
if (f === undefined) {
|
|
108
|
+
return [];
|
|
109
|
+
}
|
|
110
|
+
highSyntaxObj = this.highReg.findObjectForFile(f);
|
|
111
|
+
}
|
|
112
|
+
const highSyntax = new syntax_1.SyntaxLogic(this.highReg, highSyntaxObj).run();
|
|
96
113
|
for (const lowFile of lowObj.getABAPFiles()) {
|
|
97
114
|
const highFile = highObj.getABAPFileByName(lowFile.getFilename());
|
|
98
115
|
if (highFile === undefined) {
|
|
@@ -242,7 +259,6 @@ Only one transformation is applied to a statement at a time, so multiple steps m
|
|
|
242
259
|
if (found) {
|
|
243
260
|
return found;
|
|
244
261
|
}
|
|
245
|
-
// note: line_exists() must be replaced before this call
|
|
246
262
|
found = this.replaceTableExpression(high, lowFile, highSyntax);
|
|
247
263
|
if (found) {
|
|
248
264
|
return found;
|
|
@@ -284,7 +300,7 @@ Only one transformation is applied to a statement at a time, so multiple steps m
|
|
|
284
300
|
addFix(c.getFirstToken());
|
|
285
301
|
}
|
|
286
302
|
}
|
|
287
|
-
for (const fieldList of high.
|
|
303
|
+
for (const fieldList of high.findAllExpressionsMulti([Expressions.SQLFieldList, Expressions.SQLFieldListLoop], true)) {
|
|
288
304
|
for (const token of fieldList.getDirectTokens()) {
|
|
289
305
|
if (token.getStr() === ",") {
|
|
290
306
|
addFix(token);
|
|
@@ -366,10 +382,10 @@ Only one transformation is applied to a statement at a time, so multiple steps m
|
|
|
366
382
|
const fieldName = f.concatTokens();
|
|
367
383
|
fieldDefinition += indentation + " " + fieldName + " TYPE " + tableName + "-" + fieldName + ",\n";
|
|
368
384
|
}
|
|
369
|
-
fieldDefinition = `DATA: BEGIN OF ${name},
|
|
385
|
+
fieldDefinition = `DATA: BEGIN OF ${name},
|
|
370
386
|
${fieldDefinition}${indentation} END OF ${name}.`;
|
|
371
387
|
}
|
|
372
|
-
const fix1 = edit_helper_1.EditHelper.insertAt(lowFile, high.getStart(), `${fieldDefinition}
|
|
388
|
+
const fix1 = edit_helper_1.EditHelper.insertAt(lowFile, high.getStart(), `${fieldDefinition}
|
|
373
389
|
${indentation}`);
|
|
374
390
|
const fix2 = edit_helper_1.EditHelper.replaceRange(lowFile, inlineData.getFirstToken().getStart(), inlineData.getLastToken().getEnd(), name);
|
|
375
391
|
const fix = edit_helper_1.EditHelper.merge(fix2, fix1);
|
|
@@ -410,12 +426,12 @@ ${indentation}`);
|
|
|
410
426
|
}
|
|
411
427
|
const uniqueName = this.uniqueName(high.getFirstToken().getStart(), lowFile.getFilename(), highSyntax);
|
|
412
428
|
const name = ((_c = inlineData.findFirstExpression(Expressions.TargetField)) === null || _c === void 0 ? void 0 : _c.concatTokens()) || "error";
|
|
413
|
-
let fix1 = edit_helper_1.EditHelper.insertAt(lowFile, high.getStart(), `TYPES: BEGIN OF ${uniqueName},
|
|
414
|
-
${fieldDefinitions}${indentation} END OF ${uniqueName}.
|
|
415
|
-
${indentation}DATA ${name} TYPE STANDARD TABLE OF ${uniqueName} WITH DEFAULT KEY.
|
|
429
|
+
let fix1 = edit_helper_1.EditHelper.insertAt(lowFile, high.getStart(), `TYPES: BEGIN OF ${uniqueName},
|
|
430
|
+
${fieldDefinitions}${indentation} END OF ${uniqueName}.
|
|
431
|
+
${indentation}DATA ${name} TYPE STANDARD TABLE OF ${uniqueName} WITH DEFAULT KEY.
|
|
416
432
|
${indentation}`);
|
|
417
433
|
if (fieldDefinitions === "") {
|
|
418
|
-
fix1 = edit_helper_1.EditHelper.insertAt(lowFile, high.getStart(), `DATA ${name} TYPE STANDARD TABLE OF ${tableName} WITH DEFAULT KEY.
|
|
434
|
+
fix1 = edit_helper_1.EditHelper.insertAt(lowFile, high.getStart(), `DATA ${name} TYPE STANDARD TABLE OF ${tableName} WITH DEFAULT KEY.
|
|
419
435
|
${indentation}`);
|
|
420
436
|
}
|
|
421
437
|
const fix2 = edit_helper_1.EditHelper.replaceRange(lowFile, inlineData.getFirstToken().getStart(), inlineData.getLastToken().getEnd(), name);
|
|
@@ -436,7 +452,7 @@ ${indentation}`);
|
|
|
436
452
|
const uniqueName = this.uniqueName(high.getFirstToken().getStart(), lowFile.getFilename(), highSyntax);
|
|
437
453
|
const indentation = " ".repeat(high.getFirstToken().getStart().getCol() - 1);
|
|
438
454
|
const firstToken = high.getFirstToken();
|
|
439
|
-
const fix1 = edit_helper_1.EditHelper.insertAt(lowFile, firstToken.getStart(), `DATA ${uniqueName} LIKE LINE OF ${target === null || target === void 0 ? void 0 : target.concatTokens()}.
|
|
455
|
+
const fix1 = edit_helper_1.EditHelper.insertAt(lowFile, firstToken.getStart(), `DATA ${uniqueName} LIKE LINE OF ${target === null || target === void 0 ? void 0 : target.concatTokens()}.
|
|
440
456
|
${indentation}${uniqueName} = ${source.concatTokens()}.\n${indentation}`);
|
|
441
457
|
const fix2 = edit_helper_1.EditHelper.replaceRange(lowFile, source.getFirstToken().getStart(), source.getLastToken().getEnd(), uniqueName);
|
|
442
458
|
const fix = edit_helper_1.EditHelper.merge(fix2, fix1);
|
|
@@ -450,6 +466,11 @@ ${indentation}${uniqueName} = ${source.concatTokens()}.\n${indentation}`);
|
|
|
450
466
|
if (tableExpression === undefined) {
|
|
451
467
|
continue;
|
|
452
468
|
}
|
|
469
|
+
const concat = node.concatTokens().toUpperCase();
|
|
470
|
+
if (concat.includes(" LINE_EXISTS( ") || concat.includes(" LINE_INDEX( ")) {
|
|
471
|
+
// note: line_exists() must be replaced before handling table expressions
|
|
472
|
+
continue;
|
|
473
|
+
}
|
|
453
474
|
let pre = "";
|
|
454
475
|
let startToken = undefined;
|
|
455
476
|
for (const child of fieldChain.getChildren()) {
|
|
@@ -480,11 +501,11 @@ ${indentation}${uniqueName} = ${source.concatTokens()}.\n${indentation}`);
|
|
|
480
501
|
const uniqueName = this.uniqueName(node.getFirstToken().getStart(), lowFile.getFilename(), highSyntax);
|
|
481
502
|
const indentation = " ".repeat(node.getFirstToken().getStart().getCol() - 1);
|
|
482
503
|
const firstToken = node.getFirstToken();
|
|
483
|
-
const fix1 = edit_helper_1.EditHelper.insertAt(lowFile, firstToken.getStart(), `DATA ${uniqueName} LIKE LINE OF ${pre}.
|
|
484
|
-
${indentation}READ TABLE ${pre} ${condition}INTO ${uniqueName}.
|
|
485
|
-
${indentation}IF sy-subrc <> 0.
|
|
486
|
-
${indentation} RAISE EXCEPTION TYPE cx_sy_itab_line_not_found.
|
|
487
|
-
${indentation}ENDIF.
|
|
504
|
+
const fix1 = edit_helper_1.EditHelper.insertAt(lowFile, firstToken.getStart(), `DATA ${uniqueName} LIKE LINE OF ${pre}.
|
|
505
|
+
${indentation}READ TABLE ${pre} ${condition}INTO ${uniqueName}.
|
|
506
|
+
${indentation}IF sy-subrc <> 0.
|
|
507
|
+
${indentation} RAISE EXCEPTION TYPE cx_sy_itab_line_not_found.
|
|
508
|
+
${indentation}ENDIF.
|
|
488
509
|
${indentation}`);
|
|
489
510
|
const fix2 = edit_helper_1.EditHelper.replaceRange(lowFile, startToken.getStart(), tableExpression.getLastToken().getEnd(), uniqueName);
|
|
490
511
|
const fix = edit_helper_1.EditHelper.merge(fix2, fix1);
|
|
@@ -509,7 +530,7 @@ ${indentation}`);
|
|
|
509
530
|
const className = classNames[0].concatTokens();
|
|
510
531
|
const targetName = (_b = target.findFirstExpression(Expressions.TargetField)) === null || _b === void 0 ? void 0 : _b.concatTokens();
|
|
511
532
|
const indentation = " ".repeat(node.getFirstToken().getStart().getCol() - 1);
|
|
512
|
-
const code = ` DATA ${targetName} TYPE REF TO ${className}.
|
|
533
|
+
const code = ` DATA ${targetName} TYPE REF TO ${className}.
|
|
513
534
|
${indentation}CATCH ${className} INTO ${targetName}.`;
|
|
514
535
|
const fix = edit_helper_1.EditHelper.replaceRange(lowFile, node.getStart(), node.getEnd(), code);
|
|
515
536
|
return issue_1.Issue.atToken(lowFile, node.getFirstToken(), "Outline DATA", this.getMetadata().key, this.conf.severity, fix);
|
|
@@ -620,11 +641,11 @@ ${indentation}CATCH ${className} INTO ${targetName}.`;
|
|
|
620
641
|
const uniqueName1 = this.uniqueName(node.getFirstToken().getStart(), lowFile.getFilename(), highSyntax);
|
|
621
642
|
const uniqueName2 = this.uniqueName(node.getFirstToken().getStart(), lowFile.getFilename(), highSyntax);
|
|
622
643
|
const indentation = " ".repeat(node.getFirstToken().getStart().getCol() - 1);
|
|
623
|
-
const abap = `DATA ${uniqueName1} LIKE if_t100_message=>t100key.
|
|
624
|
-
${indentation}${uniqueName1}-msgid = ${id}.
|
|
625
|
-
${indentation}${uniqueName1}-msgno = ${number}.
|
|
626
|
-
${indentation}DATA ${uniqueName2} TYPE REF TO ${className}.
|
|
627
|
-
${indentation}CREATE OBJECT ${uniqueName2} EXPORTING textid = ${uniqueName1}.
|
|
644
|
+
const abap = `DATA ${uniqueName1} LIKE if_t100_message=>t100key.
|
|
645
|
+
${indentation}${uniqueName1}-msgid = ${id}.
|
|
646
|
+
${indentation}${uniqueName1}-msgno = ${number}.
|
|
647
|
+
${indentation}DATA ${uniqueName2} TYPE REF TO ${className}.
|
|
648
|
+
${indentation}CREATE OBJECT ${uniqueName2} EXPORTING textid = ${uniqueName1}.
|
|
628
649
|
${indentation}RAISE EXCEPTION ${uniqueName2}.`;
|
|
629
650
|
const fix = edit_helper_1.EditHelper.replaceRange(lowFile, node.getStart(), node.getEnd(), abap);
|
|
630
651
|
return issue_1.Issue.atToken(lowFile, startToken, "Downport RAISE MESSAGE", this.getMetadata().key, this.conf.severity, fix);
|
|
@@ -761,10 +782,10 @@ ${indentation}RAISE EXCEPTION ${uniqueName2}.`;
|
|
|
761
782
|
const indentation = " ".repeat(node.getFirstToken().getStart().getCol() - 1);
|
|
762
783
|
const source = (_b = templateSource === null || templateSource === void 0 ? void 0 : templateSource.findDirectExpression(Expressions.Source)) === null || _b === void 0 ? void 0 : _b.concatTokens();
|
|
763
784
|
const topTarget = (_c = node.findDirectExpression(Expressions.Target)) === null || _c === void 0 ? void 0 : _c.concatTokens();
|
|
764
|
-
const code = `CALL FUNCTION '${functionName}'
|
|
765
|
-
${indentation} EXPORTING
|
|
766
|
-
${indentation} input = ${source}
|
|
767
|
-
${indentation} IMPORTING
|
|
785
|
+
const code = `CALL FUNCTION '${functionName}'
|
|
786
|
+
${indentation} EXPORTING
|
|
787
|
+
${indentation} input = ${source}
|
|
788
|
+
${indentation} IMPORTING
|
|
768
789
|
${indentation} output = ${topTarget}.`;
|
|
769
790
|
const fix = edit_helper_1.EditHelper.replaceRange(lowFile, node.getFirstToken().getStart(), node.getLastToken().getEnd(), code);
|
|
770
791
|
return issue_1.Issue.atToken(lowFile, node.getFirstToken(), "Downport ALPHA", this.getMetadata().key, this.conf.severity, fix);
|
|
@@ -971,17 +992,26 @@ ${indentation} output = ${topTarget}.`;
|
|
|
971
992
|
return undefined;
|
|
972
993
|
}
|
|
973
994
|
outlineValue(node, lowFile, highSyntax) {
|
|
995
|
+
var _a;
|
|
974
996
|
const allSources = node.findAllExpressionsRecursive(Expressions.Source);
|
|
975
|
-
for (const
|
|
976
|
-
const firstToken =
|
|
997
|
+
for (const s of allSources) {
|
|
998
|
+
const firstToken = s.getFirstToken();
|
|
977
999
|
if (firstToken.getStr().toUpperCase() !== "VALUE") {
|
|
978
1000
|
continue;
|
|
979
1001
|
}
|
|
980
|
-
|
|
1002
|
+
let type = this.findType(s, lowFile, highSyntax);
|
|
981
1003
|
if (type === undefined) {
|
|
982
|
-
|
|
1004
|
+
if (node.get() instanceof Statements.Move && node.findDirectExpression(Expressions.Source) === s) {
|
|
1005
|
+
type = "LIKE " + ((_a = node.findDirectExpression(Expressions.Target)) === null || _a === void 0 ? void 0 : _a.concatTokens());
|
|
1006
|
+
}
|
|
1007
|
+
if (type === undefined) {
|
|
1008
|
+
continue;
|
|
1009
|
+
}
|
|
1010
|
+
}
|
|
1011
|
+
else {
|
|
1012
|
+
type = "TYPE " + type;
|
|
983
1013
|
}
|
|
984
|
-
const valueBody =
|
|
1014
|
+
const valueBody = s.findDirectExpression(Expressions.ValueBody);
|
|
985
1015
|
const uniqueName = this.uniqueName(firstToken.getStart(), lowFile.getFilename(), highSyntax);
|
|
986
1016
|
let indentation = " ".repeat(node.getFirstToken().getStart().getCol() - 1);
|
|
987
1017
|
let body = "";
|
|
@@ -1021,11 +1051,11 @@ ${indentation} output = ${topTarget}.`;
|
|
|
1021
1051
|
indentation = indentation.substring(2);
|
|
1022
1052
|
body += indentation + outlineFor.end + `.\n`;
|
|
1023
1053
|
}
|
|
1024
|
-
const abap = `DATA ${uniqueName}
|
|
1054
|
+
const abap = `DATA ${uniqueName} ${type}.\n` +
|
|
1025
1055
|
body +
|
|
1026
1056
|
indentation;
|
|
1027
1057
|
const fix1 = edit_helper_1.EditHelper.insertAt(lowFile, node.getFirstToken().getStart(), abap);
|
|
1028
|
-
const fix2 = edit_helper_1.EditHelper.replaceRange(lowFile, firstToken.getStart(),
|
|
1058
|
+
const fix2 = edit_helper_1.EditHelper.replaceRange(lowFile, firstToken.getStart(), s.getLastToken().getEnd(), uniqueName);
|
|
1029
1059
|
const fix = edit_helper_1.EditHelper.merge(fix2, fix1);
|
|
1030
1060
|
return issue_1.Issue.atToken(lowFile, firstToken, "Downport VALUE", this.getMetadata().key, this.conf.severity, fix);
|
|
1031
1061
|
}
|
|
@@ -1136,12 +1166,10 @@ ${indentation} output = ${topTarget}.`;
|
|
|
1136
1166
|
continue;
|
|
1137
1167
|
}
|
|
1138
1168
|
const found = spag.findVariable(name);
|
|
1139
|
-
if (found === undefined
|
|
1169
|
+
if (found === undefined
|
|
1170
|
+
|| found.getType() instanceof basic_1.VoidType) {
|
|
1140
1171
|
continue;
|
|
1141
1172
|
}
|
|
1142
|
-
else if (found.getType() instanceof basic_1.VoidType) {
|
|
1143
|
-
return issue_1.Issue.atToken(lowFile, i.getFirstToken(), "Error outlining voided type", this.getMetadata().key, this.conf.severity);
|
|
1144
|
-
}
|
|
1145
1173
|
const type = found.getType().getQualifiedName() ? (_b = found.getType().getQualifiedName()) === null || _b === void 0 ? void 0 : _b.toLowerCase() : found.getType().toABAP();
|
|
1146
1174
|
const code = `DATA ${name} TYPE ${type}.\n` +
|
|
1147
1175
|
" ".repeat(node.getFirstToken().getStart().getCol() - 1);
|
|
@@ -1297,9 +1325,11 @@ ${indentation} output = ${topTarget}.`;
|
|
|
1297
1325
|
var _a, _b;
|
|
1298
1326
|
const spag = highSyntax.spaghetti.lookupPosition(node.getFirstToken().getStart(), lowFile.getFilename());
|
|
1299
1327
|
for (const r of (spag === null || spag === void 0 ? void 0 : spag.getData().references) || []) {
|
|
1328
|
+
if (r.referenceType !== _reference_1.ReferenceType.BuiltinMethodReference) {
|
|
1329
|
+
continue;
|
|
1330
|
+
}
|
|
1300
1331
|
const func = r.position.getName().toUpperCase();
|
|
1301
|
-
if (
|
|
1302
|
-
&& (func === "LINE_EXISTS" || func === "LINE_INDEX")) {
|
|
1332
|
+
if (func === "LINE_EXISTS" || func === "LINE_INDEX") {
|
|
1303
1333
|
const token = r.position.getToken();
|
|
1304
1334
|
const expression = this.findMethodCallExpression(node, token);
|
|
1305
1335
|
if (expression === undefined) {
|
|
@@ -24,10 +24,10 @@ class ExitOrCheck extends _abap_rule_1.ABAPRule {
|
|
|
24
24
|
return {
|
|
25
25
|
key: "exit_or_check",
|
|
26
26
|
title: "Find EXIT or CHECK outside loops",
|
|
27
|
-
shortDescription: `Detects usages of EXIT or CHECK statements outside of loops.
|
|
27
|
+
shortDescription: `Detects usages of EXIT or CHECK statements outside of loops.
|
|
28
28
|
Use RETURN to leave procesing blocks instead.`,
|
|
29
|
-
extendedInformation: `https://help.sap.com/doc/abapdocu_751_index_htm/7.51/en-US/abenleave_processing_blocks.htm
|
|
30
|
-
https://help.sap.com/doc/abapdocu_750_index_htm/7.50/en-US/abapcheck_processing_blocks.htm
|
|
29
|
+
extendedInformation: `https://help.sap.com/doc/abapdocu_751_index_htm/7.51/en-US/abenleave_processing_blocks.htm
|
|
30
|
+
https://help.sap.com/doc/abapdocu_750_index_htm/7.50/en-US/abapcheck_processing_blocks.htm
|
|
31
31
|
https://github.com/SAP/styleguides/blob/main/clean-abap/CleanABAP.md#check-vs-return`,
|
|
32
32
|
tags: [_irule_1.RuleTag.Styleguide, _irule_1.RuleTag.SingleFile, _irule_1.RuleTag.Quickfix],
|
|
33
33
|
};
|
|
@@ -22,7 +22,7 @@ class Exporting extends _abap_rule_1.ABAPRule {
|
|
|
22
22
|
shortDescription: `Detects EXPORTING statements which can be omitted.`,
|
|
23
23
|
badExample: `call_method( EXPORTING foo = bar ).`,
|
|
24
24
|
goodExample: `call_method( foo = bar ).`,
|
|
25
|
-
extendedInformation: `https://github.com/SAP/styleguides/blob/main/clean-abap/CleanABAP.md#omit-the-optional-keyword-exporting
|
|
25
|
+
extendedInformation: `https://github.com/SAP/styleguides/blob/main/clean-abap/CleanABAP.md#omit-the-optional-keyword-exporting
|
|
26
26
|
https://docs.abapopenchecks.org/checks/30/`,
|
|
27
27
|
tags: [_irule_1.RuleTag.Styleguide, _irule_1.RuleTag.Quickfix, _irule_1.RuleTag.SingleFile],
|
|
28
28
|
};
|
|
@@ -26,7 +26,7 @@ class ForbiddenIdentifier extends _abap_rule_1.ABAPRule {
|
|
|
26
26
|
key: "forbidden_identifier",
|
|
27
27
|
title: "Forbidden Identifier",
|
|
28
28
|
shortDescription: `Forbid use of specified identifiers, list of regex.`,
|
|
29
|
-
extendedInformation: `Used in the transpiler to find javascript keywords in ABAP identifiers,
|
|
29
|
+
extendedInformation: `Used in the transpiler to find javascript keywords in ABAP identifiers,
|
|
30
30
|
https://github.com/abaplint/transpiler/blob/bda94b8b56e2b7f2f87be2168f12361aa530220e/packages/transpiler/src/validation.ts#L44`,
|
|
31
31
|
tags: [_irule_1.RuleTag.SingleFile],
|
|
32
32
|
};
|
|
@@ -28,8 +28,8 @@ class ForbiddenVoidType {
|
|
|
28
28
|
key: "forbidden_void_type",
|
|
29
29
|
title: "Forbidden Void Types",
|
|
30
30
|
shortDescription: `Avoid usage of specified void types.`,
|
|
31
|
-
extendedInformation: `Inspiration:
|
|
32
|
-
BOOLEAN, BOOLE_D, CHAR01, CHAR1, CHAR10, CHAR12, CHAR128, CHAR2, CHAR20, CHAR4, CHAR70,
|
|
31
|
+
extendedInformation: `Inspiration:
|
|
32
|
+
BOOLEAN, BOOLE_D, CHAR01, CHAR1, CHAR10, CHAR12, CHAR128, CHAR2, CHAR20, CHAR4, CHAR70,
|
|
33
33
|
DATS, TIMS, DATUM, FLAG, INT4, NUMC3, NUMC4, SAP_BOOL, TEXT25, TEXT80, X255, XFELD`,
|
|
34
34
|
};
|
|
35
35
|
}
|
|
@@ -28,26 +28,26 @@ class FunctionalWriting extends _abap_rule_1.ABAPRule {
|
|
|
28
28
|
key: "functional_writing",
|
|
29
29
|
title: "Use functional writing",
|
|
30
30
|
shortDescription: `Detects usage of call method when functional style calls can be used.`,
|
|
31
|
-
extendedInformation: `https://github.com/SAP/styleguides/blob/main/clean-abap/CleanABAP.md#prefer-functional-to-procedural-calls
|
|
31
|
+
extendedInformation: `https://github.com/SAP/styleguides/blob/main/clean-abap/CleanABAP.md#prefer-functional-to-procedural-calls
|
|
32
32
|
https://docs.abapopenchecks.org/checks/07/`,
|
|
33
33
|
tags: [_irule_1.RuleTag.Styleguide, _irule_1.RuleTag.Quickfix, _irule_1.RuleTag.SingleFile],
|
|
34
|
-
badExample: `CALL METHOD zcl_class=>method( ).
|
|
35
|
-
CALL METHOD cl_abap_typedescr=>describe_by_name
|
|
36
|
-
EXPORTING
|
|
37
|
-
p_name = 'NAME'
|
|
38
|
-
RECEIVING
|
|
39
|
-
p_descr_ref = lr_typedescr
|
|
40
|
-
EXCEPTIONS
|
|
41
|
-
type_not_found = 1
|
|
34
|
+
badExample: `CALL METHOD zcl_class=>method( ).
|
|
35
|
+
CALL METHOD cl_abap_typedescr=>describe_by_name
|
|
36
|
+
EXPORTING
|
|
37
|
+
p_name = 'NAME'
|
|
38
|
+
RECEIVING
|
|
39
|
+
p_descr_ref = lr_typedescr
|
|
40
|
+
EXCEPTIONS
|
|
41
|
+
type_not_found = 1
|
|
42
42
|
OTHERS = 2.`,
|
|
43
|
-
goodExample: `zcl_class=>method( ).
|
|
44
|
-
cl_abap_typedescr=>describe_by_name(
|
|
45
|
-
EXPORTING
|
|
46
|
-
p_name = 'NAME'
|
|
47
|
-
RECEIVING
|
|
48
|
-
p_descr_ref = lr_typedescr
|
|
49
|
-
EXCEPTIONS
|
|
50
|
-
type_not_found = 1
|
|
43
|
+
goodExample: `zcl_class=>method( ).
|
|
44
|
+
cl_abap_typedescr=>describe_by_name(
|
|
45
|
+
EXPORTING
|
|
46
|
+
p_name = 'NAME'
|
|
47
|
+
RECEIVING
|
|
48
|
+
p_descr_ref = lr_typedescr
|
|
49
|
+
EXCEPTIONS
|
|
50
|
+
type_not_found = 1
|
|
51
51
|
OTHERS = 2 ).`,
|
|
52
52
|
};
|
|
53
53
|
}
|
|
@@ -18,16 +18,16 @@ class GlobalClass extends _abap_rule_1.ABAPRule {
|
|
|
18
18
|
return {
|
|
19
19
|
key: "global_class",
|
|
20
20
|
title: "Global class checks",
|
|
21
|
-
shortDescription: `Checks related to global classes.
|
|
22
|
-
|
|
23
|
-
* global classes must be in own files
|
|
24
|
-
|
|
25
|
-
* file names must match class name
|
|
26
|
-
|
|
27
|
-
* file names must match interface name
|
|
28
|
-
|
|
29
|
-
* global classes must be global definitions
|
|
30
|
-
|
|
21
|
+
shortDescription: `Checks related to global classes.
|
|
22
|
+
|
|
23
|
+
* global classes must be in own files
|
|
24
|
+
|
|
25
|
+
* file names must match class name
|
|
26
|
+
|
|
27
|
+
* file names must match interface name
|
|
28
|
+
|
|
29
|
+
* global classes must be global definitions
|
|
30
|
+
|
|
31
31
|
* global interfaces must be global definitions`,
|
|
32
32
|
tags: [_irule_1.RuleTag.Syntax],
|
|
33
33
|
};
|
|
@@ -33,8 +33,8 @@ class IdenticalConditions extends _abap_rule_1.ABAPRule {
|
|
|
33
33
|
return {
|
|
34
34
|
key: "identical_conditions",
|
|
35
35
|
title: "Identical conditions",
|
|
36
|
-
shortDescription: `Find identical conditions in IF + CASE + WHILE etc
|
|
37
|
-
|
|
36
|
+
shortDescription: `Find identical conditions in IF + CASE + WHILE etc
|
|
37
|
+
|
|
38
38
|
Prerequsites: code is pretty printed with identical cAsE`,
|
|
39
39
|
tags: [_irule_1.RuleTag.SingleFile],
|
|
40
40
|
};
|
|
@@ -20,23 +20,23 @@ class IdenticalContents extends _abap_rule_1.ABAPRule {
|
|
|
20
20
|
key: "identical_contents",
|
|
21
21
|
title: "Identical contents",
|
|
22
22
|
shortDescription: `Find identical contents in blocks inside IFs, both in the beginning and in the end.`,
|
|
23
|
-
extendedInformation: `
|
|
24
|
-
Prerequsites: code is pretty printed with identical cAsE
|
|
25
|
-
|
|
23
|
+
extendedInformation: `
|
|
24
|
+
Prerequsites: code is pretty printed with identical cAsE
|
|
25
|
+
|
|
26
26
|
Chained statments are ignored`,
|
|
27
27
|
tags: [_irule_1.RuleTag.SingleFile],
|
|
28
|
-
badExample: `IF foo = bar.
|
|
29
|
-
WRITE 'bar'.
|
|
30
|
-
WRITE 'world'.
|
|
31
|
-
ELSE.
|
|
32
|
-
WRITE 'foo'.
|
|
33
|
-
WRITE 'world'.
|
|
28
|
+
badExample: `IF foo = bar.
|
|
29
|
+
WRITE 'bar'.
|
|
30
|
+
WRITE 'world'.
|
|
31
|
+
ELSE.
|
|
32
|
+
WRITE 'foo'.
|
|
33
|
+
WRITE 'world'.
|
|
34
34
|
ENDIF.`,
|
|
35
|
-
goodExample: `IF foo = bar.
|
|
36
|
-
WRITE 'bar'.
|
|
37
|
-
ELSE.
|
|
38
|
-
WRITE 'foo'.
|
|
39
|
-
ENDIF.
|
|
35
|
+
goodExample: `IF foo = bar.
|
|
36
|
+
WRITE 'bar'.
|
|
37
|
+
ELSE.
|
|
38
|
+
WRITE 'foo'.
|
|
39
|
+
ENDIF.
|
|
40
40
|
WRITE 'world'.`,
|
|
41
41
|
};
|
|
42
42
|
}
|
|
@@ -16,10 +16,10 @@ class IdenticalDescriptions {
|
|
|
16
16
|
key: "identical_descriptions",
|
|
17
17
|
title: "Identical descriptions",
|
|
18
18
|
shortDescription: `Searches for objects with the same type and same description`,
|
|
19
|
-
extendedInformation: `Case insensitive
|
|
20
|
-
|
|
21
|
-
Only checks the master language descriptions
|
|
22
|
-
|
|
19
|
+
extendedInformation: `Case insensitive
|
|
20
|
+
|
|
21
|
+
Only checks the master language descriptions
|
|
22
|
+
|
|
23
23
|
Works for: INTF, CLAS, DOMA, DTEL, FUNC in same FUGR`,
|
|
24
24
|
tags: [],
|
|
25
25
|
};
|
|
@@ -19,15 +19,15 @@ class IfInIf extends _abap_rule_1.ABAPRule {
|
|
|
19
19
|
key: "if_in_if",
|
|
20
20
|
title: "IF in IF",
|
|
21
21
|
shortDescription: `Detects nested ifs which can be refactored to a single condition using AND.`,
|
|
22
|
-
extendedInformation: `https://docs.abapopenchecks.org/checks/01/
|
|
22
|
+
extendedInformation: `https://docs.abapopenchecks.org/checks/01/
|
|
23
23
|
https://github.com/SAP/styleguides/blob/main/clean-abap/CleanABAP.md#keep-the-nesting-depth-low`,
|
|
24
|
-
badExample: `IF condition1.
|
|
25
|
-
IF condition2.
|
|
26
|
-
...
|
|
27
|
-
ENDIF.
|
|
24
|
+
badExample: `IF condition1.
|
|
25
|
+
IF condition2.
|
|
26
|
+
...
|
|
27
|
+
ENDIF.
|
|
28
28
|
ENDIF.`,
|
|
29
|
-
goodExample: `IF ( condition1 ) AND ( condition2 ).
|
|
30
|
-
...
|
|
29
|
+
goodExample: `IF ( condition1 ) AND ( condition2 ).
|
|
30
|
+
...
|
|
31
31
|
ENDIF.`,
|
|
32
32
|
tags: [_irule_1.RuleTag.Styleguide, _irule_1.RuleTag.SingleFile],
|
|
33
33
|
};
|
|
@@ -102,9 +102,9 @@ class ImplementMethods extends _abap_rule_1.ABAPRule {
|
|
|
102
102
|
for (const i of ((_a = file.getStructure()) === null || _a === void 0 ? void 0 : _a.findAllStatements(Statements.ClassImplementation)) || []) {
|
|
103
103
|
const name = (_b = i.findFirstExpression(Expressions.ClassName)) === null || _b === void 0 ? void 0 : _b.getFirstToken().getStr().toUpperCase();
|
|
104
104
|
if (name === impl.identifier.getName().toUpperCase()) {
|
|
105
|
-
return edit_helper_1.EditHelper.insertAt(file, i.getLastToken().getEnd(), `
|
|
106
|
-
METHOD ${methodName.toLowerCase()}.
|
|
107
|
-
RETURN. " todo, implement method
|
|
105
|
+
return edit_helper_1.EditHelper.insertAt(file, i.getLastToken().getEnd(), `
|
|
106
|
+
METHOD ${methodName.toLowerCase()}.
|
|
107
|
+
RETURN. " todo, implement method
|
|
108
108
|
ENDMETHOD.`);
|
|
109
109
|
}
|
|
110
110
|
}
|
|
@@ -31,19 +31,19 @@ class InStatementIndentation extends _abap_rule_1.ABAPRule {
|
|
|
31
31
|
key: "in_statement_indentation",
|
|
32
32
|
title: "In-statement indentation",
|
|
33
33
|
shortDescription: "Checks alignment within statements which span multiple lines.",
|
|
34
|
-
extendedInformation: `Lines following the first line should be indented once (2 spaces).
|
|
35
|
-
|
|
36
|
-
For block declaration statements, lines after the first should be indented an additional time (default: +2 spaces)
|
|
34
|
+
extendedInformation: `Lines following the first line should be indented once (2 spaces).
|
|
35
|
+
|
|
36
|
+
For block declaration statements, lines after the first should be indented an additional time (default: +2 spaces)
|
|
37
37
|
to distinguish them better from code within the block.`,
|
|
38
|
-
badExample: `IF 1 = 1
|
|
39
|
-
AND 2 = 2.
|
|
40
|
-
WRITE 'hello' &&
|
|
41
|
-
'world'.
|
|
38
|
+
badExample: `IF 1 = 1
|
|
39
|
+
AND 2 = 2.
|
|
40
|
+
WRITE 'hello' &&
|
|
41
|
+
'world'.
|
|
42
42
|
ENDIF.`,
|
|
43
|
-
goodExample: `IF 1 = 1
|
|
44
|
-
AND 2 = 2.
|
|
45
|
-
WRITE 'hello' &&
|
|
46
|
-
'world'.
|
|
43
|
+
goodExample: `IF 1 = 1
|
|
44
|
+
AND 2 = 2.
|
|
45
|
+
WRITE 'hello' &&
|
|
46
|
+
'world'.
|
|
47
47
|
ENDIF.`,
|
|
48
48
|
tags: [_irule_1.RuleTag.Whitespace, _irule_1.RuleTag.Quickfix, _irule_1.RuleTag.SingleFile],
|
|
49
49
|
};
|
|
@@ -26,9 +26,9 @@ class IntfReferencingClas {
|
|
|
26
26
|
key: "intf_referencing_clas",
|
|
27
27
|
title: "INTF referencing CLAS",
|
|
28
28
|
shortDescription: `Interface contains references to class`,
|
|
29
|
-
extendedInformation: `Only global interfaces are checked.
|
|
30
|
-
Only first level references are checked.
|
|
31
|
-
Exception class references are ignored.
|
|
29
|
+
extendedInformation: `Only global interfaces are checked.
|
|
30
|
+
Only first level references are checked.
|
|
31
|
+
Exception class references are ignored.
|
|
32
32
|
Void references are ignored.`,
|
|
33
33
|
};
|
|
34
34
|
}
|
|
@@ -15,8 +15,8 @@ class LineBreakStyle {
|
|
|
15
15
|
return {
|
|
16
16
|
key: "line_break_style",
|
|
17
17
|
title: "Makes sure line breaks are consistent in the ABAP code",
|
|
18
|
-
shortDescription: `Enforces LF as newlines in ABAP files
|
|
19
|
-
|
|
18
|
+
shortDescription: `Enforces LF as newlines in ABAP files
|
|
19
|
+
|
|
20
20
|
abapGit does not work with CRLF`,
|
|
21
21
|
tags: [_irule_1.RuleTag.Whitespace, _irule_1.RuleTag.SingleFile],
|
|
22
22
|
};
|
|
@@ -23,7 +23,7 @@ class LineLength extends _abap_rule_1.ABAPRule {
|
|
|
23
23
|
key: "line_length",
|
|
24
24
|
title: "Line length",
|
|
25
25
|
shortDescription: `Detects lines exceeding the provided maximum length.`,
|
|
26
|
-
extendedInformation: `https://github.com/SAP/styleguides/blob/main/clean-abap/CleanABAP.md#stick-to-a-reasonable-line-length
|
|
26
|
+
extendedInformation: `https://github.com/SAP/styleguides/blob/main/clean-abap/CleanABAP.md#stick-to-a-reasonable-line-length
|
|
27
27
|
https://docs.abapopenchecks.org/checks/04/`,
|
|
28
28
|
tags: [_irule_1.RuleTag.Styleguide, _irule_1.RuleTag.SingleFile],
|
|
29
29
|
};
|
|
@@ -27,7 +27,7 @@ class LineOnlyPunc extends _abap_rule_1.ABAPRule {
|
|
|
27
27
|
key: "line_only_punc",
|
|
28
28
|
title: "Line containing only punctuation",
|
|
29
29
|
shortDescription: `Detects lines containing only punctuation.`,
|
|
30
|
-
extendedInformation: `https://github.com/SAP/styleguides/blob/main/clean-abap/CleanABAP.md#close-brackets-at-line-end
|
|
30
|
+
extendedInformation: `https://github.com/SAP/styleguides/blob/main/clean-abap/CleanABAP.md#close-brackets-at-line-end
|
|
31
31
|
https://docs.abapopenchecks.org/checks/16/`,
|
|
32
32
|
tags: [_irule_1.RuleTag.Styleguide, _irule_1.RuleTag.Quickfix, _irule_1.RuleTag.SingleFile],
|
|
33
33
|
badExample: "zcl_class=>method(\n).",
|
|
@@ -30,8 +30,8 @@ class LocalVariableNames extends _abap_rule_1.ABAPRule {
|
|
|
30
30
|
return {
|
|
31
31
|
key: "local_variable_names",
|
|
32
32
|
title: "Local variable naming conventions",
|
|
33
|
-
shortDescription: `
|
|
34
|
-
Allows you to enforce a pattern, such as a prefix, for local variables, constants and field symbols.
|
|
33
|
+
shortDescription: `
|
|
34
|
+
Allows you to enforce a pattern, such as a prefix, for local variables, constants and field symbols.
|
|
35
35
|
Regexes are case-insensitive.`,
|
|
36
36
|
tags: [_irule_1.RuleTag.Naming, _irule_1.RuleTag.SingleFile],
|
|
37
37
|
};
|