Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- *&---------------------------------------------------------------------*
- *& Report ZZ_CHECK_DEMETER_LAW
- *&---------------------------------------------------------------------*
- *& Checks ABAP method code for the easiest type of LoD violation
- *& Extensible by more cases
- *&---------------------------------------------------------------------*
- report zz_check_demeter_law.
- parameters: p_class type seomtdkey-clsname, " Structure has F4 attached!
- p_meth type seomtdkey-mtdname. " Structure has F4 attached!
- start-of-selection.
- perform start.
- * ---
- class lcl_scanner definition.
- public section.
- methods:
- constructor importing it_source type stringtab
- raising cx_abap_error_analyze,
- get_first_token importing is_stmnt type sstmnt
- returning value(ev_token) type char30,
- get_second_token importing is_stmnt type sstmnt
- returning value(ev_token) type char30,
- get_nth_token importing iv_n type i
- is_stmnt type sstmnt
- returning value(ev_token) type char30,
- get_first_stmnt importing iv_first_token type char30
- returning value(es_stmnt) type sstmnt,
- get_stmnts importing iv_first_token type char30
- returning value(et_stmnt) type sstmnt_tab,
- to_string importing is_stmnt type sstmnt
- exporting ev_stmnt type string.
- data: gt_token type stokes_tab read-only,
- gt_stmnt type sstmnt_tab read-only.
- endclass. "lcl_scanner DEFINITION
- * ---
- class lcl_check_demeter definition.
- public section.
- data: gs_key type seocpdkey,
- go_descr type ref to cl_abap_classdescr read-only,
- gt_methcode type stringtab read-only,
- go_scanner type ref to lcl_scanner.
- methods:
- constructor importing iv_class type seoclsname
- iv_meth type seocpdname
- raising cx_abap_error_analyze,
- get_classdescr returning value(eo_descr) type ref to cl_abap_typedescr
- raising cx_abap_error_analyze,
- read_method raising cx_abap_error_analyze,
- read_source exporting et_methcode type stringtab
- raising cx_abap_error_analyze,
- scan_source importing it_methcode type stringtab
- exporting eo_scanner type ref to lcl_scanner
- raising cx_abap_error_analyze,
- check raising cx_abap_error_analyze .
- endclass. "lcl_check_demeter DEFINITION
- * ---
- form start.
- data: lo_demeter type ref to lcl_check_demeter,
- lo_ex type ref to cx_abap_error_analyze .
- try.
- create object lo_demeter
- exporting
- iv_class = p_class
- iv_meth = p_meth.
- lo_demeter->check( ).
- catch cx_abap_error_analyze into lo_ex.
- message lo_ex->message type 'I'.
- endtry.
- endform. "start
- * ---
- class lcl_check_demeter implementation.
- method constructor.
- gs_key-clsname = iv_class.
- gs_key-cpdname = iv_meth.
- go_descr ?= get_classdescr( ).
- read_method( ).
- endmethod. "constructor
- method get_classdescr.
- call method cl_abap_classdescr=>describe_by_name
- exporting
- p_name = gs_key-clsname
- receiving
- p_descr_ref = eo_descr
- exceptions
- others = 1.
- if sy-subrc ne 0.
- raise exception type cx_abap_error_analyze
- exporting
- message = 'Class not found'.
- endif.
- endmethod. "get_classdescr
- method read_method.
- read_source( importing et_methcode = gt_methcode ).
- scan_source( exporting it_methcode = gt_methcode
- importing eo_scanner = go_scanner ).
- endmethod. "read_method
- method read_source.
- data: lv_msg type string.
- call function 'SEO_METHOD_GET_SOURCE'
- exporting
- mtdkey = gs_key
- importing
- source_expanded = et_methcode
- exceptions
- _internal_method_not_existing = 1
- _internal_class_not_existing = 2
- version_not_existing = 3
- inactive_new = 4
- inactive_deleted = 5
- others = 6.
- if sy-subrc <> 0.
- message id sy-msgid type sy-msgty number sy-msgno
- with sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4
- into lv_msg.
- raise exception type cx_abap_error_analyze
- exporting
- message = lv_msg.
- endif.
- endmethod. "read_method
- method scan_source.
- create object eo_scanner
- exporting
- it_source = it_methcode.
- endmethod. "scan_source
- method check.
- data: lv_stmnt type string,
- lv_msg type string.
- field-symbols: <ls_stmnt> type sstmnt,
- <ls_token> type stokes.
- loop at go_scanner->gt_token assigning <ls_token>.
- if <ls_token>-str cp '*->*->*'.
- concatenate `'` <ls_token>-str `'` into lv_msg.
- concatenate 'Demeter violation' lv_msg into lv_msg
- separated by space.
- raise exception type cx_abap_error_analyze
- exporting
- message = lv_msg.
- endif.
- endloop.
- endmethod. "check
- endclass. "lcl_check_demeter IMPLEMENTATION
- * ---
- class lcl_scanner implementation.
- method get_nth_token.
- field-symbols: <ls_token> type stokes.
- data: lv_index type i.
- lv_index = iv_n - 1 + is_stmnt-from.
- read table gt_token assigning <ls_token> index lv_index.
- if sy-subrc eq 0.
- ev_token = <ls_token>-str.
- endif.
- endmethod. "get_nth_token
- method get_first_token.
- ev_token = get_nth_token( iv_n = 1 is_stmnt = is_stmnt ).
- endmethod. "get_first_token
- method get_second_token.
- ev_token = get_nth_token( iv_n = 2 is_stmnt = is_stmnt ).
- endmethod. "get_second_token
- method constructor.
- data: lv_msg type string.
- scan abap-source it_source
- tokens into gt_token
- statements into gt_stmnt
- message into lv_msg.
- if sy-subrc ne 0.
- if lv_msg is initial.
- lv_msg = 'Scanner error'.
- endif.
- raise exception type cx_abap_error_analyze
- exporting
- message = lv_msg.
- endif.
- endmethod. "constructor
- method get_first_stmnt.
- data: lt_stmnts type sstmnt_tab.
- lt_stmnts = get_stmnts( iv_first_token ).
- read table lt_stmnts into es_stmnt index 1.
- endmethod. "get_first_stmnt
- method get_stmnts.
- field-symbols: <ls_stmnt> type sstmnt.
- loop at gt_stmnt assigning <ls_stmnt>.
- if get_first_token( <ls_stmnt> ) cp iv_first_token. " cp, not eq, for being case-insensitive
- insert <ls_stmnt> into table et_stmnt.
- endif.
- endloop.
- endmethod. "get_stmnts
- method to_string.
- field-symbols: <ls_token> type stokes.
- clear ev_stmnt.
- loop at gt_token assigning <ls_token>
- from is_stmnt-from
- to is_stmnt-to.
- concatenate ev_stmnt <ls_token>-str into ev_stmnt
- separated by space.
- endloop.
- endmethod.
- endclass. "lcl_scanner IMPLEMENTATION
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement