
BEGIN OF BLOCK zz1 WITH FRAME TITLE TEXT-zz1.
SELECTION-SCREEN: BEGIN OF LINE.
PARAMETERS: p_zz_mod TYPE xfeld AS CHECKBOX.
SELECTION-SCREEN: COMMENT (79) TEXT-zz3.
SELECTION-SCREEN: END OF LINE.
SELECTION-SCREEN: END OF BLOCK zz1,
CLASS lcl_zz DEFINITION FINAL.
PUBLIC SECTION.
TYPES: BEGIN OF tp_dynpro, " needs to be identical to ty_dynpro in lcl_source_scan
repname LIKE d020s-prog,
dynnr LIKE d020s-dnum,
END OF tp_dynpro.
TYPES: ttp_dynpro TYPE STANDARD TABLE OF tp_dynpro WITH DEFAULT KEY.
CLASS-METHODS:
add_modification_includes
CHANGING c_includes TYPE prognames
c_screens TYPE ttp_dynpro
, add_enhancement_includes
CHANGING c_includes TYPE prognames
, filter_modifications
IMPORTING i_include TYPE progname
i_screen TYPE sy-dynnr
i_source_tab TYPE abaptxt255_tab
CHANGING c_findings TYPE match_result_tab
.
PRIVATE SECTION.
TYPES: BEGIN OF tp_mod_include
, include TYPE reposrc-progname
, without_assistant TYPE abap_bool
, END OF tp_mod_include
, ttp_mod_includes TYPE STANDARD TABLE OF tp_mod_include WITH KEY include
, BEGIN OF tp_mod_screen
, program TYPE d020s-prog
, screen TYPE d020s-dnum
, without_assistant TYPE abap_bool
, END OF tp_mod_screen
, ttp_mod_screens TYPE STANDARD TABLE OF tp_mod_screen WITH KEY program
.
CLASS-METHODS:
get_method_include
IMPORTING i_class TYPE seoclsname
i_method TYPE seocpdname
RETURNING VALUE(r_include) TYPE progname
, get_function_include
IMPORTING i_function TYPE tfdir-funcname
RETURNING VALUE(r_include) TYPE progname
, get_all_includes_and_screens
IMPORTING i_type TYPE smodilog-obj_type
i_name TYPE smodilog-obj_name
EXPORTING e_includes TYPE prognames
e_screens TYPE ttp_mod_screens
, get_screen_flow_logic
IMPORTING i_screen TYPE tp_mod_screen
RETURNING VALUE(r_source_tab) TYPE d022s_t
.
CLASS-DATA:
s_mod_includes TYPE ttp_mod_includes
, s_mod_screens TYPE ttp_mod_screens
.
ENDCLASS.
IF p_zz_mod = abap_true AND lt_results IS NOT INITIAL.
lcl_zz=>filter_modifications( EXPORTING i_include = gv_report
i_screen = gv_dynpro
i_source_tab = gt_source
CHANGING c_findings = lt_results ).
ENDIF.
IF p_zz_mod = abap_true.
lcl_zz=>add_enhancement_includes( CHANGING c_includes = gt_object ).
lcl_zz=>add_modification_includes( CHANGING c_includes = gt_object
c_screens = gt_dynpro ).
ENDIF.
CLASS lcl_zz IMPLEMENTATION.
METHOD add_enhancement_includes.
DATA devclass_range TYPE RANGE OF tadir-devclass.
IF devclass IS INITIAL. " if no devclass restriction on selection screen, assume the user only wants the customer (Z and Y) enhancements
devclass_range = VALUE #( sign = 'I' option = 'CP' ( low = 'Z*' ) ( low = 'Y*' ) ).
ELSE.
devclass_range = devclass[].
ENDIF.
SELECT obj_name
FROM tadir
WHERE pgmid = 'R3TR'
AND object = 'ENHO'
AND devclass IN @devclass_range
AND delflag = ''
INTO TABLE @data(enhancements).
LOOP AT enhancements INTO DATA(enh).
TRANSLATE enh(30) USING ' ='.
enh+30 = 'E'.
APPEND enh TO c_includes.
ENDLOOP.
ENDMETHOD.
METHOD add_modification_includes.
DATA include TYPE progname.
CLEAR: s_mod_includes, s_mod_screens.
IF sy-batch IS INITIAL.
CALL FUNCTION 'SAPGUI_PROGRESS_INDICATOR'
EXPORTING
text = 'GET MODIFICATION INCLUDES...'.
ENDIF.
SELECT DISTINCT obj_type, obj_name, sub_type, sub_name, operation, prot_only AS without_assistant
FROM smodilog
WHERE NOT operation IN ('MIGR', 'IMPL', 'TRSL', 'NOTE') "in sync with SE95 and Clone Finder
AND inactive = ''
AND int_type NOT IN ('DUMY') "clone finder also ignores 'XXXX'=without modification assistant, but we think this is wrong
AND obj_type IN ('PROG', 'LDBA', " LDBA = logical database, similar to PROG
'FUGR', 'FUGX', 'FUGS', " FUGX and FUGS = parts of function groups for user exits
'CLAS')
AND sub_type NOT IN ( 'REPT', 'FUGT', 'CUAD', 'DOCU', 'VARI' )
ORDER BY obj_type, obj_name, sub_type, sub_name, prot_only
INTO TABLE @DATA(modifications).
LOOP AT modifications REFERENCE INTO DATA(mod).
CASE mod->sub_type.
WHEN 'REPS'. " report source
s_mod_includes = VALUE #( BASE s_mod_includes
( include = mod->sub_name
without_assistant = mod->without_assistant ) ).
WHEN 'METH'.
s_mod_includes = VALUE #( BASE s_mod_includes
( include = get_method_include( i_class = EXACT #( mod->obj_name )
i_method = EXACT #( mod->sub_name+30 ) )
without_assistant = mod->without_assistant ) ).
WHEN 'FUNC'.
s_mod_includes = VALUE #( BASE s_mod_includes
( include = get_function_include( i_function = EXACT #( mod->sub_name ) )
without_assistant = mod->without_assistant ) ).
WHEN 'LDBA'. " logical databases. Seem to have these two code objects
s_mod_includes = VALUE #( BASE s_mod_includes
( include = mod->sub_name && 'SEL'
without_assistant = mod->without_assistant )
( include = 'SAP' && mod->sub_name
without_assistant = mod->without_assistant ) ).
WHEN 'CLAS'. " complete class
cl_oo_classname_service=>get_all_class_includes( EXPORTING class_name = EXACT #( mod->obj_name )
RECEIVING result = DATA(class_includes)
EXCEPTIONS OTHERS = 0 ).
DELETE class_includes WHERE table_line+30(2) = 'CS' OR table_line+30(2) = 'CP'. " CS = complete source, CP = frameprogram for class pool
s_mod_includes = VALUE #( BASE s_mod_includes
FOR class_incl IN class_includes
( include = class_incl
without_assistant = mod->without_assistant ) ).
WHEN 'CINC'. " class include
s_mod_includes = VALUE #( BASE s_mod_includes
( include = EXACT #( mod->sub_name )
without_assistant = mod->without_assistant ) ).
WHEN 'CPUB' OR 'CPRO' OR 'CPRI'. " class public/protected/private definitions
include = mod->sub_name.
TRANSLATE include USING ' ='.
include+30 = SWITCH #( mod->sub_type WHEN 'CPUB' THEN 'CU'
WHEN 'CPRO' THEN 'CO'
WHEN 'CPRI' THEN 'CI' ).
s_mod_includes = VALUE #( BASE s_mod_includes
( include = include
without_assistant = mod->without_assistant ) ).
WHEN 'FUGR' OR 'PROG'. " complete report or function group
get_all_includes_and_screens( EXPORTING i_type = mod->sub_type
i_name = EXACT #( mod->sub_name )
IMPORTING e_includes = DATA(includes)
e_screens = DATA(screens) ).
s_mod_includes = VALUE #( BASE s_mod_includes
FOR incl IN includes
( include = incl
without_assistant = mod->without_assistant ) ).
s_mod_screens = VALUE #( BASE s_mod_screens
FOR scr IN screens
( program = scr-program
screen = scr-screen
without_assistant = mod->without_assistant ) ).
WHEN 'DYNP'. " screen (dynpro) - the program only searches through the flow logic (code)
s_mod_screens = VALUE #( BASE s_mod_screens
( program = mod->sub_name(40)
screen = mod->sub_name+40(4)
without_assistant = mod->without_assistant ) ).
WHEN OTHERS.
LOG-POINT ID zlog FIELDS mod->obj_type mod->obj_name mod->sub_type mod->sub_name. " unknown subtype of modification
ENDCASE.
ENDLOOP.
" pass result to caller, but also keep our own data, to be used later for filtering
SORT s_mod_includes BY include. " for binary search later
DELETE ADJACENT DUPLICATES FROM s_mod_includes.
SORT s_mod_screens BY program screen. " for binary search later
DELETE ADJACENT DUPLICATES FROM s_mod_screens COMPARING program screen. " there are duplicates here because of the way SMODILOG is used
c_includes = VALUE #( BASE c_includes
FOR incl_ IN s_mod_includes
( incl_-include ) ).
c_screens = VALUE #( BASE c_screens
FOR scr_ IN s_mod_screens
( repname = scr_-program
dynnr = scr_-screen ) ).
ENDMETHOD.
METHOD get_method_include.
DATA: generic_instance TYPE REF TO if_oo_clif_incl_naming
, class_instance TYPE REF TO if_oo_class_incl_naming.
cl_oo_include_naming=>get_instance_by_name( EXPORTING name = i_class
RECEIVING cifref = generic_instance
EXCEPTIONS no_objecttype = 1
internal_error = 2
OTHERS = 3 ).
class_instance ?= generic_instance.
class_instance->get_include_by_mtdname( EXPORTING mtdname = i_method
with_enhancements = abap_true
with_alias_resolution = abap_true
RECEIVING progname = r_include
EXCEPTIONS internal_method_not_existing = 1
OTHERS = 2 ).
ASSERT sy-subrc = 0. " method not found
ENDMETHOD.
METHOD get_function_include.
SELECT SINGLE pname
FROM tfdir
WHERE funcname = @i_function
INTO @r_include.
ASSERT sy-subrc = 0.
ENDMETHOD.
METHOD get_all_includes_and_screens.
IF i_type = 'PROG'.
DATA(frame_program) = i_name.
ELSE.
DATA(function_group) = EXACT rs38l_area( i_name ).
CALL FUNCTION 'FUNCTION_INCLUDE_CONCATENATE'
CHANGING
program = frame_program
complete_area = function_group
EXCEPTIONS
OTHERS = 1.
ASSERT sy-subrc = 0.
ENDIF.
CALL FUNCTION 'RS_GET_ALL_INCLUDES'
EXPORTING
program = frame_program
TABLES
includetab = e_includes
EXCEPTIONS
OTHERS = 0.
DELETE e_includes WHERE table_line CP 'LSVIM*'. "remove reused includes from maintenance views
SORT e_includes.
DELETE ADJACENT DUPLICATES FROM e_includes.
SELECT prog AS program, dnum AS screen
FROM d020s
WHERE prog = @frame_program
INTO CORRESPONDING FIELDS OF TABLE @e_screens.
ENDMETHOD.
METHOD get_screen_flow_logic.
DATA: header TYPE d020s
, fields TYPE STANDARD TABLE OF d021s
, parameters TYPE STANDARD TABLE OF d023s
, BEGIN OF screen
, prog TYPE d020s-prog
, dnum TYPE d020s-dnum
, END OF screen
.
screen = VALUE #( prog = i_screen-program
dnum = i_screen-screen ).
IMPORT DYNPRO header fields r_source_tab parameters ID screen.
ENDMETHOD.
METHOD filter_modifications.
DATA in_modified_section TYPE abap_bool.
IF i_screen IS INITIAL.
READ TABLE s_mod_includes WITH KEY include = i_include REFERENCE INTO DATA(mod_incl) BINARY SEARCH.
CHECK sy-subrc = 0. " do not filter findings of unmodified code
CHECK mod_incl->without_assistant = abap_false. " do not filter findings of code modified without assistant
ELSE.
READ TABLE s_mod_screens WITH KEY program = i_include screen = i_screen REFERENCE INTO DATA(mod_scr) BINARY SEARCH.
CHECK sy-subrc = 0. " do not filter findings of unmodified code
CHECK mod_scr->without_assistant = abap_false. " do not filter findings of code modified without assistant
ENDIF.
DATA(next_finding_index) = 1.
READ TABLE c_findings INDEX 1 REFERENCE INTO DATA(next_finding).
LOOP AT i_source_tab REFERENCE INTO DATA(source).
DATA(source_index) = sy-tabix.
IF source->*(2) = '*{'.
IF in_modified_section = abap_true.
LOG-POINT ID zlog FIELDS i_include i_screen. " modified include with irregular *{ *} pattern - can happen when modified code is copied into a modification
RETURN. " the best way can do is to leave the remaining source code findings unfiltered
ELSE.
in_modified_section = abap_true.
ENDIF.
ELSEIF source->*(2) = '*}'.
IF in_modified_section = abap_false.
LOG-POINT ID zlog FIELDS i_include i_screen. " modified include with irregular *{ *} pattern - can happen when modified code is copied into a modification
RETURN. " the best way can do is to leave the remaining source code findings unfiltered
ELSE.
in_modified_section = abap_false.
ENDIF.
ENDIF.
DO. " loop necessary, because there can be multiple findings for same source line
IF source_index <> next_finding->line.
EXIT.
ENDIF.
IF in_modified_section = abap_true.
ADD 1 TO next_finding_index. " leave current, continue with next
ELSE.
DELETE c_findings INDEX next_finding_index. " delete current, continue with next
ENDIF.
READ TABLE c_findings INDEX next_finding_index REFERENCE INTO next_finding.
IF sy-subrc <> 0.
RETURN.
ENDIF.
ENDDO.
ENDLOOP.
ENDMETHOD.
ENDCLASS.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
3 | |
1 | |
1 | |
1 | |
1 | |
1 | |
1 | |
1 |