Skip to content

Commit c66bd35

Browse files
authored
Merge pull request #278 from SAP/Scope-of-the-Variable
Scope of the Variable
2 parents 2e4ffe7 + 4382c67 commit c66bd35

10 files changed

+898
-451
lines changed

docs/check_documentation.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
- [Cyclomatic Complexity](checks/cyclomatic-complexity.md)
1818
- [CX_ROOT Usage](checks/cx-root-usage.md)
1919
- [Database Access in Unit-Test](checks/db-access-in-ut.md)
20-
- [Declaration in IF](checks/declaration-in-if.md)
2120
- [Deprecated Classes](checks/deprecated-classes.md)
2221
- [Deprecated Key Word](checks/deprecated-key-word.md)
2322
- [Empty Catch](checks/empty_catch.md)
@@ -47,6 +46,7 @@
4746
- [READ TABLE with Subsequent Memory Assignment](checks/sub-assign-read-table.md)
4847
- [RECEIVING Statement Usage](checks/receiving-usage.md)
4948
- [Returning Name](checks/returning-name.md)
49+
- [Scope of Variable](checks/scope-of-variable.md)
5050
- [Self-Reference](checks/self-reference.md)
5151
- [TEST-SEAM Statement Usage](checks/test-seam-usage.md)
5252
- [Unit-Test Coverages (Statement, Branch and Procedure)](checks/unit-test-coverages.md)

docs/checks/declaration-in-if.md

Lines changed: 0 additions & 38 deletions
This file was deleted.
-6.12 KB
Binary file not shown.

