From 4bafb5f2a68ad0e453bf5d2574b39c76a4a91387 Mon Sep 17 00:00:00 2001 From: PCF <32403010+pcf0@users.noreply.github.com> Date: Thu, 24 Oct 2024 10:25:03 +0200 Subject: [PATCH] Check 095 - Object / Class member access - false positive with local classes (#1156) --- src/checks/zcl_aoc_check_95.clas.abap | 29 +- .../zcl_aoc_check_95.clas.testclasses.abap | 305 ++++++++++++++++++ src/checks/zcl_aoc_check_95.clas.xml | 1 + src/checks/zcl_aoc_unit_test.clas.abap | 58 ++-- 4 files changed, 357 insertions(+), 36 deletions(-) create mode 100644 src/checks/zcl_aoc_check_95.clas.testclasses.abap diff --git a/src/checks/zcl_aoc_check_95.clas.abap b/src/checks/zcl_aoc_check_95.clas.abap index 9a77c2cd..755dce85 100644 --- a/src/checks/zcl_aoc_check_95.clas.abap +++ b/src/checks/zcl_aoc_check_95.clas.abap @@ -9,13 +9,13 @@ CLASS zcl_aoc_check_95 DEFINITION METHODS constructor . METHODS check - REDEFINITION . + REDEFINITION . METHODS get_attributes - REDEFINITION . + REDEFINITION . METHODS if_ci_test~query_attributes - REDEFINITION . + REDEFINITION . METHODS put_attributes - REDEFINITION . + REDEFINITION . PROTECTED SECTION. PRIVATE SECTION. @@ -31,24 +31,29 @@ ENDCLASS. -CLASS zcl_aoc_check_95 IMPLEMENTATION. +CLASS ZCL_AOC_CHECK_95 IMPLEMENTATION. METHOD check. - DATA lv_token_string_in_char TYPE char35. - DATA ls_token TYPE stokesx. + DATA lt_statements TYPE zcl_aoc_scan=>ty_statements. + + FIELD-SYMBOLS LIKE LINE OF lt_statements. + FIELD-SYMBOLS LIKE LINE OF io_scan->statements. IF object_type <> 'CLAS'. RETURN. ENDIF. - LOOP AT io_scan->tokens INTO ls_token. - lv_token_string_in_char = ls_token-str. - IF lv_token_string_in_char+30(5) = 'CCIMP'. - mv_impl_start_position = sy-tabix. + lt_statements = io_scan->build_statements( ). + + READ TABLE lt_statements ASSIGNING WITH KEY str = 'INCLUDE METHODS'. + IF sy-subrc = 0. + READ TABLE io_scan->statements ASSIGNING INDEX -index. + IF sy-subrc = 0. + mv_impl_start_position = -to + 1. ENDIF. - ENDLOOP. + ENDIF. " check for static calls IF mv_class_in_front_not_okay = abap_true. diff --git a/src/checks/zcl_aoc_check_95.clas.testclasses.abap b/src/checks/zcl_aoc_check_95.clas.testclasses.abap new file mode 100644 index 00000000..51f4b6b1 --- /dev/null +++ b/src/checks/zcl_aoc_check_95.clas.testclasses.abap @@ -0,0 +1,305 @@ +CLASS ltcl_test DEFINITION DEFERRED. +CLASS zcl_aoc_check_95 DEFINITION LOCAL FRIENDS ltcl_test. + +CLASS ltcl_test DEFINITION FOR TESTING + DURATION SHORT + RISK LEVEL HARMLESS + FINAL. + + PRIVATE SECTION. + DATA: mt_code TYPE string_table, + ms_result TYPE scirest_ad, + mo_check TYPE REF TO zcl_aoc_check_95. + + METHODS: + setup, + export_import FOR TESTING, + test001 FOR TESTING, + test002 FOR TESTING, + test002b FOR TESTING, + test003 FOR TESTING, + test003b FOR TESTING. + +ENDCLASS. + + +CLASS ltcl_test IMPLEMENTATION. + + DEFINE _code. + APPEND &1 TO mt_code. + END-OF-DEFINITION. + + METHOD setup. + CREATE OBJECT mo_check. + zcl_aoc_unit_test=>set_check( mo_check ). + zcl_aoc_unit_test=>set_object_type( 'CLAS' ). + zcl_aoc_unit_test=>set_object_name( 'ZCL_CLASS' ). + + mo_check->mv_class_in_front_not_okay = abap_true. + mo_check->mv_object_in_front_not_okay = abap_true. + ENDMETHOD. "setup + + METHOD export_import. + zcl_aoc_unit_test=>export_import( mo_check ). + ENDMETHOD. + + METHOD test001. + _code 'CLASS-POOL.'. + _code '*"* class pool for class ZCL_CLASS'. + _code '*"* local type definitions'. + _code 'INCLUDE ZCL_CLASS=====================CCDEF.'. + _code '*"* use this source file for any type of declarations (class'. + _code '*"* definitions, interfaces or type declarations) you need for'. + _code '*"* components in the private section'. + _code '*"* class ZCL_CLASS definition'. + _code '*"* public declarations'. + _code 'INCLUDE ZCL_CLASS=====================CU.'. + _code 'CLASS ZCL_CLASS DEFINITION PUBLIC FINAL CREATE PUBLIC.'. + _code 'PUBLIC SECTION.'. + _code 'TYPES TY_TYPE TYPE STRING.'. + _code '*"* protected declarations'. + _code 'INCLUDE ZCL_CLASS=====================CO.'. + _code 'PROTECTED SECTION.'. + _code '*"* private declarations'. + _code 'INCLUDE ZCL_CLASS=====================CI.'. + _code 'PRIVATE SECTION.'. + _code 'ENDCLASS.'. + _code '"ZCL_CLASS definition'. + _code '*"* macro definitions'. + _code 'INCLUDE ZCL_CLASS=====================CCMAC.'. + _code '*"* use this source file for any macro definitions you need'. + _code '*"* in the implementation part of the class'. + _code '*"* local class implementation'. + _code 'INCLUDE ZCL_CLASS=====================CCIMP.'. + _code '*"* use this source file for the definition and implementation of'. + _code '*"* local helper classes, interface definitions and type'. + _code '*"* declarations'. + _code 'CLASS LCL_ERROR DEFINITION FINAL.'. + _code 'PRIVATE SECTION.'. + + "Suspicious section, but valid + _code 'DATA MV_DATA TYPE ZCL_CLASS=>TY_TYPE.'. + + _code 'ENDCLASS.'. + _code '*"* test class'. + _code 'INCLUDE ZCL_CLASS=====================CCAU.'. + _code '*"* use this source file for your ABAP unit test classes'. + _code 'CLASS ZCL_CLASS IMPLEMENTATION.'. + _code '*"* method''s implementations'. + _code 'INCLUDE METHODS.'. + _code 'ENDCLASS.'. + _code '"ZCL_CLASS implementation'. + + ms_result = zcl_aoc_unit_test=>check( mt_code ). + + cl_abap_unit_assert=>assert_initial( ms_result ). + ENDMETHOD. + + METHOD test002. + _code 'CLASS-POOL.'. + _code '*"* class pool for class ZCL_CLASS'. + _code '*"* local type definitions'. + _code 'INCLUDE ZCL_CLASS=====================CCDEF.'. + _code '*"* use this source file for any type of declarations (class'. + _code '*"* definitions, interfaces or type declarations) you need for'. + _code '*"* components in the private section'. + _code '*"* class ZCL_CLASS definition'. + _code '*"* public declarations'. + _code 'INCLUDE ZCL_CLASS=====================CU.'. + _code 'CLASS ZCL_CLASS DEFINITION PUBLIC FINAL CREATE PUBLIC.'. + _code 'PUBLIC SECTION.'. + _code 'CLASS-METHODS run.'. + _code '*"* protected declarations'. + _code 'INCLUDE ZCL_CLASS=====================CO.'. + _code 'PROTECTED SECTION.'. + _code '*"* private declarations'. + _code 'INCLUDE ZCL_CLASS=====================CI.'. + _code 'PRIVATE SECTION.'. + _code 'ENDCLASS.'. + _code '"ZCL_CLASS definition'. + _code '*"* macro definitions'. + _code 'INCLUDE ZCL_CLASS=====================CCMAC.'. + _code '*"* use this source file for any macro definitions you need'. + _code '*"* in the implementation part of the class'. + _code '*"* local class implementation'. + _code 'INCLUDE ZCL_CLASS=====================CCIMP.'. + _code '*"* use this source file for the definition and implementation of'. + _code '*"* local helper classes, interface definitions and type'. + _code '*"* declarations'. + _code '*"* test class'. + _code 'INCLUDE ZCL_CLASS=====================CCAU.'. + _code '*"* use this source file for your ABAP unit test classes'. + _code 'CLASS ZCL_CLASS IMPLEMENTATION.'. + _code '*"* method''s implementations'. + _code 'INCLUDE METHODS.'. + _code 'METHOD run.'. + + "Suspicious section, should ommit "ZCL_CLASS=>" + _code 'ZCL_CLASS=>run( ).'. + + _code 'ENDMETHOD.'. + _code 'ENDCLASS.'. + _code '"ZCL_CLASS implementation'. + + ms_result = zcl_aoc_unit_test=>check( mt_code ). + + cl_abap_unit_assert=>assert_equals( exp = '001' + act = ms_result-code ). + ENDMETHOD. + + METHOD test002b. + _code 'CLASS-POOL.'. + _code '*"* class pool for class ZCL_CLASS'. + _code '*"* local type definitions'. + _code 'INCLUDE ZCL_CLASS=====================CCDEF.'. + _code '*"* use this source file for any type of declarations (class'. + _code '*"* definitions, interfaces or type declarations) you need for'. + _code '*"* components in the private section'. + _code '*"* class ZCL_CLASS definition'. + _code '*"* public declarations'. + _code 'INCLUDE ZCL_CLASS=====================CU.'. + _code 'CLASS ZCL_CLASS DEFINITION PUBLIC FINAL CREATE PUBLIC.'. + _code 'PUBLIC SECTION.'. + _code 'CLASS-METHODS run.'. + _code '*"* protected declarations'. + _code 'INCLUDE ZCL_CLASS=====================CO.'. + _code 'PROTECTED SECTION.'. + _code '*"* private declarations'. + _code 'INCLUDE ZCL_CLASS=====================CI.'. + _code 'PRIVATE SECTION.'. + _code 'ENDCLASS.'. + _code '"ZCL_CLASS definition'. + _code '*"* macro definitions'. + _code 'INCLUDE ZCL_CLASS=====================CCMAC.'. + _code '*"* use this source file for any macro definitions you need'. + _code '*"* in the implementation part of the class'. + _code '*"* local class implementation'. + _code 'INCLUDE ZCL_CLASS=====================CCIMP.'. + _code '*"* use this source file for the definition and implementation of'. + _code '*"* local helper classes, interface definitions and type'. + _code '*"* declarations'. + _code '*"* test class'. + _code 'INCLUDE ZCL_CLASS=====================CCAU.'. + _code '*"* use this source file for your ABAP unit test classes'. + _code 'CLASS ZCL_CLASS IMPLEMENTATION.'. + _code '*"* method''s implementations'. + _code 'INCLUDE METHODS.'. + _code 'METHOD run.'. + + "Suspicious section, should ommit "ZCL_CLASS=>", but check is deactivated + _code 'ZCL_CLASS=>run( ).'. + + _code 'ENDMETHOD.'. + _code 'ENDCLASS.'. + _code '"ZCL_CLASS implementation'. + + mo_check->mv_class_in_front_not_okay = abap_false. + ms_result = zcl_aoc_unit_test=>check( mt_code ). + + cl_abap_unit_assert=>assert_initial( ms_result ). + ENDMETHOD. + + METHOD test003. + _code 'CLASS-POOL.'. + _code '*"* class pool for class ZCL_CLASS'. + _code '*"* local type definitions'. + _code 'INCLUDE ZCL_CLASS=====================CCDEF.'. + _code '*"* use this source file for any type of declarations (class'. + _code '*"* definitions, interfaces or type declarations) you need for'. + _code '*"* components in the private section'. + _code '*"* class ZCL_CLASS definition'. + _code '*"* public declarations'. + _code 'INCLUDE ZCL_CLASS=====================CU.'. + _code 'CLASS ZCL_CLASS DEFINITION PUBLIC FINAL CREATE PUBLIC.'. + _code 'PUBLIC SECTION.'. + _code 'METHODS run.'. + _code '*"* protected declarations'. + _code 'INCLUDE ZCL_CLASS=====================CO.'. + _code 'PROTECTED SECTION.'. + _code '*"* private declarations'. + _code 'INCLUDE ZCL_CLASS=====================CI.'. + _code 'PRIVATE SECTION.'. + _code 'ENDCLASS.'. + _code '"ZCL_CLASS definition'. + _code '*"* macro definitions'. + _code 'INCLUDE ZCL_CLASS=====================CCMAC.'. + _code '*"* use this source file for any macro definitions you need'. + _code '*"* in the implementation part of the class'. + _code '*"* local class implementation'. + _code 'INCLUDE ZCL_CLASS=====================CCIMP.'. + _code '*"* use this source file for the definition and implementation of'. + _code '*"* local helper classes, interface definitions and type'. + _code '*"* declarations'. + _code '*"* test class'. + _code 'INCLUDE ZCL_CLASS=====================CCAU.'. + _code '*"* use this source file for your ABAP unit test classes'. + _code 'CLASS ZCL_CLASS IMPLEMENTATION.'. + _code '*"* method''s implementations'. + _code 'INCLUDE METHODS.'. + _code 'METHOD run.'. + + "Suspicious section, should ommit "me->" + _code 'me->run( ).'. + + _code 'ENDMETHOD.'. + _code 'ENDCLASS.'. + _code '"ZCL_CLASS implementation'. + + ms_result = zcl_aoc_unit_test=>check( mt_code ). + + cl_abap_unit_assert=>assert_equals( exp = '002' + act = ms_result-code ). + ENDMETHOD. + + METHOD test003b. + _code 'CLASS-POOL.'. + _code '*"* class pool for class ZCL_CLASS'. + _code '*"* local type definitions'. + _code 'INCLUDE ZCL_CLASS=====================CCDEF.'. + _code '*"* use this source file for any type of declarations (class'. + _code '*"* definitions, interfaces or type declarations) you need for'. + _code '*"* components in the private section'. + _code '*"* class ZCL_CLASS definition'. + _code '*"* public declarations'. + _code 'INCLUDE ZCL_CLASS=====================CU.'. + _code 'CLASS ZCL_CLASS DEFINITION PUBLIC FINAL CREATE PUBLIC.'. + _code 'PUBLIC SECTION.'. + _code 'METHODS run.'. + _code '*"* protected declarations'. + _code 'INCLUDE ZCL_CLASS=====================CO.'. + _code 'PROTECTED SECTION.'. + _code '*"* private declarations'. + _code 'INCLUDE ZCL_CLASS=====================CI.'. + _code 'PRIVATE SECTION.'. + _code 'ENDCLASS.'. + _code '"ZCL_CLASS definition'. + _code '*"* macro definitions'. + _code 'INCLUDE ZCL_CLASS=====================CCMAC.'. + _code '*"* use this source file for any macro definitions you need'. + _code '*"* in the implementation part of the class'. + _code '*"* local class implementation'. + _code 'INCLUDE ZCL_CLASS=====================CCIMP.'. + _code '*"* use this source file for the definition and implementation of'. + _code '*"* local helper classes, interface definitions and type'. + _code '*"* declarations'. + _code '*"* test class'. + _code 'INCLUDE ZCL_CLASS=====================CCAU.'. + _code '*"* use this source file for your ABAP unit test classes'. + _code 'CLASS ZCL_CLASS IMPLEMENTATION.'. + _code '*"* method''s implementations'. + _code 'INCLUDE METHODS.'. + _code 'METHOD run.'. + + "Suspicious section, should ommit "me->", but check is deactivated + _code 'me->run( ).'. + + _code 'ENDMETHOD.'. + _code 'ENDCLASS.'. + _code '"ZCL_CLASS implementation'. + + mo_check->mv_object_in_front_not_okay = abap_false. + ms_result = zcl_aoc_unit_test=>check( mt_code ). + + cl_abap_unit_assert=>assert_initial( ms_result ). + ENDMETHOD. +ENDCLASS. diff --git a/src/checks/zcl_aoc_check_95.clas.xml b/src/checks/zcl_aoc_check_95.clas.xml index e00cf81a..762c09b4 100644 --- a/src/checks/zcl_aoc_check_95.clas.xml +++ b/src/checks/zcl_aoc_check_95.clas.xml @@ -10,6 +10,7 @@ X X X + X diff --git a/src/checks/zcl_aoc_unit_test.clas.abap b/src/checks/zcl_aoc_unit_test.clas.abap index f36ef884..4fd71d99 100644 --- a/src/checks/zcl_aoc_unit_test.clas.abap +++ b/src/checks/zcl_aoc_unit_test.clas.abap @@ -34,6 +34,9 @@ CLASS zcl_aoc_unit_test DEFINITION CLASS-METHODS export_import IMPORTING !io_check TYPE REF TO cl_ci_test_root. + CLASS-METHODS set_object_name + IMPORTING + !iv_object_name TYPE sobj_name. CLASS-METHODS set_object_type IMPORTING !iv_object_type TYPE trobjtype. @@ -58,7 +61,7 @@ ENDCLASS. -CLASS zcl_aoc_unit_test IMPLEMENTATION. +CLASS ZCL_AOC_UNIT_TEST IMPLEMENTATION. METHOD check. @@ -84,6 +87,31 @@ CLASS zcl_aoc_unit_test IMPLEMENTATION. ENDMETHOD. + METHOD create_scan. + DATA: lt_tokens TYPE stokesx_tab, + lt_statements TYPE sstmnt_tab, + lt_levels TYPE slevel_tab, + lt_structures TYPE zcl_aoc_super=>ty_structures_tt. + + SCAN ABAP-SOURCE it_code + TOKENS INTO lt_tokens + STATEMENTS INTO lt_statements + LEVELS INTO lt_levels + STRUCTURES INTO lt_structures + WITH ANALYSIS + WITH COMMENTS + WITH PRAGMAS abap_true. + cl_abap_unit_assert=>assert_subrc( msg = 'Error while parsing'(001) ). + + CREATE OBJECT ro_scan + EXPORTING + it_tokens = lt_tokens + it_statements = lt_statements + it_levels = lt_levels + it_structures = lt_structures. + ENDMETHOD. + + METHOD export_import. DATA: lv_xstr TYPE xstring. @@ -132,34 +160,16 @@ CLASS zcl_aoc_unit_test IMPLEMENTATION. ENDMETHOD. - METHOD set_object_type. + METHOD set_object_name. - go_check->object_type = iv_object_type. + go_check->object_name = iv_object_name. ENDMETHOD. - METHOD create_scan. - DATA: lt_tokens TYPE stokesx_tab, - lt_statements TYPE sstmnt_tab, - lt_levels TYPE slevel_tab, - lt_structures TYPE zcl_aoc_super=>ty_structures_tt. - SCAN ABAP-SOURCE it_code - TOKENS INTO lt_tokens - STATEMENTS INTO lt_statements - LEVELS INTO lt_levels - STRUCTURES INTO lt_structures - WITH ANALYSIS - WITH COMMENTS - WITH PRAGMAS abap_true. - cl_abap_unit_assert=>assert_subrc( msg = 'Error while parsing'(001) ). + METHOD set_object_type. - CREATE OBJECT ro_scan - EXPORTING - it_tokens = lt_tokens - it_statements = lt_statements - it_levels = lt_levels - it_structures = lt_structures. - ENDMETHOD. + go_check->object_type = iv_object_type. + ENDMETHOD. ENDCLASS.