@abaplint/core 2.120.0 → 2.120.1

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 (136) hide show
  1. package/README.md +6 -6
  2. package/build/src/cds/expressions/cds_define_abstract.js +1 -1
  3. package/build/src/cds/expressions/cds_define_custom.js +1 -1
  4. package/build/src/cds/expressions/cds_define_external_entity.js +1 -1
  5. package/build/src/cds/expressions/cds_define_hierarchy.js +1 -1
  6. package/build/src/cds/expressions/cds_define_projection.js +1 -1
  7. package/build/src/cds/expressions/cds_define_table_entity.js +1 -1
  8. package/build/src/lsp/help.js +10 -10
  9. package/build/src/registry.js +1 -1
  10. package/build/src/rules/7bit_ascii.js +4 -4
  11. package/build/src/rules/abapdoc.js +4 -4
  12. package/build/src/rules/add_test_attributes.js +20 -20
  13. package/build/src/rules/align_parameters.js +40 -40
  14. package/build/src/rules/align_type_expressions.js +28 -28
  15. package/build/src/rules/ambiguous_statement.js +7 -7
  16. package/build/src/rules/avoid_use.js +10 -10
  17. package/build/src/rules/begin_end_names.js +4 -4
  18. package/build/src/rules/begin_single_include.js +13 -13
  19. package/build/src/rules/call_transaction_authority_check.js +3 -3
  20. package/build/src/rules/cds_association_name.js +6 -6
  21. package/build/src/rules/cds_comment_style.js +4 -4
  22. package/build/src/rules/cds_field_order.js +12 -12
  23. package/build/src/rules/cds_legacy_view.js +4 -4
  24. package/build/src/rules/cds_naming.js +7 -7
  25. package/build/src/rules/chain_mainly_declarations.js +4 -4
  26. package/build/src/rules/change_if_to_case.js +8 -8
  27. package/build/src/rules/check_abstract.js +2 -2
  28. package/build/src/rules/check_comments.js +4 -4
  29. package/build/src/rules/check_include.js +4 -4
  30. package/build/src/rules/check_subrc.js +8 -8
  31. package/build/src/rules/class_attribute_names.js +6 -6
  32. package/build/src/rules/classic_exceptions_overlap.js +10 -10
  33. package/build/src/rules/clear_exporting_parameters.js +254 -0
  34. package/build/src/rules/commented_code.js +1 -1
  35. package/build/src/rules/constructor_visibility_public.js +10 -10
  36. package/build/src/rules/contains_tab.js +2 -2
  37. package/build/src/rules/cyclic_oo.js +4 -4
  38. package/build/src/rules/dangerous_statement.js +1 -1
  39. package/build/src/rules/db_operation_in_loop.js +9 -9
  40. package/build/src/rules/definitions_top.js +6 -6
  41. package/build/src/rules/downport.js +83 -83
  42. package/build/src/rules/easy_to_find_messages.js +6 -6
  43. package/build/src/rules/empty_event.js +6 -6
  44. package/build/src/rules/empty_line_in_statement.js +2 -2
  45. package/build/src/rules/empty_structure.js +6 -6
  46. package/build/src/rules/exit_or_check.js +7 -7
  47. package/build/src/rules/expand_macros.js +5 -5
  48. package/build/src/rules/exporting.js +1 -1
  49. package/build/src/rules/forbidden_identifier.js +1 -1
  50. package/build/src/rules/forbidden_void_type.js +2 -2
  51. package/build/src/rules/form_tables_obsolete.js +2 -2
  52. package/build/src/rules/fully_type_itabs.js +2 -2
  53. package/build/src/rules/function_module_recommendations.js +2 -2
  54. package/build/src/rules/functional_writing.js +17 -17
  55. package/build/src/rules/global_class.js +10 -10
  56. package/build/src/rules/identical_conditions.js +12 -12
  57. package/build/src/rules/identical_contents.js +14 -14
  58. package/build/src/rules/identical_descriptions.js +6 -6
  59. package/build/src/rules/identical_move.js +2 -2
  60. package/build/src/rules/if_in_if.js +35 -35
  61. package/build/src/rules/implement_methods.js +3 -3
  62. package/build/src/rules/implicit_start_of_selection.js +4 -4
  63. package/build/src/rules/in_statement_indentation.js +11 -11
  64. package/build/src/rules/indentation.js +16 -16
  65. package/build/src/rules/index.js +1 -0
  66. package/build/src/rules/intf_referencing_clas.js +3 -3
  67. package/build/src/rules/invalid_table_index.js +2 -2
  68. package/build/src/rules/line_break_style.js +2 -2
  69. package/build/src/rules/line_length.js +2 -2
  70. package/build/src/rules/line_only_punc.js +1 -1
  71. package/build/src/rules/local_class_naming.js +2 -2
  72. package/build/src/rules/local_variable_names.js +6 -6
  73. package/build/src/rules/macro_naming.js +2 -2
  74. package/build/src/rules/main_file_contents.js +4 -4
  75. package/build/src/rules/many_parentheses.js +10 -10
  76. package/build/src/rules/max_one_method_parameter_per_line.js +7 -7
  77. package/build/src/rules/max_one_statement.js +5 -5
  78. package/build/src/rules/method_length.js +2 -2
  79. package/build/src/rules/method_overwrites_builtin.js +12 -12
  80. package/build/src/rules/method_parameter_names.js +4 -4
  81. package/build/src/rules/mix_returning.js +8 -8
  82. package/build/src/rules/nesting.js +1 -1
  83. package/build/src/rules/no_aliases.js +5 -5
  84. package/build/src/rules/no_chained_assignment.js +1 -1
  85. package/build/src/rules/no_comments_between_methods.js +12 -12
  86. package/build/src/rules/no_external_form_calls.js +2 -2
  87. package/build/src/rules/no_inline_in_optional_branches.js +11 -11
  88. package/build/src/rules/no_macros.js +4 -4
  89. package/build/src/rules/no_prefixes.js +6 -6
  90. package/build/src/rules/no_public_attributes.js +7 -7
  91. package/build/src/rules/no_yoda_conditions.js +4 -4
  92. package/build/src/rules/nrob_consistency.js +2 -2
  93. package/build/src/rules/obsolete_statement.js +51 -51
  94. package/build/src/rules/omit_parameter_name.js +3 -3
  95. package/build/src/rules/omit_receiving.js +13 -13
  96. package/build/src/rules/parser_702_chaining.js +2 -2
  97. package/build/src/rules/parser_error.js +2 -2
  98. package/build/src/rules/parser_missing_space.js +1 -1
  99. package/build/src/rules/prefer_inline.js +16 -16
  100. package/build/src/rules/prefer_is_not.js +9 -9
  101. package/build/src/rules/prefer_raise_exception_new.js +5 -5
  102. package/build/src/rules/prefer_returning_to_exporting.js +4 -4
  103. package/build/src/rules/prefer_xsdbool.js +2 -2
  104. package/build/src/rules/preferred_compare_operator.js +2 -2
  105. package/build/src/rules/prefix_is_current_class.js +6 -6
  106. package/build/src/rules/reduce_procedural_code.js +17 -17
  107. package/build/src/rules/redundant_conversion.js +2 -2
  108. package/build/src/rules/remove_descriptions.js +4 -4
  109. package/build/src/rules/rfc_error_handling.js +7 -7
  110. package/build/src/rules/select_add_order_by.js +5 -5
  111. package/build/src/rules/select_performance.js +5 -5
  112. package/build/src/rules/select_single_full_key.js +2 -2
  113. package/build/src/rules/selection_screen_texts_missing.js +2 -2
  114. package/build/src/rules/sicf_consistency.js +2 -2
  115. package/build/src/rules/slow_parameter_passing.js +16 -16
  116. package/build/src/rules/space_before_dot.js +2 -2
  117. package/build/src/rules/sql_value_conversion.js +6 -6
  118. package/build/src/rules/start_at_tab.js +1 -1
  119. package/build/src/rules/static_call_via_instance.js +4 -4
  120. package/build/src/rules/strict_sql.js +6 -6
  121. package/build/src/rules/sy_modification.js +6 -6
  122. package/build/src/rules/tabl_enhancement_category.js +2 -2
  123. package/build/src/rules/tables_declared_locally.js +2 -2
  124. package/build/src/rules/type_form_parameters.js +2 -2
  125. package/build/src/rules/unnecessary_pragma.js +29 -29
  126. package/build/src/rules/unnecessary_return.js +11 -11
  127. package/build/src/rules/unused_macros.js +6 -6
  128. package/build/src/rules/unused_methods.js +12 -12
  129. package/build/src/rules/unused_variables.js +12 -12
  130. package/build/src/rules/use_bool_expression.js +8 -8
  131. package/build/src/rules/use_class_based_exceptions.js +8 -8
  132. package/build/src/rules/use_line_exists.js +6 -6
  133. package/build/src/rules/use_new.js +4 -4
  134. package/build/src/rules/when_others_last.js +6 -6
  135. package/build/src/rules/xml_consistency.js +3 -3
  136. package/package.json +72 -72
