1
0
mirror of https://github.com/SpaceVim/SpaceVim.git synced 2025-02-03 14:50:04 +08:00
SpaceVim/bundle/vim-javacomplete2/autoload/javacomplete/scanner.vim
2022-11-02 00:34:34 +08:00

232 lines
6.3 KiB
VimL
Vendored
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

" Vim completion script for java
" Maintainer: artur shaik <ashaihullin@gmail.com>
"
" Simple parsing functions
" Search back from the cursor position till meeting '{' or ';'.
" '{' means statement start, ';' means end of a previous statement.
" Return: statement before cursor
" Note: It's the base for parsing. And It's OK for most cases.
function! javacomplete#scanner#GetStatement()
if getline('.') =~ '^\s*\(import\|package\)\s\+'
return strpart(getline('.'), match(getline('.'), '\(import\|package\)'), col('.')-1)
endif
let lnum_old = line('.')
let col_old = col('.')
call s:SkipBlock()
while 1
if search('[{};]\|<%\|<%!', 'bW') == 0
let lnum = 1
let col = 1
else
if javacomplete#util#InCommentOrLiteral(line('.'), col('.'))
continue
endif
normal! w
let lnum = line('.')
let col = col('.')
endif
break
endwhile
silent call cursor(lnum_old, col_old)
return s:MergeLines(lnum, col, lnum_old, col_old)
endfunction
function! s:SkipBlock()
let pos = line('.') + 1
let clbracket = 0
let quoteFlag = 0
while pos > 0
let pos -= 1
if pos == 0
break
endif
let line = getline(pos)
let cursor = len(line)
while cursor > 0
if line[cursor] == '"'
if quoteFlag == 0
let quoteFlag = 1
else
let quoteFlag = 0
endif
endif
if quoteFlag
let line = line[0 : cursor - 1]. line[cursor + 1 : -1]
let cursor -= 1
continue
endif
if line[cursor] == '}'
let clbracket += 1
elseif line[cursor] == '(' && clbracket == 0
call cursor(pos, cursor)
break
elseif line[cursor] == '{'
if clbracket > 0
let clbracket -= 1
else
break
endif
endif
let cursor -= 1
endwhile
if clbracket == 0
break
endif
endwhile
endfunction
function! s:MergeLines(lnum, col, lnum_old, col_old)
let lnum = a:lnum
let col = a:col
let str = ''
if lnum < a:lnum_old
let str = javacomplete#util#Prune(strpart(getline(lnum), a:col-1))
let lnum += 1
while lnum < a:lnum_old
let str .= javacomplete#util#Prune(getline(lnum))
let lnum += 1
endwhile
let col = 1
endif
let lastline = strpart(getline(a:lnum_old), col-1, a:col_old-col)
let str .= javacomplete#util#Prune(lastline, col)
let str = javacomplete#util#RemoveBlockComments(str)
" generic in JAVA 5+
while match(str, g:RE_TYPE_ARGUMENTS) != -1
let str = substitute(str, '\(' . g:RE_TYPE_ARGUMENTS . '\)', '\=repeat("", len(submatch(1)))', 'g')
endwhile
let str = substitute(str, '\s\s\+', ' ', 'g')
if str !~ '.*'. g:RE_KEYWORDS. '.*'
let str = substitute(str, '\([.()]\)[ \t]\+', '\1', 'g')
let str = substitute(str, '[ \t]\+\([.()]\)', '\1', 'g')
endif
return javacomplete#util#Trim(str) . matchstr(lastline, '\s*$')
endfunction
" Extract a clean expr, removing some non-necessary characters.
function! javacomplete#scanner#ExtractCleanExpr(expr)
if a:expr !~ '.*'. g:RE_KEYWORDS. '.*'
let cmd = substitute(a:expr, '[ \t\r\n ]\+\([.()[\]]\)', '\1', 'g')
let cmd = substitute(cmd, '\([.()[\]]\)[ \t\r\n ]\+', '\1', 'g')
else
let cmd = a:expr
endif
let pos = strlen(cmd)-1
while pos >= 0 && cmd[pos] =~ '[a-zA-Z0-9_.)\]:<>]'
if cmd[pos] == ')'
let pos = javacomplete#util#SearchPairBackward(cmd, pos, '(', ')')
elseif cmd[pos] == ']'
let pos = javacomplete#util#SearchPairBackward(cmd, pos, '[', ']')
endif
let pos -= 1
endwhile
" try looking back for "new"
let idx = match(strpart(cmd, 0, pos+1), '\<new[ \t\r\n ]*$')
return strpart(cmd, idx != -1 ? idx : pos+1)
endfunction
function! javacomplete#scanner#ParseExpr(expr)
let items = []
let s = 0
" recognize ClassInstanceCreationExpr as a whole
let e = matchend(a:expr, '^\s*new\s\+' . g:RE_QUALID . '\s*[([]')-1
if e < 0
let e = match(a:expr, '[.([:]')
endif
let isparen = 0
while e >= 0
if a:expr[e] == '.' || a:expr[e] == ':'
let subexpr = strpart(a:expr, s, e-s)
call extend(items, isparen ? s:ProcessParentheses(subexpr) : [subexpr])
let isparen = 0
if a:expr[e] == ':' && a:expr[e+1] == ':'
let s = e + 2
else
let s = e + 1
endif
elseif a:expr[e] == '('
let e = javacomplete#util#GetMatchedIndexEx(a:expr, e, '(', ')')
let isparen = 1
if e < 0
break
else
let e = matchend(a:expr, '^\s*[.[]', e+1)-1
continue
endif
elseif a:expr[e] == '['
let e = javacomplete#util#GetMatchedIndexEx(a:expr, e, '[', ']')
if e < 0
break
else
let e = matchend(a:expr, '^\s*[.[]', e+1)-1
continue
endif
endif
let e = match(a:expr, '[.([:]', s)
endwhile
let tail = strpart(a:expr, s)
if tail !~ '^\s*$'
call extend(items, isparen ? s:ProcessParentheses(tail) : [tail])
endif
return items
endfunction
" Given optional argument, call s:ParseExpr() to parser the nonparentheses expr
fu! s:ProcessParentheses(expr, ...)
let s = matchend(a:expr, '^\s*(')
if s != -1
let e = javacomplete#util#GetMatchedIndexEx(a:expr, s-1, '(', ')')
if e >= 0
let tail = strpart(a:expr, e+1)
if tail[-1:] == '.'
return [tail[0:-2]]
endif
if tail =~ '^\s*[\=$'
return s:ProcessParentheses(strpart(a:expr, s, e-s), 1)
elseif tail =~ '^\s*\w'
return [strpart(a:expr, 0, e+1) . 'obj.']
endif
endif
" multi-dot-expr except for new expr
elseif a:0 > 0 && stridx(a:expr, '.') != match(a:expr, '\.\s*$') && a:expr !~ '^\s*new\s\+'
return javacomplete#scanner#ParseExpr(a:expr)
endif
return [a:expr]
endfu
" search decl {{{1
" Return: The declaration of identifier under the cursor
" Note: The type of a variable must be imported or a fqn.
function! javacomplete#scanner#GetVariableDeclaration()
let lnum_old = line('.')
let col_old = col('.')
silent call search('[^a-zA-Z0-9$_.,?<>[\] \t\r\n ]', 'bW') " call search('[{};(,]', 'b')
normal! w
let lnum = line('.')
let col = col('.')
if (lnum == lnum_old && col == col_old)
return ''
endif
silent call cursor(lnum_old, col_old)
return s:MergeLines(lnum, col, lnum_old, col_old)
endfunction
" vim:set fdm=marker sw=2 nowrap: