@abaplint/core 2.113.81 → 2.113.83
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/2_statements/statements/module.js +2 -1
- package/build/src/abap/5_syntax/expressions/select.js +45 -0
- package/build/src/abap/5_syntax/statements/select.js +1 -0
- package/build/src/abap/flow/flow_graph.js +7 -7
- package/build/src/lsp/help.js +10 -10
- package/build/src/registry.js +1 -1
- package/build/src/rules/7bit_ascii.js +4 -4
- package/build/src/rules/abapdoc.js +4 -4
- package/build/src/rules/add_test_attributes.js +20 -20
- package/build/src/rules/align_parameters.js +40 -40
- package/build/src/rules/align_type_expressions.js +28 -28
- package/build/src/rules/ambiguous_statement.js +7 -7
- package/build/src/rules/avoid_use.js +10 -10
- package/build/src/rules/begin_end_names.js +4 -4
- package/build/src/rules/begin_single_include.js +13 -13
- package/build/src/rules/call_transaction_authority_check.js +3 -3
- package/build/src/rules/cds_comment_style.js +4 -4
- package/build/src/rules/cds_legacy_view.js +4 -4
- package/build/src/rules/chain_mainly_declarations.js +4 -4
- package/build/src/rules/change_if_to_case.js +8 -8
- package/build/src/rules/check_abstract.js +2 -2
- package/build/src/rules/check_comments.js +4 -4
- package/build/src/rules/check_include.js +3 -3
- package/build/src/rules/check_subrc.js +8 -8
- package/build/src/rules/classic_exceptions_overlap.js +10 -10
- package/build/src/rules/commented_code.js +1 -1
- package/build/src/rules/constructor_visibility_public.js +4 -4
- package/build/src/rules/contains_tab.js +2 -2
- package/build/src/rules/cyclic_oo.js +4 -4
- package/build/src/rules/dangerous_statement.js +1 -1
- package/build/src/rules/definitions_top.js +6 -6
- package/build/src/rules/downport.js +157 -108
- package/build/src/rules/easy_to_find_messages.js +6 -6
- package/build/src/rules/empty_event.js +6 -6
- package/build/src/rules/empty_line_in_statement.js +2 -2
- package/build/src/rules/empty_structure.js +6 -6
- package/build/src/rules/exit_or_check.js +3 -3
- package/build/src/rules/expand_macros.js +5 -5
- package/build/src/rules/exporting.js +1 -1
- package/build/src/rules/forbidden_identifier.js +1 -1
- package/build/src/rules/forbidden_void_type.js +2 -2
- package/build/src/rules/fully_type_itabs.js +2 -2
- package/build/src/rules/functional_writing.js +17 -17
- package/build/src/rules/global_class.js +8 -8
- package/build/src/rules/identical_conditions.js +12 -12
- package/build/src/rules/identical_contents.js +14 -14
- package/build/src/rules/identical_descriptions.js +6 -6
- package/build/src/rules/if_in_if.js +35 -35
- package/build/src/rules/implement_methods.js +3 -3
- package/build/src/rules/implicit_start_of_selection.js +5 -5
- package/build/src/rules/in_statement_indentation.js +11 -11
- package/build/src/rules/indentation.js +16 -16
- package/build/src/rules/intf_referencing_clas.js +3 -3
- package/build/src/rules/invalid_table_index.js +2 -2
- package/build/src/rules/line_break_style.js +2 -2
- package/build/src/rules/line_length.js +1 -1
- package/build/src/rules/line_only_punc.js +1 -1
- package/build/src/rules/local_variable_names.js +6 -6
- package/build/src/rules/macro_naming.js +2 -2
- package/build/src/rules/main_file_contents.js +4 -4
- package/build/src/rules/many_parentheses.js +10 -10
- package/build/src/rules/max_one_method_parameter_per_line.js +7 -7
- package/build/src/rules/max_one_statement.js +5 -5
- package/build/src/rules/method_length.js +2 -2
- package/build/src/rules/method_overwrites_builtin.js +12 -12
- package/build/src/rules/mix_returning.js +6 -6
- package/build/src/rules/nesting.js +1 -1
- package/build/src/rules/no_chained_assignment.js +1 -1
- package/build/src/rules/no_external_form_calls.js +2 -2
- package/build/src/rules/no_inline_in_optional_branches.js +11 -11
- package/build/src/rules/no_prefixes.js +6 -6
- package/build/src/rules/no_public_attributes.js +1 -1
- package/build/src/rules/no_yoda_conditions.js +4 -4
- package/build/src/rules/nrob_consistency.js +2 -2
- package/build/src/rules/obsolete_statement.js +51 -51
- package/build/src/rules/omit_parameter_name.js +3 -3
- package/build/src/rules/omit_receiving.js +13 -13
- package/build/src/rules/parser_702_chaining.js +2 -2
- package/build/src/rules/parser_error.js +2 -2
- package/build/src/rules/parser_missing_space.js +1 -1
- package/build/src/rules/prefer_inline.js +16 -16
- package/build/src/rules/prefer_is_not.js +9 -9
- package/build/src/rules/prefer_raise_exception_new.js +5 -5
- package/build/src/rules/prefer_returning_to_exporting.js +4 -4
- package/build/src/rules/prefer_xsdbool.js +2 -2
- package/build/src/rules/preferred_compare_operator.js +2 -2
- package/build/src/rules/reduce_procedural_code.js +17 -17
- package/build/src/rules/remove_descriptions.js +4 -4
- package/build/src/rules/rfc_error_handling.js +7 -7
- package/build/src/rules/select_add_order_by.js +5 -5
- package/build/src/rules/select_performance.js +5 -5
- package/build/src/rules/select_single_full_key.js +2 -2
- package/build/src/rules/sicf_consistency.js +2 -2
- package/build/src/rules/slow_parameter_passing.js +16 -16
- package/build/src/rules/space_before_dot.js +2 -2
- package/build/src/rules/sql_value_conversion.js +6 -6
- package/build/src/rules/start_at_tab.js +1 -1
- package/build/src/rules/strict_sql.js +6 -6
- package/build/src/rules/sy_modification.js +3 -3
- package/build/src/rules/tabl_enhancement_category.js +2 -2
- package/build/src/rules/tables_declared_locally.js +2 -2
- package/build/src/rules/type_form_parameters.js +2 -2
- package/build/src/rules/unnecessary_pragma.js +29 -29
- package/build/src/rules/unnecessary_return.js +11 -11
- package/build/src/rules/unused_macros.js +6 -6
- package/build/src/rules/unused_methods.js +12 -12
- package/build/src/rules/unused_variables.js +12 -12
- package/build/src/rules/use_bool_expression.js +8 -8
- package/build/src/rules/use_class_based_exceptions.js +8 -8
- package/build/src/rules/use_line_exists.js +6 -6
- package/build/src/rules/use_new.js +4 -4
- package/build/src/rules/when_others_last.js +6 -6
- package/package.json +70 -70
|
@@ -35,14 +35,14 @@ class CheckSubrc extends _abap_rule_1.ABAPRule {
|
|
|
35
35
|
key: "check_subrc",
|
|
36
36
|
title: "Check sy-subrc",
|
|
37
37
|
shortDescription: `Check sy-subrc`,
|
|
38
|
-
extendedInformation: `Pseudo comment "#EC CI_SUBRC can be added to suppress findings
|
|
39
|
-
|
|
40
|
-
If sy-dbcnt is checked after database statements, it is considered okay.
|
|
41
|
-
|
|
42
|
-
"SELECT SINGLE @abap_true FROM " is considered as an existence check, also "SELECT COUNT( * )" is considered okay
|
|
43
|
-
|
|
44
|
-
If IS ASSIGNED is checked after assigning, it is considered okay.
|
|
45
|
-
|
|
38
|
+
extendedInformation: `Pseudo comment "#EC CI_SUBRC can be added to suppress findings
|
|
39
|
+
|
|
40
|
+
If sy-dbcnt is checked after database statements, it is considered okay.
|
|
41
|
+
|
|
42
|
+
"SELECT SINGLE @abap_true FROM " is considered as an existence check, also "SELECT COUNT( * )" is considered okay
|
|
43
|
+
|
|
44
|
+
If IS ASSIGNED is checked after assigning, it is considered okay.
|
|
45
|
+
|
|
46
46
|
FIND statement with MATCH COUNT is considered okay if subrc is not checked`,
|
|
47
47
|
tags: [_irule_1.RuleTag.SingleFile, _irule_1.RuleTag.Quickfix],
|
|
48
48
|
pseudoComment: "EC CI_SUBRC",
|
|
@@ -21,17 +21,17 @@ class ClassicExceptionsOverlap extends _abap_rule_1.ABAPRule {
|
|
|
21
21
|
shortDescription: `Find overlapping classic exceptions`,
|
|
22
22
|
extendedInformation: `When debugging its typically good to know exactly which exception is caught`,
|
|
23
23
|
tags: [_irule_1.RuleTag.SingleFile],
|
|
24
|
-
badExample: `CALL FUNCTION 'SOMETHING'
|
|
25
|
-
EXCEPTIONS
|
|
26
|
-
system_failure = 1 MESSAGE lv_message
|
|
27
|
-
communication_failure = 1 MESSAGE lv_message
|
|
28
|
-
resource_failure = 1
|
|
24
|
+
badExample: `CALL FUNCTION 'SOMETHING'
|
|
25
|
+
EXCEPTIONS
|
|
26
|
+
system_failure = 1 MESSAGE lv_message
|
|
27
|
+
communication_failure = 1 MESSAGE lv_message
|
|
28
|
+
resource_failure = 1
|
|
29
29
|
OTHERS = 1.`,
|
|
30
|
-
goodExample: `CALL FUNCTION 'SOMETHING'
|
|
31
|
-
EXCEPTIONS
|
|
32
|
-
system_failure = 1 MESSAGE lv_message
|
|
33
|
-
communication_failure = 2 MESSAGE lv_message
|
|
34
|
-
resource_failure = 3
|
|
30
|
+
goodExample: `CALL FUNCTION 'SOMETHING'
|
|
31
|
+
EXCEPTIONS
|
|
32
|
+
system_failure = 1 MESSAGE lv_message
|
|
33
|
+
communication_failure = 2 MESSAGE lv_message
|
|
34
|
+
resource_failure = 3
|
|
35
35
|
OTHERS = 4.`,
|
|
36
36
|
};
|
|
37
37
|
}
|
|
@@ -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,10 +18,10 @@ 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
27
|
};
|
|
@@ -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
|
}
|
|
@@ -41,7 +41,7 @@ class DangerousStatement extends _abap_rule_1.ABAPRule {
|
|
|
41
41
|
key: "dangerous_statement",
|
|
42
42
|
title: "Dangerous statement",
|
|
43
43
|
shortDescription: `Detects potentially dangerous statements`,
|
|
44
|
-
extendedInformation: `Dynamic SQL: Typically ABAP logic does not need dynamic SQL,
|
|
44
|
+
extendedInformation: `Dynamic SQL: Typically ABAP logic does not need dynamic SQL,
|
|
45
45
|
dynamic SQL can potentially create SQL injection problems`,
|
|
46
46
|
tags: [_irule_1.RuleTag.SingleFile, _irule_1.RuleTag.Security],
|
|
47
47
|
};
|
|
@@ -30,13 +30,13 @@ class DefinitionsTop extends _abap_rule_1.ABAPRule {
|
|
|
30
30
|
shortDescription: `Checks that definitions are placed at the beginning of METHODs, FORMs and FUNCTIONs.`,
|
|
31
31
|
extendedInformation: `https://docs.abapopenchecks.org/checks/17/`,
|
|
32
32
|
tags: [_irule_1.RuleTag.SingleFile, _irule_1.RuleTag.Quickfix],
|
|
33
|
-
badExample: `FROM foo.
|
|
34
|
-
WRITE 'hello'.
|
|
35
|
-
DATA int TYPE i.
|
|
33
|
+
badExample: `FROM foo.
|
|
34
|
+
WRITE 'hello'.
|
|
35
|
+
DATA int TYPE i.
|
|
36
36
|
ENDFORM.`,
|
|
37
|
-
goodExample: `FROM foo.
|
|
38
|
-
DATA int TYPE i.
|
|
39
|
-
WRITE 'hello'.
|
|
37
|
+
goodExample: `FROM foo.
|
|
38
|
+
DATA int TYPE i.
|
|
39
|
+
WRITE 'hello'.
|
|
40
40
|
ENDFORM.`,
|
|
41
41
|
};
|
|
42
42
|
}
|
|
@@ -2,32 +2,32 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.Downport = exports.DownportConf = void 0;
|
|
4
4
|
/* eslint-disable max-len */
|
|
5
|
-
const
|
|
5
|
+
const crypto = require("crypto");
|
|
6
|
+
const tokens_1 = require("../abap/1_lexer/tokens");
|
|
6
7
|
const Expressions = require("../abap/2_statements/expressions");
|
|
7
|
-
const
|
|
8
|
-
const
|
|
9
|
-
const issue_1 = require("../issue");
|
|
10
|
-
const _irule_1 = require("./_irule");
|
|
8
|
+
const Statements = require("../abap/2_statements/statements");
|
|
9
|
+
const statements_1 = require("../abap/2_statements/statements");
|
|
11
10
|
const _statement_1 = require("../abap/2_statements/statements/_statement");
|
|
12
|
-
const
|
|
13
|
-
const
|
|
14
|
-
const position_1 = require("../position");
|
|
15
|
-
const virtual_position_1 = require("../virtual_position");
|
|
16
|
-
const _abap_object_1 = require("../objects/_abap_object");
|
|
17
|
-
const version_1 = require("../version");
|
|
18
|
-
const registry_1 = require("../registry");
|
|
19
|
-
const syntax_1 = require("../abap/5_syntax/syntax");
|
|
11
|
+
const Structures = require("../abap/3_structures/structures");
|
|
12
|
+
const _builtin_1 = require("../abap/5_syntax/_builtin");
|
|
20
13
|
const _reference_1 = require("../abap/5_syntax/_reference");
|
|
14
|
+
const _scope_type_1 = require("../abap/5_syntax/_scope_type");
|
|
15
|
+
const syntax_1 = require("../abap/5_syntax/syntax");
|
|
16
|
+
const nodes_1 = require("../abap/nodes");
|
|
21
17
|
const _typed_identifier_1 = require("../abap/types/_typed_identifier");
|
|
22
18
|
const basic_1 = require("../abap/types/basic");
|
|
23
19
|
const config_1 = require("../config");
|
|
24
|
-
const
|
|
25
|
-
const
|
|
20
|
+
const edit_helper_1 = require("../edit_helper");
|
|
21
|
+
const issue_1 = require("../issue");
|
|
26
22
|
const objects_1 = require("../objects");
|
|
27
|
-
const
|
|
28
|
-
const
|
|
29
|
-
const
|
|
30
|
-
const
|
|
23
|
+
const _abap_object_1 = require("../objects/_abap_object");
|
|
24
|
+
const position_1 = require("../position");
|
|
25
|
+
const registry_1 = require("../registry");
|
|
26
|
+
const include_graph_1 = require("../utils/include_graph");
|
|
27
|
+
const version_1 = require("../version");
|
|
28
|
+
const virtual_position_1 = require("../virtual_position");
|
|
29
|
+
const _basic_rule_config_1 = require("./_basic_rule_config");
|
|
30
|
+
const _irule_1 = require("./_irule");
|
|
31
31
|
// todo: refactor each sub-rule to new classes?
|
|
32
32
|
// todo: add configuration
|
|
33
33
|
class DownportConf extends _basic_rule_config_1.BasicRuleConfig {
|
|
@@ -125,39 +125,39 @@ class Downport {
|
|
|
125
125
|
key: "downport",
|
|
126
126
|
title: "Downport statement",
|
|
127
127
|
shortDescription: `Downport functionality`,
|
|
128
|
-
extendedInformation: `Much like the 'commented_code' rule this rule loops through unknown statements and tries parsing with
|
|
129
|
-
a higher level language version. If successful, various rules are applied to downport the statement.
|
|
130
|
-
Target downport version is always v702, thus rule is only enabled if target version is v702.
|
|
131
|
-
|
|
132
|
-
Current rules:
|
|
133
|
-
* NEW transformed to CREATE OBJECT, opposite of https://rules.abaplint.org/use_new/
|
|
134
|
-
* DATA() definitions are outlined, opposite of https://rules.abaplint.org/prefer_inline/
|
|
135
|
-
* FIELD-SYMBOL() definitions are outlined
|
|
136
|
-
* CONV is outlined
|
|
137
|
-
* COND is outlined
|
|
138
|
-
* REDUCE is outlined
|
|
139
|
-
* SWITCH is outlined
|
|
140
|
-
* FILTER is outlined
|
|
141
|
-
* APPEND expression is outlined
|
|
142
|
-
* INSERT expression is outlined
|
|
143
|
-
* EMPTY KEY is changed to DEFAULT KEY, opposite of DEFAULT KEY in https://rules.abaplint.org/avoid_use/
|
|
144
|
-
* CAST changed to ?=
|
|
145
|
-
* LOOP AT method_call( ) is outlined
|
|
146
|
-
* VALUE # with structure fields
|
|
147
|
-
* VALUE # with internal table lines
|
|
148
|
-
* Table Expressions are outlined
|
|
149
|
-
* SELECT INTO @DATA definitions are outlined
|
|
150
|
-
* Some occurrences of string template formatting option ALPHA changed to function module call
|
|
151
|
-
* SELECT/INSERT/MODIFY/DELETE/UPDATE "," in field list removed, "@" in source/targets removed
|
|
152
|
-
* PARTIALLY IMPLEMENTED removed, it can be quick fixed via rule implement_methods
|
|
153
|
-
* RAISE EXCEPTION ... MESSAGE
|
|
154
|
-
* Moving with +=, -=, /=, *=, &&= is expanded
|
|
155
|
-
* line_exists and line_index is downported to READ TABLE
|
|
156
|
-
* ENUMs, but does not nessesarily give the correct type and value
|
|
157
|
-
* MESSAGE with non simple source
|
|
158
|
-
|
|
159
|
-
Only one transformation is applied to a statement at a time, so multiple steps might be required to do the full downport.
|
|
160
|
-
|
|
128
|
+
extendedInformation: `Much like the 'commented_code' rule this rule loops through unknown statements and tries parsing with
|
|
129
|
+
a higher level language version. If successful, various rules are applied to downport the statement.
|
|
130
|
+
Target downport version is always v702, thus rule is only enabled if target version is v702.
|
|
131
|
+
|
|
132
|
+
Current rules:
|
|
133
|
+
* NEW transformed to CREATE OBJECT, opposite of https://rules.abaplint.org/use_new/
|
|
134
|
+
* DATA() definitions are outlined, opposite of https://rules.abaplint.org/prefer_inline/
|
|
135
|
+
* FIELD-SYMBOL() definitions are outlined
|
|
136
|
+
* CONV is outlined
|
|
137
|
+
* COND is outlined
|
|
138
|
+
* REDUCE is outlined
|
|
139
|
+
* SWITCH is outlined
|
|
140
|
+
* FILTER is outlined
|
|
141
|
+
* APPEND expression is outlined
|
|
142
|
+
* INSERT expression is outlined
|
|
143
|
+
* EMPTY KEY is changed to DEFAULT KEY, opposite of DEFAULT KEY in https://rules.abaplint.org/avoid_use/
|
|
144
|
+
* CAST changed to ?=
|
|
145
|
+
* LOOP AT method_call( ) is outlined
|
|
146
|
+
* VALUE # with structure fields
|
|
147
|
+
* VALUE # with internal table lines
|
|
148
|
+
* Table Expressions are outlined
|
|
149
|
+
* SELECT INTO @DATA definitions are outlined
|
|
150
|
+
* Some occurrences of string template formatting option ALPHA changed to function module call
|
|
151
|
+
* SELECT/INSERT/MODIFY/DELETE/UPDATE "," in field list removed, "@" in source/targets removed
|
|
152
|
+
* PARTIALLY IMPLEMENTED removed, it can be quick fixed via rule implement_methods
|
|
153
|
+
* RAISE EXCEPTION ... MESSAGE
|
|
154
|
+
* Moving with +=, -=, /=, *=, &&= is expanded
|
|
155
|
+
* line_exists and line_index is downported to READ TABLE
|
|
156
|
+
* ENUMs, but does not nessesarily give the correct type and value
|
|
157
|
+
* MESSAGE with non simple source
|
|
158
|
+
|
|
159
|
+
Only one transformation is applied to a statement at a time, so multiple steps might be required to do the full downport.
|
|
160
|
+
|
|
161
161
|
Make sure to test the downported code, it might not always be completely correct.`,
|
|
162
162
|
tags: [_irule_1.RuleTag.Downport, _irule_1.RuleTag.Quickfix],
|
|
163
163
|
};
|
|
@@ -403,6 +403,10 @@ Make sure to test the downported code, it might not always be completely correct
|
|
|
403
403
|
if (found) {
|
|
404
404
|
return found;
|
|
405
405
|
}
|
|
406
|
+
found = this.downportSQLMoveInto(low, high, lowFile, highSyntax);
|
|
407
|
+
if (found) {
|
|
408
|
+
return found;
|
|
409
|
+
}
|
|
406
410
|
found = this.downportSQLExtras(low, high, lowFile, highSyntax);
|
|
407
411
|
if (found) {
|
|
408
412
|
return found;
|
|
@@ -536,6 +540,37 @@ Make sure to test the downported code, it might not always be completely correct
|
|
|
536
540
|
return undefined;
|
|
537
541
|
}
|
|
538
542
|
//////////////////////////////////////////
|
|
543
|
+
/** move INTO from after WHERE to after FROM */
|
|
544
|
+
downportSQLMoveInto(low, high, lowFile, _highSyntax) {
|
|
545
|
+
if (!(low.get() instanceof _statement_1.Unknown)) {
|
|
546
|
+
return undefined;
|
|
547
|
+
}
|
|
548
|
+
const where = high.findFirstExpression(Expressions.SQLCond);
|
|
549
|
+
if (where === undefined) {
|
|
550
|
+
return undefined;
|
|
551
|
+
}
|
|
552
|
+
let into = high.findFirstExpression(Expressions.SQLIntoList);
|
|
553
|
+
if (into === undefined) {
|
|
554
|
+
into = high.findFirstExpression(Expressions.SQLIntoStructure);
|
|
555
|
+
}
|
|
556
|
+
if (into === undefined) {
|
|
557
|
+
into = high.findFirstExpression(Expressions.SQLIntoTable);
|
|
558
|
+
}
|
|
559
|
+
if (into === undefined) {
|
|
560
|
+
return undefined;
|
|
561
|
+
}
|
|
562
|
+
if (where.getLastToken().getEnd().isBefore(into.getFirstToken().getStart()) === false) {
|
|
563
|
+
return undefined;
|
|
564
|
+
}
|
|
565
|
+
const from = high.findFirstExpression(Expressions.SQLFrom);
|
|
566
|
+
if (from === undefined) {
|
|
567
|
+
return undefined;
|
|
568
|
+
}
|
|
569
|
+
const fix1 = edit_helper_1.EditHelper.insertAt(lowFile, from.getLastToken().getEnd(), ` ` + into.concatTokens());
|
|
570
|
+
const fix2 = edit_helper_1.EditHelper.deleteRange(lowFile, into.getFirstToken().getStart(), into.getLastToken().getEnd());
|
|
571
|
+
const fix = edit_helper_1.EditHelper.merge(fix2, fix1);
|
|
572
|
+
return issue_1.Issue.atToken(lowFile, low.getFirstToken(), "SQL, move INTO", this.getMetadata().key, this.conf.severity, fix);
|
|
573
|
+
}
|
|
539
574
|
/** removes @'s and commas */
|
|
540
575
|
downportSQLExtras(low, high, lowFile, highSyntax) {
|
|
541
576
|
if (!(low.get() instanceof _statement_1.Unknown)) {
|
|
@@ -735,10 +770,10 @@ Make sure to test the downported code, it might not always be completely correct
|
|
|
735
770
|
const fieldName = f.concatTokens();
|
|
736
771
|
fieldDefinition += indentation + " " + fieldName + " TYPE " + tableName + "-" + fieldName + ",\n";
|
|
737
772
|
}
|
|
738
|
-
fieldDefinition = `DATA: BEGIN OF ${name},
|
|
773
|
+
fieldDefinition = `DATA: BEGIN OF ${name},
|
|
739
774
|
${fieldDefinition}${indentation} END OF ${name}.`;
|
|
740
775
|
}
|
|
741
|
-
const fix1 = edit_helper_1.EditHelper.insertAt(lowFile, high.getStart(), `${fieldDefinition}
|
|
776
|
+
const fix1 = edit_helper_1.EditHelper.insertAt(lowFile, high.getStart(), `${fieldDefinition}
|
|
742
777
|
${indentation}`);
|
|
743
778
|
const fix2 = edit_helper_1.EditHelper.replaceRange(lowFile, inlineData.getFirstToken().getStart(), inlineData.getLastToken().getEnd(), name);
|
|
744
779
|
const fix = edit_helper_1.EditHelper.merge(fix2, fix1);
|
|
@@ -797,12 +832,12 @@ ${indentation}`);
|
|
|
797
832
|
}
|
|
798
833
|
const uniqueName = this.uniqueName(high.getFirstToken().getStart(), lowFile.getFilename(), highSyntax);
|
|
799
834
|
const name = ((_g = inlineData.findFirstExpression(Expressions.TargetField)) === null || _g === void 0 ? void 0 : _g.concatTokens()) || "error";
|
|
800
|
-
let fix1 = edit_helper_1.EditHelper.insertAt(lowFile, high.getStart(), `TYPES: BEGIN OF ${uniqueName},
|
|
801
|
-
${fieldDefinitions}${indentation} END OF ${uniqueName}.
|
|
802
|
-
${indentation}DATA ${name} TYPE STANDARD TABLE OF ${uniqueName} WITH DEFAULT KEY.
|
|
835
|
+
let fix1 = edit_helper_1.EditHelper.insertAt(lowFile, high.getStart(), `TYPES: BEGIN OF ${uniqueName},
|
|
836
|
+
${fieldDefinitions}${indentation} END OF ${uniqueName}.
|
|
837
|
+
${indentation}DATA ${name} TYPE STANDARD TABLE OF ${uniqueName} WITH DEFAULT KEY.
|
|
803
838
|
${indentation}`);
|
|
804
839
|
if (fieldDefinitions === "") {
|
|
805
|
-
fix1 = edit_helper_1.EditHelper.insertAt(lowFile, high.getStart(), `DATA ${name} TYPE STANDARD TABLE OF ${tableName} WITH DEFAULT KEY.
|
|
840
|
+
fix1 = edit_helper_1.EditHelper.insertAt(lowFile, high.getStart(), `DATA ${name} TYPE STANDARD TABLE OF ${tableName} WITH DEFAULT KEY.
|
|
806
841
|
${indentation}`);
|
|
807
842
|
}
|
|
808
843
|
const fix2 = edit_helper_1.EditHelper.replaceRange(lowFile, inlineData.getFirstToken().getStart(), inlineData.getLastToken().getEnd(), name);
|
|
@@ -870,7 +905,7 @@ ${indentation}`);
|
|
|
870
905
|
const uniqueName = this.uniqueName(high.getFirstToken().getStart(), lowFile.getFilename(), highSyntax);
|
|
871
906
|
const indentation = " ".repeat(high.getFirstToken().getStart().getCol() - 1);
|
|
872
907
|
const firstToken = high.getFirstToken();
|
|
873
|
-
const fix1 = edit_helper_1.EditHelper.insertAt(lowFile, firstToken.getStart(), `DATA ${uniqueName} LIKE LINE OF ${target === null || target === void 0 ? void 0 : target.concatTokens()}.
|
|
908
|
+
const fix1 = edit_helper_1.EditHelper.insertAt(lowFile, firstToken.getStart(), `DATA ${uniqueName} LIKE LINE OF ${target === null || target === void 0 ? void 0 : target.concatTokens()}.
|
|
874
909
|
${indentation}${uniqueName} = ${source.concatTokens()}.\n${indentation}`);
|
|
875
910
|
const fix2 = edit_helper_1.EditHelper.replaceRange(lowFile, source.getFirstToken().getStart(), source.getLastToken().getEnd(), uniqueName);
|
|
876
911
|
const fix = edit_helper_1.EditHelper.merge(fix2, fix1);
|
|
@@ -924,7 +959,7 @@ ${indentation}${uniqueName} = ${source.concatTokens()}.\n${indentation}`);
|
|
|
924
959
|
const uniqueName = this.uniqueName(high.getFirstToken().getStart(), lowFile.getFilename(), highSyntax);
|
|
925
960
|
const indentation = " ".repeat(high.getFirstToken().getStart().getCol() - 1);
|
|
926
961
|
const firstToken = high.getFirstToken();
|
|
927
|
-
const fix1 = edit_helper_1.EditHelper.insertAt(lowFile, firstToken.getStart(), `DATA ${uniqueName} LIKE LINE OF ${target === null || target === void 0 ? void 0 : target.concatTokens()}.
|
|
962
|
+
const fix1 = edit_helper_1.EditHelper.insertAt(lowFile, firstToken.getStart(), `DATA ${uniqueName} LIKE LINE OF ${target === null || target === void 0 ? void 0 : target.concatTokens()}.
|
|
928
963
|
${indentation}${uniqueName} = ${source.concatTokens()}.\n${indentation}`);
|
|
929
964
|
const fix2 = edit_helper_1.EditHelper.replaceRange(lowFile, source.getFirstToken().getStart(), source.getLastToken().getEnd(), uniqueName);
|
|
930
965
|
const fix = edit_helper_1.EditHelper.merge(fix2, fix1);
|
|
@@ -966,14 +1001,14 @@ ${indentation}${uniqueName} = ${source.concatTokens()}.\n${indentation}`);
|
|
|
966
1001
|
const indentation = " ".repeat(high.getFirstToken().getStart().getCol() - 1);
|
|
967
1002
|
const firstToken = high.getFirstToken();
|
|
968
1003
|
// note that the tabix restore should be done before throwing the exception
|
|
969
|
-
const fix1 = edit_helper_1.EditHelper.insertAt(lowFile, firstToken.getStart(), `DATA ${uniqueName} LIKE LINE OF ${pre}.
|
|
970
|
-
${indentation}DATA ${tabixBackup} LIKE sy-tabix.
|
|
971
|
-
${indentation}${tabixBackup} = sy-tabix.
|
|
972
|
-
${indentation}READ TABLE ${pre} ${condition}INTO ${uniqueName}.
|
|
973
|
-
${indentation}sy-tabix = ${tabixBackup}.
|
|
974
|
-
${indentation}IF sy-subrc <> 0.
|
|
975
|
-
${indentation} RAISE EXCEPTION TYPE cx_sy_itab_line_not_found.
|
|
976
|
-
${indentation}ENDIF.
|
|
1004
|
+
const fix1 = edit_helper_1.EditHelper.insertAt(lowFile, firstToken.getStart(), `DATA ${uniqueName} LIKE LINE OF ${pre}.
|
|
1005
|
+
${indentation}DATA ${tabixBackup} LIKE sy-tabix.
|
|
1006
|
+
${indentation}${tabixBackup} = sy-tabix.
|
|
1007
|
+
${indentation}READ TABLE ${pre} ${condition}INTO ${uniqueName}.
|
|
1008
|
+
${indentation}sy-tabix = ${tabixBackup}.
|
|
1009
|
+
${indentation}IF sy-subrc <> 0.
|
|
1010
|
+
${indentation} RAISE EXCEPTION TYPE cx_sy_itab_line_not_found.
|
|
1011
|
+
${indentation}ENDIF.
|
|
977
1012
|
${indentation}`);
|
|
978
1013
|
const fix2 = edit_helper_1.EditHelper.replaceRange(lowFile, startToken.getStart(), tableExpression.getLastToken().getEnd(), uniqueName);
|
|
979
1014
|
const fix = edit_helper_1.EditHelper.merge(fix2, fix1);
|
|
@@ -1030,7 +1065,7 @@ ${indentation}`);
|
|
|
1030
1065
|
const className = classNames[0].concatTokens();
|
|
1031
1066
|
const targetName = (_b = target.findFirstExpression(Expressions.TargetField)) === null || _b === void 0 ? void 0 : _b.concatTokens();
|
|
1032
1067
|
const indentation = " ".repeat(node.getFirstToken().getStart().getCol() - 1);
|
|
1033
|
-
const code = ` DATA ${targetName} TYPE REF TO ${className}.
|
|
1068
|
+
const code = ` DATA ${targetName} TYPE REF TO ${className}.
|
|
1034
1069
|
${indentation}CATCH ${className} INTO ${targetName}.`;
|
|
1035
1070
|
const fix = edit_helper_1.EditHelper.replaceRange(lowFile, node.getStart(), node.getEnd(), code);
|
|
1036
1071
|
return issue_1.Issue.atToken(lowFile, node.getFirstToken(), "Outline DATA", this.getMetadata().key, this.conf.severity, fix);
|
|
@@ -1192,16 +1227,16 @@ ${indentation}CATCH ${className} INTO ${targetName}.`;
|
|
|
1192
1227
|
const uniqueName1 = this.uniqueName(node.getFirstToken().getStart(), lowFile.getFilename(), highSyntax);
|
|
1193
1228
|
const uniqueName2 = this.uniqueName(node.getFirstToken().getStart(), lowFile.getFilename(), highSyntax);
|
|
1194
1229
|
const indentation = " ".repeat(node.getFirstToken().getStart().getCol() - 1);
|
|
1195
|
-
let abap = `DATA ${uniqueName1} LIKE if_t100_message=>t100key.
|
|
1196
|
-
${indentation}${uniqueName1}-msgid = ${id}.
|
|
1230
|
+
let abap = `DATA ${uniqueName1} LIKE if_t100_message=>t100key.
|
|
1231
|
+
${indentation}${uniqueName1}-msgid = ${id}.
|
|
1197
1232
|
${indentation}${uniqueName1}-msgno = ${number}.\n`;
|
|
1198
1233
|
if (withs.length > 0) {
|
|
1199
|
-
abap += `${indentation}${uniqueName1}-attr1 = 'IF_T100_DYN_MSG~MSGV1'.
|
|
1200
|
-
${indentation}${uniqueName1}-attr2 = 'IF_T100_DYN_MSG~MSGV2'.
|
|
1201
|
-
${indentation}${uniqueName1}-attr3 = 'IF_T100_DYN_MSG~MSGV3'.
|
|
1234
|
+
abap += `${indentation}${uniqueName1}-attr1 = 'IF_T100_DYN_MSG~MSGV1'.
|
|
1235
|
+
${indentation}${uniqueName1}-attr2 = 'IF_T100_DYN_MSG~MSGV2'.
|
|
1236
|
+
${indentation}${uniqueName1}-attr3 = 'IF_T100_DYN_MSG~MSGV3'.
|
|
1202
1237
|
${indentation}${uniqueName1}-attr4 = 'IF_T100_DYN_MSG~MSGV4'.\n`;
|
|
1203
1238
|
}
|
|
1204
|
-
abap += `${indentation}DATA ${uniqueName2} TYPE REF TO ${className}.
|
|
1239
|
+
abap += `${indentation}DATA ${uniqueName2} TYPE REF TO ${className}.
|
|
1205
1240
|
${indentation}CREATE OBJECT ${uniqueName2} EXPORTING textid = ${uniqueName1}.\n`;
|
|
1206
1241
|
if (withs.length > 0) {
|
|
1207
1242
|
abap += `${indentation}${uniqueName2}->if_t100_dyn_msg~msgty = 'E'.\n`;
|
|
@@ -1313,10 +1348,10 @@ ${indentation}CREATE OBJECT ${uniqueName2} EXPORTING textid = ${uniqueName1}.\n`
|
|
|
1313
1348
|
let code = "";
|
|
1314
1349
|
if (sourceRef.findFirstExpression(Expressions.TableExpression)) {
|
|
1315
1350
|
const uniqueName = this.uniqueName(high.getFirstToken().getStart(), lowFile.getFilename(), highSyntax);
|
|
1316
|
-
code = `ASSIGN ${sourceRef.concatTokens()} TO FIELD-SYMBOL(<${uniqueName}>).
|
|
1317
|
-
IF sy-subrc <> 0.
|
|
1318
|
-
RAISE EXCEPTION TYPE cx_sy_itab_line_not_found.
|
|
1319
|
-
ENDIF.
|
|
1351
|
+
code = `ASSIGN ${sourceRef.concatTokens()} TO FIELD-SYMBOL(<${uniqueName}>).
|
|
1352
|
+
IF sy-subrc <> 0.
|
|
1353
|
+
RAISE EXCEPTION TYPE cx_sy_itab_line_not_found.
|
|
1354
|
+
ENDIF.
|
|
1320
1355
|
GET REFERENCE OF <${uniqueName}> INTO ${target.concatTokens()}`;
|
|
1321
1356
|
}
|
|
1322
1357
|
else {
|
|
@@ -1405,20 +1440,20 @@ GET REFERENCE OF <${uniqueName}> INTO ${target.concatTokens()}`;
|
|
|
1405
1440
|
const uniqueName = this.uniqueName(high.getFirstToken().getStart(), lowFile.getFilename(), highSyntax);
|
|
1406
1441
|
const uniqueFS = this.uniqueName(high.getFirstToken().getStart(), lowFile.getFilename(), highSyntax);
|
|
1407
1442
|
const uniqueNameIndex = this.uniqueName(high.getFirstToken().getStart(), lowFile.getFilename(), highSyntax);
|
|
1408
|
-
code += ` items LIKE ${loopSourceName},
|
|
1409
|
-
END OF ${groupTargetName}type.
|
|
1410
|
-
DATA ${groupTargetName}tab TYPE STANDARD TABLE OF ${groupTargetName}type WITH DEFAULT KEY.
|
|
1411
|
-
DATA ${uniqueName} LIKE LINE OF ${groupTargetName}tab.
|
|
1443
|
+
code += ` items LIKE ${loopSourceName},
|
|
1444
|
+
END OF ${groupTargetName}type.
|
|
1445
|
+
DATA ${groupTargetName}tab TYPE STANDARD TABLE OF ${groupTargetName}type WITH DEFAULT KEY.
|
|
1446
|
+
DATA ${uniqueName} LIKE LINE OF ${groupTargetName}tab.
|
|
1412
1447
|
LOOP AT ${loopSourceName} ${(_l = high.findFirstExpression(Expressions.LoopTarget)) === null || _l === void 0 ? void 0 : _l.concatTokens()}.\n`;
|
|
1413
1448
|
if (groupIndexName !== undefined) {
|
|
1414
1449
|
code += `DATA(${uniqueNameIndex}) = sy-tabix.\n`;
|
|
1415
1450
|
}
|
|
1416
|
-
code += `READ TABLE ${groupTargetName}tab ASSIGNING FIELD-SYMBOL(<${uniqueFS}>) WITH KEY ${condition}.
|
|
1451
|
+
code += `READ TABLE ${groupTargetName}tab ASSIGNING FIELD-SYMBOL(<${uniqueFS}>) WITH KEY ${condition}.
|
|
1417
1452
|
IF sy-subrc = 0.\n`;
|
|
1418
1453
|
if (groupCountName !== undefined) {
|
|
1419
1454
|
code += ` <${uniqueFS}>-${groupCountName} = <${uniqueFS}>-${groupCountName} + 1.\n`;
|
|
1420
1455
|
}
|
|
1421
|
-
code += ` INSERT ${loopTargetName}${isReference ? "->*" : ""} INTO TABLE <${uniqueFS}>-items.
|
|
1456
|
+
code += ` INSERT ${loopTargetName}${isReference ? "->*" : ""} INTO TABLE <${uniqueFS}>-items.
|
|
1422
1457
|
ELSE.\n`;
|
|
1423
1458
|
code += ` CLEAR ${uniqueName}.\n`;
|
|
1424
1459
|
for (const c of group.findAllExpressions(Expressions.LoopGroupByComponent)) {
|
|
@@ -1439,8 +1474,8 @@ ELSE.\n`;
|
|
|
1439
1474
|
}
|
|
1440
1475
|
code += ` INSERT ${loopTargetName}${isReference ? "->*" : ""} INTO TABLE ${uniqueName}-items.\n`;
|
|
1441
1476
|
code += ` INSERT ${uniqueName} INTO TABLE ${groupTargetName}tab.\n`;
|
|
1442
|
-
code += `ENDIF.
|
|
1443
|
-
ENDLOOP.
|
|
1477
|
+
code += `ENDIF.
|
|
1478
|
+
ENDLOOP.
|
|
1444
1479
|
LOOP AT ${groupTargetName}tab ${groupTarget}.`;
|
|
1445
1480
|
let fix = edit_helper_1.EditHelper.replaceRange(lowFile, high.getFirstToken().getStart(), high.getLastToken().getEnd(), code);
|
|
1446
1481
|
for (const l of ((_m = highFile.getStructure()) === null || _m === void 0 ? void 0 : _m.findAllStructures(Structures.Loop)) || []) {
|
|
@@ -1612,7 +1647,7 @@ LOOP AT ${groupTargetName}tab ${groupTarget}.`;
|
|
|
1612
1647
|
const enumName = (_b = high.findExpressionAfterToken("ENUM")) === null || _b === void 0 ? void 0 : _b.concatTokens();
|
|
1613
1648
|
const structureName = (_c = high.findExpressionAfterToken("STRUCTURE")) === null || _c === void 0 ? void 0 : _c.concatTokens();
|
|
1614
1649
|
// all ENUMS are char like?
|
|
1615
|
-
let code = `TYPES ${enumName} TYPE string.
|
|
1650
|
+
let code = `TYPES ${enumName} TYPE string.
|
|
1616
1651
|
CONSTANTS: BEGIN OF ${structureName},\n`;
|
|
1617
1652
|
let count = 1;
|
|
1618
1653
|
for (const e of enumStructure.findDirectStatements(Statements.TypeEnum).concat(enumStructure.findDirectStatements(Statements.Type))) {
|
|
@@ -1656,14 +1691,14 @@ CONSTANTS: BEGIN OF ${structureName},\n`;
|
|
|
1656
1691
|
const tabixBackup = this.uniqueName(high.getFirstToken().getStart(), lowFile.getFilename(), highSyntax);
|
|
1657
1692
|
const indentation = " ".repeat(high.getFirstToken().getStart().getCol() - 1);
|
|
1658
1693
|
// restore tabix before exeption
|
|
1659
|
-
const code = `FIELD-SYMBOLS ${uniqueName} LIKE LINE OF ${tName}.
|
|
1660
|
-
${indentation}DATA ${tabixBackup} LIKE sy-tabix.
|
|
1661
|
-
${indentation}${tabixBackup} = sy-tabix.
|
|
1662
|
-
${indentation}READ TABLE ${tName} ${condition}ASSIGNING ${uniqueName}.
|
|
1663
|
-
${indentation}sy-tabix = ${tabixBackup}.
|
|
1664
|
-
${indentation}IF sy-subrc <> 0.
|
|
1665
|
-
${indentation} RAISE EXCEPTION TYPE cx_sy_itab_line_not_found.
|
|
1666
|
-
${indentation}ENDIF.
|
|
1694
|
+
const code = `FIELD-SYMBOLS ${uniqueName} LIKE LINE OF ${tName}.
|
|
1695
|
+
${indentation}DATA ${tabixBackup} LIKE sy-tabix.
|
|
1696
|
+
${indentation}${tabixBackup} = sy-tabix.
|
|
1697
|
+
${indentation}READ TABLE ${tName} ${condition}ASSIGNING ${uniqueName}.
|
|
1698
|
+
${indentation}sy-tabix = ${tabixBackup}.
|
|
1699
|
+
${indentation}IF sy-subrc <> 0.
|
|
1700
|
+
${indentation} RAISE EXCEPTION TYPE cx_sy_itab_line_not_found.
|
|
1701
|
+
${indentation}ENDIF.
|
|
1667
1702
|
${indentation}${uniqueName}`;
|
|
1668
1703
|
const start = target.getFirstToken().getStart();
|
|
1669
1704
|
const end = (_a = tableExpression.findDirectTokenByText("]")) === null || _a === void 0 ? void 0 : _a.getEnd();
|
|
@@ -1743,11 +1778,11 @@ ${indentation}${uniqueName}`;
|
|
|
1743
1778
|
const indentation = " ".repeat(high.getFirstToken().getStart().getCol() - 1);
|
|
1744
1779
|
const source = (_b = child.findDirectExpression(Expressions.Source)) === null || _b === void 0 ? void 0 : _b.concatTokens();
|
|
1745
1780
|
const uniqueName = this.uniqueName(high.getFirstToken().getStart(), lowFile.getFilename(), highSyntax);
|
|
1746
|
-
const code = `DATA ${uniqueName} TYPE string.
|
|
1747
|
-
${indentation}CALL FUNCTION '${functionName}'
|
|
1748
|
-
${indentation} EXPORTING
|
|
1749
|
-
${indentation} input = ${source}
|
|
1750
|
-
${indentation} IMPORTING
|
|
1781
|
+
const code = `DATA ${uniqueName} TYPE string.
|
|
1782
|
+
${indentation}CALL FUNCTION '${functionName}'
|
|
1783
|
+
${indentation} EXPORTING
|
|
1784
|
+
${indentation} input = ${source}
|
|
1785
|
+
${indentation} IMPORTING
|
|
1751
1786
|
${indentation} output = ${uniqueName}.\n`;
|
|
1752
1787
|
const fix1 = edit_helper_1.EditHelper.insertAt(lowFile, high.getFirstToken().getStart(), code);
|
|
1753
1788
|
const fix2 = edit_helper_1.EditHelper.replaceRange(lowFile, child.getFirstToken().getStart(), child.getLastToken().getEnd(), uniqueName);
|
|
@@ -1780,24 +1815,33 @@ ${indentation} output = ${uniqueName}.\n`;
|
|
|
1780
1815
|
return issue_1.Issue.atToken(lowFile, high.getFirstToken(), "Outline LOOP input", this.getMetadata().key, this.conf.severity, fix);
|
|
1781
1816
|
}
|
|
1782
1817
|
outlineLoopTarget(node, lowFile, highSyntax) {
|
|
1783
|
-
var _a, _b, _c, _d, _e, _f
|
|
1818
|
+
var _a, _b, _c, _d, _e, _f;
|
|
1784
1819
|
// also allows outlining of voided types
|
|
1785
1820
|
if (!(node.get() instanceof Statements.Loop)) {
|
|
1786
1821
|
return undefined;
|
|
1787
1822
|
}
|
|
1788
|
-
const
|
|
1823
|
+
const source = node.findDirectExpression(Expressions.SimpleSource2);
|
|
1824
|
+
if (source === undefined) {
|
|
1825
|
+
return undefined;
|
|
1826
|
+
}
|
|
1827
|
+
const sourceName = source === null || source === void 0 ? void 0 : source.concatTokens();
|
|
1789
1828
|
if (sourceName === undefined) {
|
|
1790
1829
|
return undefined;
|
|
1791
1830
|
}
|
|
1831
|
+
let foundType = undefined;
|
|
1832
|
+
const spag = highSyntax.spaghetti.lookupPosition(source.getFirstToken().getStart(), lowFile.getFilename());
|
|
1833
|
+
if (spag) {
|
|
1834
|
+
foundType = spag.findVariable(source.concatTokens());
|
|
1835
|
+
}
|
|
1792
1836
|
const concat = node.concatTokens().toUpperCase();
|
|
1793
1837
|
if (concat.includes(" GROUP BY ") || concat.startsWith("LOOP AT GROUP ")) {
|
|
1794
1838
|
return undefined;
|
|
1795
1839
|
}
|
|
1796
1840
|
const isReference = concat.includes(" REFERENCE INTO ");
|
|
1797
1841
|
const indentation = " ".repeat(node.getFirstToken().getStart().getCol() - 1);
|
|
1798
|
-
const dataTarget = (
|
|
1842
|
+
const dataTarget = (_b = (_a = node.findDirectExpression(Expressions.LoopTarget)) === null || _a === void 0 ? void 0 : _a.findDirectExpression(Expressions.Target)) === null || _b === void 0 ? void 0 : _b.findDirectExpression(Expressions.InlineData);
|
|
1799
1843
|
if (dataTarget) {
|
|
1800
|
-
const targetName = ((
|
|
1844
|
+
const targetName = ((_c = dataTarget.findDirectExpression(Expressions.TargetField)) === null || _c === void 0 ? void 0 : _c.concatTokens()) || "DOWNPORT_ERROR";
|
|
1801
1845
|
let code = `DATA ${targetName} LIKE LINE OF ${sourceName}.\n${indentation}`;
|
|
1802
1846
|
if (isReference) {
|
|
1803
1847
|
const likeName = this.uniqueName(node.getFirstToken().getStart(), lowFile.getFilename(), highSyntax);
|
|
@@ -1808,10 +1852,15 @@ ${indentation} output = ${uniqueName}.\n`;
|
|
|
1808
1852
|
const fix = edit_helper_1.EditHelper.merge(fix2, fix1);
|
|
1809
1853
|
return issue_1.Issue.atToken(lowFile, node.getFirstToken(), "Outline LOOP data target", this.getMetadata().key, this.conf.severity, fix);
|
|
1810
1854
|
}
|
|
1811
|
-
const fsTarget = (
|
|
1855
|
+
const fsTarget = (_e = (_d = node.findDirectExpression(Expressions.LoopTarget)) === null || _d === void 0 ? void 0 : _d.findDirectExpression(Expressions.FSTarget)) === null || _e === void 0 ? void 0 : _e.findDirectExpression(Expressions.InlineFS);
|
|
1812
1856
|
if (fsTarget) {
|
|
1813
|
-
const targetName = ((
|
|
1814
|
-
|
|
1857
|
+
const targetName = ((_f = fsTarget.findDirectExpression(Expressions.TargetFieldSymbol)) === null || _f === void 0 ? void 0 : _f.concatTokens()) || "DOWNPORT_ERROR";
|
|
1858
|
+
let type = `LIKE LINE OF ${sourceName}`;
|
|
1859
|
+
const f = foundType === null || foundType === void 0 ? void 0 : foundType.getType();
|
|
1860
|
+
if (f instanceof basic_1.TableType && f.getRowType() instanceof basic_1.AnyType) {
|
|
1861
|
+
type = "TYPE ANY";
|
|
1862
|
+
}
|
|
1863
|
+
const code = `FIELD-SYMBOLS ${targetName} ${type}.\n${indentation}`;
|
|
1815
1864
|
const fix1 = edit_helper_1.EditHelper.insertAt(lowFile, node.getFirstToken().getStart(), code);
|
|
1816
1865
|
const fix2 = edit_helper_1.EditHelper.replaceRange(lowFile, fsTarget.getFirstToken().getStart(), fsTarget.getLastToken().getEnd(), targetName);
|
|
1817
1866
|
const fix = edit_helper_1.EditHelper.merge(fix2, fix1);
|
|
@@ -19,12 +19,12 @@ class EasyToFindMessages {
|
|
|
19
19
|
key: "easy_to_find_messages",
|
|
20
20
|
title: "Easy to find messages",
|
|
21
21
|
shortDescription: `Make messages easy to find`,
|
|
22
|
-
extendedInformation: `All messages must be statically referenced exactly once
|
|
23
|
-
|
|
24
|
-
Only MESSAGE and RAISE statments are counted as static references
|
|
25
|
-
|
|
26
|
-
Also see rule "message_exists"
|
|
27
|
-
|
|
22
|
+
extendedInformation: `All messages must be statically referenced exactly once
|
|
23
|
+
|
|
24
|
+
Only MESSAGE and RAISE statments are counted as static references
|
|
25
|
+
|
|
26
|
+
Also see rule "message_exists"
|
|
27
|
+
|
|
28
28
|
https://github.com/SAP/styleguides/blob/main/clean-abap/CleanABAP.md#make-messages-easy-to-find`,
|
|
29
29
|
tags: [_irule_1.RuleTag.Styleguide],
|
|
30
30
|
};
|
|
@@ -23,13 +23,13 @@ class EmptyEvent extends _abap_rule_1.ABAPRule {
|
|
|
23
23
|
shortDescription: `Empty selection screen or list processing event block`,
|
|
24
24
|
extendedInformation: ``,
|
|
25
25
|
tags: [_irule_1.RuleTag.SingleFile],
|
|
26
|
-
badExample: `
|
|
27
|
-
INITIALIZATION.
|
|
28
|
-
WRITE 'hello'.
|
|
26
|
+
badExample: `
|
|
27
|
+
INITIALIZATION.
|
|
28
|
+
WRITE 'hello'.
|
|
29
29
|
END-OF-SELECTION.`,
|
|
30
|
-
goodExample: `
|
|
31
|
-
START-OF-SELECTION.
|
|
32
|
-
PERFORM sdf.
|
|
30
|
+
goodExample: `
|
|
31
|
+
START-OF-SELECTION.
|
|
32
|
+
PERFORM sdf.
|
|
33
33
|
COMMIT WORK.`,
|
|
34
34
|
};
|
|
35
35
|
}
|
|
@@ -27,8 +27,8 @@ class EmptyLineinStatement extends _abap_rule_1.ABAPRule {
|
|
|
27
27
|
key: "empty_line_in_statement",
|
|
28
28
|
title: "Find empty lines in statements",
|
|
29
29
|
shortDescription: `Checks that statements do not contain empty lines.`,
|
|
30
|
-
extendedInformation: `https://github.com/SAP/styleguides/blob/main/clean-abap/CleanABAP.md#dont-obsess-with-separating-blank-lines
|
|
31
|
-
|
|
30
|
+
extendedInformation: `https://github.com/SAP/styleguides/blob/main/clean-abap/CleanABAP.md#dont-obsess-with-separating-blank-lines
|
|
31
|
+
|
|
32
32
|
https://docs.abapopenchecks.org/checks/41/`,
|
|
33
33
|
tags: [_irule_1.RuleTag.Quickfix, _irule_1.RuleTag.Whitespace, _irule_1.RuleTag.SingleFile, _irule_1.RuleTag.Styleguide],
|
|
34
34
|
badExample: `WRITE\n\nhello.`,
|