@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.
Files changed (75) hide show
  1. package/README.md +6 -6
  2. package/build/src/abap/flow/flow_graph.js +7 -7
  3. package/build/src/lsp/help.js +7 -7
  4. package/build/src/registry.js +1 -1
  5. package/build/src/rules/7bit_ascii.js +2 -2
  6. package/build/src/rules/abapdoc.js +1 -1
  7. package/build/src/rules/align_parameters.js +33 -33
  8. package/build/src/rules/ambiguous_statement.js +5 -5
  9. package/build/src/rules/avoid_use.js +6 -6
  10. package/build/src/rules/begin_end_names.js +4 -4
  11. package/build/src/rules/begin_single_include.js +12 -12
  12. package/build/src/rules/call_transaction_authority_check.js +3 -3
  13. package/build/src/rules/chain_mainly_declarations.js +4 -4
  14. package/build/src/rules/check_abstract.js +2 -2
  15. package/build/src/rules/check_comments.js +4 -4
  16. package/build/src/rules/check_include.js +3 -3
  17. package/build/src/rules/check_no_handler_pragma.js +8 -8
  18. package/build/src/rules/check_subrc.js +8 -8
  19. package/build/src/rules/commented_code.js +1 -1
  20. package/build/src/rules/constructor_visibility_public.js +4 -4
  21. package/build/src/rules/contains_tab.js +2 -2
  22. package/build/src/rules/dangerous_statement.js +1 -1
  23. package/build/src/rules/downport.js +95 -65
  24. package/build/src/rules/exit_or_check.js +3 -3
  25. package/build/src/rules/exporting.js +1 -1
  26. package/build/src/rules/forbidden_identifier.js +1 -1
  27. package/build/src/rules/forbidden_void_type.js +2 -2
  28. package/build/src/rules/functional_writing.js +17 -17
  29. package/build/src/rules/global_class.js +10 -10
  30. package/build/src/rules/identical_conditions.js +2 -2
  31. package/build/src/rules/identical_contents.js +14 -14
  32. package/build/src/rules/identical_descriptions.js +4 -4
  33. package/build/src/rules/if_in_if.js +7 -7
  34. package/build/src/rules/implement_methods.js +3 -3
  35. package/build/src/rules/in_statement_indentation.js +11 -11
  36. package/build/src/rules/intf_referencing_clas.js +3 -3
  37. package/build/src/rules/line_break_style.js +2 -2
  38. package/build/src/rules/line_length.js +1 -1
  39. package/build/src/rules/line_only_punc.js +1 -1
  40. package/build/src/rules/local_variable_names.js +2 -2
  41. package/build/src/rules/many_parentheses.js +10 -10
  42. package/build/src/rules/max_one_method_parameter_per_line.js +7 -7
  43. package/build/src/rules/max_one_statement.js +3 -3
  44. package/build/src/rules/nesting.js +1 -1
  45. package/build/src/rules/no_chained_assignment.js +1 -1
  46. package/build/src/rules/no_public_attributes.js +1 -1
  47. package/build/src/rules/no_yoda_conditions.js +4 -4
  48. package/build/src/rules/obsolete_statement.js +40 -40
  49. package/build/src/rules/omit_parameter_name.js +3 -3
  50. package/build/src/rules/omit_receiving.js +13 -13
  51. package/build/src/rules/parser_702_chaining.js +2 -2
  52. package/build/src/rules/parser_error.js +2 -2
  53. package/build/src/rules/parser_missing_space.js +1 -1
  54. package/build/src/rules/prefer_inline.js +16 -16
  55. package/build/src/rules/prefer_is_not.js +7 -7
  56. package/build/src/rules/prefer_raise_exception_new.js +3 -3
  57. package/build/src/rules/prefer_returning_to_exporting.js +1 -1
  58. package/build/src/rules/prefer_xsdbool.js +2 -2
  59. package/build/src/rules/remove_descriptions.js +4 -4
  60. package/build/src/rules/rfc_error_handling.js +9 -9
  61. package/build/src/rules/select_add_order_by.js +5 -5
  62. package/build/src/rules/select_performance.js +2 -2
  63. package/build/src/rules/sicf_consistency.js +4 -4
  64. package/build/src/rules/space_before_dot.js +2 -2
  65. package/build/src/rules/start_at_tab.js +1 -1
  66. package/build/src/rules/sy_modification.js +2 -2
  67. package/build/src/rules/tabl_enhancement_category.js +2 -2
  68. package/build/src/rules/unused_methods.js +9 -9
  69. package/build/src/rules/unused_variables.js +6 -6
  70. package/build/src/rules/use_bool_expression.js +8 -8
  71. package/build/src/rules/use_line_exists.js +6 -6
  72. package/build/src/rules/use_new.js +4 -4
  73. package/build/src/rules/when_others_last.js +6 -6
  74. package/build/src/utils/include_graph.js +3 -0
  75. 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
- const highSyntax = new syntax_1.SyntaxLogic(this.highReg, highObj).run();
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.findAllExpressionsRecursive(Expressions.SQLFieldList)) {
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 i of allSources) {
976
- const firstToken = i.getFirstToken();
997
+ for (const s of allSources) {
998
+ const firstToken = s.getFirstToken();
977
999
  if (firstToken.getStr().toUpperCase() !== "VALUE") {
978
1000
  continue;
979
1001
  }
980
- const type = this.findType(i, lowFile, highSyntax);
1002
+ let type = this.findType(s, lowFile, highSyntax);
981
1003
  if (type === undefined) {
982
- continue;
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 = i.findDirectExpression(Expressions.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} TYPE ${type}.\n` +
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(), i.getLastToken().getEnd(), uniqueName);
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 (r.referenceType === _reference_1.ReferenceType.BuiltinMethodReference
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
  };