abapGit/src/syntax/zcl_abapgit_syntax_js.clas.abap
Lars Hvam d36b43defe
line break parameters (#3444)
* line break parameters

* Update zcl_abapgit_gui_page_repo_sett.clas.abap

* Update zcl_abapgit_gui_page_repo_sett.clas.abap

* fix
2020-06-04 15:10:35 +02:00

300 lines
11 KiB
ABAP

CLASS zcl_abapgit_syntax_js DEFINITION
PUBLIC
INHERITING FROM zcl_abapgit_syntax_highlighter
CREATE PUBLIC .
PUBLIC SECTION.
CONSTANTS:
" JavaScript
" 1) General keywords
" 2) Variable types
" 3) HTML Tags
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
variables TYPE string VALUE 'variables', "#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
variables TYPE c VALUE 'V', "#EC NOTEXT
END OF c_token .
CONSTANTS:
BEGIN OF c_regex,
" comments /* ... */ or //
comment TYPE string VALUE '\/\*.*\*\/|\/\*|\*\/|\/\/', "#EC NOTEXT
" single or double quoted strings
text TYPE string VALUE '"|''', "#EC NOTEXT
" in general keywords don't contain numbers (except -ms-scrollbar-3dlight-color)
keyword TYPE string VALUE '\b[a-z-]+\b', "#EC NOTEXT
END OF c_regex .
CLASS-METHODS class_constructor .
METHODS constructor .
PROTECTED SECTION.
TYPES: BEGIN OF ty_keyword,
keyword TYPE string,
token TYPE char1,
END OF ty_keyword.
CLASS-DATA gt_keywords TYPE HASHED TABLE OF ty_keyword WITH UNIQUE KEY keyword.
CLASS-DATA gv_comment TYPE abap_bool.
CLASS-METHODS init_keywords.
CLASS-METHODS insert_keywords
IMPORTING
iv_keywords TYPE string
iv_token TYPE char1.
CLASS-METHODS is_keyword
IMPORTING iv_chunk TYPE string
RETURNING VALUE(rv_yes) TYPE abap_bool.
METHODS order_matches REDEFINITION.
METHODS parse_line REDEFINITION.
PRIVATE SECTION.
ENDCLASS.
CLASS ZCL_ABAPGIT_SYNTAX_JS IMPLEMENTATION.
METHOD class_constructor.
init_keywords( ).
ENDMETHOD.
METHOD constructor.
super->constructor( ).
" Initialize instances of regular expression
add_rule( iv_regex = c_regex-keyword
iv_token = c_token-keyword
iv_style = c_css-keyword ).
add_rule( iv_regex = c_regex-comment
iv_token = c_token-comment
iv_style = c_css-comment ).
add_rule( iv_regex = c_regex-text
iv_token = c_token-text
iv_style = c_css-text ).
" Styles for keywords
add_rule( iv_regex = ''
iv_token = c_token-variables
iv_style = c_css-variables ).
ENDMETHOD.
METHOD init_keywords.
DATA: lv_keywords TYPE string.
CLEAR gt_keywords.
" 1) General keywords
lv_keywords =
'alert|all|body|break|bytetostring|case|continue|default|delete|do|document|else|event|export|for|function|if|' &&
'import|in|innerhtml|isnan|item|mimetypes|navigator|new|onabort|onblur|onchange|onclick|ondblclick|ondragdrop|' &&
'onerror|onfocus|onkeydown|onkeypress|onkeyup|onload|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|' &&
'onmove|onreset|onselect|onsubmit|onunload|onresize|options|parsefloat|parseint|prototype|return|screen|switch|' &&
'unit|var|void|while|window|with|anchor|applet|area|button|checkbox|fileupload|form|frame|hidden|link|mimetype|' &&
'password|plugin|radio|reset|select|submit|text|textarea|abs|acos|alert|anchor|asin|atan|atan2|back|big|blink|' &&
'blur|bold|captureevents|ceil|charat|charcodeat|clearinterval|cleartimeout|click|close|concat|confirm|cos|' &&
'disableexternalcapture|enableexternalcapture|eval|exp|find|fixed|floor|focus|fontcolor|fontsize|forward|' &&
'fromcharcode|getdate|getday|getelementbyid|gethours|getminutes|getmonth|getoptionvalue|getoptionvaluecount|' &&
'getseconds|getselection|gettime|gettimezoneoffset|getyear|go|handleevent|home|indexof|italics|javaenabled|join|' &&
'lastindexof|link|load|log|match|max|min|moveabove|movebelow|moveby|moveto|movetoabsolute|open|parse|plugins|' &&
'pop|pow|preference|print|prompt|push|random|refresh|releaseevents|reload|replace|reset|resizeby|resizeto|' &&
'reverse|round|routeevent|scroll|scrollby|scrollto|search|select|setdate|sethours|setinterval|setminutes|' &&
'setmonth|setseconds|settime|settimeout|setyear|shift|sin|slice|small|sort|splice|split|sqrt|stop|strike|sub|' &&
'submit|substr|substring|sup|taintenabled|tan|togmtstring|tolocalestring|tolowercase|tostring|touppercase|' &&
'unshift|unwatch|utc|valueof|watch|write|writeln|e|ln10|ln2|log10e|log2e|max_value|min_value|negative_infinity|' &&
'nan|pi|positive_infinity|url|above|action|alinkcolor|anchors|appcodename|appname|appversion|applets|arguments|' &&
'arity|availheight|availwidth|background|backgroundcolor|below|bgcolor|border|bottom|caller|cancelbubble|' &&
'checked|clientheight|clientwidth|clientx|clienty|clip|closed|color|colordepth|complete|constructor|cookie|' &&
'count|current|defaultchecked|defaultselected|defaultstatus|defaultvalue|description|display|document|domain|' &&
'elements|embeds|enabledplugin|encoding|false|fgcolor|filename|form|formname|forms|frames|hash|height|history|' &&
'host|hostname|href|hspace|images|innerheight|innerwidth|language|lastmodified|layers|left|length|linkcolor|' &&
'links|location|locationbar|lowsrc|menubar|method|mimetypes|name|next|null|offsetheight|offsetleft|offsetparent|' &&
'offsetwidth|opener|outerheight|outerwidth|pagex|pagexoffset|pagey|pageyoffset|parent|parentlayer|pathname|' &&
'personalbar|pixeldepth|platform|plugins|port|poswidth|previous|protocol|prototype|referrer|right|scrolltop|' &&
'scrollbars|search|selected|selectedindex|self|siblingabove|siblingbelow|src|srcelement|status|statusbar|style|' &&
'suffixes|tags|target|text|this|title|toolbar|top|true|type|useragent|value|visibility|vlinkcolor|vspace|width|' &&
'window|zindex'.
insert_keywords( iv_keywords = lv_keywords
iv_token = c_token-keyword ).
" 2) Variable types
lv_keywords =
'array|boolean|date|function|image|layer|math|number|object|option|regexp|string'.
insert_keywords( iv_keywords = lv_keywords
iv_token = c_token-variables ).
ENDMETHOD.
METHOD insert_keywords.
DATA: lt_keywords TYPE STANDARD TABLE OF string,
ls_keyword TYPE ty_keyword.
FIELD-SYMBOLS: <lv_keyword> TYPE any.
SPLIT iv_keywords AT '|' INTO TABLE lt_keywords.
LOOP AT lt_keywords ASSIGNING <lv_keyword>.
CLEAR ls_keyword.
ls_keyword-keyword = <lv_keyword>.
ls_keyword-token = iv_token.
INSERT ls_keyword INTO TABLE gt_keywords.
ENDLOOP.
ENDMETHOD.
METHOD is_keyword.
DATA lv_str TYPE string.
lv_str = to_lower( iv_chunk ).
READ TABLE gt_keywords WITH TABLE KEY keyword = lv_str TRANSPORTING NO FIELDS.
rv_yes = boolc( sy-subrc = 0 ).
ENDMETHOD.
METHOD order_matches.
DATA:
lv_match TYPE string,
lv_line_len TYPE i,
lv_cmmt_end TYPE i,
lv_prev_end TYPE i,
lv_prev_token TYPE c.
FIELD-SYMBOLS:
<ls_prev> TYPE ty_match,
<ls_match> TYPE ty_match,
<ls_keyword> TYPE ty_keyword.
" Longest matches
SORT ct_matches BY offset length DESCENDING.
lv_line_len = strlen( iv_line ).
" Check if this is part of multi-line comment and mark it accordingly
IF gv_comment = abap_true.
READ TABLE ct_matches WITH KEY token = c_token-comment TRANSPORTING NO FIELDS.
IF sy-subrc <> 0.
CLEAR ct_matches.
APPEND INITIAL LINE TO ct_matches ASSIGNING <ls_match>.
<ls_match>-token = c_token-comment.
<ls_match>-offset = 0.
<ls_match>-length = lv_line_len.
RETURN.
ENDIF.
ENDIF.
LOOP AT ct_matches ASSIGNING <ls_match>.
" Delete matches after open text match
IF lv_prev_token = c_token-text AND <ls_match>-token <> c_token-text.
CLEAR <ls_match>-token.
CONTINUE.
ENDIF.
lv_match = substring( val = iv_line
off = <ls_match>-offset
len = <ls_match>-length ).
CASE <ls_match>-token.
WHEN c_token-keyword.
" Skip keyword that's part of previous (longer) keyword
IF <ls_match>-offset < lv_prev_end.
CLEAR <ls_match>-token.
CONTINUE.
ENDIF.
" Map generic keyword to specific token
lv_match = to_lower( lv_match ).
READ TABLE gt_keywords ASSIGNING <ls_keyword> WITH TABLE KEY keyword = lv_match.
IF sy-subrc = 0.
<ls_match>-token = <ls_keyword>-token.
ENDIF.
WHEN c_token-comment.
IF lv_match = '/*'.
DELETE ct_matches WHERE offset > <ls_match>-offset.
<ls_match>-length = lv_line_len - <ls_match>-offset.
gv_comment = abap_true.
ELSEIF lv_match = '//'.
DELETE ct_matches WHERE offset > <ls_match>-offset.
<ls_match>-length = lv_line_len - <ls_match>-offset.
ELSEIF lv_match = '*/'.
DELETE ct_matches WHERE offset < <ls_match>-offset.
<ls_match>-length = <ls_match>-offset + 2.
<ls_match>-offset = 0.
gv_comment = abap_false.
ELSE.
lv_cmmt_end = <ls_match>-offset + <ls_match>-length.
DELETE ct_matches WHERE offset > <ls_match>-offset AND offset <= lv_cmmt_end.
ENDIF.
WHEN c_token-text.
<ls_match>-text_tag = lv_match.
IF lv_prev_token = c_token-text.
IF <ls_match>-text_tag = <ls_prev>-text_tag.
<ls_prev>-length = <ls_match>-offset + <ls_match>-length - <ls_prev>-offset.
CLEAR lv_prev_token.
ENDIF.
CLEAR <ls_match>-token.
CONTINUE.
ENDIF.
ENDCASE.
lv_prev_token = <ls_match>-token.
lv_prev_end = <ls_match>-offset + <ls_match>-length.
ASSIGN <ls_match> TO <ls_prev>.
ENDLOOP.
DELETE ct_matches WHERE token IS INITIAL.
ENDMETHOD.
METHOD parse_line. "REDEFINITION
DATA lv_index TYPE i.
FIELD-SYMBOLS <ls_match> LIKE LINE OF rt_matches.
rt_matches = super->parse_line( iv_line ).
" Remove non-keywords
LOOP AT rt_matches ASSIGNING <ls_match> WHERE token = c_token-keyword.
lv_index = sy-tabix.
IF abap_false = is_keyword( substring( val = iv_line
off = <ls_match>-offset
len = <ls_match>-length ) ).
CLEAR <ls_match>-token.
ENDIF.
ENDLOOP.
DELETE rt_matches WHERE token IS INITIAL.
ENDMETHOD.
ENDCLASS.