From c36460fb271b228726221479d9686a7b88eb1a42 Mon Sep 17 00:00:00 2001
From: ConjuringCoffee <72548231+ConjuringCoffee@users.noreply.github.com>
Date: Fri, 5 Jan 2024 11:18:21 +0000
Subject: [PATCH 01/10] Add check 102 to detect SY-SYSID usage
---
src/checks/zcl_aoc_check_102.clas.abap | 85 +++
.../zcl_aoc_check_102.clas.locals_def.abap | 45 ++
.../zcl_aoc_check_102.clas.locals_imp.abap | 80 +++
.../zcl_aoc_check_102.clas.testclasses.abap | 493 ++++++++++++++++++
src/checks/zcl_aoc_check_102.clas.xml | 85 +++
src/checks/zcl_aoc_scan.clas.abap | 25 +-
6 files changed, 812 insertions(+), 1 deletion(-)
create mode 100644 src/checks/zcl_aoc_check_102.clas.abap
create mode 100644 src/checks/zcl_aoc_check_102.clas.locals_def.abap
create mode 100644 src/checks/zcl_aoc_check_102.clas.locals_imp.abap
create mode 100644 src/checks/zcl_aoc_check_102.clas.testclasses.abap
create mode 100644 src/checks/zcl_aoc_check_102.clas.xml
diff --git a/src/checks/zcl_aoc_check_102.clas.abap b/src/checks/zcl_aoc_check_102.clas.abap
new file mode 100644
index 00000000..c34efbf3
--- /dev/null
+++ b/src/checks/zcl_aoc_check_102.clas.abap
@@ -0,0 +1,85 @@
+"!
102 - Use of system ID
+CLASS zcl_aoc_check_102 DEFINITION
+ PUBLIC
+ INHERITING FROM zcl_aoc_super
+ FINAL.
+
+ PUBLIC SECTION.
+ METHODS constructor.
+
+ METHODS check REDEFINITION.
+
+ PRIVATE SECTION.
+
+ENDCLASS.
+
+
+CLASS zcl_aoc_check_102 IMPLEMENTATION.
+ METHOD constructor.
+ super->constructor( ).
+
+ version = '001'.
+ position = '102'.
+
+ has_attributes = abap_true.
+ attributes_ok = abap_true.
+
+ insert_scimessage( iv_code = gc_code-usage_uncategorized
+ iv_text = TEXT-001 ).
+ insert_scimessage( iv_code = gc_code-in_condition
+ iv_text = TEXT-002 ).
+ insert_scimessage( iv_code = gc_code-first_letter_used
+ iv_text = TEXT-003 ).
+ insert_scimessage( iv_code = gc_code-as_default_value
+ iv_text = TEXT-004 ).
+ insert_scimessage( iv_code = gc_code-in_concatenate
+ iv_text = TEXT-005 ).
+ insert_scimessage( iv_code = gc_code-overridden
+ iv_text = TEXT-006 ).
+ insert_scimessage( iv_code = gc_code-assigned_to_variable
+ iv_text = TEXT-007 ).
+ insert_scimessage( iv_code = gc_code-in_database_select
+ iv_text = TEXT-008 ).
+ insert_scimessage( iv_code = gc_code-in_write
+ iv_text = TEXT-009 ).
+ insert_scimessage( iv_code = gc_code-in_message
+ iv_text = TEXT-010 ).
+ insert_scimessage( iv_code = gc_code-within_macro
+ iv_text = TEXT-011 ).
+ ENDMETHOD.
+
+ METHOD check.
+ " abapOpenChecks
+ " https://github.com/larshp/abapOpenChecks
+ " MIT License
+
+ DATA(lo_helper) = NEW lcl_check_helper( io_scan ).
+
+ LOOP AT io_scan->statements ASSIGNING FIELD-SYMBOL().
+ LOOP AT io_scan->tokens ASSIGNING FIELD-SYMBOL()
+ FROM -from TO -to
+ WHERE str CP 'SY-SYSID*'
+ OR str CP '@SY-SYSID*'.
+
+ DATA(lv_index_token) = sy-tabix.
+
+ DATA(lv_error_code) = lo_helper->determine_error_code( is_token =
+ iv_index_token = lv_index_token
+ is_statement = ).
+
+ IF lv_error_code IS INITIAL.
+ " No error
+ CONTINUE.
+ ENDIF.
+
+ DATA(lv_include) = io_scan->get_include( -level ).
+
+ inform( p_sub_obj_name = lv_include
+ p_line = -row
+ p_kind = mv_errty
+ p_test = myname
+ p_code = lv_error_code ).
+ ENDLOOP.
+ ENDLOOP.
+ ENDMETHOD.
+ENDCLASS.
diff --git a/src/checks/zcl_aoc_check_102.clas.locals_def.abap b/src/checks/zcl_aoc_check_102.clas.locals_def.abap
new file mode 100644
index 00000000..ca896ac5
--- /dev/null
+++ b/src/checks/zcl_aoc_check_102.clas.locals_def.abap
@@ -0,0 +1,45 @@
+CONSTANTS:
+ BEGIN OF gc_code,
+ usage_uncategorized TYPE sci_errc VALUE '001',
+ in_condition TYPE sci_errc VALUE '002',
+ first_letter_used TYPE sci_errc VALUE '003',
+ as_default_value TYPE sci_errc VALUE '004',
+ in_concatenate TYPE sci_errc VALUE '005',
+ overridden TYPE sci_errc VALUE '006',
+ assigned_to_variable TYPE sci_errc VALUE '007',
+ in_database_select TYPE sci_errc VALUE '008',
+ in_write TYPE sci_errc VALUE '009',
+ in_message TYPE sci_errc VALUE '010',
+ within_macro TYPE sci_errc VALUE '011',
+ END OF gc_code.
+
+CLASS lcl_check_helper DEFINITION.
+
+ PUBLIC SECTION.
+ METHODS constructor
+ IMPORTING
+ io_scan TYPE REF TO zcl_aoc_scan.
+
+ METHODS determine_error_code
+ IMPORTING
+ is_token TYPE stokesx
+ iv_index_token TYPE syst_tabix
+ is_statement TYPE sstmnt
+ RETURNING
+ VALUE(rv_error_code) TYPE sci_errc.
+
+ PRIVATE SECTION.
+ DATA mo_scan TYPE REF TO zcl_aoc_scan.
+
+ METHODS is_using_only_first_letter
+ IMPORTING
+ is_token TYPE stokesx
+ RETURNING
+ VALUE(rv_result) TYPE abap_bool.
+
+ METHODS is_used_in_macro
+ IMPORTING
+ is_statement TYPE sstmnt
+ RETURNING
+ VALUE(rv_result) TYPE abap_bool.
+ENDCLASS.
diff --git a/src/checks/zcl_aoc_check_102.clas.locals_imp.abap b/src/checks/zcl_aoc_check_102.clas.locals_imp.abap
new file mode 100644
index 00000000..7e0467d6
--- /dev/null
+++ b/src/checks/zcl_aoc_check_102.clas.locals_imp.abap
@@ -0,0 +1,80 @@
+CLASS lcl_check_helper IMPLEMENTATION.
+ METHOD constructor.
+ mo_scan = io_scan.
+ ENDMETHOD.
+
+ METHOD determine_error_code.
+ IF is_using_only_first_letter( is_token ).
+ rv_error_code = gc_code-first_letter_used.
+ RETURN.
+ ENDIF.
+
+ IF is_used_in_macro( is_statement ).
+ rv_error_code = gc_code-within_macro.
+ RETURN.
+ ENDIF.
+
+ ASSIGN mo_scan->tokens[ is_statement-from ] TO FIELD-SYMBOL().
+
+ CASE -str.
+ WHEN zcl_aoc_scan=>gc_keyword-types
+ OR zcl_aoc_scan=>gc_keyword-ranges.
+ " Ignore
+ RETURN.
+ WHEN zcl_aoc_scan=>gc_keyword-concatenate.
+ rv_error_code = gc_code-in_concatenate.
+ WHEN is_token-str.
+ rv_error_code = gc_code-overridden.
+ WHEN zcl_aoc_scan=>gc_keyword-select.
+ rv_error_code = gc_code-in_database_select.
+ WHEN zcl_aoc_scan=>gc_keyword-write.
+ rv_error_code = gc_code-in_write.
+ WHEN zcl_aoc_scan=>gc_keyword-message.
+ rv_error_code = gc_code-in_message.
+ WHEN zcl_aoc_scan=>gc_keyword-if
+ OR zcl_aoc_scan=>gc_keyword-elseif
+ OR zcl_aoc_scan=>gc_keyword-case
+ OR zcl_aoc_scan=>gc_keyword-when
+ OR zcl_aoc_scan=>gc_keyword-check
+ OR zcl_aoc_scan=>gc_keyword-assert.
+ rv_error_code = gc_code-in_condition.
+ WHEN zcl_aoc_scan=>gc_keyword-methods
+ OR zcl_aoc_scan=>gc_keyword-class_methods
+ OR zcl_aoc_scan=>gc_keyword-data
+ OR zcl_aoc_scan=>gc_keyword-class_data.
+ ASSIGN mo_scan->tokens[ iv_index_token - 1 ] TO FIELD-SYMBOL().
+
+ CASE -str.
+ WHEN zcl_aoc_scan=>gc_keyword-default.
+ rv_error_code = gc_code-as_default_value.
+ WHEN zcl_aoc_scan=>gc_keyword-like
+ OR zcl_aoc_scan=>gc_keyword-type.
+ " Ignore
+ RETURN.
+ ENDCASE.
+ WHEN OTHERS.
+ READ TABLE mo_scan->tokens ASSIGNING INDEX iv_index_token - 1.
+
+ IF -str = '='
+ AND iv_index_token - is_statement-from = 2.
+ rv_error_code = gc_code-assigned_to_variable.
+ ELSE.
+ rv_error_code = gc_code-usage_uncategorized.
+ ENDIF.
+ ENDCASE.
+ ENDMETHOD.
+
+ METHOD is_using_only_first_letter.
+ rv_result = xsdbool( is_token-str = 'SY-SYSID+0(1)'
+ OR is_token-str = 'SY-SYSID(1)' ).
+ ENDMETHOD.
+
+ METHOD is_used_in_macro.
+ ASSIGN mo_scan->tokens[ is_statement-to + 1 ] TO FIELD-SYMBOL().
+
+ IF sy-subrc = 0
+ AND -str = zcl_aoc_scan=>gc_keyword-end_of_definition.
+ rv_result = abap_true.
+ ENDIF.
+ ENDMETHOD.
+ENDCLASS.
diff --git a/src/checks/zcl_aoc_check_102.clas.testclasses.abap b/src/checks/zcl_aoc_check_102.clas.testclasses.abap
new file mode 100644
index 00000000..636ebb9c
--- /dev/null
+++ b/src/checks/zcl_aoc_check_102.clas.testclasses.abap
@@ -0,0 +1,493 @@
+CLASS ltcl_test DEFINITION
+ FINAL
+ FOR TESTING
+ RISK LEVEL HARMLESS
+ DURATION SHORT.
+
+ PRIVATE SECTION.
+ DATA mt_code TYPE string_table.
+ DATA ms_result TYPE scirest_ad.
+ DATA mo_check TYPE REF TO zcl_aoc_check_102.
+
+ METHODS setup.
+
+ METHODS assert_error_code
+ IMPORTING
+ iv_expected_error_code TYPE sci_errc.
+
+ METHODS assert_no_error_code.
+ METHODS execute_check.
+
+ METHODS export_import FOR TESTING.
+ METHODS if_condition_01 FOR TESTING.
+ METHODS first_letter_01 FOR TESTING.
+ METHODS first_letter_02 FOR TESTING.
+ METHODS if_condition_02 FOR TESTING.
+ METHODS if_condition_03 FOR TESTING.
+ METHODS case_condition_01 FOR TESTING.
+ METHODS case_condition_02 FOR TESTING.
+ METHODS case_condition_03 FOR TESTING.
+ METHODS elseif_condition FOR TESTING.
+ METHODS constructor_expression_cond FOR TESTING.
+ METHODS local_variable_assignment FOR TESTING.
+ METHODS constructor_expression_switch FOR TESTING.
+ METHODS within_macro FOR TESTING.
+ METHODS method_call FOR TESTING.
+ METHODS database_select_01 FOR TESTING.
+ METHODS database_select_02 FOR TESTING.
+ METHODS ignore_type_definition_01 FOR TESTING.
+ METHODS ignore_type_definition_02 FOR TESTING.
+ METHODS ignore_type_definition_03 FOR TESTING.
+ METHODS ignore_type_definition_04 FOR TESTING.
+ METHODS ignore_type_definition_05 FOR TESTING.
+ METHODS ignore_type_definition_06 FOR TESTING.
+ METHODS ignore_type_definition_07 FOR TESTING.
+ METHODS ignore_type_definition_08 FOR TESTING.
+ METHODS ignore_ranges FOR TESTING.
+ METHODS default_value_01 FOR TESTING.
+ METHODS default_value_02 FOR TESTING.
+ METHODS concatenate FOR TESTING.
+ METHODS overridden FOR TESTING.
+ METHODS write FOR TESTING.
+ METHODS message FOR TESTING.
+ METHODS check_condition FOR TESTING.
+ METHODS assert_condition FOR TESTING.
+
+ENDCLASS.
+
+
+CLASS ltcl_test IMPLEMENTATION.
+ DEFINE _code.
+ APPEND &1 TO mt_code.
+ END-OF-DEFINITION.
+
+ METHOD setup.
+ mo_check = NEW #( ).
+ zcl_aoc_unit_test=>set_check( mo_check ).
+ ENDMETHOD.
+
+ METHOD execute_check.
+ ms_result = zcl_aoc_unit_test=>check( mt_code ).
+ ENDMETHOD.
+
+ METHOD export_import.
+ zcl_aoc_unit_test=>export_import( mo_check ).
+ ENDMETHOD.
+
+ METHOD assert_error_code.
+ cl_abap_unit_assert=>assert_equals( exp = iv_expected_error_code
+ act = ms_result-code ).
+ ENDMETHOD.
+
+ METHOD assert_no_error_code.
+ cl_abap_unit_assert=>assert_initial( ms_result ).
+ ENDMETHOD.
+
+ METHOD if_condition_01.
+ " Given
+ _code `IF sy-sysid = 'PRD'.`.
+ _code `ENDIF.`.
+
+ " When
+ execute_check( ).
+
+ " Then
+ assert_error_code( gc_code-in_condition ).
+ ENDMETHOD.
+
+ METHOD first_letter_01.
+ " Given
+ _code `IF sy-sysid+0(1) = 'P'.`.
+ _code `ENDIF.`.
+
+ " When
+ execute_check( ).
+
+ " Then
+ assert_error_code( gc_code-first_letter_used ).
+ ENDMETHOD.
+
+ METHOD first_letter_02.
+ " Given
+ _code `IF sy-sysid(1) = 'P'.`.
+ _code `ENDIF.`.
+
+ " When
+ execute_check( ).
+
+ " Then
+ assert_error_code( gc_code-first_letter_used ).
+ ENDMETHOD.
+
+ METHOD if_condition_02.
+ " Given
+ _code `IF 1 = 2 OR sy-sysid = 'PRD'.`.
+ _code `ENDIF.`.
+
+ " When
+ execute_check( ).
+
+ " Then
+ assert_error_code( gc_code-in_condition ).
+ ENDMETHOD.
+
+ METHOD case_condition_01.
+ " Given
+ _code `CASE sy-sysid.`.
+ _code ` WHEN 'PRD'.`.
+ _code `ENDCASE.`.
+
+ " When
+ execute_check( ).
+
+ " Then
+ assert_error_code( gc_code-in_condition ).
+ ENDMETHOD.
+
+ METHOD if_condition_03.
+ " Given
+ _code `IF 'PRD' = sy-sysid.`.
+ _code `ENDIF.`.
+
+ " When
+ execute_check( ).
+
+ " Then
+ assert_error_code( gc_code-in_condition ).
+ ENDMETHOD.
+
+ METHOD case_condition_02.
+ " Given
+ _code `CASE 'PRD'.`.
+ _code ` WHEN sy-sysid.`.
+ _code `ENDCASE.`.
+
+ " When
+ execute_check( ).
+
+ " Then
+ assert_error_code( gc_code-in_condition ).
+ ENDMETHOD.
+
+ METHOD case_condition_03.
+ " Given
+ _code `CASE 'PRD'.`.
+ _code ` WHEN sy-mandt OR sy-sysid.`.
+ _code `ENDCASE.`.
+
+ " When
+ execute_check( ).
+
+ " Then
+ assert_error_code( gc_code-in_condition ).
+ ENDMETHOD.
+
+ METHOD elseif_condition.
+ " Given
+ _code `IF 1 = 2.`.
+ _code `ELSEIF sy-sysid = 'PRD'.`.
+ _code `ENDIF.`.
+
+ " When
+ execute_check( ).
+
+ " Then
+ assert_error_code( gc_code-in_condition ).
+ ENDMETHOD.
+
+ METHOD constructor_expression_cond.
+ " Given
+ _code `DATA lv_result TYPE abap_bool.`.
+ _code `lv_result = COND #( WHEN sy-sysid = 'PRD' THEN abap_true ELSE abap_false ).`.
+
+ " When
+ execute_check( ).
+
+ " Then
+ assert_error_code( gc_code-usage_uncategorized ).
+ ENDMETHOD.
+
+ METHOD constructor_expression_switch.
+ " Given
+ _code `DATA lv_result TYPE abap_bool.`.
+ _code `lv_result = SWITCH #( sy-sysid WHEN 'PRD' THEN abap_true ELSE abap_false ).`.
+
+ " When
+ execute_check( ).
+
+ " Then
+ assert_error_code( gc_code-usage_uncategorized ).
+ ENDMETHOD.
+
+ METHOD local_variable_assignment.
+ " Given
+ _code `DATA lv_result TYPE string.`.
+ _code `lv_result = sy-sysid.`.
+
+ " When
+ execute_check( ).
+
+ " Then
+ assert_error_code( gc_code-assigned_to_variable ).
+ ENDMETHOD.
+
+ METHOD within_macro.
+ " Given
+ _code `DEFINE example.`.
+ _code ` DATA lv_result TYPE string.`.
+ _code ` lv_result = sy-sysid.`.
+ _code `END-OF-DEFINITION.`.
+
+ " When
+ execute_check( ).
+
+ " Then
+ assert_error_code( gc_code-within_macro ).
+ ENDMETHOD.
+
+ METHOD method_call.
+ " Given
+ _code `method( iv_system = sy-sysid ).`.
+
+ " When
+ execute_check( ).
+
+ " Then
+ assert_error_code( gc_code-usage_uncategorized ).
+ ENDMETHOD.
+
+ METHOD database_select_01.
+ " Given
+ _code `SELECT host`.
+ _code ` FROM ztable`.
+ _code ` UP TO 1 ROWS`.
+ _code ` INTO @DATA(lv_host)`.
+ _code ` WHERE sysname = @sy-sysid`.
+ _code ` ORDER BY PRIMARY KEY.`.
+ _code `ENDSELECT.`.
+
+ " When
+ execute_check( ).
+
+ " Then
+ assert_error_code( gc_code-in_database_select ).
+ ENDMETHOD.
+
+ METHOD database_select_02.
+ " Given
+ _code `DATA lv_host TYPE string.`.
+ _code `SELECT host`.
+ _code ` FROM ztable`.
+ _code ` UP TO 1 ROWS`.
+ _code ` INTO lv_host`.
+ _code ` WHERE sysname = sy-sysid`.
+ _code ` ORDER BY PRIMARY KEY.`.
+ _code `ENDSELECT.`.
+
+ " When
+ execute_check( ).
+
+ " Then
+ assert_error_code( gc_code-in_database_select ).
+ ENDMETHOD.
+
+ METHOD ignore_type_definition_01.
+ " Given
+ _code `DATA lv_system TYPE sy-sysid.`.
+
+ " When
+ execute_check( ).
+
+ " Then
+ assert_no_error_code( ).
+ ENDMETHOD.
+
+ METHOD ignore_type_definition_02.
+ " Given
+ _code `DATA lv_system LIKE sy-sysid.`.
+
+ " When
+ execute_check( ).
+
+ " Then
+ assert_no_error_code( ).
+ ENDMETHOD.
+
+ METHOD ignore_type_definition_03.
+ " Given
+ _code `CLASS-DATA gv_system TYPE sy-sysid.`.
+
+ " When
+ execute_check( ).
+
+ " Then
+ assert_no_error_code( ).
+ ENDMETHOD.
+
+ METHOD ignore_type_definition_04.
+ " Given
+ _code `CLASS-DATA gv_system LIKE sy-sysid.`.
+
+ " When
+ execute_check( ).
+
+ " Then
+ assert_no_error_code( ).
+ ENDMETHOD.
+
+ METHOD ignore_type_definition_05.
+ " Given
+ _code `TYPES: BEGIN OF gy_structure,`.
+ _code ` system TYPE sy-sysid,`.
+ _code ` END OF gy_structure.`.
+
+ " When
+ execute_check( ).
+
+ " Then
+ assert_no_error_code( ).
+ ENDMETHOD.
+
+ METHOD ignore_type_definition_06.
+ " Given
+ _code `TYPES: BEGIN OF gy_structure,`.
+ _code ` system LIKE sy-sysid,`.
+ _code ` END OF gy_structure.`.
+
+ " When
+ execute_check( ).
+
+ " Then
+ assert_no_error_code( ).
+ ENDMETHOD.
+
+ METHOD ignore_type_definition_07.
+ " Given
+ _code `METHODS example`.
+ _code ` IMPORTING`.
+ _code ` iv_system TYPE sy-sysid.`.
+
+ " When
+ execute_check( ).
+
+ " Then
+ assert_no_error_code( ).
+ ENDMETHOD.
+
+ METHOD ignore_type_definition_08.
+ " Given
+ _code `CLASS-METHODS example`.
+ _code ` IMPORTING`.
+ _code ` iv_system TYPE sy-sysid.`.
+
+ " When
+ execute_check( ).
+
+ " Then
+ assert_no_error_code( ).
+ ENDMETHOD.
+
+ METHOD ignore_ranges.
+ " Given
+ _code `RANGES range FOR sy-sysid.`.
+
+ " When
+ execute_check( ).
+
+ " Then
+ assert_no_error_code( ).
+ ENDMETHOD.
+
+ METHOD default_value_01.
+ " Given
+ _code `METHODS example`.
+ _code ` IMPORTING`.
+ _code ` iv_system TYPE syst_sysid DEFAULT sy-sysid.`.
+
+ " When
+ execute_check( ).
+
+ " Then
+ assert_error_code( gc_code-as_default_value ).
+ ENDMETHOD.
+
+ METHOD default_value_02.
+ " Given
+ _code `CLASS-METHODS example`.
+ _code ` IMPORTING`.
+ _code ` iv_system TYPE syst_sysid DEFAULT sy-sysid.`.
+
+ " When
+ execute_check( ).
+
+ " Then
+ assert_error_code( gc_code-as_default_value ).
+ ENDMETHOD.
+
+ METHOD concatenate.
+ " Given
+ _code `DATA lv_system TYPE string.`.
+ _code `CONCATENATE sy-sysid '' INTO lv_system.`.
+
+ " When
+ execute_check( ).
+
+ " Then
+ assert_error_code( gc_code-in_concatenate ).
+ ENDMETHOD.
+
+ METHOD overridden.
+ " Given
+ _code `sy-sysid = 'PRD'.`.
+
+ " When
+ execute_check( ).
+
+ " Then
+ assert_error_code( gc_code-overridden ).
+ ENDMETHOD.
+
+ METHOD write.
+ " Given
+ _code `WRITE sy-sysid.`.
+
+ " When
+ execute_check( ).
+
+ " Then
+ assert_error_code( gc_code-in_write ).
+ ENDMETHOD.
+
+ METHOD message.
+ " Given
+ _code `MESSAGE e000(z) WITH sy-sysid.`.
+
+ " When
+ execute_check( ).
+
+ " Then
+ assert_error_code( gc_code-in_message ).
+ ENDMETHOD.
+
+ METHOD check_condition.
+ " Given
+ _code `CHECK sy-sysid = 'PRD'.`.
+
+ " When
+ execute_check( ).
+
+ " Then
+ assert_error_code( gc_code-in_condition ).
+ ENDMETHOD.
+
+ METHOD assert_condition.
+ " Given
+ _code `ASSERT sy-sysid = 'PRD'.`.
+
+ " When
+ execute_check( ).
+
+ " Then
+ assert_error_code( gc_code-in_condition ).
+ ENDMETHOD.
+ENDCLASS.
diff --git a/src/checks/zcl_aoc_check_102.clas.xml b/src/checks/zcl_aoc_check_102.clas.xml
new file mode 100644
index 00000000..ea1f751c
--- /dev/null
+++ b/src/checks/zcl_aoc_check_102.clas.xml
@@ -0,0 +1,85 @@
+
+
+
+
+
+ ZCL_AOC_CHECK_102
+ E
+ 102 - Use of system ID
+ 1
+ X
+ X
+ X
+ X
+
+
+ -
+ I
+ 001
+ SY-SYSID was used
+ 27
+
+ -
+ I
+ 002
+ SY-SYSID found in IF / ELSEIF / CASE / CHECK / ASSERT
+ 106
+
+ -
+ I
+ 003
+ First letter of SY-SYSID accessed
+ 66
+
+ -
+ I
+ 004
+ SY-SYSID found as DEFAULT value
+ 62
+
+ -
+ I
+ 005
+ SY-SYSID found in CONCATENATE
+ 58
+
+ -
+ I
+ 006
+ SY-SYSID is overridden
+ 44
+
+ -
+ I
+ 007
+ SY-SYSID is assigned to a variable
+ 68
+
+ -
+ I
+ 008
+ SY-SYSID found in database SELECT
+ 66
+
+ -
+ I
+ 009
+ SY-SYSID found in WRITE
+ 46
+
+ -
+ I
+ 010
+ SY-SYSID found in MESSAGE
+ 50
+
+ -
+ I
+ 011
+ SY-SYSID found within macro
+ 54
+
+
+
+
+
diff --git a/src/checks/zcl_aoc_scan.clas.abap b/src/checks/zcl_aoc_scan.clas.abap
index 4a19cd73..93006d6a 100644
--- a/src/checks/zcl_aoc_scan.clas.abap
+++ b/src/checks/zcl_aoc_scan.clas.abap
@@ -56,6 +56,29 @@ CLASS zcl_aoc_scan DEFINITION
program TYPE c LENGTH 1 VALUE 'P',
END OF gc_level.
+ CONSTANTS: BEGIN OF gc_keyword,
+ if TYPE string VALUE 'IF',
+ elseif TYPE string VALUE 'ELSEIF',
+ case TYPE string VALUE 'CASE',
+ when TYPE string VALUE 'WHEN',
+ check TYPE string VALUE 'CHECK',
+ assert TYPE string VALUE 'ASSERT',
+ types TYPE string VALUE 'TYPES',
+ ranges TYPE string VALUE 'RANGES',
+ methods TYPE string VALUE 'METHODS',
+ class_methods TYPE string VALUE 'CLASS-METHODS',
+ data TYPE string VALUE 'DATA',
+ class_data TYPE string VALUE 'CLASS-DATA',
+ end_of_definition TYPE string VALUE 'END-OF-DEFINITION',
+ concatenate TYPE string VALUE 'CONCATENATE',
+ write TYPE string VALUE 'WRITE',
+ message TYPE string VALUE 'MESSAGE',
+ select TYPE string VALUE 'SELECT',
+ default TYPE string VALUE 'DEFAULT',
+ type TYPE string VALUE 'TYPE',
+ like TYPE string VALUE 'LIKE',
+ END OF gc_keyword.
+
TYPES:
BEGIN OF ty_position,
row TYPE token_row,
@@ -125,7 +148,7 @@ ENDCLASS.
-CLASS ZCL_AOC_SCAN IMPLEMENTATION.
+CLASS zcl_aoc_scan IMPLEMENTATION.
METHOD build_statements.
From e209473f3769cca9ca80226473d684d3b1eeac1b Mon Sep 17 00:00:00 2001
From: ConjuringCoffee <72548231+ConjuringCoffee@users.noreply.github.com>
Date: Fri, 5 Jan 2024 12:24:27 +0100
Subject: [PATCH 02/10] Add documentation for system ID check (102)
---
docs/_checks/102.md | 8 ++++++++
1 file changed, 8 insertions(+)
create mode 100644 docs/_checks/102.md
diff --git a/docs/_checks/102.md b/docs/_checks/102.md
new file mode 100644
index 00000000..80f0dec5
--- /dev/null
+++ b/docs/_checks/102.md
@@ -0,0 +1,8 @@
+---
+title: Use of system ID
+cNumber: CHECK_102
+rfc: false
+index: 102
+---
+
+Coupling your logic to the name of the SAP system (`SY-SYSID`) is generally a bad idea. Use this check to find all uses of the system ID.
\ No newline at end of file
From e2a82c90884c09862b2e2644e68175f241761312 Mon Sep 17 00:00:00 2001
From: ConjuringCoffee <72548231+ConjuringCoffee@users.noreply.github.com>
Date: Fri, 5 Jan 2024 11:31:33 +0000
Subject: [PATCH 03/10] Adapt indentation
---
src/checks/zcl_aoc_check_102.clas.abap | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/checks/zcl_aoc_check_102.clas.abap b/src/checks/zcl_aoc_check_102.clas.abap
index c34efbf3..5db1eaec 100644
--- a/src/checks/zcl_aoc_check_102.clas.abap
+++ b/src/checks/zcl_aoc_check_102.clas.abap
@@ -58,8 +58,8 @@ CLASS zcl_aoc_check_102 IMPLEMENTATION.
LOOP AT io_scan->statements ASSIGNING FIELD-SYMBOL().
LOOP AT io_scan->tokens ASSIGNING FIELD-SYMBOL()
FROM -from TO -to
- WHERE str CP 'SY-SYSID*'
- OR str CP '@SY-SYSID*'.
+ WHERE str CP 'SY-SYSID*'
+ OR str CP '@SY-SYSID*'.
DATA(lv_index_token) = sy-tabix.
From a0c8306a79ffc6f05cb93e624b102d1370b90dbf Mon Sep 17 00:00:00 2001
From: ConjuringCoffee <72548231+ConjuringCoffee@users.noreply.github.com>
Date: Fri, 5 Jan 2024 11:38:02 +0000
Subject: [PATCH 04/10] Adapt indentation
---
src/checks/zcl_aoc_check_102.clas.locals_imp.abap | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/checks/zcl_aoc_check_102.clas.locals_imp.abap b/src/checks/zcl_aoc_check_102.clas.locals_imp.abap
index 7e0467d6..98566c3c 100644
--- a/src/checks/zcl_aoc_check_102.clas.locals_imp.abap
+++ b/src/checks/zcl_aoc_check_102.clas.locals_imp.abap
@@ -55,7 +55,7 @@ CLASS lcl_check_helper IMPLEMENTATION.
WHEN OTHERS.
READ TABLE mo_scan->tokens ASSIGNING INDEX iv_index_token - 1.
- IF -str = '='
+ IF -str = '='
AND iv_index_token - is_statement-from = 2.
rv_error_code = gc_code-assigned_to_variable.
ELSE.
@@ -65,14 +65,14 @@ CLASS lcl_check_helper IMPLEMENTATION.
ENDMETHOD.
METHOD is_using_only_first_letter.
- rv_result = xsdbool( is_token-str = 'SY-SYSID+0(1)'
+ rv_result = xsdbool( is_token-str = 'SY-SYSID+0(1)'
OR is_token-str = 'SY-SYSID(1)' ).
ENDMETHOD.
METHOD is_used_in_macro.
ASSIGN mo_scan->tokens[ is_statement-to + 1 ] TO FIELD-SYMBOL().
- IF sy-subrc = 0
+ IF sy-subrc = 0
AND -str = zcl_aoc_scan=>gc_keyword-end_of_definition.
rv_result = abap_true.
ENDIF.
From 8fa1d73e5381d8fe6b331b448f55e721d46d83dc Mon Sep 17 00:00:00 2001
From: ConjuringCoffee <72548231+ConjuringCoffee@users.noreply.github.com>
Date: Fri, 5 Jan 2024 11:40:44 +0000
Subject: [PATCH 05/10] Downport IFs
---
src/checks/zcl_aoc_check_102.clas.locals_imp.abap | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/checks/zcl_aoc_check_102.clas.locals_imp.abap b/src/checks/zcl_aoc_check_102.clas.locals_imp.abap
index 98566c3c..87ebbb6b 100644
--- a/src/checks/zcl_aoc_check_102.clas.locals_imp.abap
+++ b/src/checks/zcl_aoc_check_102.clas.locals_imp.abap
@@ -4,12 +4,12 @@ CLASS lcl_check_helper IMPLEMENTATION.
ENDMETHOD.
METHOD determine_error_code.
- IF is_using_only_first_letter( is_token ).
+ IF is_using_only_first_letter( is_token ) = abap_true.
rv_error_code = gc_code-first_letter_used.
RETURN.
ENDIF.
- IF is_used_in_macro( is_statement ).
+ IF is_used_in_macro( is_statement ) = abap_true.
rv_error_code = gc_code-within_macro.
RETURN.
ENDIF.
From 5b1a4819820a81d0c10f846c7c56325ebc31f0bc Mon Sep 17 00:00:00 2001
From: ConjuringCoffee <72548231+ConjuringCoffee@users.noreply.github.com>
Date: Fri, 5 Jan 2024 11:42:37 +0000
Subject: [PATCH 06/10] Remove XSDBOOL usage
---
src/checks/zcl_aoc_check_102.clas.locals_imp.abap | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/src/checks/zcl_aoc_check_102.clas.locals_imp.abap b/src/checks/zcl_aoc_check_102.clas.locals_imp.abap
index 87ebbb6b..77701043 100644
--- a/src/checks/zcl_aoc_check_102.clas.locals_imp.abap
+++ b/src/checks/zcl_aoc_check_102.clas.locals_imp.abap
@@ -65,8 +65,10 @@ CLASS lcl_check_helper IMPLEMENTATION.
ENDMETHOD.
METHOD is_using_only_first_letter.
- rv_result = xsdbool( is_token-str = 'SY-SYSID+0(1)'
- OR is_token-str = 'SY-SYSID(1)' ).
+ CASE is_token-str.
+ WHEN 'SY-SYSID+0(1)' OR 'SY-SYSID(1)'.
+ rv_result = abap_true.
+ ENDCASE.
ENDMETHOD.
METHOD is_used_in_macro.
From cd39c802d45370c5ea3ab724675da7b8182be804 Mon Sep 17 00:00:00 2001
From: ConjuringCoffee <72548231+ConjuringCoffee@users.noreply.github.com>
Date: Fri, 5 Jan 2024 11:46:20 +0000
Subject: [PATCH 07/10] Adapt indentation
---
src/checks/zcl_aoc_check_102.clas.locals_imp.abap | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/checks/zcl_aoc_check_102.clas.locals_imp.abap b/src/checks/zcl_aoc_check_102.clas.locals_imp.abap
index 77701043..f40f5890 100644
--- a/src/checks/zcl_aoc_check_102.clas.locals_imp.abap
+++ b/src/checks/zcl_aoc_check_102.clas.locals_imp.abap
@@ -56,7 +56,7 @@ CLASS lcl_check_helper IMPLEMENTATION.
READ TABLE mo_scan->tokens ASSIGNING INDEX iv_index_token - 1.
IF -str = '='
- AND iv_index_token - is_statement-from = 2.
+ AND iv_index_token - is_statement-from = 2.
rv_error_code = gc_code-assigned_to_variable.
ELSE.
rv_error_code = gc_code-usage_uncategorized.
@@ -75,7 +75,7 @@ CLASS lcl_check_helper IMPLEMENTATION.
ASSIGN mo_scan->tokens[ is_statement-to + 1 ] TO FIELD-SYMBOL().
IF sy-subrc = 0
- AND -str = zcl_aoc_scan=>gc_keyword-end_of_definition.
+ AND -str = zcl_aoc_scan=>gc_keyword-end_of_definition.
rv_result = abap_true.
ENDIF.
ENDMETHOD.
From c22507d41d8cd91a1fc7ef06c18de02edeec81df Mon Sep 17 00:00:00 2001
From: ConjuringCoffee <72548231+ConjuringCoffee@users.noreply.github.com>
Date: Fri, 5 Jan 2024 12:15:43 +0000
Subject: [PATCH 08/10] Enable RFC
---
src/checks/zcl_aoc_check_102.clas.abap | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/src/checks/zcl_aoc_check_102.clas.abap b/src/checks/zcl_aoc_check_102.clas.abap
index 5db1eaec..250999db 100644
--- a/src/checks/zcl_aoc_check_102.clas.abap
+++ b/src/checks/zcl_aoc_check_102.clas.abap
@@ -8,9 +8,6 @@ CLASS zcl_aoc_check_102 DEFINITION
METHODS constructor.
METHODS check REDEFINITION.
-
- PRIVATE SECTION.
-
ENDCLASS.
@@ -24,6 +21,8 @@ CLASS zcl_aoc_check_102 IMPLEMENTATION.
has_attributes = abap_true.
attributes_ok = abap_true.
+ enable_rfc( ).
+
insert_scimessage( iv_code = gc_code-usage_uncategorized
iv_text = TEXT-001 ).
insert_scimessage( iv_code = gc_code-in_condition
From c6d79c91cadbe653ba27fb120f0ef4d348ea4216 Mon Sep 17 00:00:00 2001
From: ConjuringCoffee <72548231+ConjuringCoffee@users.noreply.github.com>
Date: Fri, 5 Jan 2024 13:16:27 +0100
Subject: [PATCH 09/10] Update RFC in documentation
---
docs/_checks/102.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/_checks/102.md b/docs/_checks/102.md
index 80f0dec5..82a15832 100644
--- a/docs/_checks/102.md
+++ b/docs/_checks/102.md
@@ -1,7 +1,7 @@
---
title: Use of system ID
cNumber: CHECK_102
-rfc: false
+rfc: true
index: 102
---
From 725dc6bbde67c7b23eda91e52fb04b1e9caff71f Mon Sep 17 00:00:00 2001
From: ConjuringCoffee <72548231+ConjuringCoffee@users.noreply.github.com>
Date: Fri, 5 Jan 2024 13:17:14 +0100
Subject: [PATCH 10/10] Do not use type SYST_TABIX
Co-authored-by: Lars Hvam
---
src/checks/zcl_aoc_check_102.clas.locals_def.abap | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/checks/zcl_aoc_check_102.clas.locals_def.abap b/src/checks/zcl_aoc_check_102.clas.locals_def.abap
index ca896ac5..dd350435 100644
--- a/src/checks/zcl_aoc_check_102.clas.locals_def.abap
+++ b/src/checks/zcl_aoc_check_102.clas.locals_def.abap
@@ -23,7 +23,7 @@ CLASS lcl_check_helper DEFINITION.
METHODS determine_error_code
IMPORTING
is_token TYPE stokesx
- iv_index_token TYPE syst_tabix
+ iv_index_token TYPE sy-tabix
is_statement TYPE sstmnt
RETURNING
VALUE(rv_error_code) TYPE sci_errc.