mirror of
https://github.com/SpaceVim/SpaceVim.git
synced 2025-04-13 13:10:39 +08:00
chore(java): use bundle javacomplete2
This commit is contained in:
parent
9b5703af57
commit
2e1ad13d21
@ -132,7 +132,7 @@ let s:java_interpreter = 'java'
|
||||
|
||||
function! SpaceVim#layers#lang#java#plugins() abort
|
||||
let plugins = [
|
||||
\ ['artur-shaik/vim-javacomplete2', { 'on_ft' : ['java','jsp'], 'loadconf' : 1}],
|
||||
\ [g:_spacevim_root_dir . 'bundle/vim-javacomplete2', { 'on_ft' : ['java','jsp'], 'loadconf' : 1}],
|
||||
\ ]
|
||||
call add(plugins, [g:_spacevim_root_dir . 'bundle/JavaUnit.vim', {'on_ft' : 'java'}])
|
||||
call add(plugins, [g:_spacevim_root_dir . 'bundle/java_getset.vim', {'on_ft' : 'java'}])
|
||||
|
5
bundle/README.md
vendored
5
bundle/README.md
vendored
@ -13,6 +13,7 @@ In `bundle/` directory, there are two kinds of plugins: forked plugins without c
|
||||
- [`lang#go` layer](#langgo-layer)
|
||||
- [`tmux` layer](#tmux-layer)
|
||||
- [`incsearch` layer](#incsearch-layer)
|
||||
- [`lang#java` layer](#langjava-layer)
|
||||
|
||||
<!-- vim-markdown-toc -->
|
||||
|
||||
@ -86,3 +87,7 @@ This plugins are changed based on a specific version of origin plugin.
|
||||
- [vim-asterisk@77e9706](https://github.com/haya14busa/vim-asterisk/tree/77e97061d6691637a034258cc415d98670698459)
|
||||
- [vim-over@878f83b](https://github.com/osyo-manga/vim-over/tree/878f83bdac0cda308f599d319f45c7877d5274a9)
|
||||
- [incsearch-easymotion.vim@fcdd3ae](https://github.com/haya14busa/incsearch-easymotion.vim/tree/fcdd3aee6f4c0eef1a515727199ece8d6c6041b5)
|
||||
|
||||
#### `lang#java` layer
|
||||
|
||||
- `vim-javacomplete2` based on `https://github.com/artur-shaik/vim-javacomplete2/tree/a716e32bbe36daaed6ebc9aae76525aad9536245`
|
||||
|
3
bundle/vim-javacomplete2/.bundle/config
vendored
Normal file
3
bundle/vim-javacomplete2/.bundle/config
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
---
|
||||
BUNDLE_PATH: ".vim-flavor"
|
||||
BUNDLE_DISABLE_SHARED_GEMS: "true"
|
28
bundle/vim-javacomplete2/.github/ISSUE_TEMPLATE.md
vendored
Normal file
28
bundle/vim-javacomplete2/.github/ISSUE_TEMPLATE.md
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
## Actual behavior (Required!)
|
||||
|
||||
|
||||
## Expected behavior (Required!)
|
||||
|
||||
|
||||
## The steps to reproduce actual behavior (Required!)
|
||||
1. ...
|
||||
2. ...
|
||||
3. ...
|
||||
|
||||
|
||||
## Environment (Required!)
|
||||
* OS:
|
||||
* Vim version:
|
||||
* Neovim version:
|
||||
|
||||
|
||||
## Q&A
|
||||
* Yes, I tried minimal .vimrc configuraion.
|
||||
* Yes, I have enabled logs with `JCdebugEnableLogs` and can put here content of `JCdebugGetLogContent` command, if you need.
|
||||
* Even, if you wish, I can set `g:JavaComplete_JavaviLogLevel` to `'debug'`, then set `g:JavaComplete_JavaviLogDirectory`, and put here server logs, too.
|
||||
|
||||
|
||||
## Screenshot (Optional)
|
||||
|
||||
|
||||
## The output of :redir and :message (Optional)
|
15
bundle/vim-javacomplete2/.github/workflows/vint.yml
vendored
Normal file
15
bundle/vim-javacomplete2/.github/workflows/vint.yml
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
name: Vint
|
||||
on: [pull_request]
|
||||
jobs:
|
||||
vint:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@master
|
||||
- name: Run vint with reviewdog
|
||||
uses: reviewdog/action-vint@v1.0.1
|
||||
with:
|
||||
github_token: ${{ secrets.github_token }}
|
||||
reporter: github-pr-review
|
26
bundle/vim-javacomplete2/.gitignore
vendored
Normal file
26
bundle/vim-javacomplete2/.gitignore
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
*.class
|
||||
*.py[cod]
|
||||
|
||||
# Mobile Tools for Java (J2ME)
|
||||
.mtj.tmp/
|
||||
|
||||
# Package Files #
|
||||
*.jar
|
||||
*.war
|
||||
*.ear
|
||||
|
||||
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
||||
hs_err_pid*
|
||||
|
||||
*~
|
||||
.*.sw?
|
||||
libs/javavi/target/
|
||||
|
||||
*.lock
|
||||
.vim-flavor
|
||||
|
||||
.vimrc
|
||||
|
||||
# ignore vim's help tags
|
||||
doc/tags
|
||||
tags
|
3
bundle/vim-javacomplete2/Gemfile
vendored
Normal file
3
bundle/vim-javacomplete2/Gemfile
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
source 'https://rubygems.org'
|
||||
|
||||
gem 'vim-flavor', '~> 2.2.1'
|
78
bundle/vim-javacomplete2/LICENSE
vendored
Normal file
78
bundle/vim-javacomplete2/LICENSE
vendored
Normal file
@ -0,0 +1,78 @@
|
||||
VIM LICENSE
|
||||
|
||||
I) There are no restrictions on distributing unmodified copies of Vim except
|
||||
that they must include this license text. You can also distribute
|
||||
unmodified parts of Vim, likewise unrestricted except that they must
|
||||
include this license text. You are also allowed to include executables
|
||||
that you made from the unmodified Vim sources, plus your own usage
|
||||
examples and Vim scripts.
|
||||
|
||||
II) It is allowed to distribute a modified (or extended) version of Vim,
|
||||
including executables and/or source code, when the following four
|
||||
conditions are met:
|
||||
1) This license text must be included unmodified.
|
||||
2) The modified Vim must be distributed in one of the following five ways:
|
||||
a) If you make changes to Vim yourself, you must clearly describe in
|
||||
the distribution how to contact you. When the maintainer asks you
|
||||
(in any way) for a copy of the modified Vim you distributed, you
|
||||
must make your changes, including source code, available to the
|
||||
maintainer without fee. The maintainer reserves the right to
|
||||
include your changes in the official version of Vim. What the
|
||||
maintainer will do with your changes and under what license they
|
||||
will be distributed is negotiable. If there has been no negotiation
|
||||
then this license, or a later version, also applies to your changes.
|
||||
The current maintainer is Bram Moolenaar <Bram@vim.org>. If this
|
||||
changes it will be announced in appropriate places (most likely
|
||||
vim.sf.net, www.vim.org and/or comp.editors). When it is completely
|
||||
impossible to contact the maintainer, the obligation to send him
|
||||
your changes ceases. Once the maintainer has confirmed that he has
|
||||
received your changes they will not have to be sent again.
|
||||
b) If you have received a modified Vim that was distributed as
|
||||
mentioned under a) you are allowed to further distribute it
|
||||
unmodified, as mentioned at I). If you make additional changes the
|
||||
text under a) applies to those changes.
|
||||
c) Provide all the changes, including source code, with every copy of
|
||||
the modified Vim you distribute. This may be done in the form of a
|
||||
context diff. You can choose what license to use for new code you
|
||||
add. The changes and their license must not restrict others from
|
||||
making their own changes to the official version of Vim.
|
||||
d) When you have a modified Vim which includes changes as mentioned
|
||||
under c), you can distribute it without the source code for the
|
||||
changes if the following three conditions are met:
|
||||
- The license that applies to the changes permits you to distribute
|
||||
the changes to the Vim maintainer without fee or restriction, and
|
||||
permits the Vim maintainer to include the changes in the official
|
||||
version of Vim without fee or restriction.
|
||||
- You keep the changes for at least three years after last
|
||||
distributing the corresponding modified Vim. When the maintainer
|
||||
or someone who you distributed the modified Vim to asks you (in
|
||||
any way) for the changes within this period, you must make them
|
||||
available to him.
|
||||
- You clearly describe in the distribution how to contact you. This
|
||||
contact information must remain valid for at least three years
|
||||
after last distributing the corresponding modified Vim, or as long
|
||||
as possible.
|
||||
e) When the GNU General Public License (GPL) applies to the changes,
|
||||
you can distribute the modified Vim under the GNU GPL version 2 or
|
||||
any later version.
|
||||
3) A message must be added, at least in the output of the ":version"
|
||||
command and in the intro screen, such that the user of the modified Vim
|
||||
is able to see that it was modified. When distributing as mentioned
|
||||
under 2)e) adding the message is only required for as far as this does
|
||||
not conflict with the license used for the changes.
|
||||
4) The contact information as required under 2)a) and 2)d) must not be
|
||||
removed or changed, except that the person himself can make
|
||||
corrections.
|
||||
|
||||
III) If you distribute a modified version of Vim, you are encouraged to use
|
||||
the Vim license for your changes and make them available to the
|
||||
maintainer, including the source code. The preferred way to do this is
|
||||
by e-mail or by uploading the files to a server and e-mailing the URL.
|
||||
If the number of changes is small (e.g., a modified Makefile) e-mailing a
|
||||
context diff will do. The e-mail address to be used is
|
||||
<maintainer@vim.org>
|
||||
|
||||
IV) It is not allowed to remove this license from the distribution of the Vim
|
||||
sources, parts of it or from a modified version. You may use this
|
||||
license for previous Vim releases instead of the license that they came
|
||||
with, at your option.
|
318
bundle/vim-javacomplete2/README.md
vendored
Normal file
318
bundle/vim-javacomplete2/README.md
vendored
Normal file
@ -0,0 +1,318 @@
|
||||
# DEPRECATED in favor of [jc.nvim](https://github.com/artur-shaik/jc.nvim)
|
||||
|
||||
# vim-javacomplete2
|
||||
|
||||
Updated version of the original [javacomplete plugin](http://www.vim.org/scripts/script.php?script_id=1785) for vim.
|
||||
|
||||
## Demo
|
||||
|
||||

|
||||
|
||||
Generics demo
|
||||
|
||||

|
||||
|
||||
## Intro
|
||||
|
||||
This is vim-javacomplete2, an omni-completion plugin for [Java](http://www.oracle.com/technetwork/java/javase/downloads/index.html) requiring vim 7.
|
||||
|
||||
It includes javacomplete.vim, java_parser.vim, javavi (reflecton and source parsing library), javavibridge.py, and the [javaparser](https://github.com/javaparser/javaparser) library.
|
||||
|
||||
I have kept java_parser.vim for local (live) continuous parsing, because the javaparser library can't parse unfinished files.
|
||||
|
||||
For now the main difference from the original plugin is the existence of a server-like java library, that allows communication over sockets. This speeds up reflection and parsing.
|
||||
|
||||
One more issue I had with the original javacomplete plugin is losing my classpath and as a result, completion not working.
|
||||
So now the javacomplete2 plugin detects the JRE library path, thus bringing standard java completion out of the box - no configuration required!
|
||||
The plugin will scan child directory tree for `src` directory and add it to the sources path (For this, it is nice to have [vim-rooter](https://github.com/airblade/vim-rooter.git) plugin).
|
||||
|
||||
For the first run the plugin will compile the Javavi library.
|
||||
|
||||
## Features
|
||||
|
||||
Features:
|
||||
- Server side java reflection class loader and parsing library;
|
||||
- Searches class files automatically, using `maven`, `gradle` or Eclipse's `.classpath` file to append completion classpath;
|
||||
- Generics;
|
||||
- Lambdas;
|
||||
- Annotations completion;
|
||||
- Nested classes;
|
||||
- Adding imports automatically, includes `static` imports and imports of nested classes;
|
||||
- Complete methods declaration after '@Override';
|
||||
- Jsp support, without taglibs;
|
||||
- Cross-session cache;
|
||||
- Auto insert methods that need to be implemented;
|
||||
- `toString`, `equals`, `hashCode`, Constructors, Accessors generation;
|
||||
- Class creation.
|
||||
|
||||
Features (originally existed):
|
||||
- List members of a class, including (static) fields, (static) methods and ctors;
|
||||
- List classes or subpackages of a package;
|
||||
- Provide parameters information of a method, list all overload methods;
|
||||
- Complete an incomplete word;
|
||||
- Provide a complete JAVA parser written in Vim script language;
|
||||
- Use the JVM to obtain most information.
|
||||
|
||||
Features borrowed and ported to vimscript from vim-javacompleteex:
|
||||
- Complete class name;
|
||||
- Add import statement for a given class name.
|
||||
|
||||
## Requirements
|
||||
|
||||
- Vim version 7.4 or above with python support;
|
||||
- JDK8.
|
||||
|
||||
## Installation
|
||||
|
||||
### pathogen
|
||||
Run:
|
||||
|
||||
````Shell
|
||||
cd ~/.vim/bundle
|
||||
git clone https://github.com/artur-shaik/vim-javacomplete2.git
|
||||
````
|
||||
|
||||
### Vundle
|
||||
Add to `.vimrc`:
|
||||
|
||||
````vimL
|
||||
Plugin 'artur-shaik/vim-javacomplete2'
|
||||
````
|
||||
|
||||
### NeoBundle
|
||||
Add to `.vimrc`:
|
||||
|
||||
````vimL
|
||||
NeoBundle 'artur-shaik/vim-javacomplete2'
|
||||
````
|
||||
|
||||
### vim-plug
|
||||
Add to `.vimrc`:
|
||||
````vimL
|
||||
Plug 'artur-shaik/vim-javacomplete2'
|
||||
````
|
||||
|
||||
## Configuration
|
||||
|
||||
### Required
|
||||
|
||||
Add this to your `.vimrc` file:
|
||||
|
||||
`autocmd FileType java setlocal omnifunc=javacomplete#Complete`
|
||||
|
||||
To enable smart (trying to guess import option) inserting class imports with F4, add:
|
||||
|
||||
`nmap <F4> <Plug>(JavaComplete-Imports-AddSmart)`
|
||||
|
||||
`imap <F4> <Plug>(JavaComplete-Imports-AddSmart)`
|
||||
|
||||
To enable usual (will ask for import option) inserting class imports with F5, add:
|
||||
|
||||
`nmap <F5> <Plug>(JavaComplete-Imports-Add)`
|
||||
|
||||
`imap <F5> <Plug>(JavaComplete-Imports-Add)`
|
||||
|
||||
To add all missing imports with F6:
|
||||
|
||||
`nmap <F6> <Plug>(JavaComplete-Imports-AddMissing)`
|
||||
|
||||
`imap <F6> <Plug>(JavaComplete-Imports-AddMissing)`
|
||||
|
||||
To remove all unused imports with F7:
|
||||
|
||||
`nmap <F7> <Plug>(JavaComplete-Imports-RemoveUnused)`
|
||||
|
||||
`imap <F7> <Plug>(JavaComplete-Imports-RemoveUnused)`
|
||||
|
||||
Default mappings:
|
||||
|
||||
```
|
||||
nmap <leader>jI <Plug>(JavaComplete-Imports-AddMissing)
|
||||
nmap <leader>jR <Plug>(JavaComplete-Imports-RemoveUnused)
|
||||
nmap <leader>ji <Plug>(JavaComplete-Imports-AddSmart)
|
||||
nmap <leader>jii <Plug>(JavaComplete-Imports-Add)
|
||||
|
||||
imap <C-j>I <Plug>(JavaComplete-Imports-AddMissing)
|
||||
imap <C-j>R <Plug>(JavaComplete-Imports-RemoveUnused)
|
||||
imap <C-j>i <Plug>(JavaComplete-Imports-AddSmart)
|
||||
imap <C-j>ii <Plug>(JavaComplete-Imports-Add)
|
||||
|
||||
nmap <leader>jM <Plug>(JavaComplete-Generate-AbstractMethods)
|
||||
|
||||
imap <C-j>jM <Plug>(JavaComplete-Generate-AbstractMethods)
|
||||
|
||||
nmap <leader>jA <Plug>(JavaComplete-Generate-Accessors)
|
||||
nmap <leader>js <Plug>(JavaComplete-Generate-AccessorSetter)
|
||||
nmap <leader>jg <Plug>(JavaComplete-Generate-AccessorGetter)
|
||||
nmap <leader>ja <Plug>(JavaComplete-Generate-AccessorSetterGetter)
|
||||
nmap <leader>jts <Plug>(JavaComplete-Generate-ToString)
|
||||
nmap <leader>jeq <Plug>(JavaComplete-Generate-EqualsAndHashCode)
|
||||
nmap <leader>jc <Plug>(JavaComplete-Generate-Constructor)
|
||||
nmap <leader>jcc <Plug>(JavaComplete-Generate-DefaultConstructor)
|
||||
|
||||
imap <C-j>s <Plug>(JavaComplete-Generate-AccessorSetter)
|
||||
imap <C-j>g <Plug>(JavaComplete-Generate-AccessorGetter)
|
||||
imap <C-j>a <Plug>(JavaComplete-Generate-AccessorSetterGetter)
|
||||
|
||||
vmap <leader>js <Plug>(JavaComplete-Generate-AccessorSetter)
|
||||
vmap <leader>jg <Plug>(JavaComplete-Generate-AccessorGetter)
|
||||
vmap <leader>ja <Plug>(JavaComplete-Generate-AccessorSetterGetter)
|
||||
|
||||
nmap <silent> <buffer> <leader>jn <Plug>(JavaComplete-Generate-NewClass)
|
||||
nmap <silent> <buffer> <leader>jN <Plug>(JavaComplete-Generate-ClassInFile)
|
||||
```
|
||||
|
||||
The default mappings could be disabled with following setting:
|
||||
|
||||
```vim
|
||||
let g:JavaComplete_EnableDefaultMappings = 0
|
||||
```
|
||||
|
||||
### Optional
|
||||
|
||||
`g:JavaComplete_LibsPath` - path to additional jar files. This path appends with your libraries specified in `pom.xml`. Here you can add, for example, your glassfish libs directory or your project libs. It will be automatically append your JRE home path.
|
||||
|
||||
`g:JavaComplete_SourcesPath` - path of additional sources. Don't try to add all sources you have, this will slow down the parsing process. Instead, add your project sources and necessary library sources. If you have compiled classes add them to the previous config (`g:JavaComplete_LibsPath`) instead. By default the plugin will search the `src` directory and add it automatically.
|
||||
|
||||
`let g:JavaComplete_MavenRepositoryDisable = 1` - don't append classpath with libraries specified in `pom.xml` of your project. By default is `0`.
|
||||
|
||||
`let g:JavaComplete_UseFQN = 1` - use full qualified name in completions description. By default is `0`.
|
||||
|
||||
`let g:JavaComplete_PomPath = /path/to/pom.xml` - set path to `pom.xml` explicitly. It will be set automatically, if `pom.xml` is in underlying path.
|
||||
|
||||
`let g:JavaComplete_ClosingBrace = 1` - add close brace automatically, when complete method declaration. Disable if it conflicts with another plugins.
|
||||
|
||||
`let g:JavaComplete_JavaviLogDirectory = ''` - directory, where to write server logs.
|
||||
|
||||
`let g:JavaComplete_JavaviLogLevel = 'debug'` - enables server side logging (log4j logging levels).
|
||||
|
||||
`let g:JavaComplete_BaseDir = '~/.your_cache_dir'` - set the base cache directory of javacomplete2. By default it is `~/.cache`.
|
||||
|
||||
`let g:JavaComplete_ImportDefault = 0` - the default selection of import options. By default it is 0, which means automatically select first one. To make nothing on default set `-1`.
|
||||
|
||||
`let g:JavaComplete_GradleExecutable = 'gradle'` - use your own path to gradle executable file.
|
||||
|
||||
`let g:JavaComplete_ImportSortType = 'jarName'` - imports sorting type. Sorting can be by jar archives `jarName` or by package names `packageName`.
|
||||
|
||||
`let g:JavaComplete_StaticImportsAtTop = 1` - imports sorting with static imports at the top. By default this is `0`.
|
||||
|
||||
`let g:JavaComplete_ImportOrder = ['java.', 'javax.', 'com.', 'org.', 'net.']` - Specifies the order of import groups, when use `packageName` sorting type. An import group is a list of individual import statements that all start with the same beginning of package name surrounded by blank lines above and below the group. A `*` indicates all packages not specified, for 'google style' import ordering, e.g. `let g:JavaComplete_ImportOrder = ['com.google.', *, 'java.', 'javax.']`
|
||||
|
||||
`let g:JavaComplete_RegularClasses = ['java.lang.String', 'java.lang.Object']` - Regular class names that will be used automatically when you insert import. You can populate it with your custom classes, or it will be populated automatically when you choose any import option. List will be persisted, so it will be used next time you run the same project.
|
||||
|
||||
`let g:JavaComplete_CustomTemplateDirectory = '~/jc_templates'` - set directory that contains custom templates, for class creation. By default this options is null.
|
||||
|
||||
`let g:JavaComplete_AutoStartServer = 0` - Disable automatic startup of server.
|
||||
|
||||
`let g:JavaComplete_CompletionResultSort = 1` - Sort completion results alphabetically.
|
||||
|
||||
`let g:JavaComplete_IgnoreErrorMsg = 1` - When it is greater than 0, the error message will be ignored. By default it is 0.
|
||||
|
||||
`let g:JavaComplete_CheckServerVersionAtStartup = 0` - Check server version on startup. Can be disabled on slow start, or infinite recompilation. By default it is 1.
|
||||
|
||||
`let g:JavaComplete_ExcludeClassRegex = 'lombok\(\.experimental\)\?\.var'` - Exclude matching fully qualified class names from producing import statements.
|
||||
|
||||
`let g:JavaComplete_SourceExclude = ['src/frontend']` - Exclude source directories. Accept absolute and relative values.
|
||||
|
||||
## Commands
|
||||
|
||||
`JCimportsAddMissing` - add all missing 'imports';
|
||||
|
||||
`JCimportsRemoveUnused` - remove all unsused 'imports';
|
||||
|
||||
`JCimportAdd` - add 'import' for classname that is under cursor, or before it;
|
||||
|
||||
`JCimportAddSmart` - add 'import' for classname trying to guess variant without ask user to choose an option (it will ask on false guessing).
|
||||
|
||||
|
||||
`JCgenerateAbtractMethods` - generate methods that need to be implemented;
|
||||
|
||||
`JCgenerateAccessors` - generate getters and setters for all fields;
|
||||
|
||||
`JCgenerateAccessorSetter` - generate setter for field under cursor;
|
||||
|
||||
`JCgenerateAccessorGetter` - generate getter for field under cursor;
|
||||
|
||||
`JCgenerateAccessorSetterGetter` - generate getter and setter for field under cursor;
|
||||
|
||||
`JCgenerateToString` - generate `toString` method;
|
||||
|
||||
`JCgenerateEqualsAndHashCode` - generate `equals` and `hashCode` methods;
|
||||
|
||||
`JCgenerateConstructor` - generate constructor with chosen fields;
|
||||
|
||||
`JCgenerateConstructorDefault` - generate default constructor;
|
||||
|
||||
|
||||
`JCclassNew` - open prompt to enter class creation command;
|
||||
|
||||
`JCclassInFile` - open prompt to choose template that will be used for creation class boilerplate in current empty file;
|
||||
|
||||
|
||||
`JCserverShowPort` - show port, through which vim plugin communicates with server;
|
||||
|
||||
`JCserverShowPID` - show server process identificator;
|
||||
|
||||
`JCserverStart` - start server manually;
|
||||
|
||||
`JCserverTerminate` - stop server manually;
|
||||
|
||||
`JCserverCompile` - compile server manually;
|
||||
|
||||
|
||||
`JCdebugEnableLogs` - enable logs;
|
||||
|
||||
`JCdebugDisableLogs` - disable logs;
|
||||
|
||||
`JCdebugGetLogContent` - get debug logs;
|
||||
|
||||
`JCcacheClear` - clear cache manually.
|
||||
|
||||
## Class creation
|
||||
|
||||
Prompt scheme, for class creation:
|
||||
|
||||
template:[subdirectory]:/package.ClassName extends SuperClass implements Interface(String str, public Integer i):contructor(*):toString(1)
|
||||
|
||||
A: (optional) template - which will be used to create class boilerplate. Some existed templates: junit, interface, exception, servlet, etc;
|
||||
|
||||
B: (optional) subdirectory in which class will be put. For example: test, androidTest;
|
||||
|
||||
C: class name and package. With `/` will use backsearch for parent package to put in it. Without `/` put in relative package to current;
|
||||
|
||||
D: (optional) extends and implements classes will be automatically imported;
|
||||
|
||||
E: (optional) private str variable, and public i variable will be added to class;
|
||||
|
||||
F: (optional) contructor using all fields and toString override method with only `str` field will be created. Also hashCode and equals can be used.
|
||||
|
||||
There is autocompletion in command prompt that will try to help you. Your current opened file shouldn't have dirty changes or `hidden` should be set.
|
||||
|
||||
## Limitations:
|
||||
|
||||
- First run can be slow;
|
||||
- The embedded parser works a bit slower than expected.
|
||||
|
||||
## Todo
|
||||
|
||||
- Add javadoc;
|
||||
- ~~Lambda support~~;
|
||||
- ~~Cross session cache~~;
|
||||
- Most used (classes, methods, vars) at first place (smart suggestions);
|
||||
- FXML support;
|
||||
- ~~Check for jsp support~~;
|
||||
- Refactoring support?;
|
||||
- ~~Class creation helpers~~;
|
||||
- ~~Generics~~;
|
||||
- etc...
|
||||
|
||||
## Thanks
|
||||
|
||||
- Cheng Fang author of original javacomplete plugin;
|
||||
- Zhang Li author of vim-javacompleteex plugin;
|
||||
- http://github.com/javaparser/javaparser library.
|
||||
- [vimdoc](https://github.com/google/vimdoc) generate `:h javacomplete` file
|
||||
|
||||
## FeedBack
|
||||
|
||||
Any problems, bugs or suggestions are welcome to send to ashaihullin@gmail.com
|
11
bundle/vim-javacomplete2/Rakefile
vendored
Normal file
11
bundle/vim-javacomplete2/Rakefile
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
#!/usr/bin/env rake
|
||||
|
||||
task :ci => [:dump, :test]
|
||||
|
||||
task :dump do
|
||||
sh 'vim --version'
|
||||
end
|
||||
|
||||
task :test do
|
||||
sh 'bundle exec vim-flavor test'
|
||||
end
|
6
bundle/vim-javacomplete2/addon-info.json
vendored
Normal file
6
bundle/vim-javacomplete2/addon-info.json
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"name": "javacomplete",
|
||||
"description": "Updated version of the original javacomplete plugin",
|
||||
"author": "artur shaik"
|
||||
}
|
||||
|
14
bundle/vim-javacomplete2/autoload/classpath.py
vendored
Normal file
14
bundle/vim-javacomplete2/autoload/classpath.py
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
import os
|
||||
from xml.etree.ElementTree import *
|
||||
|
||||
def ReadClasspathFile(fn):
|
||||
cp = []
|
||||
for a in parse(fn).findall('classpathentry'):
|
||||
kind = a.get('kind')
|
||||
if kind == 'src' and 'output' in a.keys():
|
||||
cp.append(os.path.abspath(a.get('output')))
|
||||
elif kind == 'lib' and 'path' in a.keys():
|
||||
cp.append(os.path.abspath(a.get('path')))
|
||||
elif kind == 'output' and 'path' in a.keys():
|
||||
cp.append(os.path.abspath(a.get('path')))
|
||||
return cp
|
11
bundle/vim-javacomplete2/autoload/cm/sources/java.vim
vendored
Normal file
11
bundle/vim-javacomplete2/autoload/cm/sources/java.vim
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
func! cm#sources#java#register()
|
||||
" the omnifunc pattern is PCRE
|
||||
call cm#register_source({'name' : 'java',
|
||||
\ 'priority': 9,
|
||||
\ 'scopes': ['java'],
|
||||
\ 'abbreviation': 'java',
|
||||
\ 'cm_refresh_patterns':['\.', '::'],
|
||||
\ 'cm_refresh': {'omnifunc': 'javacomplete#Complete' },
|
||||
\ })
|
||||
|
||||
endfunc
|
3599
bundle/vim-javacomplete2/autoload/java_parser.vim
vendored
Normal file
3599
bundle/vim-javacomplete2/autoload/java_parser.vim
vendored
Normal file
File diff suppressed because it is too large
Load Diff
499
bundle/vim-javacomplete2/autoload/javacomplete.vim
vendored
Normal file
499
bundle/vim-javacomplete2/autoload/javacomplete.vim
vendored
Normal file
@ -0,0 +1,499 @@
|
||||
" Vim completion script for java
|
||||
" Maintainer: artur shaik <ashaihullin@gmail.com>
|
||||
|
||||
|
||||
|
||||
|
||||
""
|
||||
" @section Usage, usage
|
||||
" You can use `vim-javacomplete2` just like other omni-completion plugin.
|
||||
" Many samples of input context are gived in the following section.
|
||||
"
|
||||
" See |javacomplete-faq| in time if some problem occurs.
|
||||
" When meeting other problems not described in FAQ, you can contact with
|
||||
" the author by the following e-mail: ashaihullin@gmail.com
|
||||
"
|
||||
|
||||
""
|
||||
" @section Input contexts, contexts
|
||||
" @parentsection usage
|
||||
" It recognize nearly all kinds of Primary Expressions (see langspec-3.0)
|
||||
" except for `"Primary.new Indentifier"`. Casting conversion is also supported.
|
||||
"
|
||||
" Samples of input contexts are as following: (Note that '|' indicates cursor)
|
||||
"
|
||||
" (1). after '.', list members of a class or a package
|
||||
" >
|
||||
" - package.| subpackages and classes of a package
|
||||
" - Type.| static members of the 'Type' class and "class"
|
||||
" - var.| or field.| members of a variable or a field
|
||||
" - method().| members of result of method()
|
||||
" - this.| members of the current class
|
||||
" - ClassName.this.| members of the qualified class
|
||||
" - super.| members of the super class
|
||||
" - array.| members of an array object
|
||||
" - array[i].| array access, return members of the element of array
|
||||
" - "String".| String literal, return members of java.lang.String
|
||||
" - int.| or void.| primitive type or pseudo-type, return "class"
|
||||
" - int[].| array type, return members of a array type and "class"
|
||||
" - java.lang.String[].|
|
||||
" - new int[].| members of the new array instance
|
||||
" - new java.lang.String[i=1][].|
|
||||
" - new Type().| members of the new class instance
|
||||
" - Type.class.| class literal, return members of java.lang.Class
|
||||
" - void.class.| or int.class.|
|
||||
" - ((Type)var).| cast var as Type, return members of Type.
|
||||
" - (var.method()).| same with "var.|"
|
||||
" - (new Class()).| same with "new Class().|"
|
||||
" <
|
||||
" (2). after '(', list matching methods with parameters information.
|
||||
" >
|
||||
" - method(|) methods matched
|
||||
" - var.method(|) methods matched
|
||||
" - new ClassName(|) constructors matched
|
||||
" - this(|) constructors of current class matched
|
||||
" - super(|) constructors of super class matched
|
||||
" Any place between '(' and ')' will be supported soon.
|
||||
" Help information of javadoc is not supported yet.
|
||||
" <
|
||||
" (3). after an incomplete word, list all the matched beginning with it.
|
||||
" >
|
||||
" - var.ab| subset of members of var beginning with `ab`
|
||||
" - ab| list of all maybes
|
||||
" <
|
||||
" (4). import statement
|
||||
" >
|
||||
" - " import java.util.|"
|
||||
" - " import java.ut|"
|
||||
" - " import ja|"
|
||||
" - " import java.lang.Character.|" e.g. "Subset"
|
||||
" - " import static java.lang.Math.|" e.g. "PI, abs"
|
||||
" <
|
||||
" (5). package declaration
|
||||
" >
|
||||
" - " package com.|"
|
||||
" <
|
||||
"
|
||||
" The above are in simple expression.
|
||||
"
|
||||
" (6). after compound expression:
|
||||
" >
|
||||
" - PrimaryExpr.var.|
|
||||
" - PrimaryExpr.method().|
|
||||
" - PrimaryExpr.method(|)
|
||||
" - PrimaryExpr.var.ab|
|
||||
" e.g.
|
||||
" - "java.lang . System.in .|"
|
||||
" - "java.lang.System.getenv().|"
|
||||
" - "int.class.toString().|"
|
||||
" - "list.toArray().|"
|
||||
" - "new ZipFile(path).|"
|
||||
" - "new ZipFile(path).entries().|"
|
||||
" <
|
||||
" (7). Nested expression:
|
||||
" >
|
||||
" - "System.out.println( str.| )"
|
||||
" - "System.out.println(str.charAt(| )"
|
||||
" - "for (int i = 0; i < str.|; i++)"
|
||||
" - "for ( Object o : a.getCollect| )"
|
||||
" <
|
||||
"
|
||||
|
||||
""
|
||||
" @section Kind letter, kindletter
|
||||
" @parentsection usage
|
||||
" A single letter indicates the kind of compeltion item. These kinds are:
|
||||
" >
|
||||
" + ctor
|
||||
" v local variable or parameter
|
||||
" f nonstatic field
|
||||
" F static field
|
||||
" m nonstatic method
|
||||
" M static method
|
||||
" P package
|
||||
" C class type
|
||||
" I interface type
|
||||
" <
|
||||
|
||||
""
|
||||
" @section Class creation, classnew
|
||||
" @parentsection usage
|
||||
" Prompt scheme, for class creation:
|
||||
" >
|
||||
" template:[subdirectory]:/package.ClassName extends SuperClass implements Interface(String str, public Integer i):contructor(*):toString(1)
|
||||
" <
|
||||
" A: (optional) template - which will be used to create class boilerplate. Some existed templates: junit, interface, exception, servlet, etcl
|
||||
"
|
||||
" B: (optional) subdirectory in which class will be put. For example: test, androidTest;
|
||||
"
|
||||
" C: class name and package. With `/` will use backsearch for parent package to put in it. Without `/` put in relative package to current;
|
||||
"
|
||||
" D: (optional) extends and implements classes will be automatically imported;
|
||||
"
|
||||
" E: (optional) private str variable, and public i variable will be added to class;
|
||||
"
|
||||
" F: (optional) contructor using all fields and toString override method with only 'str' field will be created. Also hashCode and equals can be used.
|
||||
"
|
||||
" There is autocompletion in command prompt that will try to help you. Your current opened file shouldn't have dirty changes or 'hidden' should be set.
|
||||
|
||||
|
||||
""
|
||||
" @section FAQ, faq
|
||||
" 4.1 Why can not complete in gradle project?
|
||||
"
|
||||
" Check if 'gradle' is in your runtime path or './gradlew' (or
|
||||
" '.\gradlew.bat' for Windows) is in your project's directory.
|
||||
"
|
||||
" 4.2 I have installed gradle, but why I can not complete R.class?
|
||||
"
|
||||
" In android project, many of the class contains a ton of
|
||||
" innerclass, javacomplete2 could works better by reflection, so you need to
|
||||
" compile you project, after use './gradlew build', R.java will be
|
||||
" automatically generated and compiled.
|
||||
|
||||
""
|
||||
" @section Todo, todo
|
||||
" - Add javadoc
|
||||
" - Cross session cache;
|
||||
" - Most used (classes, methods, vars) at first place (smart suggestions);
|
||||
" - FXML support;
|
||||
" - JSP check support;
|
||||
" - Refactoring support?;
|
||||
" - Class creation helpers;
|
||||
" - etc...
|
||||
|
||||
|
||||
if exists('g:JavaComplete_Autoload')
|
||||
finish
|
||||
endif
|
||||
let g:JavaComplete_Autoload = 1
|
||||
|
||||
" It doesn't make sense to do any work if vim doesn't support any Python since
|
||||
" we relly on it to properly work.
|
||||
if has('python3')
|
||||
command! -nargs=1 JavacompletePy py3 <args>
|
||||
command! -nargs=1 JavacompletePyfile py3file <args>
|
||||
else
|
||||
echoerr 'Javacomplete needs Python3 support to run!'
|
||||
finish
|
||||
endif
|
||||
|
||||
function! s:Log(log) abort
|
||||
let log = type(a:log) ==# type('') ? a:log : string(a:log)
|
||||
call javacomplete#logger#Log('[javacomplete] '. a:log)
|
||||
endfunction
|
||||
|
||||
let g:J_ARRAY_TYPE_MEMBERS = [
|
||||
\ {'kind': 'm', 'word': 'clone(', 'abbr': 'clone()', 'menu': 'Object clone()', },
|
||||
\ {'kind': 'm', 'word': 'equals(', 'abbr': 'equals()', 'menu': 'boolean equals(Object)', },
|
||||
\ {'kind': 'm', 'word': 'getClass(', 'abbr': 'getClass()', 'menu': 'Class Object.getClass()', },
|
||||
\ {'kind': 'm', 'word': 'hashCode(', 'abbr': 'hashCode()', 'menu': 'int hashCode()', },
|
||||
\ {'kind': 'f', 'word': 'length', 'menu': 'int'},
|
||||
\ {'kind': 'm', 'word': 'notify(', 'abbr': 'notify()', 'menu': 'void Object.notify()', },
|
||||
\ {'kind': 'm', 'word': 'notifyAll(', 'abbr': 'notifyAll()', 'menu': 'void Object.notifyAll()', },
|
||||
\ {'kind': 'm', 'word': 'toString(', 'abbr': 'toString()', 'menu': 'String toString()', },
|
||||
\ {'kind': 'm', 'word': 'wait(', 'abbr': 'wait()', 'menu': 'void Object.wait() throws InterruptedException', },
|
||||
\ {'kind': 'm', 'dup': 1, 'word': 'wait(', 'abbr': 'wait()', 'menu': 'void Object.wait(long timeout) throws InterruptedException', },
|
||||
\ {'kind': 'm', 'dup': 1, 'word': 'wait(', 'abbr': 'wait()', 'menu': 'void Object.wait(long timeout, int nanos) throws InterruptedException', }]
|
||||
|
||||
let g:J_ARRAY_TYPE_INFO = {'tag': 'CLASSDEF', 'name': '[', 'ctors': [],
|
||||
\ 'fields': [{'n': 'length', 'm': '1', 't': 'int'}],
|
||||
\ 'methods':[
|
||||
\ {'n': 'clone', 'm': '1', 'r': 'Object', 'p': [], 'd': 'Object clone()'},
|
||||
\ {'n': 'equals', 'm': '1', 'r': 'boolean', 'p': ['Object'], 'd': 'boolean Object.equals(Object obj)'},
|
||||
\ {'n': 'getClass', 'm': '100010001', 'r': 'Class', 'p': [], 'd': 'Class Object.getClass()'},
|
||||
\ {'n': 'hashCode', 'm': '100000001', 'r': 'int', 'p': [], 'd': 'int Object.hashCode()'},
|
||||
\ {'n': 'notify', 'm': '100010001', 'r': 'void', 'p': [], 'd': 'void Object.notify()'},
|
||||
\ {'n': 'notifyAll','m': '100010001', 'r': 'void', 'p': [], 'd': 'void Object.notifyAll()'},
|
||||
\ {'n': 'toString', 'm': '1', 'r': 'String', 'p': [], 'd': 'String Object.toString()'},
|
||||
\ {'n': 'wait', 'm': '10001', 'r': 'void', 'p': [], 'd': 'void Object.wait() throws InterruptedException'},
|
||||
\ {'n': 'wait', 'm': '100010001', 'r': 'void', 'p': ['long'], 'd': 'void Object.wait(long timeout) throws InterruptedException'},
|
||||
\ {'n': 'wait', 'm': '10001', 'r': 'void', 'p': ['long','int'], 'd': 'void Object.wait(long timeout, int nanos) throws InterruptedException'},
|
||||
\ ]}
|
||||
|
||||
let g:J_PRIMITIVE_TYPE_INFO = {'tag': 'CLASSDEF', 'name': '!', 'fields': [{'n': 'class','m': '1','t': 'Class'}]}
|
||||
|
||||
let g:J_JSP_BUILTIN_OBJECTS = {'session': 'javax.servlet.http.HttpSession',
|
||||
\ 'request': 'javax.servlet.http.HttpServletRequest',
|
||||
\ 'response': 'javax.servlet.http.HttpServletResponse',
|
||||
\ 'pageContext': 'javax.servlet.jsp.PageContext',
|
||||
\ 'application': 'javax.servlet.ServletContext',
|
||||
\ 'config': 'javax.servlet.ServletConfig',
|
||||
\ 'out': 'javax.servlet.jsp.JspWriter',
|
||||
\ 'page': 'javax.servlet.jsp.HttpJspPage', }
|
||||
|
||||
|
||||
let g:J_PRIMITIVE_TYPES = ['boolean', 'byte', 'char', 'int', 'short', 'long', 'float', 'double']
|
||||
let g:J_KEYWORDS_MODS = ['public', 'private', 'protected', 'static', 'final', 'synchronized', 'volatile', 'transient', 'native', 'strictfp', 'abstract']
|
||||
let g:J_KEYWORDS_TYPE = ['class', 'interface', 'enum']
|
||||
let g:J_KEYWORDS = g:J_PRIMITIVE_TYPES + g:J_KEYWORDS_MODS + g:J_KEYWORDS_TYPE + ['super', 'this', 'void', 'var'] + ['assert', 'break', 'case', 'catch', 'const', 'continue', 'default', 'do', 'else', 'extends', 'finally', 'for', 'goto', 'if', 'implements', 'import', 'instanceof', 'interface', 'new', 'package', 'return', 'switch', 'throw', 'throws', 'try', 'while', 'true', 'false', 'null']
|
||||
|
||||
let g:JC_MODIFIER_PUBLIC = 1
|
||||
let g:JC_MODIFIER_PROTECTED = 3
|
||||
let g:JC_MODIFIER_FINAL = 5
|
||||
let g:JC_MODIFIER_NATIVE = 9
|
||||
let g:JC_MODIFIER_ABSTRACT = 11
|
||||
|
||||
let g:RE_BRACKETS = '\%(\s*\[\s*\]\)'
|
||||
let g:RE_IDENTIFIER = '[a-zA-Z_$][a-zA-Z0-9_$]*'
|
||||
let g:RE_ANNOTATION = '@[a-zA-Z_][a-zA-Z0-9_$]*'
|
||||
let g:RE_QUALID = g:RE_IDENTIFIER. '\%(\s*\.\s*' .g:RE_IDENTIFIER. '\)*'
|
||||
|
||||
let g:RE_REFERENCE_TYPE = g:RE_QUALID . g:RE_BRACKETS . '*'
|
||||
let g:RE_TYPE = g:RE_REFERENCE_TYPE
|
||||
|
||||
let g:RE_TYPE_ARGUMENT = '\%(?\s\+\%(extends\|super\)\s\+\)\=' . g:RE_TYPE
|
||||
let g:RE_TYPE_ARGUMENT_EXTENDS = '\%(?\s\+\%(extends\|super\)\s\+\)' . g:RE_TYPE
|
||||
let g:RE_TYPE_ARGUMENTS = '<' . g:RE_TYPE_ARGUMENT . '\%(\s*,\s*' . g:RE_TYPE_ARGUMENT . '\)*>'
|
||||
let g:RE_TYPE_WITH_ARGUMENTS_I = g:RE_IDENTIFIER . '\s*' . g:RE_TYPE_ARGUMENTS
|
||||
let g:RE_TYPE_WITH_ARGUMENTS = g:RE_TYPE_WITH_ARGUMENTS_I . '\%(\s*' . g:RE_TYPE_WITH_ARGUMENTS_I . '\)*'
|
||||
|
||||
let g:RE_TYPE_MODS = '\%(public\|protected\|private\|abstract\|static\|final\|strictfp\)'
|
||||
let g:RE_TYPE_DECL_HEAD = '\(class\|interface\|enum\)[ \t\n\r]\+'
|
||||
let g:RE_TYPE_DECL = '\<\C\(\%(' .g:RE_TYPE_MODS. '\s\+\)*\)' .g:RE_TYPE_DECL_HEAD. '\(' .g:RE_IDENTIFIER. '\)[{< \t\n\r]'
|
||||
|
||||
let g:RE_ARRAY_TYPE = '^\s*\(' .g:RE_QUALID . '\)\(' . g:RE_BRACKETS . '\+\)\s*$'
|
||||
let g:RE_SELECT_OR_ACCESS = '^\s*\(' . g:RE_IDENTIFIER . '\)\s*\(\[.*\]\)\=\s*$'
|
||||
let g:RE_ARRAY_ACCESS = '^\s*\(' . g:RE_IDENTIFIER . '\)\s*\(\[.*\]\)\+\s*$'
|
||||
let g:RE_CASTING = '^\s*(\(' .g:RE_QUALID. '\))\s*\(' . g:RE_IDENTIFIER . '\)\>'
|
||||
|
||||
let g:RE_KEYWORDS = '\<\%(' . join(g:J_KEYWORDS, '\|') . '\)\>'
|
||||
|
||||
let g:JAVA_HOME = $JAVA_HOME
|
||||
|
||||
let g:JavaComplete_Cache = {} " FQN -> member list, e.g. {'java.lang.StringBuffer': classinfo, 'java.util': packageinfo, '/dir/TopLevelClass.java': compilationUnit}
|
||||
let g:JavaComplete_Files = {} " srouce file path -> properties, e.g. {filekey: {'unit': compilationUnit, 'changedtick': tick, }}
|
||||
|
||||
let g:JavaComplete_ProjectKey = ''
|
||||
|
||||
fu! SScope() abort
|
||||
return s:
|
||||
endfu
|
||||
|
||||
function! javacomplete#Disable() abort
|
||||
let g:JavaComplete_Disabled = 1
|
||||
endfunction
|
||||
|
||||
function! javacomplete#Enable() abort
|
||||
let g:JavaComplete_Disabled = 0
|
||||
endfunction
|
||||
|
||||
function! javacomplete#ClearCache() abort
|
||||
let g:JavaComplete_Cache = {}
|
||||
let g:JavaComplete_Files = {}
|
||||
|
||||
call javacomplete#util#RemoveFile(javacomplete#util#GetBase('cache'). g:FILE_SEP. 'class_packages_'. g:JavaComplete_ProjectKey. '.dat')
|
||||
call javacomplete#server#Communicate('-collect-packages', '', 's:ClearCache')
|
||||
endfunction
|
||||
|
||||
function! javacomplete#Complete(findstart, base) abort
|
||||
return javacomplete#complete#complete#Complete(a:findstart, a:base, 1)
|
||||
endfunction
|
||||
|
||||
" key of g:JavaComplete_Files for current buffer. It may be the full path of current file or the bufnr of unnamed buffer, and is updated when BufEnter, BufLeave.
|
||||
function! javacomplete#GetCurrentFileKey() abort
|
||||
return s:GetCurrentFileKey()
|
||||
endfunction
|
||||
|
||||
function! s:GetCurrentFileKey() abort
|
||||
return has('autocmd') ? s:curfilekey : empty(expand('%')) ? bufnr('%') : expand('%:p')
|
||||
endfunction
|
||||
|
||||
function! s:SetCurrentFileKey() abort
|
||||
let s:curfilekey = empty(expand('%')) ? bufnr('%') : expand('%:p')
|
||||
endfunction
|
||||
call s:SetCurrentFileKey()
|
||||
|
||||
function! s:HandleTextChangedI() abort
|
||||
if get(g:, 'JC_ClassnameCompletedFlag', 0) && g:JavaComplete_InsertImports
|
||||
let saveCursor = getcurpos()
|
||||
let line = getline('.')
|
||||
if empty(javacomplete#util#Trim(line))
|
||||
call cursor(line('.') - 1, 500)
|
||||
let line = getline('.')
|
||||
let offset = 1
|
||||
else
|
||||
if line[col('.') - 2] !~# '\v(\s|\.|\(|\<)'
|
||||
return
|
||||
endif
|
||||
let offset = 0
|
||||
endif
|
||||
|
||||
let g:JC_ClassnameCompletedFlag = 0
|
||||
call javacomplete#imports#Add(1)
|
||||
let saveCursor[1] = line('.') + offset
|
||||
call setpos('.', saveCursor)
|
||||
endif
|
||||
|
||||
if get(g:, 'JC_DeclarationCompletedFlag', 0)
|
||||
let line = getline('.')
|
||||
if line[col('.') - 2] != ' '
|
||||
return
|
||||
endif
|
||||
|
||||
let g:JC_DeclarationCompletedFlag = 0
|
||||
|
||||
if line !~# '.*@Override.*'
|
||||
let line = getline(line('.') - 1)
|
||||
endif
|
||||
|
||||
if line =~# '.*@Override\s\+\(\S\+\|\)\(\s\+\|\)$'
|
||||
return
|
||||
endif
|
||||
|
||||
if !empty(javacomplete#util#Trim(getline('.')))
|
||||
call feedkeys("\b\r", 'n')
|
||||
endif
|
||||
if g:JavaComplete_ClosingBrace
|
||||
call feedkeys("}\eO", 'n')
|
||||
endif
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:HandleInsertLeave() abort
|
||||
if get(g:, 'JC_DeclarationCompletedFlag', 0)
|
||||
let g:JC_DeclarationCompletedFlag = 0
|
||||
endif
|
||||
if get(g:, 'JC_ClassnameCompletedFlag', 0)
|
||||
let g:JC_ClassnameCompletedFlag = 0
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! javacomplete#UseFQN() abort
|
||||
return g:JavaComplete_UseFQN
|
||||
endfunction
|
||||
|
||||
function! s:RemoveCurrentFromCache() abort
|
||||
let package = javacomplete#complete#complete#GetPackageName()
|
||||
let classname = split(expand('%:t'), '\.')[0]
|
||||
let fqn = package. '.'. classname
|
||||
if has_key(g:JavaComplete_Cache, fqn)
|
||||
call remove(g:JavaComplete_Cache, fqn)
|
||||
endif
|
||||
call javacomplete#server#Communicate('-clear-from-cache', fqn, 's:RemoveCurrentFromCache')
|
||||
call javacomplete#server#Communicate('-async -recompile-class', fqn, 's:RemoveCurrentFromCache')
|
||||
|
||||
let arguments = '-source '. resolve(expand('%:p'))
|
||||
let arguments .= ' -class '. classname
|
||||
let arguments .= ' -package '. package
|
||||
call javacomplete#server#Communicate('-async -add-source-to-cache', arguments, 's:RemoveCurrentFromCache')
|
||||
endfunction
|
||||
|
||||
function! s:DefaultMappings() abort
|
||||
if g:JavaComplete_EnableDefaultMappings
|
||||
return
|
||||
endif
|
||||
|
||||
nmap <silent> <buffer> <leader>jI <Plug>(JavaComplete-Imports-AddMissing)
|
||||
nmap <silent> <buffer> <leader>jR <Plug>(JavaComplete-Imports-RemoveUnused)
|
||||
nmap <silent> <buffer> <leader>ji <Plug>(JavaComplete-Imports-AddSmart)
|
||||
nmap <silent> <buffer> <leader>jii <Plug>(JavaComplete-Imports-Add)
|
||||
nmap <silent> <buffer> <leader>jis <Plug>(JavaComplete-Imports-SortImports)
|
||||
|
||||
imap <silent> <buffer> <C-j>I <Plug>(JavaComplete-Imports-AddMissing)
|
||||
imap <silent> <buffer> <C-j>R <Plug>(JavaComplete-Imports-RemoveUnused)
|
||||
imap <silent> <buffer> <C-j>i <Plug>(JavaComplete-Imports-AddSmart)
|
||||
imap <silent> <buffer> <C-j>ii <Plug>(JavaComplete-Imports-Add)
|
||||
|
||||
nmap <silent> <buffer> <leader>jM <Plug>(JavaComplete-Generate-AbstractMethods)
|
||||
|
||||
imap <silent> <buffer> <C-j>jM <Plug>(JavaComplete-Generate-AbstractMethods)
|
||||
|
||||
nmap <silent> <buffer> <leader>jA <Plug>(JavaComplete-Generate-Accessors)
|
||||
nmap <silent> <buffer> <leader>js <Plug>(JavaComplete-Generate-AccessorSetter)
|
||||
nmap <silent> <buffer> <leader>jg <Plug>(JavaComplete-Generate-AccessorGetter)
|
||||
nmap <silent> <buffer> <leader>ja <Plug>(JavaComplete-Generate-AccessorSetterGetter)
|
||||
nmap <silent> <buffer> <leader>jts <Plug>(JavaComplete-Generate-ToString)
|
||||
nmap <silent> <buffer> <leader>jeq <Plug>(JavaComplete-Generate-EqualsAndHashCode)
|
||||
nmap <silent> <buffer> <leader>jc <Plug>(JavaComplete-Generate-Constructor)
|
||||
nmap <silent> <buffer> <leader>jcc <Plug>(JavaComplete-Generate-DefaultConstructor)
|
||||
|
||||
imap <silent> <buffer> <C-j>s <Plug>(JavaComplete-Generate-AccessorSetter)
|
||||
imap <silent> <buffer> <C-j>g <Plug>(JavaComplete-Generate-AccessorGetter)
|
||||
imap <silent> <buffer> <C-j>a <Plug>(JavaComplete-Generate-AccessorSetterGetter)
|
||||
|
||||
vmap <silent> <buffer> <leader>js <Plug>(JavaComplete-Generate-AccessorSetter)
|
||||
vmap <silent> <buffer> <leader>jg <Plug>(JavaComplete-Generate-AccessorGetter)
|
||||
vmap <silent> <buffer> <leader>ja <Plug>(JavaComplete-Generate-AccessorSetterGetter)
|
||||
|
||||
nmap <silent> <buffer> <leader>jn <Plug>(JavaComplete-Generate-NewClass)
|
||||
nmap <silent> <buffer> <leader>jN <Plug>(JavaComplete-Generate-ClassInFile)
|
||||
endfunction
|
||||
|
||||
augroup javacomplete
|
||||
autocmd!
|
||||
autocmd BufEnter *.java,*.jsp call s:SetCurrentFileKey()
|
||||
autocmd BufEnter *.java call s:DefaultMappings()
|
||||
autocmd BufWritePost *.java call s:RemoveCurrentFromCache()
|
||||
autocmd VimLeave * call javacomplete#server#Terminate()
|
||||
|
||||
if v:version > 704 || v:version == 704 && has('patch143')
|
||||
autocmd TextChangedI *.java,*.jsp call s:HandleTextChangedI()
|
||||
else
|
||||
echohl WarningMsg
|
||||
echomsg 'JavaComplete2 : TextChangedI feature needs vim version >= 7.4.143'
|
||||
echohl None
|
||||
endif
|
||||
autocmd InsertLeave *.java,*.jsp call s:HandleInsertLeave()
|
||||
augroup END
|
||||
|
||||
let g:JavaComplete_Home = fnamemodify(expand('<sfile>'), ':p:h:h:gs?\\?'. g:FILE_SEP. '?')
|
||||
let g:JavaComplete_JavaParserJar = fnamemodify(g:JavaComplete_Home. join(['', 'libs', 'javaparser-core-3.5.20.jar'], g:FILE_SEP), ':p')
|
||||
|
||||
call s:Log('JavaComplete_Home: '. g:JavaComplete_Home)
|
||||
""
|
||||
" path of your sources. Don't try to
|
||||
" add all sources you have, this will slow down parsing process.
|
||||
" Add you project sources and necessery library sources. If you
|
||||
" have compiled classes add them to previous config instead. By
|
||||
" default plugin will search `src` directory and add it
|
||||
" automatically.
|
||||
let g:JavaComplete_SourcesPath = get(g:, 'JavaComplete_SourcesPath', ''). g:PATH_SEP
|
||||
\. join(filter(javacomplete#util#GlobPathList(getcwd(), 'src', 0, 3), "match(v:val, '.*build.*') < 0"), g:PATH_SEP)
|
||||
|
||||
""
|
||||
" disable the maven repository.
|
||||
" >
|
||||
" let g:JavaComplete_MavenRepositoryDisabled = 1
|
||||
" <
|
||||
" by default this option is disabled (0).
|
||||
let g:JavaComplete_MavenRepositoryDisabled = 0
|
||||
|
||||
if filereadable(getcwd(). g:FILE_SEP. 'build.gradle')
|
||||
let g:JavaComplete_SourcesPath = g:JavaComplete_SourcesPath
|
||||
\. g:PATH_SEP
|
||||
\. join(javacomplete#util#GlobPathList(getcwd()
|
||||
\, join(['**', 'build', 'generated', 'source', '**', 'debug'], g:FILE_SEP), 0, 0)
|
||||
\, g:PATH_SEP)
|
||||
endif
|
||||
|
||||
for source in get(g:, 'JavaComplete_SourceExclude', [])
|
||||
let source = fnamemodify(source, ':p')
|
||||
let idx = stridx(g:JavaComplete_SourcesPath, source)
|
||||
while idx > 0
|
||||
let colon = stridx(g:JavaComplete_SourcesPath, ':', idx + 1)
|
||||
let g:JavaComplete_SourcesPath = g:JavaComplete_SourcesPath[:idx - 1] . g:JavaComplete_SourcesPath[colon + 1:]
|
||||
let idx = stridx(g:JavaComplete_SourcesPath, source)
|
||||
endwhile
|
||||
endfor
|
||||
|
||||
call s:Log('Default sources: '. g:JavaComplete_SourcesPath)
|
||||
|
||||
if exists('g:JavaComplete_LibsPath')
|
||||
let g:JavaComplete_LibsPath .= g:PATH_SEP
|
||||
else
|
||||
""
|
||||
" path of you jar files. This path will
|
||||
" always appended with '~/.m2/repository' directory. Here you can
|
||||
" add your glassfish libs directory or your project libs. It will
|
||||
" be automatically appended with you jre home path
|
||||
let g:JavaComplete_LibsPath = ''
|
||||
endif
|
||||
|
||||
call javacomplete#classpath#classpath#BuildClassPath()
|
||||
|
||||
function! javacomplete#Start() abort
|
||||
call javacomplete#server#Start()
|
||||
endfunction
|
||||
|
||||
" vim:set fdm=marker sw=2 nowrap:
|
155
bundle/vim-javacomplete2/autoload/javacomplete/classpath/ant.vim
vendored
Normal file
155
bundle/vim-javacomplete2/autoload/javacomplete/classpath/ant.vim
vendored
Normal file
@ -0,0 +1,155 @@
|
||||
let s:antXmlTemplate = [
|
||||
\ ' <target name="vjc-test-conditions">',
|
||||
\ ' <condition property="vjc-netbeans-condition">',
|
||||
\ ' <isset property="javac.classpath" />',
|
||||
\ ' </condition>',
|
||||
\ ' <condition property="vjc-project-condition">',
|
||||
\ ' <isreference refid="project.classpath"/>',
|
||||
\ ' </condition>',
|
||||
\ ' <condition property="vjc-classpath-condition">',
|
||||
\ ' <isreference refid="classpath"/>',
|
||||
\ ' </condition>',
|
||||
\ ' </target>',
|
||||
\ ' <target name="vjc-netbeans-classpath" depends="vjc-test-conditions" if="vjc-netbeans-condition">',
|
||||
\ ' <property name="javavi.classpath" value="${javac.classpath}" />',
|
||||
\ ' </target>',
|
||||
\ ' <target name="vjc-project-classpath" depends="vjc-test-conditions" if="vjc-project-condition">',
|
||||
\ ' <property name="javavi.classpath" refid="project.classpath"/>',
|
||||
\ ' </target>',
|
||||
\ ' <target name="vjc-classpath" depends="vjc-test-conditions" if="vjc-classpath-condition">',
|
||||
\ ' <property name="javavi.classpath" refid="project.classpath"/>',
|
||||
\ ' </target>',
|
||||
\ ' <target name="vjc-printclasspath" depends="vjc-project-classpath,vjc-netbeans-classpath,vjc-classpath">',
|
||||
\ ' <echo message="${javavi.classpath}"/>',
|
||||
\ ' </target>']
|
||||
|
||||
function! s:Log(log)
|
||||
let log = type(a:log) == type("") ? a:log : string(a:log)
|
||||
call javacomplete#logger#Log("[classpath.ant] ". log)
|
||||
endfunction
|
||||
|
||||
function! javacomplete#classpath#ant#IfAnt()
|
||||
if executable('ant') && g:JavaComplete_AntPath != ""
|
||||
return 1
|
||||
endif
|
||||
return 0
|
||||
endfunction
|
||||
|
||||
function! javacomplete#classpath#ant#Generate(force) abort
|
||||
let g:JavaComplete_ProjectKey = substitute(g:JavaComplete_AntPath, '[\\/:;.]', '_', 'g')
|
||||
let path = javacomplete#util#GetBase("classpath". g:FILE_SEP). g:JavaComplete_ProjectKey
|
||||
|
||||
if filereadable(path)
|
||||
if a:force == 0 && getftime(path) >= getftime(g:JavaComplete_AntPath)
|
||||
call s:Log("get libs from cache file")
|
||||
return join(readfile(path), '')
|
||||
endif
|
||||
call javacomplete#util#RemoveFile(javacomplete#util#GetBase('cache'). g:FILE_SEP. 'class_packages_'. g:JavaComplete_ProjectKey. '.dat')
|
||||
endif
|
||||
|
||||
let s:antPath = path
|
||||
let s:antOutput = []
|
||||
let cmd = "ant -projecthelp -v | grep '^ init\\>'"
|
||||
call javacomplete#util#RunSystem(
|
||||
\ cmd, "ant check 'init' target process",
|
||||
\ "javacomplete#classpath#ant#CheckInitTargetHandler")
|
||||
return '.'
|
||||
endfunction
|
||||
|
||||
function! javacomplete#classpath#ant#CheckInitTargetHandler(data, event)
|
||||
if a:event == 'exit'
|
||||
if a:data == "0"
|
||||
let hasInitTarget = !empty(s:antOutput)
|
||||
let s:antOutput = []
|
||||
call s:BuildAntClasspath(hasInitTarget)
|
||||
else
|
||||
echohl WarningMsg | echomsg "Failed to check 'init' target" | echohl None
|
||||
endif
|
||||
elseif a:event == 'stdout'
|
||||
for data in filter(a:data,'v:val =~ "^ init\\>.*$"')
|
||||
if g:JavaComplete_ShowExternalCommandsOutput
|
||||
echomsg data
|
||||
endif
|
||||
if exists('s:antOutput')
|
||||
call add(s:antOutput, data)
|
||||
endif
|
||||
endfor
|
||||
elseif a:event == 'stderr'
|
||||
for data in filter(a:data,'v:val !~ "^\\s*$"')
|
||||
echoerr data
|
||||
endfor
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:BuildAntClasspath(hasInitTarget)
|
||||
let tmpBuildFile = []
|
||||
for line in readfile(g:JavaComplete_AntPath)
|
||||
if stridx(line, '</project>') >= 0
|
||||
if a:hasInitTarget
|
||||
let xmlTemplate = s:antXmlTemplate
|
||||
let xmlTemplate[0] = xmlTemplate[0][:-2]. ' depends="init">'
|
||||
call extend(tmpBuildFile, xmlTemplate)
|
||||
else
|
||||
call extend(tmpBuildFile, s:antXmlTemplate)
|
||||
endif
|
||||
endif
|
||||
call add(tmpBuildFile, line)
|
||||
endfor
|
||||
let s:tmpAntFileName = "vjc-ant-build.xml"
|
||||
call writefile(tmpBuildFile, s:tmpAntFileName)
|
||||
|
||||
let s:antOutput = []
|
||||
let antCmd = ['ant', '-f', s:tmpAntFileName, '-q', 'vjc-printclasspath']
|
||||
call javacomplete#util#RunSystem(
|
||||
\ antCmd, "ant classpath build process",
|
||||
\ "javacomplete#classpath#ant#BuildClasspathHandler")
|
||||
endfunction
|
||||
|
||||
function! javacomplete#classpath#ant#BuildClasspathHandler(data, event)
|
||||
if a:event == 'exit'
|
||||
if a:data == "0"
|
||||
for line in s:antOutput
|
||||
let matches = matchlist(line, '\m^\s\+\[echo\]\s\+\(.*\)')
|
||||
if !empty(matches)
|
||||
let cp = matches[1]
|
||||
break
|
||||
endif
|
||||
endfor
|
||||
if cp != '.'
|
||||
call writefile([cp], s:antPath)
|
||||
endif
|
||||
|
||||
let g:JavaComplete_LibsPath .= ':'. cp
|
||||
|
||||
call javacomplete#util#RemoveFile(javacomplete#util#GetBase('cache'). g:FILE_SEP. 'class_packages_'. g:JavaComplete_ProjectKey. '.dat')
|
||||
|
||||
call javacomplete#server#UnblockStart()
|
||||
call javacomplete#server#Terminate()
|
||||
call javacomplete#server#Start()
|
||||
|
||||
echomsg "Ant classpath built successfully"
|
||||
else
|
||||
echohl WarningMsg | echomsg "Failed to build ant classpath" | echohl None
|
||||
endif
|
||||
|
||||
call delete(s:tmpAntFileName)
|
||||
|
||||
unlet s:antOutput
|
||||
unlet s:tmpAntFileName
|
||||
|
||||
elseif a:event == 'stdout'
|
||||
for data in filter(a:data,'v:val !~ "^\\s*$"')
|
||||
if g:JavaComplete_ShowExternalCommandsOutput
|
||||
echomsg data
|
||||
endif
|
||||
endfor
|
||||
if exists('s:antOutput')
|
||||
call extend(s:antOutput, a:data)
|
||||
endif
|
||||
elseif a:event == 'stderr'
|
||||
for data in filter(a:data,'v:val !~ "^\\s*$"')
|
||||
echoerr data
|
||||
endfor
|
||||
endif
|
||||
endfunction
|
||||
" vim:set fdm=marker sw=2 nowrap:
|
118
bundle/vim-javacomplete2/autoload/javacomplete/classpath/classpath.vim
vendored
Normal file
118
bundle/vim-javacomplete2/autoload/javacomplete/classpath/classpath.vim
vendored
Normal file
@ -0,0 +1,118 @@
|
||||
function! s:Log(log)
|
||||
let log = type(a:log) == type("") ? a:log : string(a:log)
|
||||
call javacomplete#logger#Log("[classpath] ". log)
|
||||
endfunction
|
||||
|
||||
function! javacomplete#classpath#classpath#BuildClassPath()
|
||||
call s:BuildClassPath(0)
|
||||
endfunction
|
||||
|
||||
function! javacomplete#classpath#classpath#RebuildClassPath()
|
||||
call s:BuildClassPath(1)
|
||||
endfunction
|
||||
|
||||
function! s:BuildClassPath(force)
|
||||
if !g:JavaComplete_MavenRepositoryDisabled
|
||||
if empty('g:JavaComplete_PomPath')
|
||||
let g:JavaComplete_PomPath = javacomplete#util#FindFile('pom.xml')
|
||||
if g:JavaComplete_PomPath != ""
|
||||
let g:JavaComplete_PomPath = fnamemodify(g:JavaComplete_PomPath, ':p')
|
||||
call s:Log("found maven file: ". g:JavaComplete_PomPath)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
if !get(g:, 'JavaComplete_GradleRepositoryDisabled', 0)
|
||||
if !exists('g:JavaComplete_GradlePath')
|
||||
if filereadable(getcwd(). g:FILE_SEP. "build.gradle")
|
||||
let g:JavaComplete_GradlePath = getcwd(). g:FILE_SEP. "build.gradle"
|
||||
else
|
||||
let g:JavaComplete_GradlePath = javacomplete#util#FindFile('build.gradle', '**3')
|
||||
endif
|
||||
if g:JavaComplete_GradlePath != ""
|
||||
let g:JavaComplete_GradlePath = fnamemodify(g:JavaComplete_GradlePath, ':p')
|
||||
call s:Log("found gradle file: ". g:JavaComplete_GradlePath)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
if !get(g:, 'JavaComplete_AntRepositoryDisabled', 0)
|
||||
if !exists('g:JavaComplete_AntPath')
|
||||
if filereadable(getcwd(). g:FILE_SEP. "build.xml")
|
||||
let g:JavaComplete_AntPath = getcwd(). g:FILE_SEP. "build.xml"
|
||||
else
|
||||
let g:JavaComplete_AntPath = javacomplete#util#FindFile('build.xml', '**3')
|
||||
endif
|
||||
if g:JavaComplete_AntPath != ""
|
||||
let g:JavaComplete_AntPath = fnamemodify(g:JavaComplete_AntPath, ':p')
|
||||
call s:Log("found ant file: ". g:JavaComplete_AntPath)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
let g:JavaComplete_LibsPath .= s:FindClassPath(a:force)
|
||||
|
||||
call s:Log("libs found: ". g:JavaComplete_LibsPath)
|
||||
endfunction
|
||||
|
||||
function! s:ReadClassPathFile(classpathFile)
|
||||
let cp = ''
|
||||
let file = g:JavaComplete_Home. join(['', 'autoload', 'classpath.py'], g:FILE_SEP)
|
||||
execute "JavacompletePyfile" file
|
||||
JavacompletePy import vim
|
||||
JavacompletePy vim.command("let cp = '%s'" % os.pathsep.join(ReadClasspathFile(vim.eval('a:classpathFile'))).replace('\\', '/'))
|
||||
return cp
|
||||
endfunction
|
||||
|
||||
function! s:UseEclipse(force)
|
||||
if has('python') || has('python3')
|
||||
let classpathFile = fnamemodify(findfile('.classpath', escape(expand('.'), '*[]?{}, ') . ';'), ':p')
|
||||
if !empty(classpathFile) && filereadable(classpathFile)
|
||||
return s:ReadClassPathFile(classpathFile)
|
||||
endif
|
||||
endif
|
||||
|
||||
return ""
|
||||
endf
|
||||
|
||||
function! s:UseMaven(force)
|
||||
if javacomplete#classpath#maven#IfMaven()
|
||||
return javacomplete#classpath#maven#Generate(a:force)
|
||||
endif
|
||||
|
||||
return ""
|
||||
endf
|
||||
|
||||
function! s:UseGradle(force)
|
||||
if javacomplete#classpath#gradle#IfGradle()
|
||||
return javacomplete#classpath#gradle#Generate(a:force)
|
||||
endif
|
||||
|
||||
return ""
|
||||
endf
|
||||
|
||||
function! s:UseAnt(force)
|
||||
if javacomplete#classpath#ant#IfAnt()
|
||||
return javacomplete#classpath#ant#Generate(a:force)
|
||||
endif
|
||||
|
||||
return ""
|
||||
endf
|
||||
|
||||
function! s:FindClassPath(force) abort
|
||||
for classpathSourceType in g:JavaComplete_ClasspathGenerationOrder
|
||||
try
|
||||
let cp = ''
|
||||
exec "let cp .= s:Use". classpathSourceType. "(". a:force. ")"
|
||||
if !empty(cp)
|
||||
call s:Log("found ". classpathSourceType. " project")
|
||||
return '.' . g:PATH_SEP . cp
|
||||
endif
|
||||
catch
|
||||
endtry
|
||||
endfor
|
||||
|
||||
return '.'
|
||||
endfunction
|
||||
|
||||
" vim:set fdm=marker sw=2 nowrap:
|
127
bundle/vim-javacomplete2/autoload/javacomplete/classpath/gradle.vim
vendored
Normal file
127
bundle/vim-javacomplete2/autoload/javacomplete/classpath/gradle.vim
vendored
Normal file
@ -0,0 +1,127 @@
|
||||
function! javacomplete#classpath#gradle#IfGradle()
|
||||
if !empty(g:JavaComplete_GradleExecutable)
|
||||
if executable(g:JavaComplete_GradleExecutable) && g:JavaComplete_GradlePath != ""
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
end
|
||||
endif
|
||||
|
||||
if g:JavaComplete_GradlePath != "" && s:IsGradleExecutable() && g:JavaComplete_GradlePath != ""
|
||||
return 1
|
||||
endif
|
||||
return 0
|
||||
endfunction
|
||||
|
||||
function! s:IsGradleExecutable()
|
||||
let osExec = javacomplete#util#IsWindows() ? '\gradlew.bat' : '/gradlew'
|
||||
let path = fnamemodify(g:JavaComplete_GradlePath, ':p:h')
|
||||
return executable('gradle') || executable(path. osExec)
|
||||
endfunction
|
||||
|
||||
function! javacomplete#classpath#gradle#BuildClasspathHandler(data, event)
|
||||
if a:event == 'exit'
|
||||
if a:data == "0"
|
||||
let cp = ''
|
||||
for i in range(len(s:gradleOutput))
|
||||
if s:gradleOutput[i] =~ '^CLASSPATH:'
|
||||
let cp .= s:gradleOutput[i][10:]
|
||||
for j in range(i, len(s:gradleOutput) - 1)
|
||||
if s:gradleOutput[j] !~ '^END CLASSPATH GENERATION'
|
||||
let cp .= s:gradleOutput[j]
|
||||
else
|
||||
break
|
||||
endif
|
||||
endfor
|
||||
break
|
||||
endif
|
||||
endfor
|
||||
let g:JavaComplete_LibsPath .= ':'. cp
|
||||
|
||||
call writefile([cp], s:gradlePath)
|
||||
|
||||
call javacomplete#util#RemoveFile(javacomplete#util#GetBase('cache'). g:FILE_SEP. 'class_packages_'. g:JavaComplete_ProjectKey. '.dat')
|
||||
|
||||
call javacomplete#server#UnblockStart()
|
||||
call javacomplete#server#Terminate()
|
||||
call javacomplete#server#Start()
|
||||
|
||||
echomsg "Gradle classpath built successfully"
|
||||
else
|
||||
echohl WarningMsg | echomsg "Failed to build gradle classpath" | echohl None
|
||||
endif
|
||||
|
||||
call delete(s:temporaryGradleFile)
|
||||
|
||||
unlet s:temporaryGradleFile
|
||||
unlet s:gradleOutput
|
||||
unlet s:gradlePath
|
||||
|
||||
elseif a:event == 'stdout'
|
||||
for data in filter(a:data,'v:val !~ "^\\s*$"')
|
||||
if g:JavaComplete_ShowExternalCommandsOutput
|
||||
echomsg data
|
||||
endif
|
||||
endfor
|
||||
if exists('s:gradleOutput')
|
||||
call extend(s:gradleOutput, a:data)
|
||||
endif
|
||||
elseif a:event == 'stderr'
|
||||
for data in filter(a:data,'v:val !~ "^\\s*$"')
|
||||
echoerr data
|
||||
endfor
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! javacomplete#classpath#gradle#Generate(force) abort
|
||||
let base = javacomplete#util#GetBase("classpath". g:FILE_SEP)
|
||||
let g:JavaComplete_ProjectKey = substitute(g:JavaComplete_GradlePath, '[\\/:;.]', '_', 'g')
|
||||
|
||||
let path = base . g:JavaComplete_ProjectKey
|
||||
if filereadable(path)
|
||||
if a:force == 0 && getftime(path) >= getftime(g:JavaComplete_GradlePath)
|
||||
return join(readfile(path), '')
|
||||
endif
|
||||
call javacomplete#util#RemoveFile(javacomplete#util#GetBase('cache'). g:FILE_SEP. 'class_packages_'. g:JavaComplete_ProjectKey. '.dat')
|
||||
endif
|
||||
call s:GenerateClassPath(path)
|
||||
return ''
|
||||
endfunction
|
||||
|
||||
function! s:GenerateClassPath(path) abort
|
||||
let s:temporaryGradleFile = tempname()
|
||||
let s:gradleOutput = []
|
||||
let s:gradlePath = a:path
|
||||
if exists(g:JavaComplete_GradleExecutable)
|
||||
let gradle = g:JavaComplete_GradleExecutable
|
||||
else
|
||||
let gradle = fnamemodify(
|
||||
\ g:JavaComplete_GradlePath, ':p:h')
|
||||
\ . (javacomplete#util#IsWindows()
|
||||
\ ?
|
||||
\ '\gradlew.bat'
|
||||
\ :
|
||||
\ '/gradlew')
|
||||
if !executable(gradle)
|
||||
let gradle = 'gradle'
|
||||
endif
|
||||
endif
|
||||
call writefile(
|
||||
\ ["rootProject{apply from: '"
|
||||
\ . g:JavaComplete_Home. g:FILE_SEP. "classpath.gradle'}"],
|
||||
\ s:temporaryGradleFile)
|
||||
let cmd = [
|
||||
\ gradle,
|
||||
\ '-p',
|
||||
\ fnamemodify(g:JavaComplete_GradlePath, ':p:h'),
|
||||
\ '-I',
|
||||
\ s:temporaryGradleFile,
|
||||
\ ':classpath']
|
||||
call javacomplete#server#BlockStart()
|
||||
call javacomplete#util#RunSystem(
|
||||
\ cmd,
|
||||
\ 'gradle classpath build process',
|
||||
\ 'javacomplete#classpath#gradle#BuildClasspathHandler')
|
||||
endfunction
|
||||
|
||||
" vim:set fdm=marker sw=2 nowrap:
|
122
bundle/vim-javacomplete2/autoload/javacomplete/classpath/maven.vim
vendored
Normal file
122
bundle/vim-javacomplete2/autoload/javacomplete/classpath/maven.vim
vendored
Normal file
@ -0,0 +1,122 @@
|
||||
let s:pomProperties={} "maven project properties
|
||||
let s:pomTags = ['build', 'properties']
|
||||
let s:mavenErrors = []
|
||||
|
||||
function! javacomplete#classpath#maven#IfMaven()
|
||||
if executable('mvn') && g:JavaComplete_PomPath != ""
|
||||
return 1
|
||||
endif
|
||||
return 0
|
||||
endfunction
|
||||
|
||||
function! javacomplete#classpath#maven#Generate(force) abort
|
||||
if a:force != 0
|
||||
let s:pomProperties = {}
|
||||
endif
|
||||
let g:JavaComplete_ProjectKey = substitute(g:JavaComplete_PomPath, '[\\/:;.]', '_', 'g')
|
||||
let path = javacomplete#util#GetBase("classpath". g:FILE_SEP). g:JavaComplete_ProjectKey
|
||||
|
||||
if filereadable(path)
|
||||
if a:force == 0 && getftime(path) >= getftime(g:JavaComplete_PomPath)
|
||||
return join(readfile(path), '')
|
||||
endif
|
||||
call javacomplete#util#RemoveFile(javacomplete#util#GetBase('cache'). g:FILE_SEP. 'class_packages_'. g:JavaComplete_ProjectKey. '.dat')
|
||||
endif
|
||||
|
||||
if !has_key(s:pomProperties, g:JavaComplete_PomPath)
|
||||
let s:mavenPath = path
|
||||
let s:mavenPom = g:JavaComplete_PomPath
|
||||
let s:mavenSettingsOutput = []
|
||||
let mvnCmd = ['mvn', '-B', '--file', g:JavaComplete_PomPath, 'dependency:build-classpath', '-DincludeScope=test']
|
||||
call javacomplete#server#BlockStart()
|
||||
call javacomplete#util#RunSystem(mvnCmd, 'maven classpath build process', 'javacomplete#classpath#maven#BuildClasspathHandler')
|
||||
return ""
|
||||
endif
|
||||
|
||||
return s:GetMavenClasspath(path, g:JavaComplete_PomPath)
|
||||
endfunction
|
||||
|
||||
function! s:GetMavenClasspath(path, pom)
|
||||
let mvnProperties = s:pomProperties[a:pom]
|
||||
let cp = get(mvnProperties, 'project.dependencybuildclasspath', '.')
|
||||
let cp .= g:PATH_SEP . get(mvnProperties, 'project.build.outputDirectory', join([fnamemodify(a:pom, ':h'), 'target', 'classes'], g:FILE_SEP))
|
||||
let cp .= g:PATH_SEP . get(mvnProperties, 'project.build.testOutputDirectory', join([fnamemodify(a:pom, ':h'), 'target', 'test-classes'], g:FILE_SEP))
|
||||
if cp != '.'
|
||||
call writefile([cp], a:path)
|
||||
endif
|
||||
return cp
|
||||
endfunction
|
||||
|
||||
function! s:ParseMavenOutput()
|
||||
let mvnProperties = {}
|
||||
let mvnIsManagedTag = 1
|
||||
let currentPath = 'project'
|
||||
for i in range(len(s:mavenSettingsOutput))
|
||||
if s:mavenSettingsOutput[i] =~ 'Dependencies classpath:'
|
||||
let mvnProperties['project.dependencybuildclasspath'] = s:mavenSettingsOutput[i + 1]
|
||||
let offset = 2
|
||||
while s:mavenSettingsOutput[i + offset] !~ '^[INFO.*'
|
||||
let mvnProperties['project.dependencybuildclasspath'] .= s:mavenSettingsOutput[i + offset]
|
||||
let offset += 1
|
||||
endwhile
|
||||
endif
|
||||
let matches = matchlist(s:mavenSettingsOutput[i], '\m^\s*<\([a-zA-Z0-9\-\.]\+\)>\s*$')
|
||||
if mvnIsManagedTag && !empty(matches)
|
||||
let mvnIsManagedTag = index(s:pomTags, matches[1]) >= 0
|
||||
let currentPath .= '.'. matches[1]
|
||||
else
|
||||
let matches = matchlist(s:mavenSettingsOutput[i], '\m^\s*</\([a-zA-Z0-9\-\.]\+\)>\s*$')
|
||||
if !empty(matches)
|
||||
let mvnIsManagedTag = index(s:pomTags, matches[1]) < 0
|
||||
let currentPath = substitute(currentPath, '\m\.'. matches[1]. '$', '', '')
|
||||
else
|
||||
let matches = matchlist(s:mavenSettingsOutput[i], '\m^\s*<\([a-zA-Z0-9\-\.]\+\)>\(.\+\)</[a-zA-Z0-9\-\.]\+>\s*$')
|
||||
if mvnIsManagedTag && !empty(matches)
|
||||
let mvnProperties[currentPath. '.'. matches[1]] = matches[2]
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endfor
|
||||
let s:pomProperties[s:mavenPom] = mvnProperties
|
||||
endfunction
|
||||
|
||||
function! javacomplete#classpath#maven#BuildClasspathHandler(data, event)
|
||||
if a:event == 'exit'
|
||||
if a:data == "0"
|
||||
call s:ParseMavenOutput()
|
||||
|
||||
let g:JavaComplete_LibsPath .= s:GetMavenClasspath(s:mavenPath, s:mavenPom)
|
||||
|
||||
call javacomplete#util#RemoveFile(javacomplete#util#GetBase('cache'). g:FILE_SEP. 'class_packages_'. g:JavaComplete_ProjectKey. '.dat')
|
||||
|
||||
call javacomplete#server#UnblockStart()
|
||||
call javacomplete#server#Terminate()
|
||||
call javacomplete#server#Start()
|
||||
|
||||
echomsg "Maven classpath built successfully"
|
||||
else
|
||||
echoerr join(s:mavenErrors, "\n")
|
||||
let s:mavenErrors = []
|
||||
echohl WarningMsg | echomsg "Failed to build maven classpath" | echohl None
|
||||
endif
|
||||
|
||||
unlet s:mavenPath
|
||||
unlet s:mavenPom
|
||||
unlet s:mavenSettingsOutput
|
||||
elseif a:event == 'stdout'
|
||||
for data in filter(a:data,'v:val !~ "^\\s*$"')
|
||||
if g:JavaComplete_ShowExternalCommandsOutput
|
||||
echomsg data
|
||||
elseif data =~ '^\[ERROR\]\w*' || data =~ '^\[WARNING\]\w*'
|
||||
echohl WarningMsg | echomsg data | echohl None
|
||||
endif
|
||||
endfor
|
||||
call extend(s:mavenSettingsOutput, a:data)
|
||||
elseif a:event == 'stderr'
|
||||
for data in filter(a:data,'v:val !~ "^\\s*$"')
|
||||
call add(s:mavenErrors, data)
|
||||
endfor
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" vim:set fdm=marker sw=2 nowrap:
|
686
bundle/vim-javacomplete2/autoload/javacomplete/collector.vim
vendored
Normal file
686
bundle/vim-javacomplete2/autoload/javacomplete/collector.vim
vendored
Normal file
@ -0,0 +1,686 @@
|
||||
" Vim completion script for java
|
||||
" Maintainer: artur shaik <ashaihullin@gmail.com>
|
||||
"
|
||||
" This file contains everything related to collecting source data
|
||||
|
||||
function! s:Log(log)
|
||||
let log = type(a:log) == type("") ? a:log : string(a:log)
|
||||
call javacomplete#logger#Log("[collector] ". log)
|
||||
endfunction
|
||||
|
||||
" a:1 - filepath
|
||||
" a:2 - package name
|
||||
function! javacomplete#collector#DoGetClassInfo(class, ...)
|
||||
let class = type(a:class) == type({}) ? a:class.name : a:class
|
||||
call s:Log("get class info. class: ". class)
|
||||
|
||||
if class != 'this' && class != 'super' && has_key(g:JavaComplete_Cache, class)
|
||||
call s:Log("class info from cache")
|
||||
return g:JavaComplete_Cache[class]
|
||||
endif
|
||||
|
||||
" array type: TypeName[] or '[I' or '[[Ljava.lang.String;'
|
||||
if class[-1:] == ']' || class[0] == '['
|
||||
return g:J_ARRAY_TYPE_INFO
|
||||
endif
|
||||
|
||||
let filekey = a:0 > 0 && len(a:1) > 0 ? a:1 : javacomplete#GetCurrentFileKey()
|
||||
let packagename = a:0 > 1 && len(a:2) > 0 ? a:2 : javacomplete#collector#GetPackageName()
|
||||
|
||||
let unit = javacomplete#parseradapter#Parse(filekey)
|
||||
let pos = java_parser#MakePos(line('.') - 1, col('.') - 1)
|
||||
let t = get(javacomplete#parseradapter#SearchTypeAt(unit, pos), -1, {})
|
||||
if has_key(t, 'extends')
|
||||
if type(t.extends) == type([]) && len(t.extends) > 0
|
||||
if type(t.extends[0]) == type("")
|
||||
let extends = t.extends[0] . '$'. class
|
||||
elseif type(t.extends[0]) == type({})
|
||||
if has_key(t.extends[0], 'name')
|
||||
let className = t.extends[0].name
|
||||
elseif has_key(t.extends[0], 'clazz')
|
||||
let className = t.extends[0].clazz.name
|
||||
else
|
||||
let className = ''
|
||||
endif
|
||||
if !empty(className)
|
||||
let imports = javacomplete#imports#GetImports('imports_fqn', filekey)
|
||||
let fqn = javacomplete#imports#SearchSingleTypeImport(className, imports)
|
||||
let extends = fqn. '$'. a:class
|
||||
endif
|
||||
else
|
||||
let extends = ''
|
||||
endif
|
||||
else
|
||||
let extends = ''
|
||||
endif
|
||||
else
|
||||
let extends = ''
|
||||
endif
|
||||
if class == 'this' || class == 'super' || (has_key(t, 'fqn') && t.fqn == packagename. '.'. class)
|
||||
if &ft == 'jsp'
|
||||
let ci = javacomplete#collector#FetchClassInfo('javax.servlet.jsp.HttpJspPage')
|
||||
return ci
|
||||
endif
|
||||
|
||||
call s:Log('A0. ' . class)
|
||||
if !empty(t)
|
||||
return javacomplete#util#Sort(s:Tree2ClassInfo(t))
|
||||
else
|
||||
return {}
|
||||
endif
|
||||
endif
|
||||
for def in get(t, 'defs', [])
|
||||
if get(def, 'tag', '') == 'CLASSDEF' && get(def, 'name', '') == class
|
||||
return javacomplete#util#Sort(s:Tree2ClassInfo(def))
|
||||
endif
|
||||
endfor
|
||||
|
||||
let typename = class
|
||||
|
||||
let typeArguments = ''
|
||||
let splittedType = s:SplitTypeArguments(typename)
|
||||
if type(splittedType) == type([])
|
||||
let typename = splittedType[0]
|
||||
let typeArguments = splittedType[1]
|
||||
endif
|
||||
|
||||
if stridx(typename, '$') > 0
|
||||
let sc = split(typename, '\$')
|
||||
let typename = sc[0]
|
||||
let nested = '$'.sc[1]
|
||||
else
|
||||
let nested = ''
|
||||
endif
|
||||
|
||||
let hasKeyword = javacomplete#util#HasKeyword(typename)
|
||||
if typename !~ '^\s*' . g:RE_QUALID . '\s*$' || hasKeyword
|
||||
call s:Log("no qualid: ". typename)
|
||||
return {}
|
||||
endif
|
||||
|
||||
let collectedArguments = s:CollectTypeArguments(typeArguments, packagename, filekey)
|
||||
|
||||
let fqns = s:CollectFQNs(typename, packagename, filekey, extends)
|
||||
for fqn in fqns
|
||||
let fqn = fqn . nested . collectedArguments
|
||||
let fqn = substitute(fqn, ' ', '', 'g')
|
||||
call javacomplete#collector#FetchClassInfo(fqn)
|
||||
|
||||
let key = s:KeyInCache(fqn)
|
||||
if !empty(key)
|
||||
return get(g:JavaComplete_Cache[key], 'tag', '') == 'CLASSDEF' ? g:JavaComplete_Cache[key] : {}
|
||||
endif
|
||||
endfor
|
||||
|
||||
return {}
|
||||
endfunction
|
||||
|
||||
function! javacomplete#collector#GetPackageName()
|
||||
let lnum_old = line('.')
|
||||
let col_old = col('.')
|
||||
|
||||
call cursor(1, 1)
|
||||
let lnum = search('^\s*package[ \t\r\n]\+\([a-zA-Z][a-zA-Z0-9._]*\);', 'w')
|
||||
let packageName = substitute(getline(lnum), '^\s*package\s\+\([a-zA-Z][a-zA-Z0-9._]*\);', '\1', '')
|
||||
|
||||
call cursor(lnum_old, col_old)
|
||||
return packageName
|
||||
endfunction
|
||||
|
||||
function! javacomplete#collector#FetchClassInfo(fqn)
|
||||
call javacomplete#collector#FetchInfoFromServer(a:fqn, '-E')
|
||||
endfunction
|
||||
|
||||
function! javacomplete#collector#FetchInfoFromServer(class, option)
|
||||
if has_key(g:JavaComplete_Cache, substitute(a:class, '\$', '.', 'g'))
|
||||
return g:JavaComplete_Cache[substitute(a:class, '\$', '.', 'g')]
|
||||
endif
|
||||
|
||||
let res = javacomplete#server#Communicate(a:option, a:class, 'collector#FetchInfoFromServer')
|
||||
if res =~ "^{'"
|
||||
silent! let dict = eval(res)
|
||||
if !empty(dict) && type(dict)==type({})
|
||||
for key in keys(dict)
|
||||
if !has_key(g:JavaComplete_Cache, key)
|
||||
if type(dict[key]) == type({})
|
||||
let g:JavaComplete_Cache[substitute(key, '\$', '.', '')] = javacomplete#util#Sort(dict[key])
|
||||
elseif type(dict[key]) == type([])
|
||||
let g:JavaComplete_Cache[substitute(key, '\$', '.', '')] = sort(dict[key])
|
||||
endif
|
||||
endif
|
||||
endfor
|
||||
else
|
||||
let b:errormsg = dict
|
||||
endif
|
||||
else
|
||||
let b:errormsg = res
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:SplitTypeArguments(typename)
|
||||
if a:typename =~ g:RE_TYPE_WITH_ARGUMENTS
|
||||
let lbridx = stridx(a:typename, '<')
|
||||
let typeArguments = a:typename[lbridx + 1 : -2]
|
||||
let typename = a:typename[0 : lbridx - 1]
|
||||
return [typename, typeArguments]
|
||||
endif
|
||||
|
||||
let lbridx = stridx(a:typename, '<')
|
||||
if lbridx > 0
|
||||
let typename = a:typename[0 : lbridx - 1]
|
||||
return [typename, 0]
|
||||
endif
|
||||
|
||||
return a:typename
|
||||
endfunction
|
||||
|
||||
function! s:CollectTypeArguments(typeArguments, packagename, filekey)
|
||||
let collectedArguments = ''
|
||||
if !empty(a:typeArguments)
|
||||
let typeArguments = a:typeArguments
|
||||
let i = 0
|
||||
let lbr = 0
|
||||
while i < len(typeArguments)
|
||||
let c = typeArguments[i]
|
||||
if c == '<'
|
||||
let lbr += 1
|
||||
elseif c == '>'
|
||||
let lbr -= 1
|
||||
endif
|
||||
|
||||
if c == ',' && lbr == 0
|
||||
let typeArguments = typeArguments[0 : i - 1] . "<_split_>". typeArguments[i + 1 : -1]
|
||||
let i += 9
|
||||
else
|
||||
let i += 1
|
||||
endif
|
||||
endwhile
|
||||
|
||||
for arg in split(typeArguments, "<_split_>")
|
||||
let argTypeArguments = ''
|
||||
if arg =~ g:RE_TYPE_WITH_ARGUMENTS
|
||||
let lbridx = stridx(arg, '<')
|
||||
let argTypeArguments = arg[lbridx : -1]
|
||||
let arg = arg[0 : lbridx - 1]
|
||||
endif
|
||||
|
||||
if arg =~ g:RE_TYPE_ARGUMENT_EXTENDS
|
||||
let i = matchend(arg, g:RE_TYPE)
|
||||
let arg = arg[i+1 : -1]
|
||||
endif
|
||||
|
||||
let fqns = s:CollectFQNs(arg, a:packagename, a:filekey, '')
|
||||
let collectedArguments .= ''
|
||||
if len(fqns) > 1
|
||||
let collectedArguments .= '('
|
||||
endif
|
||||
for fqn in fqns
|
||||
if len(fqn) > 0
|
||||
let collectedArguments .= fqn. argTypeArguments. '|'
|
||||
endif
|
||||
endfor
|
||||
if len(fqns) > 1
|
||||
let collectedArguments = collectedArguments[0:-2]. '),'
|
||||
else
|
||||
let collectedArguments = collectedArguments[0:-2]. ','
|
||||
endif
|
||||
endfor
|
||||
if !empty(collectedArguments)
|
||||
let collectedArguments = '<'. collectedArguments[0:-2]. '>'
|
||||
endif
|
||||
endif
|
||||
|
||||
return collectedArguments
|
||||
endfunction
|
||||
|
||||
function! s:Tree2ClassInfo(t)
|
||||
let t = a:t
|
||||
|
||||
" fill fields and methods
|
||||
let t.fields = []
|
||||
let t.methods = []
|
||||
let t.ctors = []
|
||||
let t.classes = []
|
||||
for def in t.defs
|
||||
if type(def) == type([]) && len(def) == 1
|
||||
let tmp = def[0]
|
||||
unlet def
|
||||
let def = tmp
|
||||
unlet tmp
|
||||
endif
|
||||
let tag = get(def, 'tag', '')
|
||||
if tag == 'METHODDEF'
|
||||
call add(def.n == t.name ? t.ctors : t.methods, def)
|
||||
elseif tag == 'VARDEF'
|
||||
call add(t.fields, def)
|
||||
elseif tag == 'CLASSDEF'
|
||||
call add(t.classes, t.fqn . '.' . def.name)
|
||||
endif
|
||||
unlet def
|
||||
endfor
|
||||
|
||||
for line in reverse(getline(0, '.'))
|
||||
let matches = matchlist(line, g:RE_TYPE_DECL_HEAD. t.name)
|
||||
if len(matches)
|
||||
if matches[1] == 'interface'
|
||||
let t.interface = 1
|
||||
elseif matches[1] == 'enum'
|
||||
let t.enum = 1
|
||||
endif
|
||||
break
|
||||
endif
|
||||
endfor
|
||||
|
||||
" convert type name in extends to fqn for class defined in source files
|
||||
if has_key(a:t, 'filepath') && a:t.filepath != javacomplete#GetCurrentFileKey()
|
||||
let filepath = a:t.filepath
|
||||
let packagename = get(g:JavaComplete_Files[filepath].unit, 'package', '')
|
||||
else
|
||||
let filepath = expand('%:p')
|
||||
let packagename = javacomplete#collector#GetPackageName()
|
||||
endif
|
||||
|
||||
if !has_key(a:t, 'extends')
|
||||
let a:t.extends = ['java.lang.Object']
|
||||
endif
|
||||
|
||||
let extends = a:t.extends
|
||||
if has_key(a:t, 'implements')
|
||||
let extends += a:t.implements
|
||||
endif
|
||||
|
||||
let i = 0
|
||||
while i < len(extends)
|
||||
if type(extends[i]) == type("") && extends[i] == get(t, 'fqn', '')
|
||||
let i += 1
|
||||
continue
|
||||
elseif type(extends[i]) == type({}) && extends[i].tag == 'ERRONEOUS'
|
||||
let i += 1
|
||||
continue
|
||||
endif
|
||||
let type2str = java_parser#type2Str(extends[i])
|
||||
let ci = javacomplete#collector#DoGetClassInfo(type2str, filepath, packagename)
|
||||
if type(ci) == type([])
|
||||
let ci = [0]
|
||||
endif
|
||||
if has_key(ci, 'fqn')
|
||||
let extends[i] = ci.fqn
|
||||
endif
|
||||
let i += 1
|
||||
endwhile
|
||||
let t.extends = javacomplete#util#uniq(extends)
|
||||
|
||||
return t
|
||||
endfunction
|
||||
|
||||
function! s:CollectFQNs(typename, packagename, filekey, extends)
|
||||
if len(split(a:typename, '\.')) > 1
|
||||
return [a:typename]
|
||||
endif
|
||||
|
||||
let brackets = stridx(a:typename, '[')
|
||||
let extra = ''
|
||||
if brackets >= 0
|
||||
let typename = a:typename[0 : brackets - 1]
|
||||
let extra = a:typename[brackets : -1]
|
||||
else
|
||||
let typename = a:typename
|
||||
endif
|
||||
|
||||
let imports = javacomplete#imports#GetImports('imports_fqn', a:filekey)
|
||||
let directFqn = javacomplete#imports#SearchSingleTypeImport(typename, imports)
|
||||
if !empty(directFqn)
|
||||
return [directFqn. extra]
|
||||
endif
|
||||
|
||||
let fqns = []
|
||||
call add(fqns, empty(a:packagename) ? a:typename : a:packagename . '.' . a:typename)
|
||||
let imports = javacomplete#imports#GetImports('imports_star', a:filekey)
|
||||
for p in imports
|
||||
call add(fqns, p . a:typename)
|
||||
endfor
|
||||
if !empty(a:extends)
|
||||
call add(fqns, a:extends)
|
||||
endif
|
||||
if typename != 'Object'
|
||||
call add(fqns, 'java.lang.Object')
|
||||
endif
|
||||
return fqns
|
||||
endfunction
|
||||
|
||||
function! s:KeyInCache(fqn)
|
||||
let fqn = substitute(a:fqn, '<', '\\<', 'g')
|
||||
let fqn = substitute(fqn, '>', '\\>', 'g')
|
||||
let fqn = substitute(fqn, ']', '\\]', 'g')
|
||||
let fqn = substitute(fqn, '[', '\\[', 'g')
|
||||
let fqn = substitute(fqn, '\$', '.', 'g')
|
||||
|
||||
let keys = keys(g:JavaComplete_Cache)
|
||||
let idx = match(keys, '\v'. fqn. '$')
|
||||
|
||||
if idx >= 0
|
||||
return keys[idx]
|
||||
endif
|
||||
|
||||
return ''
|
||||
endfunction
|
||||
|
||||
" a:1 - include related type
|
||||
function! javacomplete#collector#GetDeclaredClassName(var, ...)
|
||||
let var = javacomplete#util#Trim(a:var)
|
||||
call s:Log('get declared class name for: "' . var . '"')
|
||||
if var =~# '^\(this\|super\)$'
|
||||
return var
|
||||
endif
|
||||
|
||||
" Special handling for objects in JSP
|
||||
if &ft == 'jsp'
|
||||
if get(g:J_JSP_BUILTIN_OBJECTS, a:var, '') != ''
|
||||
return g:J_JSP_BUILTIN_OBJECTS[a:var]
|
||||
endif
|
||||
return s:FastBackwardDeclarationSearch(a:var)
|
||||
endif
|
||||
|
||||
let result = javacomplete#collector#SearchForName(var, 1, 1)
|
||||
let variable = get(result[2], -1, {})
|
||||
if get(variable, 'tag', '') == 'VARDEF'
|
||||
if has_key(variable, 't')
|
||||
let splitted = split(variable.t, '\.')
|
||||
|
||||
if len(splitted) == 1
|
||||
let rootClassName = s:SearchForRootClassName(variable)
|
||||
if len(rootClassName) > 0
|
||||
call insert(splitted, rootClassName)
|
||||
endif
|
||||
endif
|
||||
|
||||
if len(splitted) > 1
|
||||
let directFqn = javacomplete#imports#SearchSingleTypeImport(splitted[0], javacomplete#imports#GetImports('imports_fqn', javacomplete#GetCurrentFileKey()))
|
||||
if empty(directFqn)
|
||||
return variable.t
|
||||
endif
|
||||
else
|
||||
return variable.t
|
||||
endif
|
||||
return substitute(join(splitted, '.'), '\.', '\$', 'g')
|
||||
endif
|
||||
return java_parser#type2Str(variable.vartype)
|
||||
endif
|
||||
|
||||
if has_key(variable, 't')
|
||||
return variable.t
|
||||
endif
|
||||
|
||||
if a:0 > 0
|
||||
let class = get(result[0], -1, {})
|
||||
if get(class, 'tag', '') == 'CLASSDEF'
|
||||
if has_key(class, 'name')
|
||||
return class.name
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
return ''
|
||||
endfunction
|
||||
|
||||
function! s:FastBackwardDeclarationSearch(name)
|
||||
let lines = reverse(getline(0, '.'))
|
||||
for line in lines
|
||||
let splittedLine = split(line, ';')
|
||||
for l in splittedLine
|
||||
let l = javacomplete#util#Trim(l)
|
||||
let matches = matchlist(l, '^\('. g:RE_QUALID. '\)\s\+'. a:name)
|
||||
if len(matches) > 0
|
||||
return matches[1]
|
||||
endif
|
||||
endfor
|
||||
endfor
|
||||
return ''
|
||||
endfunction
|
||||
|
||||
function! s:SearchForRootClassName(variable)
|
||||
if has_key(a:variable, 'vartype') && type(a:variable.vartype) == type({})
|
||||
if has_key(a:variable.vartype, 'tag') && a:variable.vartype.tag == 'TYPEAPPLY'
|
||||
if has_key(a:variable.vartype, 'clazz') && a:variable.vartype.clazz.tag == 'SELECT'
|
||||
let clazz = a:variable.vartype.clazz
|
||||
if has_key(clazz, 'selected') && has_key(clazz.selected, 'name')
|
||||
return clazz.selected.name
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
return ""
|
||||
endfunction
|
||||
|
||||
" first: return at once if found one.
|
||||
" fullmatch: 1 - equal, 0 - match beginning
|
||||
" return [types, methods, fields, vars]
|
||||
function! javacomplete#collector#SearchForName(name, first, fullmatch)
|
||||
let result = [[], [], [], []]
|
||||
if javacomplete#util#IsKeyword(a:name)
|
||||
return result
|
||||
endif
|
||||
|
||||
let unit = javacomplete#parseradapter#Parse()
|
||||
let targetPos = java_parser#MakePos(line('.')-1, col('.')-1)
|
||||
let trees = javacomplete#parseradapter#SearchNameInAST(unit, a:name, targetPos, a:fullmatch)
|
||||
for tree in trees
|
||||
if tree.tag == 'VARDEF'
|
||||
call add(result[2], tree)
|
||||
elseif tree.tag == 'METHODDEF'
|
||||
call add(result[1], tree)
|
||||
elseif tree.tag == 'CLASSDEF'
|
||||
call add(result[0], tree.name)
|
||||
elseif tree.tag == 'LAMBDA'
|
||||
let t = s:DetermineLambdaArguments(unit, tree, a:name)
|
||||
if !empty(t)
|
||||
call add(result[2], t)
|
||||
endif
|
||||
endif
|
||||
endfor
|
||||
|
||||
if a:first && result != [[], [], [], []] | return result | endif
|
||||
|
||||
" Accessible inherited members
|
||||
let type = get(javacomplete#parseradapter#SearchTypeAt(unit, targetPos), -1, {})
|
||||
if !empty(type)
|
||||
let members = javacomplete#complete#complete#SearchMember(type, a:name, a:fullmatch, 2, 1, 0, 1)
|
||||
let result[0] += members[0]
|
||||
let result[1] += members[1]
|
||||
let result[2] += members[2]
|
||||
endif
|
||||
|
||||
" static import
|
||||
let si = javacomplete#imports#SearchStaticImports(a:name, a:fullmatch)
|
||||
let result[0] += si[0]
|
||||
let result[1] += si[1]
|
||||
let result[2] += si[2]
|
||||
|
||||
return result
|
||||
endfunction
|
||||
|
||||
function! s:DetermineLambdaArguments(unit, ti, name)
|
||||
let nameInLambda = 0
|
||||
let argIdx = 0 " argument index in method declaration
|
||||
let argPos = 0
|
||||
if type(a:ti.args) == type({})
|
||||
if a:name == a:ti.args.name
|
||||
let nameInLambda = 1
|
||||
endif
|
||||
elseif type(a:ti.args) == type([])
|
||||
for arg in a:ti.args
|
||||
if arg.name == a:name
|
||||
let nameInLambda = 1
|
||||
let argPos = arg.pos
|
||||
break
|
||||
endif
|
||||
let argIdx += 1
|
||||
endfor
|
||||
endif
|
||||
|
||||
if !nameInLambda
|
||||
return {}
|
||||
endif
|
||||
|
||||
let methods = []
|
||||
let t = a:ti
|
||||
let type = ''
|
||||
if has_key(t, 'meth') && !empty(t.meth)
|
||||
let result = []
|
||||
while 1
|
||||
if has_key(t, 'meth')
|
||||
let t = t.meth
|
||||
elseif t.tag == 'SELECT' && has_key(t, 'selected')
|
||||
call add(result, t.name. '()')
|
||||
let t = t.selected
|
||||
elseif t.tag == 'IDENT'
|
||||
call add(result, t.name)
|
||||
break
|
||||
endif
|
||||
endwhile
|
||||
|
||||
let items = reverse(result)
|
||||
let typename = javacomplete#collector#GetDeclaredClassName(items[0], 1)
|
||||
let ti = {}
|
||||
if (typename != '')
|
||||
if typename[1] == '[' || typename[-1:] == ']'
|
||||
let ti = g:J_ARRAY_TYPE_INFO
|
||||
elseif typename != 'void' && !javacomplete#util#IsBuiltinType(typename)
|
||||
let ti = javacomplete#collector#DoGetClassInfo(typename)
|
||||
endif
|
||||
else " it can be static request
|
||||
let ti = javacomplete#collector#DoGetClassInfo(items[0])
|
||||
endif
|
||||
|
||||
let ii = 1
|
||||
while !empty(ti) && ii < len(items) - 1
|
||||
" method invocation: "PrimaryExpr.method(parameters)[].|"
|
||||
if items[ii] =~ '^\s*' . g:RE_IDENTIFIER . '\s*('
|
||||
let ti = javacomplete#collector#MethodInvocation(items[ii], ti, 0)
|
||||
endif
|
||||
let ii += 1
|
||||
endwhile
|
||||
|
||||
if has_key(ti, 'methods')
|
||||
let itemName = split(items[-1], '(')[0]
|
||||
for m in ti.methods
|
||||
if m.n == itemName
|
||||
call add(methods, m)
|
||||
endif
|
||||
endfor
|
||||
|
||||
endif
|
||||
elseif has_key(t, 'stats') && !empty(t.stats)
|
||||
if t.stats.tag == 'VARDEF'
|
||||
let type = t.stats.t
|
||||
elseif t.stats.tag == 'RETURN'
|
||||
for ty in a:unit.types
|
||||
for def in ty.defs
|
||||
if def.tag == 'METHODDEF'
|
||||
if t.stats.pos >= def.body.pos && t.stats.endpos <= def.body.endpos
|
||||
let type = def.r
|
||||
endif
|
||||
endif
|
||||
endfor
|
||||
endfor
|
||||
|
||||
endif
|
||||
endif
|
||||
|
||||
for method in methods
|
||||
if a:ti.idx < len(method.p)
|
||||
let type = method.p[a:ti.idx]
|
||||
endif
|
||||
let res = s:GetLambdaParameterType(type, a:name, argIdx, argPos)
|
||||
if has_key(res, 'tag')
|
||||
return res
|
||||
endif
|
||||
endfor
|
||||
|
||||
return s:GetLambdaParameterType(type, a:name, argIdx, argPos)
|
||||
endfunction
|
||||
|
||||
" type should be FunctionInterface, and it contains only one abstract method
|
||||
function! s:GetLambdaParameterType(type, name, argIdx, argPos)
|
||||
let pType = ''
|
||||
if !empty(a:type)
|
||||
let matches = matchlist(a:type, '^java.util.function.Function<\(.*\)>')
|
||||
if len(matches) > 0
|
||||
let types = split(matches[1], ',')
|
||||
if !empty(types)
|
||||
let type = javacomplete#scanner#ExtractCleanExpr(types[0])
|
||||
return {'tag': 'VARDEF', 'name': type, 'type': {'tag': 'IDENT', 'name': type}, 'vartype': {'tag': 'IDENT', 'name': type, 'pos': a:argPos}, 'pos': a:argPos}
|
||||
endif
|
||||
else
|
||||
let functionalMembers = javacomplete#collector#DoGetClassInfo(a:type)
|
||||
if has_key(functionalMembers, 'methods')
|
||||
for m in functionalMembers.methods
|
||||
if javacomplete#util#CheckModifier(m.m, g:JC_MODIFIER_ABSTRACT)
|
||||
if a:argIdx < len(m.p)
|
||||
let pType = m.p[a:argIdx]
|
||||
break
|
||||
endif
|
||||
endif
|
||||
endfor
|
||||
|
||||
if !empty(pType)
|
||||
return {'tag': 'VARDEF', 'name': a:name, 'type': {'tag': 'IDENT', 'name': pType}, 'vartype': {'tag': 'IDENT', 'name': pType, 'pos': a:argPos}, 'pos': a:argPos}
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
return {}
|
||||
endfunction
|
||||
|
||||
function! javacomplete#collector#MethodInvocation(expr, ti, itemkind)
|
||||
let subs = split(substitute(a:expr, '\s*\(' . g:RE_IDENTIFIER . '\)\s*\((.*\)', '\1;\2', ''), ';')
|
||||
|
||||
" all methods matched
|
||||
if empty(a:ti)
|
||||
let methods = javacomplete#collector#SearchForName(subs[0], 0, 1)[1]
|
||||
elseif type(a:ti) == type({}) && get(a:ti, 'tag', '') == 'CLASSDEF'
|
||||
let methods = javacomplete#complete#complete#SearchMember(a:ti, subs[0], 1, a:itemkind, 1, 0, a:itemkind == 2)[1]
|
||||
else
|
||||
let methods = []
|
||||
endif
|
||||
|
||||
let method = s:DetermineMethod(methods, subs[1])
|
||||
if !empty(method)
|
||||
return javacomplete#complete#complete#ArrayAccess(method.r, subs[0])
|
||||
endif
|
||||
return {}
|
||||
endfunction
|
||||
|
||||
" determine overloaded method by parameters count
|
||||
function! s:DetermineMethod(methods, parameters)
|
||||
let parameters = substitute(a:parameters, '(\(.*\))', '\1', '')
|
||||
let paramsCount = len(split(parameters, ','))
|
||||
for m in a:methods
|
||||
if len(get(m, 'p', [])) == paramsCount
|
||||
return m
|
||||
endif
|
||||
endfor
|
||||
return get(a:methods, -1, {})
|
||||
endfunction
|
||||
|
||||
function! javacomplete#collector#CurrentFileInfo()
|
||||
let currentBuf = getline(1,'$')
|
||||
let base64Content = javacomplete#util#Base64Encode(join(currentBuf, "\n"))
|
||||
let ti = javacomplete#collector#DoGetClassInfo('this')
|
||||
if has_key(ti, 'name')
|
||||
let package = javacomplete#collector#GetPackageName(). '.'. ti.name
|
||||
|
||||
call javacomplete#server#Communicate('-clear-from-cache', package, 's:CurrentFileInfo')
|
||||
let response = javacomplete#server#Communicate('-class-info-by-content -target '. package. ' -content', base64Content, 'CurrentFileInfo')
|
||||
if response =~ '^{'
|
||||
return eval(response)
|
||||
endif
|
||||
else
|
||||
call s:Log("`this` class parse error [CurrentFileInfo]")
|
||||
endif
|
||||
|
||||
return {}
|
||||
endfunction
|
||||
|
||||
" vim:set fdm=marker sw=2 nowrap:
|
966
bundle/vim-javacomplete2/autoload/javacomplete/complete/complete.vim
vendored
Normal file
966
bundle/vim-javacomplete2/autoload/javacomplete/complete/complete.vim
vendored
Normal file
@ -0,0 +1,966 @@
|
||||
" Vim completion script for java
|
||||
" Maintainer: artur shaik <ashaihullin@gmail.com>
|
||||
"
|
||||
" This file contains everything related to completions
|
||||
|
||||
let b:dotexpr = ''
|
||||
let b:incomplete = ''
|
||||
let b:errormsg = ''
|
||||
|
||||
function! s:Log(log)
|
||||
let log = type(a:log) == type("") ? a:log : string(a:log)
|
||||
call javacomplete#logger#Log("[complete] ". log)
|
||||
endfunction
|
||||
|
||||
function! s:Init()
|
||||
let g:JC_ClassnameCompletedFlag = 0
|
||||
let b:dotexpr = ''
|
||||
let b:incomplete = ''
|
||||
let b:context_type = 0
|
||||
|
||||
let s:et_whole = reltime()
|
||||
endfunction
|
||||
|
||||
function! javacomplete#complete#complete#Complete(findstart, base, is_filter)
|
||||
if get(g:, 'JavaComplete_Disabled', 0)
|
||||
return
|
||||
endif
|
||||
|
||||
call javacomplete#highlights#Drop()
|
||||
|
||||
if a:findstart
|
||||
call s:Init()
|
||||
return javacomplete#complete#context#FindContext()
|
||||
endif
|
||||
|
||||
let base = (a:is_filter) ? a:base :
|
||||
\ (a:base =~ '^@') ? a:base[:2] : a:base[:1]
|
||||
let result = javacomplete#complete#context#ExecuteContext(base)
|
||||
|
||||
if g:JavaComplete_CompletionResultSort
|
||||
call sort(result)
|
||||
endif
|
||||
|
||||
if len(result) > 0
|
||||
" filter according to b:incomplete
|
||||
if a:is_filter && b:incomplete != '' && b:incomplete != '+'
|
||||
let result = filter(result,
|
||||
\ "type(v:val) == type('') ? v:val =~ '^" . b:incomplete . "' : v:val['word'] =~ '^" . b:incomplete . "'")
|
||||
endif
|
||||
|
||||
if exists('s:padding') && !empty(s:padding)
|
||||
for item in result
|
||||
if type(item) == type("")
|
||||
let item .= s:padding
|
||||
else
|
||||
let item.word .= s:padding
|
||||
endif
|
||||
endfor
|
||||
unlet s:padding
|
||||
endif
|
||||
|
||||
if type(result) == type([])
|
||||
call s:Log('finish completion' . reltimestr(reltime(s:et_whole)) . 's')
|
||||
return result
|
||||
endif
|
||||
endif
|
||||
|
||||
if len(get(b:, 'errormsg', '')) > 0
|
||||
call javacomplete#ClearCache()
|
||||
|
||||
if get(g:, 'JavaComplete_IgnoreErrorMsg', 0) <= 0
|
||||
echom 'javacomplete error: ' . b:errormsg
|
||||
let b:errormsg = ''
|
||||
endif
|
||||
endif
|
||||
|
||||
return []
|
||||
endfunction
|
||||
|
||||
function! javacomplete#complete#complete#CompleteAfterOverride()
|
||||
call s:Log("complete after override")
|
||||
|
||||
let ti = javacomplete#collector#DoGetClassInfo('this')
|
||||
let s = ''
|
||||
for i in get(ti, 'extends', [])
|
||||
let parentInfo = javacomplete#collector#DoGetClassInfo(i)
|
||||
let members = javacomplete#complete#complete#SearchMember(parentInfo, '', 1, 1, 1, 14, 0)
|
||||
let s .= s:DoGetMethodList(members[1], 14, 0)
|
||||
unlet i
|
||||
endfor
|
||||
let s = substitute(s, '\<\(abstract\|default\|native\)\s\+', '', 'g')
|
||||
let s = javacomplete#util#CleanFQN(s)
|
||||
let result = eval('[' . s . ']')
|
||||
if !empty(result)
|
||||
let g:JC_DeclarationCompletedFlag = 1
|
||||
endif
|
||||
return result
|
||||
endfunction
|
||||
|
||||
function! javacomplete#complete#complete#CompleteSimilarClasses(base)
|
||||
call s:Log("complete similar classes. base: ". a:base)
|
||||
|
||||
let result = []
|
||||
if a:base =~ g:RE_ANNOTATION || a:base == '@'
|
||||
let response = javacomplete#server#Communicate("-similar-annotations", a:base[1:], 'Filter packages by incomplete class name')
|
||||
else
|
||||
let b:incomplete = a:base
|
||||
let response = javacomplete#server#Communicate("-similar-classes", a:base, 'Filter packages by incomplete class name')
|
||||
endif
|
||||
if response =~ '^['
|
||||
call extend(result, eval(response))
|
||||
endif
|
||||
if !empty(result)
|
||||
let g:JC_ClassnameCompletedFlag = 1
|
||||
endif
|
||||
return result
|
||||
endfunction
|
||||
|
||||
function! javacomplete#complete#complete#CompleteSimilarClassesAndLocalMembers(base)
|
||||
call s:Log("complete similar classes and local fields. base: ". a:base)
|
||||
|
||||
let result =
|
||||
\ javacomplete#complete#complete#CompleteSimilarClasses(a:base) +
|
||||
\ s:DoGetMemberList(javacomplete#collector#DoGetClassInfo('this'), 7)
|
||||
if !empty(result)
|
||||
let g:JC_ClassnameCompletedFlag = 1
|
||||
endif
|
||||
return result
|
||||
endfunction
|
||||
|
||||
function! javacomplete#complete#complete#CompleteAnnotationsParameters(name)
|
||||
call s:Log("complete annotation parameters. name: ". a:name)
|
||||
|
||||
let result = []
|
||||
let last = split(a:name, '@')[-1]
|
||||
let identList = matchlist(last, '\('. g:RE_IDENTIFIER. '\)\((\|$\)')
|
||||
if !empty(identList)
|
||||
let name = identList[1]
|
||||
let ti = javacomplete#collector#DoGetClassInfo(name)
|
||||
if has_key(ti, 'methods')
|
||||
let methods = []
|
||||
for m in ti.methods
|
||||
if javacomplete#util#CheckModifier(m.m, g:JC_MODIFIER_ABSTRACT) && m.n !~ '^\(toString\|annotationType\|equals\|hashCode\)$'
|
||||
call add(methods, m)
|
||||
endif
|
||||
endfor
|
||||
call extend(result, eval('[' . s:DoGetMethodList(methods, 0, 2) . ']'))
|
||||
endif
|
||||
|
||||
endif
|
||||
|
||||
return result
|
||||
endfunction
|
||||
|
||||
" Precondition: expr must end with '.'
|
||||
" return members of the value of expression
|
||||
function! javacomplete#complete#complete#CompleteAfterDot(expr)
|
||||
call s:Log("complete after dot. expr: ". a:expr)
|
||||
|
||||
let items = javacomplete#scanner#ParseExpr(a:expr) " TODO: return a dict containing more than items
|
||||
if empty(items)
|
||||
return []
|
||||
endif
|
||||
|
||||
|
||||
" 0. String literal
|
||||
if items[-1] =~ '\("\|"\.\)$'
|
||||
call s:Log('P1. "str".|')
|
||||
return s:GetMemberList("java.lang.String")
|
||||
endif
|
||||
|
||||
|
||||
let ti = {}
|
||||
let ii = 1 " item index
|
||||
let itemkind = 0
|
||||
|
||||
" optimized process
|
||||
" search the longest expr consisting of ident
|
||||
let i = 1
|
||||
let k = i
|
||||
while i < len(items) && items[i] =~ '^\s*' . g:RE_IDENTIFIER . '\s*$'
|
||||
let ident = substitute(items[i], '\s', '', 'g')
|
||||
if ident == 'class' || ident == 'this' || ident == 'super'
|
||||
let k = i
|
||||
" return when found other keywords
|
||||
elseif javacomplete#util#IsKeyword(ident)
|
||||
return []
|
||||
endif
|
||||
let items[i] = substitute(items[i], '\s', '', 'g')
|
||||
let i += 1
|
||||
endwhile
|
||||
|
||||
if i > 1
|
||||
" cases: "this.|", "super.|", "ClassName.this.|", "ClassName.super.|", "TypeName.class.|"
|
||||
if items[k] ==# 'class' || items[k] ==# 'this' || items[k] ==# 'super'
|
||||
call s:Log('O1. ' . items[k] . ' ' . join(items[:k-1], '.'))
|
||||
let ti = javacomplete#collector#DoGetClassInfo(items[k] == 'class' ? 'java.lang.Class' : join(items[:k-1], '.'))
|
||||
if !empty(ti)
|
||||
let itemkind = items[k] ==# 'this' ? 1 : items[k] ==# 'super' ? 2 : 0
|
||||
let ii = k+1
|
||||
else
|
||||
return []
|
||||
endif
|
||||
|
||||
" case: "java.io.File.|"
|
||||
else
|
||||
let fqn = join(items[:i-1], '.')
|
||||
let srcpath = join(s:GetSourceDirs(expand('%:p'), javacomplete#collector#GetPackageName()), ',')
|
||||
call s:Log('O2. ' . fqn)
|
||||
call javacomplete#collector#FetchClassInfo(fqn)
|
||||
if get(get(g:JavaComplete_Cache, fqn, {}), 'tag', '') == 'CLASSDEF'
|
||||
let ti = g:JavaComplete_Cache[fqn]
|
||||
let itemkind = 11
|
||||
let ii = i
|
||||
endif
|
||||
endif
|
||||
else
|
||||
if items[0] =~ '^\s*' . g:RE_IDENTIFIER . '\s*('
|
||||
call insert(items, 'this', 0)
|
||||
endif
|
||||
endif
|
||||
|
||||
" first item
|
||||
if empty(ti)
|
||||
if items[0] =~ '\("\|"\.\)$'
|
||||
let items[0] = "new String()"
|
||||
endif
|
||||
|
||||
" cases:
|
||||
" 1) "int.|", "void.|" - primitive type or pseudo-type, return `class`
|
||||
" 2) "this.|", "super.|" - special reference
|
||||
" 3) "var.|" - variable or field
|
||||
" 4) "String.|" - type imported or defined locally
|
||||
" 5) "java.|" - package
|
||||
if items[0] =~ '^\s*' . g:RE_IDENTIFIER . '\s*$'
|
||||
let ident = substitute(items[0], '\s', '', 'g')
|
||||
|
||||
if javacomplete#util#IsKeyword(ident)
|
||||
" 1)
|
||||
call s:Log('F1. "' . ident . '.|"')
|
||||
if ident ==# 'void' || javacomplete#util#IsBuiltinType(ident)
|
||||
let ti = g:J_PRIMITIVE_TYPE_INFO
|
||||
let itemkind = 11
|
||||
|
||||
" 2)
|
||||
call s:Log('F2. "' . ident . '.|"')
|
||||
elseif ident ==# 'this' || ident ==# 'super'
|
||||
let itemkind = ident ==# 'this' ? 1 : ident ==# 'super' ? 2 : 0
|
||||
let ti = javacomplete#collector#DoGetClassInfo(ident)
|
||||
endif
|
||||
|
||||
else
|
||||
" 3)
|
||||
let typename = javacomplete#collector#GetDeclaredClassName(ident)
|
||||
call s:Log('F3. "' . ident . '.|" typename: "' . typename . '"')
|
||||
if (typename != '')
|
||||
if typename[0] == '[' || typename[-1:] == ']'
|
||||
let ti = g:J_ARRAY_TYPE_INFO
|
||||
elseif typename != 'void' && !javacomplete#util#IsBuiltinType(typename)
|
||||
let ti = javacomplete#collector#DoGetClassInfo(typename)
|
||||
endif
|
||||
|
||||
else
|
||||
" 4)
|
||||
call s:Log('F4. "TypeName.|"')
|
||||
let ti = javacomplete#collector#DoGetClassInfo(ident)
|
||||
let itemkind = 11
|
||||
|
||||
if get(ti, 'tag', '') != 'CLASSDEF' || get(ti, 'name', '') == 'java.lang.Object'
|
||||
let tib = ti
|
||||
let ti = {}
|
||||
endif
|
||||
|
||||
" 5)
|
||||
if empty(ti)
|
||||
call s:Log('F5. "package.|"')
|
||||
unlet ti
|
||||
let ti = s:GetMembers(ident) " s:DoGetPackegInfo(ident)
|
||||
if empty(ti)
|
||||
unlet ti
|
||||
let ti = tib
|
||||
else
|
||||
let itemkind = 20
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
" array type, return `class`: "int[] [].|", "java.lang.String[].|", "NestedClass[].|"
|
||||
elseif items[0] =~# g:RE_ARRAY_TYPE
|
||||
call s:Log('array type. "' . items[0] . '"')
|
||||
let qid = substitute(items[0], g:RE_ARRAY_TYPE, '\1', '')
|
||||
if javacomplete#util#IsBuiltinType(qid) || (!javacomplete#util#HasKeyword(qid) && !empty(javacomplete#collector#DoGetClassInfo(qid)))
|
||||
let ti = g:J_PRIMITIVE_TYPE_INFO
|
||||
let itemkind = 11
|
||||
endif
|
||||
|
||||
" class instance creation expr: "new String().|", "new NonLoadableClass().|"
|
||||
" array creation expr: "new int[i=1] [val()].|", "new java.lang.String[].|"
|
||||
elseif items[0] =~ '^\s*new\s\+'
|
||||
let joinedItems = join(items,'.')
|
||||
call s:Log('creation expr. "' . joinedItems . '"')
|
||||
let subs = split(substitute(joinedItems, '^\s*new\s\+\(' .g:RE_QUALID. '\)\s*\([<([]\|\)', '\1;\2', ''), ';')
|
||||
if len(subs) == 1
|
||||
let ti = javacomplete#collector#DoGetClassInfo(subs[0])
|
||||
if get(ti, 'tag', '') == 'CLASSDEF' && get(ti, 'name', '') != 'java.lang.Object'
|
||||
let members = javacomplete#complete#complete#SearchMember(ti, '', 1, itemkind, 1, 0)
|
||||
return eval('['. s:DoGetNestedList(members[3]) . ']')
|
||||
endif
|
||||
return s:GetMembers(subs[0]) " may be a package
|
||||
elseif subs[1][0] == '['
|
||||
let ti = g:J_ARRAY_TYPE_INFO
|
||||
elseif subs[1][0] == '(' || subs[1] =~ '<>(.*'
|
||||
let splitted = split(subs[0], '\.')
|
||||
if len(splitted) > 1
|
||||
let directFqn = javacomplete#imports#SearchSingleTypeImport(splitted[0], javacomplete#imports#GetImports('imports_fqn', javacomplete#GetCurrentFileKey()))
|
||||
if empty(directFqn)
|
||||
let s = subs[0]
|
||||
else
|
||||
let s = substitute(subs[0], '\.', '\$', 'g')
|
||||
endif
|
||||
else
|
||||
let s = subs[0]
|
||||
endif
|
||||
let ti = javacomplete#collector#DoGetClassInfo(s)
|
||||
" exclude interfaces and abstract class. TODO: exclude the inaccessible
|
||||
if get(ti, 'flags', '')[-10:-10] || get(ti, 'flags', '')[-11:-11]
|
||||
echo 'cannot instantiate the type ' . subs[0]
|
||||
let ti = {}
|
||||
return []
|
||||
endif
|
||||
endif
|
||||
|
||||
" casting conversion: "(Object)o.|"
|
||||
elseif items[0] =~ g:RE_CASTING
|
||||
call s:Log('Casting conversion. "' . items[0] . '"')
|
||||
let subs = split(substitute(items[0], g:RE_CASTING, '\1;\2', ''), ';')
|
||||
let ti = javacomplete#collector#DoGetClassInfo(subs[0])
|
||||
|
||||
" array access: "var[i][j].|" Note: "var[i][]" is incorrect
|
||||
elseif items[0] =~# g:RE_ARRAY_ACCESS
|
||||
let subs = split(substitute(items[0], g:RE_ARRAY_ACCESS, '\1;\2', ''), ';')
|
||||
if get(subs, 1, '') !~ g:RE_BRACKETS
|
||||
let typename = javacomplete#collector#GetDeclaredClassName(subs[0])
|
||||
if type(typename) == type([])
|
||||
let typename = typename[0]
|
||||
endif
|
||||
call s:Log('ArrayAccess. "' .items[0]. '.|" typename: "' . typename . '"')
|
||||
if (typename != '')
|
||||
let ti = javacomplete#complete#complete#ArrayAccess(typename, items[0])
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
|
||||
"
|
||||
" next items
|
||||
"
|
||||
while !empty(ti) && ii < len(items)
|
||||
" method invocation: "PrimaryExpr.method(parameters)[].|"
|
||||
if items[ii] =~ '^\s*' . g:RE_IDENTIFIER . '\s*('
|
||||
let tmp = ti
|
||||
unlet ti
|
||||
let ti = javacomplete#collector#MethodInvocation(items[ii], tmp, itemkind)
|
||||
unlet tmp
|
||||
let itemkind = 0
|
||||
let ii += 1
|
||||
continue
|
||||
|
||||
|
||||
" expression of selection, field access, array access
|
||||
elseif items[ii] =~ g:RE_SELECT_OR_ACCESS
|
||||
let subs = split(substitute(items[ii], g:RE_SELECT_OR_ACCESS, '\1;\2', ''), ';')
|
||||
let ident = subs[0]
|
||||
let brackets = get(subs, 1, '')
|
||||
|
||||
" package members
|
||||
if itemkind/10 == 2 && empty(brackets) && !javacomplete#util#IsKeyword(ident)
|
||||
let qn = join(items[:ii], '.')
|
||||
call s:Log("package members: ". qn)
|
||||
if type(ti) == type([])
|
||||
let idx = javacomplete#util#Index(ti, ident, 'word')
|
||||
if idx >= 0
|
||||
if ti[idx].kind == 'P'
|
||||
unlet ti
|
||||
let ti = s:GetMembers(qn)
|
||||
let ii += 1
|
||||
continue
|
||||
elseif ti[idx].kind == 'C'
|
||||
unlet ti
|
||||
let ti = javacomplete#collector#DoGetClassInfo(qn)
|
||||
let itemkind = 11
|
||||
let ii += 1
|
||||
continue
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
|
||||
" type members
|
||||
elseif itemkind/10 == 1 && empty(brackets)
|
||||
if ident ==# 'class' || ident ==# 'this' || ident ==# 'super'
|
||||
call s:Log("type members: ". ident)
|
||||
let ti = javacomplete#collector#DoGetClassInfo(ident == 'class' ? 'java.lang.Class' : join(items[:ii-1], '.'))
|
||||
let itemkind = ident ==# 'this' ? 1 : ident ==# 'super' ? 2 : 0
|
||||
let ii += 1
|
||||
continue
|
||||
|
||||
elseif !javacomplete#util#IsKeyword(ident) && type(ti) == type({}) && get(ti, 'tag', '') == 'CLASSDEF'
|
||||
" accessible static field
|
||||
call s:Log("static fields: ". ident)
|
||||
let members = javacomplete#complete#complete#SearchMember(ti, ident, 1, itemkind, 1, 0)
|
||||
if !empty(members[2])
|
||||
let ti = javacomplete#complete#complete#ArrayAccess(members[2][0].t, items[ii])
|
||||
let itemkind = 0
|
||||
let ii += 1
|
||||
continue
|
||||
endif
|
||||
|
||||
" accessible nested type
|
||||
"if !empty(filter(copy(get(ti, 'classes', [])), 'strpart(v:val, strridx(v:val, ".")) ==# "' . ident . '"'))
|
||||
if !empty(members[0])
|
||||
let ti = javacomplete#collector#DoGetClassInfo(join(items[:ii], '.'))
|
||||
let ii += 1
|
||||
continue
|
||||
endif
|
||||
|
||||
if !empty(members[3])
|
||||
if len(members[3]) > 0
|
||||
let found = 0
|
||||
for entry in members[3]
|
||||
if has_key(entry, 'n') && entry.n == ident && has_key(entry, 'm')
|
||||
let ti = javacomplete#collector#DoGetClassInfo(entry.m)
|
||||
let ii += 1
|
||||
let found = 1
|
||||
break
|
||||
endif
|
||||
endfor
|
||||
if found
|
||||
continue
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
|
||||
" instance members
|
||||
elseif itemkind/10 == 0 && !javacomplete#util#IsKeyword(ident)
|
||||
if type(ti) == type({}) && get(ti, 'tag', '') == 'CLASSDEF'
|
||||
call s:Log("instance members")
|
||||
let members = javacomplete#complete#complete#SearchMember(ti, ident, 1, itemkind, 1, 0)
|
||||
let itemkind = 0
|
||||
if !empty(members[2])
|
||||
let ti = javacomplete#complete#complete#ArrayAccess(members[2][0].t, items[ii])
|
||||
let ii += 1
|
||||
continue
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
return []
|
||||
endwhile
|
||||
|
||||
|
||||
" type info or package info --> members
|
||||
if !empty(ti)
|
||||
if type(ti) == type({})
|
||||
if get(ti, 'tag', '') == 'CLASSDEF'
|
||||
if get(ti, 'name', '') == '!'
|
||||
return [{'kind': 'f', 'word': 'class', 'menu': 'Class'}]
|
||||
elseif get(ti, 'name', '') == '['
|
||||
return g:J_ARRAY_TYPE_MEMBERS
|
||||
elseif itemkind < 20
|
||||
return s:DoGetMemberList(ti, itemkind)
|
||||
endif
|
||||
elseif get(ti, 'tag', '') == 'PACKAGE'
|
||||
" TODO: ti -> members, in addition to packages in dirs
|
||||
return s:GetMembers( substitute(join(items, '.'), '\s', '', 'g') )
|
||||
endif
|
||||
elseif type(ti) == type([])
|
||||
return ti
|
||||
endif
|
||||
endif
|
||||
|
||||
return []
|
||||
endfunction
|
||||
|
||||
function! s:GetSourceDirs(filepath, ...)
|
||||
call s:Log("get source dirs. filepath: ". a:filepath)
|
||||
|
||||
let dirs = exists('s:sourcepath') ? s:sourcepath : []
|
||||
|
||||
if !empty(a:filepath)
|
||||
let filepath = fnamemodify(a:filepath, ':p:h')
|
||||
|
||||
" get source path according to file path and package name
|
||||
let packageName = a:0 > 0 ? a:1 : javacomplete#collector#GetPackageName()
|
||||
if packageName != ''
|
||||
let path = fnamemodify(substitute(filepath, packageName, '', 'g'), ':p:h')
|
||||
if index(dirs, path) < 0
|
||||
call add(dirs, path)
|
||||
endif
|
||||
endif
|
||||
|
||||
" Consider current path as a sourcepath
|
||||
if index(dirs, filepath) < 0
|
||||
call add(dirs, filepath)
|
||||
endif
|
||||
endif
|
||||
return dirs
|
||||
endfunction
|
||||
|
||||
" return only classpath which are directories
|
||||
function! s:GetClassDirs()
|
||||
let dirs = []
|
||||
for path in split(javacomplete#server#GetClassPath(), g:PATH_SEP)
|
||||
if isdirectory(path)
|
||||
call add(dirs, fnamemodify(path, ':p:h'))
|
||||
endif
|
||||
endfor
|
||||
return dirs
|
||||
endfunction
|
||||
|
||||
function! javacomplete#complete#complete#GetPackageName()
|
||||
return javacomplete#collector#GetPackageName()
|
||||
endfunction
|
||||
|
||||
function! javacomplete#complete#complete#ArrayAccess(arraytype, expr)
|
||||
call s:Log("array access. typename: ". a:arraytype. ", expr: ". a:expr)
|
||||
|
||||
if a:expr =~ g:RE_BRACKETS | return {} | endif
|
||||
let typename = a:arraytype
|
||||
|
||||
let dims = 0
|
||||
if typename[0] == '[' || typename[-1:] == ']' || a:expr[-1:] == ']'
|
||||
let dims = javacomplete#util#CountDims(a:expr) - javacomplete#util#CountDims(typename)
|
||||
if dims == 0
|
||||
let typename = typename[0 : stridx(typename, '[') - 1]
|
||||
elseif dims < 0
|
||||
return g:J_ARRAY_TYPE_INFO
|
||||
else
|
||||
"echoerr 'dims exceeds'
|
||||
endif
|
||||
endif
|
||||
if dims == 0
|
||||
if typename != 'void' && !javacomplete#util#IsBuiltinType(typename)
|
||||
return javacomplete#collector#DoGetClassInfo(typename)
|
||||
endif
|
||||
endif
|
||||
return {}
|
||||
endfunction
|
||||
|
||||
function! s:CanAccess(mods, kind, outputkind, samePackage, isinterface)
|
||||
if a:outputkind == 14
|
||||
return javacomplete#util#CheckModifier(a:mods, [g:JC_MODIFIER_PUBLIC, g:JC_MODIFIER_PROTECTED, g:JC_MODIFIER_ABSTRACT]) && !javacomplete#util#CheckModifier(a:mods, g:JC_MODIFIER_FINAL)
|
||||
endif
|
||||
if a:outputkind == 15
|
||||
return javacomplete#util#IsStatic(a:mods)
|
||||
endif
|
||||
return (a:mods[-4:-4] || a:kind/10 == 0)
|
||||
\ && (a:kind == 1 || a:mods[-1:]
|
||||
\ || (a:mods[-3:-3] && (a:kind == 1 || a:kind == 2 || a:kind == 7 || a:samePackage))
|
||||
\ || (a:mods == 0 && (a:samePackage || a:isinterface))
|
||||
\ || (a:mods[-2:-2] && (a:kind == 1 || a:kind == 7)))
|
||||
endfunction
|
||||
|
||||
function! javacomplete#complete#complete#SearchMember(ci, name, fullmatch, kind, returnAll, outputkind, ...)
|
||||
call s:Log("search member. name: ". a:name. ", kind: ". a:kind. ", outputkind: ". a:outputkind)
|
||||
|
||||
let samePackage = javacomplete#complete#complete#GetPackageName() ==
|
||||
\ javacomplete#util#GetClassPackage(a:ci.name)
|
||||
let result = [[], [], [], []]
|
||||
|
||||
let isinterface = get(a:ci, 'interface', 0)
|
||||
|
||||
if a:kind != 13
|
||||
if a:outputkind != 14
|
||||
for m in (a:0 > 0 && a:1 ? [] : get(a:ci, 'fields', [])) + ((a:kind == 1 || a:kind == 2 || a:kind == 7) ? get(a:ci, 'declared_fields', []) : [])
|
||||
if empty(a:name) || (a:fullmatch ? m.n ==# a:name : m.n =~# '^' . a:name)
|
||||
if s:CanAccess(m.m, a:kind, a:outputkind, samePackage, isinterface)
|
||||
call add(result[2], m)
|
||||
endif
|
||||
endif
|
||||
endfor
|
||||
endif
|
||||
|
||||
for m in (a:0 > 0 && a:1 ? [] : get(a:ci, 'methods', [])) + ((a:kind == 1 || a:kind == 2 || a:kind == 7) ? get(a:ci, 'declared_methods', []) : [])
|
||||
if empty(a:name) || (a:fullmatch ? m.n ==# a:name : m.n =~# '^' . a:name)
|
||||
if s:CanAccess(m.m, a:kind, a:outputkind, samePackage, isinterface)
|
||||
call add(result[1], m)
|
||||
endif
|
||||
endif
|
||||
endfor
|
||||
endif
|
||||
|
||||
for c in get(a:ci, 'nested', [])
|
||||
let _c = substitute(c, '\$', '.', '')
|
||||
if has_key(g:JavaComplete_Cache, _c)
|
||||
let nestedClass = g:JavaComplete_Cache[_c]
|
||||
if a:kind == 12
|
||||
if javacomplete#util#IsStatic(nestedClass.flags)
|
||||
call add(result[3], {'n': split(c, '\$')[-1], 'm':c})
|
||||
endif
|
||||
else
|
||||
call add(result[3], {'n': split(c, '\$')[-1], 'm':c})
|
||||
endif
|
||||
else
|
||||
call add(result[3], {'n': split(c, '\$')[-1], 'm':c})
|
||||
endif
|
||||
endfor
|
||||
|
||||
if a:kind/10 != 0
|
||||
let types = get(a:ci, 'classes', [])
|
||||
for t in types
|
||||
if empty(a:name) || (a:fullmatch ? t[strridx(t, '.')+1:] ==# a:name : t[strridx(t, '.')+1:] =~# '^' . a:name)
|
||||
if !has_key(g:JavaComplete_Cache, t) || !has_key(g:JavaComplete_Cache[t], 'flags') || a:kind == 1 || g:JavaComplete_Cache[t].flags[-1:]
|
||||
call add(result[0], t)
|
||||
endif
|
||||
endif
|
||||
endfor
|
||||
endif
|
||||
|
||||
" key `classpath` indicates it is a loaded class from classpath
|
||||
" all public members of a loaded class are stored in current ci
|
||||
if !has_key(a:ci, 'classpath') || (a:kind == 1 || a:kind == 2)
|
||||
for i in get(a:ci, 'extends', [])
|
||||
if type(i) == type("") && i == get(a:ci, 'fqn', '')
|
||||
continue
|
||||
elseif type(i) == type({}) && i.tag == 'ERRONEOUS'
|
||||
continue
|
||||
endif
|
||||
let ci = javacomplete#collector#DoGetClassInfo(java_parser#type2Str(i))
|
||||
if type(ci) == type([])
|
||||
let ci = ci[0]
|
||||
endif
|
||||
if a:outputkind == 15
|
||||
let outputkind = 11
|
||||
else
|
||||
let outputkind = a:outputkind
|
||||
endif
|
||||
let members = javacomplete#complete#complete#SearchMember(ci, a:name, a:fullmatch, a:kind == 1 ? 2 : a:kind, a:returnAll, outputkind)
|
||||
let result[0] += members[0]
|
||||
let result[1] += members[1]
|
||||
let result[2] += members[2]
|
||||
unlet i
|
||||
endfor
|
||||
endif
|
||||
return result
|
||||
endfunction
|
||||
|
||||
function! s:DoGetNestedList(classes)
|
||||
let s = ''
|
||||
let useFQN = javacomplete#UseFQN()
|
||||
for class in a:classes
|
||||
if !useFQN
|
||||
let fieldType = javacomplete#util#CleanFQN(class.m)
|
||||
else
|
||||
let fieldType = class.m
|
||||
endif
|
||||
let s .= "{'kind':'C','word':'". class.n . "','menu':'". fieldType . "','dup':1},"
|
||||
endfor
|
||||
|
||||
return s
|
||||
endfunction
|
||||
|
||||
function! s:DoGetFieldList(fields)
|
||||
let s = ''
|
||||
let useFQN = javacomplete#UseFQN()
|
||||
for field in a:fields
|
||||
if !has_key(field, 't')
|
||||
continue
|
||||
endif
|
||||
if type(field.t) == type([])
|
||||
let fieldType = field.t[0]
|
||||
let args = ''
|
||||
for arg in field.t[1]
|
||||
let args .= arg. ','
|
||||
endfor
|
||||
if len(args) > 0
|
||||
let fieldType .= '<'. args[0:-2]. '>'
|
||||
endif
|
||||
else
|
||||
let fieldType = field.t
|
||||
endif
|
||||
if !useFQN
|
||||
let fieldType = javacomplete#util#CleanFQN(fieldType)
|
||||
endif
|
||||
let s .= "{'kind':'" . (javacomplete#util#IsStatic(field.m) ? "F" : "f") . "','word':'" . field.n . "','menu':'" . fieldType . "','dup':1},"
|
||||
endfor
|
||||
return s
|
||||
endfunction
|
||||
|
||||
function! javacomplete#complete#complete#DoGetMethodList(methods, kind, ...)
|
||||
return s:DoGetMethodList(a:methods, a:kind, a:000)
|
||||
endfunction
|
||||
|
||||
function! s:DoGetMethodList(methods, kind, ...)
|
||||
let paren = a:0 == 0 || !a:1 ? '(' : (a:1 == 2) ? ' = ' : ''
|
||||
|
||||
let abbrEnd = ''
|
||||
if b:context_type != g:JC__CONTEXT_METHOD_REFERENCE
|
||||
if a:0 == 0 || !a:1
|
||||
let abbrEnd = '()'
|
||||
endif
|
||||
endif
|
||||
|
||||
let methodNames = map(copy(a:methods), 'v:val.n')
|
||||
|
||||
let useFQN = javacomplete#UseFQN()
|
||||
let s = ''
|
||||
let origParen = paren
|
||||
for method in a:methods
|
||||
if !useFQN
|
||||
let method.d = javacomplete#util#CleanFQN(method.d)
|
||||
endif
|
||||
let paren = origParen
|
||||
if paren == '('
|
||||
if count(methodNames, method.n) == 1
|
||||
if !has_key(method, 'p')
|
||||
let paren = '()'
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
let s .= "{'kind':'" . (javacomplete#util#IsStatic(method.m) ? "M" : "m") . "','word':'" . s:GenWord(method, a:kind, paren) . "','abbr':'" . method.n . abbrEnd . "','menu':'" . method.d . "','info':'" . method.d ."','dup':'1'},"
|
||||
endfor
|
||||
|
||||
return s
|
||||
endfunction
|
||||
|
||||
function! s:GenWord(method, kind, paren)
|
||||
if a:kind == 14
|
||||
|
||||
return javacomplete#util#GenMethodParamsDeclaration(a:method). ' {'
|
||||
else
|
||||
if b:context_type != g:JC__CONTEXT_METHOD_REFERENCE
|
||||
if !empty(a:paren)
|
||||
return a:method.n . a:paren
|
||||
else
|
||||
return a:method.n . '()'
|
||||
endif
|
||||
endif
|
||||
|
||||
return a:method.n
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:UniqDeclaration(members)
|
||||
let declarations = {}
|
||||
for m in a:members
|
||||
let declarations[javacomplete#util#CleanFQN(m.d)] = m
|
||||
endfor
|
||||
let result = []
|
||||
for k in keys(declarations)
|
||||
call add(result, declarations[k])
|
||||
endfor
|
||||
return result
|
||||
endfunction
|
||||
|
||||
" kind:
|
||||
" 0 - for instance, 1 - this, 2 - super, 3 - class, 4 - array, 5 - method result, 6 - primitive type, 7 - local fields
|
||||
" 11 - for type, with `class` and static member and nested types.
|
||||
" 12 - for import static, no lparen for static methods
|
||||
" 13 - for import or extends or implements, only nested types
|
||||
" 14 - for public, protected methods of extends/implements. abstract first.
|
||||
" 20 - for package
|
||||
function! s:DoGetMemberList(ci, outputkind)
|
||||
call s:Log("get member list. outputkind: ". a:outputkind)
|
||||
|
||||
let kind = a:outputkind
|
||||
let outputkind = a:outputkind
|
||||
if type(a:ci) != type({}) || a:ci == {}
|
||||
return []
|
||||
endif
|
||||
|
||||
let s = ''
|
||||
if b:context_type == g:JC__CONTEXT_METHOD_REFERENCE
|
||||
let kind = 0
|
||||
if outputkind != 0
|
||||
let s = "{'kind': 'M', 'word': 'new', 'menu': 'new'},"
|
||||
endif
|
||||
endif
|
||||
|
||||
if kind == 11
|
||||
let tmp = javacomplete#collector#DoGetClassInfo('this')
|
||||
if tmp.name == get(a:ci, 'name', '')
|
||||
let outputkind = 15
|
||||
endif
|
||||
endif
|
||||
|
||||
let members = javacomplete#complete#complete#SearchMember(a:ci, '', 1, kind, 1, outputkind, kind == 2)
|
||||
let members[1] = s:UniqDeclaration(members[1])
|
||||
|
||||
let s .= kind == 11 ? "{'kind': 'C', 'word': 'class', 'menu': 'Class'}," : ''
|
||||
|
||||
" add accessible member types
|
||||
if kind / 10 != 0
|
||||
" Use dup here for member type can share name with field.
|
||||
for class in members[0]
|
||||
"for class in get(a:ci, 'classes', [])
|
||||
let v = get(g:JavaComplete_Cache, class, {})
|
||||
if v == {} || v.flags[-1:]
|
||||
let s .= "{'kind': 'C', 'word': '" . substitute(class, a:ci.name . '\.', '\1', '') . "','dup':1},"
|
||||
endif
|
||||
endfor
|
||||
endif
|
||||
|
||||
if kind != 13
|
||||
let fieldlist = []
|
||||
let sfieldlist = []
|
||||
for field in members[2]
|
||||
"for field in get(a:ci, 'fields', [])
|
||||
if javacomplete#util#IsStatic(field['m'])
|
||||
if kind != 1
|
||||
call add(sfieldlist, field)
|
||||
endif
|
||||
elseif kind / 10 == 0
|
||||
call add(fieldlist, field)
|
||||
endif
|
||||
endfor
|
||||
|
||||
let methodlist = []
|
||||
let smethodlist = []
|
||||
for method in members[1]
|
||||
if javacomplete#util#IsStatic(method['m'])
|
||||
if kind != 1
|
||||
call add(smethodlist, method)
|
||||
endif
|
||||
elseif kind / 10 == 0
|
||||
call add(methodlist, method)
|
||||
endif
|
||||
endfor
|
||||
|
||||
if kind / 10 == 0
|
||||
let s .= s:DoGetFieldList(fieldlist)
|
||||
let s .= s:DoGetMethodList(methodlist, outputkind)
|
||||
endif
|
||||
if b:context_type != g:JC__CONTEXT_METHOD_REFERENCE
|
||||
let s .= s:DoGetFieldList(sfieldlist)
|
||||
endif
|
||||
|
||||
let s .= s:DoGetMethodList(smethodlist, outputkind, kind == 12)
|
||||
let s .= s:DoGetNestedList(members[3])
|
||||
|
||||
let s = substitute(s, '\<' . a:ci.name . '\.', '', 'g')
|
||||
let s = substitute(s, '\<\(public\|static\|synchronized\|transient\|volatile\|final\|strictfp\|serializable\|native\)\s\+', '', 'g')
|
||||
else
|
||||
let s .= s:DoGetNestedList(members[3])
|
||||
endif
|
||||
return eval('[' . s . ']')
|
||||
endfunction
|
||||
|
||||
" interface {{{2
|
||||
|
||||
function! s:GetMemberList(class)
|
||||
if javacomplete#util#IsBuiltinType(a:class)
|
||||
return []
|
||||
endif
|
||||
|
||||
return s:DoGetMemberList(javacomplete#collector#DoGetClassInfo(a:class), 0)
|
||||
endfunction
|
||||
|
||||
function! javacomplete#complete#complete#GetConstructorList(class)
|
||||
let ci = javacomplete#collector#DoGetClassInfo(a:class)
|
||||
if empty(ci)
|
||||
return []
|
||||
endif
|
||||
|
||||
let s = ''
|
||||
for ctor in get(ci, 'ctors', [])
|
||||
let s .= "{'kind': '+', 'word':'". a:class . "(','abbr':'" . ctor.d . "','dup':1},"
|
||||
endfor
|
||||
|
||||
let s = substitute(s, '\<java\.lang\.', '', 'g')
|
||||
let s = substitute(s, '\<public\s\+', '', 'g')
|
||||
return eval('[' . s . ']')
|
||||
endfunction
|
||||
|
||||
" Name can be a (simple or qualified) package name, or a (simple or qualified)
|
||||
" type name.
|
||||
function! javacomplete#complete#complete#GetMembers(fqn, ...)
|
||||
return s:GetMembers(a:fqn, a:000)
|
||||
endfunction
|
||||
|
||||
function! s:GetMembers(fqn, ...)
|
||||
call s:Log("get members. fqn: ". a:fqn)
|
||||
|
||||
let list = []
|
||||
let isClass = 0
|
||||
|
||||
if b:context_type == g:JC__CONTEXT_IMPORT_STATIC || b:context_type == g:JC__CONTEXT_IMPORT
|
||||
let res = javacomplete#server#Communicate('-E', a:fqn, 's:GetMembers for static')
|
||||
if res =~ "^{'"
|
||||
let dict = eval(res)
|
||||
for key in keys(dict)
|
||||
let g:JavaComplete_Cache[substitute(key, '\$', '.', 'g')] = javacomplete#util#Sort(dict[key])
|
||||
endfor
|
||||
endif
|
||||
endif
|
||||
|
||||
call javacomplete#collector#FetchInfoFromServer(a:fqn, '-p')
|
||||
let v = get(g:JavaComplete_Cache, a:fqn, {})
|
||||
if type(v) == type([])
|
||||
let list = v
|
||||
elseif type(v) == type({}) && v != {}
|
||||
if get(v, 'tag', '') == 'PACKAGE'
|
||||
if b:context_type == g:JC__CONTEXT_IMPORT_STATIC || b:context_type == g:JC__CONTEXT_IMPORT
|
||||
call add(list, {'kind': 'P', 'word': '*;'})
|
||||
endif
|
||||
if b:context_type != g:JC__CONTEXT_PACKAGE_DECL
|
||||
for c in sort(get(v, 'classes', []))
|
||||
call add(list, {'kind': 'C', 'word': c})
|
||||
endfor
|
||||
endif
|
||||
for p in sort(get(v, 'subpackages', []))
|
||||
call add(list, {'kind': 'P', 'word': p})
|
||||
endfor
|
||||
else
|
||||
let isClass = 1
|
||||
let list += s:DoGetMemberList(v, b:context_type == g:JC__CONTEXT_IMPORT || b:context_type == g:JC__CONTEXT_COMPLETE_CLASSNAME ? 13 : b:context_type == g:JC__CONTEXT_IMPORT_STATIC ? 12 : 11)
|
||||
endif
|
||||
endif
|
||||
|
||||
if !isClass
|
||||
let list += s:DoGetPackageInfoInDirs(a:fqn, b:context_type == g:JC__CONTEXT_PACKAGE_DECL)
|
||||
endif
|
||||
|
||||
return list
|
||||
endfunction
|
||||
|
||||
" a:1 - incomplete mode
|
||||
" return packages in classes directories or source pathes
|
||||
function! s:DoGetPackageInfoInDirs(package, onlyPackages, ...)
|
||||
call s:Log("package info in directories. package: ". a:package)
|
||||
|
||||
let list = []
|
||||
|
||||
let pathes = s:GetSourceDirs(expand('%:p'))
|
||||
for path in s:GetClassDirs()
|
||||
if index(pathes, path) <= 0
|
||||
call add(pathes, path)
|
||||
endif
|
||||
endfor
|
||||
|
||||
let globpattern = a:0 > 0 ? a:package . '*' : substitute(a:package, '\.', '/', 'g') . '/*'
|
||||
let matchpattern = a:0 > 0 ? a:package : a:package . '[\\/]'
|
||||
for f in split(globpath(join(pathes, ','), globpattern), "\n")
|
||||
for path in pathes
|
||||
let idx = matchend(f, escape(path, ' \') . '[\\/]\?\C' . matchpattern)
|
||||
if idx != -1
|
||||
let name = (a:0 > 0 ? a:package : '') . strpart(f, idx)
|
||||
if f[-5:] == '.java'
|
||||
if !a:onlyPackages
|
||||
call add(list, {'kind': 'C', 'word': name[:-6]})
|
||||
endif
|
||||
elseif name =~ '^' . g:RE_IDENTIFIER . '$' && isdirectory(f) && f !~# 'CVS$'
|
||||
call add(list, {'kind': 'P', 'word': name})
|
||||
endif
|
||||
endif
|
||||
endfor
|
||||
endfor
|
||||
return list
|
||||
endfunction
|
||||
|
||||
" vim:set fdm=marker sw=2 nowrap:
|
263
bundle/vim-javacomplete2/autoload/javacomplete/complete/context.vim
vendored
Normal file
263
bundle/vim-javacomplete2/autoload/javacomplete/complete/context.vim
vendored
Normal file
@ -0,0 +1,263 @@
|
||||
let g:JC__CONTEXT_AFTER_DOT = 1
|
||||
let g:JC__CONTEXT_METHOD_PARAM = 2
|
||||
let g:JC__CONTEXT_IMPORT = 3
|
||||
let g:JC__CONTEXT_IMPORT_STATIC = 4
|
||||
let g:JC__CONTEXT_PACKAGE_DECL = 6
|
||||
let g:JC__CONTEXT_COMPLETE_CLASSNAME = 7
|
||||
let g:JC__CONTEXT_COMPLETE_CLASSNAME_AND_LOCAL_MEMBERS = 8
|
||||
let g:JC__CONTEXT_METHOD_REFERENCE = 9
|
||||
let g:JC__CONTEXT_ANNOTATION_FIELDS = 10
|
||||
let g:JC__CONTEXT_COMPLETE_ON_OVERRIDE = 11
|
||||
let g:JC__CONTEXT_OTHER = 0
|
||||
|
||||
function! s:Log(log)
|
||||
let log = type(a:log) == type("") ? a:log : string(a:log)
|
||||
call javacomplete#logger#Log("[context] ". a:log)
|
||||
endfunction
|
||||
|
||||
function! s:ContextType2Str(type)
|
||||
if a:type == g:JC__CONTEXT_COMPLETE_ON_OVERRIDE
|
||||
return "CONTEXT_COMPLETE_ON_OVERRIDE"
|
||||
elseif a:type == g:JC__CONTEXT_IMPORT
|
||||
return "CONTEXT_IMPORT"
|
||||
elseif a:type == g:JC__CONTEXT_AFTER_DOT
|
||||
return "CONTEXT_AFTER_DOT"
|
||||
elseif a:type == g:JC__CONTEXT_COMPLETE_CLASSNAME
|
||||
return "CONTEXT_COMPLETE_CLASSNAME"
|
||||
elseif a:type == g:JC__CONTEXT_COMPLETE_CLASSNAME_AND_LOCAL_MEMBERS
|
||||
return "CONTEXT_COMPLETE_CLASSNAME_AND_LOCAL_MEMBERS"
|
||||
elseif a:type == g:JC__CONTEXT_METHOD_PARAM
|
||||
return "CONTEXT_METHOD_PARAM"
|
||||
elseif a:type == g:JC__CONTEXT_PACKAGE_DECL
|
||||
return "CONTEXT_PACKAGE_DECL"
|
||||
elseif a:type == g:JC__CONTEXT_IMPORT_STATIC
|
||||
return "CONTEXT_IMPORT_STATIC"
|
||||
elseif a:type == g:JC__CONTEXT_METHOD_REFERENCE
|
||||
return "CONTEXT_METHOD_REFERENCE"
|
||||
elseif a:type == g:JC__CONTEXT_ANNOTATION_FIELDS
|
||||
return "CONTEXT_ANNOTATION_FIELDS"
|
||||
endif
|
||||
return "CONTEXT_OTHER"
|
||||
endfunction
|
||||
|
||||
function! javacomplete#complete#context#FindContext()
|
||||
let statement = javacomplete#scanner#GetStatement()
|
||||
|
||||
let start = col('.') - 1
|
||||
|
||||
if statement =~ '^[@A-Z]\w*$'
|
||||
let b:context_type = g:JC__CONTEXT_COMPLETE_CLASSNAME_AND_LOCAL_MEMBERS
|
||||
|
||||
let curline = getline(".")
|
||||
let start = col('.') - 1
|
||||
|
||||
while start > 0 && curline[start - 1] =~ '[@A-Za-z0-9_]'
|
||||
let start -= 1
|
||||
if curline[start] == '@'
|
||||
break
|
||||
endif
|
||||
endwhile
|
||||
|
||||
return start
|
||||
elseif statement =~ '[.0-9A-Za-z_]\s*$'
|
||||
let valid = 1
|
||||
if statement =~ '\.\s*$'
|
||||
let valid = statement =~ '[")0-9A-Za-z_\]]\s*\.\s*$' && statement !~ '\<\H\w\+\.\s*$' && statement !~ '\C\<\(abstract\|assert\|break\|case\|catch\|const\|continue\|default\|do\|else\|enum\|extends\|final\|finally\|for\|goto\|if\|implements\|import\|instanceof\|interface\|native\|new\|package\|private\|protected\|public\|return\|static\|strictfp\|switch\|synchronized\|throw\|throws\|transient\|try\|volatile\|while\|true\|false\|null\)\.\s*$'
|
||||
endif
|
||||
if !valid
|
||||
return -1
|
||||
endif
|
||||
|
||||
let i = len(statement)
|
||||
let quoteParity = 1
|
||||
while i >= 0
|
||||
let ch = statement[i]
|
||||
if ch == '"'
|
||||
let quoteParity = !quoteParity
|
||||
endif
|
||||
|
||||
let i -= 1
|
||||
endwhile
|
||||
|
||||
if !quoteParity
|
||||
let b:context_type = g:JC__CONTEXT_OTHER
|
||||
return -1
|
||||
endif
|
||||
|
||||
let b:context_type = g:JC__CONTEXT_AFTER_DOT
|
||||
|
||||
" import or package declaration
|
||||
if statement =~# '^\s*\(import\|package\)\s\+'
|
||||
let statement = substitute(statement, '\s\+\.', '.', 'g')
|
||||
let statement = substitute(statement, '\.\s\+', '.', 'g')
|
||||
if statement =~ '^\s*import\s\+'
|
||||
let b:context_type = statement =~# '\<static\s\+' ? g:JC__CONTEXT_IMPORT_STATIC : g:JC__CONTEXT_IMPORT
|
||||
let b:dotexpr = substitute(statement, '^\s*import\s\+\(static\s\+\)\?', '', '')
|
||||
else
|
||||
let b:context_type = g:JC__CONTEXT_PACKAGE_DECL
|
||||
let b:dotexpr = substitute(statement, '\s*package\s\+', '', '')
|
||||
endif
|
||||
|
||||
" String literal
|
||||
elseif statement =~ '"\s*\.\s*\(\S*\.\s*\|\S*\|\)$'
|
||||
let b:dotexpr = substitute(statement, '\s*\.\s*$', '\.', '')
|
||||
let b:dotexpr = b:dotexpr[:strridx(b:dotexpr, '.')]
|
||||
let b:incomplete = statement[len(b:dotexpr):]
|
||||
return start - strlen(b:incomplete)
|
||||
|
||||
elseif &ft == 'jsp' && statement =~# '.*page.*import.*'
|
||||
let b:context_type = g:JC__CONTEXT_IMPORT
|
||||
let b:dotexpr = javacomplete#scanner#ExtractCleanExpr(statement)
|
||||
|
||||
" new
|
||||
elseif matchend(statement, '\<new\s\+' . g:RE_QUALID . '$') != -1
|
||||
let b:incomplete = substitute(statement, '^.*\<new\s\+', '', '')
|
||||
let b:context_type = g:JC__CONTEXT_COMPLETE_CLASSNAME
|
||||
return start - strlen(b:incomplete)
|
||||
|
||||
" type declaration
|
||||
elseif matchend(statement, '^\s*' . g:RE_TYPE_DECL) != -1
|
||||
if !matchend(statement, '\<(extends|implements)\s\+' . g:RE_QUALID . '$')
|
||||
" return if not after extends or implements
|
||||
return -1
|
||||
endif
|
||||
let b:incomplete = substitute(statement, '^.*\<\(extends\|implements\)\s\+', '', '')
|
||||
let b:context_type = g:JC__CONTEXT_COMPLETE_CLASSNAME
|
||||
return start - strlen(b:incomplete)
|
||||
else
|
||||
let stat = javacomplete#util#Trim(statement)
|
||||
if matchend(stat, '.*@Override\%(\s\+\w*\)\?$') >= 0
|
||||
let b:context_type = g:JC__CONTEXT_COMPLETE_ON_OVERRIDE
|
||||
endif
|
||||
endif
|
||||
|
||||
let b:dotexpr = javacomplete#scanner#ExtractCleanExpr(statement)
|
||||
if b:dotexpr =~ '.*::.*'
|
||||
let b:context_type = g:JC__CONTEXT_METHOD_REFERENCE
|
||||
let b:incomplete = strpart(b:dotexpr, stridx(b:dotexpr, ':') + 2)
|
||||
let b:dotexpr = strpart(b:dotexpr, 0, strridx(b:dotexpr, ':') + 1)
|
||||
return start - strlen(b:incomplete)
|
||||
endif
|
||||
|
||||
" all cases: " java.ut|" or " java.util.|" or "ja|"
|
||||
let b:incomplete = strpart(b:dotexpr, strridx(b:dotexpr, '.')+1)
|
||||
let b:dotexpr = strpart(b:dotexpr, 0, strridx(b:dotexpr, '.')+1)
|
||||
return start - strlen(b:incomplete)
|
||||
|
||||
elseif statement =~ '^@'. g:RE_IDENTIFIER
|
||||
let b:context_type = g:JC__CONTEXT_ANNOTATION_FIELDS
|
||||
let b:incomplete = substitute(statement, '\s*(\s*$', '', '')
|
||||
|
||||
return start
|
||||
|
||||
" method parameters, treat methodname or 'new' as an incomplete word
|
||||
elseif statement =~ '(\s*$'
|
||||
" TODO: Need to exclude method declaration?
|
||||
let b:context_type = g:JC__CONTEXT_METHOD_PARAM
|
||||
let pos = strridx(statement, '(')
|
||||
let s:padding = strpart(statement, pos+1)
|
||||
let start = start - (len(statement) - pos)
|
||||
|
||||
let statement = substitute(statement, '\s*(\s*$', '', '')
|
||||
|
||||
" new ClassName?
|
||||
let str = matchstr(statement, '\<new\s\+' . g:RE_QUALID . '$')
|
||||
if str != ''
|
||||
let str = substitute(str, '^new\s\+', '', '')
|
||||
if !javacomplete#util#IsKeyword(str)
|
||||
let b:incomplete = '+'
|
||||
let b:dotexpr = str
|
||||
return start - len(b:dotexpr)
|
||||
endif
|
||||
|
||||
" normal method invocations
|
||||
else
|
||||
let pos = match(statement, '\s*' . g:RE_IDENTIFIER . '$')
|
||||
" case: "method(|)", "this(|)", "super(|)"
|
||||
if pos == 0
|
||||
let statement = substitute(statement, '^\s*', '', '')
|
||||
" treat "this" or "super" as a type name.
|
||||
if statement == 'this' || statement == 'super'
|
||||
let b:dotexpr = statement
|
||||
let b:incomplete = '+'
|
||||
return start - len(b:dotexpr)
|
||||
|
||||
elseif !javacomplete#util#IsKeyword(statement)
|
||||
let b:incomplete = statement
|
||||
return start - strlen(b:incomplete)
|
||||
endif
|
||||
|
||||
" case: "expr.method(|)"
|
||||
elseif statement[pos-1] == '.' && !javacomplete#util#IsKeyword(strpart(statement, pos))
|
||||
let b:dotexpr = javacomplete#scanner#ExtractCleanExpr(strpart(statement, 0, pos))
|
||||
let b:incomplete = strpart(statement, pos)
|
||||
return start - strlen(b:incomplete)
|
||||
endif
|
||||
endif
|
||||
|
||||
elseif statement =~ '[.0-9A-Za-z_\<\>]*::$'
|
||||
let b:context_type = g:JC__CONTEXT_METHOD_REFERENCE
|
||||
let b:dotexpr = javacomplete#scanner#ExtractCleanExpr(statement)
|
||||
return start - strlen(b:incomplete)
|
||||
endif
|
||||
|
||||
return -1
|
||||
endfunction
|
||||
|
||||
function! javacomplete#complete#context#ExecuteContext(base)
|
||||
let result = []
|
||||
|
||||
call s:Log("context: ". s:ContextType2Str(b:context_type))
|
||||
if len(b:incomplete) > 0
|
||||
call s:Log("incomplete: ". b:incomplete)
|
||||
endif
|
||||
if len(b:dotexpr) > 0
|
||||
call s:Log("dot expression: ". b:dotexpr)
|
||||
endif
|
||||
|
||||
" Try to complete incomplete class name
|
||||
if b:context_type == g:JC__CONTEXT_COMPLETE_CLASSNAME_AND_LOCAL_MEMBERS && a:base =~ '^[@A-Z]\([A-Za-z0-9_]*\|\)$'
|
||||
let result = javacomplete#complete#complete#CompleteSimilarClassesAndLocalMembers(a:base)
|
||||
elseif b:context_type == g:JC__CONTEXT_COMPLETE_CLASSNAME && a:base =~ '^[@A-Z]\([A-Za-z0-9_]*\|\)$'
|
||||
let result = javacomplete#complete#complete#CompleteSimilarClasses(a:base)
|
||||
elseif b:context_type == g:JC__CONTEXT_COMPLETE_ON_OVERRIDE
|
||||
let result = javacomplete#complete#complete#CompleteAfterOverride()
|
||||
endif
|
||||
|
||||
if !empty(result)
|
||||
return result
|
||||
endif
|
||||
|
||||
if b:dotexpr !~ '^\s*$'
|
||||
if b:context_type == g:JC__CONTEXT_AFTER_DOT || b:context_type == g:JC__CONTEXT_METHOD_REFERENCE
|
||||
let result = javacomplete#complete#complete#CompleteAfterDot(b:dotexpr)
|
||||
elseif b:context_type == g:JC__CONTEXT_IMPORT || b:context_type == g:JC__CONTEXT_IMPORT_STATIC || b:context_type == g:JC__CONTEXT_PACKAGE_DECL
|
||||
let result = javacomplete#complete#complete#GetMembers(b:dotexpr[:-2])
|
||||
elseif b:context_type == g:JC__CONTEXT_METHOD_PARAM
|
||||
if b:incomplete == '+'
|
||||
let result = javacomplete#complete#complete#GetConstructorList(b:dotexpr)
|
||||
else
|
||||
let result = javacomplete#complete#complete#CompleteAfterDot(b:dotexpr)
|
||||
endif
|
||||
endif
|
||||
|
||||
" only incomplete word
|
||||
elseif b:incomplete !~ '^\s*$'
|
||||
" only need methods
|
||||
if b:context_type == g:JC__CONTEXT_METHOD_PARAM
|
||||
let methods = javacomplete#collector#SearchForName(b:incomplete, 0, 1)[1]
|
||||
call extend(result, eval('[' . javacomplete#complete#complete#DoGetMethodList(methods, 0) . ']'))
|
||||
elseif b:context_type == g:JC__CONTEXT_ANNOTATION_FIELDS
|
||||
let result = javacomplete#complete#complete#CompleteAnnotationsParameters(b:incomplete)
|
||||
else
|
||||
let result = javacomplete#complete#complete#CompleteSimilarClassesAndLocalMembers(a:base)
|
||||
endif
|
||||
|
||||
" then no filter needed
|
||||
let b:incomplete = ''
|
||||
endif
|
||||
|
||||
return result
|
||||
endfunction
|
||||
|
||||
" vim:set fdm=marker sw=2 nowrap:
|
634
bundle/vim-javacomplete2/autoload/javacomplete/generators.vim
vendored
Normal file
634
bundle/vim-javacomplete2/autoload/javacomplete/generators.vim
vendored
Normal file
@ -0,0 +1,634 @@
|
||||
" Vim completion script for java
|
||||
" Maintainer: artur shaik <ashaihullin@gmail.com>
|
||||
"
|
||||
" Source code generators
|
||||
|
||||
function! s:Log(log)
|
||||
let log = type(a:log) == type("") ? a:log : string(a:log)
|
||||
call javacomplete#logger#Log("[generators] ". log)
|
||||
endfunction
|
||||
|
||||
let g:JavaComplete_Templates = {}
|
||||
let g:JavaComplete_Generators = {}
|
||||
|
||||
let g:JavaComplete_Templates['setter'] =
|
||||
\ "$modifiers void $funcname($type $varname) {\n" .
|
||||
\ "$accessor.$varname = $varname;\n" .
|
||||
\ "}"
|
||||
|
||||
let g:JavaComplete_Templates['getter'] =
|
||||
\ "$modifiers $type $funcname() {\n" .
|
||||
\ "return $varname;\n" .
|
||||
\ "}"
|
||||
|
||||
let g:JavaComplete_Templates['abstractDeclaration'] =
|
||||
\ "@Override\n" .
|
||||
\ "$declaration {\n" .
|
||||
\ "throw new UnsupportedOperationException();\n" .
|
||||
\ "}"
|
||||
|
||||
function! s:CollectVars()
|
||||
let currentFileVars = []
|
||||
for d in s:ti.defs
|
||||
if d.tag == 'VARDEF'
|
||||
let var = s:GetVariable(s:ti.name, d)
|
||||
call add(currentFileVars, var)
|
||||
endif
|
||||
endfor
|
||||
return currentFileVars
|
||||
endfunction
|
||||
|
||||
function! javacomplete#generators#GenerateClass(options, ...)
|
||||
let template = a:0 > 0 && !empty(a:1) ? '_'. a:1 : ''
|
||||
let classCommand = {'template': 'class'. template, 'options': a:options, 'position_type' : 1}
|
||||
call <SID>generateByTemplate(classCommand)
|
||||
endfunction
|
||||
|
||||
function! javacomplete#generators#GenerateConstructor(default)
|
||||
let defaultConstructorCommand = {'key': '1', 'desc': 'generate default constructor', 'call': '<SID>generateByTemplate', 'template': 'constructor', 'replace': {'type': 'same'}, 'options': {'default': 1}}
|
||||
if a:default == 0
|
||||
let commands = [
|
||||
\ defaultConstructorCommand,
|
||||
\ {'key': '2', 'desc': 'generate constructor', 'call': '<SID>generateByTemplate', 'template': 'constructor', 'replace': {'type': 'same'}}
|
||||
\ ]
|
||||
call s:FieldsListBuffer(commands)
|
||||
else
|
||||
let s:ti = javacomplete#collector#DoGetClassInfo('this')
|
||||
let s:savedCursorPosition = getpos('.')
|
||||
call <SID>generateByTemplate(defaultConstructorCommand)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! javacomplete#generators#GenerateEqualsAndHashCode()
|
||||
let commands = [
|
||||
\ {'key': '1', 'desc': 'generate `equals` method', 'call': '<SID>generateByTemplate', 'template': 'equals', 'replace': {'type': 'similar'}},
|
||||
\ {'key': '2', 'desc': 'generate `hashCode` method', 'call': '<SID>generateByTemplate', 'template': 'hashCode', 'replace': {'type': 'similar'}},
|
||||
\ {'key': '3', 'desc': 'generate `equals` and `hashCode` methods', 'call': '<SID>generateByTemplate', 'template': ['hashCode', 'equals'], 'replace': {'type': 'similar'}}
|
||||
\ ]
|
||||
call s:FieldsListBuffer(commands)
|
||||
endfunction
|
||||
|
||||
function! javacomplete#generators#GenerateToString()
|
||||
let commands = [
|
||||
\ {'key': '1', 'desc': 'generate `toString` method using concatination', 'call': '<SID>generateByTemplate', 'template': 'toString_concat', 'replace': {'type': 'similar'}},
|
||||
\ {'key': '2', 'desc': 'generate `toString` method using StringBuilder', 'call': '<SID>generateByTemplate', 'template': 'toString_StringBuilder', 'replace': {'type': 'similar'}}
|
||||
\ ]
|
||||
call s:FieldsListBuffer(commands)
|
||||
endfunction
|
||||
|
||||
function! s:FieldsListBuffer(commands)
|
||||
let s:ti = javacomplete#collector#DoGetClassInfo('this')
|
||||
let s:savedCursorPosition = getpos('.')
|
||||
let contentLine = s:CreateBuffer("__FieldsListBuffer__", "remove unnecessary fields", a:commands)
|
||||
|
||||
let b:currentFileVars = s:CollectVars()
|
||||
|
||||
let lines = ""
|
||||
let idx = 0
|
||||
while idx < len(b:currentFileVars)
|
||||
let var = b:currentFileVars[idx]
|
||||
let lines = lines. "\n". "f". idx. " --> ". var.type . " ". var.name
|
||||
let idx += 1
|
||||
endwhile
|
||||
silent put = lines
|
||||
|
||||
call cursor(contentLine + 1, 0)
|
||||
endfunction
|
||||
|
||||
function! javacomplete#generators#GenerateByTemplate(command)
|
||||
call <SID>generateByTemplate(a:command)
|
||||
endfunction
|
||||
|
||||
" a:1 - method declaration to replace
|
||||
function! <SID>generateByTemplate(command)
|
||||
let command = a:command
|
||||
if !has_key(command, 'fields')
|
||||
let command['fields'] = []
|
||||
endif
|
||||
|
||||
if bufname('%') == "__FieldsListBuffer__"
|
||||
call s:Log("generate method with template: ". string(command.template))
|
||||
|
||||
let currentBuf = getline(1,'$')
|
||||
for line in currentBuf
|
||||
if line =~ '^f[0-9]\+.*'
|
||||
let cmd = line[0]
|
||||
let idx = line[1:stridx(line, ' ')-1]
|
||||
let var = b:currentFileVars[idx]
|
||||
call add(command['fields'], var)
|
||||
endif
|
||||
endfor
|
||||
|
||||
execute "bwipeout!"
|
||||
endif
|
||||
|
||||
let result = []
|
||||
let templates = type(command.template) != type([]) ? [command.template] : command.template
|
||||
let class = {}
|
||||
if has_key(s:, 'ti')
|
||||
let class['name'] = s:ti.name
|
||||
endif
|
||||
let class['fields'] = command['fields']
|
||||
for template in templates
|
||||
call s:CheckAndLoadTemplate(template)
|
||||
if has_key(g:JavaComplete_Generators, template)
|
||||
call s:Log(g:JavaComplete_Generators[template]['data'])
|
||||
execute g:JavaComplete_Generators[template]['data']
|
||||
|
||||
let arguments = [class]
|
||||
if has_key(command, 'options')
|
||||
call add(arguments, command.options)
|
||||
endif
|
||||
let TemplateFunction = function('s:__'. template)
|
||||
for line in split(call(TemplateFunction, arguments), '\n')
|
||||
call add(result, line)
|
||||
endfor
|
||||
call add(result, '')
|
||||
endif
|
||||
endfor
|
||||
|
||||
if len(result) > 0
|
||||
if has_key(command, 'replace')
|
||||
let toReplace = []
|
||||
if command.replace.type == 'same'
|
||||
let defs = s:GetNewMethodsDefinitions(result)
|
||||
for def in defs
|
||||
call add(toReplace, def.d)
|
||||
endfor
|
||||
elseif command.replace.type == 'similar'
|
||||
let defs = s:GetNewMethodsDefinitions(result)
|
||||
for def in defs
|
||||
let m = s:FindMethod(s:ti.methods, def)
|
||||
if !empty(m)
|
||||
call add(toReplace, m.d)
|
||||
endif
|
||||
endfor
|
||||
endif
|
||||
|
||||
let idx = 0
|
||||
while idx < len(s:ti.defs)
|
||||
let def = s:ti.defs[idx]
|
||||
if get(def, 'tag', '') == 'METHODDEF'
|
||||
\ && index(toReplace, get(def, 'd', '')) > -1
|
||||
\ && has_key(def, 'body') && has_key(def.body, 'endpos')
|
||||
|
||||
let startline = java_parser#DecodePos(def.pos).line
|
||||
if !empty(getline(startline))
|
||||
let startline += 1
|
||||
endif
|
||||
let endline = java_parser#DecodePos(def.body.endpos).line + 1
|
||||
silent! execute startline.','.endline. 'delete _'
|
||||
|
||||
call setpos('.', s:savedCursorPosition)
|
||||
let s:ti = javacomplete#collector#DoGetClassInfo('this')
|
||||
let idx = 0
|
||||
else
|
||||
let idx += 1
|
||||
endif
|
||||
endwhile
|
||||
endif
|
||||
if has_key(command, 'position_type')
|
||||
call s:InsertResults(result, command['position_type'])
|
||||
else
|
||||
call s:InsertResults(result)
|
||||
endif
|
||||
if has_key(s:, 'savedCursorPosition')
|
||||
call setpos('.', s:savedCursorPosition)
|
||||
endif
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:CheckAndLoadTemplate(template)
|
||||
let filenames = []
|
||||
if isdirectory(g:JavaComplete_CustomTemplateDirectory)
|
||||
call add(filenames, expand(g:JavaComplete_CustomTemplateDirectory). '/gen__'. a:template. '.tpl')
|
||||
endif
|
||||
call add(filenames, g:JavaComplete_Home. '/plugin/res/gen__'. a:template. '.tpl')
|
||||
for filename in filenames
|
||||
if filereadable(filename)
|
||||
if has_key(g:JavaComplete_Generators, a:template)
|
||||
if getftime(filename) > g:JavaComplete_Generators[a:template]['file_time']
|
||||
let g:JavaComplete_Generators[a:template]['data'] = join(readfile(filename), "\n")
|
||||
let g:JavaComplete_Generators[a:template]['file_time'] = getftime(filename)
|
||||
endif
|
||||
else
|
||||
let g:JavaComplete_Generators[a:template] = {}
|
||||
let g:JavaComplete_Generators[a:template]['data'] = join(readfile(filename), "\n")
|
||||
let g:JavaComplete_Generators[a:template]['file_time'] = getftime(filename)
|
||||
endif
|
||||
break
|
||||
endif
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
function! javacomplete#generators#AbstractDeclaration()
|
||||
let s:ti = javacomplete#collector#DoGetClassInfo('this')
|
||||
if get(s:ti, 'interface', 0) == 1
|
||||
return
|
||||
endif
|
||||
let s = ''
|
||||
let abstractMethods = []
|
||||
let implementedMethods = []
|
||||
for i in get(s:ti, 'extends', [])
|
||||
let parentInfo = javacomplete#collector#DoGetClassInfo(i)
|
||||
let members = javacomplete#complete#complete#SearchMember(parentInfo, '', 1, 1, 1, 14, 0)
|
||||
for m in members[1]
|
||||
if javacomplete#util#CheckModifier(m.m, [g:JC_MODIFIER_ABSTRACT])
|
||||
call add(abstractMethods, m)
|
||||
elseif javacomplete#util#CheckModifier(m.m, [g:JC_MODIFIER_PUBLIC])
|
||||
call add(implementedMethods, m)
|
||||
endif
|
||||
endfor
|
||||
unlet i
|
||||
endfor
|
||||
|
||||
let result = []
|
||||
let method = g:JavaComplete_Templates['abstractDeclaration']
|
||||
for m in abstractMethods
|
||||
if !empty(s:CheckImplementationExistense(s:ti, implementedMethods, m))
|
||||
continue
|
||||
endif
|
||||
let declaration = javacomplete#util#GenMethodParamsDeclaration(m)
|
||||
let declaration = substitute(declaration, '\<\(abstract\|default\|native\)\s\+', '', 'g')
|
||||
let declaration = javacomplete#util#CleanFQN(declaration)
|
||||
|
||||
call add(result, '')
|
||||
for line in split(substitute(method, '$declaration', declaration, 'g'), '\n')
|
||||
call add(result, line)
|
||||
endfor
|
||||
|
||||
call add(implementedMethods, m)
|
||||
endfor
|
||||
|
||||
call s:InsertResults(result)
|
||||
endfunction
|
||||
|
||||
" ti - this class info
|
||||
" implementedMethods - implemented methods from parent class
|
||||
" method - method to check
|
||||
function! s:CheckImplementationExistense(ti, implementedMethods, method)
|
||||
let methods = a:ti.methods
|
||||
call extend(methods, a:implementedMethods)
|
||||
return s:FindMethod(methods, a:method)
|
||||
endfunction
|
||||
|
||||
function! s:GetParams(params)
|
||||
let params = []
|
||||
for param in a:params
|
||||
if type(param) == type({}) && has_key(param, 'type')
|
||||
if has_key(param.type, 'name')
|
||||
call add(params, javacomplete#util#CleanFQN(param.type.name))
|
||||
elseif has_key(param.type, 'clazz') && has_key(param.type.clazz, 'name')
|
||||
let name = javacomplete#util#CleanFQN(param.type.clazz.name)
|
||||
if has_key(param.type, 'arguments')
|
||||
let args = []
|
||||
for arg in param.type.arguments
|
||||
if type(arg) == type({})
|
||||
if len(arg.name) == 1
|
||||
call add(params, '\('. g:RE_TYPE_ARGUMENT_EXTENDS. '\|'. g:RE_TYPE. '\)')
|
||||
else
|
||||
call add(params, arg.name)
|
||||
endif
|
||||
else
|
||||
call add(params, '?')
|
||||
endif
|
||||
endfor
|
||||
let name .= '<'. join(args, ',\s*'). '>'
|
||||
endif
|
||||
call add(params, name)
|
||||
elseif has_key(param.type, 'typetag')
|
||||
call add(params, param.type.typetag)
|
||||
elseif has_key(param.type, 'tag') && param.type.tag == 'TYPEARRAY'
|
||||
if has_key(param.type, 'elementtype') && has_key(param.type.elementtype, 'name')
|
||||
call add(params, param.type.elementtype.name . '[]')
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endfor
|
||||
return params
|
||||
endfunction
|
||||
|
||||
function! s:FindMethod(methods, method)
|
||||
let searchMethodParamList = []
|
||||
if has_key(a:method, 'p')
|
||||
for p in a:method.p
|
||||
call add(searchMethodParamList, javacomplete#util#CleanFQN(p))
|
||||
endfor
|
||||
elseif has_key(a:method, 'params')
|
||||
call extend(searchMethodParamList, s:GetParams(a:method.params))
|
||||
endif
|
||||
|
||||
let methodDeclaration = javacomplete#util#CleanFQN(a:method.r . ' '. a:method.n)
|
||||
for method in a:methods
|
||||
if methodDeclaration ==# javacomplete#util#CleanFQN(method.r . ' '. method.n)
|
||||
let methodParamList = []
|
||||
if has_key(method, 'params')
|
||||
call extend(methodParamList, s:GetParams(method.params))
|
||||
elseif has_key(method, 'p')
|
||||
for param in method.p
|
||||
if type(param) == type("")
|
||||
call add(methodParamList, javacomplete#util#CleanFQN(param))
|
||||
endif
|
||||
endfor
|
||||
endif
|
||||
|
||||
" compare parameters need to be done with regexp because of separator of
|
||||
" arguments if paramater has generic arguments
|
||||
let i = 0
|
||||
let _continue = 0
|
||||
for p in searchMethodParamList
|
||||
if i < len(methodParamList)
|
||||
if p !~ methodParamList[i]
|
||||
let _continue = 1
|
||||
break
|
||||
endif
|
||||
else
|
||||
let _continue = 1
|
||||
break
|
||||
endif
|
||||
let i += 1
|
||||
endfor
|
||||
if _continue == 1
|
||||
continue
|
||||
endif
|
||||
return method
|
||||
endif
|
||||
endfor
|
||||
return {}
|
||||
endfunction
|
||||
|
||||
function! s:CreateBuffer(name, title, commands)
|
||||
let n = bufwinnr(a:name)
|
||||
if n != -1
|
||||
execute "bwipeout!"
|
||||
endif
|
||||
exec 'silent! split '. a:name
|
||||
|
||||
" Mark the buffer as scratch
|
||||
setlocal buftype=nofile
|
||||
setlocal bufhidden=wipe
|
||||
setlocal noswapfile
|
||||
setlocal nowrap
|
||||
setlocal nobuflisted
|
||||
|
||||
nnoremap <buffer> <silent> q :bwipeout!<CR>
|
||||
|
||||
syn match Comment "^\".*"
|
||||
put = '\"-----------------------------------------------------'
|
||||
put = '\" '. a:title
|
||||
put = '\" '
|
||||
put = '\" q - close this window'
|
||||
for command in a:commands
|
||||
put = '\" '. command.key . ' - '. command.desc
|
||||
if has_key(command, 'call')
|
||||
exec "nnoremap <buffer> <silent> ". command.key . " :call ". command.call . "(". string(command). ")<CR>"
|
||||
endif
|
||||
endfor
|
||||
put = '\"-----------------------------------------------------'
|
||||
|
||||
return line(".") + 1
|
||||
endfunction
|
||||
|
||||
function! javacomplete#generators#Accessors()
|
||||
let s:ti = javacomplete#collector#DoGetClassInfo('this')
|
||||
|
||||
let commands = [{'key': 's', 'desc': 'generate accessors', 'call': '<SID>generateAccessors'}]
|
||||
let contentLine = s:CreateBuffer("__AccessorsBuffer__", "remove unnecessary accessors", commands)
|
||||
|
||||
let b:currentFileVars = s:CollectVars()
|
||||
|
||||
let lines = ""
|
||||
let idx = 0
|
||||
while idx < len(b:currentFileVars)
|
||||
let var = b:currentFileVars[idx]
|
||||
let varName = toupper(var.name[0]). var.name[1:]
|
||||
let lines = lines. "\n". "g". idx. " --> ". var.type . " get". varName . "()"
|
||||
if !var.final
|
||||
let lines = lines. "\n". "s". idx. " --> ". "set". varName . "(". var.type . " ". var.name. ")"
|
||||
endif
|
||||
let lines = lines. "\n"
|
||||
|
||||
let idx += 1
|
||||
endwhile
|
||||
silent put = lines
|
||||
|
||||
call cursor(contentLine + 1, 0)
|
||||
|
||||
endfunction
|
||||
|
||||
function! javacomplete#generators#Accessor(...)
|
||||
let s:ti = javacomplete#collector#DoGetClassInfo('this')
|
||||
call <SID>generateAccessors(a:000)
|
||||
endfunction
|
||||
|
||||
function! s:AddAccessor(map, result, var, declaration, type)
|
||||
let method = g:JavaComplete_Templates[a:type]
|
||||
|
||||
let mods = "public"
|
||||
if a:var.static
|
||||
let mods = mods . " static"
|
||||
let accessor = a:var.className
|
||||
else
|
||||
let accessor = 'this'
|
||||
endif
|
||||
|
||||
let method = substitute(method, '$type', a:var.type, 'g')
|
||||
let method = substitute(method, '$varname', a:var.name, 'g')
|
||||
let method = substitute(method, '$funcname', a:declaration, 'g')
|
||||
let method = substitute(method, '$modifiers', mods, 'g')
|
||||
let method = substitute(method, '$accessor', accessor, 'g')
|
||||
|
||||
let begin = len(a:result)
|
||||
call add(a:result, '')
|
||||
for line in split(method, '\n')
|
||||
call add(a:result, line)
|
||||
endfor
|
||||
let end = len(a:result)
|
||||
call add(a:map, [begin, end])
|
||||
endfunction
|
||||
|
||||
function! s:GetVariable(className, def)
|
||||
let var = {
|
||||
\ 'name': a:def.name,
|
||||
\ 'type': a:def.t,
|
||||
\ 'className': a:className,
|
||||
\ 'static': javacomplete#util#IsStatic(a:def.m),
|
||||
\ 'final': javacomplete#util#CheckModifier(a:def.m, g:JC_MODIFIER_FINAL),
|
||||
\ 'isArray': a:def.t =~# g:RE_ARRAY_TYPE}
|
||||
|
||||
let varName = toupper(var.name[0]). var.name[1:]
|
||||
for def in get(s:ti, 'defs', [])
|
||||
if get(def, 'tag', '') == 'METHODDEF'
|
||||
if stridx(get(def, 'd', ''), var.type. ' get'. varName. '()') > -1
|
||||
let var.getter = 'get'. varName. '()'
|
||||
break
|
||||
endif
|
||||
endif
|
||||
endfor
|
||||
return var
|
||||
endfunction
|
||||
|
||||
function! s:CreateAccessors(map, result, var, cmd)
|
||||
let varName = toupper(a:var.name[0]). a:var.name[1:]
|
||||
if !a:var.final && stridx(a:cmd, 's') > -1
|
||||
call s:AddAccessor(a:map, a:result, a:var, "set". varName, 'setter')
|
||||
endif
|
||||
if stridx(a:cmd, 'g') > -1
|
||||
call s:AddAccessor(a:map, a:result, a:var, "get". varName, 'getter')
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! <SID>generateAccessors(...)
|
||||
let result = []
|
||||
let locationMap = []
|
||||
if bufname('%') == "__AccessorsBuffer__"
|
||||
call s:Log("generate accessor for selected fields")
|
||||
let currentBuf = getline(1,'$')
|
||||
for line in currentBuf
|
||||
if line =~ '^\(g\|s\)[0-9]\+.*'
|
||||
let cmd = line[0]
|
||||
let idx = line[1:stridx(line, ' ')-1]
|
||||
let var = b:currentFileVars[idx]
|
||||
call s:CreateAccessors(locationMap, result, var, cmd)
|
||||
endif
|
||||
endfor
|
||||
|
||||
execute "bwipeout!"
|
||||
else
|
||||
call s:Log("generate accessor for fields under cursor")
|
||||
if mode() == 'n'
|
||||
let currentLines = [line('.') - 1]
|
||||
elseif mode() == 'v'
|
||||
let [lnum1, col1] = getpos("'<")[1:2]
|
||||
let [lnum2, col2] = getpos("'>")[1:2]
|
||||
let currentLines = range(lnum1 - 1, lnum2 - 1)
|
||||
else
|
||||
let currentLines = []
|
||||
endif
|
||||
for d in get(s:ti, 'defs', [])
|
||||
if get(d, 'tag', '') == 'VARDEF'
|
||||
let line = java_parser#DecodePos(d.pos).line
|
||||
if has_key(d, 'endpos')
|
||||
let endline = java_parser#DecodePos(d.endpos).line
|
||||
else
|
||||
let endline = line
|
||||
endif
|
||||
for l in currentLines
|
||||
if l >= line && l <= endline
|
||||
let cmd = len(a:1) > 0 ? a:1[0] : 'sg'
|
||||
let var = s:GetVariable(s:ti.name, d)
|
||||
call s:CreateAccessors(locationMap, result, var, cmd)
|
||||
endif
|
||||
endfor
|
||||
endif
|
||||
endfor
|
||||
|
||||
endif
|
||||
|
||||
call s:InsertResults(s:FilterExistedMethods(locationMap, result))
|
||||
endfunction
|
||||
|
||||
function! s:FilterExistedMethods(locationMap, result)
|
||||
let resultMethods = []
|
||||
for def in s:GetNewMethodsDefinitions(a:result)
|
||||
if !empty(s:CheckImplementationExistense(s:ti, [], def))
|
||||
continue
|
||||
endif
|
||||
for m in a:locationMap
|
||||
if m[0] <= def.beginline && m[1] >= def.endline
|
||||
call extend(resultMethods, a:result[m[0] : m[1] -1])
|
||||
break
|
||||
endif
|
||||
endfor
|
||||
endfor
|
||||
|
||||
return resultMethods
|
||||
endfunction
|
||||
|
||||
" create temporary buffer with class declaration, then parse it to get new
|
||||
" methods definitions.
|
||||
function! s:GetNewMethodsDefinitions(declarations)
|
||||
let n = bufwinnr("__tmp_buffer__")
|
||||
if n != -1
|
||||
execute "bwipeout!"
|
||||
endif
|
||||
silent! split __tmp_buffer__
|
||||
let result = ['class Tmp {']
|
||||
call extend(result, a:declarations)
|
||||
call add(result, '}')
|
||||
call append(0, result)
|
||||
let tmpClassInfo = javacomplete#collector#DoGetClassInfo('this', '__tmp_buffer__')
|
||||
let defs = []
|
||||
for def in get(tmpClassInfo, 'defs', [])
|
||||
if get(def, 'tag', '') == 'METHODDEF'
|
||||
let def.beginline = java_parser#DecodePos(def.pos).line
|
||||
let def.endline = java_parser#DecodePos(def.body.endpos).line
|
||||
call add(defs, def)
|
||||
endif
|
||||
endfor
|
||||
execute "bwipeout!"
|
||||
|
||||
return defs
|
||||
endfunction
|
||||
|
||||
function! s:InsertResults(result, ...)
|
||||
if len(a:result) > 0
|
||||
let positionType = a:0 > 0 && len(a:1) > 0 ? a:1 : 'END'
|
||||
if positionType == 'END'
|
||||
call s:InsertAtTheEndOfTheClass(a:result)
|
||||
return
|
||||
endif
|
||||
|
||||
call s:Log(a:result)
|
||||
call append(0, a:result)
|
||||
silent execute "normal! dd"
|
||||
silent execute "normal! =G"
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:InsertAtTheEndOfTheClass(result)
|
||||
let result = a:result
|
||||
let t = javacomplete#collector#CurrentFileInfo()
|
||||
let contentLine = line('.')
|
||||
let currentCol = col('.')
|
||||
let posResult = {}
|
||||
for clazz in values(t)
|
||||
if contentLine > clazz.pos[0] && contentLine <= clazz.endpos[0]
|
||||
let posResult[clazz.endpos[0] - clazz.pos[0]] = clazz.endpos
|
||||
endif
|
||||
endfor
|
||||
|
||||
let saveCursor = getpos('.')
|
||||
call s:Log(posResult)
|
||||
if len(posResult) > 0
|
||||
let pos = posResult[min(keys(posResult))]
|
||||
let endline = pos[0]
|
||||
if pos[1] > 1 && !empty(javacomplete#util#Trim(getline(pos[0])[:pos[1] - 2]))
|
||||
let endline += 1
|
||||
call cursor(pos[0], pos[1])
|
||||
execute "normal! i\r"
|
||||
endif
|
||||
elseif has_key(s:, 'ti') && has_key(s:ti, 'endpos')
|
||||
let endline = java_parser#DecodePos(s:ti.endpos).line
|
||||
else
|
||||
call s:Log("cannot find `endpos` [InsertResult]")
|
||||
return
|
||||
endif
|
||||
|
||||
if empty(javacomplete#util#Trim(getline(endline - 1)))
|
||||
if empty(result[0])
|
||||
let result = result[1:]
|
||||
endif
|
||||
elseif !empty(result[0])
|
||||
call insert(result, '', 0)
|
||||
endif
|
||||
|
||||
call append(endline - 1, result)
|
||||
call cursor(endline - 1, 1)
|
||||
silent execute "normal! =G"
|
||||
if has('saveCursor')
|
||||
call setpos('.', saveCursor)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" vim:set fdm=marker sw=2 nowrap:
|
44
bundle/vim-javacomplete2/autoload/javacomplete/highlights.vim
vendored
Normal file
44
bundle/vim-javacomplete2/autoload/javacomplete/highlights.vim
vendored
Normal file
@ -0,0 +1,44 @@
|
||||
" Vim completion script for java
|
||||
" Maintainer: artur shaik <ashaihullin@gmail.com>
|
||||
"
|
||||
" Work with attention highlights
|
||||
|
||||
let s:matchesCount = 0
|
||||
let s:signId = 271992
|
||||
sign define jc2signparseproblem text=->
|
||||
|
||||
function! s:Log(log)
|
||||
let log = type(a:log) == type("") ? a:log : string(a:log)
|
||||
call javacomplete#logger#Log("[highlights] ". log)
|
||||
endfunction
|
||||
|
||||
function! javacomplete#highlights#Drop()
|
||||
if s:matchesCount > 0 && !empty(getmatches())
|
||||
lclose
|
||||
exe "sign unplace * file=". expand("%:p")
|
||||
call clearmatches()
|
||||
call setloclist(0, [], 'f')
|
||||
let s:matchesCount = len(getmatches())
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! javacomplete#highlights#ShowProblems(problems)
|
||||
let loclist = []
|
||||
let matchposlist = []
|
||||
for problem in a:problems
|
||||
call extend(loclist,[{
|
||||
\ 'bufnr':bufnr('%'),
|
||||
\ 'lnum': problem['lnum'],
|
||||
\ 'col': problem['col'],
|
||||
\ 'text': problem['message']}])
|
||||
call add(matchposlist,[problem['lnum'], problem['col']])
|
||||
exe ":sign place ".s:signId." line=".problem['lnum'].
|
||||
\ " name=jc2signparseproblem file=" . expand("%:p")
|
||||
endfor
|
||||
if !empty(matchposlist)
|
||||
let s:matchesCount = len(matchposlist)
|
||||
call setloclist(0, loclist, 'r')
|
||||
call matchaddpos("SpellBad", matchposlist)
|
||||
lopen
|
||||
endif
|
||||
endfunction
|
576
bundle/vim-javacomplete2/autoload/javacomplete/imports.vim
vendored
Normal file
576
bundle/vim-javacomplete2/autoload/javacomplete/imports.vim
vendored
Normal file
@ -0,0 +1,576 @@
|
||||
" Vim completion script for java
|
||||
" Maintainer: artur shaik <ashaihullin@gmail.com>
|
||||
"
|
||||
" Everything to work with imports
|
||||
|
||||
function! s:Log(log)
|
||||
let log = type(a:log) == type("") ? a:log : string(a:log)
|
||||
call javacomplete#logger#Log("[imports] ". log)
|
||||
endfunction
|
||||
|
||||
" Similar with filter(), but returns a new list instead of operating in-place.
|
||||
" `item` has the value of the current item.
|
||||
function! s:filter(expr, string)
|
||||
if type(a:expr) == type([])
|
||||
let result = []
|
||||
for item in a:expr
|
||||
if eval(a:string)
|
||||
call add(result, item)
|
||||
endif
|
||||
endfor
|
||||
return result
|
||||
else
|
||||
let result = {}
|
||||
for item in items(a:expr)
|
||||
if eval(a:string)
|
||||
let result[item[0]] = item[1]
|
||||
endif
|
||||
endfor
|
||||
return result
|
||||
endif
|
||||
endfu
|
||||
|
||||
function! s:GenerateImports()
|
||||
let imports = []
|
||||
|
||||
let lnum_old = line('.')
|
||||
let col_old = col('.')
|
||||
call cursor(1, 1)
|
||||
|
||||
if &ft == 'jsp'
|
||||
while 1
|
||||
let lnum = search('\<import\s*=\s*[''"]', 'Wc')
|
||||
if (lnum == 0)
|
||||
break
|
||||
endif
|
||||
|
||||
let str = getline(lnum)
|
||||
if str =~ '<%\s*@\s*page\>' || str =~ '<jsp:\s*directive.page\>'
|
||||
let stat = matchlist(str, '.*import\s*=\s*[''"]\([a-zA-Z0-9_$.*, \t]\+\)[''"].*')
|
||||
if !empty(stat)
|
||||
for item in stat[1:]
|
||||
if !empty(item)
|
||||
for i in split(item, ',')
|
||||
call add(imports, [substitute(i, '\s', '', 'g'), lnum])
|
||||
endfor
|
||||
endif
|
||||
endfor
|
||||
endif
|
||||
endif
|
||||
call cursor(lnum + 1, 1)
|
||||
endwhile
|
||||
else
|
||||
while 1
|
||||
let lnum = search('\<import\>', 'Wc')
|
||||
if (lnum == 0)
|
||||
break
|
||||
elseif !javacomplete#util#InComment(line("."), col(".")-1)
|
||||
call search(' \S', 'e')
|
||||
" TODO: search semicolon or import keyword, excluding comment
|
||||
let stat = matchstr(getline(lnum)[col('.')-1:], '\(static\s\+\)\?\(' .g:RE_QUALID. '\%(\s*\.\s*\*\)\?\)\s*;')
|
||||
if !empty(stat)
|
||||
call add(imports, [stat[:-2], lnum])
|
||||
endif
|
||||
else
|
||||
let curPos = getpos('.')
|
||||
call cursor(curPos[1] + 1, curPos[2])
|
||||
endif
|
||||
endwhile
|
||||
endif
|
||||
|
||||
call cursor(lnum_old, col_old)
|
||||
return imports
|
||||
endfunction
|
||||
|
||||
function! javacomplete#imports#GetImports(kind, ...)
|
||||
let filekey = a:0 > 0 && !empty(a:1) ? a:1 : javacomplete#GetCurrentFileKey()
|
||||
let props = get(g:JavaComplete_Files, filekey, {})
|
||||
let props['imports'] = filekey == javacomplete#GetCurrentFileKey() ? s:GenerateImports() : props.unit.imports
|
||||
let props['imports_static'] = []
|
||||
let props['imports_fqn'] = []
|
||||
let props['imports_star'] = ['java.lang.']
|
||||
if &ft == 'jsp' || filekey =~ '\.jsp$'
|
||||
let props.imports_star += ['javax.servlet.', 'javax.servlet.http.', 'javax.servlet.jsp.']
|
||||
endif
|
||||
|
||||
for import in props.imports
|
||||
let subs = matchlist(import[0], '^\s*\(static\s\+\)\?\(' .g:RE_QUALID. '\%(\s*\.\s*\*\)\?\)\s*$')
|
||||
if !empty(subs)
|
||||
let qid = substitute(subs[2] , '\s', '', 'g')
|
||||
if !empty(subs[1])
|
||||
if qid[-1:] == '*'
|
||||
call add(props.imports_static, qid[:-2])
|
||||
else
|
||||
call add(props.imports_static, qid)
|
||||
call add(props.imports_fqn, qid)
|
||||
endif
|
||||
elseif qid[-1:] == '*'
|
||||
call add(props.imports_star, qid[:-2])
|
||||
else
|
||||
call add(props.imports_fqn, qid)
|
||||
endif
|
||||
endif
|
||||
endfor
|
||||
let g:JavaComplete_Files[filekey] = props
|
||||
return get(props, a:kind, [])
|
||||
endfu
|
||||
|
||||
" search for name in
|
||||
" return the fqn matched
|
||||
function! javacomplete#imports#SearchSingleTypeImport(name, fqns)
|
||||
let matches = s:filter(a:fqns, 'item =~# ''\<' . a:name . '$''')
|
||||
if len(matches) == 1
|
||||
return matches[0]
|
||||
elseif !empty(matches)
|
||||
echoerr 'Name "' . a:name . '" conflicts between ' . join(matches, ' and ')
|
||||
return matches[0]
|
||||
endif
|
||||
return ''
|
||||
endfu
|
||||
|
||||
" search for name in static imports, return list of members with the same name
|
||||
" return [types, methods, fields]
|
||||
function! javacomplete#imports#SearchStaticImports(name, fullmatch)
|
||||
let result = [[], [], []]
|
||||
let candidates = [] " list of the canonical name
|
||||
for item in javacomplete#imports#GetImports('imports_static')
|
||||
if item[-1:] == '*' " static import on demand
|
||||
call add(candidates, item[:-3])
|
||||
elseif item[strridx(item, '.')+1:] ==# a:name
|
||||
\ || (!a:fullmatch && item[strridx(item, '.')+1:] =~ '^' . a:name)
|
||||
call add(candidates, item[:strridx(item, '.') - 1])
|
||||
endif
|
||||
endfor
|
||||
if empty(candidates)
|
||||
return result
|
||||
endif
|
||||
|
||||
" read type info which are not in cache
|
||||
let commalist = ''
|
||||
for typename in candidates
|
||||
if !has_key(g:JavaComplete_Cache, typename)
|
||||
let res = javacomplete#server#Communicate('-E', typename, 's:SearchStaticImports')
|
||||
if res =~ "^{'"
|
||||
let dict = eval(res)
|
||||
for key in keys(dict)
|
||||
let g:JavaComplete_Cache[key] = javacomplete#util#Sort(dict[key])
|
||||
endfor
|
||||
endif
|
||||
endif
|
||||
endfor
|
||||
|
||||
" search in all candidates
|
||||
for typename in candidates
|
||||
let ti = get(g:JavaComplete_Cache, typename, 0)
|
||||
if type(ti) == type({}) && get(ti, 'tag', '') == 'CLASSDEF'
|
||||
let members = javacomplete#complete#complete#SearchMember(ti, a:name, a:fullmatch, 12, 1, 0)
|
||||
if !empty(members[1]) || !empty(members[2])
|
||||
call add(result[0], ti)
|
||||
endif
|
||||
let result[1] += members[1]
|
||||
let result[2] += members[2]
|
||||
else
|
||||
" TODO: mark the wrong import declaration.
|
||||
endif
|
||||
endfor
|
||||
return result
|
||||
endfu
|
||||
|
||||
function! javacomplete#imports#SortImports()
|
||||
let imports = javacomplete#imports#GetImports('imports')
|
||||
if (len(imports) > 0)
|
||||
let beginLine = imports[0][1]
|
||||
let lastLine = imports[len(imports) - 1][1]
|
||||
let importsList = []
|
||||
for import in imports
|
||||
call add(importsList, import[0])
|
||||
endfor
|
||||
|
||||
call sort(importsList)
|
||||
let importsListSorted = s:SortImportsList(importsList)
|
||||
|
||||
if g:JavaComplete_StaticImportsAtTop
|
||||
let importsListSorted = s:StaticImportsFirst(importsListSorted)
|
||||
endif
|
||||
|
||||
let saveCursor = getpos('.')
|
||||
silent execute beginLine.','.lastLine. 'delete _'
|
||||
for imp in importsListSorted
|
||||
if imp != ''
|
||||
if &ft == 'jsp'
|
||||
call append(beginLine - 1, '<%@ page import = "'. imp. '" %>')
|
||||
else
|
||||
call append(beginLine - 1, 'import '. imp. ';')
|
||||
endif
|
||||
else
|
||||
call append(beginLine - 1, '')
|
||||
endif
|
||||
let beginLine += 1
|
||||
endfor
|
||||
let saveCursor[1] += beginLine - lastLine - 1
|
||||
call setpos('.', saveCursor)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:AddImport(import)
|
||||
if exists('g:JavaComplete_ExcludeClassRegex')
|
||||
if a:import =~ get(g:, 'JavaComplete_ExcludeClassRegex')
|
||||
return
|
||||
endif
|
||||
endif
|
||||
|
||||
let importPackage = a:import[0:strridx(a:import, '.') - 1]
|
||||
if importPackage == javacomplete#collector#GetPackageName()
|
||||
return
|
||||
endif
|
||||
|
||||
let isStaticImport = a:import =~ "^static.*" ? 1 : 0
|
||||
let import = substitute(a:import, "\\$", ".", "g")
|
||||
if !isStaticImport
|
||||
let importsFqn = javacomplete#imports#GetImports('imports_fqn')
|
||||
let importsStar = javacomplete#imports#GetImports('imports_star')
|
||||
else
|
||||
let importsStar = javacomplete#imports#GetImports('imports_static')
|
||||
let importsFqn = importsStar
|
||||
let import = import[stridx(import, " ") + 1:]
|
||||
endif
|
||||
|
||||
for imp in importsFqn
|
||||
if imp == import
|
||||
redraw
|
||||
echom 'JavaComplete: import for '. import. ' already exists'
|
||||
return
|
||||
endif
|
||||
endfor
|
||||
|
||||
let splittedImport = split(import, '\.')
|
||||
let className = splittedImport[-1]
|
||||
call remove(splittedImport, len(splittedImport) - 1)
|
||||
let importPath = join(splittedImport, '.')
|
||||
for imp in importsStar
|
||||
if imp == importPath. '.'
|
||||
redraw
|
||||
echom 'JavaComplete: import for '. import. ' already exists'
|
||||
return
|
||||
endif
|
||||
endfor
|
||||
|
||||
if className != '*'
|
||||
if has_key(g:JavaComplete_Cache, className)
|
||||
call remove(g:JavaComplete_Cache, className)
|
||||
endif
|
||||
endif
|
||||
|
||||
let imports = javacomplete#imports#GetImports('imports')
|
||||
if empty(imports)
|
||||
for i in range(line('$'))
|
||||
if getline(i) =~ '^package\s\+.*\;$'
|
||||
let insertline = i + 2
|
||||
call append(i, '')
|
||||
break
|
||||
endif
|
||||
endfor
|
||||
if !exists('insertline')
|
||||
let insertline = 1
|
||||
endif
|
||||
let linesCount = line('$')
|
||||
while (javacomplete#util#Trim(getline(insertline)) == '' && insertline < linesCount)
|
||||
silent execute insertline. 'delete _'
|
||||
endwhile
|
||||
|
||||
let insertline = insertline - 1
|
||||
let newline = 1
|
||||
else
|
||||
let replaceIdx = -1
|
||||
let idx = 0
|
||||
for i in imports
|
||||
if split(i[0], '\.')[-1] == className
|
||||
let replaceIdx = idx
|
||||
break
|
||||
endif
|
||||
let idx += 1
|
||||
endfor
|
||||
let insertline = imports[len(imports) - 1][1] - 1
|
||||
let newline = 0
|
||||
if replaceIdx >= 0
|
||||
let saveCursor = getcurpos()
|
||||
silent execute imports[replaceIdx][1]. 'normal! dd'
|
||||
call remove(imports, replaceIdx)
|
||||
let saveCursor[1] -= 1
|
||||
call setpos('.', saveCursor)
|
||||
endif
|
||||
endif
|
||||
|
||||
if &ft == 'jsp'
|
||||
call append(insertline, '<%@ page import = "'. import. '" %>')
|
||||
else
|
||||
if isStaticImport
|
||||
call append(insertline, 'import static '. import. ';')
|
||||
else
|
||||
call append(insertline, 'import '. import. ';')
|
||||
endif
|
||||
endif
|
||||
|
||||
if newline
|
||||
call append(insertline + 1, '')
|
||||
endif
|
||||
|
||||
endfunction
|
||||
|
||||
function! s:StaticImportsFirst(importsList)
|
||||
let staticImportsList = []
|
||||
let l_a = copy(a:importsList)
|
||||
for imp in l_a
|
||||
if imp =~ '^static'
|
||||
call remove(a:importsList, index(a:importsList, imp))
|
||||
call add(staticImportsList, imp)
|
||||
endif
|
||||
endfor
|
||||
if len(staticImportsList) > 0
|
||||
call add(staticImportsList, '')
|
||||
endif
|
||||
return staticImportsList + a:importsList
|
||||
endfunction
|
||||
|
||||
function! s:SortImportsList(importsList, ...)
|
||||
let sortType = a:0 > 0 ? a:1 : g:JavaComplete_ImportSortType
|
||||
let importsListSorted = []
|
||||
if sortType == 'packageName'
|
||||
let beforeWildcardSorted = []
|
||||
let afterWildcardSorted = ['']
|
||||
let wildcardSeen = 0
|
||||
for a in g:JavaComplete_ImportOrder
|
||||
if a ==? '*'
|
||||
let wildcardSeen = 1
|
||||
continue
|
||||
endif
|
||||
let l_a = filter(copy(a:importsList),"v:val =~? '^" . substitute(a, '\.', '\\.', 'g') . "'")
|
||||
if len(l_a) > 0
|
||||
for imp in l_a
|
||||
call remove(a:importsList, index(a:importsList, imp))
|
||||
if wildcardSeen == 0
|
||||
call add(beforeWildcardSorted, imp)
|
||||
else
|
||||
call add(afterWildcardSorted, imp)
|
||||
endif
|
||||
endfor
|
||||
if wildcardSeen == 0
|
||||
call add(beforeWildcardSorted, '')
|
||||
else
|
||||
call add(afterWildcardSorted, '')
|
||||
endif
|
||||
endif
|
||||
endfor
|
||||
let importsListSorted = beforeWildcardSorted + a:importsList + afterWildcardSorted
|
||||
else
|
||||
let response = javacomplete#server#Communicate("-fetch-class-archives", join(a:importsList, ","), "Fetch imports jar archives")
|
||||
if response =~ '^['
|
||||
let result = sort(eval(response), 's:_SortArchivesByFirstClassName')
|
||||
for jar in result
|
||||
for classFqn in sort(jar[1])
|
||||
let idx = index(a:importsList, classFqn)
|
||||
let cf = a:importsList[idx]
|
||||
call remove(a:importsList, idx)
|
||||
call add(importsListSorted, cf)
|
||||
endfor
|
||||
call add(importsListSorted, '')
|
||||
endfor
|
||||
endif
|
||||
if len(a:importsList) > 0
|
||||
for imp in a:importsList
|
||||
call add(importsListSorted, imp)
|
||||
endfor
|
||||
endif
|
||||
endif
|
||||
while (len(importsListSorted) > 0) && (importsListSorted[-1] ==? '')
|
||||
call remove(importsListSorted, -1)
|
||||
endwhile
|
||||
return importsListSorted
|
||||
endfunction
|
||||
|
||||
function! s:_SortArchivesByFirstClassName(i1, i2)
|
||||
return a:i1[1][0] > a:i2[1][0]
|
||||
endfunction
|
||||
|
||||
function! s:_SortStaticToEnd(i1, i2)
|
||||
if stridx(a:i1, '$') >= 0 && stridx(a:i2, '$') < 0
|
||||
return 1
|
||||
elseif stridx(a:i2, '$') >= 0 && stridx(a:i1, '$') < 0
|
||||
return -1
|
||||
else
|
||||
return a:i1 > a:i2
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" a:1 - use smart import if True
|
||||
function! javacomplete#imports#Add(...)
|
||||
call javacomplete#server#Start()
|
||||
|
||||
let i = 0
|
||||
let classname = ''
|
||||
while empty(classname)
|
||||
let offset = col('.') - i
|
||||
if offset <= 0
|
||||
return
|
||||
endif
|
||||
let classname = javacomplete#util#GetClassNameWithScope(offset)
|
||||
let i += 1
|
||||
endwhile
|
||||
|
||||
if classname =~ '^@.*'
|
||||
let classname = classname[1:]
|
||||
endif
|
||||
if index(g:J_KEYWORDS, classname) >= 0
|
||||
return
|
||||
endif
|
||||
if a:0 > 0 && a:1 && index(keys(javacomplete#util#GetRegularClassesDict()), classname) >= 0
|
||||
call s:AddImport(javacomplete#util#GetRegularClassesDict()[classname])
|
||||
call javacomplete#imports#SortImports()
|
||||
else
|
||||
let response = javacomplete#server#Communicate("-class-packages", classname, 'Filter packages to add import')
|
||||
if response =~ '^['
|
||||
let result = eval(response)
|
||||
let import = s:ChooseImportOption(result, classname)
|
||||
|
||||
if !empty(import)
|
||||
call s:AddImport(import)
|
||||
call javacomplete#imports#SortImports()
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! javacomplete#imports#getType(...)
|
||||
call javacomplete#server#Start()
|
||||
|
||||
let i = 0
|
||||
let classname = ''
|
||||
while empty(classname)
|
||||
let offset = col('.') - i
|
||||
if offset <= 0
|
||||
return
|
||||
endif
|
||||
let classname = javacomplete#util#GetClassNameWithScope(offset)
|
||||
let i += 1
|
||||
endwhile
|
||||
|
||||
if classname =~ '^@.*'
|
||||
let classname = classname[1:]
|
||||
endif
|
||||
if index(keys(javacomplete#util#GetRegularClassesDict()), classname) != -1
|
||||
echo javacomplete#util#GetRegularClassesDict()[classname]
|
||||
else
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:ChooseImportOption(options, classname)
|
||||
let import = ''
|
||||
let options = a:options
|
||||
if len(options) == 0
|
||||
echo "JavaComplete: classname '". a:classname. "' not found in any scope."
|
||||
|
||||
elseif len(options) == 1
|
||||
let import = options[0]
|
||||
|
||||
else
|
||||
call sort(options, 's:_SortStaticToEnd')
|
||||
let options = s:SortImportsList(options, 'packageName')
|
||||
let index = 0
|
||||
let message = ''
|
||||
for imp in options
|
||||
if len(imp) == 0
|
||||
let message .= "\n"
|
||||
else
|
||||
let message .= "candidate [". index. "]: ". imp. "\n"
|
||||
endif
|
||||
let index += 1
|
||||
endfor
|
||||
let message .= "\nselect one candidate [". g:JavaComplete_ImportDefault."]: "
|
||||
let userinput = input(message, '')
|
||||
if empty(userinput)
|
||||
let userinput = g:JavaComplete_ImportDefault
|
||||
elseif userinput =~ '^[0-9]*$'
|
||||
let userinput = str2nr(userinput)
|
||||
else
|
||||
let userinput = -1
|
||||
endif
|
||||
redraw!
|
||||
|
||||
if userinput < 0 || userinput >= len(options)
|
||||
echo "JavaComplete: wrong input"
|
||||
else
|
||||
let import = options[userinput]
|
||||
call s:PopulateRegularClasses(a:classname, import)
|
||||
endif
|
||||
endif
|
||||
return import
|
||||
endfunction
|
||||
|
||||
function! s:PopulateRegularClasses(classname, import)
|
||||
let s:RegularClassesDict = javacomplete#util#GetRegularClassesDict()
|
||||
let s:RegularClassesDict[a:classname] = a:import
|
||||
call javacomplete#util#SaveRegularClassesList(s:RegularClassesDict)
|
||||
endfunction
|
||||
|
||||
function! javacomplete#imports#RemoveUnused()
|
||||
call javacomplete#highlights#Drop()
|
||||
|
||||
let currentBuf = getline(1,'$')
|
||||
let base64Content = javacomplete#util#Base64Encode(join(currentBuf, "\n"))
|
||||
|
||||
let response = javacomplete#server#Communicate('-unused-imports -content', base64Content, 'RemoveUnusedImports')
|
||||
if response =~ '^{'
|
||||
let response = eval(response)
|
||||
if has_key(response, 'imports')
|
||||
let saveCursor = getpos('.')
|
||||
let unusedImports = response['imports']
|
||||
for unusedImport in unusedImports
|
||||
let imports = javacomplete#imports#GetImports('imports')
|
||||
if stridx(unusedImport, '$') != -1
|
||||
let unusedImport = 'static '. substitute(unusedImport, "\\$", ".", "")
|
||||
endif
|
||||
for import in imports
|
||||
if import[0] == unusedImport
|
||||
silent execute import[1]. 'delete _'
|
||||
endif
|
||||
endfor
|
||||
endfor
|
||||
let saveCursor[1] = saveCursor[1] - len(unusedImports)
|
||||
call setpos('.', saveCursor)
|
||||
elseif has_key(response, 'parse-problems')
|
||||
call javacomplete#highlights#ShowProblems(response['parse-problems'])
|
||||
endif
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! javacomplete#imports#AddMissing()
|
||||
call javacomplete#highlights#Drop()
|
||||
|
||||
let currentBuf = getline(1,'$')
|
||||
let base64Content = javacomplete#util#Base64Encode(join(currentBuf, "\n"))
|
||||
|
||||
let response = javacomplete#server#Communicate('-missing-imports -content', base64Content, 'AddMissingImports')
|
||||
if response =~ '^{'
|
||||
let response = eval(response)
|
||||
if has_key(response, 'imports')
|
||||
for import in response['imports']
|
||||
let classname = split(import[0], '\(\.\|\$\)')[-1]
|
||||
if index(keys(javacomplete#util#GetRegularClassesDict()), classname) < 0
|
||||
let result = s:ChooseImportOption(import, classname)
|
||||
if !empty(result)
|
||||
call s:AddImport(result)
|
||||
endif
|
||||
else
|
||||
call s:AddImport(javacomplete#util#GetRegularClassesDict()[classname])
|
||||
endif
|
||||
endfor
|
||||
call javacomplete#imports#SortImports()
|
||||
elseif has_key(response, 'parse-problems')
|
||||
call javacomplete#highlights#ShowProblems(response['parse-problems'])
|
||||
endif
|
||||
else
|
||||
echo response
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" vim:set fdm=marker sw=2 nowrap:
|
35
bundle/vim-javacomplete2/autoload/javacomplete/logger.vim
vendored
Normal file
35
bundle/vim-javacomplete2/autoload/javacomplete/logger.vim
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
" Vim completion script for java
|
||||
" Maintainer: artur shaik <ashaihullin@gmail.com>
|
||||
"
|
||||
" Debug methods
|
||||
|
||||
let s:log = []
|
||||
let s:loglevel = 1
|
||||
if !exists('s:startupDate')
|
||||
let s:startupDate = reltime()
|
||||
endif
|
||||
|
||||
function! javacomplete#logger#Enable()
|
||||
let s:loglevel = 0
|
||||
endfunction
|
||||
|
||||
function! javacomplete#logger#Disable()
|
||||
let s:loglevel = 1
|
||||
endfunction
|
||||
|
||||
function! javacomplete#logger#GetContent()
|
||||
new
|
||||
set modifiable
|
||||
put =s:log
|
||||
set nomodifiable
|
||||
set nomodified
|
||||
endfunction
|
||||
|
||||
function! javacomplete#logger#Log(log)
|
||||
if 0 >= s:loglevel
|
||||
let log = type(a:log) == type("") ? a:log : string(a:log)
|
||||
call add(s:log, reltimestr(reltime(s:startupDate)). " ". log)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" vim:set fdm=marker sw=2 nowrap:
|
491
bundle/vim-javacomplete2/autoload/javacomplete/newclass.vim
vendored
Normal file
491
bundle/vim-javacomplete2/autoload/javacomplete/newclass.vim
vendored
Normal file
@ -0,0 +1,491 @@
|
||||
" Vim completion script for java
|
||||
" Maintainer: artur shaik <ashaihullin@gmail.com>
|
||||
"
|
||||
" Classes generator
|
||||
|
||||
function! s:Log(log)
|
||||
let log = type(a:log) == type("") ? a:log : string(a:log)
|
||||
call javacomplete#logger#Log("[newclass] ". log)
|
||||
endfunction
|
||||
|
||||
function! javacomplete#newclass#TemplatesCompletion(argLead, command, cursorPos)
|
||||
call s:Log("arglead:[".a:argLead ."] cmdline:[" .a:command ."] cursorpos:[" .a:cursorPos ."]")
|
||||
let result = []
|
||||
let commandTokens = split(a:command, ':', 1)
|
||||
let command = len(commandTokens) >= 1 ? commandTokens[-1] : a:command
|
||||
call extend(result, s:FetchTemplatesByPrefix(command, 0))
|
||||
return result
|
||||
endfunction
|
||||
|
||||
function! javacomplete#newclass#Completion(argLead, command, cursorPos)
|
||||
call s:Log("arglead:[".a:argLead ."] cmdline:[" .a:command ."] cursorpos:[" .a:cursorPos ."]")
|
||||
let result = []
|
||||
let commandTokens = split(a:command, ':', 1)
|
||||
let command = len(commandTokens) >= 1 ? commandTokens[-1] : a:command
|
||||
if command[0] == '/'
|
||||
call extend(result, s:ClassnameCompletions(command[1:], s:GetCompleted(commandTokens), 0))
|
||||
elseif command[0] == '['
|
||||
call extend(result, s:FetchAvailableSubDirectories(command[1:], s:GetCompleted(commandTokens)))
|
||||
elseif len(commandTokens) == 1
|
||||
call extend(result, s:FetchTemplatesByPrefix(command, 1))
|
||||
call extend(result, s:ClassnameCompletions(command, s:GetCompleted(commandTokens), 1))
|
||||
elseif len(commandTokens) == 2
|
||||
call extend(result, s:ClassnameCompletions(command, s:GetCompleted(commandTokens), 1))
|
||||
call extend(result, s:ClassMethods(command, s:GetCompleted(commandTokens)))
|
||||
elseif len(commandTokens) == 3
|
||||
if commandTokens[1] =~ '[\[\]]'
|
||||
call extend(result, s:ClassnameCompletions(command, s:GetCompleted(commandTokens), 1))
|
||||
else
|
||||
call extend(result, s:ClassMethods(command, s:GetCompleted(commandTokens)))
|
||||
endif
|
||||
else
|
||||
call extend(result, s:ClassMethods(command, s:GetCompleted(commandTokens)))
|
||||
endif
|
||||
return result
|
||||
endfunction
|
||||
|
||||
function! s:FetchTemplatesByPrefix(command, addSeparator)
|
||||
let result = s:FetchTemplatesByPath(
|
||||
\ g:JavaComplete_Home. '/plugin/res/gen__class_',
|
||||
\ a:command,
|
||||
\ a:addSeparator)
|
||||
if isdirectory(g:JavaComplete_CustomTemplateDirectory)
|
||||
call extend(result,
|
||||
\ s:FetchTemplatesByPath(expand(g:JavaComplete_CustomTemplateDirectory). '/gen__class_',
|
||||
\ a:command,
|
||||
\ a:addSeparator))
|
||||
endif
|
||||
return result
|
||||
endfunction
|
||||
|
||||
function! s:FetchTemplatesByPath(path, command, addSeparator)
|
||||
let result = []
|
||||
let cutLength = len(a:path)
|
||||
for template in glob(a:path. a:command. '*.tpl', 0, 1)
|
||||
call add(result, template[cutLength:-5]. (a:addSeparator == 1 ? ':' : ''))
|
||||
endfor
|
||||
return result
|
||||
endfunction
|
||||
|
||||
function! s:ClassnameCompletions(command, completed, isRelative)
|
||||
if stridx(a:command, ' ') < 0
|
||||
return s:FetchAvailablePackages(a:command, a:completed, a:isRelative)
|
||||
else
|
||||
return s:FetchKeywords(a:command, a:completed, a:isRelative)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:FetchAvailablePackages(command, completed, isRelative)
|
||||
let result = []
|
||||
let currentPath = split(expand('%:p:h'), g:FILE_SEP)
|
||||
if a:isRelative == 0
|
||||
let currentPackage = split(javacomplete#collector#GetPackageName(), '\.')
|
||||
let sameSubpackageIdx = index(currentPath, currentPackage[0])
|
||||
if sameSubpackageIdx >= 0
|
||||
let currentPath = currentPath[:sameSubpackageIdx - 1]
|
||||
if empty(a:command)
|
||||
for p in currentPackage
|
||||
call add(result, a:completed. '/'. p)
|
||||
endfor
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
let command = substitute(a:command, '\.', g:FILE_SEP, 'g')
|
||||
let cutLength = len(join(currentPath, g:FILE_SEP)) + 2
|
||||
for path in glob(g:FILE_SEP. join(currentPath, g:FILE_SEP). g:FILE_SEP. '**'. g:FILE_SEP. command. '*'. g:FILE_SEP, 1, 1)
|
||||
let p = substitute(path[cutLength:], g:FILE_SEP, '.', 'g')
|
||||
if a:isRelative == 0
|
||||
let p = '/'. p
|
||||
endif
|
||||
call add(result, a:completed. p)
|
||||
endfor
|
||||
return result
|
||||
endfunction
|
||||
|
||||
function! s:FetchKeywords(command, completed, isRelative)
|
||||
let keywords = ['extends', 'implements']
|
||||
let tokens = split(a:command, ' ', 1)
|
||||
if len(tokens) > 1 && index(keywords, tokens[-2]) >= 0
|
||||
return []
|
||||
endif
|
||||
let completed = a:completed. (a:isRelative == 0 ? '/' : '')
|
||||
let completed = completed. join(tokens[:-2], ' ')
|
||||
let result = []
|
||||
for kw in keywords
|
||||
if a:command =~ '\<'. kw. '\>'
|
||||
\ || kw !~ '\<'. tokens[-1]. '*'
|
||||
continue
|
||||
endif
|
||||
call add(result, completed. ' '. kw)
|
||||
endfor
|
||||
return result
|
||||
endfunction
|
||||
|
||||
function! s:FetchAvailableSubDirectories(command, completed)
|
||||
let result = []
|
||||
let currentPath = split(expand('%:p:h'), g:FILE_SEP)
|
||||
let currentPath = currentPath[:index(currentPath, 'src')]
|
||||
let prePath = g:FILE_SEP. join(currentPath, g:FILE_SEP). g:FILE_SEP
|
||||
let cutLength = len(prePath)
|
||||
for path in glob(prePath. a:command. '*'. g:FILE_SEP, 0, 1)
|
||||
call add(result, a:completed. '['. path[cutLength:-2]. ']')
|
||||
endfor
|
||||
return result
|
||||
endfunction
|
||||
|
||||
function! s:ClassMethods(command, completed)
|
||||
let keywords = ['constructor(', 'toString(', 'hashCode(', 'equals(']
|
||||
let result = []
|
||||
for kw in keywords
|
||||
if kw !~ '\<'. a:command. '*'
|
||||
continue
|
||||
endif
|
||||
call add(result, a:completed. kw)
|
||||
endfor
|
||||
return result
|
||||
endfunction
|
||||
|
||||
function! s:GetCompleted(commandTokens)
|
||||
let completed = join(a:commandTokens[:-2], ':')
|
||||
if !empty(completed)
|
||||
let completed = completed. ':'
|
||||
endif
|
||||
return completed
|
||||
endfunction
|
||||
|
||||
function! javacomplete#newclass#CreateInFile()
|
||||
let templates = s:FetchTemplatesByPrefix('', 0)
|
||||
let message = join(templates, ', ')
|
||||
let message .= "\nenter template name [default]: "
|
||||
let userinput = input(message, '', 'customlist,javacomplete#newclass#TemplatesCompletion')
|
||||
call s:Log("input: ". userinput)
|
||||
|
||||
let currentPath = split(expand('%:p:h'), g:FILE_SEP)
|
||||
call filter(currentPath, 'empty(v:val) == 0')
|
||||
if has('win32') && currentPath[0][-1:] ==':'
|
||||
let currentPath = currentPath[1:]
|
||||
endif
|
||||
|
||||
let data = {}
|
||||
let data['path'] = ''
|
||||
let data['current_path'] = g:FILE_SEP. join(currentPath, g:FILE_SEP)
|
||||
let data['class'] = expand('%:t:r')
|
||||
let data['package'] = s:DeterminePackage(currentPath)
|
||||
if !empty(userinput)
|
||||
let data['template'] = userinput
|
||||
endif
|
||||
call s:Log(data)
|
||||
call s:CreateClass(data)
|
||||
endfunction
|
||||
|
||||
function! s:DeterminePackage(currentPath)
|
||||
let i = 0
|
||||
while i < len(a:currentPath)
|
||||
if a:currentPath[i] == 'java'
|
||||
break
|
||||
endif
|
||||
let i += 1
|
||||
endwhile
|
||||
if i < len(a:currentPath)
|
||||
let package = a:currentPath[i + 1:]
|
||||
else
|
||||
let rootPackage = input("\nenter your root package: ")
|
||||
if empty(rootPackage)
|
||||
return ''
|
||||
endif
|
||||
let i = 0
|
||||
while i < len(a:currentPath)
|
||||
if a:currentPath[i] == rootPackage
|
||||
break
|
||||
endif
|
||||
let i += 1
|
||||
endwhile
|
||||
if i < len(a:currentPath)
|
||||
let package = a:currentPath[i:]
|
||||
else
|
||||
return ''
|
||||
endif
|
||||
endif
|
||||
return join(package, '.')
|
||||
endfunction
|
||||
|
||||
function! javacomplete#newclass#CreateClass()
|
||||
call javacomplete#Enable()
|
||||
call javacomplete#Start()
|
||||
let message = "enter new class name: "
|
||||
let userinput = input(message, '', 'customlist,javacomplete#newclass#Completion')
|
||||
if empty(userinput)
|
||||
return
|
||||
endif
|
||||
call s:Log("input: ". userinput)
|
||||
|
||||
let currentPackage = split(javacomplete#collector#GetPackageName(), '\.')
|
||||
let currentPath = split(expand('%:p:h'), g:FILE_SEP)
|
||||
call filter(currentPath, 'empty(v:val) == 0')
|
||||
if has('win32') && currentPath[0][-1:] ==':'
|
||||
let currentPath = currentPath[1:]
|
||||
endif
|
||||
let data = s:ParseInput(
|
||||
\ userinput, reverse(copy(currentPath)), currentPackage)
|
||||
if type(data) != type({})
|
||||
echom "\n"
|
||||
echoerr "Error: could not parse input line"
|
||||
return
|
||||
endif
|
||||
let data['current_path'] = g:FILE_SEP. join(currentPath, g:FILE_SEP). g:FILE_SEP
|
||||
call s:CreateClass(data)
|
||||
endfunction
|
||||
|
||||
function! s:CreateClass(data)
|
||||
call s:Log("create class: ". string(a:data))
|
||||
|
||||
let path = a:data['current_path']
|
||||
\ . g:FILE_SEP
|
||||
\ . a:data['path']
|
||||
if filewritable(path) != 2
|
||||
call mkdir(path, 'p')
|
||||
endif
|
||||
let fileName = fnamemodify(path. g:FILE_SEP. a:data['class'], ":p")
|
||||
let bufname = bufname('')
|
||||
if getbufvar(bufname, "&mod") == 1 && getbufvar(bufname, "&hidden") == 0
|
||||
execute ':vs'
|
||||
endif
|
||||
execute ':e '. fileName. '.java'
|
||||
let fileSize = getfsize(fileName. '.java')
|
||||
if (fileSize <= 0 && fileSize > -2) || (line('$') == 1 && getline(1) == '')
|
||||
let options = {
|
||||
\ 'name' : a:data['class'],
|
||||
\ 'package' : a:data['package']
|
||||
\ }
|
||||
if has_key(a:data, 'fields')
|
||||
let options['fields'] = a:data['fields']
|
||||
endif
|
||||
if has_key(a:data, 'extends')
|
||||
let options['extends'] = a:data['extends']
|
||||
endif
|
||||
if has_key(a:data, 'implements')
|
||||
let options['implements'] = a:data['implements']
|
||||
endif
|
||||
let isInterfaceTemplate = 0
|
||||
if has_key(a:data, 'template')
|
||||
if a:data['template'] == 'interface'
|
||||
let isInterfaceTemplate = 1
|
||||
endif
|
||||
call javacomplete#generators#GenerateClass(options, a:data['template'])
|
||||
else
|
||||
call javacomplete#generators#GenerateClass(options)
|
||||
endif
|
||||
silent execute "normal! gg=G"
|
||||
call search(a:data['class'])
|
||||
silent execute "normal! j"
|
||||
call javacomplete#imports#AddMissing()
|
||||
if !isInterfaceTemplate
|
||||
call javacomplete#generators#AbstractDeclaration()
|
||||
endif
|
||||
if has_key(a:data, 'methods')
|
||||
let methods = a:data['methods']
|
||||
let vars = s:GetVariables(get(a:data, 'fields', {}))
|
||||
if has_key(methods, 'constructor')
|
||||
let command = {'template': 'constructor', 'replace': {'type': 'same'}, 'fields' : []}
|
||||
call s:InsertVars(command, methods['constructor'], vars)
|
||||
call javacomplete#generators#GenerateByTemplate(command)
|
||||
endif
|
||||
if has_key(methods, 'toString')
|
||||
let command = {'template': 'toString_StringBuilder', 'replace': {'type': 'similar'}, 'fields' : []}
|
||||
if empty(methods['toString'])
|
||||
call add(methods['toString'], '*')
|
||||
endif
|
||||
call s:InsertVars(command, methods['toString'], vars)
|
||||
call javacomplete#generators#GenerateByTemplate(command)
|
||||
endif
|
||||
if has_key(methods, 'equals')
|
||||
let command = {'template': 'equals', 'replace': {'type': 'similar'}, 'fields' : []}
|
||||
if empty(methods['equals'])
|
||||
call add(methods['equals'], '*')
|
||||
endif
|
||||
call s:InsertVars(command, methods['equals'], vars)
|
||||
call javacomplete#generators#GenerateByTemplate(command)
|
||||
endif
|
||||
if has_key(methods, 'hashCode')
|
||||
let command = {'template': 'hashCode', 'replace': {'type': 'similar'}, 'fields' : []}
|
||||
if empty(methods['hashCode'])
|
||||
call add(methods['hashCode'], '*')
|
||||
endif
|
||||
call s:InsertVars(command, methods['hashCode'], vars)
|
||||
call javacomplete#generators#GenerateByTemplate(command)
|
||||
endif
|
||||
endif
|
||||
if !isInterfaceTemplate
|
||||
if has_key(a:data, 'fields')
|
||||
call javacomplete#generators#Accessors()
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:InsertVars(command, method, vars)
|
||||
for arg in a:method
|
||||
if arg == '*'
|
||||
let a:command['fields'] = values(a:vars)
|
||||
break
|
||||
endif
|
||||
|
||||
call add(a:command['fields'], a:vars[arg])
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
function! s:GetVariables(fields)
|
||||
let result = {}
|
||||
for fieldIdx in keys(a:fields)
|
||||
let field = a:fields[fieldIdx]
|
||||
let var = {
|
||||
\ 'name' : field['name'],
|
||||
\ 'type' : field['type'],
|
||||
\ 'static' : field['mod'] =~ '.*\<static\>.*',
|
||||
\ 'final' : field['mod'] =~ '.*\<final\>.*',
|
||||
\ 'isArray' : field['type'] =~# g:RE_ARRAY_TYPE
|
||||
\ }
|
||||
let result[fieldIdx] = var
|
||||
endfor
|
||||
return result
|
||||
endfunction
|
||||
|
||||
function! s:ParseInput(userinput, currentPath, currentPackage)
|
||||
let submatch = matchlist(a:userinput, '^\([A-Za-z0-9_]*:\)\=\(\[.\{-}\]:\)\=\(\%(\/\|\/\.\|\)'. g:RE_TYPE. '\)\(\s\+extends\s\+'. g:RE_TYPE. '\)\=\(\s\+implements\s\+'. g:RE_TYPE. '\)\=\((.\{-})\|\)\(:.*\)\=$')
|
||||
if !empty(submatch)
|
||||
let path = split(submatch[3], '\.')
|
||||
let subdir = !empty(submatch[2]) ? submatch[2][1:-3] : ''
|
||||
let classData = s:BuildPathData(path, subdir, a:currentPath, a:currentPackage)
|
||||
if !empty(submatch[1])
|
||||
let classData['template'] = submatch[1][:-2]
|
||||
endif
|
||||
if !empty(submatch[4])
|
||||
let m = matchlist(submatch[4], '.*extends\s\+\('. g:RE_TYPE. '\)')
|
||||
if !empty(m)
|
||||
let classData['extends'] = m[1]
|
||||
endif
|
||||
endif
|
||||
if !empty(submatch[5])
|
||||
let m = matchlist(submatch[5], '.*implements\s\+\('. g:RE_TYPE. '\)')
|
||||
if !empty(m)
|
||||
let classData['implements'] = m[1]
|
||||
endif
|
||||
endif
|
||||
if !empty(submatch[6])
|
||||
let fieldsMap = s:ParseFields(submatch[6])
|
||||
if type(fieldsMap) == type({})
|
||||
let classData['fields'] = fieldsMap
|
||||
endif
|
||||
endif
|
||||
if !empty(submatch[7])
|
||||
let methodsMap = s:ParseMethods(submatch[7])
|
||||
if !empty(methodsMap)
|
||||
let classData['methods'] = methodsMap
|
||||
endif
|
||||
endif
|
||||
return classData
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:ParseMethods(methods)
|
||||
let methodsMap = {}
|
||||
let methods = split(a:methods[1:], ':')
|
||||
for method in methods
|
||||
let bracketsIdx = stridx(method, '(')
|
||||
if bracketsIdx > 0
|
||||
let methodName = method[:bracketsIdx - 1]
|
||||
let methodsMap[methodName] = []
|
||||
let args = split(method[bracketsIdx + 1:-2], ',')
|
||||
for arg in args
|
||||
if arg != '*'
|
||||
let arg = arg*1
|
||||
endif
|
||||
call add(methodsMap[methodName], arg)
|
||||
endfor
|
||||
else
|
||||
let methodsMap[method] = []
|
||||
endif
|
||||
endfor
|
||||
return methodsMap
|
||||
endfunction
|
||||
|
||||
function! s:ParseFields(fields)
|
||||
let fields = javacomplete#util#Trim(a:fields[1:-2])
|
||||
if !empty(fields)
|
||||
let fieldsList = split(fields, ',')
|
||||
let fieldsMap = {}
|
||||
let idx = 1
|
||||
for field in fieldsList
|
||||
let fieldMatch = matchlist(field, '^\s*\(\%('. g:RE_TYPE_MODS. '\s\+\)\+\)\=\('. g:RE_TYPE. '\)\s\+\('. g:RE_IDENTIFIER. '\).*$')
|
||||
if !empty(fieldMatch)
|
||||
let fieldMap = {}
|
||||
let fieldMap['mod'] = empty(fieldMatch[1]) ?
|
||||
\ 'private' : javacomplete#util#Trim(fieldMatch[1])
|
||||
let fieldMap['type'] = fieldMatch[2]
|
||||
let fieldMap['name'] = fieldMatch[3]
|
||||
let fieldsMap[string(idx)] = fieldMap
|
||||
let idx += 1
|
||||
endif
|
||||
endfor
|
||||
return fieldsMap
|
||||
endif
|
||||
return 0
|
||||
endfunction
|
||||
|
||||
function! s:BuildPathData(path, subdir, currentPath, currentPackage)
|
||||
if !empty(a:subdir)
|
||||
let idx = index(a:currentPath, 'src')
|
||||
let newPath = repeat('..'. g:FILE_SEP, idx)
|
||||
let newPath .= a:subdir. g:FILE_SEP. 'java'. g:FILE_SEP
|
||||
let newPath .= join(a:currentPackage, g:FILE_SEP). g:FILE_SEP
|
||||
else
|
||||
let newPath = ''
|
||||
endif
|
||||
|
||||
let path = a:path
|
||||
if path[0] == '/' || path[0][0] == '/'
|
||||
if path[0] == '/'
|
||||
let path = path[1:]
|
||||
else
|
||||
let path[0] = path[0][1:]
|
||||
endif
|
||||
let sameSubpackageIdx = index(a:currentPath, a:currentPackage[0])
|
||||
if sameSubpackageIdx < 0
|
||||
return s:RelativePath(path, newPath, a:currentPath, a:currentPackage)
|
||||
endif
|
||||
let currentPath = a:currentPath[:sameSubpackageIdx]
|
||||
let idx = index(currentPath, path[0])
|
||||
if idx < 0
|
||||
let newPath .= repeat('..'. g:FILE_SEP, len(currentPath))
|
||||
let newPath .= join(path[:-2], g:FILE_SEP)
|
||||
let newPackage = path[:-2]
|
||||
else
|
||||
let newPath .= idx > 0 ?
|
||||
\ repeat('..'. g:FILE_SEP,
|
||||
\ len(currentPath[:idx-1]))
|
||||
\ :
|
||||
\ ''
|
||||
let newPath .= join(path[1:-2], g:FILE_SEP)
|
||||
let newPackage = path[1:-2]
|
||||
call extend(newPackage, reverse(currentPath)[:-idx-1], 0)
|
||||
endif
|
||||
return {
|
||||
\ 'path' : newPath,
|
||||
\ 'class' : path[-1],
|
||||
\ 'package' : join(newPackage, '.')
|
||||
\ }
|
||||
else
|
||||
return s:RelativePath(path, newPath, a:currentPath, a:currentPackage)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:RelativePath(path, newPath, currentPath, currentPackage)
|
||||
let newPackage = join(a:currentPackage + a:path[:-2], '.')
|
||||
return {
|
||||
\ 'path' : a:newPath. join(a:path[:-2], g:FILE_SEP),
|
||||
\ 'class' : a:path[-1],
|
||||
\ 'package' : newPackage
|
||||
\ }
|
||||
endfunction
|
||||
|
||||
" vim:set fdm=marker sw=2 nowrap:
|
151
bundle/vim-javacomplete2/autoload/javacomplete/parseradapter.vim
vendored
Normal file
151
bundle/vim-javacomplete2/autoload/javacomplete/parseradapter.vim
vendored
Normal file
@ -0,0 +1,151 @@
|
||||
" Vim completion script for java
|
||||
" Maintainer: artur shaik <ashaihullin@gmail.com>
|
||||
"
|
||||
" Methods that calling internal parser
|
||||
|
||||
function! javacomplete#parseradapter#Parse(...)
|
||||
let filename = a:0 == 0 ? '%' : a:1
|
||||
let currentFilename = javacomplete#GetCurrentFileKey()
|
||||
|
||||
let changed = 0
|
||||
if filename == '%' || currentFilename == filename
|
||||
let props = get(g:JavaComplete_Files, currentFilename, {})
|
||||
if get(props, 'changedtick', -1) != b:changedtick
|
||||
let changed = 1
|
||||
let props.changedtick = b:changedtick
|
||||
let lines = getline('^', '$')
|
||||
endif
|
||||
else
|
||||
let props = get(g:JavaComplete_Files, filename, {})
|
||||
if get(props, 'modifiedtime', 0) != getftime(filename)
|
||||
let changed = 1
|
||||
let props.modifiedtime = getftime(filename)
|
||||
if filename =~ '^__'
|
||||
let lines = getline('^', '$')
|
||||
else
|
||||
let lines = readfile(filename)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
if changed
|
||||
call java_parser#InitParser(lines)
|
||||
call java_parser#SetLogLevel(0)
|
||||
let props.unit = java_parser#compilationUnit()
|
||||
|
||||
if &ft == 'jsp'
|
||||
return props
|
||||
endif
|
||||
|
||||
let package = has_key(props.unit, 'package') ? props.unit.package . '.' : ''
|
||||
call s:UpdateFQN(props.unit, package)
|
||||
endif
|
||||
if filename !~ '^__'
|
||||
let g:JavaComplete_Files[filename] = props
|
||||
endif
|
||||
return props.unit
|
||||
endfunction
|
||||
|
||||
" update fqn for toplevel types or nested types.
|
||||
" not for local type or anonymous type
|
||||
function! s:UpdateFQN(tree, qn)
|
||||
if a:tree.tag == 'TOPLEVEL'
|
||||
for def in a:tree.types
|
||||
call s:UpdateFQN(def, a:qn)
|
||||
endfor
|
||||
elseif a:tree.tag == 'CLASSDEF'
|
||||
let a:tree.fqn = a:qn . a:tree.name
|
||||
for def in a:tree.defs
|
||||
if type(def) != type([])
|
||||
unlet def
|
||||
continue
|
||||
endif
|
||||
if def.tag == 'CLASSDEF'
|
||||
call s:UpdateFQN(def, a:tree.fqn . '.')
|
||||
endif
|
||||
endfor
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" TreeVisitor {{{2
|
||||
" parent argument exist for lambdas only
|
||||
function! s:visitTree(tree, param, parent) dict
|
||||
if type(a:tree) == type({})
|
||||
exe get(self, get(a:tree, 'tag', ''), '')
|
||||
elseif type(a:tree) == type([])
|
||||
for tree in a:tree
|
||||
call self.visit(tree, a:param, a:parent)
|
||||
unlet tree
|
||||
endfor
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" we need to return to parent leafs to get lambda's arguments declaration
|
||||
function! s:lambdaMeth(tree)
|
||||
if a:tree.tag == 'APPLY'
|
||||
return {'meth': a:tree.meth, 'stats': {}}
|
||||
elseif a:tree.tag == 'VARDEF'
|
||||
return {'stats': {'tag': a:tree.tag, 't': a:tree.t, 'name': a:tree.name, 'endpos': a:tree.endpos, 'n': a:tree.n, 'pos': a:tree.pos, 'm': a:tree.m}, 'meth': {}}
|
||||
elseif a:tree.tag == 'RETURN'
|
||||
return {'stats': {'tag': a:tree.tag, 'endpos': a:tree.endpos, 'pos': a:tree.pos}, 'meth': {}}
|
||||
endif
|
||||
return {'meth': {}, 'stats': {}}
|
||||
endfunction
|
||||
|
||||
let s:TreeVisitor = {'visit': function('s:visitTree'),
|
||||
\ 'lambdameth': function('s:lambdaMeth'),
|
||||
\ 'TOPLEVEL' : 'call self.visit(a:tree.types, a:param, a:tree)',
|
||||
\ 'BLOCK' : 'let stats = a:tree.stats | if stats == [] | call java_parser#GotoPosition(a:tree.pos) | let stats = java_parser#block().stats | endif | call self.visit(stats, a:param, a:tree)',
|
||||
\ 'DOLOOP' : 'call self.visit(a:tree.body, a:param, a:tree) | call self.visit(a:tree.cond, a:param, a:tree)',
|
||||
\ 'WHILELOOP' : 'call self.visit(a:tree.cond, a:param, a:tree) | call self.visit(a:tree.body, a:param, a:tree)',
|
||||
\ 'FORLOOP' : 'call self.visit(a:tree.init, a:param, a:tree) | call self.visit(a:tree.cond, a:param, a:tree) | call self.visit(a:tree.step, a:param, a:tree) | call self.visit(a:tree.body, a:param, a:tree)',
|
||||
\ 'FOREACHLOOP' : 'call self.visit(a:tree.var, a:param, a:tree) | call self.visit(a:tree.expr, a:param, a:tree) | call self.visit(a:tree.body, a:param, a:tree)',
|
||||
\ 'LABELLED' : 'call self.visit(a:tree.body, a:param, a:tree)',
|
||||
\ 'SWITCH' : 'call self.visit(a:tree.selector, a:param, a:tree) | call self.visit(a:tree.cases, a:param, a:tree)',
|
||||
\ 'CASE' : 'call self.visit(a:tree.pat, a:param, a:tree) | call self.visit(a:tree.stats, a:param, a:tree)',
|
||||
\ 'SYNCHRONIZED': 'call self.visit(a:tree.lock, a:param, a:tree) | call self.visit(a:tree.body, a:param, a:tree)',
|
||||
\ 'TRY' : 'call self.visit(a:tree.params, a:param, a:tree) | call self.visit(a:tree.body, a:param, a:tree) | call self.visit(a:tree.catchers, a:param, a:tree) | call self.visit(a:tree.finalizer, a:param, a:tree) ',
|
||||
\ 'RARROW' : 'call self.visit(a:tree.body, a:param, a:tree)',
|
||||
\ 'CATCH' : 'call self.visit(a:tree.param,a:param, a:tree) | call self.visit(a:tree.body, a:param, a:tree)',
|
||||
\ 'CONDEXPR' : 'call self.visit(a:tree.cond, a:param, a:tree) | call self.visit(a:tree.truepart, a:param, a:tree) | call self.visit(a:tree.falsepart, a:param, a:tree)',
|
||||
\ 'IF' : 'call self.visit(a:tree.cond, a:param, a:tree) | call self.visit(a:tree.thenpart, a:param, a:tree) | if has_key(a:tree, "elsepart") | call self.visit(a:tree.elsepart, a:param, a:tree) | endif',
|
||||
\ 'EXEC' : 'call self.visit(a:tree.expr, a:param, a:tree)',
|
||||
\ 'APPLY' : 'call self.visit(a:tree.meth, a:param, a:tree) | call self.visit(a:tree.args, a:param, a:tree)',
|
||||
\ 'NEWCLASS' : 'call self.visit(a:tree.def, a:param, a:tree)',
|
||||
\ 'RETURN' : 'if has_key(a:tree, "expr") | call self.visit(a:tree.expr, a:param, a:tree) | endif',
|
||||
\ 'LAMBDA' : 'call extend(a:tree, self.lambdameth(a:parent)) | call self.visit(a:tree.meth, a:param, a:tree) | call self.visit(a:tree.stats, a:param, a:tree) | call self.visit(a:tree.args, a:param, a:tree) | call self.visit(a:tree.body, a:param, a:tree)'
|
||||
\}
|
||||
|
||||
let s:TV_CMP_POS = 'a:tree.pos <= a:param.pos && a:param.pos <= get(a:tree, "endpos", -1)'
|
||||
let s:TV_CMP_POS_BODY = 'has_key(a:tree, "body") && a:tree.body.pos <= a:param.pos && a:param.pos <= get(a:tree.body, "endpos", -1)'
|
||||
|
||||
" Return a stack of enclosing types (including local or anonymous classes).
|
||||
" Given the optional argument, return all (toplevel or static member) types besides enclosing types.
|
||||
function! javacomplete#parseradapter#SearchTypeAt(tree, targetPos, ...)
|
||||
let s:TreeVisitor.CLASSDEF = 'if a:param.allNonLocal || ' . s:TV_CMP_POS . ' | call add(a:param.result, a:tree) | call self.visit(a:tree.defs, a:param, a:tree) | endif'
|
||||
let s:TreeVisitor.METHODDEF = 'if ' . s:TV_CMP_POS_BODY . ' | call self.visit(a:tree.body, a:param, a:tree) | endif'
|
||||
let s:TreeVisitor.VARDEF = 'if has_key(a:tree, "init") && !a:param.allNonLocal && ' . s:TV_CMP_POS . ' | call self.visit(a:tree.init, a:param, a:tree) | endif'
|
||||
let s:TreeVisitor.IDENT = ''
|
||||
|
||||
let result = []
|
||||
call s:TreeVisitor.visit(a:tree, {'result': result, 'pos': a:targetPos, 'allNonLocal': a:0 == 0 ? 0 : 1}, {})
|
||||
return result
|
||||
endfunction
|
||||
|
||||
" a:1 match beginning
|
||||
" return a stack of matching name
|
||||
function! javacomplete#parseradapter#SearchNameInAST(tree, name, targetPos, fullmatch)
|
||||
let comparator = a:fullmatch ? '==#' : '=~# "^" .'
|
||||
let cmd = 'if a:tree.name ' .comparator. ' a:param.name | call add(a:param.result, a:tree) | endif'
|
||||
let cmdPos = 'if a:tree.name ' .comparator. ' a:param.name && a:tree.pos <= a:param.pos | call add(a:param.result, a:tree) | endif'
|
||||
let s:TreeVisitor.CLASSDEF = 'if ' . s:TV_CMP_POS . ' | ' . cmd . ' | call self.visit(a:tree.defs, a:param, a:tree) | endif'
|
||||
let s:TreeVisitor.METHODDEF = cmd . ' | if ' . s:TV_CMP_POS_BODY . ' | call self.visit(a:tree.params, a:param, a:tree) | call self.visit(a:tree.body, a:param, a:tree) | endif'
|
||||
let s:TreeVisitor.VARDEF = cmdPos . ' | if has_key(a:tree, "init") && ' . s:TV_CMP_POS . ' | call self.visit(a:tree.init, a:param, a:tree) | endif'
|
||||
let s:TreeVisitor.IDENT = 'if a:parent.tag == "LAMBDA" && a:parent.body.pos <= a:param.pos | call add(a:param.result, a:parent) | endif'
|
||||
|
||||
let result = []
|
||||
call s:TreeVisitor.visit(a:tree, {'result': result, 'pos': a:targetPos, 'name': a:name}, {})
|
||||
return result
|
||||
endfunction
|
||||
|
||||
" vim:set fdm=marker sw=2 nowrap:
|
231
bundle/vim-javacomplete2/autoload/javacomplete/scanner.vim
vendored
Normal file
231
bundle/vim-javacomplete2/autoload/javacomplete/scanner.vim
vendored
Normal file
@ -0,0 +1,231 @@
|
||||
" 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:
|
425
bundle/vim-javacomplete2/autoload/javacomplete/server.vim
vendored
Normal file
425
bundle/vim-javacomplete2/autoload/javacomplete/server.vim
vendored
Normal file
@ -0,0 +1,425 @@
|
||||
" Vim completion script for java
|
||||
" Maintainer: artur shaik <ashaihullin@gmail.com>
|
||||
"
|
||||
" Java server bridge initiator and caller
|
||||
|
||||
let s:serverStartBlocked = 0
|
||||
let s:autoRecompileCheckFlag = 0
|
||||
|
||||
function! s:Log(log)
|
||||
let log = type(a:log) == type("") ? a:log : string(a:log)
|
||||
call javacomplete#logger#Log("[server] ". log)
|
||||
endfunction
|
||||
|
||||
function! javacomplete#server#BlockStart()
|
||||
let s:serverStartBlocked = 1
|
||||
endfunction
|
||||
|
||||
function! javacomplete#server#UnblockStart()
|
||||
let s:serverStartBlocked = 0
|
||||
endfunction
|
||||
|
||||
function! s:System(cmd, caller)
|
||||
let t = reltime()
|
||||
let res = system(a:cmd)
|
||||
call s:Log(reltimestr(reltime(t)) . 's to exec "' . a:cmd . '" by ' . a:caller)
|
||||
return res
|
||||
endfunction
|
||||
|
||||
function! s:Poll()
|
||||
let value = 0
|
||||
JavacompletePy << EOPC
|
||||
try:
|
||||
vim.command("let value = '%d'" % bridgeState.poll())
|
||||
except:
|
||||
# we'll get here if the bridgeState variable was not defined or if it's None.
|
||||
# In this case we stop the processing and return the default 0 value.
|
||||
pass
|
||||
EOPC
|
||||
return value
|
||||
endfunction
|
||||
|
||||
function! javacomplete#server#Terminate()
|
||||
if s:Poll()
|
||||
JavacompletePy bridgeState.terminateServer()
|
||||
|
||||
let pid = 0
|
||||
JavacompletePy vim.command('let pid = %d' % bridgeState.pid())
|
||||
if pid > 1
|
||||
if g:JavaComplete_IsWindows
|
||||
call system('taskkill /t /pid '. pid)
|
||||
else
|
||||
call system('kill '. (pid + 1))
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:ControlServerAppVersion()
|
||||
let classpath =
|
||||
\ s:GetJavaviClassPath(). g:PATH_SEP.
|
||||
\ s:GetJavaviDeps(). g:PATH_SEP
|
||||
let s:serverVersionOutput = []
|
||||
call javacomplete#util#RunSystem(join(
|
||||
\ [
|
||||
\ javacomplete#server#GetJVMLauncher(), '-cp', classpath,
|
||||
\ 'kg.ash.javavi.Javavi -version'
|
||||
\ ]),
|
||||
\ 'Javavi server version check',
|
||||
\ 'javacomplete#server#CheckServerAccordance')
|
||||
endfunction
|
||||
|
||||
function! javacomplete#server#CheckServerAccordance(data, event)
|
||||
if a:event == 'exit'
|
||||
if a:data == '0'
|
||||
let serverVersion = join(s:serverVersionOutput)
|
||||
if !javacomplete#version#CheckServerCompatibility(serverVersion)
|
||||
call s:Log("server ". serverVersion. " is outdated, recompile")
|
||||
call javacomplete#server#Compile()
|
||||
endif
|
||||
endif
|
||||
|
||||
unlet s:serverVersionOutput
|
||||
elseif a:event == 'stdout'
|
||||
call extend(s:serverVersionOutput, a:data)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! javacomplete#server#Start()
|
||||
if s:Poll() == 0 && s:serverStartBlocked == 0
|
||||
if get(g:, 'JavaComplete_CheckServerVersionAtStartup', 1)
|
||||
call s:ControlServerAppVersion()
|
||||
endif
|
||||
|
||||
JavacompletePy import vim
|
||||
let file = g:JavaComplete_Home. g:FILE_SEP. "autoload". g:FILE_SEP. "javavibridge.py"
|
||||
call s:Log("executing python file: " . file)
|
||||
execute "JavacompletePyfile ". file
|
||||
|
||||
let javaProps = []
|
||||
if exists('g:JavaComplete_JavaviLogLevel')
|
||||
call add(javaProps, '-Dlog.level='. g:JavaComplete_JavaviLogLevel)
|
||||
endif
|
||||
if !empty(g:JavaComplete_JavaviLogDirectory)
|
||||
call add(javaProps, '-Dlog.directory='. g:JavaComplete_JavaviLogDirectory)
|
||||
endif
|
||||
JavacompletePy vim.command('let port = "%s"' % SERVER[1])
|
||||
call add(javaProps, '-Ddaemon.port='. port)
|
||||
let log4j2Config = join([g:JavaComplete_Home,'libs', 'javavi', 'target', 'classes', 'log4j2.xml'], g:FILE_SEP)
|
||||
call add(javaProps, '-Dlog4j.configurationFile='. log4j2Config)
|
||||
|
||||
let classpath = substitute(javacomplete#server#GetClassPath(), '\\', '\\\\', 'g')
|
||||
let sources = []
|
||||
if exists('g:JavaComplete_SourcesPath')
|
||||
let sources += ['-sources', s:ExpandAllPaths(g:JavaComplete_SourcesPath)]
|
||||
endif
|
||||
|
||||
let args = javaProps + ['kg.ash.javavi.Javavi'] + sources
|
||||
if g:JavaComplete_ServerAutoShutdownTime > 0
|
||||
let args += ['-t', g:JavaComplete_ServerAutoShutdownTime]
|
||||
endif
|
||||
let args += ['-base', javacomplete#util#GetBase('')]
|
||||
let args += ['-compiler', javacomplete#server#GetCompiler()]
|
||||
if !empty(g:JavaComplete_ProjectKey)
|
||||
let args += ['-project', g:JavaComplete_ProjectKey]
|
||||
endif
|
||||
|
||||
call s:Log("server classpath: -cp ". classpath)
|
||||
call s:Log("server arguments:". join(args, ' '))
|
||||
|
||||
JavacompletePy bridgeState = JavaviBridge()
|
||||
JavacompletePy bridgeState.setupServer(vim.eval('javacomplete#server#GetJVMLauncher()'), vim.eval('args'), vim.eval('classpath'))
|
||||
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! javacomplete#server#ShowPort()
|
||||
if s:Poll()
|
||||
JavacompletePy vim.command('echo "Javavi port: %d"' % bridgeState.port())
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! javacomplete#server#ShowPID()
|
||||
if s:Poll()
|
||||
JavacompletePy vim.command('echo "Javavi pid: %d"' % bridgeState.pid())
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! javacomplete#server#GetCompiler()
|
||||
return exists('g:JavaComplete_JavaCompiler') && g:JavaComplete_JavaCompiler !~ '^\s*$' ? g:JavaComplete_JavaCompiler : 'javac'
|
||||
endfunction
|
||||
|
||||
function! javacomplete#server#SetCompiler(compiler)
|
||||
let g:JavaComplete_JavaCompiler = a:compiler
|
||||
endfunction
|
||||
|
||||
function! javacomplete#server#GetJVMLauncher()
|
||||
return exists('g:JavaComplete_JvmLauncher') && g:JavaComplete_JvmLauncher !~ '^\s*$' ? g:JavaComplete_JvmLauncher : 'java'
|
||||
endfunction
|
||||
|
||||
function! javacomplete#server#SetJVMLauncher(interpreter)
|
||||
if javacomplete#server#GetJVMLauncher() != a:interpreter
|
||||
let g:JavaComplete_Cache = {}
|
||||
endif
|
||||
let g:JavaComplete_JvmLauncher = a:interpreter
|
||||
endfunction
|
||||
|
||||
function! javacomplete#server#CompilationJobHandler(data, event)
|
||||
if a:event == 'exit'
|
||||
if a:data == "0"
|
||||
JCserverStart
|
||||
echo 'Javavi compilation finished '
|
||||
else
|
||||
echo 'Failed to compile javavi server'
|
||||
endif
|
||||
let s:compilationIsRunning = 0
|
||||
elseif a:event == 'stderr'
|
||||
echomsg join(a:data)
|
||||
elseif a:event == 'stdout'
|
||||
if g:JavaComplete_ShowExternalCommandsOutput
|
||||
echomsg join(a:data)
|
||||
endif
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! javacomplete#server#Compile()
|
||||
call javacomplete#server#Terminate()
|
||||
|
||||
let javaviDir = g:JavaComplete_Home. g:FILE_SEP. join(['libs', 'javavi'], g:FILE_SEP). g:FILE_SEP
|
||||
if isdirectory(javaviDir. join(['target', 'classes'], g:FILE_SEP))
|
||||
call javacomplete#util#RemoveFile(javaviDir.join(['target', 'classes'], g:FILE_SEP))
|
||||
endif
|
||||
|
||||
let s:compilationIsRunning = 1
|
||||
if executable('mvn')
|
||||
let command = ['mvn', '-B', '-f', javaviDir. g:FILE_SEP. 'pom.xml', 'compile']
|
||||
else
|
||||
call mkdir(javaviDir. join(['target', 'classes'], g:FILE_SEP), "p")
|
||||
let deps = s:GetJavaviDeps()
|
||||
let command = javacomplete#server#GetCompiler()
|
||||
let command .= ' -d '. javaviDir. 'target'. g:FILE_SEP. 'classes -classpath '. javaviDir. 'target'. g:FILE_SEP. 'classes'. g:PATH_SEP. deps. ' -sourcepath '. javaviDir. 'src'. g:FILE_SEP. 'main'. g:FILE_SEP. 'java -g -nowarn -target 1.8 -source 1.8 -encoding UTF-8 '. javaviDir. join(['src', 'main', 'java', 'kg', 'ash', 'javavi', 'Javavi.java'], g:FILE_SEP)
|
||||
endif
|
||||
call javacomplete#util#RunSystem(command, "server compilation", "javacomplete#server#CompilationJobHandler")
|
||||
endfunction
|
||||
|
||||
" Check if Javavi classes exists and return classpath directory.
|
||||
" If not found, build Javavi library classes with maven or javac.
|
||||
fu! s:GetJavaviClassPath()
|
||||
let javaviDir = g:JavaComplete_Home. join(['', 'libs', 'javavi', ''], g:FILE_SEP)
|
||||
if !isdirectory(javaviDir. "target". g:FILE_SEP. "classes")
|
||||
call javacomplete#server#Compile()
|
||||
endif
|
||||
|
||||
if !empty(javacomplete#util#GlobPathList(javaviDir. 'target'. g:FILE_SEP. 'classes', '**'. g:FILE_SEP. '*.class', 1, 0))
|
||||
return javaviDir. "target". g:FILE_SEP. "classes"
|
||||
else
|
||||
if !get(s:, 'compilationIsRunning', 0)
|
||||
echo "No Javavi library classes found, it means that we couldn't compile it. Do you have JDK8+ installed?"
|
||||
endif
|
||||
endif
|
||||
endfu
|
||||
|
||||
" Function for server communication {{{2
|
||||
function! javacomplete#server#Communicate(option, args, log)
|
||||
if !s:Poll()
|
||||
call javacomplete#server#Start()
|
||||
endif
|
||||
|
||||
if s:Poll()
|
||||
if !empty(a:args)
|
||||
let args = ' "'. substitute(a:args, '"', '\\"', 'g'). '"'
|
||||
else
|
||||
let args = ''
|
||||
endif
|
||||
let cmd = a:option. args
|
||||
call s:Log("communicate: ". cmd. " [". a:log. "]")
|
||||
let result = ""
|
||||
JavacompletePy << EOPC
|
||||
vim.command('let result = "%s"' % bridgeState.send(vim.eval("cmd")).replace('"', '\\"'))
|
||||
EOPC
|
||||
|
||||
call s:Log(result)
|
||||
if result =~ '^message:'
|
||||
echom result
|
||||
return "[]"
|
||||
endif
|
||||
|
||||
return result
|
||||
endif
|
||||
|
||||
return ""
|
||||
endfunction
|
||||
|
||||
function! javacomplete#server#GetClassPath()
|
||||
let jars = s:GetExtraPath()
|
||||
let path = s:GetJavaviClassPath() . g:PATH_SEP. s:GetJavaviDeps(). g:PATH_SEP
|
||||
let path = path . join(jars, g:PATH_SEP) . g:PATH_SEP
|
||||
|
||||
if &ft == 'jsp'
|
||||
let path .= s:GetClassPathOfJsp()
|
||||
endif
|
||||
|
||||
if exists('b:classpath') && b:classpath !~ '^\s*$'
|
||||
call s:Log(b:classpath)
|
||||
return path . b:classpath
|
||||
endif
|
||||
|
||||
if exists('s:classpath')
|
||||
call s:Log(s:classpath)
|
||||
return path . javacomplete#GetClassPath()
|
||||
endif
|
||||
|
||||
if exists('g:java_classpath') && g:java_classpath !~ '^\s*$'
|
||||
call s:Log(g:java_classpath)
|
||||
return path . g:java_classpath
|
||||
endif
|
||||
|
||||
if empty($CLASSPATH)
|
||||
if g:JAVA_HOME == ''
|
||||
let java = javacomplete#server#GetJVMLauncher()
|
||||
let javaSettings = split(s:System(java. " -XshowSettings", "Get java settings"), '\n')
|
||||
for line in javaSettings
|
||||
if line =~ 'java\.home'
|
||||
let g:JAVA_HOME = split(line, ' = ')[1]
|
||||
endif
|
||||
endfor
|
||||
endif
|
||||
return path. g:JAVA_HOME. g:FILE_SEP. 'lib'
|
||||
endif
|
||||
|
||||
return path . $CLASSPATH
|
||||
endfunction
|
||||
|
||||
function! s:ExpandAllPaths(path)
|
||||
let result = ''
|
||||
let list = javacomplete#util#uniq(sort(split(a:path, g:PATH_SEP)))
|
||||
for l in list
|
||||
let result = result. substitute(expand(l), '\\', '/', 'g') . g:PATH_SEP
|
||||
endfor
|
||||
return result
|
||||
endfunction
|
||||
|
||||
function! s:GetJavaviDeps()
|
||||
let deps = []
|
||||
call add(deps, fnamemodify(g:JavaComplete_Home. join(['', 'libs', 'javaparser-core-3.5.20.jar'], g:FILE_SEP), ":p"))
|
||||
call add(deps, fnamemodify(g:JavaComplete_Home. join(['', 'libs', 'javavi_log4j-api.jar'], g:FILE_SEP), ":p"))
|
||||
call add(deps, fnamemodify(g:JavaComplete_Home. join(['', 'libs', 'javavi_log4j-core.jar'], g:FILE_SEP), ":p"))
|
||||
let path = join(deps, g:PATH_SEP)
|
||||
if exists('b:classpath') && b:classpath !~ '^\s*$'
|
||||
return path . b:classpath
|
||||
endif
|
||||
|
||||
if exists('s:classpath')
|
||||
return path . s:GetClassPath()
|
||||
endif
|
||||
|
||||
if exists('g:java_classpath') && g:java_classpath !~ '^\s*$'
|
||||
return path . g:java_classpath
|
||||
endif
|
||||
|
||||
return path
|
||||
endfunction
|
||||
|
||||
function! s:GetExtraPath()
|
||||
let jars = []
|
||||
let extrapath = ''
|
||||
if exists('g:JavaComplete_LibsPath')
|
||||
let paths = split(g:JavaComplete_LibsPath, g:PATH_SEP)
|
||||
for path in paths
|
||||
let exp = s:ExpandPathToJars(path)
|
||||
if empty(exp)
|
||||
" ex: target/classes
|
||||
call extend(jars, [path])
|
||||
else
|
||||
call extend(jars, exp)
|
||||
endif
|
||||
endfor
|
||||
endif
|
||||
|
||||
return jars
|
||||
endfunction
|
||||
|
||||
function! s:ExpandPathToJars(path, ...)
|
||||
if isdirectory(a:path)
|
||||
return javacomplete#util#GlobPathList(a:path, "**5/*.jar", 1, 0)
|
||||
\ + javacomplete#util#GlobPathList(a:path, "**5/*.zip", 1, 0)
|
||||
elseif index(['zip', 'jar'], fnamemodify(a:path, ':e')) != -1
|
||||
return [a:path]
|
||||
endif
|
||||
return []
|
||||
endfunction
|
||||
|
||||
fu! s:GetClassPathOfJsp()
|
||||
if exists('b:classpath_jsp')
|
||||
return b:classpath_jsp
|
||||
endif
|
||||
|
||||
let b:classpath_jsp = ''
|
||||
let path = expand('%:p:h')
|
||||
while 1
|
||||
if isdirectory(path . '/WEB-INF' )
|
||||
if isdirectory(path . '/WEB-INF/classes')
|
||||
let b:classpath_jsp .= g:PATH_SEP . path . '/WEB-INF/classes'
|
||||
endif
|
||||
if isdirectory(path . '/WEB-INF/lib')
|
||||
let b:classpath_jsp .= g:PATH_SEP . path . '/WEB-INF/lib/*.jar'
|
||||
endif
|
||||
endif
|
||||
return b:classpath_jsp
|
||||
endif
|
||||
|
||||
let prev = path
|
||||
let path = fnamemodify(path, ":p:h:h")
|
||||
if path == prev
|
||||
break
|
||||
endif
|
||||
endwhile
|
||||
return ''
|
||||
endfu
|
||||
|
||||
function! s:GetClassPath()
|
||||
return exists('s:classpath') ? join(s:classpath, g:PATH_SEP) : ''
|
||||
endfu
|
||||
|
||||
function! s:GetDebugLogPath()
|
||||
return javacomplete#server#Communicate('-get-debug-log-path', '', '')
|
||||
endfunction
|
||||
|
||||
function! javacomplete#server#EnableDebug()
|
||||
let g:JavaComplete_JavaviLogLevel = "debug"
|
||||
if s:Poll()
|
||||
JCserverTerminate
|
||||
JCserverStart
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! javacomplete#server#EnableTraceDebug()
|
||||
let g:JavaComplete_JavaviLogLevel = "trace"
|
||||
if s:Poll()
|
||||
JCserverTerminate
|
||||
JCserverStart
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! javacomplete#server#GetLogContent()
|
||||
let bufferName = "__JCServer_Log_Buffer__"
|
||||
let n = bufnr(bufferName)
|
||||
if n != -1
|
||||
execute "bwipeout! ". n
|
||||
endif
|
||||
let curWin = winnr("#")
|
||||
execute 'silent! split '. bufferName
|
||||
set modifiable
|
||||
setlocal buftype=nofile
|
||||
setlocal bufhidden=wipe
|
||||
setlocal noswapfile
|
||||
setlocal nowrap
|
||||
setlocal nobuflisted
|
||||
execute '.-1read '. s:GetDebugLogPath()
|
||||
execute "normal! G"
|
||||
set nomodified
|
||||
nnoremap <buffer> <silent> q :bwipeout!<CR>
|
||||
execute curWin. 'wincmd w'
|
||||
endfunction
|
||||
|
||||
" vim:set fdm=marker sw=2 nowrap:
|
453
bundle/vim-javacomplete2/autoload/javacomplete/util.vim
vendored
Normal file
453
bundle/vim-javacomplete2/autoload/javacomplete/util.vim
vendored
Normal file
@ -0,0 +1,453 @@
|
||||
" Vim completion script for java
|
||||
" Maintainer: artur shaik <ashaihullin@gmail.com>
|
||||
"
|
||||
" Utility functions
|
||||
|
||||
function! s:Log(log)
|
||||
let log = type(a:log) == type("") ? a:log : string(a:log)
|
||||
call javacomplete#logger#Log("[util] ". log)
|
||||
endfunction
|
||||
|
||||
" TODO: search pair used in string, like
|
||||
" 'create(ao.fox("("), new String).foo().'
|
||||
function! javacomplete#util#GetMatchedIndexEx(str, idx, one, another)
|
||||
let pos = a:idx
|
||||
while 0 <= pos && pos < len(a:str)
|
||||
let pos = match(a:str, '['. a:one . escape(a:another, ']') .']', pos+1)
|
||||
if pos != -1
|
||||
if a:str[pos] == a:one
|
||||
let pos = javacomplete#util#GetMatchedIndexEx(a:str, pos, a:one, a:another)
|
||||
elseif a:str[pos] == a:another
|
||||
break
|
||||
endif
|
||||
endif
|
||||
endwhile
|
||||
return 0 <= pos && pos < len(a:str) ? pos : -3
|
||||
endfunction
|
||||
|
||||
" set string literal empty, remove comments, trim begining or ending spaces
|
||||
" test case: ' sb. /* block comment*/ append( "stringliteral" ) // comment '
|
||||
function! javacomplete#util#Prune(str, ...)
|
||||
if a:str =~ '^\s*$' | return '' | endif
|
||||
|
||||
let str = substitute(a:str, '"\(\\\(["\\''ntbrf]\)\|[^"]\)*"', '""', 'g')
|
||||
let str = substitute(str, '\/\/.*', '', 'g')
|
||||
let str = javacomplete#util#RemoveBlockComments(str)
|
||||
let str = javacomplete#util#Trim(str)
|
||||
return a:0 > 0 ? str : str . ' '
|
||||
endfunction
|
||||
|
||||
" Given argument, replace block comments with spaces of same number
|
||||
function! javacomplete#util#RemoveBlockComments(str, ...)
|
||||
let result = a:str
|
||||
let ib = match(result, '\/\*')
|
||||
let ie = match(result, '\*\/')
|
||||
while ib != -1 && ie != -1 && ib < ie
|
||||
let result = strpart(result, 0, ib) . (a:0 == 0 ? ' ' : repeat(' ', ie-ib+2)) . result[ie+2: ]
|
||||
let ib = match(result, '\/\*')
|
||||
let ie = match(result, '\*\/')
|
||||
endwhile
|
||||
return result
|
||||
endfunction
|
||||
|
||||
function! javacomplete#util#Trim(str)
|
||||
let str = substitute(a:str, '^\s*', '', '')
|
||||
return substitute(str, '\s*$', '', '')
|
||||
endfunction
|
||||
|
||||
fu! javacomplete#util#SplitAt(str, index)
|
||||
return [strpart(a:str, 0, a:index+1), strpart(a:str, a:index+1)]
|
||||
endfu
|
||||
|
||||
function! javacomplete#util#SearchPairBackward(str, idx, one, another)
|
||||
let idx = a:idx
|
||||
let n = 0
|
||||
while idx >= 0
|
||||
let idx -= 1
|
||||
if a:str[idx] == a:one
|
||||
if n == 0
|
||||
break
|
||||
endif
|
||||
let n -= 1
|
||||
elseif a:str[idx] == a:another " nested
|
||||
let n += 1
|
||||
endif
|
||||
endwhile
|
||||
return idx
|
||||
endfunction
|
||||
|
||||
function! javacomplete#util#CountDims(str)
|
||||
if match(a:str, '[[\]]') == -1
|
||||
return 0
|
||||
endif
|
||||
|
||||
" int[] -> [I, String[] ->
|
||||
let dims = len(matchstr(a:str, '^[\+'))
|
||||
if dims == 0
|
||||
let idx = len(a:str)-1
|
||||
while idx >= 0 && a:str[idx] == ']'
|
||||
let dims += 1
|
||||
let idx = javacomplete#util#SearchPairBackward(a:str, idx, '[', ']')-1
|
||||
endwhile
|
||||
endif
|
||||
return dims
|
||||
endfu
|
||||
|
||||
function! javacomplete#util#Index(list, expr, key)
|
||||
let i = 0
|
||||
while i < len(a:list)
|
||||
if get(a:list[i], a:key, '') == a:expr
|
||||
return i
|
||||
endif
|
||||
let i += 1
|
||||
endwhile
|
||||
return -1
|
||||
endfunction
|
||||
|
||||
function! javacomplete#util#KeepCursor(cmd)
|
||||
let lnum_old = line('.')
|
||||
let col_old = col('.')
|
||||
exe a:cmd
|
||||
call cursor(lnum_old, col_old)
|
||||
endfunction
|
||||
|
||||
function! javacomplete#util#InCommentOrLiteral(line, col)
|
||||
if has("syntax") && &ft != 'jsp'
|
||||
return synIDattr(synID(a:line, a:col, 1), "name") =~? '\(Comment\|String\|Character\)'
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! javacomplete#util#InComment(line, col)
|
||||
if has("syntax") && &ft != 'jsp'
|
||||
return synIDattr(synID(a:line, a:col, 1), "name") =~? 'comment'
|
||||
endif
|
||||
endfunction
|
||||
|
||||
fu! javacomplete#util#GotoUpperBracket()
|
||||
let searched = 0
|
||||
while (!searched)
|
||||
call search('[{}]', 'bW')
|
||||
if getline('.')[col('.')-1] == '}'
|
||||
normal! %
|
||||
else
|
||||
let searched = 1
|
||||
endif
|
||||
endwhile
|
||||
endfu
|
||||
|
||||
function! javacomplete#util#GetClassNameWithScope(...)
|
||||
let offset = a:0 > 0 ? a:1 : col('.')
|
||||
let curline = getline('.')
|
||||
let word_l = offset - 1
|
||||
while curline[word_l - 1] =~ '[\.:@A-Za-z0-9_]'
|
||||
let word_l -= 1
|
||||
if curline[word_l] == '@'
|
||||
break
|
||||
endif
|
||||
endwhile
|
||||
let word_r = word_l
|
||||
while curline[word_r] =~ '[@A-Za-z0-9_]'
|
||||
let word_r += 1
|
||||
endwhile
|
||||
|
||||
return curline[word_l : word_r - 1]
|
||||
endfunction
|
||||
|
||||
function! s:MemberCompare(m1, m2)
|
||||
return a:m1['n'] == a:m2['n'] ? 0 : a:m1['n'] > a:m2['n'] ? 1 : -1
|
||||
endfunction
|
||||
|
||||
function! javacomplete#util#Sort(ci)
|
||||
let ci = a:ci
|
||||
if has_key(ci, 'fields')
|
||||
call sort(ci['fields'], 's:MemberCompare')
|
||||
endif
|
||||
if has_key(ci, 'methods')
|
||||
call sort(ci['methods'], 's:MemberCompare')
|
||||
endif
|
||||
return ci
|
||||
endfunction
|
||||
|
||||
function! javacomplete#util#CleanFQN(fqnDeclaration)
|
||||
let start = 0
|
||||
let fqnDeclaration = a:fqnDeclaration
|
||||
let result = matchlist(fqnDeclaration, '\<'. g:RE_IDENTIFIER. '\%(\s*\.\s*\('. g:RE_IDENTIFIER. '\)\)*', start)
|
||||
while !empty(result)
|
||||
|
||||
if len(result[1]) > 0
|
||||
if result[0][-1:-1] == '$'
|
||||
let result[0] = result[0][:-2]. '\$'
|
||||
endif
|
||||
let fqnDeclaration = substitute(fqnDeclaration, result[0], result[1], '')
|
||||
let shift = result[1]
|
||||
else
|
||||
let shift = result[0]
|
||||
endif
|
||||
if shift[-1:-1] == '$'
|
||||
let shift = shift[:-2]. '\$'
|
||||
endif
|
||||
let start = match(fqnDeclaration, shift, start) + len(shift)
|
||||
|
||||
let result = matchlist(fqnDeclaration, '\<'. g:RE_IDENTIFIER. '\%(\s*\.\s*\('. g:RE_IDENTIFIER. '\)\)*', start)
|
||||
endwhile
|
||||
|
||||
return fqnDeclaration
|
||||
endfunction
|
||||
|
||||
function! javacomplete#util#FindFile(what, ...) abort
|
||||
let direction = a:0 > 0 ? a:1 : ';'
|
||||
let old_suffixesadd = &suffixesadd
|
||||
try
|
||||
let &suffixesadd = ''
|
||||
return findfile(a:what, escape(expand('.'), '*[]?{}, ') . direction)
|
||||
finally
|
||||
let &suffixesadd = old_suffixesadd
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
function! javacomplete#util#GlobPathList(path, pattern, suf, depth)
|
||||
if v:version > 704 || v:version == 704 && has('patch279')
|
||||
let pathList = globpath(a:path, a:pattern, a:suf, 1)
|
||||
else
|
||||
let pathList = split(globpath(a:path, a:pattern, a:suf), "\n")
|
||||
endif
|
||||
if a:depth > 0
|
||||
let depths = []
|
||||
for i in range(1, a:depth)
|
||||
call add(depths, repeat("*".g:FILE_SEP, i))
|
||||
endfor
|
||||
for i in depths
|
||||
call extend(pathList, javacomplete#util#GlobPathList(a:path, i. a:pattern, 0, 0))
|
||||
endfor
|
||||
endif
|
||||
return pathList
|
||||
endfunction
|
||||
|
||||
function! javacomplete#util#IsWindows() abort
|
||||
return has("win32") || has("win64") || has("win16") || has("dos32") || has("dos16")
|
||||
endfunction
|
||||
|
||||
function! s:JobVimOnCloseHandler(channel)
|
||||
let job = s:asyncJobs[s:ChannelId(a:channel)]
|
||||
let info = job_info(job['job'])
|
||||
let Handler = function(job['handler'])
|
||||
call call(Handler, [info['exitval'], 'exit'])
|
||||
endfunction
|
||||
|
||||
function! s:JobVimOnErrorHandler(channel, text)
|
||||
let job = s:asyncJobs[s:ChannelId(a:channel)]
|
||||
let Handler = function(job['handler'])
|
||||
call call(Handler, [[a:text], 'stderr'])
|
||||
endfunction
|
||||
|
||||
function! s:JobVimOnCallbackHandler(channel, text)
|
||||
let job = s:asyncJobs[s:ChannelId(a:channel)]
|
||||
let Handler = function(job['handler'])
|
||||
call call(Handler, [[a:text], 'stdout'])
|
||||
endfunction
|
||||
|
||||
function! s:JobNeoVimResponseHandler(jobId, data, event)
|
||||
let job = s:asyncJobs[a:jobId]
|
||||
let Handler = function(job['handler'])
|
||||
call call(Handler, [a:data, a:event])
|
||||
endfunction
|
||||
|
||||
function! s:ChannelId(channel)
|
||||
return matchstr(a:channel, '\d\+')
|
||||
endfunction
|
||||
|
||||
function! s:NewJob(id, handler)
|
||||
let s:asyncJobs = get(s:, 'asyncJobs', {})
|
||||
let s:asyncJobs[a:id] = {}
|
||||
let s:asyncJobs[a:id]['handler'] = a:handler
|
||||
endfunction
|
||||
|
||||
function! javacomplete#util#RunSystem(command, shellName, handler)
|
||||
call s:Log("running command: ". string(a:command))
|
||||
if has('nvim')
|
||||
if exists('*jobstart')
|
||||
let callbacks = {
|
||||
\ 'on_stdout': function('s:JobNeoVimResponseHandler'),
|
||||
\ 'on_stderr': function('s:JobNeoVimResponseHandler'),
|
||||
\ 'on_exit': function('s:JobNeoVimResponseHandler')
|
||||
\ }
|
||||
let jobId = jobstart(a:command, extend({'shell': a:shellName}, callbacks))
|
||||
call s:NewJob(jobId, a:handler)
|
||||
return
|
||||
endif
|
||||
elseif exists('*job_start')
|
||||
let options = {
|
||||
\ 'out_cb' : function('s:JobVimOnCallbackHandler'),
|
||||
\ 'err_cb' : function('s:JobVimOnErrorHandler'),
|
||||
\ 'close_cb' : function('s:JobVimOnCloseHandler')
|
||||
\ }
|
||||
if has('win32') && type(a:command) == 3
|
||||
let a:command[0] = exepath(a:command[0])
|
||||
endif
|
||||
let job = job_start(a:command, options)
|
||||
let jobId = s:ChannelId(job_getchannel(job))
|
||||
call s:NewJob(jobId, a:handler)
|
||||
let s:asyncJobs[jobId]['job'] = job
|
||||
return
|
||||
endif
|
||||
|
||||
if type(a:command) == type([])
|
||||
let ret = system(join(a:command, " "))
|
||||
else
|
||||
let ret = system(a:command)
|
||||
endif
|
||||
for l in split(ret, "\n")
|
||||
call call(a:handler, [[l], "stdout"])
|
||||
endfor
|
||||
call call(a:handler, ["0", "exit"])
|
||||
endfunction
|
||||
|
||||
function! javacomplete#util#Base64Encode(str)
|
||||
JavacompletePy import base64
|
||||
JavacompletePy import vim
|
||||
JavacompletePy content = vim.eval('a:str') if sys.version_info.major == 2 else bytes(vim.eval('a:str'), 'utf-8')
|
||||
JavacompletePy b64 = base64.b64encode(content)
|
||||
JavacompletePy vim.command("let base64 = '%s'" % (b64 if sys.version_info.major == 2 else b64.decode('utf-8')))
|
||||
return base64
|
||||
endfunction
|
||||
|
||||
function! javacomplete#util#RemoveFile(file)
|
||||
if filewritable(a:file)
|
||||
if g:JavaComplete_IsWindows
|
||||
silent exe '!rmdir /s /q "'. a:file. '"'
|
||||
else
|
||||
silent exe '!rm -r "'. a:file. '"'
|
||||
endif
|
||||
silent redraw!
|
||||
endif
|
||||
endfunction
|
||||
|
||||
if exists('*uniq')
|
||||
function! javacomplete#util#uniq(list) abort
|
||||
return uniq(a:list)
|
||||
endfunction
|
||||
else
|
||||
function! javacomplete#util#uniq(list) abort
|
||||
let i = len(a:list) - 1
|
||||
while 0 < i
|
||||
if a:list[i] ==# a:list[i - 1]
|
||||
call remove(a:list, i)
|
||||
let i -= 2
|
||||
else
|
||||
let i -= 1
|
||||
endif
|
||||
endwhile
|
||||
return a:list
|
||||
endfunction
|
||||
endif
|
||||
|
||||
function! javacomplete#util#GetBase(extra)
|
||||
let base = expand(g:JavaComplete_BaseDir. g:FILE_SEP. "javacomplete2". g:FILE_SEP. a:extra)
|
||||
if !isdirectory(base)
|
||||
call mkdir(base, "p")
|
||||
endif
|
||||
|
||||
return base
|
||||
endfunction
|
||||
|
||||
function! javacomplete#util#RemoveEmptyClasses(classes)
|
||||
return filter(a:classes, 'v:val !~ "^$"')
|
||||
endfunction
|
||||
|
||||
function! javacomplete#util#GetRegularClassesDict()
|
||||
if exists('s:RegularClassesDict')
|
||||
return s:RegularClassesDict
|
||||
endif
|
||||
let path = javacomplete#util#GetBase('cache'). g:FILE_SEP. 'regular_classes_'. g:JavaComplete_ProjectKey. '.dat'
|
||||
if filereadable(path)
|
||||
let classes = readfile(path)
|
||||
else
|
||||
let classes = []
|
||||
endif
|
||||
let classes = javacomplete#util#RemoveEmptyClasses(javacomplete#util#uniq(sort(extend(classes, g:JavaComplete_RegularClasses))))
|
||||
let dict = {}
|
||||
for class in classes
|
||||
call extend(dict, {split(class,'\.')[-1] : class})
|
||||
endfor
|
||||
let s:RegularClassesDict = dict
|
||||
return s:RegularClassesDict
|
||||
endfunction
|
||||
|
||||
function! javacomplete#util#SaveRegularClassesList(classesDict)
|
||||
let path = javacomplete#util#GetBase('cache'). g:FILE_SEP. 'regular_classes_'. g:JavaComplete_ProjectKey. '.dat'
|
||||
call writefile(values(a:classesDict), path)
|
||||
unlet s:RegularClassesDict
|
||||
endfunction
|
||||
|
||||
function! javacomplete#util#IsStatic(modifier)
|
||||
return a:modifier[strlen(a:modifier)-4]
|
||||
endfunction
|
||||
|
||||
function! javacomplete#util#IsBuiltinType(name)
|
||||
return index(g:J_PRIMITIVE_TYPES, a:name) >= 0
|
||||
endfunction
|
||||
|
||||
function! javacomplete#util#IsKeyword(name)
|
||||
return index(g:J_KEYWORDS, a:name) >= 0
|
||||
endfunction
|
||||
|
||||
function! javacomplete#util#HasKeyword(name)
|
||||
return a:name =~# g:RE_KEYWORDS
|
||||
endfunction
|
||||
|
||||
function! javacomplete#util#CheckModifier(modifier, condition)
|
||||
if type(a:condition) == type([])
|
||||
for condition in a:condition
|
||||
if condition <= len(a:modifier)
|
||||
if a:modifier[-condition : -condition] == '1'
|
||||
return 1
|
||||
endif
|
||||
endif
|
||||
endfor
|
||||
return 0
|
||||
else
|
||||
if a:condition <= len(a:modifier)
|
||||
return a:modifier[-a:condition : -a:condition] == '1'
|
||||
endif
|
||||
return 0
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! javacomplete#util#GenMethodParamsDeclaration(method)
|
||||
if has_key(a:method, 'p')
|
||||
let match = matchlist(a:method.d, '^\(.*(\)')
|
||||
if len(match) > 0
|
||||
let d = match[1]
|
||||
let match = matchlist(a:method.d, '.*)\(.*\)$')
|
||||
let throws = len(match) > 0 ? substitute(match[1], ',', ', ', 'g') : ''
|
||||
|
||||
let ds = []
|
||||
let paramNames = []
|
||||
for p in a:method.p
|
||||
let repeats = count(a:method.p, p) > 1 ? 1 : 0
|
||||
if index(g:J_PRIMITIVE_TYPES, p) >= 0
|
||||
let var = p[0]
|
||||
else
|
||||
let p = javacomplete#util#CleanFQN(p)
|
||||
let var = tolower(p[0]). p[1:]
|
||||
endif
|
||||
let match = matchlist(var, '^\([a-zA-Z0-9]\+\)\A*')
|
||||
let countVar = count(paramNames, match[1]) + repeats
|
||||
call add(paramNames, match[1])
|
||||
call add(ds, p. ' '. match[1]. (countVar > 0 ? countVar : ""))
|
||||
endfor
|
||||
return d. join(ds, ', '). ')'. throws
|
||||
endif
|
||||
endif
|
||||
return a:method.d
|
||||
endfunction
|
||||
|
||||
function! javacomplete#util#GetClassPackage(class)
|
||||
let lastDot = strridx(a:class, '.')
|
||||
if lastDot > 0
|
||||
return a:class[0:lastDot - 1]
|
||||
endif
|
||||
return a:class
|
||||
endfunction
|
||||
|
||||
" vim:set fdm=marker sw=2 nowrap:
|
44
bundle/vim-javacomplete2/autoload/javacomplete/version.vim
vendored
Normal file
44
bundle/vim-javacomplete2/autoload/javacomplete/version.vim
vendored
Normal file
@ -0,0 +1,44 @@
|
||||
" Vim completion script for java
|
||||
" Maintainer: artur shaik <ashaihullin@gmail.com>
|
||||
"
|
||||
" Version control
|
||||
|
||||
let g:JavaComplete_ServerCompatibilityVersion = "2.4.1"
|
||||
|
||||
function! javacomplete#version#GetCompatibilityVerison()
|
||||
return g:JavaComplete_ServerCompatibilityVersion
|
||||
endfunction
|
||||
|
||||
function! javacomplete#version#CompareVersions(scriptVersion, serverVersion)
|
||||
let scriptVersion = split(a:scriptVersion, '\.')
|
||||
let serverVersion = split(a:serverVersion, '\.')
|
||||
while len(scriptVersion) < len(serverVersion)
|
||||
call add(scriptVersion, '0')
|
||||
endwhile
|
||||
while len(serverVersion) < len(scriptVersion)
|
||||
call add(serverVersion, '0')
|
||||
endwhile
|
||||
let i = 0
|
||||
while i < len(scriptVersion)
|
||||
if i < len(serverVersion)
|
||||
if str2nr(scriptVersion[i]) < str2nr(serverVersion[i])
|
||||
return -1
|
||||
elseif str2nr(scriptVersion[i]) > str2nr(serverVersion[i])
|
||||
return 1
|
||||
endif
|
||||
else
|
||||
return 1
|
||||
endif
|
||||
let i += 1
|
||||
endwhile
|
||||
return 0
|
||||
endfunction
|
||||
|
||||
function! javacomplete#version#CheckServerCompatibility(serverVersion)
|
||||
return
|
||||
\ javacomplete#version#CompareVersions(
|
||||
\ g:JavaComplete_ServerCompatibilityVersion,
|
||||
\ a:serverVersion) <= 0
|
||||
endfunction
|
||||
|
||||
" vim:set fdm=marker sw=2 nowrap:
|
137
bundle/vim-javacomplete2/autoload/javavibridge.py
vendored
Normal file
137
bundle/vim-javacomplete2/autoload/javavibridge.py
vendored
Normal file
@ -0,0 +1,137 @@
|
||||
#!/usr/bin/env python
|
||||
# encoding: utf-8
|
||||
|
||||
import socket
|
||||
import sys
|
||||
import tempfile
|
||||
import time
|
||||
import subprocess
|
||||
import os
|
||||
|
||||
# function to get free port from ycmd
|
||||
def GetUnusedLocalhostPort():
|
||||
sock = socket.socket()
|
||||
# This tells the OS to give us any free port in the range [1024 - 65535]
|
||||
sock.bind(('', 0))
|
||||
port = sock.getsockname()[1]
|
||||
sock.close()
|
||||
return port
|
||||
|
||||
SERVER = ('127.0.0.1', GetUnusedLocalhostPort())
|
||||
|
||||
# A wrapper for subprocess.Popen that works around a Popen bug on Windows.
|
||||
def SafePopen(args, **kwargs):
|
||||
if kwargs.get('stdin') is None:
|
||||
kwargs['stdin'] = subprocess.PIPE if sys.platform == 'win32' else None
|
||||
|
||||
return subprocess.Popen(args, **kwargs)
|
||||
|
||||
class JavaviBridge():
|
||||
|
||||
pythonVersion = sys.version_info.major
|
||||
sock = None
|
||||
popen = None
|
||||
logfile = None
|
||||
|
||||
def setupServer(self, javabin, args, classpath):
|
||||
is_win = sys.platform == 'win32'
|
||||
separator = (';' if is_win else ':')
|
||||
fileSeparator = ('\\' if is_win else '/')
|
||||
|
||||
classpathset = set(classpath.split(separator))
|
||||
|
||||
environ = os.environ.copy()
|
||||
if 'CLASSPATH' in environ:
|
||||
classpathset.union(environ['CLASSPATH'].split(separator))
|
||||
|
||||
environ['CLASSPATH'] = separator.join(classpathset)
|
||||
|
||||
if vim.eval('get(g:, "JavaComplete_JavaviLogLevel", 0)') != 0:
|
||||
defaulttmp = tempfile.gettempdir() + fileSeparator + 'javavi_log'
|
||||
logdir = vim.eval(
|
||||
"empty(g:JavaComplete_JavaviLogDirectory) ? '%s' : g:JavaComplete_JavaviLogDirectory"
|
||||
% defaulttmp)
|
||||
if not os.path.isdir(logdir):
|
||||
os.mkdir(logdir)
|
||||
self.logfile = open("%s%s%s" % (
|
||||
logdir, fileSeparator, "javavi_stdout.log"),
|
||||
"a")
|
||||
output = self.logfile
|
||||
else:
|
||||
output = subprocess.PIPE
|
||||
|
||||
args = [javabin] + args + ['-D', str(SERVER[1])]
|
||||
if is_win and vim.eval('has("gui_running")'):
|
||||
info = subprocess.STARTUPINFO()
|
||||
info.dwFlags = 1
|
||||
info.wShowWindow = 0
|
||||
self.popen = SafePopen(args, env=environ, stdout = output, stderr = output, startupinfo = info)
|
||||
else:
|
||||
self.popen = SafePopen(args, env=environ, stdout = output, stderr = output)
|
||||
|
||||
def pid(self):
|
||||
return self.popen.pid
|
||||
|
||||
def port(self):
|
||||
return SERVER[1]
|
||||
|
||||
def poll(self):
|
||||
if self.popen:
|
||||
return self.popen.poll() is None
|
||||
else:
|
||||
return 0
|
||||
|
||||
def terminateServer(self):
|
||||
if self.popen:
|
||||
self.popen.terminate()
|
||||
self.popen.wait()
|
||||
|
||||
if self.logfile:
|
||||
self.logfile.close()
|
||||
|
||||
def makeSocket(self):
|
||||
try:
|
||||
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
except socket.error as msg:
|
||||
self.sock = None
|
||||
|
||||
try:
|
||||
self.sock.connect(SERVER)
|
||||
time.sleep(.1)
|
||||
except socket.error as msg:
|
||||
self.sock.close()
|
||||
self.sock = None
|
||||
|
||||
if self.sock is None:
|
||||
print('could not open socket, try again')
|
||||
return
|
||||
|
||||
self.sock.setblocking(0)
|
||||
|
||||
|
||||
def send(self, data):
|
||||
if self.sock is None:
|
||||
self.makeSocket()
|
||||
if self.sock is None:
|
||||
return ''
|
||||
|
||||
if self.pythonVersion == 3:
|
||||
self.sock.sendall((str(data) + '\n').encode('UTF-8'))
|
||||
else:
|
||||
self.sock.sendall((data.decode('UTF-8') + '\n').encode('UTF-8'))
|
||||
|
||||
totalData = []
|
||||
while 1:
|
||||
try:
|
||||
data = self.sock.recv(4096)
|
||||
if not data or len(data) == 0:
|
||||
break
|
||||
|
||||
totalData.append(data.decode('UTF-8'))
|
||||
time.sleep(0.0001)
|
||||
except:
|
||||
if totalData: break
|
||||
|
||||
self.sock.close()
|
||||
self.sock = None
|
||||
return ''.join(totalData)
|
60
bundle/vim-javacomplete2/classpath.gradle
vendored
Normal file
60
bundle/vim-javacomplete2/classpath.gradle
vendored
Normal file
@ -0,0 +1,60 @@
|
||||
task classpath {
|
||||
doLast {
|
||||
HashSet<String> classpathFiles = new HashSet<String>()
|
||||
for (project in allprojects) {
|
||||
if (project.hasProperty('android')) {
|
||||
project.android.getBootClasspath().each {
|
||||
classpathFiles += it
|
||||
}
|
||||
if (project.android.hasProperty('applicationVariants')) {
|
||||
project.android.applicationVariants.all { variant ->
|
||||
|
||||
def variantBase = variant.baseName.replaceAll("-", File.separator)
|
||||
|
||||
def buildClasses = project.getBuildDir().absolutePath +
|
||||
File.separator + "intermediates" +
|
||||
File.separator + "classes" +
|
||||
File.separator + variantBase
|
||||
|
||||
classpathFiles += buildClasses
|
||||
|
||||
def userClasses = project.getBuildDir().absolutePath +
|
||||
File.separator + "intermediates" +
|
||||
File.separator + "javac" +
|
||||
File.separator + variant.baseName.replaceAll("-", File.separator) +
|
||||
File.separator + "compile" + variantBase.capitalize() + "JavaWithJavac" + File.separator + "classes"
|
||||
|
||||
classpathFiles += userClasses
|
||||
|
||||
variant.getCompileClasspath().each {
|
||||
classpathFiles += it
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Print the list of all dependencies jar files.
|
||||
project.configurations.findAll {
|
||||
it.metaClass.respondsTo(it, "isCanBeResolved") ? it.isCanBeResolved() : false
|
||||
}.each {
|
||||
it.resolve().each {
|
||||
if (it.inspect().endsWith("jar")) {
|
||||
classpathFiles += it
|
||||
} else if (it.inspect().endsWith("aar")) {
|
||||
// If the dependency is an AAR file we try to determine the location
|
||||
// of the classes.jar file in the exploded aar folder.
|
||||
def splitted = it.inspect().split("/")
|
||||
def namespace = splitted[-5]
|
||||
def name = splitted[-4]
|
||||
def version = splitted[-3]
|
||||
def explodedPath = "$project.buildDir/intermediates/exploded-aar/$namespace/$name/$version/jars/classes.jar"
|
||||
classpathFiles += explodedPath
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
def classpath = classpathFiles.join(File.pathSeparator)
|
||||
println "CLASSPATH:" + classpath
|
||||
println "END CLASSPATH GENERATION"
|
||||
}
|
||||
}
|
BIN
bundle/vim-javacomplete2/doc/demo.gif
vendored
Normal file
BIN
bundle/vim-javacomplete2/doc/demo.gif
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 328 KiB |
BIN
bundle/vim-javacomplete2/doc/generics_demo.gif
vendored
Normal file
BIN
bundle/vim-javacomplete2/doc/generics_demo.gif
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 266 KiB |
821
bundle/vim-javacomplete2/doc/javacomplete.txt
vendored
Normal file
821
bundle/vim-javacomplete2/doc/javacomplete.txt
vendored
Normal file
@ -0,0 +1,821 @@
|
||||
*javacomplete.txt* Updated version of the original javacomplete plugin
|
||||
artur shaik *javacomplete*
|
||||
|
||||
==============================================================================
|
||||
CONTENTS *javacomplete-contents*
|
||||
1. Overview..........................................|javacomplete-overview|
|
||||
1. Download......................................|javacomplete-download|
|
||||
2. Features......................................|javacomplete-features|
|
||||
3. Install........................................|javacomplete-install|
|
||||
4. Requirements..............................|javacomplete-requirements|
|
||||
2. Usage................................................|javacomplete-usage|
|
||||
1. Class creation................................|javacomplete-classnew|
|
||||
2. Commands......................................|javacomplete-commands|
|
||||
3. Input contexts................................|javacomplete-contexts|
|
||||
4. Kind letter.................................|javacomplete-kindletter|
|
||||
5. Options.........................................|javacomplete-config|
|
||||
3. FAQ....................................................|javacomplete-faq|
|
||||
4. History............................................|javacomplete-history|
|
||||
5. Todo..................................................|javacomplete-todo|
|
||||
6. Thanks..............................................|javacomplete-thanks|
|
||||
|
||||
==============================================================================
|
||||
OVERVIEW *javacomplete-overview*
|
||||
|
||||
This is javacomplete, an omni-completion script of JAVA language for vim 7 and
|
||||
above. It includes javacomplete.vim, java_parser.vim, javavi library,
|
||||
javaparser library and javacomplete.txt.
|
||||
|
||||
==============================================================================
|
||||
DOWNLOAD *javacomplete-download*
|
||||
|
||||
You can download the lastest version from this url:
|
||||
https://github.com/artur-shaik/vim-javacomplete2
|
||||
|
||||
==============================================================================
|
||||
FEATURES *javacomplete-features*
|
||||
|
||||
1. List members of a class, including (static) fields, (static) methods and
|
||||
ctors;
|
||||
2. List classes or subpackages of a package;
|
||||
3. Provide parameters information of a method, list all overload methods;
|
||||
4. Complete an incomplete word;
|
||||
5. Provide a complete JAVA parser written in Vim script language;
|
||||
6. Use the JVM to obtain most information;
|
||||
7. Use the embedded parser to obtain the class information from source
|
||||
files;
|
||||
8. JSP is supported, Builtin objects such as request, session can be
|
||||
recognized;
|
||||
9. The classes and jar files in the WEB-INF will be appended automatically
|
||||
to the classpath;
|
||||
10. Server side java reflection class loader and parsing library;
|
||||
11. Search class files automatically;
|
||||
12. Complete class name;
|
||||
13. Add import statement for a given class name;
|
||||
14. Complete methods declaration after '@Override';
|
||||
15. Support for maven, gradle and Eclipse's '.classpath';
|
||||
16. Cross-session cache;
|
||||
17. Auto insert methods that need to be implemented;
|
||||
18. `toString`, `equals`, `hashCode`, Accessors generation.
|
||||
|
||||
==============================================================================
|
||||
INSTALL *javacomplete-install*
|
||||
|
||||
1. This assumes you are using `Vundle`.
|
||||
Adapt for your plugin manager of choice. Put this into your `.vimrc`.
|
||||
>
|
||||
" Java completion plugin.
|
||||
Plugin 'artur-shaik/vim-javacomplete2'
|
||||
<
|
||||
2. Set 'omnifunc' option. e.g.
|
||||
|
||||
>
|
||||
autocmd Filetype java setlocal omnifunc=javacomplete#Complete
|
||||
<
|
||||
3. Map keys you prefer:
|
||||
For smart (trying to guess import option) insert class import with <F4>:
|
||||
>
|
||||
nmap <F4> <Plug>(JavaComplete-Imports-AddSmart)
|
||||
imap <F4> <Plug>(JavaComplete-Imports-AddSmart)
|
||||
<
|
||||
For usual (will ask for import option) insert class import with <F5>:
|
||||
>
|
||||
nmap <F5> <Plug>(JavaComplete-Imports-Add)
|
||||
imap <F5> <Plug>(JavaComplete-Imports-Add)
|
||||
<
|
||||
For add all missing imports with <F6>:
|
||||
>
|
||||
nmap <F6> <Plug>(JavaComplete-Imports-AddMissing)
|
||||
imap <F6> <Plug>(JavaComplete-Imports-AddMissing)
|
||||
<
|
||||
For remove all missing imports with <F7>:
|
||||
>
|
||||
nmap <F7> <Plug>(JavaComplete-Imports-RemoveUnused)
|
||||
imap <F7> <Plug>(JavaComplete-Imports-RemoveUnused)
|
||||
<
|
||||
For sorting all imports with <F8>:
|
||||
>
|
||||
nmap <F8> <Plug>(JavaComplete-Imports-SortImports)
|
||||
imap <F8> <Plug>(JavaComplete-Imports-SortImports)
|
||||
<
|
||||
|
||||
Default mappings:
|
||||
>
|
||||
nmap <leader>jI <Plug>(JavaComplete-Imports-AddMissing)
|
||||
nmap <leader>jR <Plug>(JavaComplete-Imports-RemoveUnused)
|
||||
nmap <leader>ji <Plug>(JavaComplete-Imports-AddSmart)
|
||||
nmap <leader>jii <Plug>(JavaComplete-Imports-Add)
|
||||
nmap <Leader>jis <Plug>(JavaComplete-Imports-SortImports)
|
||||
|
||||
imap <C-j>I <Plug>(JavaComplete-Imports-AddMissing)
|
||||
imap <C-j>R <Plug>(JavaComplete-Imports-RemoveUnused)
|
||||
imap <C-j>i <Plug>(JavaComplete-Imports-AddSmart)
|
||||
imap <C-j>ii <Plug>(JavaComplete-Imports-Add)
|
||||
|
||||
nmap <leader>jM <Plug>(JavaComplete-Generate-AbstractMethods)
|
||||
|
||||
imap <C-j>jM <Plug>(JavaComplete-Generate-AbstractMethods)
|
||||
|
||||
nmap <leader>jA <Plug>(JavaComplete-Generate-Accessors)
|
||||
nmap <leader>js <Plug>(JavaComplete-Generate-AccessorSetter)
|
||||
nmap <leader>jg <Plug>(JavaComplete-Generate-AccessorGetter)
|
||||
nmap <leader>ja <Plug>(JavaComplete-Generate-AccessorSetterGetter)
|
||||
nmap <leader>jts <Plug>(JavaComplete-Generate-ToString)
|
||||
nmap <leader>jeq <Plug>(JavaComplete-Generate-EqualsAndHashCode)
|
||||
nmap <leader>jc <Plug>(JavaComplete-Generate-Constructor)
|
||||
nmap <leader>jcc <Plug>(JavaComplete-Generate-DefaultConstructor)
|
||||
|
||||
imap <C-j>s <Plug>(JavaComplete-Generate-AccessorSetter)
|
||||
imap <C-j>g <Plug>(JavaComplete-Generate-AccessorGetter)
|
||||
imap <C-j>a <Plug>(JavaComplete-Generate-AccessorSetterGetter)
|
||||
|
||||
vmap <leader>js <Plug>(JavaComplete-Generate-AccessorSetter)
|
||||
vmap <leader>jg <Plug>(JavaComplete-Generate-AccessorGetter)
|
||||
vmap <leader>ja <Plug>(JavaComplete-Generate-AccessorSetterGetter)
|
||||
<
|
||||
|
||||
4. Javavi library will be automatcally compiled when you
|
||||
use first time. If no libs/javavi/target is generated, check that you have
|
||||
the write permission and jdk installed.
|
||||
|
||||
==============================================================================
|
||||
REQUIREMENTS *javacomplete-requirements*
|
||||
|
||||
|
||||
1. Vim version 7.4 and above with python support;
|
||||
2. JDK8.
|
||||
|
||||
|
||||
==============================================================================
|
||||
USAGE *javacomplete-usage*
|
||||
|
||||
You can use `vim-javacomplete2` just like other omni-completion plugin. Many
|
||||
samples of input context are gived in the following section.
|
||||
|
||||
See |javacomplete-faq| in time if some problem occurs. When meeting other
|
||||
problems not described in FAQ, you can contact with the auther by the
|
||||
following e-mail: ashaihullin@gmail.com
|
||||
|
||||
|
||||
==============================================================================
|
||||
CLASS CREATION *javacomplete-classnew*
|
||||
|
||||
Prompt scheme, for class creation:
|
||||
>
|
||||
template:[subdirectory]:/package.ClassName extends SuperClass implements
|
||||
Interface(String str, public Integer i):contructor(*):toString(1)
|
||||
<
|
||||
A: (optional) template - which will be used to create class boilerplate. Some
|
||||
existed templates: junit, interface, exception, servlet, etcl
|
||||
|
||||
B: (optional) subdirectory in which class will be put. For example: test,
|
||||
androidTest;
|
||||
|
||||
C: class name and package. With `/` will use backsearch for parent package to
|
||||
put in it. Without `/` put in relative package to current;
|
||||
|
||||
D: (optional) extends and implements classes will be automatically imported;
|
||||
|
||||
E: (optional) private str variable, and public i variable will be added to
|
||||
class;
|
||||
|
||||
F: (optional) contructor using all fields and toString override method with
|
||||
only 'str' field will be created. Also hashCode and equals can be used.
|
||||
|
||||
There is autocompletion in command prompt that will try to help you. Your
|
||||
current opened file shouldn't have dirty changes or 'hidden' should be set.
|
||||
|
||||
==============================================================================
|
||||
COMMANDS *javacomplete-commands*
|
||||
|
||||
All these commands are supported when encoding with java project.
|
||||
|
||||
:JCimportsAddMissing *:JCimportsAddMissing*
|
||||
add all missing 'imports'
|
||||
|
||||
:JCimportsRemoveUnused *:JCimportsRemoveUnused*
|
||||
remove all unsused 'imports'
|
||||
|
||||
:JCimportAdd *:JCimportAdd*
|
||||
add 'import' for classname that is under cursor, or before it
|
||||
|
||||
:JCimportAddSmart *:JCimportAddSmart*
|
||||
add 'import' for classname trying to guess variant without ask user to
|
||||
choose an option (it will ask on false guessing)
|
||||
|
||||
:JCimportsSort *:JCimportsSort*
|
||||
sort all 'imports'
|
||||
|
||||
:JCserverShowPort *:JCserverShowPort*
|
||||
show port, through which vim plugin communicates with server;
|
||||
|
||||
:JCserverShowPID *:JCserverShowPID*
|
||||
show server process identificator;
|
||||
|
||||
:JCserverStart *:JCserverStart*
|
||||
start server manually;
|
||||
|
||||
:JCserverTerminate *:JCserverTerminate*
|
||||
stop server manually;
|
||||
|
||||
:JCserverCompile *:JCserverCompile*
|
||||
compile server manually;
|
||||
|
||||
:JCdebugEnableLogs *:JCdebugEnableLogs*
|
||||
enable logs;
|
||||
|
||||
:JCdebugDisableLogs *:JCdebugDisableLogs*
|
||||
disable logs;
|
||||
|
||||
:JCdebugGetLogContent *:JCdebugGetLogContent*
|
||||
get debug logs;
|
||||
|
||||
:JCcacheClear *:JCcacheClear*
|
||||
clear cache manually.
|
||||
|
||||
:JCgenerateAbstractMethods *:JCgenerateAbstractMethods*
|
||||
generate methods that need to be implemented
|
||||
|
||||
:JCgenerateAccessors *:JCgenerateAccessors*
|
||||
generate getters and setters for all fields;
|
||||
|
||||
:JCgenerateAccessorSetter *:JCgenerateAccessorSetter*
|
||||
generate setter for field under cursor;
|
||||
|
||||
:JCgenerateAccessorGetter *:JCgenerateAccessorGetter*
|
||||
generate getter for field under cursor;
|
||||
|
||||
:JCgenerateAccessorSetterGetter *:JCgenerateAccessorSetterGetter*
|
||||
generate getter and setter for field under cursor;
|
||||
|
||||
:JCgenerateToString *:JCgenerateToString*
|
||||
generate 'toString' method;
|
||||
|
||||
:JCgenerateEqualsAndHashCode *:JCgenerateEqualsAndHashCode*
|
||||
generate 'equals' and 'hashCode' methods;
|
||||
|
||||
:JCgenerateConstructor *:JCgenerateConstructor*
|
||||
generate constructor with chosen fields;
|
||||
|
||||
:JCgenerateConstructorDefault *:JCgenerateConstructorDefault*
|
||||
generate default constructor;
|
||||
|
||||
:JCclassNew *:JCclassNew*
|
||||
open prompt to enter class creation command;
|
||||
|
||||
:JCclassInFile *:JCclassInFile*
|
||||
open prompt to choose template that will be used for creation class
|
||||
boilerplate in current empty file;
|
||||
|
||||
==============================================================================
|
||||
INPUT CONTEXTS *javacomplete-contexts*
|
||||
|
||||
It recognize nearly all kinds of Primary Expressions (see langspec-3.0) except
|
||||
for `"Primary.new Indentifier"`. Casting conversion is also supported.
|
||||
|
||||
Samples of input contexts are as following: (Note that '|' indicates cursor)
|
||||
|
||||
(1). after '.', list members of a class or a package
|
||||
>
|
||||
- package.| subpackages and classes of a package
|
||||
- Type.| static members of the 'Type' class and "class"
|
||||
- var.| or field.| members of a variable or a field
|
||||
- method().| members of result of method()
|
||||
- this.| members of the current class
|
||||
- ClassName.this.| members of the qualified class
|
||||
- super.| members of the super class
|
||||
- array.| members of an array object
|
||||
- array[i].| array access, return members of the element of array
|
||||
- "String".| String literal, return members of java.lang.String
|
||||
- int.| or void.| primitive type or pseudo-type, return "class"
|
||||
- int[].| array type, return members of a array type and "class"
|
||||
- java.lang.String[].|
|
||||
- new int[].| members of the new array instance
|
||||
- new java.lang.String[i=1][].|
|
||||
- new Type().| members of the new class instance
|
||||
- Type.class.| class literal, return members of java.lang.Class
|
||||
- void.class.| or int.class.|
|
||||
- ((Type)var).| cast var as Type, return members of Type.
|
||||
- (var.method()).| same with "var.|"
|
||||
- (new Class()).| same with "new Class().|"
|
||||
<
|
||||
(2). after '(', list matching methods with parameters information.
|
||||
>
|
||||
- method(|) methods matched
|
||||
- var.method(|) methods matched
|
||||
- new ClassName(|) constructors matched
|
||||
- this(|) constructors of current class matched
|
||||
- super(|) constructors of super class matched
|
||||
Any place between '(' and ')' will be supported soon.
|
||||
Help information of javadoc is not supported yet.
|
||||
<
|
||||
(3). after an incomplete word, list all the matched beginning with it.
|
||||
>
|
||||
- var.ab| subset of members of var beginning with `ab`
|
||||
- ab| list of all maybes
|
||||
<
|
||||
(4). import statement
|
||||
>
|
||||
- " import java.util.|"
|
||||
- " import java.ut|"
|
||||
- " import ja|"
|
||||
- " import java.lang.Character.|" e.g. "Subset"
|
||||
- " import static java.lang.Math.|" e.g. "PI, abs"
|
||||
<
|
||||
(5). package declaration
|
||||
>
|
||||
- " package com.|"
|
||||
<
|
||||
|
||||
The above are in simple expression.
|
||||
|
||||
(6). after compound expression:
|
||||
>
|
||||
- PrimaryExpr.var.|
|
||||
- PrimaryExpr.method().|
|
||||
- PrimaryExpr.method(|)
|
||||
- PrimaryExpr.var.ab|
|
||||
e.g.
|
||||
- "java.lang . System.in .|"
|
||||
- "java.lang.System.getenv().|"
|
||||
- "int.class.toString().|"
|
||||
- "list.toArray().|"
|
||||
- "new ZipFile(path).|"
|
||||
- "new ZipFile(path).entries().|"
|
||||
<
|
||||
(7). Nested expression:
|
||||
>
|
||||
- "System.out.println( str.| )"
|
||||
- "System.out.println(str.charAt(| )"
|
||||
- "for (int i = 0; i < str.|; i++)"
|
||||
- "for ( Object o : a.getCollect| )"
|
||||
<
|
||||
|
||||
|
||||
==============================================================================
|
||||
KIND LETTER *javacomplete-kindletter*
|
||||
|
||||
A single letter indicates the kind of compeltion item. These kinds are:
|
||||
>
|
||||
+ ctor
|
||||
v local variable or parameter
|
||||
f nonstatic field
|
||||
F static field
|
||||
m nonstatic method
|
||||
M static method
|
||||
P package
|
||||
C class type
|
||||
I interface type
|
||||
<
|
||||
|
||||
==============================================================================
|
||||
OPTIONS *javacomplete-config*
|
||||
|
||||
All these options are supported when encoding with java project.
|
||||
|
||||
*g:JavaComplete_SourcesPath*
|
||||
path of your sources. Don't try to add all sources you have, this will slow
|
||||
down parsing process. Add you project sources and necessery library sources.
|
||||
If you have compiled classes add them to previous config instead. By default
|
||||
plugin will search `src` directory and add it automatically.
|
||||
|
||||
*g:JavaComplete_MavenRepositoryDisabled*
|
||||
disable the maven repository.
|
||||
>
|
||||
let g:JavaComplete_MavenRepositoryDisabled = 1
|
||||
<
|
||||
by default this option is disabled (0).
|
||||
|
||||
*g:JavaComplete_LibsPath*
|
||||
path of you jar files. This path will always appended with '~/.m2/repository'
|
||||
directory. Here you can add your glassfish libs directory or your project
|
||||
libs. It will be automatically appended with you jre home path
|
||||
|
||||
*g:JavaComplete_BaseDir*
|
||||
Base cache directory of javacomplete2 (default is ~/.cache):
|
||||
>
|
||||
let g:JavaComplete_BaseDir = '~/.your_cache_dir'
|
||||
<
|
||||
|
||||
*g:JavaComplete_ImportDefault*
|
||||
In the import selection the default behavior is to use the first option
|
||||
available:
|
||||
>
|
||||
let g:JavaComplete_ImportDefault = 0
|
||||
<
|
||||
To avoid this behavior use:
|
||||
>
|
||||
let g:JavaComplete_ImportDefault = -1
|
||||
<
|
||||
|
||||
*g:JavaComplete_InsertImports*
|
||||
Import selection is activated automatically when completing new class name.
|
||||
This can be avoided by setting:
|
||||
>
|
||||
let g:JavaComplete_InsertImports = 0
|
||||
<
|
||||
|
||||
*g:JavaComplete_GradleExecutable*
|
||||
Set the path of gradle executable file. by default it is empty string.
|
||||
|
||||
*g:JavaComplete_ServerAutoShutdownTime*
|
||||
The Java daemon should kill itself when Vim stops. Also its possible to
|
||||
configure the timeout, so if there is no request during this time the daemon
|
||||
will stop. To configure the timemout use the following (in seconds). By
|
||||
default this option is 0.
|
||||
|
||||
*g:JavaComplete_ImportSortType*
|
||||
Sorting can by jar archives `jarName` or by package names `packageName`. This
|
||||
option is to set the imports sorting type. By default this option is
|
||||
`jarName`:
|
||||
>
|
||||
let g:JavaComplete_ImportSortType = 'jarName'
|
||||
<
|
||||
|
||||
|
||||
*g:JavaComplete_ImportOrder*
|
||||
Specifies the order of import groups, when use `packageName` sorting type, for
|
||||
example:
|
||||
>
|
||||
let g:JavaComplete_ImportOrder = ['java.', 'javax.', 'com.', 'org.', 'net.']
|
||||
<
|
||||
An import group is a list of individual import statements that all start with
|
||||
the same beginning of package name surrounded by blank lines above and below
|
||||
the group.
|
||||
|
||||
*g:JavaComplete_RegularClasses*
|
||||
Regular class names that will be used automatically when you insert import:
|
||||
>
|
||||
let g:JavaComplete_RegularClasses = ['java.lang.String', 'java.lang.Object']
|
||||
<
|
||||
You can populate it with your custom classes, or it will be populated
|
||||
automatically when you choose any import option. List will be persisted, so it
|
||||
will be used next time you run the same project.
|
||||
|
||||
*g:JavaComplete_AutoStartServer*
|
||||
Disable automatic startup of server:
|
||||
>
|
||||
let g:JavaComplete_AutoStartServer = 0
|
||||
<
|
||||
By default this option is disabled (1).
|
||||
|
||||
*g:JavaComplete_UseFQN*
|
||||
Use fully qualified name in description:
|
||||
>
|
||||
let g:JavaComplete_UseFQN = 1
|
||||
<
|
||||
By default this option is disabled (0).
|
||||
|
||||
|
||||
*g:JavaComplete_EnableDefaultMappings*
|
||||
Enable or disable default key mappings, by default this option is 1, and
|
||||
default mappings are defined. To disable default mappings, set this option to
|
||||
1.
|
||||
>
|
||||
let g:JavaComplete_EnableDefaultMappings = 1
|
||||
<
|
||||
|
||||
*g:JavaComplete_PomPath*
|
||||
Set pom.xml path explicitly:
|
||||
>
|
||||
let g:JavaComplete_PomPath = /path/to/pom.xml
|
||||
<
|
||||
It will be set automatically, if pom.xml is in underlying path.
|
||||
|
||||
*g:JavaComplete_ClosingBrace*
|
||||
Close brace on method declaration completion:
|
||||
>
|
||||
let g:JavaComplete_ClosingBrace = 1
|
||||
<
|
||||
Add close brace automatically, when complete method declaration. By default
|
||||
this option is enabled (1). Disable if it conflicts with another plugins.
|
||||
|
||||
*g:JavaComplete_JavaviLogDirectory*
|
||||
Set the directory where to write server logs. By default this option is empty.
|
||||
|
||||
*g:JavaComplete_CustomTemplateDirectory*
|
||||
Set directory that contains custom templates for class creation, for example:
|
||||
>
|
||||
let g:JavaComplete_CustomTemplateDirectory = '~/jc_templates'
|
||||
<
|
||||
By default this options is empty string.
|
||||
|
||||
==============================================================================
|
||||
FAQ *javacomplete-faq*
|
||||
|
||||
4.1 Why can not complete in gradle project?
|
||||
|
||||
Check if 'gradle' is in your runtime path or './gradlew' (or
|
||||
'.\gradlew.bat' for Windows) is in your project's directory.
|
||||
|
||||
4.2 I have installed gradle, but why I can not complete R.class?
|
||||
|
||||
In android project, many of the class contains a ton of innerclass,
|
||||
javacomplete2 could works better by reflection, so you need to compile you
|
||||
project, after use './gradlew build', R.java will be automatically
|
||||
generated and compiled.
|
||||
|
||||
==============================================================================
|
||||
HISTORY *javacomplete-history*
|
||||
|
||||
|
||||
This section document the history of `vim-javacomplete2`.
|
||||
|
||||
v2.3.4 2015-12-14
|
||||
|
||||
Use maven, gradle, or Eclipse's 'classpath` file to generate classpath
|
||||
|
||||
Complete methods declaration on '@Override'.
|
||||
|
||||
v2.3.3 2015-10-08
|
||||
|
||||
Jsp files support, no taglibs yet.
|
||||
|
||||
Vimscript refactored.
|
||||
|
||||
Read eclipse ".classpath" file.
|
||||
|
||||
Option to set jvm launcher and compiler for javavi server.
|
||||
|
||||
Using <Plug> mappings.
|
||||
|
||||
Bug fixes.
|
||||
|
||||
v2.3.2 2015-09-18
|
||||
|
||||
Nested classes.
|
||||
|
||||
Vimscript refactored.
|
||||
|
||||
v2.3.1 2015-09-07
|
||||
|
||||
Better experience with imports.
|
||||
|
||||
Commands added.
|
||||
|
||||
v2.3 2015-07-29
|
||||
|
||||
Annotations completion support.
|
||||
|
||||
Option to swtich use of FQN in completion suggestions.
|
||||
|
||||
Check python support before start.
|
||||
|
||||
v2.2 2015-07-08
|
||||
|
||||
Lambda expressions parsing.
|
||||
|
||||
v2.1 2015-06-12
|
||||
|
||||
Generics completion. Bug fixes.
|
||||
|
||||
Added g:JavaComplete_MavenRepositoryDisable option.
|
||||
|
||||
v2.0 2015-05-26
|
||||
|
||||
Writed new library for reflection and parsing. Parsing make by
|
||||
|
||||
third party library. Library run in server like way.
|
||||
|
||||
Added class name completion and insertion of class import.
|
||||
|
||||
Added auto classpath searcher.
|
||||
|
||||
v0.77.1.2 2011-01-30
|
||||
|
||||
Fixed to adapt globpath() (vim < 7.2). Patched by Sam Lidder.
|
||||
|
||||
v0.77.1.1 2010-11-12
|
||||
|
||||
Fixed to ignore the 'suffixes' and 'wildignore' options which
|
||||
|
||||
make Reflection.class can not be found.
|
||||
|
||||
v0.77.1 2007-09-19
|
||||
|
||||
Supported showing method parameters information in any place
|
||||
|
||||
between parenthesises.
|
||||
|
||||
v0.77 2007-09-19
|
||||
|
||||
bug fix
|
||||
|
||||
Added GetCurrentFileKey() avoid empty key of s:files for current buffer.
|
||||
|
||||
Use a new strategy for searching inherited members.
|
||||
|
||||
Supported new contexts "jav|", "var|", just after an incomplete word.
|
||||
|
||||
Supported new context "abs(|)", a imported static method.
|
||||
|
||||
Improved FoundClassDeclaration()
|
||||
|
||||
Fixed bug calling cursor(0, 0)
|
||||
|
||||
Rewrote DoGetClassInfo(), GetFQN() and IsFQN()
|
||||
|
||||
Fixed a bug when merging superclass's members
|
||||
|
||||
Improved s:MergeLines() and s:ExtractCleanExpr().
|
||||
|
||||
Rewrote CompleteAfterDot(). Added ParseExpr(). Removed
|
||||
s:GetNextSubexprType()
|
||||
|
||||
Supported accessible static imported members.
|
||||
|
||||
Supported accessible inherited members.
|
||||
|
||||
Used b:changedtick and getftime() to check buffer (or other file) for
|
||||
changing.
|
||||
|
||||
Supported not-file-name toplevel or static member class in source files.
|
||||
|
||||
v0.76.8 2007-08-30
|
||||
|
||||
Created the s:TreeVisitor to search type or symbol names.
|
||||
|
||||
Supported local and anonymous class.
|
||||
|
||||
Supported appending automatically classpath under WEB-INF for jsp files.
|
||||
|
||||
v0.76.7 2007-08-28
|
||||
|
||||
Fixed case of "new java.util.zip.ZipFile().|"
|
||||
|
||||
Improved process of type arguments and method parameters. JAVA5+
|
||||
|
||||
Reorganize codes in javacomplete#Complete()
|
||||
|
||||
Added CONTEXT_NEED_TYPE, removed CONTEXT_INCOMPLETE_WORD
|
||||
|
||||
Add Context types for type declaration: CONTEXT_NEED_TYPE
|
||||
|
||||
v0.76.6 2007-08-23
|
||||
|
||||
Improved GetStatement() and related. Bug fixed.
|
||||
|
||||
v0.76.5 2007-08-21
|
||||
|
||||
Fixed bug: "foo().|", "getFoo().foo().|",
|
||||
|
||||
"for (Enumeration entries = ; entries.|; )".
|
||||
|
||||
Supported input contexts: "((Object)o).|", "((Object)o).getClass().|",
|
||||
|
||||
"new ZipFile(path).|", "(new String().)|".
|
||||
|
||||
v0.76.4 2007-08-17
|
||||
|
||||
Improved input contexts: "int.class.toString().|", "list.toArray().|".
|
||||
|
||||
Fixed recognizing "this(|)", "method1(|)"
|
||||
|
||||
Added the 'kind' letter to distinguish between classes and packages.
|
||||
|
||||
Support accessible nested classes.
|
||||
|
||||
Support import static members and import accessible nested classes.
|
||||
|
||||
Fixed a bug when Reflection.java is in the path which contains space.
|
||||
|
||||
Improved process of this and super in JSP.
|
||||
|
||||
Fixed an severe bug parsing current jsp file.
|
||||
|
||||
v0.76.3 2007-08-10
|
||||
|
||||
Add an option 'searchdecl' set by javacomplete#SetSearchdeclMethod().
|
||||
|
||||
Make an improvement for jsp file.
|
||||
|
||||
Clear cache when set options affecting classpath.
|
||||
|
||||
Improved DoGetPackageList() and s:GenerateImports().
|
||||
|
||||
Replace codes searching list of string with index().
|
||||
|
||||
v0.76.2 2007-08-08
|
||||
|
||||
Fix failing to list members of nested class.
|
||||
|
||||
Combine members of local packages and loadable packages.
|
||||
|
||||
Add quick recognition of package or import.
|
||||
|
||||
Add inherited fields and methods to local class.
|
||||
|
||||
v0.76.1 2007-08-04
|
||||
|
||||
Fix using a: in javacomplete#SetClassPath()
|
||||
|
||||
Fix a bug in javacomplete#GetClassPath()
|
||||
|
||||
v0.76 2007-08-04
|
||||
|
||||
2007-08-04
|
||||
|
||||
Fix a infinite loop bug in s:GetMatchedIndexEx()
|
||||
|
||||
Fix that array type not recognised in compound expression.
|
||||
|
||||
Add a option for JDK1.1. See FAQ 3.
|
||||
|
||||
2007-08-03
|
||||
|
||||
Improve for 'this' or 'super'.
|
||||
|
||||
Support searching toplevel class in sourcepath.
|
||||
|
||||
Clean
|
||||
|
||||
2007-08-02
|
||||
|
||||
Improve the process of checking a class in one of packages.
|
||||
|
||||
2007-08-01
|
||||
|
||||
Add Searchdecl() using java_parser.vim to provide quick information.
|
||||
|
||||
Supports input context: "StringLiteral".|, "int.|", "void.|"
|
||||
|
||||
2007-07-28
|
||||
|
||||
Automatcally compile Reflection.java and place it to $HOME.
|
||||
|
||||
Add option 'javacompiler', default 'javac'
|
||||
|
||||
Add option 'java', default 'java'
|
||||
|
||||
v0.75 2007-02-13
|
||||
|
||||
Add java_parser.vim.
|
||||
|
||||
Add b:sourcepath option.
|
||||
|
||||
Improve recognition of classes defined in current buffer or in source path.
|
||||
|
||||
Support generating class information from tags instead of returning list
|
||||
directly.
|
||||
|
||||
v0.74 2007-02-03
|
||||
|
||||
Support jre1.2 (and above).
|
||||
|
||||
Support input context like "boolean.class.|"
|
||||
|
||||
Handle java primitive types like 'int'.
|
||||
|
||||
v0.73 2007-02-01
|
||||
|
||||
Fix bug that CLASSPATH not used when b:classpath or g:java_classpath not
|
||||
set.
|
||||
|
||||
Fix bug that call filter() without making a copy for incomplete.
|
||||
|
||||
Improve recognition of declaration of this class
|
||||
|
||||
v0.72 2007-01-31
|
||||
|
||||
Handle nested expression.
|
||||
|
||||
v0.71 2007-01-28
|
||||
|
||||
Add Basic support for class in current folder.
|
||||
|
||||
v0.70 2007-01-27
|
||||
|
||||
Complete the reflection part.
|
||||
|
||||
v0.60 2007-01-25
|
||||
|
||||
Design TClassInfo, etc.
|
||||
|
||||
v0.50 2007-01-21
|
||||
|
||||
Use java and Reflection.class directly.
|
||||
|
||||
==============================================================================
|
||||
TODO *javacomplete-todo*
|
||||
|
||||
Add javadoc
|
||||
Cross session cache;
|
||||
Most used (classes, methods, vars) at first place (smart suggestions);
|
||||
FXML support;
|
||||
JSP check support;
|
||||
Refactoring support?;
|
||||
Class creation helpers;
|
||||
etc...
|
||||
|
||||
==============================================================================
|
||||
THANKS *javacomplete-thanks*
|
||||
|
||||
* Cheng Fang author of original javacomplete plugin;
|
||||
* Zhang Li author of vim-javacompleteex plugin;
|
||||
* http://github.com/javaparser/javaparser library.
|
||||
|
||||
FeedBack: Any problem, bug or suggest are welcome to send to
|
||||
ashaihullin@gmail.com
|
||||
|
||||
|
||||
vim:tw=78:ts=8:ft=help:norl:
|
105
bundle/vim-javacomplete2/libs/javavi/pom.xml
vendored
Normal file
105
bundle/vim-javacomplete2/libs/javavi/pom.xml
vendored
Normal file
@ -0,0 +1,105 @@
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>kg.ash.javavi</groupId>
|
||||
<artifactId>javavi</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>javavi</name>
|
||||
<url>http://maven.apache.org</url>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.github.javaparser</groupId>
|
||||
<artifactId>javaparser-core</artifactId>
|
||||
<version>3.5.20</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>kg.ash.javavi.apache.logging.log4j</groupId>
|
||||
<artifactId>log4j-api</artifactId>
|
||||
<version>2.7</version>
|
||||
<scope>system</scope>
|
||||
<systemPath>${basedir}/../javavi_log4j-api.jar</systemPath>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>kg.ash.javavi.apache.logging.log4j</groupId>
|
||||
<artifactId>log4j-core</artifactId>
|
||||
<version>2.7</version>
|
||||
<scope>system</scope>
|
||||
<systemPath>${basedir}/../javavi_log4j-core.jar</systemPath>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.13.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.json</groupId>
|
||||
<artifactId>json</artifactId>
|
||||
<version>20150729</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jmockit</groupId>
|
||||
<artifactId>jmockit</artifactId>
|
||||
<version>1.20</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.1</version>
|
||||
<configuration>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>exec-maven-plugin</artifactId>
|
||||
<version>1.3.2</version>
|
||||
<configuration>
|
||||
<executable>java</executable>
|
||||
<arguments>
|
||||
<argument>-Xms512m</argument>
|
||||
<argument>-Xmx512m</argument>
|
||||
<argument>-XX:NewRatio=3</argument>
|
||||
<argument>-XX:+PrintGCTimeStamps</argument>
|
||||
<argument>-XX:+PrintGCDetails</argument>
|
||||
<argument>-Xloggc:gc.log</argument>
|
||||
<argument>-classpath</argument>
|
||||
<classpath/>
|
||||
<argument>kg.ash.javavi.Javavi</argument>
|
||||
</arguments>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<!-- Build an executable JAR -->
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<version>2.4</version>
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifest>
|
||||
<addClasspath>true</addClasspath>
|
||||
<classpathPrefix>lib/</classpathPrefix>
|
||||
<mainClass>kg.ash.javavi.Javavi</mainClass>
|
||||
</manifest>
|
||||
</archive>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
144
bundle/vim-javacomplete2/libs/javavi/src/main/java/kg/ash/javavi/Daemon.java
vendored
Normal file
144
bundle/vim-javacomplete2/libs/javavi/src/main/java/kg/ash/javavi/Daemon.java
vendored
Normal file
@ -0,0 +1,144 @@
|
||||
package kg.ash.javavi;
|
||||
|
||||
import kg.ash.javavi.apache.logging.log4j.LogManager;
|
||||
import kg.ash.javavi.apache.logging.log4j.Logger;
|
||||
import kg.ash.javavi.cache.Cache;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.PrintStream;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
|
||||
public class Daemon extends Thread {
|
||||
|
||||
public static final Logger logger = LogManager.getLogger();
|
||||
|
||||
private int port;
|
||||
private int timeoutSeconds;
|
||||
private Timer timeoutTimer = new Timer();
|
||||
private TimerTask timeoutTask;
|
||||
|
||||
public Daemon(int port, int timeoutSeconds) {
|
||||
this.port = port;
|
||||
this.timeoutSeconds = timeoutSeconds;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
ServerSocket echoServer = null;
|
||||
Cache.getInstance().collectPackages();
|
||||
|
||||
while (true) {
|
||||
if (timeoutSeconds > 0) {
|
||||
timeoutTask = new TimeoutTask();
|
||||
timeoutTimer.schedule(timeoutTask, timeoutSeconds * 1000);
|
||||
}
|
||||
|
||||
try {
|
||||
if (echoServer == null) {
|
||||
echoServer = new ServerSocket(port);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
logger.warn(e);
|
||||
break;
|
||||
}
|
||||
|
||||
try (Socket clientSocket = echoServer.accept()) {
|
||||
if (timeoutTask != null) {
|
||||
timeoutTask.cancel();
|
||||
}
|
||||
|
||||
try (BufferedReader is = new BufferedReader(
|
||||
new InputStreamReader(clientSocket.getInputStream()));
|
||||
PrintStream os = new PrintStream(clientSocket.getOutputStream())) {
|
||||
while (true) {
|
||||
String[] request = parseRequest(is.readLine());
|
||||
if (request != null) {
|
||||
os.print(Javavi.makeResponse(request));
|
||||
}
|
||||
break;
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
logger.error(e, e);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
logger.error(e);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String[] parseRequest(String request) {
|
||||
if (request == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
List<String> args = new LinkedList<>();
|
||||
|
||||
StringBuilder buff = new StringBuilder();
|
||||
boolean quoteFlag = false;
|
||||
boolean slashFlag = false;
|
||||
for (char ch : request.toCharArray()) {
|
||||
if (quoteFlag) {
|
||||
if (ch == '\\') {
|
||||
if (slashFlag) {
|
||||
buff.append("\\");
|
||||
slashFlag = false;
|
||||
} else {
|
||||
slashFlag = true;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (ch == '"' && !slashFlag) {
|
||||
if (buff.length() == 0) {
|
||||
args.add("");
|
||||
}
|
||||
quoteFlag = false;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (ch == '"' && !slashFlag) {
|
||||
quoteFlag = true;
|
||||
}
|
||||
|
||||
if (!quoteFlag) {
|
||||
if (ch == ' ') {
|
||||
if (buff.length() > 0) {
|
||||
args.add(buff.toString());
|
||||
buff = new StringBuilder();
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if ((ch != '"' && !slashFlag) || ((ch == '"' || ch == 'n') && slashFlag)) {
|
||||
if (slashFlag && ch != '"') {
|
||||
buff.append('\\');
|
||||
}
|
||||
buff.append(ch);
|
||||
}
|
||||
|
||||
if (slashFlag) {
|
||||
slashFlag = false;
|
||||
}
|
||||
}
|
||||
if (buff.length() > 0) {
|
||||
args.add(buff.toString());
|
||||
}
|
||||
|
||||
return args.toArray(new String[0]);
|
||||
}
|
||||
|
||||
class TimeoutTask extends TimerTask {
|
||||
public void run() {
|
||||
logger.info("Shutdown by timeout timer.");
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
}
|
115
bundle/vim-javacomplete2/libs/javavi/src/main/java/kg/ash/javavi/Javavi.java
vendored
Normal file
115
bundle/vim-javacomplete2/libs/javavi/src/main/java/kg/ash/javavi/Javavi.java
vendored
Normal file
@ -0,0 +1,115 @@
|
||||
package kg.ash.javavi;
|
||||
|
||||
import kg.ash.javavi.actions.Action;
|
||||
import kg.ash.javavi.actions.ActionFactory;
|
||||
import kg.ash.javavi.apache.logging.log4j.LogManager;
|
||||
import kg.ash.javavi.apache.logging.log4j.Logger;
|
||||
import kg.ash.javavi.searchers.ClasspathCollector;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
public class Javavi {
|
||||
|
||||
public static final String VERSION = "2.4.3";
|
||||
|
||||
public static String NEWLINE = "";
|
||||
|
||||
public static final Logger logger = LogManager.getLogger();
|
||||
|
||||
static void output(String s) {
|
||||
System.out.print(s);
|
||||
}
|
||||
|
||||
private static void usage() {
|
||||
version();
|
||||
System.out.println(
|
||||
" java [-classpath] kg.ash.javavi.Javavi [-sources sourceDirs] [-h] [-v] [-d] [-D "
|
||||
+ "port] [action]");
|
||||
System.out.println("Options:");
|
||||
System.out.println(" -h help");
|
||||
System.out.println(" -v version");
|
||||
System.out.println(" -sources sources directory");
|
||||
System.out.println(" -d enable debug mode");
|
||||
System.out.println(" -D port start daemon on specified port");
|
||||
}
|
||||
|
||||
private static void version() {
|
||||
System.out.println("Reflection and parsing for javavi " + "vim plugin (" + VERSION + ")");
|
||||
}
|
||||
|
||||
public static HashMap<String, String> system = new HashMap<>();
|
||||
public static Daemon daemon = null;
|
||||
|
||||
public static void main(String[] args) {
|
||||
logger.info("starting javavi server on port: {}", System.getProperty("daemon.port", "0"));
|
||||
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("output included libraries");
|
||||
new ClasspathCollector().collectClassPath().forEach(logger::trace);
|
||||
}
|
||||
|
||||
String response = makeResponse(args);
|
||||
|
||||
output(response);
|
||||
}
|
||||
|
||||
public static String makeResponse(String[] args) {
|
||||
|
||||
long ms = System.currentTimeMillis();
|
||||
Action action = null;
|
||||
boolean asyncRun = false;
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
String arg = args[i];
|
||||
logger.debug("argument: {}", arg);
|
||||
switch (arg) {
|
||||
case "-h":
|
||||
usage();
|
||||
return "";
|
||||
case "-v":
|
||||
version();
|
||||
return "";
|
||||
case "-sources":
|
||||
system.put("sources", args[++i]);
|
||||
break;
|
||||
case "-n":
|
||||
NEWLINE = "\n";
|
||||
break;
|
||||
case "-base":
|
||||
system.put("base", args[++i]);
|
||||
break;
|
||||
case "-project":
|
||||
system.put("project", args[++i]);
|
||||
break;
|
||||
case "-compiler":
|
||||
system.put("compiler", args[++i]);
|
||||
break;
|
||||
case "-async":
|
||||
asyncRun = true;
|
||||
break;
|
||||
default:
|
||||
if (action == null) {
|
||||
action = ActionFactory.get(arg);
|
||||
}
|
||||
}
|
||||
|
||||
if (action != null) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
String result = "";
|
||||
if (action != null) {
|
||||
logger.debug("new {} action: \"{}\"", asyncRun ? "async" : "",
|
||||
action.getClass().getSimpleName());
|
||||
|
||||
if (asyncRun) {
|
||||
final Action a = action;
|
||||
new Thread(() -> a.perform(args)).start();
|
||||
} else {
|
||||
result = action.perform(args);
|
||||
}
|
||||
}
|
||||
logger.debug("action time: {}ms", (System.currentTimeMillis() - ms));
|
||||
return result;
|
||||
}
|
||||
}
|
114
bundle/vim-javacomplete2/libs/javavi/src/main/java/kg/ash/javavi/TargetParser.java
vendored
Normal file
114
bundle/vim-javacomplete2/libs/javavi/src/main/java/kg/ash/javavi/TargetParser.java
vendored
Normal file
@ -0,0 +1,114 @@
|
||||
package kg.ash.javavi;
|
||||
|
||||
import kg.ash.javavi.searchers.ClassSearcher;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class TargetParser {
|
||||
|
||||
private final Pattern pattern = Pattern.compile("^(.*?)<(.*)>$");
|
||||
private final Pattern extendsPattern = Pattern.compile("^?[\\s]+(super|extends)\\s+(.*)$");
|
||||
private final ClassSearcher seacher = new ClassSearcher();
|
||||
|
||||
private final List<String> typeArguments = new ArrayList<>();
|
||||
private String sources;
|
||||
|
||||
public TargetParser(String sources) {
|
||||
this.sources = sources;
|
||||
}
|
||||
|
||||
public String parse(String target) {
|
||||
typeArguments.clear();
|
||||
|
||||
Matcher matcher = pattern.matcher(target);
|
||||
if (matcher.find()) {
|
||||
target = matcher.group(1);
|
||||
String ta = markSplits(matcher.group(2));
|
||||
for (String arguments : ta.split("<_split_>")) {
|
||||
parseArguments(arguments);
|
||||
}
|
||||
}
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
private void parseArguments(String arguments) {
|
||||
arguments = arguments.replaceAll("(\\(|\\))", "");
|
||||
String[] argumentVariants = arguments.split("\\|");
|
||||
boolean added = false;
|
||||
for (String arg : argumentVariants) {
|
||||
Matcher argMatcher = pattern.matcher(arg);
|
||||
boolean matchResult = argMatcher.find();
|
||||
if (matchResult) {
|
||||
arg = argMatcher.group(1);
|
||||
}
|
||||
String name = getExactName(arg);
|
||||
if (seacher.find(name.replaceAll("(\\[|\\])", ""), sources)) {
|
||||
if (matchResult && !argMatcher.group(2).equals("?")) {
|
||||
typeArguments.add(String.format("%s<%s>", name, argMatcher.group(2)));
|
||||
} else {
|
||||
typeArguments.add(name);
|
||||
}
|
||||
added = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!added) {
|
||||
typeArguments.add("java.lang.Object");
|
||||
}
|
||||
}
|
||||
|
||||
private String getExactName(String name) {
|
||||
Matcher matcher = extendsPattern.matcher(name);
|
||||
if (matcher.find()) {
|
||||
name = matcher.group(2);
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
private String markSplits(String ta) {
|
||||
int i = 0;
|
||||
int lbr = 0;
|
||||
while (i < ta.length()) {
|
||||
char c = ta.charAt(i);
|
||||
if (c == '<') {
|
||||
lbr++;
|
||||
} else if (c == '>') {
|
||||
lbr--;
|
||||
} else if (c == ',' && lbr == 0) {
|
||||
ta = ta.substring(0, i) + "<_split_>" + ta.substring(i + 1, ta.length());
|
||||
i += 9;
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
return ta;
|
||||
}
|
||||
|
||||
public List<String> getTypeArguments() {
|
||||
return typeArguments;
|
||||
}
|
||||
|
||||
public String getTypeArgumentsString() {
|
||||
return getTypeArgumentsString(this.typeArguments);
|
||||
}
|
||||
|
||||
public static String getTypeArgumentsString(List<String> typeArguments) {
|
||||
if (typeArguments.isEmpty()) {
|
||||
return "";
|
||||
}
|
||||
|
||||
StringBuilder builder = new StringBuilder("<");
|
||||
for (String arg : typeArguments) {
|
||||
builder.append(arg).append(",");
|
||||
}
|
||||
builder.setCharAt(builder.length() - 1, '>');
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
5
bundle/vim-javacomplete2/libs/javavi/src/main/java/kg/ash/javavi/actions/Action.java
vendored
Normal file
5
bundle/vim-javacomplete2/libs/javavi/src/main/java/kg/ash/javavi/actions/Action.java
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
package kg.ash.javavi.actions;
|
||||
|
||||
public interface Action {
|
||||
String perform(String[] args);
|
||||
}
|
59
bundle/vim-javacomplete2/libs/javavi/src/main/java/kg/ash/javavi/actions/ActionFactory.java
vendored
Normal file
59
bundle/vim-javacomplete2/libs/javavi/src/main/java/kg/ash/javavi/actions/ActionFactory.java
vendored
Normal file
@ -0,0 +1,59 @@
|
||||
package kg.ash.javavi.actions;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class ActionFactory {
|
||||
public static Action get(String action) {
|
||||
switch (action) {
|
||||
case "-E":
|
||||
return new GetClassInfoAction();
|
||||
case "-p":
|
||||
return new GetPackageInfoAction();
|
||||
case "-s":
|
||||
return new GetClassInfoFromSourceAction();
|
||||
case "-class-packages":
|
||||
return new GetClassPackagesAction();
|
||||
case "-similar-classes":
|
||||
return new FilterSimilarClassesAction();
|
||||
case "-similar-annotations":
|
||||
return new FilterSimilarAnnotationsAction();
|
||||
case "-D":
|
||||
return new ExecuteDaemonAction();
|
||||
case "-unused-imports":
|
||||
return new GetUnusedImportsAction();
|
||||
case "-missing-imports":
|
||||
return new GetMissingImportsAction();
|
||||
case "-clear-from-cache":
|
||||
return new RemoveClassInfoFromCache();
|
||||
case "-recompile-class":
|
||||
return new ClassRecompileAction();
|
||||
case "-collect-packages":
|
||||
return new CollectPackagesAction();
|
||||
case "-fetch-class-archives":
|
||||
return new GetClassesArchiveNamesAction();
|
||||
case "-class-info-by-content":
|
||||
return new ParseByContentAction();
|
||||
case "-get-debug-log-path":
|
||||
return new GetDebugLogPath();
|
||||
case "-version":
|
||||
return new GetAppVersion();
|
||||
case "-add-source-to-cache":
|
||||
return new AddClassToCacheAction();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String getJavaViSources(Map<String, String> javaViSystem) {
|
||||
String sources = javaViSystem.get("sources");
|
||||
return sources != null ? sources.replace('\\', '/') : "";
|
||||
}
|
||||
|
||||
public static String getArgWithName(String[] args, String name) {
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
if (args[i].equals(name)) {
|
||||
return args[i + 1];
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
24
bundle/vim-javacomplete2/libs/javavi/src/main/java/kg/ash/javavi/actions/ActionWithTarget.java
vendored
Normal file
24
bundle/vim-javacomplete2/libs/javavi/src/main/java/kg/ash/javavi/actions/ActionWithTarget.java
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
package kg.ash.javavi.actions;
|
||||
|
||||
import static kg.ash.javavi.actions.ActionFactory.getJavaViSources;
|
||||
|
||||
import kg.ash.javavi.Javavi;
|
||||
import kg.ash.javavi.TargetParser;
|
||||
|
||||
public abstract class ActionWithTarget implements Action {
|
||||
|
||||
protected TargetParser targetParser;
|
||||
protected String sources;
|
||||
|
||||
public ActionWithTarget() {
|
||||
sources = getJavaViSources(Javavi.system);
|
||||
targetParser = new TargetParser(sources);
|
||||
}
|
||||
|
||||
protected String parseTarget(String[] args) {
|
||||
if (args.length > 0) {
|
||||
return targetParser.parse(args[args.length - 1]);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
package kg.ash.javavi.actions;
|
||||
|
||||
import static kg.ash.javavi.actions.ActionFactory.getArgWithName;
|
||||
|
||||
import kg.ash.javavi.apache.logging.log4j.LogManager;
|
||||
import kg.ash.javavi.apache.logging.log4j.Logger;
|
||||
import kg.ash.javavi.cache.Cache;
|
||||
import kg.ash.javavi.searchers.ClassNameMap;
|
||||
import kg.ash.javavi.searchers.JavaClassMap;
|
||||
|
||||
public class AddClassToCacheAction implements Action {
|
||||
|
||||
public static final Logger logger = LogManager.getLogger();
|
||||
|
||||
@Override
|
||||
public String perform(String[] args) {
|
||||
String sourceFileArg = getArgWithName(args, "-source");
|
||||
String classNameArg = getArgWithName(args, "-class");
|
||||
String packageNameArg = getArgWithName(args, "-package");
|
||||
|
||||
ClassNameMap cnm = (ClassNameMap) Cache.getInstance().getClassPackages().get(classNameArg);
|
||||
if (cnm == null) {
|
||||
cnm = new ClassNameMap(classNameArg);
|
||||
}
|
||||
|
||||
cnm.setJavaFile(sourceFileArg);
|
||||
cnm.add(packageNameArg, JavaClassMap.SOURCETYPE_SOURCES, JavaClassMap.TYPE_SUBPACKAGE,
|
||||
null);
|
||||
|
||||
Cache.getInstance().getClassPackages().put(classNameArg, cnm);
|
||||
return "";
|
||||
}
|
||||
}
|
@ -0,0 +1,75 @@
|
||||
package kg.ash.javavi.actions;
|
||||
|
||||
import kg.ash.javavi.Javavi;
|
||||
import kg.ash.javavi.apache.logging.log4j.LogManager;
|
||||
import kg.ash.javavi.apache.logging.log4j.Logger;
|
||||
import kg.ash.javavi.cache.Cache;
|
||||
import kg.ash.javavi.searchers.ClassNameMap;
|
||||
import kg.ash.javavi.searchers.JavaClassMap;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class ClassRecompileAction extends ActionWithTarget {
|
||||
|
||||
public static final Logger logger = LogManager.getLogger();
|
||||
|
||||
@Override
|
||||
public String perform(String[] args) {
|
||||
String target = parseTarget(args);
|
||||
String[] splitted = target.split("\\.");
|
||||
|
||||
ClassNameMap classMap = findClass(splitted[splitted.length - 1]);
|
||||
if (classMap != null && classMap.getClassFile() != null && classMap.getJavaFile() != null) {
|
||||
String classFile = classMap.getClassFile();
|
||||
String sourceFile = classMap.getJavaFile();
|
||||
String classDir = classFile.substring(0, classFile.lastIndexOf(File.separator));
|
||||
|
||||
int offset = findOffset(sourceFile.substring(0, sourceFile.lastIndexOf(File.separator)),
|
||||
classDir);
|
||||
classDir = classFile.substring(0, offset);
|
||||
|
||||
if (classDir.isEmpty()) {
|
||||
return "";
|
||||
}
|
||||
|
||||
String compiler = Javavi.system.get("compiler");
|
||||
String classPath = System.getProperty("java.class.path");
|
||||
|
||||
execute(String.format("%s -cp %s -d %s %s", compiler, classPath, classDir, sourceFile));
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
private void execute(String command) {
|
||||
try {
|
||||
Process p = Runtime.getRuntime().exec(command);
|
||||
p.waitFor();
|
||||
} catch (Exception e) {
|
||||
logger.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
private int findOffset(String sourceFile, String classDir) {
|
||||
int offset = 0;
|
||||
while (!sourceFile.endsWith(classDir)) {
|
||||
int index = classDir.indexOf(File.separator, 2);
|
||||
if (index == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
classDir = classDir.substring(index);
|
||||
offset += index;
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
|
||||
private ClassNameMap findClass(String name) {
|
||||
JavaClassMap classMap = Cache.getInstance().getClassPackages().get(name);
|
||||
if (classMap != null && classMap instanceof ClassNameMap) {
|
||||
return (ClassNameMap) classMap;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
package kg.ash.javavi.actions;
|
||||
|
||||
import kg.ash.javavi.cache.Cache;
|
||||
|
||||
public class CollectPackagesAction implements Action {
|
||||
|
||||
@Override
|
||||
public String perform(String[] args) {
|
||||
Cache.getInstance().getClassPackages().clear();
|
||||
Cache.getInstance().collectPackages();
|
||||
return "";
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
package kg.ash.javavi.actions;
|
||||
|
||||
import kg.ash.javavi.Daemon;
|
||||
import kg.ash.javavi.Javavi;
|
||||
import kg.ash.javavi.apache.logging.log4j.LogManager;
|
||||
import kg.ash.javavi.apache.logging.log4j.Logger;
|
||||
|
||||
public class ExecuteDaemonAction implements Action {
|
||||
|
||||
public static final Logger logger = LogManager.getLogger();
|
||||
|
||||
@Override
|
||||
public String perform(String[] args) {
|
||||
if (Javavi.daemon != null) {
|
||||
return "";
|
||||
}
|
||||
|
||||
Integer daemonPort = Integer.valueOf(System.getProperty("daemon.port", "0"));
|
||||
if (daemonPort == 0) {
|
||||
return "Error: daemonPort is null";
|
||||
}
|
||||
|
||||
logger.debug("starting daemon mode");
|
||||
Javavi.daemon = new Daemon(daemonPort, -1);
|
||||
Javavi.daemon.start();
|
||||
|
||||
return "";
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package kg.ash.javavi.actions;
|
||||
|
||||
import kg.ash.javavi.cache.Cache;
|
||||
import kg.ash.javavi.output.OutputSimilarAnnotations;
|
||||
|
||||
public class FilterSimilarAnnotationsAction extends ActionWithTarget {
|
||||
|
||||
@Override
|
||||
public String perform(String[] args) {
|
||||
return new OutputSimilarAnnotations(Cache.getInstance().getClassPackages()).get(
|
||||
parseTarget(args));
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package kg.ash.javavi.actions;
|
||||
|
||||
import kg.ash.javavi.cache.Cache;
|
||||
import kg.ash.javavi.output.OutputSimilarClasses;
|
||||
|
||||
public class FilterSimilarClassesAction extends ActionWithTarget {
|
||||
|
||||
@Override
|
||||
public String perform(String[] args) {
|
||||
return new OutputSimilarClasses(Cache.getInstance().getClassPackages()).get(
|
||||
parseTarget(args));
|
||||
}
|
||||
}
|
11
bundle/vim-javacomplete2/libs/javavi/src/main/java/kg/ash/javavi/actions/GetAppVersion.java
vendored
Normal file
11
bundle/vim-javacomplete2/libs/javavi/src/main/java/kg/ash/javavi/actions/GetAppVersion.java
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
package kg.ash.javavi.actions;
|
||||
|
||||
import kg.ash.javavi.Javavi;
|
||||
|
||||
public class GetAppVersion implements Action {
|
||||
|
||||
@Override
|
||||
public String perform(String[] args) {
|
||||
return Javavi.VERSION;
|
||||
}
|
||||
}
|
34
bundle/vim-javacomplete2/libs/javavi/src/main/java/kg/ash/javavi/actions/GetClassInfoAction.java
vendored
Normal file
34
bundle/vim-javacomplete2/libs/javavi/src/main/java/kg/ash/javavi/actions/GetClassInfoAction.java
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
package kg.ash.javavi.actions;
|
||||
|
||||
import kg.ash.javavi.clazz.SourceClass;
|
||||
import kg.ash.javavi.output.OutputClassInfo;
|
||||
import kg.ash.javavi.readers.ClassReader;
|
||||
import kg.ash.javavi.searchers.ClassSearcher;
|
||||
|
||||
public class GetClassInfoAction extends ActionWithTarget {
|
||||
|
||||
@Override
|
||||
public String perform(String[] args) {
|
||||
String target = parseTarget(args);
|
||||
|
||||
ClassSearcher searcher = new ClassSearcher();
|
||||
boolean found = true;
|
||||
while (!searcher.find(target, sources)) {
|
||||
if (!target.contains(".")) {
|
||||
found = false;
|
||||
break;
|
||||
}
|
||||
target = target.substring(0, target.lastIndexOf("."));
|
||||
}
|
||||
|
||||
if (found) {
|
||||
ClassReader reader = searcher.getReader();
|
||||
reader.setTypeArguments(targetParser.getTypeArguments());
|
||||
SourceClass clazz = reader.read(target);
|
||||
if (clazz != null) {
|
||||
return new OutputClassInfo().get(clazz);
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package kg.ash.javavi.actions;
|
||||
|
||||
import kg.ash.javavi.output.OutputClassInfo;
|
||||
import kg.ash.javavi.readers.Parser;
|
||||
|
||||
public class GetClassInfoFromSourceAction extends ActionWithTarget {
|
||||
|
||||
@Override
|
||||
public String perform(String[] args) {
|
||||
Parser parser = new Parser(sources, parseTarget(args));
|
||||
return new OutputClassInfo().get(parser.read(null));
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package kg.ash.javavi.actions;
|
||||
|
||||
import kg.ash.javavi.cache.Cache;
|
||||
import kg.ash.javavi.output.OutputClassPackages;
|
||||
|
||||
public class GetClassPackagesAction extends ActionWithTarget {
|
||||
|
||||
@Override
|
||||
public String perform(String[] args) {
|
||||
return new OutputClassPackages(Cache.getInstance().getClassPackages()).get(
|
||||
parseTarget(args));
|
||||
}
|
||||
}
|
@ -0,0 +1,79 @@
|
||||
package kg.ash.javavi.actions;
|
||||
|
||||
import kg.ash.javavi.apache.logging.log4j.LogManager;
|
||||
import kg.ash.javavi.apache.logging.log4j.Logger;
|
||||
import kg.ash.javavi.cache.Cache;
|
||||
import kg.ash.javavi.searchers.JavaClassMap;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class GetClassesArchiveNamesAction extends ActionWithTarget {
|
||||
|
||||
public static final Logger logger = LogManager.getLogger();
|
||||
|
||||
@Override
|
||||
public String perform(String[] args) {
|
||||
String classes = parseTarget(args);
|
||||
|
||||
Map<String, List<String>> result = new HashMap<>();
|
||||
for (String _classFqn : classes.split(",")) {
|
||||
final String classFqn = removeStaticKeyword(_classFqn);
|
||||
|
||||
String[] classFqnArray = classFqn.split("\\.");
|
||||
String className = classFqnArray[classFqnArray.length - 1];
|
||||
|
||||
logger.debug("class name: {}", className);
|
||||
|
||||
HashMap<String, JavaClassMap> classPackages = getClassPackages();
|
||||
if (classPackages.containsKey(className)) {
|
||||
String classPackage = removeLastElementAndJoin(classFqnArray);
|
||||
|
||||
logger.debug("class name: {}", className);
|
||||
|
||||
JavaClassMap cm = classPackages.get(className);
|
||||
Arrays.stream(new String[] { "", "$" }).forEach(s -> {
|
||||
if (cm.getSubpackages().get(classPackage + s) != null) {
|
||||
String fileName = cm.getSubpackages().get(classPackage + s);
|
||||
if (result.containsKey(fileName)) {
|
||||
result.get(fileName).add(classFqn);
|
||||
} else {
|
||||
result.put(fileName, new ArrayList<>(Arrays.asList(classFqn)));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
return String.format("[%s]", buildResult(result));
|
||||
}
|
||||
|
||||
private String removeStaticKeyword(String classFqn) {
|
||||
if (classFqn.contains(" ")) {
|
||||
return classFqn.split(" ")[1];
|
||||
}
|
||||
return classFqn;
|
||||
}
|
||||
|
||||
private HashMap<String, JavaClassMap> getClassPackages() {
|
||||
return Cache.getInstance().getClassPackages();
|
||||
}
|
||||
|
||||
private String removeLastElementAndJoin(String[] array) {
|
||||
String[] newArray = new String[array.length - 1];
|
||||
System.arraycopy(array, 0, newArray, 0, newArray.length);
|
||||
return String.join(".", newArray);
|
||||
}
|
||||
|
||||
private StringBuilder buildResult(Map<String, List<String>> result) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
result.forEach((s, l) -> {
|
||||
builder.append("['").append(s).append("',[");
|
||||
l.forEach(classFqn -> builder.append("'").append(classFqn).append("',"));
|
||||
builder.append("]],");
|
||||
});
|
||||
return builder;
|
||||
}
|
||||
}
|
18
bundle/vim-javacomplete2/libs/javavi/src/main/java/kg/ash/javavi/actions/GetDebugLogPath.java
vendored
Normal file
18
bundle/vim-javacomplete2/libs/javavi/src/main/java/kg/ash/javavi/actions/GetDebugLogPath.java
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
package kg.ash.javavi.actions;
|
||||
|
||||
import kg.ash.javavi.apache.logging.log4j.LogManager;
|
||||
import kg.ash.javavi.apache.logging.log4j.core.LoggerContext;
|
||||
import kg.ash.javavi.apache.logging.log4j.core.lookup.StrLookup;
|
||||
|
||||
public class GetDebugLogPath implements Action {
|
||||
|
||||
@Override
|
||||
public String perform(String[] args) {
|
||||
LoggerContext ctx = (LoggerContext) LogManager.getContext();
|
||||
StrLookup lookup = (ctx.getConfiguration()).getStrSubstitutor().getVariableResolver();
|
||||
String timeId = lookup.lookup("log.time_id");
|
||||
String logsDirectory = System.getProperty("log.directory", lookup.lookup("log.directory"));
|
||||
String daemonPort = System.getProperty("daemon.port", lookup.lookup("daemon.port"));
|
||||
return String.format("%s/%s-%s.log", logsDirectory, timeId, daemonPort);
|
||||
}
|
||||
}
|
@ -0,0 +1,95 @@
|
||||
package kg.ash.javavi.actions;
|
||||
|
||||
import com.github.javaparser.ast.ImportDeclaration;
|
||||
import com.github.javaparser.ast.Node;
|
||||
import com.github.javaparser.printer.PrettyPrinter;
|
||||
import com.github.javaparser.printer.PrettyPrinterConfiguration;
|
||||
import kg.ash.javavi.clazz.ClassImport;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class GetMissingImportsAction extends ImportsAction {
|
||||
|
||||
// TODO(joshleeb): Move this somewhere nice.
|
||||
private static String removeComments(Node n) {
|
||||
PrettyPrinterConfiguration config = new PrettyPrinterConfiguration();
|
||||
config.setPrintComments(false);
|
||||
return new PrettyPrinter(config).print(n);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String action() {
|
||||
List<String> importTails = new ArrayList<>();
|
||||
List<String> asteriskImports = new ArrayList<>();
|
||||
if (compilationUnit.getImports() != null) {
|
||||
for (ImportDeclaration importDeclaration :
|
||||
compilationUnit.getImports()) {
|
||||
ClassImport classImport = new ClassImport(
|
||||
removeComments(
|
||||
importDeclaration.getName()),
|
||||
importDeclaration.isStatic(),
|
||||
importDeclaration.isAsterisk());
|
||||
if (classImport.isAsterisk()) {
|
||||
asteriskImports.add(classImport.getName());
|
||||
} else {
|
||||
importTails.add(classImport.getTail());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (compilationUnit.getPackageDeclaration().isPresent()) {
|
||||
asteriskImports.add(
|
||||
removeComments(
|
||||
compilationUnit.getPackageDeclaration().
|
||||
get().getName()));
|
||||
}
|
||||
|
||||
StringBuilder result = new StringBuilder("{'imports':[");
|
||||
for (String classname : classnames) {
|
||||
if (!importTails.contains(classname)) {
|
||||
GetClassPackagesAction getPackagesAction =
|
||||
new GetClassPackagesAction();
|
||||
String packages = getPackagesAction.perform(
|
||||
new String[] { classname });
|
||||
|
||||
if (packages.startsWith("message:")) {
|
||||
return packages;
|
||||
} else if (packages.length() == 2) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String[] splitted = packages.substring(
|
||||
1, packages.length() - 1).split(",");
|
||||
boolean found = false;
|
||||
for (String foundPackage : splitted) {
|
||||
if (foundPackage.trim().isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (String asteriskImport : asteriskImports) {
|
||||
if (isolatePackage(foundPackage)
|
||||
.equals(asteriskImport)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
if (declarations.contains(classname)) {
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
result.append(packages).append(",");
|
||||
}
|
||||
}
|
||||
}
|
||||
return result.append("]}").toString();
|
||||
}
|
||||
|
||||
private static String isolatePackage(String pkg) {
|
||||
pkg = pkg.trim().substring(1, pkg.length() - 1);
|
||||
return pkg.substring(0, pkg.lastIndexOf("."));
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
package kg.ash.javavi.actions;
|
||||
|
||||
import kg.ash.javavi.cache.Cache;
|
||||
import kg.ash.javavi.output.OutputPackageInfo;
|
||||
|
||||
public class GetPackageInfoAction extends ActionWithTarget {
|
||||
|
||||
@Override
|
||||
public String perform(String[] args) {
|
||||
return new OutputPackageInfo(Cache.getInstance().getClassPackages()).get(parseTarget(args));
|
||||
}
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
package kg.ash.javavi.actions;
|
||||
|
||||
import com.github.javaparser.ast.ImportDeclaration;
|
||||
import com.github.javaparser.ast.Node;
|
||||
import com.github.javaparser.printer.PrettyPrinter;
|
||||
import com.github.javaparser.printer.PrettyPrinterConfiguration;
|
||||
import kg.ash.javavi.clazz.ClassImport;
|
||||
|
||||
public class GetUnusedImportsAction extends ImportsAction {
|
||||
|
||||
@Override
|
||||
public String action() {
|
||||
StringBuilder result = new StringBuilder("{'imports':[");
|
||||
for (ImportDeclaration importDeclaration :
|
||||
compilationUnit.getImports()) {
|
||||
if (importDeclaration.isAsterisk()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ClassImport classImport = new ClassImport(
|
||||
removeComments(importDeclaration.getName()),
|
||||
importDeclaration.isStatic(),
|
||||
importDeclaration.isAsterisk());
|
||||
|
||||
String classname = classImport.getTail();
|
||||
if (!classnames.contains(classname)) {
|
||||
result.append("'")
|
||||
.append(classImport.getHead())
|
||||
.append(classImport.isStatic() ? "$" : ".")
|
||||
.append(classname)
|
||||
.append("',");
|
||||
}
|
||||
}
|
||||
return result.append("]}").toString();
|
||||
}
|
||||
|
||||
private static String removeComments(Node n) {
|
||||
PrettyPrinterConfiguration config =
|
||||
new PrettyPrinterConfiguration();
|
||||
config.setPrintComments(false);
|
||||
return new PrettyPrinter(config).print(n);
|
||||
}
|
||||
}
|
75
bundle/vim-javacomplete2/libs/javavi/src/main/java/kg/ash/javavi/actions/ImportsAction.java
vendored
Normal file
75
bundle/vim-javacomplete2/libs/javavi/src/main/java/kg/ash/javavi/actions/ImportsAction.java
vendored
Normal file
@ -0,0 +1,75 @@
|
||||
package kg.ash.javavi.actions;
|
||||
|
||||
import com.github.javaparser.Range;
|
||||
import com.github.javaparser.ast.CompilationUnit;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.Base64;
|
||||
import java.util.HashSet;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
import kg.ash.javavi.readers.source.ClassNamesFetcher;
|
||||
import kg.ash.javavi.readers.source.CompilationUnitCreator;
|
||||
import kg.ash.javavi.readers.source.CompilationUnitResult;
|
||||
|
||||
public abstract class ImportsAction implements Action {
|
||||
|
||||
protected Set<String> classnames;
|
||||
protected Set<String> declarations;
|
||||
protected CompilationUnit compilationUnit;
|
||||
|
||||
@Override
|
||||
public String perform(String[] args) {
|
||||
try {
|
||||
String base64Content = getContent(args);
|
||||
String content = new String(
|
||||
Base64.getDecoder().decode(base64Content), "UTF-8");
|
||||
|
||||
CompilationUnitResult compilationUnitResult =
|
||||
CompilationUnitCreator.createFromContent(content);
|
||||
if (compilationUnitResult == null) {
|
||||
return "Couldn't parse file";
|
||||
} else if (compilationUnitResult.getProblems() != null) {
|
||||
StringBuilder result =
|
||||
new StringBuilder("{'parse-problems':[");
|
||||
Set<Range> ranges = new HashSet<>();
|
||||
compilationUnitResult.getProblems().stream().forEach(p -> {
|
||||
p.getLocation().get().getBegin().getRange()
|
||||
.filter(range -> !ranges.contains(range))
|
||||
.ifPresent(range -> {
|
||||
result.append("{'message':'").append(p.getMessage()).append("'");
|
||||
result.append(",'lnum':'")
|
||||
.append(range.begin.line).append("'");
|
||||
result.append(",'col':'")
|
||||
.append(range.begin.column).append("'},");
|
||||
ranges.add(range);
|
||||
});
|
||||
});
|
||||
return result.append("]}").toString();
|
||||
} else {
|
||||
compilationUnit = compilationUnitResult.getCompilationUnit();
|
||||
}
|
||||
|
||||
ClassNamesFetcher classnamesFetcher =
|
||||
new ClassNamesFetcher(compilationUnit);
|
||||
classnames = classnamesFetcher.getNames();
|
||||
declarations = classnamesFetcher.getDeclarationList();
|
||||
|
||||
return action();
|
||||
} catch (UnsupportedEncodingException ex) {
|
||||
return ex.getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
private String getContent(String[] args) {
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
if (args[i].equals("-content")) {
|
||||
return args[i + 1];
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
public abstract String action();
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
package kg.ash.javavi.actions;
|
||||
|
||||
import static kg.ash.javavi.actions.ActionFactory.getArgWithName;
|
||||
import static kg.ash.javavi.actions.ActionFactory.getJavaViSources;
|
||||
|
||||
import kg.ash.javavi.Javavi;
|
||||
import kg.ash.javavi.output.OutputClassInfo;
|
||||
import kg.ash.javavi.readers.Parser;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.Base64;
|
||||
|
||||
public class ParseByContentAction implements Action {
|
||||
|
||||
@Override
|
||||
public String perform(String[] args) {
|
||||
try {
|
||||
String targetClass = getArgWithName(args, "-target");
|
||||
String base64Content = getArgWithName(args, "-content");
|
||||
|
||||
String content = new String(Base64.getDecoder().decode(base64Content), "UTF-8");
|
||||
Parser parser = new Parser(getJavaViSources(Javavi.system));
|
||||
parser.setSourceContent(content);
|
||||
|
||||
return new OutputClassInfo().get(parser.read(targetClass));
|
||||
} catch (UnsupportedEncodingException ex) {
|
||||
return ex.getMessage();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
package kg.ash.javavi.actions;
|
||||
|
||||
import kg.ash.javavi.cache.Cache;
|
||||
|
||||
public class RemoveClassInfoFromCache extends ActionWithTarget {
|
||||
|
||||
@Override
|
||||
public String perform(String[] args) {
|
||||
String target = parseTarget(args);
|
||||
if (Cache.getInstance().getClasses().containsKey(target)) {
|
||||
Cache.getInstance().getClasses().remove(target);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
108
bundle/vim-javacomplete2/libs/javavi/src/main/java/kg/ash/javavi/cache/Cache.java
vendored
Normal file
108
bundle/vim-javacomplete2/libs/javavi/src/main/java/kg/ash/javavi/cache/Cache.java
vendored
Normal file
@ -0,0 +1,108 @@
|
||||
package kg.ash.javavi.cache;
|
||||
|
||||
import kg.ash.javavi.Javavi;
|
||||
import kg.ash.javavi.apache.logging.log4j.LogManager;
|
||||
import kg.ash.javavi.apache.logging.log4j.Logger;
|
||||
import kg.ash.javavi.clazz.SourceClass;
|
||||
import kg.ash.javavi.searchers.JavaClassMap;
|
||||
import kg.ash.javavi.searchers.PackagesLoader;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
|
||||
public class Cache {
|
||||
|
||||
public static final Logger logger = LogManager.getLogger();
|
||||
public static final String PACKAGES_EMPTY_ERROR
|
||||
= "message: packages still empty, try later. indexing...";
|
||||
|
||||
private CacheSerializator serializator = new CacheSerializator();
|
||||
private HashMap<String, JavaClassMap> classPackages = new HashMap<>();
|
||||
private HashMap<String, SourceClass> classes = new HashMap<>();
|
||||
private Timer autosaveCacheTimer = new Timer();
|
||||
private boolean collectIsRunning = false;
|
||||
private int autosavePeriod = 60;
|
||||
private int cacheCode;
|
||||
|
||||
private static Cache instance;
|
||||
|
||||
public static Cache getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new Cache();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
public synchronized void collectPackages() {
|
||||
if (collectIsRunning) {
|
||||
return;
|
||||
}
|
||||
|
||||
collectIsRunning = true;
|
||||
new Thread(() -> {
|
||||
logger.info("start collecting cache");
|
||||
loadCache();
|
||||
|
||||
if (classPackages.isEmpty()) {
|
||||
logger.info("collecting empty cache");
|
||||
|
||||
HashMap<String, JavaClassMap> classPackagesTemp = new HashMap<>();
|
||||
new PackagesLoader(Javavi.system.get("sources")).collectPackages(classPackagesTemp);
|
||||
classPackages.putAll(classPackagesTemp);
|
||||
|
||||
saveCache();
|
||||
}
|
||||
|
||||
cacheCode = getClassPackages().hashCode();
|
||||
collectIsRunning = false;
|
||||
|
||||
autosaveCacheTimer.schedule(new AutosaveTask(this), autosavePeriod * 1000);
|
||||
}).start();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void loadCache() {
|
||||
Object o = serializator.loadCache("class_packages");
|
||||
if (o != null) {
|
||||
try {
|
||||
classPackages = (HashMap<String, JavaClassMap>) o;
|
||||
} catch (ClassCastException e) {
|
||||
logger.warn("Couldn't load cache");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void saveCache() {
|
||||
serializator.saveCache("class_packages", classPackages);
|
||||
}
|
||||
|
||||
public HashMap<String, JavaClassMap> getClassPackages() {
|
||||
if (classPackages.isEmpty()) {
|
||||
collectPackages();
|
||||
}
|
||||
return classPackages;
|
||||
}
|
||||
|
||||
public HashMap<String, SourceClass> getClasses() {
|
||||
return classes;
|
||||
}
|
||||
|
||||
class AutosaveTask extends TimerTask {
|
||||
private final Cache cache;
|
||||
|
||||
public AutosaveTask(Cache cache) {
|
||||
this.cache = cache;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
int newCode = cache.getClassPackages().hashCode();
|
||||
if (newCode != cache.cacheCode) {
|
||||
logger.info("autosave cache: {} != {}", newCode, cache.cacheCode);
|
||||
cache.saveCache();
|
||||
cache.cacheCode = cache.getClassPackages().hashCode();
|
||||
}
|
||||
cache.autosaveCacheTimer.schedule(new AutosaveTask(cache), cache.autosavePeriod * 1000);
|
||||
}
|
||||
}
|
||||
}
|
75
bundle/vim-javacomplete2/libs/javavi/src/main/java/kg/ash/javavi/cache/CacheSerializator.java
vendored
Normal file
75
bundle/vim-javacomplete2/libs/javavi/src/main/java/kg/ash/javavi/cache/CacheSerializator.java
vendored
Normal file
@ -0,0 +1,75 @@
|
||||
package kg.ash.javavi.cache;
|
||||
|
||||
import kg.ash.javavi.Javavi;
|
||||
import kg.ash.javavi.apache.logging.log4j.LogManager;
|
||||
import kg.ash.javavi.apache.logging.log4j.Logger;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.util.Map;
|
||||
|
||||
public class CacheSerializator {
|
||||
|
||||
public static final Logger logger = LogManager.getLogger();
|
||||
|
||||
private String base = null;
|
||||
private String project = null;
|
||||
|
||||
public CacheSerializator() {
|
||||
if (Javavi.system.containsKey("base")) {
|
||||
Map<String, String> system = Javavi.system;
|
||||
|
||||
base = system.get("base");
|
||||
if (system.containsKey("project")) {
|
||||
project = Javavi.system.get("project");
|
||||
}
|
||||
|
||||
File cacheFile = new File(base + File.separator + "cache");
|
||||
if (!cacheFile.exists()) {
|
||||
cacheFile.mkdir();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void saveCache(String name, Object data) {
|
||||
if (base != null && project != null) {
|
||||
String filename = String.format(
|
||||
"%s%scache%s%s_%s.dat",
|
||||
base,
|
||||
File.separator,
|
||||
File.separator,
|
||||
name,
|
||||
project);
|
||||
logger.info("saving cache {} to file {}", name, filename);
|
||||
try (FileOutputStream fout = new FileOutputStream(filename);
|
||||
ObjectOutputStream oos = new ObjectOutputStream(fout)) {
|
||||
oos.writeObject(data);
|
||||
} catch (Throwable e) {
|
||||
logger.error(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Object loadCache(String name) {
|
||||
if (base != null && project != null) {
|
||||
String filename = String.format(
|
||||
"%s%scache%s%s_%s.dat",
|
||||
base,
|
||||
File.separator,
|
||||
File.separator,
|
||||
name,
|
||||
project);
|
||||
logger.info("loading cache {} from file {}", name, filename);
|
||||
try (FileInputStream fin = new FileInputStream(filename);
|
||||
ObjectInputStream ois = new ObjectInputStream(fin)) {
|
||||
return ois.readObject();
|
||||
} catch (Throwable e) {
|
||||
logger.warn("Couldn't load cache");
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
64
bundle/vim-javacomplete2/libs/javavi/src/main/java/kg/ash/javavi/clazz/ClassConstructor.java
vendored
Normal file
64
bundle/vim-javacomplete2/libs/javavi/src/main/java/kg/ash/javavi/clazz/ClassConstructor.java
vendored
Normal file
@ -0,0 +1,64 @@
|
||||
package kg.ash.javavi.clazz;
|
||||
|
||||
import com.github.javaparser.ast.Modifier;
|
||||
|
||||
import java.util.EnumSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
public class ClassConstructor {
|
||||
|
||||
private String declaration = "";
|
||||
private EnumSet<Modifier> modifiers;
|
||||
private List<ClassTypeParameter> typeParameters = new LinkedList<>();
|
||||
|
||||
public void setDeclaration(String declaration) {
|
||||
this.declaration = declaration;
|
||||
}
|
||||
|
||||
public String getDeclaration() {
|
||||
return declaration;
|
||||
}
|
||||
|
||||
public void setModifiers(EnumSet<Modifier> modifiers) {
|
||||
this.modifiers = modifiers;
|
||||
}
|
||||
|
||||
public EnumSet<Modifier> getModifiers() {
|
||||
return modifiers;
|
||||
}
|
||||
|
||||
public void addTypeParameter(ClassTypeParameter parameter) {
|
||||
typeParameters.add(parameter);
|
||||
}
|
||||
|
||||
public List<ClassTypeParameter> getTypeParameters() {
|
||||
return typeParameters;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final ClassConstructor other = (ClassConstructor) obj;
|
||||
if (!Objects.equals(this.declaration, other.declaration) && (this.declaration == null
|
||||
|| !this.declaration.equals(other.declaration))) {
|
||||
return false;
|
||||
}
|
||||
return this.modifiers == other.modifiers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = 7;
|
||||
hash = 17 * hash + (modifiers.hashCode());
|
||||
hash = 17 * hash + (this.declaration != null ? this.declaration.hashCode() : 0);
|
||||
return hash;
|
||||
}
|
||||
}
|
63
bundle/vim-javacomplete2/libs/javavi/src/main/java/kg/ash/javavi/clazz/ClassField.java
vendored
Normal file
63
bundle/vim-javacomplete2/libs/javavi/src/main/java/kg/ash/javavi/clazz/ClassField.java
vendored
Normal file
@ -0,0 +1,63 @@
|
||||
package kg.ash.javavi.clazz;
|
||||
|
||||
import com.github.javaparser.ast.Modifier;
|
||||
|
||||
import java.util.EnumSet;
|
||||
import java.util.Objects;
|
||||
|
||||
public class ClassField {
|
||||
|
||||
private String name;
|
||||
private EnumSet<Modifier> modifiers;
|
||||
private String typeName;
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setModifiers(EnumSet<Modifier> modifiers) {
|
||||
this.modifiers = modifiers;
|
||||
}
|
||||
|
||||
public EnumSet<Modifier> getModifiers() {
|
||||
return modifiers;
|
||||
}
|
||||
|
||||
public void setTypeName(String typeName) {
|
||||
this.typeName = typeName;
|
||||
}
|
||||
|
||||
public String getTypeName() {
|
||||
return typeName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final ClassField other = (ClassField) obj;
|
||||
if (!Objects.equals(this.name, other.name) && (this.name == null || !this.name.equals(
|
||||
other.name))) {
|
||||
return false;
|
||||
}
|
||||
return this.typeName == other.typeName || (this.typeName != null && this.typeName.equals(
|
||||
other.typeName));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = 7;
|
||||
hash = 17 * hash + (this.name != null ? this.name.hashCode() : 0);
|
||||
hash = 17 * hash + (this.typeName != null ? this.typeName.hashCode() : 0);
|
||||
return hash;
|
||||
}
|
||||
}
|
45
bundle/vim-javacomplete2/libs/javavi/src/main/java/kg/ash/javavi/clazz/ClassImport.java
vendored
Normal file
45
bundle/vim-javacomplete2/libs/javavi/src/main/java/kg/ash/javavi/clazz/ClassImport.java
vendored
Normal file
@ -0,0 +1,45 @@
|
||||
package kg.ash.javavi.clazz;
|
||||
|
||||
public class ClassImport {
|
||||
private String name;
|
||||
private boolean isStatic;
|
||||
private boolean isAsterisk;
|
||||
|
||||
public ClassImport(String name, boolean isStatic, boolean isAsterisk) {
|
||||
this.name = name;
|
||||
this.isStatic = isStatic;
|
||||
this.isAsterisk = isAsterisk;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public boolean isStatic() {
|
||||
return isStatic;
|
||||
}
|
||||
|
||||
public boolean isAsterisk() {
|
||||
return isAsterisk;
|
||||
}
|
||||
|
||||
public String getHead() {
|
||||
return name.substring(0, name.lastIndexOf("."));
|
||||
}
|
||||
|
||||
public String getTail() {
|
||||
if (name.contains(".")) {
|
||||
String[] splitted = name.split("\\.");
|
||||
return splitted[splitted.length - 1];
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return String.format("%s, isStatic: %b", name, isStatic);
|
||||
}
|
||||
}
|
102
bundle/vim-javacomplete2/libs/javavi/src/main/java/kg/ash/javavi/clazz/ClassMethod.java
vendored
Normal file
102
bundle/vim-javacomplete2/libs/javavi/src/main/java/kg/ash/javavi/clazz/ClassMethod.java
vendored
Normal file
@ -0,0 +1,102 @@
|
||||
package kg.ash.javavi.clazz;
|
||||
|
||||
import com.github.javaparser.ast.Modifier;
|
||||
|
||||
import java.util.EnumSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
public class ClassMethod {
|
||||
|
||||
private String name;
|
||||
private EnumSet<Modifier> modifiers;
|
||||
private String declaration;
|
||||
private String typeName;
|
||||
private List<ClassTypeParameter> typeParameters = new LinkedList<>();
|
||||
private boolean deprecated = false;
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setModifiers(EnumSet<Modifier> modifiers) {
|
||||
this.modifiers = modifiers;
|
||||
}
|
||||
|
||||
public EnumSet<Modifier> getModifiers() {
|
||||
return modifiers;
|
||||
}
|
||||
|
||||
public void setDeclaration(String declaration) {
|
||||
this.declaration = declaration;
|
||||
}
|
||||
|
||||
public String getDeclaration() {
|
||||
return declaration;
|
||||
}
|
||||
|
||||
public void setTypeName(String typeName) {
|
||||
this.typeName = typeName;
|
||||
}
|
||||
|
||||
public String getTypeName() {
|
||||
return typeName;
|
||||
}
|
||||
|
||||
public void addTypeParameter(ClassTypeParameter typeParameter) {
|
||||
typeParameters.add(typeParameter);
|
||||
}
|
||||
|
||||
public List<ClassTypeParameter> getTypeParameters() {
|
||||
return typeParameters;
|
||||
}
|
||||
|
||||
public void setDeprecated(boolean deprecated) {
|
||||
this.deprecated = deprecated;
|
||||
}
|
||||
|
||||
public boolean getDeprecated() {
|
||||
return deprecated;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final ClassMethod other = (ClassMethod) obj;
|
||||
if (!Objects.equals(this.name, other.name) && (this.name == null || !this.name.equals(
|
||||
other.name))) {
|
||||
return false;
|
||||
}
|
||||
if (!Objects.equals(this.typeName, other.typeName) && (this.typeName == null
|
||||
|| !this.typeName.equals(other.typeName))) {
|
||||
return false;
|
||||
}
|
||||
return this.declaration == other.declaration || (this.declaration != null
|
||||
&& this.declaration.equals(other.declaration));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = 7;
|
||||
hash = 17 * hash + (this.name != null ? this.name.hashCode() : 0);
|
||||
hash = 17 * hash + (this.typeName != null ? this.typeName.hashCode() : 0);
|
||||
hash = 17 * hash + (this.declaration != null ? this.declaration.hashCode() : 0);
|
||||
return hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
}
|
18
bundle/vim-javacomplete2/libs/javavi/src/main/java/kg/ash/javavi/clazz/ClassTypeParameter.java
vendored
Normal file
18
bundle/vim-javacomplete2/libs/javavi/src/main/java/kg/ash/javavi/clazz/ClassTypeParameter.java
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
package kg.ash.javavi.clazz;
|
||||
|
||||
public class ClassTypeParameter {
|
||||
|
||||
private String name;
|
||||
|
||||
public ClassTypeParameter(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
}
|
36
bundle/vim-javacomplete2/libs/javavi/src/main/java/kg/ash/javavi/clazz/CodeRegion.java
vendored
Normal file
36
bundle/vim-javacomplete2/libs/javavi/src/main/java/kg/ash/javavi/clazz/CodeRegion.java
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
package kg.ash.javavi.clazz;
|
||||
|
||||
public class CodeRegion {
|
||||
|
||||
private int beginLine = -1;
|
||||
private int beginColumn = -1;
|
||||
private int endLine = -1;
|
||||
private int endColumn = -1;
|
||||
|
||||
public CodeRegion() {
|
||||
}
|
||||
|
||||
public CodeRegion(int beginLine, int beginColumn, int endLine, int endColumn) {
|
||||
this.beginLine = beginLine;
|
||||
this.beginColumn = beginColumn;
|
||||
this.endLine = endLine;
|
||||
this.endColumn = endColumn;
|
||||
}
|
||||
|
||||
public int getBeginLine() {
|
||||
return beginLine;
|
||||
}
|
||||
|
||||
public int getBeginColumn() {
|
||||
return beginColumn;
|
||||
}
|
||||
|
||||
public int getEndLine() {
|
||||
return endLine;
|
||||
}
|
||||
|
||||
public int getEndColumn() {
|
||||
return endColumn;
|
||||
}
|
||||
|
||||
}
|
161
bundle/vim-javacomplete2/libs/javavi/src/main/java/kg/ash/javavi/clazz/SourceClass.java
vendored
Normal file
161
bundle/vim-javacomplete2/libs/javavi/src/main/java/kg/ash/javavi/clazz/SourceClass.java
vendored
Normal file
@ -0,0 +1,161 @@
|
||||
package kg.ash.javavi.clazz;
|
||||
|
||||
import com.github.javaparser.ast.Modifier;
|
||||
import kg.ash.javavi.TargetParser;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
|
||||
public class SourceClass {
|
||||
|
||||
private String pkg = null;
|
||||
private String name = null;
|
||||
private EnumSet<Modifier> modifiers;
|
||||
private boolean isInterface = false;
|
||||
private List<ClassConstructor> constructors = new ArrayList<>();
|
||||
private List<ClassMethod> methods = new ArrayList<>();
|
||||
private List<ClassField> fields = new ArrayList<>();
|
||||
private List<ClassImport> imports = new ArrayList<>();
|
||||
|
||||
private String superclass = null;
|
||||
private List<String> interfaces = new ArrayList<>();
|
||||
|
||||
private List<SourceClass> linkedClasses = new ArrayList<>();
|
||||
private List<String> typeArguments = new ArrayList<>();
|
||||
|
||||
private List<String> nestedClasses = new ArrayList<>();
|
||||
|
||||
private CodeRegion region = new CodeRegion();
|
||||
|
||||
public String getName() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
if (pkg != null) {
|
||||
sb.append(pkg).append(".");
|
||||
}
|
||||
sb.append(name).append(TargetParser.getTypeArgumentsString(typeArguments));
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getSimpleName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public List<ClassConstructor> getConstructors() {
|
||||
return constructors;
|
||||
}
|
||||
|
||||
public void addConstructor(ClassConstructor constructor) {
|
||||
if (constructor != null && !constructors.contains(constructor)) {
|
||||
constructors.add(constructor);
|
||||
}
|
||||
}
|
||||
|
||||
public List<ClassMethod> getMethods() {
|
||||
return methods;
|
||||
}
|
||||
|
||||
public void addMethod(ClassMethod method) {
|
||||
if (method != null && !methods.contains(method)) {
|
||||
methods.add(method);
|
||||
}
|
||||
}
|
||||
|
||||
public List<ClassField> getFields() {
|
||||
return fields;
|
||||
}
|
||||
|
||||
public void addField(ClassField field) {
|
||||
if (field != null && !fields.contains(field)) {
|
||||
fields.add(field);
|
||||
}
|
||||
}
|
||||
|
||||
public EnumSet<Modifier> getModifiers() {
|
||||
return modifiers;
|
||||
}
|
||||
|
||||
public void setModifiers(EnumSet<Modifier> modifiers) {
|
||||
this.modifiers = modifiers;
|
||||
}
|
||||
|
||||
public String getPackage() {
|
||||
return pkg;
|
||||
}
|
||||
|
||||
public void setPackage(String pakage) {
|
||||
this.pkg = pakage;
|
||||
}
|
||||
|
||||
public void setSuperclass(String superclass) {
|
||||
this.superclass = superclass;
|
||||
}
|
||||
|
||||
public String getSuperclass() {
|
||||
return superclass;
|
||||
}
|
||||
|
||||
public void addImport(ClassImport classImport) {
|
||||
imports.add(classImport);
|
||||
}
|
||||
|
||||
public List<ClassImport> getImports() {
|
||||
return imports;
|
||||
}
|
||||
|
||||
public void addInterface(String interfaceName) {
|
||||
interfaces.add(interfaceName);
|
||||
}
|
||||
|
||||
public List<String> getInterfaces() {
|
||||
return interfaces;
|
||||
}
|
||||
|
||||
public void setIsInterface(boolean isInterface) {
|
||||
this.isInterface = isInterface;
|
||||
}
|
||||
|
||||
public boolean isInterface() {
|
||||
return isInterface;
|
||||
}
|
||||
|
||||
public void addLinkedClass(SourceClass clazz) {
|
||||
linkedClasses.add(clazz);
|
||||
methods.addAll(clazz.getMethods());
|
||||
fields.addAll(clazz.getFields());
|
||||
}
|
||||
|
||||
public List<SourceClass> getLinkedClasses() {
|
||||
return linkedClasses;
|
||||
}
|
||||
|
||||
public void addTypeArgument(String type) {
|
||||
typeArguments.add(type);
|
||||
}
|
||||
|
||||
public void addNestedClass(String cls) {
|
||||
nestedClasses.add(cls);
|
||||
}
|
||||
|
||||
public List<String> getNestedClasses() {
|
||||
return nestedClasses;
|
||||
}
|
||||
|
||||
public void setRegion(int beginLine, int beginColumn, int endLine, int endColumn) {
|
||||
setRegion(new CodeRegion(beginLine, beginColumn, endLine, endColumn));
|
||||
}
|
||||
|
||||
public void setRegion(CodeRegion region) {
|
||||
this.region = region;
|
||||
}
|
||||
|
||||
public CodeRegion getRegion() {
|
||||
return region;
|
||||
}
|
||||
}
|
229
bundle/vim-javacomplete2/libs/javavi/src/main/java/kg/ash/javavi/output/OutputClassInfo.java
vendored
Normal file
229
bundle/vim-javacomplete2/libs/javavi/src/main/java/kg/ash/javavi/output/OutputClassInfo.java
vendored
Normal file
@ -0,0 +1,229 @@
|
||||
package kg.ash.javavi.output;
|
||||
|
||||
import kg.ash.javavi.Javavi;
|
||||
import kg.ash.javavi.clazz.ClassConstructor;
|
||||
import kg.ash.javavi.clazz.ClassField;
|
||||
import kg.ash.javavi.clazz.ClassMethod;
|
||||
import kg.ash.javavi.clazz.ClassTypeParameter;
|
||||
import kg.ash.javavi.clazz.SourceClass;
|
||||
import kg.ash.javavi.readers.Reflection;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
public class OutputClassInfo {
|
||||
|
||||
public static final String KEY_NAME = "'n':";
|
||||
public static final String KEY_TYPE = "'t':";
|
||||
public static final String KEY_MODIFIER = "'m':";
|
||||
public static final String KEY_PARAMETERTYPES = "'p':";
|
||||
public static final String KEY_RETURNTYPE = "'r':";
|
||||
public static final String KEY_DESCRIPTION = "'d':";
|
||||
public static final String KEY_DECLARING_CLASS = "'c':";
|
||||
|
||||
public String get(SourceClass clazz) {
|
||||
HashMap<String, String> classMap = new HashMap<>();
|
||||
putClassInfo(classMap, clazz);
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (classMap.size() > 0) {
|
||||
sb.append("{");
|
||||
for (String s : classMap.keySet()) {
|
||||
sb.append("'").append(s).append("':")
|
||||
.append(classMap.get(s)).append(",");
|
||||
}
|
||||
sb.append("}");
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private void putClassInfo(
|
||||
HashMap<String, String> map, SourceClass clazz) {
|
||||
if (clazz == null || map.containsKey(clazz.getName())) {
|
||||
return;
|
||||
}
|
||||
|
||||
StringBuilder sb = init(clazz);
|
||||
isIntefaceOrClass(sb, clazz);
|
||||
hasNested(sb, clazz);
|
||||
hasConstructors(sb, clazz);
|
||||
hasFields(sb, clazz);
|
||||
hasMethods(sb, clazz);
|
||||
finish(sb, clazz, map);
|
||||
}
|
||||
|
||||
private StringBuilder init(SourceClass clazz) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("{")
|
||||
.append("'tag':'CLASSDEF',")
|
||||
.append(Javavi.NEWLINE)
|
||||
.append("'flags':'")
|
||||
.append(Integer.toString(
|
||||
Reflection.EnumSetModifierToInt(
|
||||
clazz.getModifiers()), 2))
|
||||
.append("',")
|
||||
.append(Javavi.NEWLINE)
|
||||
.append("'name':'")
|
||||
.append(clazz.getName())
|
||||
.append("',")
|
||||
.append(Javavi.NEWLINE)
|
||||
.append("'classpath':'1',")
|
||||
.append(Javavi.NEWLINE)
|
||||
.append("'pos':[")
|
||||
.append(clazz.getRegion().getBeginLine())
|
||||
.append(",")
|
||||
.append(clazz.getRegion().getBeginColumn())
|
||||
.append("],")
|
||||
.append("'endpos':[")
|
||||
.append(clazz.getRegion().getEndLine())
|
||||
.append(",")
|
||||
.append(clazz.getRegion().getEndColumn())
|
||||
.append("],")
|
||||
.append("'fqn':'")
|
||||
.append(clazz.getName())
|
||||
.append("',")
|
||||
.append(Javavi.NEWLINE);
|
||||
|
||||
return sb;
|
||||
}
|
||||
|
||||
private void isIntefaceOrClass(StringBuilder sb, SourceClass clazz) {
|
||||
if (clazz.isInterface()) {
|
||||
sb.append("'interface':'1','extends':[");
|
||||
} else {
|
||||
String superclass = clazz.getSuperclass();
|
||||
if (superclass != null
|
||||
&& !"java.lang.Object".equals(superclass)) {
|
||||
sb.append("'extends':['").append(superclass)
|
||||
.append("'],").append(Javavi.NEWLINE);
|
||||
}
|
||||
sb.append("'implements':[");
|
||||
}
|
||||
|
||||
clazz.getInterfaces().forEach(
|
||||
iface -> sb.append("'").append(iface).append("',"));
|
||||
sb.append("],").append(Javavi.NEWLINE);
|
||||
}
|
||||
|
||||
private void hasNested(StringBuilder sb, SourceClass clazz) {
|
||||
sb.append("'nested':[");
|
||||
clazz.getNestedClasses().forEach(
|
||||
nested -> sb.append("'").append(nested).append("',"));
|
||||
sb.append("],").append(Javavi.NEWLINE);
|
||||
}
|
||||
|
||||
private void hasConstructors(StringBuilder sb, SourceClass clazz) {
|
||||
sb.append("'ctors':[");
|
||||
for (ClassConstructor ctor : clazz.getConstructors()) {
|
||||
sb.append("{");
|
||||
|
||||
appendModifier(sb,
|
||||
Reflection.EnumSetModifierToInt(
|
||||
ctor.getModifiers()));
|
||||
appendParameterTypes(sb, ctor.getTypeParameters());
|
||||
|
||||
sb.append(KEY_DESCRIPTION).append("'")
|
||||
.append(ctor.getDeclaration()).append("'");
|
||||
|
||||
sb.append("},").append(Javavi.NEWLINE);
|
||||
}
|
||||
|
||||
sb.append("],").append(Javavi.NEWLINE);
|
||||
}
|
||||
|
||||
|
||||
private void hasFields(StringBuilder sb, SourceClass clazz) {
|
||||
sb.append("'fields':[");
|
||||
for (ClassField field : clazz.getFields()) {
|
||||
sb.append("{");
|
||||
sb.append(KEY_NAME).append("'")
|
||||
.append(field.getName()).append("',");
|
||||
|
||||
if (!field.getTypeName().equals(clazz.getName())) {
|
||||
sb.append(KEY_DECLARING_CLASS).append("'")
|
||||
.append(field.getTypeName()).append("',");
|
||||
}
|
||||
|
||||
appendModifier(sb, Reflection.EnumSetModifierToInt(
|
||||
field.getModifiers()));
|
||||
sb.append(KEY_TYPE)
|
||||
.append("'")
|
||||
.append(field.getTypeName())
|
||||
.append("'")
|
||||
.append("},")
|
||||
.append(Javavi.NEWLINE);
|
||||
}
|
||||
|
||||
sb.append("],").append(Javavi.NEWLINE);
|
||||
}
|
||||
|
||||
private void hasMethods(StringBuilder sb, SourceClass clazz) {
|
||||
sb.append("'methods':[");
|
||||
for (ClassMethod method : clazz.getMethods()) {
|
||||
sb.append("{");
|
||||
|
||||
sb.append(KEY_NAME).append("'")
|
||||
.append(method.getName()).append("',");
|
||||
|
||||
if (!method.getTypeName().equals(clazz.getName())) {
|
||||
sb.append(KEY_DECLARING_CLASS)
|
||||
.append("'")
|
||||
.append(method.getTypeName())
|
||||
.append("',");
|
||||
}
|
||||
|
||||
appendModifier(sb, Reflection.EnumSetModifierToInt(
|
||||
method.getModifiers()));
|
||||
|
||||
sb.append(KEY_RETURNTYPE).append("'")
|
||||
.append(method.getTypeName()).append("',");
|
||||
|
||||
appendParameterTypes(sb, method.getTypeParameters());
|
||||
|
||||
sb.append(KEY_DESCRIPTION)
|
||||
.append("'");
|
||||
if (method.getDeprecated()) {
|
||||
sb.append("@Deprecated ");
|
||||
}
|
||||
sb.append(method.getDeclaration())
|
||||
.append("'")
|
||||
.append("},")
|
||||
.append(Javavi.NEWLINE);
|
||||
}
|
||||
sb.append("],").append(Javavi.NEWLINE);
|
||||
}
|
||||
|
||||
private void finish(
|
||||
StringBuilder sb, SourceClass clazz,
|
||||
HashMap<String, String> map) {
|
||||
|
||||
sb.append("}");
|
||||
|
||||
map.put(clazz.getName(), sb.toString());
|
||||
|
||||
for (SourceClass sourceClass : clazz.getLinkedClasses()) {
|
||||
putClassInfo(map, sourceClass);
|
||||
}
|
||||
}
|
||||
|
||||
private void appendModifier(StringBuilder sb, int modifier) {
|
||||
sb.append(KEY_MODIFIER).append("'")
|
||||
.append(Integer.toString(modifier, 2)).append("',");
|
||||
}
|
||||
|
||||
private void appendParameterTypes(
|
||||
StringBuilder sb, List<ClassTypeParameter> paramTypes) {
|
||||
if (paramTypes == null || paramTypes.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
sb.append(KEY_PARAMETERTYPES).append("[");
|
||||
|
||||
paramTypes.forEach(
|
||||
parameter -> sb.append("'").append(
|
||||
parameter.getName()).append("',"));
|
||||
|
||||
sb.append("],");
|
||||
}
|
||||
}
|
56
bundle/vim-javacomplete2/libs/javavi/src/main/java/kg/ash/javavi/output/OutputClassPackages.java
vendored
Normal file
56
bundle/vim-javacomplete2/libs/javavi/src/main/java/kg/ash/javavi/output/OutputClassPackages.java
vendored
Normal file
@ -0,0 +1,56 @@
|
||||
package kg.ash.javavi.output;
|
||||
|
||||
import com.github.javaparser.ast.Modifier;
|
||||
import kg.ash.javavi.Javavi;
|
||||
import kg.ash.javavi.cache.Cache;
|
||||
import kg.ash.javavi.clazz.SourceClass;
|
||||
import kg.ash.javavi.readers.ClassReader;
|
||||
import kg.ash.javavi.searchers.ClassSearcher;
|
||||
import kg.ash.javavi.searchers.JavaClassMap;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
public class OutputClassPackages {
|
||||
|
||||
private HashMap<String, JavaClassMap> classPackages;
|
||||
private String sources = Javavi.system.get("sources").replace('\\', '/');
|
||||
|
||||
public OutputClassPackages(HashMap<String, JavaClassMap> classPackages) {
|
||||
this.classPackages = classPackages;
|
||||
}
|
||||
|
||||
public String get(String targetClass) {
|
||||
if (classPackages == null || classPackages.isEmpty()) {
|
||||
return Cache.PACKAGES_EMPTY_ERROR;
|
||||
}
|
||||
|
||||
StringBuilder builder = new StringBuilder("");
|
||||
if (classPackages.containsKey(targetClass)) {
|
||||
JavaClassMap cm = classPackages.get(targetClass);
|
||||
if (cm.getType() == JavaClassMap.TYPE_CLASS) {
|
||||
cm.getSubpackages().keySet().forEach((String scope) -> {
|
||||
if (scope.endsWith("$")) {
|
||||
String target = scope + targetClass;
|
||||
ClassSearcher seacher = new ClassSearcher();
|
||||
if (seacher.find(target, sources)) {
|
||||
ClassReader reader = seacher.getReader();
|
||||
SourceClass clazz = reader.read(target);
|
||||
if (clazz != null && clazz.getModifiers().contains(Modifier.STATIC)) {
|
||||
scope = "static " + scope;
|
||||
}
|
||||
}
|
||||
}
|
||||
builder.append("'")
|
||||
.append(scope)
|
||||
.append(scope.endsWith("$") ? "" : ".")
|
||||
.append(targetClass)
|
||||
.append("',")
|
||||
.append(Javavi.NEWLINE);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return String.format("[%s]", builder);
|
||||
}
|
||||
|
||||
}
|
41
bundle/vim-javacomplete2/libs/javavi/src/main/java/kg/ash/javavi/output/OutputPackageInfo.java
vendored
Normal file
41
bundle/vim-javacomplete2/libs/javavi/src/main/java/kg/ash/javavi/output/OutputPackageInfo.java
vendored
Normal file
@ -0,0 +1,41 @@
|
||||
package kg.ash.javavi.output;
|
||||
|
||||
import kg.ash.javavi.cache.Cache;
|
||||
import kg.ash.javavi.searchers.JavaClassMap;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
public class OutputPackageInfo {
|
||||
|
||||
private HashMap<String, JavaClassMap> classPackages;
|
||||
|
||||
public OutputPackageInfo(HashMap<String, JavaClassMap> classPackages) {
|
||||
this.classPackages = classPackages;
|
||||
}
|
||||
|
||||
public String get(String targetPackage) {
|
||||
if (classPackages == null || classPackages.isEmpty()) {
|
||||
return Cache.PACKAGES_EMPTY_ERROR;
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (classPackages.containsKey(targetPackage)) {
|
||||
JavaClassMap classMap = classPackages.get(targetPackage);
|
||||
|
||||
sb.append("'")
|
||||
.append(targetPackage)
|
||||
.append("':")
|
||||
.append("{'tag':'PACKAGE'")
|
||||
.append(",'subpackages':[")
|
||||
.append(classMap.getCachedSubpackages())
|
||||
.append("]")
|
||||
.append(",'classes':[")
|
||||
.append(classMap.getCachedClasses().toString())
|
||||
.append("]")
|
||||
.append("},");
|
||||
}
|
||||
|
||||
return String.format("{%s}", sb);
|
||||
}
|
||||
|
||||
}
|
51
bundle/vim-javacomplete2/libs/javavi/src/main/java/kg/ash/javavi/output/OutputSimilar.java
vendored
Normal file
51
bundle/vim-javacomplete2/libs/javavi/src/main/java/kg/ash/javavi/output/OutputSimilar.java
vendored
Normal file
@ -0,0 +1,51 @@
|
||||
package kg.ash.javavi.output;
|
||||
|
||||
import kg.ash.javavi.Javavi;
|
||||
import kg.ash.javavi.cache.Cache;
|
||||
import kg.ash.javavi.searchers.JavaClassMap;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class OutputSimilar {
|
||||
|
||||
protected String wordPrefix = "";
|
||||
|
||||
protected HashMap<String, JavaClassMap> classPackages;
|
||||
|
||||
public OutputSimilar(HashMap<String, JavaClassMap> classPackages) {
|
||||
this.classPackages = classPackages;
|
||||
}
|
||||
|
||||
public String get(String target) {
|
||||
if (target == null) {
|
||||
target = "";
|
||||
}
|
||||
|
||||
if (classPackages == null || classPackages.isEmpty()) {
|
||||
return Cache.PACKAGES_EMPTY_ERROR;
|
||||
}
|
||||
|
||||
List<String> keys = getKeys(target);
|
||||
Collections.sort(keys);
|
||||
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for (String key : keys) {
|
||||
classPackages.get(key)
|
||||
.getPaths()
|
||||
.forEach(scope -> builder.append("{")
|
||||
.append("'word':'")
|
||||
.append(wordPrefix)
|
||||
.append(key)
|
||||
.append("', 'menu':'")
|
||||
.append(scope)
|
||||
.append("', 'type': 'c'},")
|
||||
.append(Javavi.NEWLINE));
|
||||
}
|
||||
return String.format("[%s]", builder);
|
||||
}
|
||||
|
||||
protected abstract List<String> getKeys(String target);
|
||||
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
package kg.ash.javavi.output;
|
||||
|
||||
import kg.ash.javavi.searchers.JavaClassMap;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
public class OutputSimilarAnnotations extends OutputSimilar {
|
||||
|
||||
public OutputSimilarAnnotations(HashMap<String, JavaClassMap> classPackages) {
|
||||
super(classPackages);
|
||||
wordPrefix = "@";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getKeys(String target) {
|
||||
List<String> keysResult = new ArrayList<>();
|
||||
|
||||
classPackages.forEach((key, value) -> {
|
||||
if (target.isEmpty() || key.startsWith(target)) {
|
||||
value.getPaths()
|
||||
.stream()
|
||||
.filter(isFromClasspath(value))
|
||||
.forEach(fqn -> addIfAnnotation(keysResult, fqn, key));
|
||||
}
|
||||
});
|
||||
|
||||
return keysResult;
|
||||
}
|
||||
|
||||
private void addIfAnnotation(List<String> keys, String fqn, String key) {
|
||||
try {
|
||||
String fullFqn = String.format("%s.%s", fqn, key);
|
||||
ClassLoader loader = getClass().getClassLoader();
|
||||
Class cls = Class.forName(fullFqn, false, loader);
|
||||
if (cls.isAnnotation()) {
|
||||
keys.add(key);
|
||||
}
|
||||
} catch (NoClassDefFoundError | ClassNotFoundException ex) {
|
||||
}
|
||||
}
|
||||
|
||||
private Predicate<String> isFromClasspath(JavaClassMap map) {
|
||||
return s -> map.getSourceType(s) == JavaClassMap.SOURCETYPE_CLASSPATH;
|
||||
}
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
package kg.ash.javavi.output;
|
||||
|
||||
import kg.ash.javavi.searchers.JavaClassMap;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class OutputSimilarClasses extends OutputSimilar {
|
||||
|
||||
public OutputSimilarClasses(HashMap<String, JavaClassMap> classPackages) {
|
||||
super(classPackages);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getKeys(String target) {
|
||||
if (target.isEmpty()) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
return classPackages.keySet()
|
||||
.stream()
|
||||
.filter(k -> k.startsWith(target))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
}
|
13
bundle/vim-javacomplete2/libs/javavi/src/main/java/kg/ash/javavi/readers/ClassReader.java
vendored
Normal file
13
bundle/vim-javacomplete2/libs/javavi/src/main/java/kg/ash/javavi/readers/ClassReader.java
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
package kg.ash.javavi.readers;
|
||||
|
||||
import kg.ash.javavi.clazz.SourceClass;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface ClassReader {
|
||||
SourceClass read(String fqn);
|
||||
|
||||
ClassReader setTypeArguments(List<String> typeArguments);
|
||||
|
||||
ClassReader addKnown(List knownClasses);
|
||||
}
|
48
bundle/vim-javacomplete2/libs/javavi/src/main/java/kg/ash/javavi/readers/FileClassLoader.java
vendored
Normal file
48
bundle/vim-javacomplete2/libs/javavi/src/main/java/kg/ash/javavi/readers/FileClassLoader.java
vendored
Normal file
@ -0,0 +1,48 @@
|
||||
package kg.ash.javavi.readers;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
|
||||
public class FileClassLoader extends ClassLoader {
|
||||
|
||||
private String classFile;
|
||||
|
||||
public FileClassLoader(ClassLoader parent, String classFile) {
|
||||
super(parent);
|
||||
this.classFile = classFile;
|
||||
}
|
||||
|
||||
// TODO: Handle throwables.
|
||||
public Class loadClass(String name) {
|
||||
try {
|
||||
if (name.startsWith("java.")) {
|
||||
return Class.forName(name);
|
||||
}
|
||||
|
||||
File file = new File(classFile);
|
||||
if (file.exists()) {
|
||||
FileInputStream fileInputStream = new FileInputStream(file);
|
||||
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
||||
int data = fileInputStream.read();
|
||||
|
||||
while (data != -1) {
|
||||
buffer.write(data);
|
||||
data = fileInputStream.read();
|
||||
}
|
||||
|
||||
fileInputStream.close();
|
||||
|
||||
byte[] classData = buffer.toByteArray();
|
||||
return defineClass(name, classData, 0, classData.length);
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
try {
|
||||
return Class.forName(name);
|
||||
} catch (Throwable t2) {
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
365
bundle/vim-javacomplete2/libs/javavi/src/main/java/kg/ash/javavi/readers/Parser.java
vendored
Normal file
365
bundle/vim-javacomplete2/libs/javavi/src/main/java/kg/ash/javavi/readers/Parser.java
vendored
Normal file
@ -0,0 +1,365 @@
|
||||
package kg.ash.javavi.readers;
|
||||
|
||||
import com.github.javaparser.Position;
|
||||
import com.github.javaparser.ast.CompilationUnit;
|
||||
import com.github.javaparser.ast.ImportDeclaration;
|
||||
import com.github.javaparser.ast.Modifier;
|
||||
import com.github.javaparser.ast.Node;
|
||||
import com.github.javaparser.ast.NodeList;
|
||||
import com.github.javaparser.ast.PackageDeclaration;
|
||||
import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
|
||||
import com.github.javaparser.ast.body.ConstructorDeclaration;
|
||||
import com.github.javaparser.ast.body.FieldDeclaration;
|
||||
import com.github.javaparser.ast.body.MethodDeclaration;
|
||||
import com.github.javaparser.ast.body.Parameter;
|
||||
import com.github.javaparser.ast.body.VariableDeclarator;
|
||||
import com.github.javaparser.ast.type.ClassOrInterfaceType;
|
||||
import com.github.javaparser.ast.type.TypeParameter;
|
||||
import com.github.javaparser.ast.visitor.VoidVisitorAdapter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import kg.ash.javavi.apache.logging.log4j.LogManager;
|
||||
import kg.ash.javavi.apache.logging.log4j.Logger;
|
||||
|
||||
import kg.ash.javavi.cache.Cache;
|
||||
import kg.ash.javavi.clazz.ClassConstructor;
|
||||
import kg.ash.javavi.clazz.ClassField;
|
||||
import kg.ash.javavi.clazz.ClassImport;
|
||||
import kg.ash.javavi.clazz.ClassMethod;
|
||||
import kg.ash.javavi.clazz.ClassTypeParameter;
|
||||
import kg.ash.javavi.clazz.SourceClass;
|
||||
import kg.ash.javavi.readers.source.ClassNamesFetcher;
|
||||
import kg.ash.javavi.readers.source.CompilationUnitCreator;
|
||||
import kg.ash.javavi.readers.source.CompilationUnitResult;
|
||||
import kg.ash.javavi.searchers.ClassSearcher;
|
||||
import kg.ash.javavi.searchers.FqnSearcher;
|
||||
|
||||
public class Parser implements ClassReader {
|
||||
|
||||
public static final Logger logger = LogManager.getLogger();
|
||||
|
||||
private String sources;
|
||||
private String sourceFile = null;
|
||||
private String sourceContent = null;
|
||||
private ClassOrInterfaceDeclaration parentClass = null;
|
||||
|
||||
public Parser(String sources) {
|
||||
this.sources = sources.replace('\\', '/');
|
||||
}
|
||||
|
||||
public Parser(String sources, String sourceFile) {
|
||||
this.sources = sources.replace('\\', '/');
|
||||
this.sourceFile = sourceFile.replace('\\', '/');
|
||||
}
|
||||
|
||||
public void setSourceContent(String sourceContent) {
|
||||
this.sourceContent = sourceContent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClassReader setTypeArguments(List<String> typeArguments) {
|
||||
// Not supported yet.
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClassReader addKnown(List list) {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SourceClass read(String targetClass) {
|
||||
if ((sourceFile == null || sourceFile.isEmpty())
|
||||
&& (sourceContent == null || sourceContent.isEmpty())) {
|
||||
return null;
|
||||
}
|
||||
|
||||
logger.debug("read class from sources: {}", targetClass);
|
||||
|
||||
if (targetClass.contains("$")) {
|
||||
targetClass = targetClass.split("\\$")[0];
|
||||
}
|
||||
|
||||
if (Cache.getInstance().getClasses().containsKey(targetClass)) {
|
||||
return Cache.getInstance().getClasses().get(targetClass);
|
||||
}
|
||||
|
||||
CompilationUnitResult cur = sourceFile != null
|
||||
? CompilationUnitCreator.createFromFile(sourceFile)
|
||||
: CompilationUnitCreator.createFromContent(sourceContent);
|
||||
|
||||
CompilationUnit cu;
|
||||
if (cur == null) {
|
||||
return null;
|
||||
} else if (cur.getProblems() != null) {
|
||||
return null;
|
||||
} else {
|
||||
cu = cur.getCompilationUnit();
|
||||
}
|
||||
|
||||
SourceClass clazz = new SourceClass();
|
||||
Cache.getInstance().getClasses().put(targetClass, clazz);
|
||||
|
||||
Optional<PackageDeclaration> packageDeclaration =
|
||||
cu.getPackageDeclaration();
|
||||
if (packageDeclaration.isPresent()) {
|
||||
clazz.setPackage(packageDeclaration.get().getNameAsString());
|
||||
}
|
||||
|
||||
Optional<Position> beginning = cu.getBegin();
|
||||
Optional<Position> ending = cu.getEnd();
|
||||
if (beginning.isPresent() && ending.isPresent()) {
|
||||
clazz.setRegion(
|
||||
beginning.get().line,
|
||||
beginning.get().column,
|
||||
ending.get().line,
|
||||
ending.get().column);
|
||||
}
|
||||
|
||||
if (cu.getImports() != null) {
|
||||
for (ImportDeclaration id : cu.getImports()) {
|
||||
clazz.addImport(
|
||||
new ClassImport(
|
||||
id.getName().toString(),
|
||||
id.isStatic(),
|
||||
id.isAsterisk()));
|
||||
}
|
||||
}
|
||||
|
||||
ClassOrInterfaceVisitor coiVisitor =
|
||||
new ClassOrInterfaceVisitor(clazz);
|
||||
coiVisitor.visit(cu, null);
|
||||
clazz = coiVisitor.getClazz();
|
||||
|
||||
ClassVisitor visitor = new ClassVisitor(clazz);
|
||||
visitChildren(parentClass.getChildNodes(), visitor);
|
||||
clazz = visitor.getClazz();
|
||||
|
||||
List<String> impls = new ArrayList<>();
|
||||
if (clazz.getSuperclass() != null) {
|
||||
impls.add(clazz.getSuperclass());
|
||||
}
|
||||
|
||||
impls.addAll(clazz.getInterfaces());
|
||||
for (String impl : impls) {
|
||||
ClassSearcher seacher = new ClassSearcher();
|
||||
if (seacher.find(impl, sources)) {
|
||||
SourceClass implClass = seacher.getReader().read(impl);
|
||||
if (implClass != null) {
|
||||
clazz.addLinkedClass(implClass);
|
||||
for (ClassConstructor c : implClass.getConstructors()) {
|
||||
|
||||
if (implClass.getName().equals("java.lang.Object")) {
|
||||
continue;
|
||||
}
|
||||
c.setDeclaration(
|
||||
c.getDeclaration().replace(
|
||||
implClass.getName(), clazz.getName()));
|
||||
c.setDeclaration(c.getDeclaration()
|
||||
.replace(
|
||||
implClass.getSimpleName(),
|
||||
clazz.getSimpleName()));
|
||||
clazz.addConstructor(c);
|
||||
}
|
||||
for (ClassMethod method : implClass.getMethods()) {
|
||||
clazz.addMethod(method);
|
||||
}
|
||||
for (ClassField field : implClass.getFields()) {
|
||||
clazz.addField(field);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return clazz;
|
||||
}
|
||||
|
||||
private void visitChildren(List<Node> nodes, ClassVisitor visitor) {
|
||||
for (Node n : nodes) {
|
||||
if (n instanceof FieldDeclaration) {
|
||||
visitor.visit((FieldDeclaration) n, null);
|
||||
} else if (n instanceof MethodDeclaration) {
|
||||
visitor.visit((MethodDeclaration) n, null);
|
||||
} else if (n instanceof ConstructorDeclaration) {
|
||||
visitor.visit((ConstructorDeclaration) n, null);
|
||||
} else if (n instanceof ClassOrInterfaceDeclaration) {
|
||||
visitor.visit((ClassOrInterfaceDeclaration) n, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setExtendedAndInterfaceTypes(
|
||||
SourceClass clazz, ClassOrInterfaceDeclaration n) {
|
||||
NodeList<ClassOrInterfaceType> extendedTypes = n.getExtendedTypes();
|
||||
if (extendedTypes != null && extendedTypes.size() > 0) {
|
||||
String className = extendedTypes.get(0).getNameAsString();
|
||||
clazz.setSuperclass(
|
||||
new FqnSearcher(sources).getFqn(clazz, className));
|
||||
} else {
|
||||
clazz.setSuperclass("java.lang.Object");
|
||||
addConstructorIfNotEmpty(clazz);
|
||||
}
|
||||
|
||||
NodeList<ClassOrInterfaceType> implementedTypes =
|
||||
n.getImplementedTypes();
|
||||
if (implementedTypes != null) {
|
||||
for (ClassOrInterfaceType iface : implementedTypes) {
|
||||
clazz.addInterface(
|
||||
new FqnSearcher(sources).getFqn(
|
||||
clazz, iface.getNameAsString()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class ClassOrInterfaceVisitor extends VoidVisitorAdapter<Object> {
|
||||
|
||||
private SourceClass clazz;
|
||||
|
||||
public ClassOrInterfaceVisitor(SourceClass clazz) {
|
||||
this.clazz = clazz;
|
||||
}
|
||||
|
||||
public SourceClass getClazz() {
|
||||
return clazz;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(ClassOrInterfaceDeclaration n, Object arg) {
|
||||
parentClass = n;
|
||||
clazz.setName(n.getNameAsString());
|
||||
clazz.setModifiers(n.getModifiers());
|
||||
clazz.setIsInterface(n.isInterface());
|
||||
|
||||
Optional<Position> beginning = n.getBegin();
|
||||
Optional<Position> ending = n.getEnd();
|
||||
if (beginning.isPresent() && ending.isPresent()) {
|
||||
clazz.setRegion(
|
||||
beginning.get().line,
|
||||
beginning.get().column,
|
||||
ending.get().line,
|
||||
ending.get().column);
|
||||
}
|
||||
|
||||
setExtendedAndInterfaceTypes(clazz, n);
|
||||
}
|
||||
}
|
||||
|
||||
private void addConstructorIfNotEmpty(SourceClass clazz) {
|
||||
if (clazz.getConstructors().isEmpty()) {
|
||||
ClassConstructor ctor = new ClassConstructor();
|
||||
ctor.setDeclaration(
|
||||
String.format("public %s()", clazz.getName()));
|
||||
ctor.setModifiers(EnumSet.of(Modifier.PUBLIC));
|
||||
clazz.addConstructor(ctor);
|
||||
}
|
||||
}
|
||||
|
||||
private class ClassVisitor extends VoidVisitorAdapter<Object> {
|
||||
|
||||
private SourceClass clazz;
|
||||
|
||||
public ClassVisitor(SourceClass clazz) {
|
||||
this.clazz = clazz;
|
||||
}
|
||||
|
||||
public SourceClass getClazz() {
|
||||
return clazz;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(ConstructorDeclaration n, Object arg) {
|
||||
ClassConstructor constructor = new ClassConstructor();
|
||||
constructor.setDeclaration(n.getDeclarationAsString());
|
||||
constructor.setModifiers(n.getModifiers());
|
||||
if (n.getTypeParameters() != null) {
|
||||
for (TypeParameter parameter : n.getTypeParameters()) {
|
||||
constructor.addTypeParameter(
|
||||
new ClassTypeParameter(parameter.getNameAsString()));
|
||||
}
|
||||
}
|
||||
clazz.addConstructor(constructor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(MethodDeclaration n, Object arg) {
|
||||
ClassMethod method = new ClassMethod();
|
||||
method.setName(n.getNameAsString());
|
||||
method.setModifiers(n.getModifiers());
|
||||
method.setDeclaration(n.getDeclarationAsString());
|
||||
|
||||
n.getAnnotationByClass(Deprecated.class)
|
||||
.ifPresent(c -> method.setDeprecated(true));
|
||||
|
||||
String className = n.getType().toString();
|
||||
method.setTypeName(
|
||||
new FqnSearcher(sources).getFqn(clazz, className));
|
||||
|
||||
if (n.getTypeParameters() != null) {
|
||||
for (TypeParameter parameter : n.getTypeParameters()) {
|
||||
method.addTypeParameter(
|
||||
new ClassTypeParameter(
|
||||
parameter.getNameAsString()));
|
||||
}
|
||||
}
|
||||
|
||||
if (n.getParameters() != null) {
|
||||
for (Parameter parameter : n.getParameters()) {
|
||||
method.addTypeParameter(
|
||||
new ClassTypeParameter(
|
||||
parameter.getType().toString(
|
||||
ClassNamesFetcher.withoutComments())));
|
||||
}
|
||||
}
|
||||
clazz.addMethod(method);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(FieldDeclaration n, Object arg) {
|
||||
for (VariableDeclarator v : n.getVariables()) {
|
||||
ClassField field = new ClassField();
|
||||
field.setName(v.getNameAsString());
|
||||
field.setModifiers(n.getModifiers());
|
||||
|
||||
String className = n.getElementType().asString();
|
||||
field.setTypeName(
|
||||
new FqnSearcher(sources).getFqn(clazz, className));
|
||||
|
||||
clazz.addField(field);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(ClassOrInterfaceDeclaration n, Object arg) {
|
||||
SourceClass clazz = new SourceClass();
|
||||
clazz.setName(this.clazz.getSimpleName() + "$" + n.getName());
|
||||
clazz.setModifiers(n.getModifiers());
|
||||
clazz.setIsInterface(n.isInterface());
|
||||
|
||||
Optional<Position> beginning = n.getBegin();
|
||||
Optional<Position> ending = n.getEnd();
|
||||
if (beginning.isPresent() && ending.isPresent()) {
|
||||
clazz.setRegion(
|
||||
beginning.get().line,
|
||||
beginning.get().column,
|
||||
ending.get().line,
|
||||
ending.get().column);
|
||||
}
|
||||
|
||||
setExtendedAndInterfaceTypes(clazz, n);
|
||||
|
||||
clazz.setPackage(this.clazz.getPackage());
|
||||
|
||||
ClassVisitor visitor = new ClassVisitor(clazz);
|
||||
visitChildren(n.getChildNodes(), visitor);
|
||||
this.clazz.addNestedClass(clazz.getName());
|
||||
this.clazz.addLinkedClass(clazz);
|
||||
|
||||
Cache.getInstance().getClasses().put(clazz.getName(), clazz);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
391
bundle/vim-javacomplete2/libs/javavi/src/main/java/kg/ash/javavi/readers/Reflection.java
vendored
Normal file
391
bundle/vim-javacomplete2/libs/javavi/src/main/java/kg/ash/javavi/readers/Reflection.java
vendored
Normal file
@ -0,0 +1,391 @@
|
||||
package kg.ash.javavi.readers;
|
||||
|
||||
import com.github.javaparser.ast.Modifier;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import kg.ash.javavi.apache.logging.log4j.LogManager;
|
||||
import kg.ash.javavi.apache.logging.log4j.Logger;
|
||||
|
||||
import kg.ash.javavi.TargetParser;
|
||||
import kg.ash.javavi.cache.Cache;
|
||||
import kg.ash.javavi.clazz.ClassConstructor;
|
||||
import kg.ash.javavi.clazz.ClassField;
|
||||
import kg.ash.javavi.clazz.ClassMethod;
|
||||
import kg.ash.javavi.clazz.ClassTypeParameter;
|
||||
import kg.ash.javavi.clazz.SourceClass;
|
||||
import kg.ash.javavi.searchers.ClassNameMap;
|
||||
import kg.ash.javavi.searchers.ClassSearcher;
|
||||
|
||||
public class Reflection implements ClassReader {
|
||||
|
||||
public static final Logger logger = LogManager.getLogger();
|
||||
|
||||
private String sources;
|
||||
private List<String> typeArguments = null;
|
||||
|
||||
private List<String> knownClasses = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public ClassReader setTypeArguments(List<String> typeArguments) {
|
||||
this.typeArguments = typeArguments;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClassReader addKnown(List knownClasses) {
|
||||
this.knownClasses.addAll(knownClasses);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Reflection(String sources) {
|
||||
this.sources = sources;
|
||||
}
|
||||
|
||||
public static boolean exist(String name) {
|
||||
try {
|
||||
Class.forName(name);
|
||||
return true;
|
||||
} catch (Exception | NoClassDefFoundError ex) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private String getNameWithArguments(String name) {
|
||||
if (typeArguments != null && !typeArguments.isEmpty()) {
|
||||
name += "<" + String.join(",", typeArguments) + ">";
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SourceClass read(String name) {
|
||||
String nameWithArguments = getNameWithArguments(name);
|
||||
|
||||
logger.debug("read class with reflections: {}", nameWithArguments);
|
||||
|
||||
HashMap<String, SourceClass> cachedClasses =
|
||||
Cache.getInstance().getClasses();
|
||||
if (cachedClasses.containsKey(nameWithArguments)) {
|
||||
return cachedClasses.get(nameWithArguments);
|
||||
}
|
||||
|
||||
SourceClass result = loadFromCompiledSource(name);
|
||||
if (result == null) {
|
||||
result = lookup(name);
|
||||
}
|
||||
if (result == null && !name.startsWith("java.lang.")) {
|
||||
result = lookup("java.lang." + name);
|
||||
}
|
||||
|
||||
String binaryName = name;
|
||||
while (result == null) {
|
||||
int lastDotPos = binaryName.lastIndexOf('.');
|
||||
if (lastDotPos == -1) {
|
||||
break;
|
||||
}
|
||||
|
||||
binaryName = String.format("%s$%s",
|
||||
binaryName.substring(0, lastDotPos),
|
||||
binaryName.substring(
|
||||
lastDotPos + 1, binaryName.length()));
|
||||
|
||||
result = lookup(binaryName);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private SourceClass loadFromCompiledSource(String name) {
|
||||
String last = name.substring(name.lastIndexOf(".") + 1);
|
||||
ClassNameMap classMap = (ClassNameMap) Cache.getInstance()
|
||||
.getClassPackages()
|
||||
.get(getNameWithArguments(last));
|
||||
if (classMap != null) {
|
||||
if (classMap.getClassFile() != null
|
||||
&& classMap.getJavaFile() != null) {
|
||||
logger.debug(
|
||||
"loading class from compiled source: {}", classMap);
|
||||
|
||||
ClassLoader parentClassLoader =
|
||||
FileClassLoader.class.getClassLoader();
|
||||
FileClassLoader fileClassLoader =
|
||||
new FileClassLoader(parentClassLoader,
|
||||
classMap.getClassFile());
|
||||
Class clazz = fileClassLoader.loadClass(name);
|
||||
if (clazz != null) {
|
||||
try {
|
||||
return getSourceClass(clazz);
|
||||
} catch (Throwable t) {
|
||||
logger.error(t, t);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private SourceClass lookup(String className) {
|
||||
try {
|
||||
logger.debug("lookup class name: {}", className);
|
||||
|
||||
Class clazz = Class.forName(className);
|
||||
return getSourceClass(clazz);
|
||||
} catch (Exception ex) {
|
||||
logger.debug(String.format("error lookup %s", className), ex);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private String popTypeArgument(List<String> arguments) {
|
||||
if (!arguments.isEmpty()) {
|
||||
String argument = arguments.get(0);
|
||||
arguments.remove(0);
|
||||
return argument;
|
||||
}
|
||||
|
||||
return "java.lang.Object";
|
||||
}
|
||||
|
||||
private String getGenericName(
|
||||
TreeMap<String, String> taa, String genericName) {
|
||||
|
||||
if (typeArguments == null || typeArguments.isEmpty()) {
|
||||
return genericName;
|
||||
}
|
||||
for (Entry<String, String> kv : taa.entrySet()) {
|
||||
genericName = genericName.replaceAll(
|
||||
String.format("\\b%s\\b", kv.getKey()),
|
||||
Matcher.quoteReplacement(kv.getValue()));
|
||||
}
|
||||
return genericName;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public SourceClass getSourceClass(Class cls) {
|
||||
logger.debug("class loaded: {}", cls.getName());
|
||||
|
||||
String name = cls.getName();
|
||||
knownClasses.add(name);
|
||||
if (name.contains(".")) {
|
||||
name = name.substring(name.lastIndexOf(".") + 1);
|
||||
}
|
||||
|
||||
SourceClass clazz = new SourceClass();
|
||||
clazz.setName(name);
|
||||
clazz.setModifiers(EnumSetModifierFromInt(cls.getModifiers()));
|
||||
clazz.setIsInterface(cls.isInterface());
|
||||
if (cls.getPackage() != null) {
|
||||
clazz.setPackage(cls.getPackage().getName());
|
||||
}
|
||||
|
||||
TreeMap<String, String> typeArgumentsMap = new TreeMap<>();
|
||||
if (typeArguments != null && !typeArguments.isEmpty()) {
|
||||
List<String> arguments = new ArrayList<>(typeArguments);
|
||||
Stream.of(cls.getTypeParameters()).forEachOrdered(type -> {
|
||||
typeArgumentsMap.put(
|
||||
type.getTypeName(), popTypeArgument(arguments));
|
||||
clazz.addTypeArgument(
|
||||
typeArgumentsMap.get(type.getTypeName()));
|
||||
});
|
||||
}
|
||||
|
||||
List<Class> linked = new ArrayList<>();
|
||||
Stream.of(cls.getDeclaredClasses()).forEach(c -> {
|
||||
linked.add(c);
|
||||
clazz.addNestedClass(c.getName());
|
||||
});
|
||||
|
||||
Optional.ofNullable(cls.getSuperclass()).ifPresent(c -> {
|
||||
linked.add(c);
|
||||
clazz.setSuperclass(c.getName());
|
||||
});
|
||||
|
||||
Stream.of(cls.getGenericInterfaces())
|
||||
.map(i -> getGenericName(
|
||||
typeArgumentsMap, i.getTypeName()))
|
||||
.forEach(clazz::addInterface);
|
||||
|
||||
ClassSearcher seacher = new ClassSearcher();
|
||||
clazz.getInterfaces().stream().forEach(i -> {
|
||||
TargetParser parser = new TargetParser(sources);
|
||||
String ifaceClassName = parser.parse(i);
|
||||
if (!knownClasses.contains(ifaceClassName) && seacher.find(ifaceClassName, sources)) {
|
||||
clazz.addLinkedClass(
|
||||
seacher.getReader().addKnown(knownClasses).setTypeArguments(
|
||||
parser.getTypeArguments()).read(ifaceClassName));
|
||||
}
|
||||
});
|
||||
|
||||
linked.stream()
|
||||
.filter(c -> !knownClasses.contains(c.getName()))
|
||||
.map(this::getSourceClass)
|
||||
.forEach(clazz::addLinkedClass);
|
||||
|
||||
Stream.of(cls.getConstructors()).forEachOrdered(ctor -> {
|
||||
ClassConstructor constructor = new ClassConstructor();
|
||||
|
||||
String genericDeclaration =
|
||||
getGenericName(typeArgumentsMap,
|
||||
ctor.toGenericString());
|
||||
constructor.setDeclaration(genericDeclaration);
|
||||
constructor.setModifiers(
|
||||
EnumSetModifierFromInt(ctor.getModifiers()));
|
||||
|
||||
Stream.of(ctor.getGenericParameterTypes())
|
||||
.map(t -> getGenericName(
|
||||
typeArgumentsMap, t.getTypeName()))
|
||||
.forEach(t -> constructor.addTypeParameter(
|
||||
new ClassTypeParameter(t)));
|
||||
|
||||
clazz.addConstructor(constructor);
|
||||
});
|
||||
|
||||
Set<Field> fieldsSet = new HashSet<>();
|
||||
fieldsSet.addAll(Arrays.asList(cls.getDeclaredFields()));
|
||||
fieldsSet.addAll(Arrays.asList(cls.getFields()));
|
||||
fieldsSet.forEach(f -> {
|
||||
ClassField field = new ClassField();
|
||||
field.setName(f.getName());
|
||||
field.setModifiers(EnumSetModifierFromInt(f.getModifiers()));
|
||||
|
||||
String genericType = getGenericName(typeArgumentsMap,
|
||||
f.getGenericType().getTypeName());
|
||||
field.setTypeName(genericType);
|
||||
|
||||
clazz.addField(field);
|
||||
});
|
||||
|
||||
Set<Method> methodsSet = new HashSet<>();
|
||||
methodsSet.addAll(Arrays.asList(cls.getDeclaredMethods()));
|
||||
methodsSet.addAll(Arrays.asList(cls.getMethods()));
|
||||
methodsSet.forEach(m -> {
|
||||
if (!m.getDeclaringClass().getName().equals(cls.getName())) {
|
||||
return;
|
||||
}
|
||||
ClassMethod method = new ClassMethod();
|
||||
if (m.getAnnotationsByType(Deprecated.class).length > 0) {
|
||||
method.setDeprecated(true);
|
||||
}
|
||||
method.setName(m.getName());
|
||||
method.setModifiers(EnumSetModifierFromInt(m.getModifiers()));
|
||||
|
||||
String genericDeclaration = getGenericName(
|
||||
typeArgumentsMap, m.toGenericString());
|
||||
method.setDeclaration(genericDeclaration);
|
||||
|
||||
String genericReturnType = getGenericName(
|
||||
typeArgumentsMap,
|
||||
m.getGenericReturnType().getTypeName());
|
||||
method.setTypeName(genericReturnType);
|
||||
|
||||
Type[] parameterTypes = m.getGenericParameterTypes();
|
||||
Stream.of(parameterTypes)
|
||||
.map(t -> getGenericName(typeArgumentsMap, t.getTypeName()))
|
||||
.forEachOrdered(
|
||||
t -> method.addTypeParameter(
|
||||
new ClassTypeParameter(t)));
|
||||
|
||||
clazz.addMethod(method);
|
||||
});
|
||||
|
||||
Cache.getInstance().getClasses().put(
|
||||
getNameWithArguments(cls.getName()), clazz);
|
||||
return clazz;
|
||||
}
|
||||
|
||||
public static EnumSet<Modifier> EnumSetModifierFromInt(int i) {
|
||||
EnumSet<Modifier> set = EnumSet.noneOf(Modifier.class);
|
||||
|
||||
if (java.lang.reflect.Modifier.isPublic(i)) {
|
||||
set.add(Modifier.PUBLIC);
|
||||
}
|
||||
if (java.lang.reflect.Modifier.isPrivate(i)) {
|
||||
set.add(Modifier.PRIVATE);
|
||||
}
|
||||
if (java.lang.reflect.Modifier.isProtected(i)) {
|
||||
set.add(Modifier.PROTECTED);
|
||||
}
|
||||
if (java.lang.reflect.Modifier.isStatic(i)) {
|
||||
set.add(Modifier.STATIC);
|
||||
}
|
||||
if (java.lang.reflect.Modifier.isFinal(i)) {
|
||||
set.add(Modifier.FINAL);
|
||||
}
|
||||
if (java.lang.reflect.Modifier.isSynchronized(i)) {
|
||||
set.add(Modifier.SYNCHRONIZED);
|
||||
}
|
||||
if (java.lang.reflect.Modifier.isVolatile(i)) {
|
||||
set.add(Modifier.VOLATILE);
|
||||
}
|
||||
if (java.lang.reflect.Modifier.isTransient(i)) {
|
||||
set.add(Modifier.TRANSIENT);
|
||||
}
|
||||
if (java.lang.reflect.Modifier.isNative(i)) {
|
||||
set.add(Modifier.NATIVE);
|
||||
}
|
||||
if (java.lang.reflect.Modifier.isAbstract(i)) {
|
||||
set.add(Modifier.ABSTRACT);
|
||||
}
|
||||
if (java.lang.reflect.Modifier.isStrict(i)) {
|
||||
set.add(Modifier.STRICTFP);
|
||||
}
|
||||
|
||||
return set;
|
||||
}
|
||||
|
||||
public static int EnumSetModifierToInt(EnumSet<Modifier> set) {
|
||||
int mod = 0;
|
||||
|
||||
if (set.contains(Modifier.PUBLIC)) {
|
||||
mod |= java.lang.reflect.Modifier.PUBLIC;
|
||||
}
|
||||
if (set.contains(Modifier.PRIVATE)) {
|
||||
mod |= java.lang.reflect.Modifier.PRIVATE;
|
||||
}
|
||||
if (set.contains(Modifier.PROTECTED)) {
|
||||
mod |= java.lang.reflect.Modifier.PROTECTED;
|
||||
}
|
||||
if (set.contains(Modifier.STATIC)) {
|
||||
mod |= java.lang.reflect.Modifier.STATIC;
|
||||
}
|
||||
if (set.contains(Modifier.FINAL)) {
|
||||
mod |= java.lang.reflect.Modifier.FINAL;
|
||||
}
|
||||
if (set.contains(Modifier.SYNCHRONIZED)) {
|
||||
mod |= java.lang.reflect.Modifier.SYNCHRONIZED;
|
||||
}
|
||||
if (set.contains(Modifier.VOLATILE)) {
|
||||
mod |= java.lang.reflect.Modifier.VOLATILE;
|
||||
}
|
||||
if (set.contains(Modifier.TRANSIENT)) {
|
||||
mod |= java.lang.reflect.Modifier.TRANSIENT;
|
||||
}
|
||||
if (set.contains(Modifier.NATIVE)) {
|
||||
mod |= java.lang.reflect.Modifier.NATIVE;
|
||||
}
|
||||
if (set.contains(Modifier.ABSTRACT)) {
|
||||
mod |= java.lang.reflect.Modifier.ABSTRACT;
|
||||
}
|
||||
if (set.contains(Modifier.STRICTFP)) {
|
||||
mod |= java.lang.reflect.Modifier.STRICT;
|
||||
}
|
||||
|
||||
return mod;
|
||||
}
|
||||
}
|
@ -0,0 +1,250 @@
|
||||
package kg.ash.javavi.readers.source;
|
||||
|
||||
import com.github.javaparser.ast.CompilationUnit;
|
||||
import com.github.javaparser.ast.ImportDeclaration;
|
||||
import com.github.javaparser.ast.Node;
|
||||
import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
|
||||
import com.github.javaparser.ast.body.ConstructorDeclaration;
|
||||
import com.github.javaparser.ast.body.FieldDeclaration;
|
||||
import com.github.javaparser.ast.body.MethodDeclaration;
|
||||
import com.github.javaparser.ast.body.Parameter;
|
||||
import com.github.javaparser.ast.expr.AnnotationExpr;
|
||||
import com.github.javaparser.ast.expr.Expression;
|
||||
import com.github.javaparser.ast.expr.FieldAccessExpr;
|
||||
import com.github.javaparser.ast.expr.MethodCallExpr;
|
||||
import com.github.javaparser.ast.expr.Name;
|
||||
import com.github.javaparser.ast.expr.NameExpr;
|
||||
import com.github.javaparser.ast.stmt.BlockStmt;
|
||||
import com.github.javaparser.ast.type.ClassOrInterfaceType;
|
||||
import com.github.javaparser.ast.type.Type;
|
||||
import com.github.javaparser.ast.type.UnionType;
|
||||
import com.github.javaparser.ast.visitor.TreeVisitor;
|
||||
import com.github.javaparser.ast.visitor.VoidVisitorAdapter;
|
||||
import com.github.javaparser.printer.PrettyPrinterConfiguration;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class ClassNamesFetcher {
|
||||
|
||||
private final CompilationUnit compilationUnit;
|
||||
private final Set<String> resultList = new HashSet<>();
|
||||
private final Set<String> declarationList = new HashSet<>();
|
||||
private List<String> staticImportsList = new ArrayList<>();
|
||||
|
||||
public static PrettyPrinterConfiguration withoutComments() {
|
||||
PrettyPrinterConfiguration pp = new PrettyPrinterConfiguration();
|
||||
pp.setPrintComments(false);
|
||||
return pp;
|
||||
}
|
||||
|
||||
public ClassNamesFetcher(CompilationUnit compilationUnit) {
|
||||
this.compilationUnit = compilationUnit;
|
||||
for (ImportDeclaration id : compilationUnit.getImports()) {
|
||||
if (id.isStatic()) {
|
||||
String name = id.getName().toString();
|
||||
staticImportsList.add(
|
||||
name.substring(
|
||||
name.lastIndexOf(".") + 1, name.length()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public Set<String> getNames() {
|
||||
List<VoidVisitorAdapter> adapters = new ArrayList<>();
|
||||
adapters.add(new ClassTypeVisitor());
|
||||
adapters.add(new TypesVisitor());
|
||||
adapters.add(new AnnotationsVisitor());
|
||||
adapters.forEach(a -> a.visit(compilationUnit, null));
|
||||
|
||||
return resultList;
|
||||
}
|
||||
|
||||
public Set<String> getDeclarationList() {
|
||||
if (resultList.isEmpty()) {
|
||||
getNames();
|
||||
}
|
||||
return declarationList;
|
||||
}
|
||||
|
||||
private class ClassTypeVisitor extends VoidVisitorAdapter<Object> {
|
||||
|
||||
@Override
|
||||
public void visit(ClassOrInterfaceDeclaration type, Object arg) {
|
||||
new DeepVisitor(this, arg).visitBreadthFirst(type);
|
||||
if (type.getAnnotations() != null) {
|
||||
for (AnnotationExpr expr : type.getAnnotations()) {
|
||||
resultList.add(expr.getNameAsString());
|
||||
List<Node> children = expr.getChildNodes();
|
||||
for (Node node : children.subList(1, children.size())) {
|
||||
new DeepVisitor(this, arg).visitBreadthFirst(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class AnnotationsVisitor extends VoidVisitorAdapter<Object> {
|
||||
|
||||
private void addAnnotations(
|
||||
List<AnnotationExpr> annotations, Object arg) {
|
||||
if (annotations != null) {
|
||||
for (AnnotationExpr expr : annotations) {
|
||||
resultList.add(expr.getNameAsString());
|
||||
List<Node> children = expr.getChildNodes();
|
||||
for (Node node : children.subList(1, children.size())) {
|
||||
new DeepVisitor(this, arg).visitBreadthFirst(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(ConstructorDeclaration type, Object arg) {
|
||||
addAnnotations(type.getAnnotations(), arg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(FieldDeclaration type, Object arg) {
|
||||
addAnnotations(type.getAnnotations(), arg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(MethodDeclaration type, Object arg) {
|
||||
addAnnotations(type.getAnnotations(), arg);
|
||||
if (type.getParameters() != null) {
|
||||
for (Parameter param : type.getParameters()) {
|
||||
addAnnotations(param.getAnnotations(), arg);
|
||||
}
|
||||
}
|
||||
|
||||
if (type.getThrownExceptions() != null) {
|
||||
for (Type expr : type.getThrownExceptions()) {
|
||||
resultList.add(expr.toString(withoutComments()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class TypesVisitor extends VoidVisitorAdapter<Object> {
|
||||
|
||||
@Override
|
||||
public void visit(BlockStmt type, Object arg) {
|
||||
new DeepVisitor(this, arg).visitBreadthFirst(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(FieldAccessExpr type, Object arg) {
|
||||
addStatic(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(MethodCallExpr type, Object arg) {
|
||||
addStatic(type);
|
||||
}
|
||||
|
||||
private void addStatic(Expression type) {
|
||||
if (type.getChildNodes() != null &&
|
||||
type.getChildNodes().size() > 0) {
|
||||
String name = type.getChildNodes().
|
||||
get(0).toString(withoutComments());
|
||||
if (!name.contains(".")) {
|
||||
resultList.add(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(ClassOrInterfaceType type, Object arg) {
|
||||
String name = type.getNameAsString();
|
||||
String fullName = type.toString(withoutComments());
|
||||
if (!fullName.startsWith(name)) {
|
||||
if (!type.getChildNodes().isEmpty()) {
|
||||
name = type.getChildNodes().
|
||||
get(0).toString(withoutComments());
|
||||
}
|
||||
}
|
||||
if (name.contains(".")) {
|
||||
name = name.split("\\.")[0];
|
||||
}
|
||||
resultList.add(name);
|
||||
if (type.getTypeArguments().isPresent()) {
|
||||
for (Type t : type.getTypeArguments().get()) {
|
||||
String typeName = t.toString(withoutComments());
|
||||
if (typeName.contains(".")) {
|
||||
typeName = typeName.split("\\.")[0];
|
||||
}
|
||||
resultList.add(typeName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class DeepVisitor extends TreeVisitor {
|
||||
|
||||
private VoidVisitorAdapter<Object> adapter;
|
||||
private Object arg;
|
||||
|
||||
public DeepVisitor(VoidVisitorAdapter<Object> adapter, Object arg) {
|
||||
this.adapter = adapter;
|
||||
this.arg = arg;
|
||||
}
|
||||
|
||||
public void process(Node node) {
|
||||
if (node instanceof ClassOrInterfaceType) {
|
||||
adapter.visit((ClassOrInterfaceType) node, arg);
|
||||
} else if (node instanceof UnionType) {
|
||||
((UnionType) node).getElements()
|
||||
.forEach(
|
||||
t -> resultList.add(
|
||||
t.toString(withoutComments())));
|
||||
} else if (node instanceof MethodCallExpr) {
|
||||
MethodCallExpr methodCall = ((MethodCallExpr) node);
|
||||
String name = methodCall.getNameAsString();
|
||||
if (staticImportsList.contains(name)) {
|
||||
resultList.add(name);
|
||||
}
|
||||
} else if (node instanceof NameExpr) {
|
||||
// javaparser has no difference on 'method call' expression,
|
||||
// so class name with static method call look the same as
|
||||
// object method call. that's why we check here for usual
|
||||
// class name type with upper case letter at the beginning.
|
||||
// it can miss some unusual class names with lower case at
|
||||
// the beginning.
|
||||
NameExpr nameExpr = (NameExpr) node;
|
||||
String parent = "";
|
||||
if (nameExpr.getParentNode().isPresent()) {
|
||||
parent = nameExpr.getParentNode().
|
||||
get().toString(withoutComments());
|
||||
}
|
||||
String name = nameExpr.getNameAsString();
|
||||
if (name != null) {
|
||||
if (!parent.startsWith("@") &&
|
||||
!parent.equals(name) &&
|
||||
parent.endsWith(name)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (name.matches("^[A-Z][A-Za-z0-9_]*")) {
|
||||
resultList.add(name);
|
||||
}
|
||||
}
|
||||
} else if (node instanceof Name) {
|
||||
String name = node.toString(withoutComments());
|
||||
|
||||
if (name.matches("^[A-Z][A-Za-z0-9_]*")) {
|
||||
resultList.add(name);
|
||||
}
|
||||
} else if (node instanceof ClassOrInterfaceDeclaration) {
|
||||
ClassOrInterfaceDeclaration declaration =
|
||||
(ClassOrInterfaceDeclaration) node;
|
||||
declarationList.add(
|
||||
declaration.getName().toString(
|
||||
withoutComments()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
package kg.ash.javavi.readers.source;
|
||||
|
||||
import com.github.javaparser.JavaParser;
|
||||
import com.github.javaparser.ParseProblemException;
|
||||
import com.github.javaparser.TokenMgrException;
|
||||
import com.github.javaparser.ast.CompilationUnit;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileReader;
|
||||
import java.io.StringReader;
|
||||
|
||||
import kg.ash.javavi.apache.logging.log4j.LogManager;
|
||||
import kg.ash.javavi.apache.logging.log4j.Logger;
|
||||
|
||||
public class CompilationUnitCreator {
|
||||
|
||||
public static final Logger logger = LogManager.getLogger();
|
||||
|
||||
public static CompilationUnitResult createFromFile(String fileName) {
|
||||
try {
|
||||
return new CompilationUnitResult(
|
||||
JavaParser.parse(new FileReader(fileName)));
|
||||
} catch (TokenMgrException | FileNotFoundException e) {
|
||||
logger.error(e, e);
|
||||
return null;
|
||||
} catch (ParseProblemException ex) {
|
||||
logger.debug("parse error", ex);
|
||||
return new CompilationUnitResult(
|
||||
ex.getProblems());
|
||||
}
|
||||
}
|
||||
|
||||
public static CompilationUnitResult createFromContent(String content) {
|
||||
try {
|
||||
return new CompilationUnitResult(
|
||||
JavaParser.parse(new StringReader(content)));
|
||||
} catch (TokenMgrException ex) {
|
||||
logger.error(ex, ex);
|
||||
return null;
|
||||
} catch (ParseProblemException ex) {
|
||||
logger.debug("parse error", ex);
|
||||
return new CompilationUnitResult(
|
||||
ex.getProblems());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
package kg.ash.javavi.readers.source;
|
||||
|
||||
import com.github.javaparser.Problem;
|
||||
import com.github.javaparser.ast.CompilationUnit;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class CompilationUnitResult {
|
||||
|
||||
private CompilationUnit compilationUnit;
|
||||
private List<Problem> problems;
|
||||
|
||||
public CompilationUnitResult(CompilationUnit compilationUnit) {
|
||||
this.compilationUnit = compilationUnit;
|
||||
}
|
||||
|
||||
public CompilationUnitResult(List<Problem> problems) {
|
||||
this.problems = problems;
|
||||
}
|
||||
|
||||
public CompilationUnit getCompilationUnit() {
|
||||
return compilationUnit;
|
||||
}
|
||||
|
||||
public void setCompilationUnit(CompilationUnit compilationUnit) {
|
||||
this.compilationUnit = compilationUnit;
|
||||
}
|
||||
|
||||
public List<Problem> getProblems() {
|
||||
return problems;
|
||||
}
|
||||
|
||||
public void setProblems(List<Problem> problems) {
|
||||
this.problems = problems;
|
||||
}
|
||||
}
|
@ -0,0 +1,60 @@
|
||||
package kg.ash.javavi.searchers;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.FileSystems;
|
||||
import java.nio.file.FileVisitResult;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.PathMatcher;
|
||||
import java.nio.file.SimpleFileVisitor;
|
||||
import java.nio.file.attribute.BasicFileAttributes;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class ByExtensionVisitor extends SimpleFileVisitor<Path> {
|
||||
|
||||
private final List<PathMatcher> matchers = new ArrayList<>();
|
||||
private List<String> resultList = new ArrayList<>();
|
||||
|
||||
public ByExtensionVisitor(List<String> patterns) {
|
||||
matchers.addAll(getMatchers(patterns));
|
||||
}
|
||||
|
||||
private List<PathMatcher> getMatchers(List<String> patterns) {
|
||||
return patterns.stream()
|
||||
.map(p -> FileSystems.getDefault().getPathMatcher("glob:" + p))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public List<String> getResultList() {
|
||||
return resultList;
|
||||
}
|
||||
|
||||
private void find(Path file) {
|
||||
Path name = file.getFileName();
|
||||
if (name != null) {
|
||||
for (PathMatcher matcher : matchers) {
|
||||
if (matcher.matches(name)) {
|
||||
resultList.add(file.toFile().getPath().replace('\\', '/'));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
|
||||
find(file);
|
||||
return FileVisitResult.CONTINUE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
|
||||
return FileVisitResult.CONTINUE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileVisitResult visitFileFailed(Path file, IOException exc) {
|
||||
return FileVisitResult.CONTINUE;
|
||||
}
|
||||
}
|
38
bundle/vim-javacomplete2/libs/javavi/src/main/java/kg/ash/javavi/searchers/ClassNameMap.java
vendored
Normal file
38
bundle/vim-javacomplete2/libs/javavi/src/main/java/kg/ash/javavi/searchers/ClassNameMap.java
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
package kg.ash.javavi.searchers;
|
||||
|
||||
public class ClassNameMap extends JavaClassMap {
|
||||
|
||||
public String javaFile = null;
|
||||
public String classFile = null;
|
||||
|
||||
public ClassNameMap(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getType() {
|
||||
return JavaClassMap.TYPE_CLASS;
|
||||
}
|
||||
|
||||
public void setJavaFile(String javaFile) {
|
||||
this.javaFile = javaFile;
|
||||
}
|
||||
|
||||
public String getJavaFile() {
|
||||
return javaFile;
|
||||
}
|
||||
|
||||
public void setClassFile(String classFile) {
|
||||
this.classFile = classFile;
|
||||
}
|
||||
|
||||
public String getClassFile() {
|
||||
return classFile;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("name = %s, type = %d, javaFile = %s, classFile = %s", name, getType(),
|
||||
javaFile, classFile);
|
||||
}
|
||||
}
|
68
bundle/vim-javacomplete2/libs/javavi/src/main/java/kg/ash/javavi/searchers/ClassSearcher.java
vendored
Normal file
68
bundle/vim-javacomplete2/libs/javavi/src/main/java/kg/ash/javavi/searchers/ClassSearcher.java
vendored
Normal file
@ -0,0 +1,68 @@
|
||||
package kg.ash.javavi.searchers;
|
||||
|
||||
import kg.ash.javavi.apache.logging.log4j.LogManager;
|
||||
import kg.ash.javavi.apache.logging.log4j.Logger;
|
||||
import kg.ash.javavi.readers.ClassReader;
|
||||
import kg.ash.javavi.readers.Parser;
|
||||
import kg.ash.javavi.readers.Reflection;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
public class ClassSearcher {
|
||||
|
||||
public static final Logger logger = LogManager.getLogger();
|
||||
|
||||
private boolean isReflected = false;
|
||||
private String sources;
|
||||
private String sourceFile = null;
|
||||
|
||||
public boolean find(String targetClass, String sources) {
|
||||
logger.debug("executing search of \"{}\"", targetClass);
|
||||
|
||||
this.sources = sources;
|
||||
if (Reflection.exist(targetClass) || Reflection.exist("java.lang." + targetClass)) {
|
||||
isReflected = true;
|
||||
return true;
|
||||
} else {
|
||||
String[] sourcesArray = sources.split(File.pathSeparator);
|
||||
for (String sourceDir : sourcesArray) {
|
||||
if (targetClass.contains("$")) {
|
||||
targetClass = targetClass.split("\\$")[0];
|
||||
}
|
||||
targetClass = targetClass.replaceAll("[\\[\\]]", "");
|
||||
SourceFileVisitor visitor = new SourceFileVisitor(targetClass);
|
||||
try {
|
||||
Files.walkFileTree(Paths.get(sourceDir), visitor);
|
||||
|
||||
if (visitor.getTargetFile() != null) {
|
||||
sourceFile = visitor.getTargetFile().replace('\\', '/');
|
||||
return true;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
logger.error(e, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public ClassReader getReader() {
|
||||
if (isReflected()) {
|
||||
return new Reflection(sources);
|
||||
} else {
|
||||
return new Parser(sources, getSourceFile());
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isReflected() {
|
||||
return isReflected;
|
||||
}
|
||||
|
||||
public String getSourceFile() {
|
||||
return sourceFile;
|
||||
}
|
||||
}
|
@ -0,0 +1,69 @@
|
||||
package kg.ash.javavi.searchers;
|
||||
|
||||
import kg.ash.javavi.apache.logging.log4j.LogManager;
|
||||
import kg.ash.javavi.apache.logging.log4j.Logger;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class ClasspathCollector {
|
||||
|
||||
public static final Logger logger = LogManager.getLogger();
|
||||
|
||||
private ByExtensionVisitor finder = new ByExtensionVisitor(
|
||||
Arrays.asList("*.jar", "*.JAR", "*.zip", "*.ZIP", "*.class",
|
||||
"*.jmod", "classlist"));
|
||||
|
||||
private String pSep = File.pathSeparator;
|
||||
|
||||
public List<String> collectClassPath() {
|
||||
List<String> result = new ArrayList<>();
|
||||
|
||||
String extdirs = System.getProperty("java.ext.dirs");
|
||||
if (extdirs != null) {
|
||||
Stream.of(extdirs.split(pSep))
|
||||
.map(path -> addPathFromDir(path + File.separator))
|
||||
.forEach(result::addAll);
|
||||
}
|
||||
|
||||
result.addAll(addPathFromDir(System.getProperty("java.home")));
|
||||
|
||||
String classPath = System.getProperty("java.class.path");
|
||||
Stream.of(classPath.split(pSep))
|
||||
.filter(p -> p.length() >= 4).forEach(path -> {
|
||||
if (path.contains("vim-javacomplete2/libs/")) {
|
||||
return;
|
||||
}
|
||||
String ext = path.substring(path.length() - 4)
|
||||
.toLowerCase();
|
||||
if (ext.endsWith(".jar") || ext.endsWith(".zip")) {
|
||||
result.add(path);
|
||||
} else {
|
||||
result.addAll(addPathFromDir(path));
|
||||
}
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<String> addPathFromDir(String dirpath) {
|
||||
List<String> result = new ArrayList<>();
|
||||
File dir = new File(dirpath);
|
||||
if (dir.isDirectory()) {
|
||||
try {
|
||||
Files.walkFileTree(Paths.get(dir.getPath()), finder);
|
||||
result.addAll(finder.getResultList());
|
||||
} catch (IOException e) {
|
||||
logger.error(e, e);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
@ -0,0 +1,118 @@
|
||||
package kg.ash.javavi.searchers;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Enumeration;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Stream;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
import kg.ash.javavi.apache.logging.log4j.LogManager;
|
||||
import kg.ash.javavi.apache.logging.log4j.Logger;
|
||||
|
||||
public class ClasspathPackageSearcher implements PackageSeacherIFace {
|
||||
|
||||
public static final Logger logger = LogManager.getLogger();
|
||||
|
||||
public List<PackageEntry> loadEntries() {
|
||||
List<PackageEntry> result = new ArrayList<>();
|
||||
|
||||
List<String> knownPaths = new ArrayList<>();
|
||||
new ClasspathCollector().collectClassPath()
|
||||
.stream()
|
||||
.forEach(filePath -> {
|
||||
if (filePath.toLowerCase().endsWith(".class")) {
|
||||
String path = filePath.substring(
|
||||
0, filePath.length() - 6)
|
||||
.replaceAll("/", ".");
|
||||
String newPath = path.substring(
|
||||
0, path.lastIndexOf("."));
|
||||
String fileName = path.substring(
|
||||
path.lastIndexOf(".") + 1, path.length());
|
||||
Optional<PackageEntry> kp = knownPaths.parallelStream()
|
||||
.filter(s -> newPath.endsWith(s))
|
||||
.findFirst()
|
||||
.map(p -> p + File.separator + fileName + ".class")
|
||||
.map(p -> new PackageEntry(
|
||||
p,
|
||||
JavaClassMap.SOURCETYPE_CLASSPATH,
|
||||
filePath,
|
||||
PackageEntry.FILETYPE_CLASS));
|
||||
if (kp.isPresent()) {
|
||||
result.add(kp.get());
|
||||
return;
|
||||
}
|
||||
|
||||
String[] split = path.split("\\.");
|
||||
int j = split.length - 2;
|
||||
while (j > 0) {
|
||||
path = "";
|
||||
for (int i = j; i <= split.length - 2; i++) {
|
||||
path += split[i] + ".";
|
||||
}
|
||||
String pkg = getPackageByFile(path + fileName);
|
||||
if (pkg != null) {
|
||||
result.add(
|
||||
new PackageEntry(
|
||||
pkg + File.separator +
|
||||
fileName + ".class",
|
||||
JavaClassMap.SOURCETYPE_CLASSPATH,
|
||||
filePath,
|
||||
PackageEntry.FILETYPE_CLASS));
|
||||
knownPaths.add(pkg);
|
||||
break;
|
||||
} else {
|
||||
j--;
|
||||
}
|
||||
}
|
||||
} else if (filePath.endsWith("classlist")) {
|
||||
try (Stream<String> stream =
|
||||
Files.lines(Paths.get(filePath))) {
|
||||
stream.forEach(l -> {
|
||||
result.add(
|
||||
new PackageEntry(l + ".class",
|
||||
JavaClassMap.SOURCETYPE_CLASSPATH,
|
||||
filePath));
|
||||
});
|
||||
} catch (IOException ex) {
|
||||
logger.warn("error read classlist file", ex);
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
for (Enumeration entries =
|
||||
new ZipFile(filePath).entries();
|
||||
entries.hasMoreElements(); ) {
|
||||
String entry = entries.nextElement().toString();
|
||||
if (filePath.endsWith(".jmod")
|
||||
&& entry.startsWith("classes/")) {
|
||||
entry = entry.substring(8);
|
||||
}
|
||||
result.add(
|
||||
new PackageEntry(entry,
|
||||
JavaClassMap.SOURCETYPE_CLASSPATH,
|
||||
filePath));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error(e, e);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private String getPackageByFile(String path) {
|
||||
try {
|
||||
Class clazz = Class.forName(path);
|
||||
return clazz.getPackage().getName();
|
||||
} catch (ExceptionInInitializerError |
|
||||
ClassNotFoundException |
|
||||
NoClassDefFoundError ex) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
86
bundle/vim-javacomplete2/libs/javavi/src/main/java/kg/ash/javavi/searchers/FqnSearcher.java
vendored
Normal file
86
bundle/vim-javacomplete2/libs/javavi/src/main/java/kg/ash/javavi/searchers/FqnSearcher.java
vendored
Normal file
@ -0,0 +1,86 @@
|
||||
package kg.ash.javavi.searchers;
|
||||
|
||||
import kg.ash.javavi.TargetParser;
|
||||
import kg.ash.javavi.clazz.ClassImport;
|
||||
import kg.ash.javavi.clazz.SourceClass;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class FqnSearcher {
|
||||
|
||||
private String sources;
|
||||
|
||||
public FqnSearcher(String sources) {
|
||||
this.sources = sources;
|
||||
if (this.sources != null) {
|
||||
this.sources = this.sources.replace('\\', '/');
|
||||
}
|
||||
}
|
||||
|
||||
public String getFqn(SourceClass clazz, String name) {
|
||||
TargetParser targetParser = new TargetParser(sources);
|
||||
name = targetParser.parse(name);
|
||||
|
||||
List<String> fqns = new ArrayList<>();
|
||||
for (ClassImport ci : clazz.getImports()) {
|
||||
if (!ci.isAsterisk()) {
|
||||
if (ci.getTail().equals(name)) {
|
||||
fqns.add(ci.getName());
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
fqns.add(replaceAsterisk(ci.getName()) + name);
|
||||
}
|
||||
}
|
||||
|
||||
if (clazz.getPackage() != null) {
|
||||
fqns.add(clazz.getPackage().concat(".").concat(name));
|
||||
}
|
||||
|
||||
String result = searchForRealClass(fqns);
|
||||
if (result == null) {
|
||||
result = name;
|
||||
}
|
||||
|
||||
return result.concat(searchForTypeArguments(clazz, targetParser.getTypeArguments()));
|
||||
}
|
||||
|
||||
private String searchForRealClass(List<String> fqns) {
|
||||
ClassSearcher seacher = new ClassSearcher();
|
||||
for (String fqn : fqns) {
|
||||
if (seacher.find(fqn, sources)) {
|
||||
return fqn;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private String searchForTypeArguments(SourceClass clazz, List<String> typeArguments) {
|
||||
if (typeArguments.isEmpty()) {
|
||||
return "";
|
||||
}
|
||||
|
||||
StringBuilder arguments = new StringBuilder("<");
|
||||
for (String arg : typeArguments) {
|
||||
String fqn = getFqn(clazz, arg);
|
||||
arguments.append(fqn).append(",");
|
||||
}
|
||||
arguments.setCharAt(arguments.length() - 1, '>');
|
||||
|
||||
return arguments.toString();
|
||||
}
|
||||
|
||||
private String replaceAsterisk(String asteriskImport) {
|
||||
String[] splitted = asteriskImport.split("\\.");
|
||||
String importName = "";
|
||||
for (String s : splitted) {
|
||||
if (!s.equals("*")) {
|
||||
importName += s.concat(".");
|
||||
}
|
||||
}
|
||||
|
||||
return importName;
|
||||
}
|
||||
}
|
86
bundle/vim-javacomplete2/libs/javavi/src/main/java/kg/ash/javavi/searchers/JavaClassMap.java
vendored
Normal file
86
bundle/vim-javacomplete2/libs/javavi/src/main/java/kg/ash/javavi/searchers/JavaClassMap.java
vendored
Normal file
@ -0,0 +1,86 @@
|
||||
package kg.ash.javavi.searchers;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public abstract class JavaClassMap implements Serializable {
|
||||
|
||||
public static final int SOURCETYPE_CLASSPATH = 0;
|
||||
public static final int SOURCETYPE_SOURCES = 1;
|
||||
|
||||
public static final int TYPE_CLASS = 0;
|
||||
public static final int TYPE_SUBPACKAGE = 1;
|
||||
|
||||
protected String name = null;
|
||||
protected HashMap<String, Integer> pathsMap = new HashMap<>();
|
||||
protected List<String> classes = new ArrayList<>();
|
||||
protected Map<String, String> subpackages = new HashMap<>();
|
||||
|
||||
public JavaClassMap(String name) {
|
||||
setName(name);
|
||||
}
|
||||
|
||||
public boolean contains(String path) {
|
||||
return pathsMap.containsKey(path);
|
||||
}
|
||||
|
||||
public Set<String> getPaths() {
|
||||
return pathsMap.keySet();
|
||||
}
|
||||
|
||||
public int getSourceType(String path) {
|
||||
return pathsMap.get(path);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public void add(String path, int source, int type, String filename) {
|
||||
if (!contains(path)) {
|
||||
pathsMap.put(path, source);
|
||||
if (type == TYPE_CLASS) {
|
||||
classes.add(path);
|
||||
} else {
|
||||
subpackages.put(path, filename);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public StringBuilder getCachedClasses() {
|
||||
StringBuilder cachedClasses = new StringBuilder();
|
||||
classes.stream()
|
||||
.sorted()
|
||||
.forEach(path -> cachedClasses.append("'").append(path).append("',"));
|
||||
return cachedClasses;
|
||||
}
|
||||
|
||||
public StringBuilder getCachedSubpackages() {
|
||||
StringBuilder cachedSubpackages = new StringBuilder();
|
||||
subpackages.keySet()
|
||||
.stream()
|
||||
.sorted()
|
||||
.forEach(path -> cachedSubpackages.append("'").append(path).append("',"));
|
||||
return cachedSubpackages;
|
||||
}
|
||||
|
||||
|
||||
public Map<String, String> getSubpackages() {
|
||||
return subpackages;
|
||||
}
|
||||
|
||||
public abstract int getType();
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("name: %s, type: %d", name, getType());
|
||||
}
|
||||
}
|
60
bundle/vim-javacomplete2/libs/javavi/src/main/java/kg/ash/javavi/searchers/PackageEntry.java
vendored
Normal file
60
bundle/vim-javacomplete2/libs/javavi/src/main/java/kg/ash/javavi/searchers/PackageEntry.java
vendored
Normal file
@ -0,0 +1,60 @@
|
||||
package kg.ash.javavi.searchers;
|
||||
|
||||
public class PackageEntry {
|
||||
|
||||
public final static int FILETYPE_JAVA = 0;
|
||||
public final static int FILETYPE_CLASS = 1;
|
||||
|
||||
private String entry;
|
||||
private int source;
|
||||
private String javaFile = null;
|
||||
private String classFile = null;
|
||||
private String archiveName = null;
|
||||
|
||||
public PackageEntry(String entry, int source) {
|
||||
this.entry = entry;
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
public PackageEntry(String entry, int source, String archiveName) {
|
||||
this.entry = entry;
|
||||
this.source = source;
|
||||
this.archiveName = archiveName;
|
||||
}
|
||||
|
||||
public PackageEntry(String entry, int source, String filePath, int fileType) {
|
||||
this.entry = entry;
|
||||
this.source = source;
|
||||
if (fileType == FILETYPE_JAVA) {
|
||||
this.javaFile = filePath;
|
||||
} else {
|
||||
this.classFile = filePath;
|
||||
}
|
||||
}
|
||||
|
||||
public String getEntry() {
|
||||
return entry;
|
||||
}
|
||||
|
||||
public int getSource() {
|
||||
return source;
|
||||
}
|
||||
|
||||
public String getJavaFile() {
|
||||
return javaFile;
|
||||
}
|
||||
|
||||
public String getClassFile() {
|
||||
return classFile;
|
||||
}
|
||||
|
||||
public String getArchiveName() {
|
||||
return archiveName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("{%s, %d, %s, %s}", entry, source, javaFile, classFile);
|
||||
}
|
||||
|
||||
}
|
13
bundle/vim-javacomplete2/libs/javavi/src/main/java/kg/ash/javavi/searchers/PackageNameMap.java
vendored
Normal file
13
bundle/vim-javacomplete2/libs/javavi/src/main/java/kg/ash/javavi/searchers/PackageNameMap.java
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
package kg.ash.javavi.searchers;
|
||||
|
||||
public class PackageNameMap extends JavaClassMap {
|
||||
|
||||
public PackageNameMap(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getType() {
|
||||
return JavaClassMap.TYPE_SUBPACKAGE;
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
package kg.ash.javavi.searchers;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface PackageSeacherIFace {
|
||||
List<PackageEntry> loadEntries();
|
||||
}
|
114
bundle/vim-javacomplete2/libs/javavi/src/main/java/kg/ash/javavi/searchers/PackagesLoader.java
vendored
Normal file
114
bundle/vim-javacomplete2/libs/javavi/src/main/java/kg/ash/javavi/searchers/PackagesLoader.java
vendored
Normal file
@ -0,0 +1,114 @@
|
||||
package kg.ash.javavi.searchers;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
public class PackagesLoader {
|
||||
|
||||
private HashMap<String, JavaClassMap> classPackages;
|
||||
private List<PackageSeacherIFace> searchers = new ArrayList<>();
|
||||
|
||||
public PackagesLoader(String sourceDirectories) {
|
||||
searchers.add(new ClasspathPackageSearcher());
|
||||
searchers.add(new SourcePackageSearcher(sourceDirectories));
|
||||
}
|
||||
|
||||
public void collectPackages(HashMap<String, JavaClassMap> classPackages) {
|
||||
this.classPackages = classPackages;
|
||||
|
||||
List<PackageEntry> entries = new ArrayList<>();
|
||||
searchers.parallelStream().forEach(s -> entries.addAll(s.loadEntries()));
|
||||
|
||||
entries.forEach(entry -> appendEntry(entry));
|
||||
}
|
||||
|
||||
public void setSearchers(List<PackageSeacherIFace> searchers) {
|
||||
this.searchers = searchers;
|
||||
}
|
||||
|
||||
private void appendEntry(PackageEntry entry) {
|
||||
String name = entry.getEntry();
|
||||
if (isClassFile(name)) {
|
||||
int seppos = name.lastIndexOf('$');
|
||||
if (seppos < 0) {
|
||||
seppos = name.replace('\\', '/').lastIndexOf('/');
|
||||
}
|
||||
if (seppos != -1) {
|
||||
processClass(entry, seppos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private JavaClassMap getClassMap(String name, int type) {
|
||||
if (classPackages.containsKey(name) && classPackages.get(name).getType() == type) {
|
||||
return classPackages.get(name);
|
||||
}
|
||||
|
||||
JavaClassMap jcm;
|
||||
if (type == JavaClassMap.TYPE_CLASS) {
|
||||
jcm = new ClassNameMap(name);
|
||||
} else {
|
||||
jcm = new PackageNameMap(name);
|
||||
}
|
||||
|
||||
classPackages.put(name, jcm);
|
||||
return jcm;
|
||||
}
|
||||
|
||||
private void processClass(PackageEntry entry, int seppos) {
|
||||
String name = entry.getEntry();
|
||||
String parent = name.substring(0, seppos);
|
||||
String child = name.substring(seppos + 1, name.length() - 6);
|
||||
|
||||
boolean nested = false;
|
||||
String parentDots = makeDots(parent);
|
||||
if (name.contains("$")) {
|
||||
nested = true;
|
||||
parentDots += "$";
|
||||
}
|
||||
|
||||
int source = entry.getSource();
|
||||
|
||||
if (!child.isEmpty() && !parentDots.isEmpty()) {
|
||||
ClassNameMap classMap = (ClassNameMap) getClassMap(child, JavaClassMap.TYPE_CLASS);
|
||||
classMap.add(parentDots, source, JavaClassMap.TYPE_SUBPACKAGE, entry.getArchiveName());
|
||||
if (entry.getJavaFile() != null) {
|
||||
classMap.setJavaFile(entry.getJavaFile());
|
||||
}
|
||||
if (entry.getClassFile() != null) {
|
||||
classMap.setClassFile(entry.getClassFile());
|
||||
}
|
||||
|
||||
if (!nested) {
|
||||
getClassMap(parentDots, JavaClassMap.TYPE_SUBPACKAGE).add(child, source,
|
||||
JavaClassMap.TYPE_CLASS, null);
|
||||
}
|
||||
|
||||
addToParent(parent, source);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isClassFile(String name) {
|
||||
return name.endsWith(".class");
|
||||
}
|
||||
|
||||
private void addToParent(String name, int source) {
|
||||
int seppos = name.replace('\\', '/').lastIndexOf('/');
|
||||
if (seppos == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
String parent = name.substring(0, seppos);
|
||||
String child = name.substring(seppos + 1);
|
||||
|
||||
getClassMap(makeDots(parent), JavaClassMap.TYPE_SUBPACKAGE).add(child, source,
|
||||
JavaClassMap.TYPE_SUBPACKAGE, null);
|
||||
|
||||
addToParent(parent, source);
|
||||
}
|
||||
|
||||
private String makeDots(String name) {
|
||||
return name.replaceAll("/", ".").replaceAll("[.]{2,}", "");
|
||||
}
|
||||
}
|
@ -0,0 +1,94 @@
|
||||
package kg.ash.javavi.searchers;
|
||||
|
||||
import kg.ash.javavi.apache.logging.log4j.LogManager;
|
||||
import kg.ash.javavi.apache.logging.log4j.Logger;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.FileSystems;
|
||||
import java.nio.file.FileVisitResult;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.PathMatcher;
|
||||
import java.nio.file.SimpleFileVisitor;
|
||||
import java.nio.file.attribute.BasicFileAttributes;
|
||||
|
||||
public class SourceFileVisitor extends SimpleFileVisitor<Path> {
|
||||
|
||||
public static final Logger logger = LogManager.getLogger();
|
||||
|
||||
private final PathMatcher matcher;
|
||||
private String targetFile;
|
||||
private String pattern;
|
||||
|
||||
public SourceFileVisitor(String pattern) {
|
||||
String path;
|
||||
pattern = pattern != null ? pattern : "";
|
||||
|
||||
if (pattern.contains(".")) {
|
||||
String[] splitted = pattern.split("\\.");
|
||||
path = splitted[splitted.length - 1];
|
||||
} else {
|
||||
path = pattern;
|
||||
}
|
||||
|
||||
logger.info("visit source: {}", path);
|
||||
matcher = FileSystems.getDefault().getPathMatcher(String.format("glob:%s.java", path));
|
||||
|
||||
this.pattern = pattern;
|
||||
}
|
||||
|
||||
public String getTargetFile() {
|
||||
return targetFile;
|
||||
}
|
||||
|
||||
private boolean find(Path file) {
|
||||
Path name = file.getFileName();
|
||||
|
||||
if (name != null && matcher.matches(name)) {
|
||||
if (pattern.contains(".")) {
|
||||
return checkPattern(file);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean checkPattern(Path file) {
|
||||
String[] splitted = pattern.split("\\.");
|
||||
for (int i = splitted.length - 2; i >= 0; i--) {
|
||||
file = file.getParent();
|
||||
if (file != null) {
|
||||
String filename = file.getFileName().toString();
|
||||
if (!filename.equals(splitted[i])) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
|
||||
if (!find(file)) {
|
||||
return FileVisitResult.CONTINUE;
|
||||
}
|
||||
|
||||
targetFile = file.toFile().getPath().replace('\\', '/');
|
||||
return FileVisitResult.TERMINATE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
|
||||
if (!find(dir)) {
|
||||
return FileVisitResult.CONTINUE;
|
||||
}
|
||||
|
||||
return FileVisitResult.TERMINATE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileVisitResult visitFileFailed(Path file, IOException exc) {
|
||||
return FileVisitResult.CONTINUE;
|
||||
}
|
||||
}
|
@ -0,0 +1,88 @@
|
||||
package kg.ash.javavi.searchers;
|
||||
|
||||
import com.github.javaparser.JavaParser;
|
||||
import com.github.javaparser.ast.CompilationUnit;
|
||||
import kg.ash.javavi.apache.logging.log4j.LogManager;
|
||||
import kg.ash.javavi.apache.logging.log4j.Logger;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class SourcePackageSearcher implements PackageSeacherIFace {
|
||||
|
||||
public static final Logger logger = LogManager.getLogger();
|
||||
|
||||
private String sourceDirectories = "";
|
||||
private ByExtensionVisitor finder = new ByExtensionVisitor(Arrays.asList("*.java"));
|
||||
|
||||
public SourcePackageSearcher(String sourceDirectories) {
|
||||
if (sourceDirectories != null) {
|
||||
this.sourceDirectories = sourceDirectories;
|
||||
}
|
||||
}
|
||||
|
||||
public List<PackageEntry> loadEntries() {
|
||||
List<PackageEntry> result = new ArrayList<>();
|
||||
for (String directory : getExistDirectories()) {
|
||||
try {
|
||||
logger.debug("search source files");
|
||||
|
||||
Files.walkFileTree(Paths.get(directory), finder);
|
||||
for (String path : finder.getResultList()) {
|
||||
String packagePath = fetchPackagePath(path);
|
||||
if (packagePath != null) {
|
||||
logger.trace(path);
|
||||
|
||||
packagePath = packagePath.substring(0, packagePath.length() - 4) + "class";
|
||||
result.add(
|
||||
new PackageEntry(packagePath, JavaClassMap.SOURCETYPE_SOURCES, path,
|
||||
PackageEntry.FILETYPE_JAVA));
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
logger.error(e, e);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<String> getExistDirectories() {
|
||||
String[] splitted = sourceDirectories.split(File.pathSeparator);
|
||||
return Arrays.asList(splitted)
|
||||
.stream()
|
||||
.filter(d -> new File(d).isDirectory())
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private String fetchPackagePath(String sourcePath) {
|
||||
CompilationUnit cu;
|
||||
try (FileInputStream in = new FileInputStream(sourcePath)) {
|
||||
cu = JavaParser.parse(in);
|
||||
} catch (Exception ex) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (cu.getPackageDeclaration().isPresent()) {
|
||||
int lastslash = sourcePath.replace('\\', '/').lastIndexOf('/');
|
||||
if (lastslash >= 0) {
|
||||
String className = sourcePath.substring(lastslash + 1);
|
||||
String path = cu.getPackageDeclaration()
|
||||
.get()
|
||||
.getNameAsString()
|
||||
.replace(".", File.separator);
|
||||
return path + File.separator + className;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
27
bundle/vim-javacomplete2/libs/javavi/src/main/resources/log4j2.xml
vendored
Normal file
27
bundle/vim-javacomplete2/libs/javavi/src/main/resources/log4j2.xml
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Configuration status="warn" name="Javavi" packages="kg.ash.javavi">
|
||||
<Properties>
|
||||
<Property name="daemon.port">0</Property>
|
||||
<Property name="log.level">off</Property>
|
||||
<Property name="log.directory">/tmp/javavi_log</Property>
|
||||
<Property name="log.time_id">${date:yyMMddHHmm}</Property>
|
||||
</Properties>
|
||||
<Appenders>
|
||||
<Console name="CONSOLE-OUT" target="SYSTEM_OUT">
|
||||
<PatternLayout pattern=" [%c] %m%xEx%n"/>
|
||||
</Console>
|
||||
|
||||
<File name="Javavi" fileName="${sys:log.directory}/${log.time_id}-${sys:daemon.port}.log"
|
||||
immediateFlush="true" append="true">
|
||||
<PatternLayout>
|
||||
<Pattern>%d{MMdd HH:mm:ss.SSS} %p{length=1} [%t] %m [%c{-3}]%n</Pattern>
|
||||
</PatternLayout>
|
||||
</File>
|
||||
</Appenders>
|
||||
<Loggers>
|
||||
<Root level="${sys:log.level}">
|
||||
<AppenderRef ref="CONSOLE-OUT" />
|
||||
<AppenderRef ref="Javavi"/>
|
||||
</Root>
|
||||
</Loggers>
|
||||
</Configuration>
|
34
bundle/vim-javacomplete2/libs/javavi/src/test/java/kg/ash/javavi/DaemonTest.java
vendored
Normal file
34
bundle/vim-javacomplete2/libs/javavi/src/test/java/kg/ash/javavi/DaemonTest.java
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
package kg.ash.javavi;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public class DaemonTest {
|
||||
|
||||
private Daemon daemon = new Daemon(0, -1);
|
||||
|
||||
@Test
|
||||
public void testParseLine() {
|
||||
Assert.assertArrayEquals(new String[] { "-v" }, daemon.parseRequest("-v"));
|
||||
Assert.assertArrayEquals(new String[] { "-E", "java.util.List" },
|
||||
daemon.parseRequest("-E \"java.util.List\""));
|
||||
Assert.assertArrayEquals(new String[] { "-E", "java.util.List" },
|
||||
daemon.parseRequest("-E java.util.List"));
|
||||
Assert.assertArrayEquals(new String[] { "-E", "java.util.List<HashMap<String,Integer>>" },
|
||||
daemon.parseRequest("-E java.util.List<HashMap<String,Integer>>"));
|
||||
Assert.assertArrayEquals(new String[0], daemon.parseRequest(""));
|
||||
Assert.assertArrayEquals(new String[] { "-E", "" }, daemon.parseRequest("-E \"\""));
|
||||
Assert.assertEquals("\\n", daemon.parseRequest("\"\\\\n\"")[0]);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseEmptyValue() {
|
||||
Assert.assertEquals(new String[] { "-sources", "" }, daemon.parseRequest("-sources \"\""));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWindowsDirectoryValue() {
|
||||
Assert.assertEquals(new String[] { "-base", "C:\\Documents and Settings\\directory\\" },
|
||||
daemon.parseRequest("-base \"C:\\\\Documents and Settings\\\\directory\\\\\""));
|
||||
}
|
||||
}
|
68
bundle/vim-javacomplete2/libs/javavi/src/test/java/kg/ash/javavi/TargetParserTest.java
vendored
Normal file
68
bundle/vim-javacomplete2/libs/javavi/src/test/java/kg/ash/javavi/TargetParserTest.java
vendored
Normal file
@ -0,0 +1,68 @@
|
||||
package kg.ash.javavi;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public class TargetParserTest {
|
||||
|
||||
@Test
|
||||
public void testParse() {
|
||||
TargetParser parser = new TargetParser("");
|
||||
Assert.assertEquals("", parser.parse(""));
|
||||
Assert.assertEquals("java.util.List", parser.parse("java.util.List"));
|
||||
Assert.assertEquals(0, parser.getTypeArguments().size());
|
||||
|
||||
Assert.assertEquals("java.util.List",
|
||||
parser.parse("java.util.List<java.util.List<HashMap<String,BigDecimal>>>"));
|
||||
Assert.assertEquals(1, parser.getTypeArguments().size());
|
||||
Assert.assertEquals("java.util.List<HashMap<String,BigDecimal>>",
|
||||
parser.getTypeArguments().get(0));
|
||||
|
||||
Assert.assertEquals("HashMap", parser.parse("HashMap<Long, HashMap<String,String>>"));
|
||||
|
||||
Assert.assertEquals("java.util.HashMap", parser.parse(
|
||||
"java.util.HashMap<(kg.ash.demo.String|java.lang.String),java.math.BigDecimal>"));
|
||||
Assert.assertEquals(2, parser.getTypeArguments().size());
|
||||
Assert.assertEquals("java.lang.String", parser.getTypeArguments().get(0));
|
||||
Assert.assertEquals("java.math.BigDecimal", parser.getTypeArguments().get(1));
|
||||
|
||||
Assert.assertEquals("java.util.List", parser.parse("java.util.List<? super Integer>"));
|
||||
Assert.assertEquals("Integer", parser.getTypeArguments().get(0));
|
||||
|
||||
Assert.assertEquals("java.util.List", parser.parse("java.util.List<? super Integer[]>"));
|
||||
Assert.assertEquals("Integer[]", parser.getTypeArguments().get(0));
|
||||
|
||||
Assert.assertEquals("java.util.List", parser.parse("java.util.List<? extends Integer>"));
|
||||
Assert.assertEquals("Integer", parser.getTypeArguments().get(0));
|
||||
|
||||
Assert.assertEquals("java.lang.Class", parser.parse("java.lang.Class<?>"));
|
||||
|
||||
Assert.assertEquals("java.util.HashMap$KeySet", parser.parse(
|
||||
"java.util.HashMap$KeySet<(kg.ash.demo.String|java.lang.String),java.math"
|
||||
+ ".BigDecimal>"));
|
||||
Assert.assertEquals(2, parser.getTypeArguments().size());
|
||||
Assert.assertEquals("java.lang.String", parser.getTypeArguments().get(0));
|
||||
Assert.assertEquals("java.math.BigDecimal", parser.getTypeArguments().get(1));
|
||||
|
||||
Assert.assertEquals("java.util.List",
|
||||
parser.parse("java.util.List<java.lang.Object, java.lang.Object, java.lang.Object>"));
|
||||
Assert.assertEquals("java.util.List", parser.parse(
|
||||
"java.util.List<(kg.test.Object|java.lang.Object),(kg.test.Object|java.lang.Object),"
|
||||
+ "(kg.test.String|java.lang.String|java.lang.Object)>"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTypeArgumentsToString() {
|
||||
TargetParser parser = new TargetParser("");
|
||||
parser.parse("java.util.List");
|
||||
Assert.assertEquals("", parser.getTypeArgumentsString());
|
||||
parser.parse("java.util.List<java.math.BigDecimal>");
|
||||
Assert.assertEquals("<java.math.BigDecimal>", parser.getTypeArgumentsString());
|
||||
parser.parse("java.util.List<SomeClass>");
|
||||
Assert.assertEquals("<java.lang.Object>", parser.getTypeArgumentsString());
|
||||
parser.parse(
|
||||
"java.util.HashMap<(kg.ash.demo.String|java.lang.String),java.math.BigDecimal>");
|
||||
Assert.assertEquals("<java.lang.String,java.math.BigDecimal>",
|
||||
parser.getTypeArgumentsString());
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user