* _______ _______ _______ _______ _______ _______ ______ _______ _______ ______ _______ * | _ | _ | _ | | | _ | || _ | _ | _ | | _ | * | |_| | |_| | |_| | _ | | |_| | _ | |_| | |_| | | || | |_| | * | | | | |_| | | | | | | | | |_||_| | * | | _ || | ___| _| | |_| | | _ || __ | | * | _ | |_| | _ | | | |_| _ | | _ | |_| | | | | _ | * |__| |__|_______|__| |__|___| |_______|__| |__|______||__| |__|_______|___| |_|__| |__| * www.abapcadabra.com *------------------------------------------------------------------------------------------- * program : ZABAPCADABRA_AUTO_PIMPER * title : Auto-pimp your Abap report * functional area : X-component * environment : 4.7 * program Function : Using the ZABAPCADABRA_PIMP_TEMPLATE report, this report * will place comment-banners into your coding and fill in some * of the details for you. Feel free to add/change the template ! * Documentation : Search for "auto pimp" on AbapcadabrA.com * Previous version : This is the initial version * Developer name : Wim Maasdam * Development date : 12-06-2017 * Version : 0.1 *--------------------------------------------------------------------- * Change list: * Date Description * 12-06-2017 Initial release *--------------------------------------------------------------------- REPORT ZABAPCADABRA_AUTO_PIMPER LINE-SIZE 212. class lcl_report_scanner definition FINAL. PUBLIC SECTION. constants: co_template_report type sy-repid value 'ZABAPCADABRA_AUTOPIMP_TEMPLATE'. types: begin of ty_scan_results, superSourceLine type sy-dbcnt, linetype type c length 30, content type char255, object type c length 30, sourceLine type c length 5, "Max accepted.. key1 type c length 40, key2 type c length 40, resultCounter type n length 5, one TYPE i, colors TYPE lvc_t_scol, end of ty_scan_results. class-data: gv_main_program type sy-repid, gt_templatecode type standard table of char255, gt_sourcecode type standard table of char255, gt_scan_results_templ type standard table of ty_scan_results, gt_scan_results type standard table of ty_scan_results. class-methods: initialize, read_report importing main_program type any collapse_includes type boolean DEFAULT abap_true, set_result importing resultCounter type any default 0 linetype type any default space superSourceline type any key1 type any default space key2 type any default space, scan_impact_points importing define_only type boolean default abap_false, apply_cblocks importing datum type d with_report_header type boolean default abap_true, editor_report importing copy_to_clipboard type boolean . endclass. class lcl_report_scanner implementation. "The scanner class method initialize. * Read the TEMPLATE report - which is a total MUST for this setup read report co_template_report into gt_templatecode. if sy-subrc <> 0. message 'Fatal: Template report ZABAPCADABRA_AUTOPIMP_TEMPLATE is missing' type 'E'. endif. read_report( co_template_report ). gt_templatecode[] = gt_sourcecode[]. scan_impact_points( ). gt_scan_results_templ[] = gt_scan_results[]. clear: gt_sourcecode[], gt_scan_results[]. endmethod. method read_report. data: lt_sourcecode2 type standard table of char255, lv_sourcecode type char255, lv_sourcecode2 type char255, lv_include_name type char255, lt_statements type standard table of SSTMNT ##NEEDED, lv_tabix type sy-tabix, lv_tabix_num type n length 5, lv_devclass type tadir-devclass. data: lt_keywords type standard table of char50, lt_tokens type standard table of STOKES, lw_token TYPE STOKES. gv_main_program = main_program. clear: gt_sourcecode[]. * Read the main report read report gv_main_program into gt_sourcecode. check sy-subrc = 0. check collapse_includes = abap_true. * Perform the SCAN - with focus on local and global data declarations append 'INCLUDE' to lt_keywords. * Position 200 onwards is used to identify the original main source and line loop at gt_sourcecode into lv_sourcecode. lv_tabix_num = sy-tabix. concatenate '"' gv_main_program lv_tabix_num into lv_sourcecode+200 SEPARATED BY space. modify gt_sourcecode from lv_sourcecode. endloop. * Resolve includes in n rounds (include in include in include in ...): do 5 times. scan abap-source gt_sourcecode KEYWORDS FROM lt_keywords STATEMENTS INTO lt_statements TOKENS INTO lt_tokens. delete lt_tokens where STR = 'INCLUDE'. sort lt_tokens by row descending. "< Insert Includes BOTTOM UP loop at lt_tokens into lw_token. lv_tabix = lw_token-row + 1. lv_include_name = lw_token-str. select single devclass from tadir into lv_devclass where pgmid = 'R3TR' and object = 'PROG' and obj_name = lv_include_name. if sy-subrc = 0 and ( lv_devclass(1) = 'Z' or lv_devclass(1) = 'Y' or lv_devclass = '$TMP' ). * Read include coding read report lv_include_name into lt_sourcecode2. if sy-subrc = 0. concatenate '* Resolved INCLUDE >>' lv_include_name into lv_sourcecode SEPARATED BY space. modify gt_sourcecode from lv_sourcecode index lw_token-row. loop at lt_sourcecode2 into lv_sourcecode2. * Position 200 onwards is used to identify the original include source and line lv_tabix_num = sy-tabix. concatenate '"' lv_include_name lv_tabix_num into lv_sourcecode2+200 SEPARATED BY space. modify lt_sourcecode2 from lv_sourcecode2. endloop. insert lines of lt_sourcecode2 into gt_sourcecode index lv_tabix. endif. endif. endloop. enddo. endmethod. method set_result. "resultCounter = superSourceline = lineType = data: lw_scan_results type ty_scan_results. lw_scan_results-resultCounter = resultCounter. lw_scan_results-superSourceLine = superSourceline. lw_scan_results-linetype = lineType. lw_scan_results-key1 = key1. lw_scan_results-key2 = key2. read table gt_sourcecode index superSourceline into lw_scan_results-content. split lw_scan_results-content+202 at space into lw_scan_results-object lw_scan_results-sourceLine. lw_scan_results-content = lw_scan_results-content(200). lw_scan_results-one = 1. append lw_scan_results to gt_scan_results. endmethod. method scan_impact_points. data: lt_keywords type standard table of char50, lt_statements type standard table of SSTMNT, lw_statement TYPE SSTMNT, lt_tokens type standard table of STOKES, lw_token TYPE STOKES, lw_token_hlp TYPE STOKES, lw_token_hlp2 TYPE STOKES, lv_TOKEN_ROW type TOKEN_ROW, lv_classname type c length 32, begin of lw_control_flags, reporthdr type boolean, datadef type boolean, selscreen type boolean, at_selection type boolean, class_d_level type boolean, class_i_level type boolean, forms_level type boolean, modules_level type boolean, end of lw_control_flags. * Perform the SCAN - with focus on local and global data declarations if define_only = abap_true. append 'DEFINE' to lt_keywords. else. append 'DATA' to lt_keywords. append 'TABLES' to lt_keywords. append 'PARAMETER' to lt_keywords. append 'PARAMETERS' to lt_keywords. append 'SELECT-OPTION' to lt_keywords. append 'SELECT-OPTIONS' to lt_keywords. append 'SELECTION-SCREEN' to lt_keywords. append 'DEFINE' to lt_keywords. append 'FORM' to lt_keywords. append 'CLASS' to lt_keywords. append 'MODULE' to lt_keywords. append 'METHOD' to lt_keywords. append 'REPORT' to lt_keywords. append 'PROGRAM' to lt_keywords. append 'INITIALIZATION' to lt_keywords. append 'AT' to lt_keywords. append 'START-OF-SELECTION' to lt_keywords. append 'END-OF-SELECTION' to lt_keywords. append 'INCLUDE' to lt_keywords. endif. *----------------------------------------------------- SCAN ABAP-SOURCE gt_sourcecode KEYWORDS FROM lt_keywords STATEMENTS INTO lt_statements TOKENS INTO lt_tokens. *----------------------------------------------------- clear: lw_control_flags. loop at lt_statements into lw_statement. loop at lt_tokens into lw_token from lw_statement-from to lw_statement-to. lv_TOKEN_ROW = lw_token-ROW. add 1 to lw_statement-from. read table lt_tokens into lw_token_hlp index lw_statement-from. case lw_token-STR. when 'REPORT' or 'PROGRAM'. if lw_control_flags-reporthdr = abap_false. set_result( linetype = 'REPORT_HEADER' superSourceline = lv_TOKEN_ROW key1 = lw_token_hlp-STR ). endif. lw_control_flags-reporthdr = abap_true. when 'INCLUDE'. add 1 to lw_statement-from. read table lt_tokens into lw_token_hlp2 index lw_statement-from. if lw_token_hlp2-STR <> 'STRUCTURE'. "INCLUDE STRUCTURE definitions are not coding includes set_result( linetype = 'ABAP_INCLUDE' superSourceline = lv_TOKEN_ROW key1 = lw_token_hlp-STR ). if lw_control_flags-reporthdr = abap_false. * The main program has an INCLUDE before REPORT or PROGRAM, which implies the REPORT or PROGRAM statement * is on the first include. set_result( linetype = 'REPORT_HEADER' superSourceline = lv_TOKEN_ROW key1 = lw_token_hlp-STR ). endif. lw_control_flags-reporthdr = abap_true. endif. when 'DATA' or 'TABLES'. if lw_control_flags-datadef = abap_false. set_result( linetype = 'DATA_DEFINITIONS' superSourceline = lv_TOKEN_ROW key1 = lw_token_hlp-STR ). lw_control_flags-datadef = abap_true. endif. when 'PARAMETER' or 'PARAMETERS' or 'SELECT-OPTION' or 'SELECT-OPTIONS' or 'SELECTION-SCREEN'. if lw_control_flags-selscreen = abap_false. set_result( linetype = 'SELECTION_SCREEN' superSourceline = lv_TOKEN_ROW key1 = lw_token_hlp-STR ). lw_control_flags-selscreen = abap_true. endif. when 'FORM'. set_result( linetype = 'FORM_ROUTINE' superSourceline = lv_TOKEN_ROW key1 = lw_token_hlp-STR ). lw_control_flags-datadef = abap_true. if lw_control_flags-forms_level = abap_false. set_result( linetype = 'FORM_ROUTINES' superSourceline = lv_TOKEN_ROW key1 = lw_token_hlp-STR ). endif. lw_control_flags-forms_level = abap_true. when 'METHOD'. set_result( linetype = 'CLASS_METHOD' superSourceline = lv_TOKEN_ROW key1 = lw_token_hlp-STR key2 = lv_classname ). lw_control_flags-datadef = abap_true. when 'CLASS'. add 1 to lw_statement-from. read table lt_tokens into lw_token_hlp2 index lw_statement-from. case lw_token_hlp2-STR. when 'DEFINITION'. set_result( linetype = 'CLASS_DEFINITION' superSourceline = lv_TOKEN_ROW key1 = lw_token_hlp-STR ). if lw_control_flags-class_d_level = abap_false. set_result( linetype = 'CLASS_DEFINITIONS' superSourceline = lv_TOKEN_ROW key1 = lw_token_hlp-STR ). endif. lw_control_flags-class_d_level = abap_true. when 'IMPLEMENTATION'. set_result( linetype = 'CLASS_IMPLEMENTATION' superSourceline = lv_TOKEN_ROW key1 = lw_token_hlp-STR ). if lw_control_flags-class_i_level = abap_false. set_result( linetype = 'CLASS_IMPLEMENTATIONS' superSourceline = lv_TOKEN_ROW key1 = lw_token_hlp-STR ). endif. lw_control_flags-class_i_level = abap_true. lv_classname = lw_token_hlp-STR. " 0 or lw_char255(18) = 'END-OF-DEFINITION.'. lw_positions-cblock_ended = abap_true. else. append lw_char255 to lt_template_cblock. endif. add 1 to lw_positions-pointer. endwhile. end-of-definition. sort gt_scan_results by superSourceLine DESCENDING linetype. * If the report header should be left in tact - remove gt_scan_results for a predefined linetype: if with_report_header = abap_false. delete gt_scan_results where linetype = 'REPORT_HEADER'. endif. clear: lw_parameter_info. lw_parameter_info-report = gv_main_program. select single text from TRDIRT into lw_parameter_info-title where NAME = gv_main_program and sprsl = sy-langu. write: datum dd/mm/yyyy to lw_parameter_info-datum. select NAME_TEXTC from USER_ADDR into lw_parameter_info-developer up to 1 rows where bname = sy-uname. endselect. *--------------------------------------------------------------- loop at gt_scan_results into lw_scan_result. *--------------------------------------------------------------- read table gt_scan_results_templ into lw_scan_result_templ with key key1 = lw_scan_result-linetype. if sy-subrc = 0. clear: lt_template_cblock[]. * We have a match - template and actual source have a relation: * Set parameter_info, based on the actual source code: if lw_scan_result-content cs '"'. lw_parameter_info-in_line_comment = lw_scan_result-content+sy-fdpos. shift lw_parameter_info-in_line_comment left by 1 places. else. clear: lw_parameter_info-in_line_comment. endif. * Determine comment-block from template: fetch_block lw_scan_result_templ-superSourceLine. * If a coding block is available, populate it with info: if not lt_template_cblock[] is initial. loop at lt_template_cblock into lw_char255. setpar: '{repid}' lw_parameter_info-report, '{title}' lw_parameter_info-title, '{saprl}' sy-saprl, '{uname}' sy-uname, '{datum}' lw_parameter_info-datum, '{developer}' lw_parameter_info-developer, '{class}' lw_scan_result-key1, '{classmethod}' lw_scan_result-key2, '{method}' lw_scan_result-key1, '{form}' lw_scan_result-key1, '{module}' lw_scan_result-key1, '{macro}' lw_scan_result-key1, '{include}' lw_scan_result-key1, '{comments}' lw_parameter_info-in_line_comment. endloop. endif. * The block is ready ro be implemented. First remove the block that is already available: clear lw_positions. lw_positions-pointer = lw_scan_result-supersourceline - 1. while lw_positions-cblock_ended = abap_false. if lw_positions-pointer = 0. lw_positions-cblock_ended = abap_true. else. read table gt_sourcecode index lw_positions-pointer into lw_char255. if sy-subrc <> 0 or lw_char255 is initial. lw_positions-cblock_ended = abap_true. elseif lw_char255(1) = '*'. delete gt_sourcecode index lw_positions-pointer. subtract 1 from lw_positions-pointer. else. lw_positions-cblock_ended = abap_true. endif. endif. endwhile. add 1 to lw_positions-pointer. * Then insert the new block: insert lines of lt_template_cblock into gt_sourcecode index lw_positions-pointer. endif. *--------------------------------------------------------------- endloop. *--------------------------------------------------------------- read table gt_scan_results_templ into lw_scan_result_templ with key key1 = 'REPORT_FOOTER'. if sy-subrc = 0. * First remove comment coding from the end of the report: describe table gt_sourcecode lines lw_positions-pointer. clear lw_positions-cblock_ended. while lw_positions-cblock_ended = abap_false. if lw_positions-pointer = 0. lw_positions-cblock_ended = abap_true. else. read table gt_sourcecode index lw_positions-pointer into lw_char255. if sy-subrc <> 0 or lw_char255 is initial. lw_positions-cblock_ended = abap_true. elseif lw_char255(1) = '*'. delete gt_sourcecode index lw_positions-pointer. subtract 1 from lw_positions-pointer. else. lw_positions-cblock_ended = abap_true. endif. endif. endwhile. clear: lt_template_cblock[]. fetch_block lw_scan_result_templ-superSourceLine. append lines of lt_template_cblock to gt_sourcecode. endif. ENDMETHOD. METHOD editor_report. data: lv_sourceline type char255, lv_returncode type i. loop at gt_sourcecode into lv_sourceline. write: /(5) sy-tabix. if lv_sourceline+202(25) = 'ZABAPCADABRA_AUTOPIMP_TEM'. write: lv_sourceline(200) color 2 INTENSIFIED off. else. write: lv_sourceline(200). endif. lv_sourceline = lv_sourceline(200). modify gt_sourcecode from lv_sourceline. endloop. if copy_to_clipboard = abap_true. cl_gui_frontend_services=>clipboard_export( importing data = lcl_report_scanner=>gt_sourcecode changing rc = lv_returncode exceptions others = 4 ). if sy-subrc = 0. message 'Source code placed on clipboard' type 'S'. endif. endif. ENDMETHOD. endclass. SELECTION-SCREEN BEGIN OF LINE. SELECTION-SCREEN COMMENT 1(33) lbl_01 FOR FIELD pa_main. PARAMETER: pa_main type RS38M-PROGRAMM. SELECTION-SCREEN END OF LINE. SELECTION-SCREEN SKIP. SELECTION-SCREEN BEGIN OF LINE. PARAMETER: pa_rehdr AS CHECKBOX. SELECTION-SCREEN COMMENT 3(20) lbl_02 FOR FIELD pa_rehdr. SELECTION-SCREEN COMMENT 24(10) lbl_03 FOR FIELD pa_datum. PARAMETER: pa_datum type d DEFAULT sy-datum. SELECTION-SCREEN END OF LINE. SELECTION-SCREEN BEGIN OF LINE. PARAMETER: pa_incde AS CHECKBOX. SELECTION-SCREEN COMMENT 3(55) lbl_04 FOR FIELD pa_incde. SELECTION-SCREEN END OF LINE. SELECTION-SCREEN BEGIN OF LINE. PARAMETER: pa_clbrd AS CHECKBOX. SELECTION-SCREEN COMMENT 3(35) lbl_05 FOR FIELD pa_clbrd. SELECTION-SCREEN END OF LINE. INITIALIZATION. lcl_report_scanner=>initialize( ). lbl_01 = 'Abap source code'. lbl_02 = 'Renew report header'. lbl_03 = 'With date'. lbl_04 = 'Resolve includes (incorporate in main report) '. lbl_05 = 'Place results on clipboard (CTRL-V)'. START-OF-SELECTION. lcl_report_scanner=>read_report( exporting main_program = pa_main collapse_includes = pa_incde ). lcl_report_scanner=>scan_impact_points( ). lcl_report_scanner=>apply_cblocks( exporting datum = pa_datum with_report_header = pa_rehdr ). lcl_report_scanner=>editor_report( pa_clbrd ).