docs/checks/scope-of-variable.md

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# code pal for ABAP
2+
3+
[code pal for ABAP](../../README.md) > [Documentation](../check_documentation.md) > [Scope of Variable](scope-of-variable.md)
4+
5+
## Scope of Variable
6+
7+
### What is the Intent of the Check?
8+
If a variable is declared in a statement, it should be used/referred to inside this statement only (not outside).
9+
10+
### How does the check work?
11+
It searches for `DATA` and `FIELD-SYMBOLS` declaration inside of `IF`, `ELSEIF`, `ELSE`, `DO`, `CASE/WHEN`, `LOOP`, and `WHILE` statements, and for its usage/reference outside this statement.
12+
13+
### How to solve the issue?
14+
Relocate the declaration.
15+
16+
### What to do in case of exception?
17+
You can suppress Code Inspector findings generated by this check using the pseudo comment `"#EC SCOPE_OF_VAR`.
18+
The pseudo comment must be placed right after the variable usage/referece.
19+
20+
```abap
21+
IF has_entries = abap_true.
22+
DATA(value) = 1.
23+
ELSE.
24+
value = 2. "#EC SCOPE_OF_VAR
25+
ENDIF.
26+
```
27+
28+
### Example
29+
30+
Before:
31+
```abap
32+
IF has_entries = abap_true.
33+
DATA(value) = 1.
34+
ELSE.
35+
value = 2.
36+
ENDIF.
37+
```
38+
39+
After:
40+
```abap
41+
DATA value TYPE i.
42+
43+
IF has_entries = abap_true.
44+
value = 1.
45+
ELSE.
46+
value = 2.
47+
ENDIF.
48+
```
49+
50+
### Further Readings & Knowledge
51+
* [ABAP Styleguides on Clean Code](https://github.com/SAP/styleguides/blob/master/clean-abap/CleanABAP.md#dont-declare-inline-in-optional-branches)

src/checks/y_check_declaration_in_if.clas.abap

Lines changed: 0 additions & 109 deletions
This file was deleted.

src/checks/y_check_declaration_in_if.clas.testclasses.abap

Lines changed: 0 additions & 52 deletions
This file was deleted.
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
CLASS y_check_scope_of_variable DEFINITION PUBLIC INHERITING FROM y_check_base CREATE PUBLIC .
2+
PUBLIC SECTION.
3+
METHODS constructor .
4+
5+
PROTECTED SECTION.
6+
METHODS inspect_tokens REDEFINITION.
7+
8+
PRIVATE SECTION.
9+
METHODS is_isolated IMPORTING strucutre_row TYPE stmnt_stru
10+
RETURNING VALUE(result) TYPE abap_bool.
11+
12+
METHODS extract_variable_name IMPORTING token TYPE string
13+
RETURNING VALUE(result) TYPE string.
14+
15+
METHODS get_scope_structure IMPORTING strucutre_row TYPE stmnt_stru
16+
RETURNING VALUE(result) TYPE sstruc.
17+
18+
ENDCLASS.
19+
20+
21+
22+
CLASS y_check_scope_of_variable IMPLEMENTATION.
23+
24+
25+
METHOD constructor.
26+
super->constructor( ).
27+
28+
settings-pseudo_comment = '"#EC SCOPE_OF_VAR' ##NO_TEXT.
29+
settings-disable_threshold_selection = abap_true.
30+
settings-threshold = 0.
31+
settings-prio = c_warning.
32+
settings-documentation = |{ c_docs_path-checks }scope-of-variable.md|.
33+
34+
set_check_message( 'Variable in use out of its scope!' ).
35+
ENDMETHOD.
36+
37+
38+
METHOD inspect_tokens.
39+
40+
DATA(token) = get_token_abs( statement-from ).
41+
42+
IF token NP 'DATA(*)'
43+
AND token NP 'FIELD-SYMBOLS(*)'.
44+
RETURN.
45+
ENDIF.
46+
47+
IF is_isolated( statement-struc ) = abap_false.
48+
RETURN.
49+
ENDIF.
50+
51+
DATA(variable) = extract_variable_name( token ).
52+
DATA(scope) = get_scope_structure( statement-struc ).
53+
DATA(statement_index) = index.
54+
55+
LOOP AT ref_scan_manager->get_statements( ) ASSIGNING FIELD-SYMBOL(<statement>)
56+
FROM scope-stmnt_from TO scope-stmnt_to
57+
WHERE number > statement-number.
58+
59+
statement_index = statement_index + 1.
60+
61+
IF <statement>-struc = statement-struc.
62+
CONTINUE.
63+
ENDIF.
64+
65+
LOOP AT ref_scan_manager->get_tokens( ) ASSIGNING FIELD-SYMBOL(<tokens>)
66+
FROM <statement>-from TO <statement>-to
67+
WHERE str = variable.
68+
69+
DATA(check_configuration) = detect_check_configuration( <statement> ).
70+
71+
IF check_configuration IS INITIAL.
72+
RETURN.
73+
ENDIF.
74+
75+
raise_error( statement_level = <statement>-level
76+
statement_index = statement_index
77+
statement_from = <statement>-from
78+
error_priority = check_configuration-prio ).
79+
ENDLOOP.
80+
81+
ENDLOOP.
82+
ENDMETHOD.
83+
84+
85+
METHOD is_isolated.
86+
DATA(structures) = ref_scan_manager->get_structures( ).
87+
DATA(structure) = structures[ strucutre_row ].
88+
89+
result = xsdbool( structure-stmnt_type = scan_struc_stmnt_type-if
90+
OR structure-stmnt_type = scan_struc_stmnt_type-then
91+
OR structure-stmnt_type = scan_struc_stmnt_type-elseif
92+
OR structure-stmnt_type = scan_struc_stmnt_type-else
93+
OR structure-stmnt_type = scan_struc_stmnt_type-do
94+
OR structure-stmnt_type = scan_struc_stmnt_type-case
95+
OR structure-stmnt_type = scan_struc_stmnt_type-when
96+
OR structure-stmnt_type = scan_struc_stmnt_type-loop
97+
OR structure-stmnt_type = scan_struc_stmnt_type-while ).
98+
ENDMETHOD.
99+
100+
101+
METHOD extract_variable_name.
102+
result = token.
103+
REPLACE ALL OCCURRENCES OF 'DATA(' IN result WITH ''.
104+
REPLACE ALL OCCURRENCES OF 'FIELD-SYMBOLS(' IN result WITH ''.
105+
REPLACE ALL OCCURRENCES OF ')' IN result WITH ''.
106+
ENDMETHOD.
107+
108+
109+
METHOD get_scope_structure.
110+
DATA(structures) = ref_scan_manager->get_structures( ).
111+
DATA(structure) = structures[ strucutre_row ].
112+
113+
DATA(is_root) = xsdbool( structure-stmnt_type = scan_struc_stmnt_type-form
114+
OR structure-stmnt_type = scan_struc_stmnt_type-method
115+
OR structure-stmnt_type = scan_struc_stmnt_type-function
116+
OR structure-stmnt_type = scan_struc_stmnt_type-module
117+
OR structure-type = scan_struc_type-event ).
118+
119+
result = COND #( WHEN is_root = abap_true THEN structure
120+
ELSE get_scope_structure( structure-back ) ).
121+
ENDMETHOD.
122+
123+
ENDCLASS.

0 commit comments

Comments
 (0)