@@ -62,17 +62,17 @@ class ChangeIfToCase extends _abap_rule_1.ABAPRule {
62
62
  title: "Change IF to CASE",
63
63
  shortDescription: `Finds IF constructs that can be changed to CASE`,
64
64
  // eslint-disable-next-line max-len
65
- extendedInformation: `https://github.com/SAP/styleguides/blob/main/clean-abap/CleanABAP.md#prefer-case-to-else-if-for-multiple-alternative-conditions
66
-
65
+ extendedInformation: `https://github.com/SAP/styleguides/blob/main/clean-abap/CleanABAP.md#prefer-case-to-else-if-for-multiple-alternative-conditions
66
+
67
67
  If the first comparison is a boolean compare, no issue is reported.`,
68
68
  tags: [_irule_1.RuleTag.SingleFile, _irule_1.RuleTag.Styleguide],
69
- badExample: `IF l_fcat-fieldname EQ 'FOO'.
70
- ELSEIF l_fcat-fieldname = 'BAR'
71
- OR l_fcat-fieldname = 'MOO'.
69
+ badExample: `IF l_fcat-fieldname EQ 'FOO'.
70
+ ELSEIF l_fcat-fieldname = 'BAR'
71
+ OR l_fcat-fieldname = 'MOO'.
72
72
  ENDIF.`,
73
- goodExample: `CASE l_fcat-fieldname.
74
- WHEN 'FOO'.
75
- WHEN 'BAR' OR 'MOO'.
73
+ goodExample: `CASE l_fcat-fieldname.
74
+ WHEN 'FOO'.
75
+ WHEN 'BAR' OR 'MOO'.
76
76
  ENDCASE.`,
77
77
  };
78
78
  }
@@ -23,8 +23,8 @@ class CheckAbstract extends _abap_rule_1.ABAPRule {
23
23
  return {
24
24
  key: "check_abstract",
25
25
  title: "Check abstract methods and classes",
26
- shortDescription: `Checks abstract methods and classes:
27
- - class defined as abstract and final,
26
+ shortDescription: `Checks abstract methods and classes:
27
+ - class defined as abstract and final,
28
28
  - non-abstract class contains abstract methods`,
29
29
  extendedInformation: `If a class defines only constants, use an interface instead`,
30
30
  tags: [_irule_1.RuleTag.SingleFile],
@@ -28,11 +28,11 @@ class CheckComments extends _abap_rule_1.ABAPRule {
28
28
  return {
29
29
  key: "check_comments",
30
30
  title: "Check Comments",
31
- shortDescription: `
31
+ shortDescription: `
32
32
  Various checks for comment usage.`,
33
- extendedInformation: `
34
- Detects end of line comments. Comments starting with "#EC" or "##" are ignored
35
-
33
+ extendedInformation: `
34
+ Detects end of line comments. Comments starting with "#EC" or "##" are ignored
35
+
36
36
  https://github.com/SAP/styleguides/blob/main/clean-abap/CleanABAP.md#put-comments-before-the-statement-they-relate-to`,
37
37
  tags: [_irule_1.RuleTag.Styleguide, _irule_1.RuleTag.SingleFile],
38
38
  badExample: `WRITE 2. " descriptive comment`,
@@ -23,10 +23,10 @@ class CheckInclude {
23
23
  key: "check_include",
24
24
  title: "Check INCLUDEs",
25
25
  shortDescription: `Checks INCLUDE statements`,
26
- extendedInformation: `
27
- * Reports unused includes
28
- * Errors if the includes are not found
29
- * Error if including a main program
26
+ extendedInformation: `
27
+ * Reports unused includes
28
+ * Errors if the includes are not found
29
+ * Error if including a main program
30
30
  * Skips ZX* includes`,
31
31
  tags: [_irule_1.RuleTag.Syntax],
32
32
  };
@@ -69,14 +69,14 @@ class CheckSubrc extends _abap_rule_1.ABAPRule {
69
69
  key: "check_subrc",
70
70
  title: "Check sy-subrc",
71
71
  shortDescription: `Check sy-subrc`,
72
- extendedInformation: `Pseudo comment "#EC CI_SUBRC can be added to suppress findings
73
-
74
- If sy-dbcnt is checked after database statements, it is considered okay.
75
-
76
- "SELECT SINGLE @abap_true FROM " is considered as an existence check, also "SELECT COUNT( * )" is considered okay
77
-
78
- If IS ASSIGNED is checked after assigning, it is considered okay.
79
-
72
+ extendedInformation: `Pseudo comment "#EC CI_SUBRC can be added to suppress findings
73
+
74
+ If sy-dbcnt is checked after database statements, it is considered okay.
75
+
76
+ "SELECT SINGLE @abap_true FROM " is considered as an existence check, also "SELECT COUNT( * )" is considered okay
77
+
78
+ If IS ASSIGNED is checked after assigning, it is considered okay.
79
+
80
80
  FIND statement with MATCH COUNT is considered okay if subrc is not checked`,
81
81
  tags: [_irule_1.RuleTag.SingleFile, _irule_1.RuleTag.Quickfix],
82
82
  pseudoComment: "EC CI_SUBRC",
@@ -37,13 +37,13 @@ class ClassAttributeNames extends _abap_rule_1.ABAPRule {
37
37
  title: "Class attributes naming",
38
38
  shortDescription: `Allows you to enforce a pattern, such as a prefix, for class variable names.`,
39
39
  tags: [_irule_1.RuleTag.Naming, _irule_1.RuleTag.SingleFile],
40
- badExample: `CLASS zcl_foo DEFINITION PUBLIC.
41
- PUBLIC SECTION.
42
- DATA counter TYPE i.
40
+ badExample: `CLASS zcl_foo DEFINITION PUBLIC.
41
+ PUBLIC SECTION.
42
+ DATA counter TYPE i.
43
43
  ENDCLASS.`,
44
- goodExample: `CLASS zcl_foo DEFINITION PUBLIC.
45
- PUBLIC SECTION.
46
- DATA mv_counter TYPE i.
44
+ goodExample: `CLASS zcl_foo DEFINITION PUBLIC.
45
+ PUBLIC SECTION.
46
+ DATA mv_counter TYPE i.
47
47
  ENDCLASS.`,
48
48
  };
49
49
  }
@@ -54,17 +54,17 @@ class ClassicExceptionsOverlap extends _abap_rule_1.ABAPRule {
54
54
  shortDescription: `Find overlapping classic exceptions`,
55
55
  extendedInformation: `When debugging its typically good to know exactly which exception is caught`,
56
56
  tags: [_irule_1.RuleTag.SingleFile],
57
- badExample: `CALL FUNCTION 'SOMETHING'
58
- EXCEPTIONS
59
- system_failure = 1 MESSAGE lv_message
60
- communication_failure = 1 MESSAGE lv_message
61
- resource_failure = 1
57
+ badExample: `CALL FUNCTION 'SOMETHING'
58
+ EXCEPTIONS
59
+ system_failure = 1 MESSAGE lv_message
60
+ communication_failure = 1 MESSAGE lv_message
61
+ resource_failure = 1
62
62
  OTHERS = 1.`,
63
- goodExample: `CALL FUNCTION 'SOMETHING'
64
- EXCEPTIONS
65
- system_failure = 1 MESSAGE lv_message
66
- communication_failure = 2 MESSAGE lv_message
67
- resource_failure = 3
63
+ goodExample: `CALL FUNCTION 'SOMETHING'
64
+ EXCEPTIONS
65
+ system_failure = 1 MESSAGE lv_message
66
+ communication_failure = 2 MESSAGE lv_message
67
+ resource_failure = 3
68
68
  OTHERS = 4.`,
69
69
  };
70
70
  }
@@ -0,0 +1,254 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.ClearExportingParameters = exports.ClearExportingParametersConf = void 0;
37
+ const issue_1 = require("../issue");
38
+ const _basic_rule_config_1 = require("./_basic_rule_config");
39
+ const _irule_1 = require("./_irule");
40
+ const syntax_1 = require("../abap/5_syntax/syntax");
41
+ const _abap_object_1 = require("../objects/_abap_object");
42
+ const _scope_type_1 = require("../abap/5_syntax/_scope_type");
43
+ const objects_1 = require("../objects");
44
+ const _reference_1 = require("../abap/5_syntax/_reference");
45
+ const basic_1 = require("../abap/types/basic");
46
+ const _statement_1 = require("../abap/2_statements/statements/_statement");
47
+ const edit_helper_1 = require("../edit_helper");
48
+ const Expressions = __importStar(require("../abap/2_statements/expressions"));
49
+ class ClearExportingParametersConf extends _basic_rule_config_1.BasicRuleConfig {
50
+ constructor() {
51
+ super(...arguments);
52
+ /** Skip specific parameter names, case insensitive
53
+ * @uniqueItems true
54
+ */
55
+ this.skipNames = [];
56
+ }
57
+ }
58
+ exports.ClearExportingParametersConf = ClearExportingParametersConf;
59
+ class ClearExportingParameters {
60
+ constructor() {
61
+ this.conf = new ClearExportingParametersConf();
62
+ }
63
+ getMetadata() {
64
+ return {
65
+ key: "clear_exporting_parameters",
66
+ title: "Clear EXPORTING parameters",
67
+ shortDescription: `Checks that EXPORTING parameters passed by reference are cleared or assigned before they are read`,
68
+ extendedInformation: `An EXPORTING parameter passed by reference behaves like a CHANGING parameter: it is not
69
+ initialized when the method is called, so it can still contain a value supplied by the caller. Clear or overwrite it
70
+ before reading it, so a leftover value is not accidentally used.
71
+
72
+ https://github.com/SAP/styleguides/blob/main/clean-abap/CleanABAP.md#clear-or-overwrite-exporting-reference-parameters
73
+
74
+ https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/abenref_transf_output_param_guidl.htm
75
+
76
+ Note: EXPORTING parameters passed by VALUE are always initialized and are therefore not reported.
77
+ Reading and writing the parameter in the same statement (e.g. "ev_result = ev_result + 1") is reported,
78
+ as the source is evaluated before the parameter is assigned.
79
+ Objects containing parser or syntax errors are not reported.
80
+
81
+ Only class and interface method implementations are checked, function module parameters are currently not supported.`,
82
+ tags: [_irule_1.RuleTag.Styleguide],
83
+ badExample: `CLASS lcl DEFINITION.
84
+ PUBLIC SECTION.
85
+ METHODS foo EXPORTING ev_result TYPE i.
86
+ ENDCLASS.
87
+ CLASS lcl IMPLEMENTATION.
88
+ METHOD foo.
89
+ ev_result = ev_result + 1.
90
+ ENDMETHOD.
91
+ ENDCLASS.`,
92
+ goodExample: `CLASS lcl DEFINITION.
93
+ PUBLIC SECTION.
94
+ METHODS foo EXPORTING ev_result TYPE i.
95
+ ENDCLASS.
96
+ CLASS lcl IMPLEMENTATION.
97
+ METHOD foo.
98
+ CLEAR ev_result.
99
+ ev_result = ev_result + 1.
100
+ ENDMETHOD.
101
+ ENDCLASS.`,
102
+ };
103
+ }
104
+ getConfig() {
105
+ return this.conf;
106
+ }
107
+ setConfig(conf) {
108
+ this.conf = conf;
109
+ if (this.conf.skipNames === undefined) {
110
+ this.conf.skipNames = [];
111
+ }
112
+ }
113
+ initialize(reg) {
114
+ this.reg = reg;
115
+ return this;
116
+ }
117
+ run(obj) {
118
+ if (!(obj instanceof _abap_object_1.ABAPObject) || obj instanceof objects_1.Interface) {
119
+ return [];
120
+ }
121
+ for (const file of obj.getABAPFiles()) {
122
+ for (const statement of file.getStatements()) {
123
+ if (statement.get() instanceof _statement_1.Unknown) {
124
+ return []; // contains parser errors
125
+ }
126
+ }
127
+ }
128
+ const syntax = new syntax_1.SyntaxLogic(this.reg, obj).run();
129
+ if (syntax.issues.length > 0) {
130
+ return []; // contains syntax errors
131
+ }
132
+ const issues = [];
133
+ this.traverse(syntax.spaghetti.getTop(), obj, issues);
134
+ return issues;
135
+ }
136
+ traverse(node, obj, issues) {
137
+ if (node.getIdentifier().stype === _scope_type_1.ScopeType.Method) {
138
+ this.checkMethod(node, obj, issues);
139
+ }
140
+ for (const child of node.getChildren()) {
141
+ this.traverse(child, obj, issues);
142
+ }
143
+ }
144
+ checkMethod(node, obj, issues) {
145
+ const parameters = this.findExportingByReference(node, obj);
146
+ if (parameters.length === 0) {
147
+ return;
148
+ }
149
+ const references = this.collectReferences(node);
150
+ for (const parameter of parameters) {
151
+ const issue = this.checkParameter(parameter, references, obj);
152
+ if (issue !== undefined) {
153
+ issues.push(issue);
154
+ }
155
+ }
156
+ }
157
+ findExportingByReference(node, obj) {
158
+ var _a;
159
+ const ret = [];
160
+ const vars = node.getData().vars;
161
+ for (const name in vars) {
162
+ const parameter = vars[name];
163
+ const meta = parameter.getMeta();
164
+ if (meta.includes("exporting" /* IdentifierMeta.MethodExporting */) === false
165
+ || meta.includes("pass_by_value" /* IdentifierMeta.PassByValue */) === true) {
166
+ continue;
167
+ }
168
+ else if ((_a = this.conf.skipNames) === null || _a === void 0 ? void 0 : _a.some(s => s.toUpperCase() === name.toUpperCase())) {
169
+ continue;
170
+ }
171
+ const type = parameter.getType();
172
+ if (type instanceof basic_1.VoidType || type instanceof basic_1.UnknownType) {
173
+ continue; // e.g. RAP magic parameters, or unresolved types
174
+ }
175
+ else if (this.isPassByValue(parameter, obj) === true) {
176
+ continue; // VALUE(..) parameters are always initialized
177
+ }
178
+ ret.push(parameter);
179
+ }
180
+ return ret;
181
+ }
182
+ isPassByValue(parameter, obj) {
183
+ var _a;
184
+ // the PassByValue meta is not set for EXPORTING parameters, so determine it from the definition
185
+ const file = obj.getABAPFileByName(parameter.getFilename());
186
+ if (file === undefined) {
187
+ return false;
188
+ }
189
+ const statement = edit_helper_1.EditHelper.findStatement(parameter.getToken(), file);
190
+ if (statement === undefined) {
191
+ return false;
192
+ }
193
+ for (const param of statement.findAllExpressions(Expressions.MethodParam)) {
194
+ const nameToken = (_a = param.findFirstExpression(Expressions.MethodParamName)) === null || _a === void 0 ? void 0 : _a.getFirstToken();
195
+ if (nameToken !== undefined && nameToken.getStart().equals(parameter.getStart())) {
196
+ return param.getFirstToken().getStr().toUpperCase() === "VALUE";
197
+ }
198
+ }
199
+ return false;
200
+ }
201
+ collectReferences(node) {
202
+ // methods do not nest, so all descendant scopes (FOR, LET, ...) belong to this method
203
+ const ret = [...node.getData().references];
204
+ for (const child of node.getChildren()) {
205
+ ret.push(...this.collectReferences(child));
206
+ }
207
+ return ret;
208
+ }
209
+ checkParameter(parameter, references, obj) {
210
+ let firstRead = undefined;
211
+ let earliestWrite = undefined;
212
+ for (const reference of references) {
213
+ if (reference.resolved === undefined || parameter.equals(reference.resolved) === false) {
214
+ continue;
215
+ }
216
+ const pos = reference.position.getStart();
217
+ if (reference.referenceType === _reference_1.ReferenceType.DataReadReference) {
218
+ if (firstRead === undefined || pos.isBefore(firstRead.position.getStart())) {
219
+ firstRead = reference;
220
+ }
221
+ }
222
+ else if (reference.referenceType === _reference_1.ReferenceType.DataWriteReference) {
223
+ if (earliestWrite === undefined || pos.isBefore(earliestWrite)) {
224
+ earliestWrite = pos;
225
+ }
226
+ }
227
+ }
228
+ if (firstRead === undefined) {
229
+ return undefined; // never read, no hazard
230
+ }
231
+ // the parameter is safe only if it is written in a statement strictly before the first read
232
+ const readStatement = this.statementStart(firstRead.position.getStart(), obj);
233
+ const writeStatement = earliestWrite === undefined ? undefined : this.statementStart(earliestWrite, obj);
234
+ if (writeStatement !== undefined && readStatement !== undefined && writeStatement.isBefore(readStatement)) {
235
+ return undefined;
236
+ }
237
+ const message = `EXPORTING parameter "${parameter.getName().toLowerCase()}" read before it is cleared or assigned`;
238
+ return issue_1.Issue.atIdentifier(firstRead.position, message, this.getMetadata().key, this.conf.severity);
239
+ }
240
+ statementStart(pos, obj) {
241
+ for (const file of obj.getABAPFiles()) {
242
+ for (const statement of file.getStatements()) {
243
+ const start = statement.getStart();
244
+ const end = statement.getEnd();
245
+ if (pos.equals(start) || (pos.isAfter(start) && pos.isBefore(end))) {
246
+ return start;
247
+ }
248
+ }
249
+ }
250
+ return undefined;
251
+ }
252
+ }
253
+ exports.ClearExportingParameters = ClearExportingParameters;
254
+ //# sourceMappingURL=clear_exporting_parameters.js.map
@@ -30,7 +30,7 @@ class CommentedCode extends _abap_rule_1.ABAPRule {
30
30
  key: "commented_code",
31
31
  title: "Find commented code",
32
32
  shortDescription: `Detects usage of commented out code.`,
33
- extendedInformation: `https://github.com/SAP/styleguides/blob/main/clean-abap/CleanABAP.md#delete-code-instead-of-commenting-it
33
+ extendedInformation: `https://github.com/SAP/styleguides/blob/main/clean-abap/CleanABAP.md#delete-code-instead-of-commenting-it
34
34
  https://docs.abapopenchecks.org/checks/14/`,
35
35
  tags: [_irule_1.RuleTag.Styleguide, _irule_1.RuleTag.Quickfix, _irule_1.RuleTag.SingleFile],
36
36
  badExample: `* WRITE 'hello world'.`,
@@ -18,19 +18,19 @@ class ConstructorVisibilityPublic {
18
18
  key: "constructor_visibility_public",
19
19
  title: "Check constructor visibility is public",
20
20
  shortDescription: `Constructor must be placed in the public section, even if the class is not CREATE PUBLIC.`,
21
- extendedInformation: `
22
- This only applies to global classes.
23
-
24
- https://github.com/SAP/styleguides/blob/main/clean-abap/CleanABAP.md#if-your-global-class-is-create-private-leave-the-constructor-public
21
+ extendedInformation: `
22
+ This only applies to global classes.
23
+
24
+ https://github.com/SAP/styleguides/blob/main/clean-abap/CleanABAP.md#if-your-global-class-is-create-private-leave-the-constructor-public
25
25
  https://help.sap.com/doc/abapdocu_751_index_htm/7.51/en-US/abeninstance_constructor_guidl.htm`,
26
26
  tags: [_irule_1.RuleTag.Styleguide, _irule_1.RuleTag.SingleFile],
27
- badExample: `CLASS zcl_foo DEFINITION PUBLIC CREATE PRIVATE.
28
- PRIVATE SECTION.
29
- METHODS constructor.
27
+ badExample: `CLASS zcl_foo DEFINITION PUBLIC CREATE PRIVATE.
28
+ PRIVATE SECTION.
29
+ METHODS constructor.
30
30
  ENDCLASS.`,
31
- goodExample: `CLASS zcl_foo DEFINITION PUBLIC CREATE PRIVATE.
32
- PUBLIC SECTION.
33
- METHODS constructor.
31
+ goodExample: `CLASS zcl_foo DEFINITION PUBLIC CREATE PRIVATE.
32
+ PUBLIC SECTION.
33
+ METHODS constructor.
34
34
  ENDCLASS.`,
35
35
  };
36
36
  }
@@ -25,8 +25,8 @@ class ContainsTab extends _abap_rule_1.ABAPRule {
25
25
  key: "contains_tab",
26
26
  title: "Code contains tab",
27
27
  shortDescription: `Checks for usage of tabs (enable to enforce spaces)`,
28
- extendedInformation: `
29
- https://docs.abapopenchecks.org/checks/09/
28
+ extendedInformation: `
29
+ https://docs.abapopenchecks.org/checks/09/
30
30
  https://github.com/SAP/styleguides/blob/main/clean-abap/CleanABAP.md#indent-and-snap-to-tab`,
31
31
  tags: [_irule_1.RuleTag.Whitespace, _irule_1.RuleTag.Quickfix, _irule_1.RuleTag.Styleguide, _irule_1.RuleTag.SingleFile],
32
32
  badExample: `\tWRITE 'hello world'.`,
@@ -32,10 +32,10 @@ class CyclicOO {
32
32
  key: "cyclic_oo",
33
33
  title: "Cyclic OO",
34
34
  shortDescription: `Finds cyclic/circular OO references`,
35
- extendedInformation: `Runs for global INTF + CLAS objects
36
-
37
- Objects must be without syntax errors for this rule to take effect
38
-
35
+ extendedInformation: `Runs for global INTF + CLAS objects
36
+
37
+ Objects must be without syntax errors for this rule to take effect
38
+
39
39
  References in testclass includes are ignored`,
40
40
  };
41
41
  }
@@ -77,7 +77,7 @@ class DangerousStatement extends _abap_rule_1.ABAPRule {
77
77
  key: "dangerous_statement",
78
78
  title: "Dangerous statement",
79
79
  shortDescription: `Detects potentially dangerous statements`,
80
- extendedInformation: `Dynamic SQL: Typically ABAP logic does not need dynamic SQL,
80
+ extendedInformation: `Dynamic SQL: Typically ABAP logic does not need dynamic SQL,
81
81
  dynamic SQL can potentially create SQL injection problems`,
82
82
  tags: [_irule_1.RuleTag.SingleFile, _irule_1.RuleTag.Security],
83
83
  badExample: `SELECT * FROM (lv_table_name) INTO TABLE @DATA(lt_rows).`,
@@ -54,16 +54,16 @@ class DbOperationInLoop extends _abap_rule_1.ABAPRule {
54
54
  title: "Database operation in loop",
55
55
  shortDescription: `Database operation in LOOP/DO/WHILE`,
56
56
  tags: [_irule_1.RuleTag.SingleFile, _irule_1.RuleTag.Performance],
57
- badExample: `LOOP AT lt_items INTO DATA(ls_item).
58
- SELECT SINGLE name FROM zcustomer INTO @DATA(lv_name) WHERE id = @ls_item-customer_id.
57
+ badExample: `LOOP AT lt_items INTO DATA(ls_item).
58
+ SELECT SINGLE name FROM zcustomer INTO @DATA(lv_name) WHERE id = @ls_item-customer_id.
59
59
  ENDLOOP.`,
60
- goodExample: `ASSERT lines( lt_items ) > 0.
61
- SELECT id, name FROM zcustomer INTO TABLE @DATA(lt_customers)
62
- FOR ALL ENTRIES IN @lt_items
63
- WHERE id = @lt_items-customer_id.
64
-
65
- LOOP AT lt_items INTO DATA(ls_item).
66
- READ TABLE lt_customers INTO DATA(ls_customer) WITH KEY id = ls_item-customer_id.
60
+ goodExample: `ASSERT lines( lt_items ) > 0.
61
+ SELECT id, name FROM zcustomer INTO TABLE @DATA(lt_customers)
62
+ FOR ALL ENTRIES IN @lt_items
63
+ WHERE id = @lt_items-customer_id.
64
+
65
+ LOOP AT lt_items INTO DATA(ls_item).
66
+ READ TABLE lt_customers INTO DATA(ls_customer) WITH KEY id = ls_item-customer_id.
67
67
  ENDLOOP.`,
68
68
  };
69
69
  }
@@ -63,13 +63,13 @@ class DefinitionsTop extends _abap_rule_1.ABAPRule {
63
63
  shortDescription: `Checks that definitions are placed at the beginning of METHODs, FORMs and FUNCTIONs.`,
64
64
  extendedInformation: `https://docs.abapopenchecks.org/checks/17/`,
65
65
  tags: [_irule_1.RuleTag.SingleFile, _irule_1.RuleTag.Quickfix],
66
- badExample: `FORM foo.
67
- WRITE 'hello'.
68
- DATA int TYPE i.
66
+ badExample: `FORM foo.
67
+ WRITE 'hello'.
68
+ DATA int TYPE i.
69
69
  ENDFORM.`,
70
- goodExample: `FORM foo.
71
- DATA int TYPE i.
72
- WRITE 'hello'.
70
+ goodExample: `FORM foo.
71
+ DATA int TYPE i.
72
+ WRITE 'hello'.
73
73
  ENDFORM.`,
74
74
  };
75
75
  }