From 29f0a9646cbd1340f43da76b4b0c3fe9106ee730 Mon Sep 17 00:00:00 2001 From: TheWirtschaftsmann Date: Tue, 13 Dec 2016 17:59:02 +0200 Subject: [PATCH 1/4] Xml syntax #443 * Refactoring update Overview of changes: - Renaming of ltcl_code_highlighter* to ltcl_syntax_highlighter*. - Fine-tuning of regex generation. - Fine-tuning of order_matches to take into account key words inside of structures. * file extension Refactored checking of file extension. * Refactoring of highlighter Refactoring of highlighter and adding XML-parser. --- src/zabapgit_page_diff.prog.abap | 9 +- src/zabapgit_syntax_highlighter.prog.abap | 956 ++++++++++++++-------- 2 files changed, 632 insertions(+), 333 deletions(-) diff --git a/src/zabapgit_page_diff.prog.abap b/src/zabapgit_page_diff.prog.abap index 0cab80365..79ed392c0 100644 --- a/src/zabapgit_page_diff.prog.abap +++ b/src/zabapgit_page_diff.prog.abap @@ -255,24 +255,21 @@ CLASS lcl_gui_page_diff IMPLEMENTATION. METHOD render_lines. - DATA: lo_highlighter TYPE REF TO lcl_code_highlighter, + DATA: lo_highlighter TYPE REF TO lcl_syntax_highlighter, lt_diffs TYPE lcl_diff=>ty_diffs_tt, lv_local TYPE string, lv_remote TYPE string, lv_lattr TYPE string, lv_rattr TYPE string, - lv_highlight TYPE abap_bool, lv_insert_nav TYPE abap_bool. FIELD-SYMBOLS LIKE LINE OF lt_diffs. - CREATE OBJECT lo_highlighter. + lo_highlighter = lcl_syntax_highlighter=>create( is_diff-filename ). CREATE OBJECT ro_html. lt_diffs = is_diff-o_diff->get( ). - lv_highlight = boolc( is_diff-filename CP '*.abap' ). - LOOP AT lt_diffs ASSIGNING . IF -short = abap_false. lv_insert_nav = abap_true. @@ -292,7 +289,7 @@ CLASS lcl_gui_page_diff IMPLEMENTATION. lv_remote = -old. ENDIF. - IF lv_highlight = abap_true. + IF lo_highlighter IS BOUND. lv_local = lo_highlighter->process_line( lv_local ). lv_remote = lo_highlighter->process_line( lv_remote ). ELSE. diff --git a/src/zabapgit_syntax_highlighter.prog.abap b/src/zabapgit_syntax_highlighter.prog.abap index 8ccef3149..718357b6c 100644 --- a/src/zabapgit_syntax_highlighter.prog.abap +++ b/src/zabapgit_syntax_highlighter.prog.abap @@ -2,43 +2,31 @@ *& Include ZABAPGIT_SYNTAX_HIGHLIGHTER *&---------------------------------------------------------------------* *&---------------------------------------------------------------------* -*& Class lcl_code_highligher +*& Class lcl_syntax_highligher *&---------------------------------------------------------------------* -CLASS ltcl_code_highlighter1 DEFINITION DEFERRED. -CLASS ltcl_code_highlighter2 DEFINITION DEFERRED. +CLASS ltcl_syntax_highlighter1 DEFINITION DEFERRED. +CLASS ltcl_syntax_highlighter2 DEFINITION DEFERRED. + +CLASS lcl_syntax_abap DEFINITION DEFERRED. +CLASS lcl_syntax_xml DEFINITION DEFERRED. *----------------------------------------------------------------------* -* CLASS lcl_code_highlighter DEFINITION +* CLASS lcl_syntax_highlighter DEFINITION *----------------------------------------------------------------------* -CLASS lcl_code_highlighter DEFINITION FRIENDS ltcl_code_highlighter1 ltcl_code_highlighter2. +CLASS lcl_syntax_highlighter DEFINITION ABSTRACT + FRIENDS ltcl_syntax_highlighter1 ltcl_syntax_highlighter2. PUBLIC SECTION. - CLASS-METHODS: - class_constructor. + CLASS-METHODS create + IMPORTING iv_filename TYPE string + RETURNING VALUE(ro_instance) TYPE REF TO lcl_syntax_highlighter. - METHODS: - process_line + METHODS process_line IMPORTING iv_line TYPE string RETURNING VALUE(rv_line) TYPE string. - PRIVATE SECTION. - CONSTANTS: - BEGIN OF c_token, - keyword TYPE c VALUE 'K', - text TYPE c VALUE 'T', - comment TYPE c VALUE 'C', - none TYPE c VALUE 'N', - END OF c_token. - - CONSTANTS: - BEGIN OF c_css, - keyword TYPE string VALUE 'keyword', - text TYPE string VALUE 'text', - comment TYPE string VALUE 'comment', - none TYPE string VALUE 'none', - END OF c_css. - + PROTECTED SECTION. TYPES: BEGIN OF ty_match, token TYPE char1, " Type of matches @@ -52,45 +40,108 @@ CLASS lcl_code_highlighter DEFINITION FRIENDS ltcl_code_highlighter1 ltcl_code_h TYPES: BEGIN OF ty_regex, - regex TYPE REF TO cl_abap_regex, - token TYPE char1, + regex TYPE REF TO cl_abap_regex, + token TYPE char1, END OF ty_regex. + TYPES: + BEGIN OF ty_style_map, + token TYPE char1, + style TYPE string, + END OF ty_style_map. + + CONSTANTS: + BEGIN OF c_css, + keyword TYPE string VALUE 'keyword', "#EC NOTEXT + text TYPE string VALUE 'text', "#EC NOTEXT + comment TYPE string VALUE 'comment', "#EC NOTEXT + xml_tag TYPE string VALUE 'xml_tag', "#EC NOTEXT + attr TYPE string VALUE 'attr', "#EC NOTEXT + attr_val TYPE string VALUE 'attr_val', "#EC NOTEXT + none TYPE string VALUE 'none', "#EC NOTEXT + END OF c_css. + + CONSTANTS: + BEGIN OF c_token, + keyword TYPE c VALUE 'K', "#EC NOTEXT + text TYPE c VALUE 'T', "#EC NOTEXT + comment TYPE c VALUE 'C', "#EC NOTEXT + xml_tag TYPE c VALUE 'X', "#EC NOTEXT + attr TYPE c VALUE 'A', "#EC NOTEXT + attr_val TYPE c VALUE 'V', "#EC NOTEXT + none TYPE c VALUE 'N', "#EC NOTEXT + END OF c_token. + CLASS-DATA: BEGIN OF c_regex, - comment TYPE string, - text TYPE string, - keyword TYPE string, + comment TYPE string, + text TYPE string, + keyword TYPE string, + xml_tag TYPE string, + attr TYPE string, + attr_val TYPE string, END OF c_regex. - CLASS-DATA: mo_regex_table TYPE TABLE OF ty_regex. + CLASS-DATA: + mo_regex_table TYPE TABLE OF ty_regex, + mo_style_map TYPE TABLE OF ty_style_map. - METHODS: - parse_line + METHODS parse_line IMPORTING iv_line TYPE string RETURNING VALUE(rt_matches) TYPE ty_match_tt. - METHODS: - order_matches + METHODS order_matches ABSTRACT IMPORTING iv_line TYPE string CHANGING ct_matches TYPE ty_match_tt. - METHODS: - format_line + METHODS extend_matches + IMPORTING iv_line TYPE string + CHANGING ct_matches TYPE ty_match_tt. + + METHODS format_line IMPORTING iv_line TYPE string it_matches TYPE ty_match_tt RETURNING VALUE(rv_line) TYPE string. - METHODS: - apply_style + METHODS apply_style IMPORTING iv_line TYPE string iv_class TYPE string RETURNING VALUE(rv_line) TYPE string. -ENDCLASS. "lcl_code_highlighter DEFINITION +ENDCLASS. " lcl_syntax_highlighter DEFINITION *----------------------------------------------------------------------* -* Macros +* CLASS lcl_syntax_abap DEFINITION +*----------------------------------------------------------------------* +* +*----------------------------------------------------------------------* +CLASS lcl_syntax_abap DEFINITION INHERITING FROM lcl_syntax_highlighter. + + PUBLIC SECTION. + CLASS-METHODS class_constructor. + + PROTECTED SECTION. + CLASS-METHODS get_keywords RETURNING VALUE(rv_string) TYPE string. + METHODS order_matches REDEFINITION. + +ENDCLASS. " lcl_syntax_abap DEFINITION + +*----------------------------------------------------------------------* +* CLASS lcl_syntax_xml DEFINITION +*----------------------------------------------------------------------* +* +*----------------------------------------------------------------------* +CLASS lcl_syntax_xml DEFINITION INHERITING FROM lcl_syntax_highlighter. + PUBLIC SECTION. + CLASS-METHODS class_constructor. + + PROTECTED SECTION. + METHODS order_matches REDEFINITION. + +ENDCLASS. " lcl_syntax_xml DEFINITION + +*----------------------------------------------------------------------* +* Macros to fill table with a regular expressions to be parsed *----------------------------------------------------------------------* DEFINE _add_regex. @@ -100,24 +151,205 @@ DEFINE _add_regex. pattern = c_regex-&1 ignore_case = abap_true. - ls_regex_table-token = c_token-&1. + ls_regex_table-token = c_token-&1. APPEND ls_regex_table TO mo_regex_table. -END-OF-DEFINITION. +END-OF-DEFINITION. " _add_regex *----------------------------------------------------------------------* -* CLASS lcl_code_highlighter IMPLEMENTATION +* Macros to fill table with mapping of tokens against CSS-styles *----------------------------------------------------------------------* -CLASS lcl_code_highlighter IMPLEMENTATION. + +DEFINE _add_style_mapping. + + ls_style_map-token = c_token-&1. + ls_style_map-style = c_css-&1. + APPEND ls_style_map TO mo_style_map. + +END-OF-DEFINITION. " _add_style_mapping +*----------------------------------------------------------------------* +* CLASS lcl_syntax_highlighter IMPLEMENTATION +*----------------------------------------------------------------------* +* Implementation of syntax highligther for ABAP source code +*----------------------------------------------------------------------* +CLASS lcl_syntax_highlighter IMPLEMENTATION. + + METHOD create. + + " Create instance of highighter dynamically dependent on syntax type + IF iv_filename CP '*.abap'. + CREATE OBJECT ro_instance TYPE lcl_syntax_abap. + ELSEIF iv_filename CP '*.xml'. + CREATE OBJECT ro_instance TYPE lcl_syntax_xml. + ELSE. + CLEAR ro_instance. + ENDIF. + + ENDMETHOD. " create. + + METHOD parse_line. + + DATA: + lo_regex TYPE REF TO cl_abap_regex, + lo_matcher TYPE REF TO cl_abap_matcher, + lt_result TYPE match_result_tab, + ls_match TYPE ty_match. + + FIELD-SYMBOLS: + TYPE ty_regex, + TYPE match_result, + TYPE ty_match. + + " Process syntax-dependent regex table and find all matches + LOOP AT mo_regex_table ASSIGNING . + lo_regex = -regex. + lo_matcher = lo_regex->create_matcher( text = iv_line ). + lt_result = lo_matcher->find_all( ). + + " Save matches into custom table with predefined tokens + LOOP AT lt_result ASSIGNING . + CLEAR: ls_match. + ls_match-token = -token. + ls_match-offset = -offset. + ls_match-length = -length. + APPEND ls_match TO rt_matches. + ENDLOOP. + ENDLOOP. + + ENDMETHOD. " parse_line + + METHOD extend_matches. + DATA: + lv_line_len TYPE i, + lv_last_pos TYPE i VALUE 0, + lv_length TYPE i, + ls_match TYPE ty_match. + + FIELD-SYMBOLS TYPE ty_match. + + lv_line_len = strlen( iv_line ). + + " Add entries refering to parts of text that should not be formatted + LOOP AT ct_matches ASSIGNING . + IF -offset > lv_last_pos. + lv_length = -offset - lv_last_pos. + ls_match-token = c_token-none. + ls_match-offset = lv_last_pos. + ls_match-length = lv_length. + INSERT ls_match INTO ct_matches INDEX sy-tabix. + ENDIF. + lv_last_pos = -offset + -length. + ENDLOOP. + + " Add remainder of the string + IF lv_line_len > lv_last_pos. + lv_length = lv_line_len - lv_last_pos. + ls_match-token = c_token-none. + ls_match-offset = lv_last_pos. + ls_match-length = lv_length. + APPEND ls_match TO ct_matches. + ENDIF. + + ENDMETHOD. " extend_matches + + METHOD format_line. + + DATA: + lv_chunk TYPE string, + lv_css_class TYPE string, + ls_style_map TYPE ty_style_map. + + FIELD-SYMBOLS TYPE ty_match. + + LOOP AT it_matches ASSIGNING . + lv_chunk = substring( val = iv_line off = -offset len = -length ). + + READ TABLE mo_style_map INTO ls_style_map WITH KEY token = -token. + + IF sy-subrc IS INITIAL. + lv_css_class = ls_style_map-style. + ELSE. + CLEAR: lv_css_class. + ENDIF. + + lv_chunk = me->apply_style( iv_line = lv_chunk + iv_class = lv_css_class ). + + rv_line = rv_line && lv_chunk. + ENDLOOP. + + ENDMETHOD. " format_line + + METHOD apply_style. + + DATA lv_escaped TYPE string. + + lv_escaped = escape( val = iv_line format = cl_abap_format=>e_html_attr ). + IF iv_class IS NOT INITIAL. + rv_line = |{ lv_escaped }|. + ELSE. + rv_line = lv_escaped. + ENDIF. + + ENDMETHOD. " apply_style + + METHOD process_line. + + DATA: lt_matches TYPE ty_match_tt. + + IF strlen( iv_line ) = 0. + RETURN. + ENDIF. + + lt_matches = me->parse_line( iv_line = iv_line ). + + me->order_matches( EXPORTING iv_line = iv_line + CHANGING ct_matches = lt_matches ). + + me->extend_matches( EXPORTING iv_line = iv_line + CHANGING ct_matches = lt_matches ). + + rv_line = me->format_line( iv_line = iv_line + it_matches = lt_matches ). + + ENDMETHOD. " process_line + +ENDCLASS. " lcl_syntax_highlighter IMPLEMENTATION + +*----------------------------------------------------------------------* +* CLASS lcl_syntax_abap IMPLEMENTATION +*----------------------------------------------------------------------* +* Implementation of syntax highligther for XML source code +*----------------------------------------------------------------------* +CLASS lcl_syntax_abap IMPLEMENTATION. METHOD class_constructor. - DATA: ls_regex_table TYPE ty_regex. + DATA: + ls_regex_table TYPE ty_regex, + ls_style_map TYPE ty_style_map. - c_regex-comment = '##|"|^\*'. - c_regex-text = '`|''|\||\{|\}'. - c_regex-keyword = '&&|\b(' && - '\*-INPUT|\?TO|ABAP-SOURCE|ABBREVIATED|ABS|ABSTRACT|ACCEPT|ACCEPTING|ACCESSPOLICY' && + " Declare regular expressions' constants + c_regex-comment = '##|"|^\*'. "#EC NOTEXT + c_regex-text = '`|''|\||\{|\}'. "#EC NOTEXT + c_regex-keyword = '&&|\b(' && get_keywords( ) && ')\b'. "#EC NOTEXT + + " Initialize instances of regular expressions + _add_regex keyword. + _add_regex comment. + _add_regex text. + + " Initialize mapping of tokens and CSS-styles + _add_style_mapping keyword. + _add_style_mapping comment. + _add_style_mapping text. + + ENDMETHOD. " class_constructor + + METHOD get_keywords. + + rv_string = + '\?TO|ABAP-SOURCE|ABBREVIATED|ABS|ABSTRACT|ACCEPT|ACCEPTING|ACCESSPOLICY' && '|ACCORDING|ACOS|ACTIVATION|ACTUAL|ADD|ADD-CORRESPONDING|ADJACENT|AFTER|ALIAS' && '|ALIASES|ALIGN|ALL|ALLOCATE|ALPHA|ANALYSIS|ANALYZER|AND|ANY|APPEND|APPENDAGE' && '|APPENDING|APPLICATION|ARCHIVE|AREA|ARITHMETIC|AS|ASCENDING|ASIN|ASPECT|ASSERT' && @@ -210,58 +442,15 @@ CLASS lcl_code_highlighter IMPLEMENTATION. '|UNWIND|UP|UPDATE|UPPER|USER|USER-COMMAND|USING|UTF-8|VALID|VALUE|VALUE-REQUEST|VALUES' && '|VARY|VARYING|VERIFICATION-MESSAGE|VERSION|VIA|VIEW|VISIBLE|WAIT|WARNING|WHEN|WHENEVER' && '|WHERE|WHILE|WIDTH|WINDOW|WINDOWS|WITH|WITH-HEADING|WITHOUT|WITH-TITLE|WORD|WORK' && - '|WRITE|WRITER|X|XML|XOR|XSD|XSTRLEN|YELLOW|YES|YYMMDD|Z|ZERO|ZONE' && - ')\b'. - - " Initialize instances of regular expressions - _add_regex keyword. - _add_regex comment. - _add_regex text. - - ENDMETHOD. "class_constructor - - METHOD parse_line. - - DATA: - lo_regex TYPE REF TO cl_abap_regex, - lo_matcher TYPE REF TO cl_abap_matcher, - lt_result TYPE match_result_tab, - ls_match TYPE ty_match. - - FIELD-SYMBOLS: - TYPE ty_regex, - TYPE match_result, - TYPE ty_match. - - LOOP AT mo_regex_table ASSIGNING . - lo_regex = -regex. - lo_matcher = lo_regex->create_matcher( text = iv_line ). - lt_result = lo_matcher->find_all( ). - - LOOP AT lt_result ASSIGNING . - ls_match-token = -token. - ls_match-offset = -offset. - ls_match-length = -length. - - IF ls_match-token = c_token-text. - ls_match-text_tag = substring( val = iv_line off = ls_match-offset len = ls_match-length ). - ENDIF. - - APPEND ls_match TO rt_matches. - ENDLOOP. - ENDLOOP. - - ENDMETHOD. " parse_line + '|WRITE|WRITER|X|XML|XOR|XSD|XSTRLEN|YELLOW|YES|YYMMDD|Z|ZERO|ZONE'. + ENDMETHOD. " get_keywords. METHOD order_matches. DATA: lv_index TYPE sy-tabix, lv_line_len TYPE i, - lv_prev_token TYPE c, - lv_last_pos TYPE i VALUE 0, - lv_length TYPE i, - ls_match TYPE ty_match. + lv_prev_token TYPE c. FIELD-SYMBOLS: TYPE ty_match, @@ -281,11 +470,20 @@ CLASS lcl_code_highlighter IMPLEMENTATION. ENDIF. CASE -token. + WHEN c_token-keyword. + IF -offset > 0. + " Delete match if keyword is part of structure or field symbol + IF substring( val = iv_line off = ( -offset - 1 ) len = 1 ) CA '-<'. + DELETE ct_matches INDEX lv_index. + CONTINUE. + ENDIF. + ENDIF. WHEN c_token-comment. -length = lv_line_len - -offset. DELETE ct_matches FROM lv_index + 1. CONTINUE. WHEN c_token-text. + -text_tag = substring( val = iv_line off = -offset len = -length ). IF lv_prev_token = c_token-text. IF -text_tag = -text_tag. -length = -offset + -length - -offset. @@ -310,153 +508,160 @@ CLASS lcl_code_highlighter IMPLEMENTATION. lv_prev_token = -token. ASSIGN TO . ENDLOOP. + ENDMETHOD. " order_matches. +ENDCLASS. " lcl_syntax_abap IMPLEMENTATION - " Add entries refering to parts of text that should not be formatted - LOOP AT ct_matches ASSIGNING . - IF -offset > lv_last_pos. - lv_length = -offset - lv_last_pos. - ls_match-token = c_token-none. - ls_match-offset = lv_last_pos. - ls_match-length = lv_length. - INSERT ls_match INTO ct_matches INDEX sy-tabix. - ENDIF. - lv_last_pos = -offset + -length. - ENDLOOP. - - " Add remainder of the string - IF lv_line_len > lv_last_pos. - lv_length = lv_line_len - lv_last_pos. - ls_match-token = c_token-none. - ls_match-offset = lv_last_pos. - ls_match-length = lv_length. - APPEND ls_match TO ct_matches. - ENDIF. - - ENDMETHOD. " order_matches. - - METHOD format_line. +*----------------------------------------------------------------------* +* CLASS lcl_syntax_xml IMPLEMENTATION +*----------------------------------------------------------------------* +* +*----------------------------------------------------------------------* +CLASS lcl_syntax_xml IMPLEMENTATION. + METHOD class_constructor. DATA: - lv_chunk TYPE string, - lv_css_class TYPE string. + ls_regex_table TYPE ty_regex, + ls_style_map TYPE ty_style_map. + + c_regex-xml_tag = '[<>]'. "#EC NOTEXT + c_regex-attr = '\s[a-z:]+\s*(?==)'. "#EC NOTEXT + c_regex-attr_val = '["''][^''"]+[''"]'. "#EC NOTEXT + + " Initialize instances of regular expressions + _add_regex xml_tag. + _add_regex attr. + _add_regex attr_val. + + " Initialize mapping of tokens and CSS-styles + _add_style_mapping xml_tag. + _add_style_mapping attr. + _add_style_mapping attr_val. + + ENDMETHOD. + + METHOD order_matches. + DATA: + lv_index TYPE sy-tabix, + lv_line_len TYPE i, + lv_prev_token TYPE c, + lv_state TYPE c VALUE 'O'. " O - for open tag; C - for closed tag; FIELD-SYMBOLS: - TYPE ty_match. + TYPE ty_match, + TYPE ty_match. - LOOP AT it_matches ASSIGNING . - lv_chunk = substring( val = iv_line off = -offset len = -length ). + SORT ct_matches BY offset. + + lv_line_len = strlen( iv_line ). + + LOOP AT ct_matches ASSIGNING . + lv_index = sy-tabix. CASE -token. - WHEN c_token-keyword. - lv_css_class = c_css-keyword. - WHEN c_token-comment. - lv_css_class = c_css-comment. - WHEN c_token-text. - lv_css_class = c_css-text. - WHEN c_token-none. - CLEAR: lv_css_class. + WHEN c_token-xml_tag. + -text_tag = substring( val = iv_line off = -offset len = -length ). + IF -text_tag = '>' AND lv_prev_token = c_token-xml_tag. " No other matches between two tags + lv_state = 'C'. + -length = -offset - -offset + -length. + DELETE ct_matches INDEX lv_index. + CONTINUE. + ELSEIF -text_tag = '>' AND lv_prev_token <> c_token-xml_tag. " Adjust length and offset of closing tag + lv_state = 'C'. + -length = -offset - -offset - -length + -length. + -offset = -offset + -length. + ELSE. + lv_state = 'O'. + ENDIF. + + WHEN OTHERS. + IF lv_prev_token = c_token-xml_tag. + -length = -offset - -offset. " Extend length of the opening tag + ENDIF. + + IF lv_state = 'C'. " Delete all matches between tags + DELETE ct_matches INDEX lv_index. + CONTINUE. + ENDIF. ENDCASE. - lv_chunk = me->apply_style( iv_line = lv_chunk - iv_class = lv_css_class ). - - rv_line = rv_line && lv_chunk. + lv_prev_token = -token. + ASSIGN TO . ENDLOOP. - - ENDMETHOD. "format_line - - METHOD apply_style. - - DATA lv_escaped TYPE string. - - lv_escaped = escape( val = iv_line format = cl_abap_format=>e_html_attr ). - IF iv_class IS NOT INITIAL. - rv_line = |{ lv_escaped }|. - ELSE. - rv_line = lv_escaped. - ENDIF. - - ENDMETHOD. "apply_style - - METHOD process_line. - - DATA: lt_matches TYPE ty_match_tt. - - IF strlen( iv_line ) = 0. - RETURN. - ENDIF. - - lt_matches = me->parse_line( iv_line ). - - me->order_matches( EXPORTING iv_line = iv_line - CHANGING ct_matches = lt_matches ). - - rv_line = me->format_line( iv_line = iv_line - it_matches = lt_matches ). - - ENDMETHOD. " process_line - -ENDCLASS. " lcl_code_highlighter IMPLEMENTATION + ENDMETHOD. " order_matches +ENDCLASS. " lcl_syntax_xml IMPLEMENTATION *----------------------------------------------------------------------* -* CLASS ltcl_code_highlighter definition +* CLASS ltcl_syntax_highlighter1 definition *----------------------------------------------------------------------* -CLASS ltcl_code_highlighter1 DEFINITION FINAL +CLASS ltcl_syntax_highlighter1 DEFINITION FINAL FOR TESTING RISK LEVEL HARMLESS DURATION SHORT. PRIVATE SECTION. DATA: - mo TYPE REF TO lcl_code_highlighter, - mt_after_parse TYPE lcl_code_highlighter=>ty_match_tt, - ms_match TYPE lcl_code_highlighter=>ty_match, - mt_after_order TYPE lcl_code_highlighter=>ty_match_tt. + mo TYPE REF TO lcl_syntax_highlighter, + mt_after_parse TYPE lcl_syntax_highlighter=>ty_match_tt, + mt_after_order TYPE lcl_syntax_highlighter=>ty_match_tt, + mt_after_extend TYPE lcl_syntax_highlighter=>ty_match_tt, + ms_match TYPE lcl_syntax_highlighter=>ty_match. METHODS: setup, - test IMPORTING iv_line TYPE string, + test IMPORTING iv_line TYPE string + iv_filename TYPE string + RETURNING VALUE(ro_instance) TYPE REF TO lcl_syntax_highlighter, test01 FOR TESTING, test02 FOR TESTING, test03 FOR TESTING, test04 FOR TESTING, test05 FOR TESTING, test06 FOR TESTING, - test07 FOR TESTING. + test07 FOR TESTING, + test08 FOR TESTING. -ENDCLASS. " ltcl_code_highlighter +ENDCLASS. " ltcl_syntax_highlighter1 *----------------------------------------------------------------------* -* CLASS ltcl_code_highlighter IMPLEMENTATION +* CLASS ltcl_syntax_highlighter1 IMPLEMENTATION *----------------------------------------------------------------------* -CLASS ltcl_code_highlighter1 IMPLEMENTATION. +CLASS ltcl_syntax_highlighter1 IMPLEMENTATION. DEFINE _generate_parse. ms_match-token = &1. ms_match-offset = &2. ms_match-length = &3. - ms_match-text_tag = &4. - APPEND ms_match to mt_after_parse. - END-OF-DEFINITION. + append ms_match to mt_after_parse. + END-OF-DEFINITION. " _generate_parse DEFINE _generate_order. ms_match-token = &1. ms_match-offset = &2. ms_match-length = &3. ms_match-text_tag = &4. - APPEND ms_match to mt_after_order. - END-OF-DEFINITION. + append ms_match to mt_after_order. + END-OF-DEFINITION. " _generate_order + + DEFINE _generate_extend. + ms_match-token = &1. + ms_match-offset = &2. + ms_match-length = &3. + ms_match-text_tag = &4. + append ms_match to mt_after_extend. + END-OF-DEFINITION. " _generate_extend METHOD setup. - CREATE OBJECT mo. CLEAR mt_after_parse. CLEAR mt_after_order. + CLEAR mt_after_extend. ENDMETHOD. " setup METHOD test. - DATA: lt_matches_act TYPE lcl_code_highlighter=>ty_match_tt. + DATA: + lt_matches_act TYPE lcl_syntax_highlighter=>ty_match_tt. + mo = lcl_syntax_highlighter=>create( iv_filename ). - lt_matches_act = mo->parse_line( iv_line ). + lt_matches_act = mo->parse_line( iv_line = iv_line ). SORT lt_matches_act BY offset. @@ -464,263 +669,352 @@ CLASS ltcl_code_highlighter1 IMPLEMENTATION. act = lt_matches_act msg = | Error during parsing: { iv_line }| ). - IF lines( mt_after_order ) > 0. - mo->order_matches( EXPORTING iv_line = iv_line - CHANGING ct_matches = lt_matches_act ). + mo->order_matches( EXPORTING iv_line = iv_line + CHANGING ct_matches = lt_matches_act ). - cl_abap_unit_assert=>assert_equals( exp = mt_after_order - act = lt_matches_act - msg = | Error during ordering: { iv_line }| ). - ENDIF. + cl_abap_unit_assert=>assert_equals( exp = mt_after_order + act = lt_matches_act + msg = | Error during ordering: { iv_line }| ). - ENDMETHOD. + mo->extend_matches( EXPORTING iv_line = iv_line + CHANGING ct_matches = lt_matches_act ). + cl_abap_unit_assert=>assert_equals( exp = mt_after_extend + act = lt_matches_act + msg = | Error during extending: { iv_line }| ). + + ENDMETHOD. "test ****************************************************** * Test parsing and ordering of comments * ****************************************************** METHOD test01. - DATA: lv_line TYPE string. + DATA: + lv_line TYPE string, + lv_filename TYPE string VALUE 'file_name.abap'. "#EC NOTEXT - lv_line = '* commented out line with key word data'. + lv_line = '* commented out line with key word data'. "#EC NOTEXT " Generate table with expected values after parsing - _generate_parse 'C' 0 1 ''. - _generate_parse 'K' 12 3 ''. - _generate_parse 'K' 16 4 ''. - _generate_parse 'K' 21 4 ''. - _generate_parse 'K' 26 3 ''. - _generate_parse 'K' 30 4 ''. - _generate_parse 'K' 35 4 ''. + _generate_parse 'C' 0 1. + _generate_parse 'K' 12 3. + _generate_parse 'K' 16 4. + _generate_parse 'K' 21 4. + _generate_parse 'K' 26 3. + _generate_parse 'K' 30 4. + _generate_parse 'K' 35 4. " Generate table with expected values after ordering _generate_order 'C' 0 39 ''. - test( lv_line ). + " Generate table with expected values after ordering + _generate_extend 'C' 0 39 ''. - ENDMETHOD. + test( iv_line = lv_line iv_filename = lv_filename ). + + ENDMETHOD. "test01 ****************************************************** * Test parsing and ordering of remainder of string * ****************************************************** METHOD test02. - DATA: lv_line TYPE string. + DATA: + lv_line TYPE string, + lv_filename TYPE string VALUE 'file_name.abap'. "#EC NOTEXT - lv_line = 'data: lv_var_name type string.'. + lv_line = 'data: lv_var_name type string.'. "#EC NOTEXT " Generate table with expected values after parsing - _generate_parse 'K' 0 4 ''. - _generate_parse 'K' 18 4 ''. + _generate_parse 'K' 0 4. + _generate_parse 'K' 18 4. " Generate table with expected values after ordering _generate_order 'K' 0 4 ''. - _generate_order 'N' 4 14 ''. _generate_order 'K' 18 4 ''. - _generate_order 'N' 22 8 ''. - test( lv_line ). + " Generate table with expected values after extending + _generate_extend 'K' 0 4 ''. + _generate_extend 'N' 4 14 ''. + _generate_extend 'K' 18 4 ''. + _generate_extend 'N' 22 8 ''. - ENDMETHOD. + test( iv_line = lv_line iv_filename = lv_filename ). + + ENDMETHOD. "test02 ****************************************************** * Test parsing and ordering of key words & texts * ****************************************************** METHOD test03. - DATA: lv_line TYPE string. + DATA: + lv_line TYPE string, + lv_filename TYPE string VALUE 'file_name.abap'. "#EC NOTEXT - lv_line = 'call function ''FM_NAME''. " Commented'. + + lv_line = 'call function ''FM_NAME''. " Commented'. "#EC NOTEXT " Generate table with expected values after parsing - _generate_parse 'K' 0 4 ''. - _generate_parse 'K' 5 8 ''. - _generate_parse 'T' 14 1 ''''. - _generate_parse 'T' 22 1 ''''. - _generate_parse 'C' 25 1 ''. + _generate_parse 'K' 0 4. + _generate_parse 'K' 5 8. + _generate_parse 'T' 14 1. + _generate_parse 'T' 22 1. + _generate_parse 'C' 25 1. " Generate table with expected values after ordering _generate_order 'K' 0 4 ''. - _generate_order 'N' 4 1 ''. _generate_order 'K' 5 8 ''. - _generate_order 'N' 13 1 ''. _generate_order 'T' 14 9 ''''. - _generate_order 'N' 23 2 ''. _generate_order 'C' 25 11 ''. - test( lv_line ). + " Generate table with expected values after extending + _generate_extend 'K' 0 4 ''. + _generate_extend 'N' 4 1 ''. + _generate_extend 'K' 5 8 ''. + _generate_extend 'N' 13 1 ''. + _generate_extend 'T' 14 9 ''''. + _generate_extend 'N' 23 2 ''. + _generate_extend 'C' 25 11 ''. - ENDMETHOD. + test( iv_line = lv_line iv_filename = lv_filename ). + + ENDMETHOD. "test03 ****************************************************** * Test parsing and ordering of key words in texts * ****************************************************** METHOD test04. - DATA: lv_line TYPE string. + DATA: + lv_line TYPE string, + lv_filename TYPE string VALUE 'file_name.abap'. "#EC NOTEXT - lv_line = 'constants: lc_var type string value ''simpletext data simpletext''.'. + lv_line = 'constants: lc_var type string value ''simpletext data simpletext''.'. "#EC NOTEXT " Generate table with expected values after parsing - _generate_parse 'K' 0 9 ''. - _generate_parse 'K' 18 4 ''. - _generate_parse 'K' 30 5 ''. - _generate_parse 'T' 36 1 ''''. - _generate_parse 'K' 48 4 ''. - _generate_parse 'T' 63 1 ''''. + _generate_parse 'K' 0 9. + _generate_parse 'K' 18 4. + _generate_parse 'K' 30 5. + _generate_parse 'T' 36 1. + _generate_parse 'K' 48 4. + _generate_parse 'T' 63 1. " Generate table with expected values after ordering _generate_order 'K' 0 9 ''. - _generate_order 'N' 9 9 ''. _generate_order 'K' 18 4 ''. - _generate_order 'N' 22 8 ''. _generate_order 'K' 30 5 ''. - _generate_order 'N' 35 1 ''. _generate_order 'T' 36 28 ''''. - _generate_order 'N' 64 1 ''. - test( lv_line ). + " Generate table with expected values after ordering + _generate_extend 'K' 0 9 ''. + _generate_extend 'N' 9 9 ''. + _generate_extend 'K' 18 4 ''. + _generate_extend 'N' 22 8 ''. + _generate_extend 'K' 30 5 ''. + _generate_extend 'N' 35 1 ''. + _generate_extend 'T' 36 28 ''''. + _generate_extend 'N' 64 1 ''. - ENDMETHOD. + test( iv_line = lv_line iv_filename = lv_filename ). + + ENDMETHOD. "test04 ****************************************************** * Test parsing and ordering texts in curly brackets * ****************************************************** METHOD test05. - DATA: lv_line TYPE string. + DATA: + lv_line TYPE string, + lv_filename TYPE string VALUE 'file_name.abap'. "#EC NOTEXT - lv_line = 'a = |{ b }={ c }|.'. + lv_line = 'a = |{ b }={ c }|.'. "#EC NOTEXT " Generate table with expected values after parsing - _generate_parse 'T' 4 1 '|'. - _generate_parse 'T' 5 1 '{'. - _generate_parse 'T' 9 1 '}'. - _generate_parse 'T' 11 1 '{'. - _generate_parse 'K' 13 1 ''. - _generate_parse 'T' 15 1 '}'. - _generate_parse 'T' 16 1 '|'. + _generate_parse 'T' 4 1. + _generate_parse 'T' 5 1. + _generate_parse 'T' 9 1. + _generate_parse 'T' 11 1. + _generate_parse 'K' 13 1. + _generate_parse 'T' 15 1. + _generate_parse 'T' 16 1. " Generate table with expected values after ordering - _generate_order 'N' 0 4 ''. _generate_order 'T' 4 1 '|'. - _generate_order 'N' 5 5 ''. _generate_order 'T' 10 1 '}'. - _generate_order 'N' 11 2 ''. _generate_order 'K' 13 1 ''. - _generate_order 'N' 14 2 ''. _generate_order 'T' 16 1 '}'. - _generate_order 'N' 17 1 ''. - test( lv_line ). + " Generate table with expected values after extending + _generate_extend 'N' 0 4 ''. + _generate_extend 'T' 4 1 '|'. + _generate_extend 'N' 5 5 ''. + _generate_extend 'T' 10 1 '}'. + _generate_extend 'N' 11 2 ''. + _generate_extend 'K' 13 1 ''. + _generate_extend 'N' 14 2 ''. + _generate_extend 'T' 16 1 '}'. + _generate_extend 'N' 17 1 ''. - ENDMETHOD. + test( iv_line = lv_line iv_filename = lv_filename ). + + ENDMETHOD. "test05 ****************************************************** * Test parsing and ordering of texts * ****************************************************** METHOD test06. - DATA: lv_line TYPE string. + DATA: + lv_line TYPE string, + lv_filename TYPE string VALUE 'file_name.abap'. "#EC NOTEXT - lv_line = 'lv_line = lc_constant && |XYZ { ''ab'' && |ac{ ''UU'' }| }|'. + lv_line = 'lv_line = lc_constant && |XYZ { ''ab'' && |ac{ ''UU'' }| }|'. "#EC NOTEXT " Generate table with expected values after parsing - _generate_parse 'K' 22 2 ''. - _generate_parse 'T' 25 1 '|'. - _generate_parse 'T' 30 1 '{'. - _generate_parse 'T' 32 1 ''''. - _generate_parse 'T' 35 1 ''''. - _generate_parse 'K' 37 2 ''. - _generate_parse 'T' 40 1 '|'. - _generate_parse 'T' 43 1 '{'. - _generate_parse 'T' 45 1 ''''. - _generate_parse 'T' 48 1 ''''. - _generate_parse 'T' 50 1 '}'. - _generate_parse 'T' 51 1 '|'. - _generate_parse 'T' 53 1 '}'. - _generate_parse 'T' 54 1 '|'. + _generate_parse 'K' 22 2. + _generate_parse 'T' 25 1. + _generate_parse 'T' 30 1. + _generate_parse 'T' 32 1. + _generate_parse 'T' 35 1. + _generate_parse 'K' 37 2. + _generate_parse 'T' 40 1. + _generate_parse 'T' 43 1. + _generate_parse 'T' 45 1. + _generate_parse 'T' 48 1. + _generate_parse 'T' 50 1. + _generate_parse 'T' 51 1. + _generate_parse 'T' 53 1. + _generate_parse 'T' 54 1. " Generate table with expected values after ordering - _generate_order 'N' 00 22 ''. _generate_order 'K' 22 2 ''. - _generate_order 'N' 24 1 ''. _generate_order 'T' 25 5 '|'. - _generate_order 'N' 30 2 ''. _generate_order 'T' 32 4 ''''. - _generate_order 'N' 36 1 ''. _generate_order 'K' 37 2 ''. - _generate_order 'N' 39 1 ''. _generate_order 'T' 40 3 '|'. - _generate_order 'N' 43 2 ''. _generate_order 'T' 45 4 ''''. - _generate_order 'N' 49 2 ''. _generate_order 'T' 51 1 '}'. - _generate_order 'N' 52 2 ''. _generate_order 'T' 54 1 '}'. - test( lv_line ). + " Generate table with expected values after extending + _generate_extend 'N' 00 22 ''. + _generate_extend 'K' 22 2 ''. + _generate_extend 'N' 24 1 ''. + _generate_extend 'T' 25 5 '|'. + _generate_extend 'N' 30 2 ''. + _generate_extend 'T' 32 4 ''''. + _generate_extend 'N' 36 1 ''. + _generate_extend 'K' 37 2 ''. + _generate_extend 'N' 39 1 ''. + _generate_extend 'T' 40 3 '|'. + _generate_extend 'N' 43 2 ''. + _generate_extend 'T' 45 4 ''''. + _generate_extend 'N' 49 2 ''. + _generate_extend 'T' 51 1 '}'. + _generate_extend 'N' 52 2 ''. + _generate_extend 'T' 54 1 '}'. - ENDMETHOD. + test( iv_line = lv_line iv_filename = lv_filename ). + ENDMETHOD. "test06 + +******************************************************** +* Check that '*' in select statement is not a match * +******************************************************** METHOD test07. - DATA: lv_line TYPE string. + DATA: + lv_line TYPE string, + lv_filename TYPE string VALUE 'file_name.abap'. "#EC NOTEXT - lv_line = 'SELECT * FROM foo'. + lv_line = 'SELECT * FROM foo'. "#EC NOTEXT " Generate table with expected values after parsing - _generate_parse 'K' 0 6 ''. - _generate_parse 'K' 9 4 ''. + _generate_parse 'K' 0 6. + _generate_parse 'K' 9 4. - test( lv_line ). + " Generate table with expected values after ordering + _generate_order 'K' 0 6 ''. + _generate_order 'K' 9 4 ''. - ENDMETHOD. + " Generate table with expected values after ordering + _generate_extend 'K' 0 6 ''. + _generate_extend 'N' 6 3 ''. + _generate_extend 'K' 9 4 ''. + _generate_extend 'N' 13 4 ''. -ENDCLASS. + test( iv_line = lv_line iv_filename = lv_filename ). -CLASS ltcl_code_highlighter2 DEFINITION FINAL + ENDMETHOD. "test07 + +******************************************************** +* Test parsing and ordering of key words in structures * +******************************************************** + METHOD test08. + + DATA: + lv_line TYPE string, + lv_filename TYPE string VALUE 'file_name.abap'. "#EC NOTEXT + + lv_line = 'lv_length = -length.'. "#EC NOTEXT + + " Generate table with expected values after parsing + _generate_parse 'K' 13 5. + _generate_parse 'K' 20 6. + + " Generate table with expected values after ordering + _generate_extend 'N' 0 27 ''. + + test( iv_line = lv_line iv_filename = lv_filename ). + + ENDMETHOD. "test08 +ENDCLASS. " ltcl_syntax_highlighter1 IMPLEMENTATION + +*----------------------------------------------------------------------* +* CLASS ltcl_syntax_highlighter2 DEFINITION +*----------------------------------------------------------------------* +* +*----------------------------------------------------------------------* +CLASS ltcl_syntax_highlighter2 DEFINITION FINAL FOR TESTING RISK LEVEL HARMLESS DURATION SHORT. PRIVATE SECTION. - DATA: - mo TYPE REF TO lcl_code_highlighter. + DATA mo TYPE REF TO lcl_syntax_highlighter. - METHODS: setup. METHODS: process_line FOR TESTING. - METHODS: format_line FOR TESTING. - METHODS: apply_style FOR TESTING. + METHODS: format_line FOR TESTING. + METHODS: apply_style FOR TESTING. -ENDCLASS. " ltcl_code_highlighter +ENDCLASS. " ltcl_syntax_highlighter2 *----------------------------------------------------------------------* -* CLASS ltcl_code_highlighter IMPLEMENTATION +* CLASS ltcl_syntax_highlighter IMPLEMENTATION *----------------------------------------------------------------------* -CLASS ltcl_code_highlighter2 IMPLEMENTATION. - - - METHOD setup. - CREATE OBJECT mo. - ENDMETHOD. - +CLASS ltcl_syntax_highlighter2 IMPLEMENTATION. METHOD format_line. DATA: lv_line TYPE string, lv_line_act TYPE string, - lv_line_exp TYPE string. + lv_line_exp TYPE string, + lv_filename TYPE string VALUE 'file_name.abap'. "#EC NOTEXT. - lv_line = 'call function ''FM_NAME''. " Commented'. + " Create syntax highlighter + mo = lcl_syntax_highlighter=>create( lv_filename ). + + lv_line = 'call function ''FM_NAME''. " Commented'. "#EC NOTEXT lv_line_exp = - 'call' && - ' function' && - ' 'FM_NAME'.' && - ' " Commented'. + 'call' && "#EC NOTEXT + ' function' && "#EC NOTEXT + ' 'FM_NAME'.' && "#EC NOTEXT + ' " Commented'. "#EC NOTEXT - lv_line_act = mo->process_line( lv_line ). + lv_line_act = mo->process_line( iv_line = lv_line ). cl_abap_unit_assert=>assert_equals( exp = lv_line_exp act = lv_line_act @@ -730,34 +1024,42 @@ CLASS ltcl_code_highlighter2 IMPLEMENTATION. METHOD apply_style. DATA: - lv_line_act TYPE string. + lv_line_act TYPE string, + lv_filename TYPE string VALUE 'file_name.abap'. "#EC NOTEXT. + + " Create syntax highlighter + mo = lcl_syntax_highlighter=>create( lv_filename ). " Call the method and compare results - lv_line_act = mo->apply_style( iv_line = 'CALL FUNCTION' - iv_class = lcl_code_highlighter=>c_css-keyword ). + lv_line_act = mo->apply_style( iv_line = 'CALL FUNCTION' "#EC NOTEXT + iv_class = lcl_syntax_highlighter=>c_css-keyword ). cl_abap_unit_assert=>assert_equals( act = lv_line_act - exp = 'CALL FUNCTION' - msg = 'Failure during applying of style.' ). + exp = 'CALL FUNCTION' "#EC NOTEXT + msg = 'Failure during applying of style.' ). "#EC NOTEXT ENDMETHOD. " apply_style METHOD process_line. DATA: - lv_line_act TYPE string. + lv_line_act TYPE string, + lv_filename TYPE string VALUE 'file_name.abap'. "#EC NOTEXT. + + " Create syntax highlighter + mo = lcl_syntax_highlighter=>create( lv_filename ). " Call the method with empty parameter and compare results lv_line_act = mo->process_line( iv_line = '' ). cl_abap_unit_assert=>assert_equals( act = lv_line_act exp = '' - msg = 'Failure in method process_line.' ). + msg = 'Failure in method process_line.' ). "#EC NOTEXT " Call the method with non-empty line and compare results - lv_line_act = mo->process_line( iv_line = '* CALL FUNCTION' ). + lv_line_act = mo->process_line( iv_line = '* CALL FUNCTION' ). "#EC NOTEXT cl_abap_unit_assert=>assert_equals( act = lv_line_act - exp = '* CALL FUNCTION' - msg = 'Failure in method process_line.' ). + exp = '* CALL FUNCTION' "#EC NOTEXT + msg = 'Failure in method process_line.' ). "#EC NOTEXT ENDMETHOD. " process_line -ENDCLASS. " ltcl_code_highlighter \ No newline at end of file +ENDCLASS. " ltcl_syntax_highlighter \ No newline at end of file From b509a3e11fae45f3368cf63b021ad9bae9e8685c Mon Sep 17 00:00:00 2001 From: TheWirtschaftsmann Date: Wed, 14 Dec 2016 17:57:31 +0200 Subject: [PATCH 2/4] Xml syntax - part2 #443 * code style adjustments * styles & small fixes * Refactoring of XML-parser --- src/zabapgit_css_common.w3mi.data.css | 3 + src/zabapgit_syntax_highlighter.prog.abap | 659 +++++++++++++--------- 2 files changed, 405 insertions(+), 257 deletions(-) diff --git a/src/zabapgit_css_common.w3mi.data.css b/src/zabapgit_css_common.w3mi.data.css index f81327870..924b1d664 100644 --- a/src/zabapgit_css_common.w3mi.data.css +++ b/src/zabapgit_css_common.w3mi.data.css @@ -503,6 +503,9 @@ table.diff_tab code { table.diff_tab code span.keyword { color: #0a69ce; } table.diff_tab code span.text { color: #48ce4f; } table.diff_tab code span.comment { color: #808080; font-style: italic; } +table.diff_tab code span.xml_tag { color: #3370e0; } +table.diff_tab code span.attr { color: #f20707; } +table.diff_tab code span.attr_val { color: #7a02f9; } table.diff_tab tbody tr:first-child td { padding-top: 0.5em; } table.diff_tab tbody tr:last-child td { padding-bottom: 0.5em; } diff --git a/src/zabapgit_syntax_highlighter.prog.abap b/src/zabapgit_syntax_highlighter.prog.abap index 718357b6c..65f8b1601 100644 --- a/src/zabapgit_syntax_highlighter.prog.abap +++ b/src/zabapgit_syntax_highlighter.prog.abap @@ -5,8 +5,8 @@ *& Class lcl_syntax_highligher *&---------------------------------------------------------------------* -CLASS ltcl_syntax_highlighter1 DEFINITION DEFERRED. -CLASS ltcl_syntax_highlighter2 DEFINITION DEFERRED. +CLASS ltcl_syntax_cases DEFINITION DEFERRED. +CLASS ltcl_syntax_basic_logic DEFINITION DEFERRED. CLASS lcl_syntax_abap DEFINITION DEFERRED. CLASS lcl_syntax_xml DEFINITION DEFERRED. @@ -15,9 +15,10 @@ CLASS lcl_syntax_xml DEFINITION DEFERRED. * CLASS lcl_syntax_highlighter DEFINITION *----------------------------------------------------------------------* CLASS lcl_syntax_highlighter DEFINITION ABSTRACT - FRIENDS ltcl_syntax_highlighter1 ltcl_syntax_highlighter2. + FRIENDS ltcl_syntax_cases ltcl_syntax_basic_logic. PUBLIC SECTION. + CLASS-METHODS create IMPORTING iv_filename TYPE string RETURNING VALUE(ro_instance) TYPE REF TO lcl_syntax_highlighter. @@ -27,6 +28,7 @@ CLASS lcl_syntax_highlighter DEFINITION ABSTRACT RETURNING VALUE(rv_line) TYPE string. PROTECTED SECTION. + TYPES: BEGIN OF ty_match, token TYPE char1, " Type of matches @@ -39,74 +41,37 @@ CLASS lcl_syntax_highlighter DEFINITION ABSTRACT ty_match_tt TYPE STANDARD TABLE OF ty_match WITH DEFAULT KEY. TYPES: - BEGIN OF ty_regex, + BEGIN OF ty_rule, regex TYPE REF TO cl_abap_regex, token TYPE char1, - END OF ty_regex. + style TYPE string, + END OF ty_rule. - TYPES: - BEGIN OF ty_style_map, - token TYPE char1, - style TYPE string, - END OF ty_style_map. + CONSTANTS c_token_none TYPE c VALUE '.'. - CONSTANTS: - BEGIN OF c_css, - keyword TYPE string VALUE 'keyword', "#EC NOTEXT - text TYPE string VALUE 'text', "#EC NOTEXT - comment TYPE string VALUE 'comment', "#EC NOTEXT - xml_tag TYPE string VALUE 'xml_tag', "#EC NOTEXT - attr TYPE string VALUE 'attr', "#EC NOTEXT - attr_val TYPE string VALUE 'attr_val', "#EC NOTEXT - none TYPE string VALUE 'none', "#EC NOTEXT - END OF c_css. - - CONSTANTS: - BEGIN OF c_token, - keyword TYPE c VALUE 'K', "#EC NOTEXT - text TYPE c VALUE 'T', "#EC NOTEXT - comment TYPE c VALUE 'C', "#EC NOTEXT - xml_tag TYPE c VALUE 'X', "#EC NOTEXT - attr TYPE c VALUE 'A', "#EC NOTEXT - attr_val TYPE c VALUE 'V', "#EC NOTEXT - none TYPE c VALUE 'N', "#EC NOTEXT - END OF c_token. - - CLASS-DATA: - BEGIN OF c_regex, - comment TYPE string, - text TYPE string, - keyword TYPE string, - xml_tag TYPE string, - attr TYPE string, - attr_val TYPE string, - END OF c_regex. - - CLASS-DATA: - mo_regex_table TYPE TABLE OF ty_regex, - mo_style_map TYPE TABLE OF ty_style_map. + DATA mt_rules TYPE STANDARD TABLE OF ty_rule. METHODS parse_line - IMPORTING iv_line TYPE string - RETURNING VALUE(rt_matches) TYPE ty_match_tt. + IMPORTING iv_line TYPE string + RETURNING VALUE(rt_matches) TYPE ty_match_tt. METHODS order_matches ABSTRACT - IMPORTING iv_line TYPE string - CHANGING ct_matches TYPE ty_match_tt. + IMPORTING iv_line TYPE string + CHANGING ct_matches TYPE ty_match_tt. METHODS extend_matches - IMPORTING iv_line TYPE string - CHANGING ct_matches TYPE ty_match_tt. + IMPORTING iv_line TYPE string + CHANGING ct_matches TYPE ty_match_tt. METHODS format_line - IMPORTING iv_line TYPE string - it_matches TYPE ty_match_tt - RETURNING VALUE(rv_line) TYPE string. + IMPORTING iv_line TYPE string + it_matches TYPE ty_match_tt + RETURNING VALUE(rv_line) TYPE string. METHODS apply_style - IMPORTING iv_line TYPE string - iv_class TYPE string - RETURNING VALUE(rv_line) TYPE string. + IMPORTING iv_line TYPE string + iv_class TYPE string + RETURNING VALUE(rv_line) TYPE string. ENDCLASS. " lcl_syntax_highlighter DEFINITION @@ -115,13 +80,40 @@ ENDCLASS. " lcl_syntax_highlighter DEFINITION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* -CLASS lcl_syntax_abap DEFINITION INHERITING FROM lcl_syntax_highlighter. +CLASS lcl_syntax_abap DEFINITION INHERITING FROM lcl_syntax_highlighter FINAL. PUBLIC SECTION. - CLASS-METHODS class_constructor. + + CLASS-METHODS class_constructor. + METHODS constructor. + + CONSTANTS: + BEGIN OF c_css, + keyword TYPE string VALUE 'keyword', "#EC NOTEXT + text TYPE string VALUE 'text', "#EC NOTEXT + comment TYPE string VALUE 'comment', "#EC NOTEXT + END OF c_css. + + CONSTANTS: + BEGIN OF c_token, + keyword TYPE c VALUE 'K', "#EC NOTEXT + text TYPE c VALUE 'T', "#EC NOTEXT + comment TYPE c VALUE 'C', "#EC NOTEXT + END OF c_token. PROTECTED SECTION. - CLASS-METHODS get_keywords RETURNING VALUE(rv_string) TYPE string. + + CLASS-DATA: + c_keyword_regex TYPE REF TO cl_abap_regex, " Temporary + BEGIN OF c_regex, + comment TYPE string, + text TYPE string, + keyword TYPE string, + END OF c_regex. + + CLASS-METHODS get_keywords + RETURNING VALUE(rv_string) TYPE string. + METHODS order_matches REDEFINITION. ENDCLASS. " lcl_syntax_abap DEFINITION @@ -131,11 +123,35 @@ ENDCLASS. " lcl_syntax_abap DEFINITION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* -CLASS lcl_syntax_xml DEFINITION INHERITING FROM lcl_syntax_highlighter. +CLASS lcl_syntax_xml DEFINITION INHERITING FROM lcl_syntax_highlighter FINAL. + PUBLIC SECTION. - CLASS-METHODS class_constructor. + + METHODS constructor. + + CONSTANTS: + BEGIN OF c_css, + xml_tag TYPE string VALUE 'xml_tag', "#EC NOTEXT + attr TYPE string VALUE 'attr', "#EC NOTEXT + attr_val TYPE string VALUE 'attr_val', "#EC NOTEXT + END OF c_css. + + CONSTANTS: + BEGIN OF c_token, + xml_tag TYPE c VALUE 'X', "#EC NOTEXT + attr TYPE c VALUE 'A', "#EC NOTEXT + attr_val TYPE c VALUE 'V', "#EC NOTEXT + END OF c_token. PROTECTED SECTION. + + CLASS-DATA: + BEGIN OF c_regex, + xml_tag TYPE string, + attr TYPE string, + attr_val TYPE string, + END OF c_regex. + METHODS order_matches REDEFINITION. ENDCLASS. " lcl_syntax_xml DEFINITION @@ -144,34 +160,25 @@ ENDCLASS. " lcl_syntax_xml DEFINITION * Macros to fill table with a regular expressions to be parsed *----------------------------------------------------------------------* -DEFINE _add_regex. +DEFINE _add_rule. - CREATE OBJECT ls_regex_table-regex + CREATE OBJECT ls_rule-regex EXPORTING pattern = c_regex-&1 ignore_case = abap_true. - ls_regex_table-token = c_token-&1. - APPEND ls_regex_table TO mo_regex_table. + ls_rule-token = c_token-&1. + ls_rule-style = c_css-&1. + APPEND ls_rule TO mt_rules. -END-OF-DEFINITION. " _add_regex +END-OF-DEFINITION. " _add_rule -*----------------------------------------------------------------------* -* Macros to fill table with mapping of tokens against CSS-styles -*----------------------------------------------------------------------* - -DEFINE _add_style_mapping. - - ls_style_map-token = c_token-&1. - ls_style_map-style = c_css-&1. - APPEND ls_style_map TO mo_style_map. - -END-OF-DEFINITION. " _add_style_mapping *----------------------------------------------------------------------* * CLASS lcl_syntax_highlighter IMPLEMENTATION *----------------------------------------------------------------------* * Implementation of syntax highligther for ABAP source code *----------------------------------------------------------------------* + CLASS lcl_syntax_highlighter IMPLEMENTATION. METHOD create. @@ -196,12 +203,12 @@ CLASS lcl_syntax_highlighter IMPLEMENTATION. ls_match TYPE ty_match. FIELD-SYMBOLS: - TYPE ty_regex, + LIKE LINE OF mt_rules, TYPE match_result, TYPE ty_match. " Process syntax-dependent regex table and find all matches - LOOP AT mo_regex_table ASSIGNING . + LOOP AT mt_rules ASSIGNING . lo_regex = -regex. lo_matcher = lo_regex->create_matcher( text = iv_line ). lt_result = lo_matcher->find_all( ). @@ -219,6 +226,7 @@ CLASS lcl_syntax_highlighter IMPLEMENTATION. ENDMETHOD. " parse_line METHOD extend_matches. + DATA: lv_line_len TYPE i, lv_last_pos TYPE i VALUE 0, @@ -229,11 +237,13 @@ CLASS lcl_syntax_highlighter IMPLEMENTATION. lv_line_len = strlen( iv_line ). + SORT ct_matches BY offset. + " Add entries refering to parts of text that should not be formatted LOOP AT ct_matches ASSIGNING . IF -offset > lv_last_pos. lv_length = -offset - lv_last_pos. - ls_match-token = c_token-none. + ls_match-token = c_token_none. ls_match-offset = lv_last_pos. ls_match-length = lv_length. INSERT ls_match INTO ct_matches INDEX sy-tabix. @@ -244,7 +254,7 @@ CLASS lcl_syntax_highlighter IMPLEMENTATION. " Add remainder of the string IF lv_line_len > lv_last_pos. lv_length = lv_line_len - lv_last_pos. - ls_match-token = c_token-none. + ls_match-token = c_token_none. ls_match-offset = lv_last_pos. ls_match-length = lv_length. APPEND ls_match TO ct_matches. @@ -255,25 +265,19 @@ CLASS lcl_syntax_highlighter IMPLEMENTATION. METHOD format_line. DATA: - lv_chunk TYPE string, - lv_css_class TYPE string, - ls_style_map TYPE ty_style_map. + lv_chunk TYPE string, + ls_rule LIKE LINE OF mt_rules. FIELD-SYMBOLS TYPE ty_match. LOOP AT it_matches ASSIGNING . lv_chunk = substring( val = iv_line off = -offset len = -length ). - READ TABLE mo_style_map INTO ls_style_map WITH KEY token = -token. - - IF sy-subrc IS INITIAL. - lv_css_class = ls_style_map-style. - ELSE. - CLEAR: lv_css_class. - ENDIF. + CLEAR ls_rule. " Failed read equals no style + READ TABLE mt_rules INTO ls_rule WITH KEY token = -token. lv_chunk = me->apply_style( iv_line = lv_chunk - iv_class = lv_css_class ). + iv_class = ls_rule-style ). rv_line = rv_line && lv_chunk. ENDLOOP. @@ -321,31 +325,40 @@ ENDCLASS. " lcl_syntax_highlighter IMPLEMENTATION *----------------------------------------------------------------------* * Implementation of syntax highligther for XML source code *----------------------------------------------------------------------* + CLASS lcl_syntax_abap IMPLEMENTATION. METHOD class_constructor. - DATA: - ls_regex_table TYPE ty_regex, - ls_style_map TYPE ty_style_map. - - " Declare regular expressions' constants - c_regex-comment = '##|"|^\*'. "#EC NOTEXT - c_regex-text = '`|''|\||\{|\}'. "#EC NOTEXT - c_regex-keyword = '&&|\b(' && get_keywords( ) && ')\b'. "#EC NOTEXT - - " Initialize instances of regular expressions - _add_regex keyword. - _add_regex comment. - _add_regex text. - - " Initialize mapping of tokens and CSS-styles - _add_style_mapping keyword. - _add_style_mapping comment. - _add_style_mapping text. + CREATE OBJECT c_keyword_regex + EXPORTING + pattern = '&&|\b(' && get_keywords( ) && ')\b' + ignore_case = abap_true. ENDMETHOD. " class_constructor + METHOD constructor. + + DATA ls_rule LIKE LINE OF mt_rules. + + super->constructor( ). + + " Declare regular expressions' constants + c_regex-comment = '##|"|^\*'. "#EC NOTEXT + c_regex-text = '`|''|\||\{|\}'. "#EC NOTEXT + + " Initialize instances of regular expression + _add_rule comment. + _add_rule text. + + " Temporary + ls_rule-regex = c_keyword_regex. + ls_rule-token = c_token-keyword. + ls_rule-style = c_css-keyword. + APPEND ls_rule TO mt_rules. + + ENDMETHOD. " constructor + METHOD get_keywords. rv_string = @@ -426,7 +439,7 @@ CLASS lcl_syntax_abap IMPLEMENTATION. '|SAVING|SCALE_PRESERVING|SCALE_PRESERVING_SCIENTIFIC|SCAN|SCIENTIFIC|SCIENTIFIC_WITH_LEADING_ZERO' && '|SCREEN|SCROLL|SCROLL-BOUNDARY|SCROLLING|SEARCH|SECONDARY|SECONDS|SECTION|SELECT|SELECTION' && '|SELECTIONS|SELECTION-SCREEN|SELECTION-SET|SELECTION-SETS|SELECTION-TABLE|SELECT-OPTIONS' && - '|SELECTOR|SELECTOR|SEND|SEPARATE|SEPARATED|SET|SHARED|SHIFT|SHORT|SHORTDUMP-ID|SIGN' && + '|SELECTOR|SEND|SEPARATE|SEPARATED|SET|SHARED|SHIFT|SHORT|SHORTDUMP-ID|SIGN' && '|SIGN_AS_POSTFIX|SIMPLE|SIN|SINGLE|SINH|SIZE|SKIP|SKIPPING|SMART|SOME|SORT|SORTABLE' && '|SORTED|SOURCE|SPACE|SPECIFIED|SPLIT|SPOOL|SPOTS|SQL|SQLSCRIPT|SQRT|STABLE|STAMP' && '|STANDARD|STARTING|START-OF-SELECTION|STATE|STATEMENT|STATEMENTS|STATIC|STATICS|STATUSINFO' && @@ -443,6 +456,7 @@ CLASS lcl_syntax_abap IMPLEMENTATION. '|VARY|VARYING|VERIFICATION-MESSAGE|VERSION|VIA|VIEW|VISIBLE|WAIT|WARNING|WHEN|WHENEVER' && '|WHERE|WHILE|WIDTH|WINDOW|WINDOWS|WITH|WITH-HEADING|WITHOUT|WITH-TITLE|WORD|WORK' && '|WRITE|WRITER|X|XML|XOR|XSD|XSTRLEN|YELLOW|YES|YYMMDD|Z|ZERO|ZONE'. + ENDMETHOD. " get_keywords. METHOD order_matches. @@ -478,10 +492,12 @@ CLASS lcl_syntax_abap IMPLEMENTATION. CONTINUE. ENDIF. ENDIF. + WHEN c_token-comment. -length = lv_line_len - -offset. DELETE ct_matches FROM lv_index + 1. CONTINUE. + WHEN c_token-text. -text_tag = substring( val = iv_line off = -offset len = -length ). IF lv_prev_token = c_token-text. @@ -503,12 +519,15 @@ CLASS lcl_syntax_abap IMPLEMENTATION. DELETE ct_matches INDEX lv_index. CONTINUE. ENDIF. + ENDCASE. lv_prev_token = -token. ASSIGN TO . ENDLOOP. + ENDMETHOD. " order_matches. + ENDCLASS. " lcl_syntax_abap IMPLEMENTATION *----------------------------------------------------------------------* @@ -517,29 +536,26 @@ ENDCLASS. " lcl_syntax_abap IMPLEMENTATION * *----------------------------------------------------------------------* CLASS lcl_syntax_xml IMPLEMENTATION. - METHOD class_constructor. - DATA: - ls_regex_table TYPE ty_regex, - ls_style_map TYPE ty_style_map. + METHOD constructor. - c_regex-xml_tag = '[<>]'. "#EC NOTEXT - c_regex-attr = '\s[a-z:]+\s*(?==)'. "#EC NOTEXT - c_regex-attr_val = '["''][^''"]+[''"]'. "#EC NOTEXT + DATA ls_rule LIKE LINE OF mt_rules. + + super->constructor( ). + + c_regex-xml_tag = '[<>]'. "#EC NOTEXT + c_regex-attr = '\s[-a-z:_0-9]+\s*(?==)'. "#EC NOTEXT + c_regex-attr_val = '["''][^''"]+[''"]'. "#EC NOTEXT " Initialize instances of regular expressions - _add_regex xml_tag. - _add_regex attr. - _add_regex attr_val. - - " Initialize mapping of tokens and CSS-styles - _add_style_mapping xml_tag. - _add_style_mapping attr. - _add_style_mapping attr_val. + _add_rule xml_tag. + _add_rule attr. + _add_rule attr_val. ENDMETHOD. METHOD order_matches. + DATA: lv_index TYPE sy-tabix, lv_line_len TYPE i, @@ -582,48 +598,54 @@ CLASS lcl_syntax_xml IMPLEMENTATION. DELETE ct_matches INDEX lv_index. CONTINUE. ENDIF. + ENDCASE. lv_prev_token = -token. ASSIGN TO . ENDLOOP. + ENDMETHOD. " order_matches + ENDCLASS. " lcl_syntax_xml IMPLEMENTATION *----------------------------------------------------------------------* -* CLASS ltcl_syntax_highlighter1 definition +* CLASS ltcl_syntax_cases definition *----------------------------------------------------------------------* -CLASS ltcl_syntax_highlighter1 DEFINITION FINAL +CLASS ltcl_syntax_cases DEFINITION FINAL FOR TESTING RISK LEVEL HARMLESS DURATION SHORT. PRIVATE SECTION. DATA: - mo TYPE REF TO lcl_syntax_highlighter, mt_after_parse TYPE lcl_syntax_highlighter=>ty_match_tt, mt_after_order TYPE lcl_syntax_highlighter=>ty_match_tt, mt_after_extend TYPE lcl_syntax_highlighter=>ty_match_tt, ms_match TYPE lcl_syntax_highlighter=>ty_match. METHODS: - setup, - test IMPORTING iv_line TYPE string - iv_filename TYPE string - RETURNING VALUE(ro_instance) TYPE REF TO lcl_syntax_highlighter, - test01 FOR TESTING, - test02 FOR TESTING, - test03 FOR TESTING, - test04 FOR TESTING, - test05 FOR TESTING, - test06 FOR TESTING, - test07 FOR TESTING, - test08 FOR TESTING. + do_test IMPORTING iv_line TYPE string + iv_filename TYPE string + RETURNING VALUE(ro_instance) TYPE REF TO lcl_syntax_highlighter, + test_abap_01 FOR TESTING, + test_abap_02 FOR TESTING, + test_abap_03 FOR TESTING, + test_abap_04 FOR TESTING, + test_abap_05 FOR TESTING, + test_abap_06 FOR TESTING, + test_abap_07 FOR TESTING, + test_abap_08 FOR TESTING, + test_xml_01 FOR TESTING, + test_xml_02 FOR TESTING, + test_xml_03 FOR TESTING, + test_xml_04 FOR TESTING, + test_xml_05 FOR TESTING. -ENDCLASS. " ltcl_syntax_highlighter1 +ENDCLASS. " ltcl_syntax_cases *----------------------------------------------------------------------* -* CLASS ltcl_syntax_highlighter1 IMPLEMENTATION +* CLASS ltcl_syntax_cases IMPLEMENTATION *----------------------------------------------------------------------* -CLASS ltcl_syntax_highlighter1 IMPLEMENTATION. +CLASS ltcl_syntax_cases IMPLEMENTATION. DEFINE _generate_parse. ms_match-token = &1. @@ -648,20 +670,14 @@ CLASS ltcl_syntax_highlighter1 IMPLEMENTATION. append ms_match to mt_after_extend. END-OF-DEFINITION. " _generate_extend - METHOD setup. - CLEAR mt_after_parse. - CLEAR mt_after_order. - CLEAR mt_after_extend. - ENDMETHOD. " setup + METHOD do_test. - METHOD test. + DATA: lt_matches_act TYPE lcl_syntax_highlighter=>ty_match_tt, + lo TYPE REF TO lcl_syntax_highlighter. - DATA: - lt_matches_act TYPE lcl_syntax_highlighter=>ty_match_tt. - mo = lcl_syntax_highlighter=>create( iv_filename ). - - lt_matches_act = mo->parse_line( iv_line = iv_line ). + lo = lcl_syntax_highlighter=>create( iv_filename ). + lt_matches_act = lo->parse_line( iv_line = iv_line ). SORT lt_matches_act BY offset. @@ -669,15 +685,15 @@ CLASS ltcl_syntax_highlighter1 IMPLEMENTATION. act = lt_matches_act msg = | Error during parsing: { iv_line }| ). - mo->order_matches( EXPORTING iv_line = iv_line + lo->order_matches( EXPORTING iv_line = iv_line CHANGING ct_matches = lt_matches_act ). cl_abap_unit_assert=>assert_equals( exp = mt_after_order act = lt_matches_act msg = | Error during ordering: { iv_line }| ). - mo->extend_matches( EXPORTING iv_line = iv_line - CHANGING ct_matches = lt_matches_act ). + lo->extend_matches( EXPORTING iv_line = iv_line + CHANGING ct_matches = lt_matches_act ). cl_abap_unit_assert=>assert_equals( exp = mt_after_extend act = lt_matches_act @@ -688,11 +704,9 @@ CLASS ltcl_syntax_highlighter1 IMPLEMENTATION. ****************************************************** * Test parsing and ordering of comments * ****************************************************** - METHOD test01. + METHOD test_abap_01. - DATA: - lv_line TYPE string, - lv_filename TYPE string VALUE 'file_name.abap'. "#EC NOTEXT + DATA lv_line TYPE string. lv_line = '* commented out line with key word data'. "#EC NOTEXT @@ -711,18 +725,16 @@ CLASS ltcl_syntax_highlighter1 IMPLEMENTATION. " Generate table with expected values after ordering _generate_extend 'C' 0 39 ''. - test( iv_line = lv_line iv_filename = lv_filename ). + do_test( iv_line = lv_line iv_filename = '*.abap' ). - ENDMETHOD. "test01 + ENDMETHOD. " test_abap_01 ****************************************************** * Test parsing and ordering of remainder of string * ****************************************************** - METHOD test02. + METHOD test_abap_02. - DATA: - lv_line TYPE string, - lv_filename TYPE string VALUE 'file_name.abap'. "#EC NOTEXT + DATA lv_line TYPE string. lv_line = 'data: lv_var_name type string.'. "#EC NOTEXT @@ -736,22 +748,20 @@ CLASS ltcl_syntax_highlighter1 IMPLEMENTATION. " Generate table with expected values after extending _generate_extend 'K' 0 4 ''. - _generate_extend 'N' 4 14 ''. + _generate_extend '.' 4 14 ''. _generate_extend 'K' 18 4 ''. - _generate_extend 'N' 22 8 ''. + _generate_extend '.' 22 8 ''. - test( iv_line = lv_line iv_filename = lv_filename ). + do_test( iv_line = lv_line iv_filename = '*.abap' ). - ENDMETHOD. "test02 + ENDMETHOD. " test_abap_02 ****************************************************** * Test parsing and ordering of key words & texts * ****************************************************** - METHOD test03. + METHOD test_abap_03. - DATA: - lv_line TYPE string, - lv_filename TYPE string VALUE 'file_name.abap'. "#EC NOTEXT + DATA lv_line TYPE string. lv_line = 'call function ''FM_NAME''. " Commented'. "#EC NOTEXT @@ -771,25 +781,23 @@ CLASS ltcl_syntax_highlighter1 IMPLEMENTATION. " Generate table with expected values after extending _generate_extend 'K' 0 4 ''. - _generate_extend 'N' 4 1 ''. + _generate_extend '.' 4 1 ''. _generate_extend 'K' 5 8 ''. - _generate_extend 'N' 13 1 ''. + _generate_extend '.' 13 1 ''. _generate_extend 'T' 14 9 ''''. - _generate_extend 'N' 23 2 ''. + _generate_extend '.' 23 2 ''. _generate_extend 'C' 25 11 ''. - test( iv_line = lv_line iv_filename = lv_filename ). + do_test( iv_line = lv_line iv_filename = '*.abap' ). - ENDMETHOD. "test03 + ENDMETHOD. " test_abap_03 ****************************************************** * Test parsing and ordering of key words in texts * ****************************************************** - METHOD test04. + METHOD test_abap_04. - DATA: - lv_line TYPE string, - lv_filename TYPE string VALUE 'file_name.abap'. "#EC NOTEXT + DATA lv_line TYPE string. lv_line = 'constants: lc_var type string value ''simpletext data simpletext''.'. "#EC NOTEXT @@ -809,26 +817,24 @@ CLASS ltcl_syntax_highlighter1 IMPLEMENTATION. " Generate table with expected values after ordering _generate_extend 'K' 0 9 ''. - _generate_extend 'N' 9 9 ''. + _generate_extend '.' 9 9 ''. _generate_extend 'K' 18 4 ''. - _generate_extend 'N' 22 8 ''. + _generate_extend '.' 22 8 ''. _generate_extend 'K' 30 5 ''. - _generate_extend 'N' 35 1 ''. + _generate_extend '.' 35 1 ''. _generate_extend 'T' 36 28 ''''. - _generate_extend 'N' 64 1 ''. + _generate_extend '.' 64 1 ''. - test( iv_line = lv_line iv_filename = lv_filename ). + do_test( iv_line = lv_line iv_filename = '*.abap' ). - ENDMETHOD. "test04 + ENDMETHOD. " test_abap_04 ****************************************************** * Test parsing and ordering texts in curly brackets * ****************************************************** - METHOD test05. + METHOD test_abap_05. - DATA: - lv_line TYPE string, - lv_filename TYPE string VALUE 'file_name.abap'. "#EC NOTEXT + DATA lv_line TYPE string. lv_line = 'a = |{ b }={ c }|.'. "#EC NOTEXT @@ -848,28 +854,26 @@ CLASS ltcl_syntax_highlighter1 IMPLEMENTATION. _generate_order 'T' 16 1 '}'. " Generate table with expected values after extending - _generate_extend 'N' 0 4 ''. + _generate_extend '.' 0 4 ''. _generate_extend 'T' 4 1 '|'. - _generate_extend 'N' 5 5 ''. + _generate_extend '.' 5 5 ''. _generate_extend 'T' 10 1 '}'. - _generate_extend 'N' 11 2 ''. + _generate_extend '.' 11 2 ''. _generate_extend 'K' 13 1 ''. - _generate_extend 'N' 14 2 ''. + _generate_extend '.' 14 2 ''. _generate_extend 'T' 16 1 '}'. - _generate_extend 'N' 17 1 ''. + _generate_extend '.' 17 1 ''. - test( iv_line = lv_line iv_filename = lv_filename ). + do_test( iv_line = lv_line iv_filename = '*.abap' ). - ENDMETHOD. "test05 + ENDMETHOD. " test_abap_05 ****************************************************** * Test parsing and ordering of texts * ****************************************************** - METHOD test06. + METHOD test_abap_06. - DATA: - lv_line TYPE string, - lv_filename TYPE string VALUE 'file_name.abap'. "#EC NOTEXT + DATA lv_line TYPE string. lv_line = 'lv_line = lc_constant && |XYZ { ''ab'' && |ac{ ''UU'' }| }|'. "#EC NOTEXT @@ -900,35 +904,33 @@ CLASS ltcl_syntax_highlighter1 IMPLEMENTATION. _generate_order 'T' 54 1 '}'. " Generate table with expected values after extending - _generate_extend 'N' 00 22 ''. + _generate_extend '.' 00 22 ''. _generate_extend 'K' 22 2 ''. - _generate_extend 'N' 24 1 ''. + _generate_extend '.' 24 1 ''. _generate_extend 'T' 25 5 '|'. - _generate_extend 'N' 30 2 ''. + _generate_extend '.' 30 2 ''. _generate_extend 'T' 32 4 ''''. - _generate_extend 'N' 36 1 ''. + _generate_extend '.' 36 1 ''. _generate_extend 'K' 37 2 ''. - _generate_extend 'N' 39 1 ''. + _generate_extend '.' 39 1 ''. _generate_extend 'T' 40 3 '|'. - _generate_extend 'N' 43 2 ''. + _generate_extend '.' 43 2 ''. _generate_extend 'T' 45 4 ''''. - _generate_extend 'N' 49 2 ''. + _generate_extend '.' 49 2 ''. _generate_extend 'T' 51 1 '}'. - _generate_extend 'N' 52 2 ''. + _generate_extend '.' 52 2 ''. _generate_extend 'T' 54 1 '}'. - test( iv_line = lv_line iv_filename = lv_filename ). + do_test( iv_line = lv_line iv_filename = '*.abap' ). - ENDMETHOD. "test06 + ENDMETHOD. " test_abap_06 ******************************************************** * Check that '*' in select statement is not a match * ******************************************************** - METHOD test07. + METHOD test_abap_07. - DATA: - lv_line TYPE string, - lv_filename TYPE string VALUE 'file_name.abap'. "#EC NOTEXT + DATA lv_line TYPE string. lv_line = 'SELECT * FROM foo'. "#EC NOTEXT @@ -940,24 +942,22 @@ CLASS ltcl_syntax_highlighter1 IMPLEMENTATION. _generate_order 'K' 0 6 ''. _generate_order 'K' 9 4 ''. - " Generate table with expected values after ordering + " Generate table with expected values after extending _generate_extend 'K' 0 6 ''. - _generate_extend 'N' 6 3 ''. + _generate_extend '.' 6 3 ''. _generate_extend 'K' 9 4 ''. - _generate_extend 'N' 13 4 ''. + _generate_extend '.' 13 4 ''. - test( iv_line = lv_line iv_filename = lv_filename ). + do_test( iv_line = lv_line iv_filename = '*.abap' ). - ENDMETHOD. "test07 + ENDMETHOD. " test_abap_07 ******************************************************** * Test parsing and ordering of key words in structures * ******************************************************** - METHOD test08. + METHOD test_abap_08. - DATA: - lv_line TYPE string, - lv_filename TYPE string VALUE 'file_name.abap'. "#EC NOTEXT + DATA lv_line TYPE string. lv_line = 'lv_length = -length.'. "#EC NOTEXT @@ -965,46 +965,197 @@ CLASS ltcl_syntax_highlighter1 IMPLEMENTATION. _generate_parse 'K' 13 5. _generate_parse 'K' 20 6. + " Generate table with expected values after extending + _generate_extend '.' 0 27 ''. + + do_test( iv_line = lv_line iv_filename = '*.abap' ). + + ENDMETHOD. " test_abap_08 + +******************************************************** +* Test parsing and ordering of tags in xml * +******************************************************** + METHOD test_xml_01. + + DATA lv_line TYPE string. + + lv_line = 'Text'. "#EC NOTEXT + + " Generate table with expected values after parsing + _generate_parse 'X' 0 1. + _generate_parse 'X' 4 1. + _generate_parse 'X' 9 1. + _generate_parse 'X' 14 1. + " Generate table with expected values after ordering - _generate_extend 'N' 0 27 ''. + _generate_order 'X' 0 5 '<'. + _generate_order 'X' 9 6 '<'. - test( iv_line = lv_line iv_filename = lv_filename ). + " Generate table with expected values after extending + _generate_extend 'X' 0 5 '<'. + _generate_extend '.' 5 4 ''. + _generate_extend 'X' 9 6 '<'. - ENDMETHOD. "test08 -ENDCLASS. " ltcl_syntax_highlighter1 IMPLEMENTATION + do_test( iv_line = lv_line iv_filename = '*.xml' ). + + ENDMETHOD. " test_xml_01 + + METHOD test_xml_02. + + DATA lv_line TYPE string. + + lv_line = ''. "#EC NOTEXT + + " Generate table with expected values after parsing + _generate_parse 'X' 0 1. + _generate_parse 'X' 5 1. + + " Generate table with expected values after ordering + _generate_order 'X' 0 6 '<'. + + " Generate table with expected values after extending + _generate_extend 'X' 0 6 '<'. + + do_test( iv_line = lv_line iv_filename = '*.xml' ). + + ENDMETHOD. " test_xml_02 + + METHOD test_xml_03. + + DATA lv_line TYPE string. + + lv_line = ''. "#EC NOTEXT + + " Generate table with expected values after parsing + _generate_parse 'X' 0 1. + _generate_parse 'A' 4 10. + _generate_parse 'V' 15 7. + _generate_parse 'X' 23 1. + + " Generate table with expected values after ordering + _generate_order 'X' 0 4 '<'. + _generate_order 'A' 4 10 ''. + _generate_order 'V' 15 7 ''. + _generate_order 'X' 22 2 '>'. + + " Generate table with expected values after extending + _generate_extend 'X' 0 4 '<'. + _generate_extend 'A' 4 10 ''. + _generate_extend '.' 14 1 ''. + _generate_extend 'V' 15 7 ''. + _generate_extend 'X' 22 2 '>'. + + do_test( iv_line = lv_line iv_filename = '*.xml' ). + + ENDMETHOD. " test_xml_03 + + METHOD test_xml_04. + + DATA lv_line TYPE string. + + lv_line = ''. "#EC NOTEXT + + " Generate table with expected values after parsing + _generate_parse 'X' 0 1. + _generate_parse 'A' 5 8. + _generate_parse 'V' 14 5. + _generate_parse 'X' 20 1. + + " Generate table with expected values after ordering + _generate_order 'X' 0 5 '<'. + _generate_order 'A' 5 8 ''. + _generate_order 'V' 14 5 ''. + _generate_order 'X' 19 2 '>'. + + " Generate table with expected values after extending + _generate_extend 'X' 0 5 '<'. + _generate_extend 'A' 5 8 ''. + _generate_extend '.' 13 1 ''. + _generate_extend 'V' 14 5 ''. + _generate_extend 'X' 19 2 '>'. + + do_test( iv_line = lv_line iv_filename = '*.xml' ). + + ENDMETHOD. " test_xml_04 + + METHOD test_xml_05. + + DATA lv_line TYPE string. + + lv_line = '"text"'. "#EC NOTEXT + + " Generate table with expected values after parsing + _generate_parse 'X' 0 1. + _generate_parse 'A' 7 6. + _generate_parse 'V' 14 4. + _generate_parse 'A' 18 6. + _generate_parse 'V' 25 4. + _generate_parse 'X' 29 1. + _generate_parse 'V' 30 6. + _generate_parse 'X' 36 1. + _generate_parse 'X' 44 1. + + " Generate table with expected values after ordering + _generate_order 'X' 0 7 '<'. + _generate_order 'A' 7 6 ''. + _generate_order 'V' 14 4 ''. + _generate_order 'A' 18 6 ''. + _generate_order 'V' 25 4 ''. + _generate_order 'X' 29 1 '>'. + _generate_order 'X' 36 9 '<'. + + " Generate table with expected values after extending + _generate_extend 'X' 0 7 '<'. + _generate_extend 'A' 7 6 ''. + _generate_extend '.' 13 1 ''. + _generate_extend 'V' 14 4 ''. + _generate_extend 'A' 18 6 ''. + _generate_extend '.' 24 1 ''. + _generate_extend 'V' 25 4 ''. + _generate_extend 'X' 29 1 '>'. + _generate_extend '.' 30 6 ''. + _generate_extend 'X' 36 9 '<'. + + do_test( iv_line = lv_line iv_filename = '*.xml' ). + + ENDMETHOD. " test_xml_05 +ENDCLASS. " ltcl_syntax_cases IMPLEMENTATION *----------------------------------------------------------------------* -* CLASS ltcl_syntax_highlighter2 DEFINITION +* CLASS ltcl_syntax_basic_logic DEFINITION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* -CLASS ltcl_syntax_highlighter2 DEFINITION FINAL +CLASS ltcl_syntax_basic_logic DEFINITION FINAL FOR TESTING RISK LEVEL HARMLESS DURATION SHORT. PRIVATE SECTION. DATA mo TYPE REF TO lcl_syntax_highlighter. - METHODS: process_line FOR TESTING. - METHODS: format_line FOR TESTING. - METHODS: apply_style FOR TESTING. + METHODS: + setup, + process_line FOR TESTING, + format_line FOR TESTING, + apply_style FOR TESTING. -ENDCLASS. " ltcl_syntax_highlighter2 +ENDCLASS. " ltcl_syntax_basic_logic *----------------------------------------------------------------------* * CLASS ltcl_syntax_highlighter IMPLEMENTATION *----------------------------------------------------------------------* -CLASS ltcl_syntax_highlighter2 IMPLEMENTATION. +CLASS ltcl_syntax_basic_logic IMPLEMENTATION. + + METHOD setup. + mo = lcl_syntax_highlighter=>create( '*.abap' ). + ENDMETHOD. " setup + METHOD format_line. DATA: lv_line TYPE string, lv_line_act TYPE string, - lv_line_exp TYPE string, - lv_filename TYPE string VALUE 'file_name.abap'. "#EC NOTEXT. - - " Create syntax highlighter - mo = lcl_syntax_highlighter=>create( lv_filename ). + lv_line_exp TYPE string. lv_line = 'call function ''FM_NAME''. " Commented'. "#EC NOTEXT @@ -1023,29 +1174,22 @@ CLASS ltcl_syntax_highlighter2 IMPLEMENTATION. ENDMETHOD. " format_line METHOD apply_style. - DATA: - lv_line_act TYPE string, - lv_filename TYPE string VALUE 'file_name.abap'. "#EC NOTEXT. - " Create syntax highlighter - mo = lcl_syntax_highlighter=>create( lv_filename ). + DATA lv_line_act TYPE string. " Call the method and compare results lv_line_act = mo->apply_style( iv_line = 'CALL FUNCTION' "#EC NOTEXT - iv_class = lcl_syntax_highlighter=>c_css-keyword ). + iv_class = lcl_syntax_abap=>c_css-keyword ). cl_abap_unit_assert=>assert_equals( act = lv_line_act exp = 'CALL FUNCTION' "#EC NOTEXT msg = 'Failure during applying of style.' ). "#EC NOTEXT + ENDMETHOD. " apply_style METHOD process_line. - DATA: - lv_line_act TYPE string, - lv_filename TYPE string VALUE 'file_name.abap'. "#EC NOTEXT. - " Create syntax highlighter - mo = lcl_syntax_highlighter=>create( lv_filename ). + DATA lv_line_act TYPE string. " Call the method with empty parameter and compare results lv_line_act = mo->process_line( iv_line = '' ). @@ -1060,6 +1204,7 @@ CLASS ltcl_syntax_highlighter2 IMPLEMENTATION. cl_abap_unit_assert=>assert_equals( act = lv_line_act exp = '* CALL FUNCTION' "#EC NOTEXT msg = 'Failure in method process_line.' ). "#EC NOTEXT + ENDMETHOD. " process_line ENDCLASS. " ltcl_syntax_highlighter \ No newline at end of file From 5af19e6200fba9636f71e9f6d0ea4d30be1fa7bc Mon Sep 17 00:00:00 2001 From: sbcgua Date: Wed, 14 Dec 2016 19:53:43 +0200 Subject: [PATCH 3/4] faster abap syntax (hash vs regex) #443 --- src/zabapgit_syntax_highlighter.prog.abap | 200 +++++++++++++--------- 1 file changed, 115 insertions(+), 85 deletions(-) diff --git a/src/zabapgit_syntax_highlighter.prog.abap b/src/zabapgit_syntax_highlighter.prog.abap index 65f8b1601..06a5bd184 100644 --- a/src/zabapgit_syntax_highlighter.prog.abap +++ b/src/zabapgit_syntax_highlighter.prog.abap @@ -1,9 +1,6 @@ *&---------------------------------------------------------------------* *& Include ZABAPGIT_SYNTAX_HIGHLIGHTER *&---------------------------------------------------------------------* -*&---------------------------------------------------------------------* -*& Class lcl_syntax_highligher -*&---------------------------------------------------------------------* CLASS ltcl_syntax_cases DEFINITION DEFERRED. CLASS ltcl_syntax_basic_logic DEFINITION DEFERRED. @@ -52,8 +49,8 @@ CLASS lcl_syntax_highlighter DEFINITION ABSTRACT DATA mt_rules TYPE STANDARD TABLE OF ty_rule. METHODS parse_line - IMPORTING iv_line TYPE string - RETURNING VALUE(rt_matches) TYPE ty_match_tt. + IMPORTING iv_line TYPE string + EXPORTING et_matches TYPE ty_match_tt. METHODS order_matches ABSTRACT IMPORTING iv_line TYPE string @@ -78,51 +75,49 @@ ENDCLASS. " lcl_syntax_highlighter DEFINITION *----------------------------------------------------------------------* * CLASS lcl_syntax_abap DEFINITION *----------------------------------------------------------------------* -* -*----------------------------------------------------------------------* CLASS lcl_syntax_abap DEFINITION INHERITING FROM lcl_syntax_highlighter FINAL. PUBLIC SECTION. - CLASS-METHODS class_constructor. - METHODS constructor. + CLASS-METHODS class_constructor. + METHODS constructor. CONSTANTS: BEGIN OF c_css, keyword TYPE string VALUE 'keyword', "#EC NOTEXT text TYPE string VALUE 'text', "#EC NOTEXT comment TYPE string VALUE 'comment', "#EC NOTEXT - END OF c_css. + END OF c_css, - CONSTANTS: BEGIN OF c_token, keyword TYPE c VALUE 'K', "#EC NOTEXT text TYPE c VALUE 'T', "#EC NOTEXT comment TYPE c VALUE 'C', "#EC NOTEXT - END OF c_token. + END OF c_token, + + BEGIN OF c_regex, + comment TYPE string VALUE '##|"|^\*', + text TYPE string VALUE '`|''|\||\{|\}', + keyword TYPE string VALUE '&&|\b[-_a-z0-9]+\b', + END OF c_regex. PROTECTED SECTION. - CLASS-DATA: - c_keyword_regex TYPE REF TO cl_abap_regex, " Temporary - BEGIN OF c_regex, - comment TYPE string, - text TYPE string, - keyword TYPE string, - END OF c_regex. + CLASS-DATA gt_keywords TYPE HASHED TABLE OF string WITH UNIQUE KEY table_line. - CLASS-METHODS get_keywords - RETURNING VALUE(rv_string) TYPE string. + CLASS-METHODS init_keywords. + CLASS-METHODS is_keyword + IMPORTING iv_chunk TYPE string + RETURNING VALUE(rv_yes) TYPE abap_bool. METHODS order_matches REDEFINITION. + METHODS parse_line REDEFINITION. ENDCLASS. " lcl_syntax_abap DEFINITION *----------------------------------------------------------------------* * CLASS lcl_syntax_xml DEFINITION *----------------------------------------------------------------------* -* -*----------------------------------------------------------------------* CLASS lcl_syntax_xml DEFINITION INHERITING FROM lcl_syntax_highlighter FINAL. PUBLIC SECTION. @@ -134,24 +129,22 @@ CLASS lcl_syntax_xml DEFINITION INHERITING FROM lcl_syntax_highlighter FINAL. xml_tag TYPE string VALUE 'xml_tag', "#EC NOTEXT attr TYPE string VALUE 'attr', "#EC NOTEXT attr_val TYPE string VALUE 'attr_val', "#EC NOTEXT - END OF c_css. + END OF c_css, - CONSTANTS: BEGIN OF c_token, xml_tag TYPE c VALUE 'X', "#EC NOTEXT attr TYPE c VALUE 'A', "#EC NOTEXT attr_val TYPE c VALUE 'V', "#EC NOTEXT - END OF c_token. + END OF c_token, + + BEGIN OF c_regex, + xml_tag TYPE string VALUE '[<>]', "#EC NOTEXT + attr TYPE string VALUE '\s[-a-z:_0-9]+\s*(?==)', "#EC NOTEXT + attr_val TYPE string VALUE '["''][^''"]+[''"]', "#EC NOTEXT + END OF c_regex. PROTECTED SECTION. - CLASS-DATA: - BEGIN OF c_regex, - xml_tag TYPE string, - attr TYPE string, - attr_val TYPE string, - END OF c_regex. - METHODS order_matches REDEFINITION. ENDCLASS. " lcl_syntax_xml DEFINITION @@ -207,6 +200,8 @@ CLASS lcl_syntax_highlighter IMPLEMENTATION. TYPE match_result, TYPE ty_match. + CLEAR et_matches. + " Process syntax-dependent regex table and find all matches LOOP AT mt_rules ASSIGNING . lo_regex = -regex. @@ -219,7 +214,7 @@ CLASS lcl_syntax_highlighter IMPLEMENTATION. ls_match-token = -token. ls_match-offset = -offset. ls_match-length = -length. - APPEND ls_match TO rt_matches. + APPEND ls_match TO et_matches. ENDLOOP. ENDLOOP. @@ -305,7 +300,8 @@ CLASS lcl_syntax_highlighter IMPLEMENTATION. RETURN. ENDIF. - lt_matches = me->parse_line( iv_line = iv_line ). + me->parse_line( EXPORTING iv_line = iv_line + IMPORTING et_matches = lt_matches ). me->order_matches( EXPORTING iv_line = iv_line CHANGING ct_matches = lt_matches ). @@ -330,39 +326,40 @@ CLASS lcl_syntax_abap IMPLEMENTATION. METHOD class_constructor. - CREATE OBJECT c_keyword_regex - EXPORTING - pattern = '&&|\b(' && get_keywords( ) && ')\b' - ignore_case = abap_true. + init_keywords( ). ENDMETHOD. " class_constructor + METHOD is_keyword. + + DATA lv_str TYPE string. + + lv_str = to_upper( iv_chunk ). + READ TABLE gt_keywords WITH KEY table_line = lv_str TRANSPORTING NO FIELDS. + rv_yes = boolc( sy-subrc = 0 ). + + ENDMETHOD. " is_keyword. + METHOD constructor. DATA ls_rule LIKE LINE OF mt_rules. super->constructor( ). - " Declare regular expressions' constants - c_regex-comment = '##|"|^\*'. "#EC NOTEXT - c_regex-text = '`|''|\||\{|\}'. "#EC NOTEXT - " Initialize instances of regular expression + _add_rule keyword. _add_rule comment. _add_rule text. - " Temporary - ls_rule-regex = c_keyword_regex. - ls_rule-token = c_token-keyword. - ls_rule-style = c_css-keyword. - APPEND ls_rule TO mt_rules. - ENDMETHOD. " constructor - METHOD get_keywords. + METHOD init_keywords. - rv_string = - '\?TO|ABAP-SOURCE|ABBREVIATED|ABS|ABSTRACT|ACCEPT|ACCEPTING|ACCESSPOLICY' && + DATA: lv_keywords TYPE string, + lt_keywords TYPE STANDARD TABLE OF string. + + lv_keywords = + '&&|?TO|ABAP-SOURCE|ABBREVIATED|ABS|ABSTRACT|ACCEPT|ACCEPTING|ACCESSPOLICY' && '|ACCORDING|ACOS|ACTIVATION|ACTUAL|ADD|ADD-CORRESPONDING|ADJACENT|AFTER|ALIAS' && '|ALIASES|ALIGN|ALL|ALLOCATE|ALPHA|ANALYSIS|ANALYZER|AND|ANY|APPEND|APPENDAGE' && '|APPENDING|APPLICATION|ARCHIVE|AREA|ARITHMETIC|AS|ASCENDING|ASIN|ASPECT|ASSERT' && @@ -435,17 +432,18 @@ CLASS lcl_syntax_abap IMPLEMENTATION. '|REPLACEMENT|REPLACING|REPORT|REQUEST|REQUESTED|RESERVE|RESET|RESOLUTION' && '|RESPECTING|RESPONSIBLE|RESULT|RESULTS|RESUMABLE|RESUME|RETRY|RETURN|RETURNCODE' && '|RETURNING|RIGHT|RIGHT-JUSTIFIED|RIGHTPLUS|RIGHTSPACE|RISK|RMC_COMMUNICATION_FAILURE' && - '|RMC_INVALID_STATUS|RMC_SYSTEM_FAILURE|ROLE|ROLLBACK|ROUND|ROWS|RTTI|RUN|SAP|SAP-SPOOL' && - '|SAVING|SCALE_PRESERVING|SCALE_PRESERVING_SCIENTIFIC|SCAN|SCIENTIFIC|SCIENTIFIC_WITH_LEADING_ZERO' && - '|SCREEN|SCROLL|SCROLL-BOUNDARY|SCROLLING|SEARCH|SECONDARY|SECONDS|SECTION|SELECT|SELECTION' && - '|SELECTIONS|SELECTION-SCREEN|SELECTION-SET|SELECTION-SETS|SELECTION-TABLE|SELECT-OPTIONS' && - '|SELECTOR|SEND|SEPARATE|SEPARATED|SET|SHARED|SHIFT|SHORT|SHORTDUMP-ID|SIGN' && - '|SIGN_AS_POSTFIX|SIMPLE|SIN|SINGLE|SINH|SIZE|SKIP|SKIPPING|SMART|SOME|SORT|SORTABLE' && - '|SORTED|SOURCE|SPACE|SPECIFIED|SPLIT|SPOOL|SPOTS|SQL|SQLSCRIPT|SQRT|STABLE|STAMP' && - '|STANDARD|STARTING|START-OF-SELECTION|STATE|STATEMENT|STATEMENTS|STATIC|STATICS|STATUSINFO' && - '|STEP-LOOP|STOP|STRLEN|STRUCTURE|STRUCTURES|STYLE|SUBKEY|SUBMATCHES|SUBMIT|SUBROUTINE' && - '|SUBSCREEN|SUBSTRING|SUBTRACT|SUBTRACT-CORRESPONDING|SUFFIX|SUM|SUMMARY|SUMMING|SUPPLIED' && - '|SUPPLY|SUPPRESS|SWITCH|SWITCHSTATES|SYMBOL|SYNCPOINTS|SYNTAX|SYNTAX-CHECK|SYNTAX-TRACE' && + '|RMC_INVALID_STATUS|RMC_SYSTEM_FAILURE|ROLE|ROLLBACK|ROUND|ROWS|RTTI|RUN|SAP' && + '|SAP-SPOOL|SAVING|SCALE_PRESERVING|SCALE_PRESERVING_SCIENTIFIC|SCAN|SCIENTIFIC' && + '|SCIENTIFIC_WITH_LEADING_ZERO|SCREEN|SCROLL|SCROLL-BOUNDARY|SCROLLING|SEARCH' && + '|SECONDARY|SECONDS|SECTION|SELECT|SELECTION|SELECTIONS|SELECTION-SCREEN|SELECTION-SET' && + '|SELECTION-SETS|SELECTION-TABLE|SELECT-OPTIONS|SELECTOR|SEND|SEPARATE|SEPARATED|SET' && + '|SHARED|SHIFT|SHORT|SHORTDUMP-ID|SIGN|SIGN_AS_POSTFIX|SIMPLE|SIN|SINGLE|SINH|SIZE' && + '|SKIP|SKIPPING|SMART|SOME|SORT|SORTABLE|SORTED|SOURCE|SPACE|SPECIFIED|SPLIT|SPOOL' && + '|SPOTS|SQL|SQLSCRIPT|SQRT|STABLE|STAMP|STANDARD|STARTING|START-OF-SELECTION|STATE' && + '|STATEMENT|STATEMENTS|STATIC|STATICS|STATUSINFO|STEP-LOOP|STOP|STRLEN|STRUCTURE' && + '|STRUCTURES|STYLE|SUBKEY|SUBMATCHES|SUBMIT|SUBROUTINE|SUBSCREEN|SUBSTRING|SUBTRACT' && + '|SUBTRACT-CORRESPONDING|SUFFIX|SUM|SUMMARY|SUMMING|SUPPLIED|SUPPLY|SUPPRESS|SWITCH' && + '|SWITCHSTATES|SYMBOL|SYNCPOINTS|SYNTAX|SYNTAX-CHECK|SYNTAX-TRACE' && '|SYSTEM-CALL|SYSTEM-EXCEPTIONS|SYSTEM-EXIT|TAB|TABBED|TABLE|TABLES|TABLEVIEW|TABSTRIP' && '|TAN|TANH|TARGET|TASK|TASKS|TEST|TESTING|TEXT|TEXTPOOL|THEN|THROW|TIME|TIMES|TIMESTAMP' && '|TIMEZONE|TITLE|TITLEBAR|TITLE-LINES|TO|TOKENIZATION|TOKENS|TOP-LINES|TOP-OF-PAGE' && @@ -457,7 +455,31 @@ CLASS lcl_syntax_abap IMPLEMENTATION. '|WHERE|WHILE|WIDTH|WINDOW|WINDOWS|WITH|WITH-HEADING|WITHOUT|WITH-TITLE|WORD|WORK' && '|WRITE|WRITER|X|XML|XOR|XSD|XSTRLEN|YELLOW|YES|YYMMDD|Z|ZERO|ZONE'. - ENDMETHOD. " get_keywords. + SPLIT lv_keywords AT '|' INTO TABLE lt_keywords. + gt_keywords = lt_keywords. " Hash table + + ENDMETHOD. " init_keywords + + METHOD parse_line. "REDEFINITION + + DATA lv_index TYPE i. + + FIELD-SYMBOLS LIKE LINE OF et_matches. + + super->parse_line( EXPORTING iv_line = iv_line + IMPORTING et_matches = et_matches ). + + " Remove non-keywords + LOOP AT et_matches ASSIGNING WHERE token = c_token-keyword. + lv_index = sy-tabix. + IF abap_false = is_keyword( substring( val = iv_line + off = -offset + len = -length ) ). + DELETE et_matches INDEX lv_index. + ENDIF. + ENDLOOP. + + ENDMETHOD. " parse_line. METHOD order_matches. @@ -499,21 +521,23 @@ CLASS lcl_syntax_abap IMPLEMENTATION. CONTINUE. WHEN c_token-text. - -text_tag = substring( val = iv_line off = -offset len = -length ). + -text_tag = substring( val = iv_line + off = -offset + len = -length ). IF lv_prev_token = c_token-text. IF -text_tag = -text_tag. -length = -offset + -length - -offset. CLEAR lv_prev_token. ELSEIF -text_tag = '}' AND -text_tag = '{'. - -length = -offset - -offset - 1. " Shifted } out of highlight - -offset = -offset + 1. " Shifted { out of highlight + -length = -offset - -offset - 1. " Shift } out of scope + -offset = -offset + 1. " Shift { out of scope CLEAR lv_prev_token. ELSEIF -text_tag = '{'. -length = -offset - -offset. CLEAR lv_prev_token. ELSEIF -text_tag = '}'. -length = -offset - -offset. - -offset = -offset + 1. " Shifted } out of highlight + -offset = -offset + 1. " Shift } out of scope CLEAR lv_prev_token. ENDIF. DELETE ct_matches INDEX lv_index. @@ -543,10 +567,6 @@ CLASS lcl_syntax_xml IMPLEMENTATION. super->constructor( ). - c_regex-xml_tag = '[<>]'. "#EC NOTEXT - c_regex-attr = '\s[-a-z:_0-9]+\s*(?==)'. "#EC NOTEXT - c_regex-attr_val = '["''][^''"]+[''"]'. "#EC NOTEXT - " Initialize instances of regular expressions _add_rule xml_tag. _add_rule attr. @@ -575,13 +595,19 @@ CLASS lcl_syntax_xml IMPLEMENTATION. CASE -token. WHEN c_token-xml_tag. - -text_tag = substring( val = iv_line off = -offset len = -length ). - IF -text_tag = '>' AND lv_prev_token = c_token-xml_tag. " No other matches between two tags + -text_tag = substring( val = iv_line + off = -offset + len = -length ). + + " No other matches between two tags + IF -text_tag = '>' AND lv_prev_token = c_token-xml_tag. lv_state = 'C'. -length = -offset - -offset + -length. DELETE ct_matches INDEX lv_index. CONTINUE. - ELSEIF -text_tag = '>' AND lv_prev_token <> c_token-xml_tag. " Adjust length and offset of closing tag + + " Adjust length and offset of closing tag + ELSEIF -text_tag = '>' AND lv_prev_token <> c_token-xml_tag. lv_state = 'C'. -length = -offset - -offset - -length + -length. -offset = -offset + -length. @@ -677,7 +703,8 @@ CLASS ltcl_syntax_cases IMPLEMENTATION. lo = lcl_syntax_highlighter=>create( iv_filename ). - lt_matches_act = lo->parse_line( iv_line = iv_line ). + lo->parse_line( EXPORTING iv_line = iv_line + IMPORTING et_matches = lt_matches_act ). SORT lt_matches_act BY offset. @@ -1181,9 +1208,10 @@ CLASS ltcl_syntax_basic_logic IMPLEMENTATION. lv_line_act = mo->apply_style( iv_line = 'CALL FUNCTION' "#EC NOTEXT iv_class = lcl_syntax_abap=>c_css-keyword ). - cl_abap_unit_assert=>assert_equals( act = lv_line_act - exp = 'CALL FUNCTION' "#EC NOTEXT - msg = 'Failure during applying of style.' ). "#EC NOTEXT + cl_abap_unit_assert=>assert_equals( + act = lv_line_act + exp = 'CALL FUNCTION' "#EC NOTEXT + msg = 'Failure during applying of style.' ). "#EC NOTEXT ENDMETHOD. " apply_style @@ -1194,16 +1222,18 @@ CLASS ltcl_syntax_basic_logic IMPLEMENTATION. " Call the method with empty parameter and compare results lv_line_act = mo->process_line( iv_line = '' ). - cl_abap_unit_assert=>assert_equals( act = lv_line_act - exp = '' - msg = 'Failure in method process_line.' ). "#EC NOTEXT + cl_abap_unit_assert=>assert_equals( + act = lv_line_act + exp = '' + msg = 'Failure in method process_line.' ). "#EC NOTEXT " Call the method with non-empty line and compare results lv_line_act = mo->process_line( iv_line = '* CALL FUNCTION' ). "#EC NOTEXT - cl_abap_unit_assert=>assert_equals( act = lv_line_act - exp = '* CALL FUNCTION' "#EC NOTEXT - msg = 'Failure in method process_line.' ). "#EC NOTEXT + cl_abap_unit_assert=>assert_equals( + act = lv_line_act + exp = '* CALL FUNCTION' "#EC NOTEXT + msg = 'Failure in method process_line.' ). "#EC NOTEXT ENDMETHOD. " process_line From 79d74c06f16a13e4b1abc67dbf7e0000a855ce57 Mon Sep 17 00:00:00 2001 From: sbcgua Date: Thu, 15 Dec 2016 22:24:09 +0200 Subject: [PATCH 4/4] linter fix --- src/zabapgit_syntax_highlighter.prog.abap | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/zabapgit_syntax_highlighter.prog.abap b/src/zabapgit_syntax_highlighter.prog.abap index 06a5bd184..c80816ab0 100644 --- a/src/zabapgit_syntax_highlighter.prog.abap +++ b/src/zabapgit_syntax_highlighter.prog.abap @@ -1076,7 +1076,7 @@ CLASS ltcl_syntax_cases IMPLEMENTATION. ENDMETHOD. " test_xml_03 - METHOD test_xml_04. + METHOD test_xml_04. DATA lv_line TYPE string. @@ -1105,7 +1105,7 @@ CLASS ltcl_syntax_cases IMPLEMENTATION. ENDMETHOD. " test_xml_04 - METHOD test_xml_05. + METHOD test_xml_05. DATA lv_line TYPE string. @@ -1146,6 +1146,7 @@ CLASS ltcl_syntax_cases IMPLEMENTATION. do_test( iv_line = lv_line iv_filename = '*.xml' ). ENDMETHOD. " test_xml_05 + ENDCLASS. " ltcl_syntax_cases IMPLEMENTATION *----------------------------------------------------------------------*