@abaplint/core 2.86.3 → 2.86.6
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 +8 -8
- 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 +93 -76
- 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/keyword_case.js +5 -0
- 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/method_overwrites_builtin.js +2 -2
- 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/nrob_consistency.js +2 -2
- 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_types.js +2 -21
- package/build/src/rules/unused_variables.js +8 -8
- 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/package.json +66 -66
|
@@ -35,33 +35,33 @@ class Downport {
|
|
|
35
35
|
key: "downport",
|
|
36
36
|
title: "Downport statement",
|
|
37
37
|
shortDescription: `Experimental downport functionality`,
|
|
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
|
-
|
|
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
|
+
|
|
65
65
|
Only one transformation is applied to a statement at a time, so multiple steps might be required to do the full downport.`,
|
|
66
66
|
tags: [_irule_1.RuleTag.Experimental, _irule_1.RuleTag.Downport, _irule_1.RuleTag.Quickfix],
|
|
67
67
|
};
|
|
@@ -267,6 +267,10 @@ Only one transformation is applied to a statement at a time, so multiple steps m
|
|
|
267
267
|
if (found) {
|
|
268
268
|
return found;
|
|
269
269
|
}
|
|
270
|
+
found = this.replaceMethodConditional(high, lowFile, highSyntax);
|
|
271
|
+
if (found) {
|
|
272
|
+
return found;
|
|
273
|
+
}
|
|
270
274
|
found = this.replaceTableExpression(high, lowFile, highSyntax);
|
|
271
275
|
if (found) {
|
|
272
276
|
return found;
|
|
@@ -390,10 +394,10 @@ Only one transformation is applied to a statement at a time, so multiple steps m
|
|
|
390
394
|
const fieldName = f.concatTokens();
|
|
391
395
|
fieldDefinition += indentation + " " + fieldName + " TYPE " + tableName + "-" + fieldName + ",\n";
|
|
392
396
|
}
|
|
393
|
-
fieldDefinition = `DATA: BEGIN OF ${name},
|
|
397
|
+
fieldDefinition = `DATA: BEGIN OF ${name},
|
|
394
398
|
${fieldDefinition}${indentation} END OF ${name}.`;
|
|
395
399
|
}
|
|
396
|
-
const fix1 = edit_helper_1.EditHelper.insertAt(lowFile, high.getStart(), `${fieldDefinition}
|
|
400
|
+
const fix1 = edit_helper_1.EditHelper.insertAt(lowFile, high.getStart(), `${fieldDefinition}
|
|
397
401
|
${indentation}`);
|
|
398
402
|
const fix2 = edit_helper_1.EditHelper.replaceRange(lowFile, inlineData.getFirstToken().getStart(), inlineData.getLastToken().getEnd(), name);
|
|
399
403
|
const fix = edit_helper_1.EditHelper.merge(fix2, fix1);
|
|
@@ -434,12 +438,12 @@ ${indentation}`);
|
|
|
434
438
|
}
|
|
435
439
|
const uniqueName = this.uniqueName(high.getFirstToken().getStart(), lowFile.getFilename(), highSyntax);
|
|
436
440
|
const name = ((_c = inlineData.findFirstExpression(Expressions.TargetField)) === null || _c === void 0 ? void 0 : _c.concatTokens()) || "error";
|
|
437
|
-
let fix1 = edit_helper_1.EditHelper.insertAt(lowFile, high.getStart(), `TYPES: BEGIN OF ${uniqueName},
|
|
438
|
-
${fieldDefinitions}${indentation} END OF ${uniqueName}.
|
|
439
|
-
${indentation}DATA ${name} TYPE STANDARD TABLE OF ${uniqueName} WITH DEFAULT KEY.
|
|
441
|
+
let fix1 = edit_helper_1.EditHelper.insertAt(lowFile, high.getStart(), `TYPES: BEGIN OF ${uniqueName},
|
|
442
|
+
${fieldDefinitions}${indentation} END OF ${uniqueName}.
|
|
443
|
+
${indentation}DATA ${name} TYPE STANDARD TABLE OF ${uniqueName} WITH DEFAULT KEY.
|
|
440
444
|
${indentation}`);
|
|
441
445
|
if (fieldDefinitions === "") {
|
|
442
|
-
fix1 = edit_helper_1.EditHelper.insertAt(lowFile, high.getStart(), `DATA ${name} TYPE STANDARD TABLE OF ${tableName} WITH DEFAULT KEY.
|
|
446
|
+
fix1 = edit_helper_1.EditHelper.insertAt(lowFile, high.getStart(), `DATA ${name} TYPE STANDARD TABLE OF ${tableName} WITH DEFAULT KEY.
|
|
443
447
|
${indentation}`);
|
|
444
448
|
}
|
|
445
449
|
const fix2 = edit_helper_1.EditHelper.replaceRange(lowFile, inlineData.getFirstToken().getStart(), inlineData.getLastToken().getEnd(), name);
|
|
@@ -460,7 +464,7 @@ ${indentation}`);
|
|
|
460
464
|
const uniqueName = this.uniqueName(high.getFirstToken().getStart(), lowFile.getFilename(), highSyntax);
|
|
461
465
|
const indentation = " ".repeat(high.getFirstToken().getStart().getCol() - 1);
|
|
462
466
|
const firstToken = high.getFirstToken();
|
|
463
|
-
const fix1 = edit_helper_1.EditHelper.insertAt(lowFile, firstToken.getStart(), `DATA ${uniqueName} LIKE LINE OF ${target === null || target === void 0 ? void 0 : target.concatTokens()}.
|
|
467
|
+
const fix1 = edit_helper_1.EditHelper.insertAt(lowFile, firstToken.getStart(), `DATA ${uniqueName} LIKE LINE OF ${target === null || target === void 0 ? void 0 : target.concatTokens()}.
|
|
464
468
|
${indentation}${uniqueName} = ${source.concatTokens()}.\n${indentation}`);
|
|
465
469
|
const fix2 = edit_helper_1.EditHelper.replaceRange(lowFile, source.getFirstToken().getStart(), source.getLastToken().getEnd(), uniqueName);
|
|
466
470
|
const fix = edit_helper_1.EditHelper.merge(fix2, fix1);
|
|
@@ -497,11 +501,11 @@ ${indentation}${uniqueName} = ${source.concatTokens()}.\n${indentation}`);
|
|
|
497
501
|
const uniqueName = this.uniqueName(node.getFirstToken().getStart(), lowFile.getFilename(), highSyntax);
|
|
498
502
|
const indentation = " ".repeat(node.getFirstToken().getStart().getCol() - 1);
|
|
499
503
|
const firstToken = node.getFirstToken();
|
|
500
|
-
const fix1 = edit_helper_1.EditHelper.insertAt(lowFile, firstToken.getStart(), `DATA ${uniqueName} LIKE LINE OF ${pre}.
|
|
501
|
-
${indentation}READ TABLE ${pre} ${condition}INTO ${uniqueName}.
|
|
502
|
-
${indentation}IF sy-subrc <> 0.
|
|
503
|
-
${indentation} RAISE EXCEPTION TYPE cx_sy_itab_line_not_found.
|
|
504
|
-
${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.
|
|
505
509
|
${indentation}`);
|
|
506
510
|
const fix2 = edit_helper_1.EditHelper.replaceRange(lowFile, startToken.getStart(), tableExpression.getLastToken().getEnd(), uniqueName);
|
|
507
511
|
const fix = edit_helper_1.EditHelper.merge(fix2, fix1);
|
|
@@ -542,7 +546,7 @@ ${indentation}`);
|
|
|
542
546
|
const className = classNames[0].concatTokens();
|
|
543
547
|
const targetName = (_b = target.findFirstExpression(Expressions.TargetField)) === null || _b === void 0 ? void 0 : _b.concatTokens();
|
|
544
548
|
const indentation = " ".repeat(node.getFirstToken().getStart().getCol() - 1);
|
|
545
|
-
const code = ` DATA ${targetName} TYPE REF TO ${className}.
|
|
549
|
+
const code = ` DATA ${targetName} TYPE REF TO ${className}.
|
|
546
550
|
${indentation}CATCH ${className} INTO ${targetName}.`;
|
|
547
551
|
const fix = edit_helper_1.EditHelper.replaceRange(lowFile, node.getStart(), node.getEnd(), code);
|
|
548
552
|
return issue_1.Issue.atToken(lowFile, node.getFirstToken(), "Outline DATA", this.getMetadata().key, this.conf.severity, fix);
|
|
@@ -653,11 +657,11 @@ ${indentation}CATCH ${className} INTO ${targetName}.`;
|
|
|
653
657
|
const uniqueName1 = this.uniqueName(node.getFirstToken().getStart(), lowFile.getFilename(), highSyntax);
|
|
654
658
|
const uniqueName2 = this.uniqueName(node.getFirstToken().getStart(), lowFile.getFilename(), highSyntax);
|
|
655
659
|
const indentation = " ".repeat(node.getFirstToken().getStart().getCol() - 1);
|
|
656
|
-
const abap = `DATA ${uniqueName1} LIKE if_t100_message=>t100key.
|
|
657
|
-
${indentation}${uniqueName1}-msgid = ${id}.
|
|
658
|
-
${indentation}${uniqueName1}-msgno = ${number}.
|
|
659
|
-
${indentation}DATA ${uniqueName2} TYPE REF TO ${className}.
|
|
660
|
-
${indentation}CREATE OBJECT ${uniqueName2} EXPORTING textid = ${uniqueName1}.
|
|
660
|
+
const abap = `DATA ${uniqueName1} LIKE if_t100_message=>t100key.
|
|
661
|
+
${indentation}${uniqueName1}-msgid = ${id}.
|
|
662
|
+
${indentation}${uniqueName1}-msgno = ${number}.
|
|
663
|
+
${indentation}DATA ${uniqueName2} TYPE REF TO ${className}.
|
|
664
|
+
${indentation}CREATE OBJECT ${uniqueName2} EXPORTING textid = ${uniqueName1}.
|
|
661
665
|
${indentation}RAISE EXCEPTION ${uniqueName2}.`;
|
|
662
666
|
const fix = edit_helper_1.EditHelper.replaceRange(lowFile, node.getStart(), node.getEnd(), abap);
|
|
663
667
|
return issue_1.Issue.atToken(lowFile, startToken, "Downport RAISE MESSAGE", this.getMetadata().key, this.conf.severity, fix);
|
|
@@ -738,11 +742,11 @@ ${indentation}RAISE EXCEPTION ${uniqueName2}.`;
|
|
|
738
742
|
const tName = target.concatTokens().split("[")[0];
|
|
739
743
|
const condition = this.tableCondition(tableExpression);
|
|
740
744
|
const indentation = " ".repeat(high.getFirstToken().getStart().getCol() - 1);
|
|
741
|
-
const code = `FIELD-SYMBOLS ${uniqueName} LIKE LINE OF ${tName}.
|
|
742
|
-
${indentation}READ TABLE ${tName} ${condition}ASSIGNING ${uniqueName}.
|
|
743
|
-
${indentation}IF sy-subrc <> 0.
|
|
744
|
-
${indentation} RAISE EXCEPTION TYPE cx_sy_itab_line_not_found.
|
|
745
|
-
${indentation}ENDIF.
|
|
745
|
+
const code = `FIELD-SYMBOLS ${uniqueName} LIKE LINE OF ${tName}.
|
|
746
|
+
${indentation}READ TABLE ${tName} ${condition}ASSIGNING ${uniqueName}.
|
|
747
|
+
${indentation}IF sy-subrc <> 0.
|
|
748
|
+
${indentation} RAISE EXCEPTION TYPE cx_sy_itab_line_not_found.
|
|
749
|
+
${indentation}ENDIF.
|
|
746
750
|
${indentation}${uniqueName}`;
|
|
747
751
|
const start = target.getFirstToken().getStart();
|
|
748
752
|
const end = (_a = tableExpression.findDirectTokenByText("]")) === null || _a === void 0 ? void 0 : _a.getEnd();
|
|
@@ -830,10 +834,10 @@ ${indentation}${uniqueName}`;
|
|
|
830
834
|
const indentation = " ".repeat(node.getFirstToken().getStart().getCol() - 1);
|
|
831
835
|
const source = (_b = templateSource === null || templateSource === void 0 ? void 0 : templateSource.findDirectExpression(Expressions.Source)) === null || _b === void 0 ? void 0 : _b.concatTokens();
|
|
832
836
|
const topTarget = (_c = node.findDirectExpression(Expressions.Target)) === null || _c === void 0 ? void 0 : _c.concatTokens();
|
|
833
|
-
const code = `CALL FUNCTION '${functionName}'
|
|
834
|
-
${indentation} EXPORTING
|
|
835
|
-
${indentation} input = ${source}
|
|
836
|
-
${indentation} IMPORTING
|
|
837
|
+
const code = `CALL FUNCTION '${functionName}'
|
|
838
|
+
${indentation} EXPORTING
|
|
839
|
+
${indentation} input = ${source}
|
|
840
|
+
${indentation} IMPORTING
|
|
837
841
|
${indentation} output = ${topTarget}.`;
|
|
838
842
|
const fix = edit_helper_1.EditHelper.replaceRange(lowFile, node.getFirstToken().getStart(), node.getLastToken().getEnd(), code);
|
|
839
843
|
return issue_1.Issue.atToken(lowFile, node.getFirstToken(), "Downport ALPHA", this.getMetadata().key, this.conf.severity, fix);
|
|
@@ -894,40 +898,37 @@ ${indentation} output = ${topTarget}.`;
|
|
|
894
898
|
return undefined;
|
|
895
899
|
}
|
|
896
900
|
outlineFor(forLoop, indentation, lowFile, highSyntax) {
|
|
897
|
-
var _a, _b, _c, _d, _e
|
|
901
|
+
var _a, _b, _c, _d, _e;
|
|
898
902
|
let body = "";
|
|
899
903
|
let end = "";
|
|
900
904
|
const loopSource = (_a = forLoop.findFirstExpression(Expressions.Source)) === null || _a === void 0 ? void 0 : _a.concatTokens();
|
|
901
905
|
const loopTargetField = (_b = forLoop.findFirstExpression(Expressions.TargetField)) === null || _b === void 0 ? void 0 : _b.concatTokens();
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
const cond = forLoop.findFirstExpression(Expressions.Cond);
|
|
906
|
-
body += indentation + `WHILE NOT ${cond === null || cond === void 0 ? void 0 : cond.concatTokens()}.\n`;
|
|
907
|
-
const field = (_e = (_d = forLoop.findDirectExpression(Expressions.InlineFieldDefinition)) === null || _d === void 0 ? void 0 : _d.findFirstExpression(Expressions.Field)) === null || _e === void 0 ? void 0 : _e.concatTokens();
|
|
908
|
-
end += ` ${field} = ${field} + 1.\n`;
|
|
909
|
-
end += indentation + "ENDWHILE";
|
|
906
|
+
let cond = ((_c = forLoop.findDirectExpression(Expressions.ComponentCond)) === null || _c === void 0 ? void 0 : _c.concatTokens()) || "";
|
|
907
|
+
if (cond !== "") {
|
|
908
|
+
cond = " WHERE " + cond;
|
|
910
909
|
}
|
|
911
|
-
|
|
910
|
+
if (forLoop.findDirectTokenByText("UNTIL")
|
|
911
|
+
|| forLoop.findDirectTokenByText("WHILE")) {
|
|
912
912
|
const fieldDef = forLoop.findDirectExpression(Expressions.InlineFieldDefinition);
|
|
913
|
-
const field = (
|
|
913
|
+
const field = (_d = fieldDef === null || fieldDef === void 0 ? void 0 : fieldDef.findFirstExpression(Expressions.Field)) === null || _d === void 0 ? void 0 : _d.concatTokens();
|
|
914
914
|
body += indentation + "DATA " + field + " TYPE i.\n";
|
|
915
915
|
const second = fieldDef === null || fieldDef === void 0 ? void 0 : fieldDef.getChildren()[2];
|
|
916
916
|
if ((second === null || second === void 0 ? void 0 : second.get()) instanceof Expressions.Source) {
|
|
917
917
|
body += indentation + field + " = " + second.concatTokens() + ".\n";
|
|
918
918
|
}
|
|
919
|
+
const not = forLoop.findDirectTokenByText("UNTIL") ? " NOT" : "";
|
|
919
920
|
const cond = forLoop.findFirstExpression(Expressions.Cond);
|
|
920
|
-
body += indentation + `WHILE ${cond === null || cond === void 0 ? void 0 : cond.concatTokens()}.\n`;
|
|
921
|
+
body += indentation + `WHILE${not} ${cond === null || cond === void 0 ? void 0 : cond.concatTokens()}.\n`;
|
|
921
922
|
end += ` ${field} = ${field} + 1.\n`;
|
|
922
923
|
end += indentation + "ENDWHILE";
|
|
923
924
|
}
|
|
924
925
|
else if (loopTargetField) {
|
|
925
|
-
body += indentation + `LOOP AT ${loopSource} INTO DATA(${loopTargetField}).\n`;
|
|
926
|
+
body += indentation + `LOOP AT ${loopSource} INTO DATA(${loopTargetField})${cond}.\n`;
|
|
926
927
|
end = "ENDLOOP";
|
|
927
928
|
}
|
|
928
929
|
else if (loopTargetField === undefined) {
|
|
929
|
-
const loopTargetFieldSymbol = (
|
|
930
|
-
body += indentation + `LOOP AT ${loopSource} ASSIGNING FIELD-SYMBOL(${loopTargetFieldSymbol}).\n`;
|
|
930
|
+
const loopTargetFieldSymbol = (_e = forLoop.findFirstExpression(Expressions.TargetFieldSymbol)) === null || _e === void 0 ? void 0 : _e.concatTokens();
|
|
931
|
+
body += indentation + `LOOP AT ${loopSource} ASSIGNING FIELD-SYMBOL(${loopTargetFieldSymbol})${cond}.\n`;
|
|
931
932
|
end = "ENDLOOP";
|
|
932
933
|
}
|
|
933
934
|
const l = forLoop.findDirectExpression(Expressions.Let);
|
|
@@ -1030,12 +1031,12 @@ ${indentation} output = ${topTarget}.`;
|
|
|
1030
1031
|
name = init.getFirstToken().getStr();
|
|
1031
1032
|
body += indentation + `DATA(${name}) = ${(_a = reduceBody.findFirstExpression(Expressions.Source)) === null || _a === void 0 ? void 0 : _a.concatTokens()}.\n`;
|
|
1032
1033
|
}
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1034
|
+
let end = "";
|
|
1035
|
+
for (const forLoop of (reduceBody === null || reduceBody === void 0 ? void 0 : reduceBody.findDirectExpressions(Expressions.For)) || []) {
|
|
1036
|
+
const outlineFor = this.outlineFor(forLoop, indentation, lowFile, highSyntax);
|
|
1037
|
+
body += outlineFor.body;
|
|
1038
|
+
end = outlineFor.end + `.\n` + end;
|
|
1036
1039
|
}
|
|
1037
|
-
const outlineFor = this.outlineFor(forLoop, indentation, lowFile, highSyntax);
|
|
1038
|
-
body += outlineFor.body;
|
|
1039
1040
|
const next = reduceBody.findDirectExpression(Expressions.ReduceNext);
|
|
1040
1041
|
if (next === undefined) {
|
|
1041
1042
|
continue;
|
|
@@ -1055,7 +1056,7 @@ ${indentation} output = ${topTarget}.`;
|
|
|
1055
1056
|
body += concat;
|
|
1056
1057
|
}
|
|
1057
1058
|
}
|
|
1058
|
-
body += indentation +
|
|
1059
|
+
body += indentation + end;
|
|
1059
1060
|
body += indentation + `${uniqueName} = ${name}.\n`;
|
|
1060
1061
|
const abap = `DATA ${uniqueName} TYPE ${type}.\n` +
|
|
1061
1062
|
body +
|
|
@@ -1355,6 +1356,10 @@ ${indentation} output = ${topTarget}.`;
|
|
|
1355
1356
|
if (i.getFirstToken().getStr().toUpperCase() !== "CONV") {
|
|
1356
1357
|
continue;
|
|
1357
1358
|
}
|
|
1359
|
+
const end = i.findDirectTokenByText(")");
|
|
1360
|
+
if (end === undefined) {
|
|
1361
|
+
continue;
|
|
1362
|
+
}
|
|
1358
1363
|
const body = (_a = i.findDirectExpression(Expressions.ConvBody)) === null || _a === void 0 ? void 0 : _a.concatTokens();
|
|
1359
1364
|
if (body === undefined) {
|
|
1360
1365
|
continue;
|
|
@@ -1366,7 +1371,7 @@ ${indentation} output = ${topTarget}.`;
|
|
|
1366
1371
|
indent + `${uniqueName} = ${body}.\n` +
|
|
1367
1372
|
indent;
|
|
1368
1373
|
const fix1 = edit_helper_1.EditHelper.insertAt(lowFile, node.getFirstToken().getStart(), abap);
|
|
1369
|
-
const fix2 = edit_helper_1.EditHelper.replaceRange(lowFile, i.getFirstToken().getStart(),
|
|
1374
|
+
const fix2 = edit_helper_1.EditHelper.replaceRange(lowFile, i.getFirstToken().getStart(), end.getEnd(), uniqueName);
|
|
1370
1375
|
const fix = edit_helper_1.EditHelper.merge(fix2, fix1);
|
|
1371
1376
|
return issue_1.Issue.atToken(lowFile, i.getFirstToken(), "Downport CONV", this.getMetadata().key, this.conf.severity, fix);
|
|
1372
1377
|
}
|
|
@@ -1427,6 +1432,18 @@ ${indentation} output = ${topTarget}.`;
|
|
|
1427
1432
|
}
|
|
1428
1433
|
return undefined;
|
|
1429
1434
|
}
|
|
1435
|
+
replaceMethodConditional(node, lowFile, _highSyntax) {
|
|
1436
|
+
for (const c of node.findAllExpressionsRecursive(Expressions.Compare)) {
|
|
1437
|
+
const chain = c.findDirectExpression(Expressions.MethodCallChain);
|
|
1438
|
+
if (chain === undefined) {
|
|
1439
|
+
continue;
|
|
1440
|
+
}
|
|
1441
|
+
const end = chain.getLastToken().getEnd();
|
|
1442
|
+
const fix = edit_helper_1.EditHelper.insertAt(lowFile, end, " IS NOT INITIAL");
|
|
1443
|
+
return issue_1.Issue.atToken(lowFile, chain.getFirstToken(), "Downport method conditional", this.getMetadata().key, this.conf.severity, fix);
|
|
1444
|
+
}
|
|
1445
|
+
return undefined;
|
|
1446
|
+
}
|
|
1430
1447
|
replaceContains(node, lowFile, highSyntax) {
|
|
1431
1448
|
const spag = highSyntax.spaghetti.lookupPosition(node.getFirstToken().getStart(), lowFile.getFilename());
|
|
1432
1449
|
// only downport if its an single method call condition
|
|
@@ -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
|
}
|
|
@@ -141,12 +141,16 @@ class KeywordCase extends _abap_rule_1.ABAPRule {
|
|
|
141
141
|
}
|
|
142
142
|
}
|
|
143
143
|
const skip = new Skip(this.getConfig());
|
|
144
|
+
let prev = undefined;
|
|
144
145
|
for (const statement of file.getStatements()) {
|
|
145
146
|
if (skip.skipStatement(statement) === true) {
|
|
146
147
|
continue;
|
|
147
148
|
}
|
|
148
149
|
let result = this.traverse(statement, statement.get());
|
|
149
150
|
if (result.length > 0) {
|
|
151
|
+
if (prev && result[0].token.getStart().equals(prev.getStart())) {
|
|
152
|
+
continue;
|
|
153
|
+
}
|
|
150
154
|
if (statement.getColon() !== undefined) {
|
|
151
155
|
// if its a chained statement, go token by token
|
|
152
156
|
result = [result[0]];
|
|
@@ -156,6 +160,7 @@ class KeywordCase extends _abap_rule_1.ABAPRule {
|
|
|
156
160
|
if (issues.length > MAX_ISSUES) {
|
|
157
161
|
break;
|
|
158
162
|
}
|
|
163
|
+
prev = result[0].token;
|
|
159
164
|
}
|
|
160
165
|
}
|
|
161
166
|
return issues;
|
|
@@ -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).",
|