├── .bundle └── config ├── .github ├── ISSUE_TEMPLATE.md └── workflows │ └── vint.yml ├── .gitignore ├── Gemfile ├── LICENSE ├── README.md ├── Rakefile ├── addon-info.json ├── autoload ├── classpath.py ├── cm │ └── sources │ │ └── java.vim ├── java_parser.vim ├── javacomplete.vim ├── javacomplete │ ├── classpath │ │ ├── ant.vim │ │ ├── classpath.vim │ │ ├── gradle.vim │ │ └── maven.vim │ ├── collector.vim │ ├── complete │ │ ├── complete.vim │ │ └── context.vim │ ├── generators.vim │ ├── highlights.vim │ ├── imports.vim │ ├── logger.vim │ ├── newclass.vim │ ├── parseradapter.vim │ ├── scanner.vim │ ├── server.vim │ ├── util.vim │ └── version.vim └── javavibridge.py ├── classpath.gradle ├── doc ├── demo.gif ├── generics_demo.gif └── javacomplete.txt ├── libs ├── javaparser-core-3.5.20.jar ├── javavi │ ├── pom.xml │ └── src │ │ ├── main │ │ ├── java │ │ │ └── kg │ │ │ │ └── ash │ │ │ │ └── javavi │ │ │ │ ├── Daemon.java │ │ │ │ ├── Javavi.java │ │ │ │ ├── TargetParser.java │ │ │ │ ├── actions │ │ │ │ ├── Action.java │ │ │ │ ├── ActionFactory.java │ │ │ │ ├── ActionWithTarget.java │ │ │ │ ├── AddClassToCacheAction.java │ │ │ │ ├── ClassRecompileAction.java │ │ │ │ ├── CollectPackagesAction.java │ │ │ │ ├── ExecuteDaemonAction.java │ │ │ │ ├── FilterSimilarAnnotationsAction.java │ │ │ │ ├── FilterSimilarClassesAction.java │ │ │ │ ├── GetAppVersion.java │ │ │ │ ├── GetClassInfoAction.java │ │ │ │ ├── GetClassInfoFromSourceAction.java │ │ │ │ ├── GetClassPackagesAction.java │ │ │ │ ├── GetClassesArchiveNamesAction.java │ │ │ │ ├── GetDebugLogPath.java │ │ │ │ ├── GetMissingImportsAction.java │ │ │ │ ├── GetPackageInfoAction.java │ │ │ │ ├── GetUnusedImportsAction.java │ │ │ │ ├── ImportsAction.java │ │ │ │ ├── ParseByContentAction.java │ │ │ │ └── RemoveClassInfoFromCache.java │ │ │ │ ├── cache │ │ │ │ ├── Cache.java │ │ │ │ └── CacheSerializator.java │ │ │ │ ├── clazz │ │ │ │ ├── ClassConstructor.java │ │ │ │ ├── ClassField.java │ │ │ │ ├── ClassImport.java │ │ │ │ ├── ClassMethod.java │ │ │ │ ├── ClassTypeParameter.java │ │ │ │ ├── CodeRegion.java │ │ │ │ └── SourceClass.java │ │ │ │ ├── output │ │ │ │ ├── OutputClassInfo.java │ │ │ │ ├── OutputClassPackages.java │ │ │ │ ├── OutputPackageInfo.java │ │ │ │ ├── OutputSimilar.java │ │ │ │ ├── OutputSimilarAnnotations.java │ │ │ │ └── OutputSimilarClasses.java │ │ │ │ ├── readers │ │ │ │ ├── ClassReader.java │ │ │ │ ├── FileClassLoader.java │ │ │ │ ├── Parser.java │ │ │ │ ├── Reflection.java │ │ │ │ └── source │ │ │ │ │ ├── ClassNamesFetcher.java │ │ │ │ │ ├── CompilationUnitCreator.java │ │ │ │ │ └── CompilationUnitResult.java │ │ │ │ └── searchers │ │ │ │ ├── ByExtensionVisitor.java │ │ │ │ ├── ClassNameMap.java │ │ │ │ ├── ClassSearcher.java │ │ │ │ ├── ClasspathCollector.java │ │ │ │ ├── ClasspathPackageSearcher.java │ │ │ │ ├── FqnSearcher.java │ │ │ │ ├── JavaClassMap.java │ │ │ │ ├── PackageEntry.java │ │ │ │ ├── PackageNameMap.java │ │ │ │ ├── PackageSeacherIFace.java │ │ │ │ ├── PackagesLoader.java │ │ │ │ ├── SourceFileVisitor.java │ │ │ │ └── SourcePackageSearcher.java │ │ └── resources │ │ │ └── log4j2.xml │ │ └── test │ │ ├── java │ │ └── kg │ │ │ └── ash │ │ │ └── javavi │ │ │ ├── DaemonTest.java │ │ │ ├── TargetParserTest.java │ │ │ ├── actions │ │ │ ├── ClassRecompileActionTest.java │ │ │ ├── GetClassInfoActionTest.java │ │ │ └── GetClassesArchiveNamesActionTest.java │ │ │ ├── output │ │ │ ├── OutputClassInfoTest.java │ │ │ ├── OutputClassPackagesTest.java │ │ │ ├── OutputPackageInfoTest.java │ │ │ └── OutputSimilarClassesTest.java │ │ │ ├── readers │ │ │ └── source │ │ │ │ └── ClassNamesFetcherTest.java │ │ │ └── searchers │ │ │ ├── ClasspathPackageSearcherTest.java │ │ │ ├── FqnSeacherTest.java │ │ │ ├── PackagesLoaderTest.java │ │ │ └── SourceFileVisitorTest.java │ │ └── resources │ │ └── kg │ │ └── ash │ │ └── javavi │ │ ├── ClassWithClasses.java │ │ └── ResourceClassForClassFetcherTest.java ├── javavi_log4j-api.jar └── javavi_log4j-core.jar ├── plugin ├── javacomplete.vim └── res │ ├── gen__class.tpl │ ├── gen__class_android_activity.tpl │ ├── gen__class_android_broadcast_receiver.tpl │ ├── gen__class_android_fragment.tpl │ ├── gen__class_android_service.tpl │ ├── gen__class_annotation.tpl │ ├── gen__class_enum.tpl │ ├── gen__class_exception.tpl │ ├── gen__class_interface.tpl │ ├── gen__class_junit.tpl │ ├── gen__class_main.tpl │ ├── gen__class_servlet.tpl │ ├── gen__class_singleton.tpl │ ├── gen__constructor.tpl │ ├── gen__equals.tpl │ ├── gen__hashCode.tpl │ ├── gen__toString_StringBuilder.tpl │ └── gen__toString_concat.tpl ├── rplugin └── python3 │ └── deoplete │ └── sources │ └── javacomplete2.py └── t ├── collector.vim ├── complete.vim ├── data ├── LambdaAnonClass.java ├── LambdaNamedClass.java └── LambdaReturnClass.java ├── imports.vim ├── java_parser.vim ├── javacomplete.vim ├── newclass.vim ├── parseradapter.vim ├── scanner.vim ├── utils.vim └── version.vim /.bundle/config: -------------------------------------------------------------------------------- 1 | --- 2 | BUNDLE_PATH: ".vim-flavor" 3 | BUNDLE_DISABLE_SHARED_GEMS: "true" 4 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ## Actual behavior (Required!) 2 | 3 | 4 | ## Expected behavior (Required!) 5 | 6 | 7 | ## The steps to reproduce actual behavior (Required!) 8 | 1. ... 9 | 2. ... 10 | 3. ... 11 | 12 | 13 | ## Environment (Required!) 14 | * OS: 15 | * Vim version: 16 | * Neovim version: 17 | 18 | 19 | ## Q&A 20 | * Yes, I tried minimal .vimrc configuraion. 21 | * Yes, I have enabled logs with `JCdebugEnableLogs` and can put here content of `JCdebugGetLogContent` command, if you need. 22 | * Even, if you wish, I can set `g:JavaComplete_JavaviLogLevel` to `'debug'`, then set `g:JavaComplete_JavaviLogDirectory`, and put here server logs, too. 23 | 24 | 25 | ## Screenshot (Optional) 26 | 27 | 28 | ## The output of :redir and :message (Optional) 29 | -------------------------------------------------------------------------------- /.github/workflows/vint.yml: -------------------------------------------------------------------------------- 1 | name: Vint 2 | on: [pull_request] 3 | jobs: 4 | vint: 5 | strategy: 6 | fail-fast: false 7 | runs-on: ubuntu-latest 8 | steps: 9 | - name: Checkout 10 | uses: actions/checkout@master 11 | - name: Run vint with reviewdog 12 | uses: reviewdog/action-vint@v1.0.1 13 | with: 14 | github_token: ${{ secrets.github_token }} 15 | reporter: github-pr-review 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.class 2 | *.py[cod] 3 | 4 | # Mobile Tools for Java (J2ME) 5 | .mtj.tmp/ 6 | 7 | # Package Files # 8 | *.jar 9 | *.war 10 | *.ear 11 | 12 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 13 | hs_err_pid* 14 | 15 | *~ 16 | .*.sw? 17 | libs/javavi/target/ 18 | 19 | *.lock 20 | .vim-flavor 21 | 22 | .vimrc 23 | 24 | # ignore vim's help tags 25 | doc/tags 26 | tags 27 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | gem 'vim-flavor', '~> 2.2.1' 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | VIM LICENSE 2 | 3 | I) There are no restrictions on distributing unmodified copies of Vim except 4 | that they must include this license text. You can also distribute 5 | unmodified parts of Vim, likewise unrestricted except that they must 6 | include this license text. You are also allowed to include executables 7 | that you made from the unmodified Vim sources, plus your own usage 8 | examples and Vim scripts. 9 | 10 | II) It is allowed to distribute a modified (or extended) version of Vim, 11 | including executables and/or source code, when the following four 12 | conditions are met: 13 | 1) This license text must be included unmodified. 14 | 2) The modified Vim must be distributed in one of the following five ways: 15 | a) If you make changes to Vim yourself, you must clearly describe in 16 | the distribution how to contact you. When the maintainer asks you 17 | (in any way) for a copy of the modified Vim you distributed, you 18 | must make your changes, including source code, available to the 19 | maintainer without fee. The maintainer reserves the right to 20 | include your changes in the official version of Vim. What the 21 | maintainer will do with your changes and under what license they 22 | will be distributed is negotiable. If there has been no negotiation 23 | then this license, or a later version, also applies to your changes. 24 | The current maintainer is Bram Moolenaar . If this 25 | changes it will be announced in appropriate places (most likely 26 | vim.sf.net, www.vim.org and/or comp.editors). When it is completely 27 | impossible to contact the maintainer, the obligation to send him 28 | your changes ceases. Once the maintainer has confirmed that he has 29 | received your changes they will not have to be sent again. 30 | b) If you have received a modified Vim that was distributed as 31 | mentioned under a) you are allowed to further distribute it 32 | unmodified, as mentioned at I). If you make additional changes the 33 | text under a) applies to those changes. 34 | c) Provide all the changes, including source code, with every copy of 35 | the modified Vim you distribute. This may be done in the form of a 36 | context diff. You can choose what license to use for new code you 37 | add. The changes and their license must not restrict others from 38 | making their own changes to the official version of Vim. 39 | d) When you have a modified Vim which includes changes as mentioned 40 | under c), you can distribute it without the source code for the 41 | changes if the following three conditions are met: 42 | - The license that applies to the changes permits you to distribute 43 | the changes to the Vim maintainer without fee or restriction, and 44 | permits the Vim maintainer to include the changes in the official 45 | version of Vim without fee or restriction. 46 | - You keep the changes for at least three years after last 47 | distributing the corresponding modified Vim. When the maintainer 48 | or someone who you distributed the modified Vim to asks you (in 49 | any way) for the changes within this period, you must make them 50 | available to him. 51 | - You clearly describe in the distribution how to contact you. This 52 | contact information must remain valid for at least three years 53 | after last distributing the corresponding modified Vim, or as long 54 | as possible. 55 | e) When the GNU General Public License (GPL) applies to the changes, 56 | you can distribute the modified Vim under the GNU GPL version 2 or 57 | any later version. 58 | 3) A message must be added, at least in the output of the ":version" 59 | command and in the intro screen, such that the user of the modified Vim 60 | is able to see that it was modified. When distributing as mentioned 61 | under 2)e) adding the message is only required for as far as this does 62 | not conflict with the license used for the changes. 63 | 4) The contact information as required under 2)a) and 2)d) must not be 64 | removed or changed, except that the person himself can make 65 | corrections. 66 | 67 | III) If you distribute a modified version of Vim, you are encouraged to use 68 | the Vim license for your changes and make them available to the 69 | maintainer, including the source code. The preferred way to do this is 70 | by e-mail or by uploading the files to a server and e-mailing the URL. 71 | If the number of changes is small (e.g., a modified Makefile) e-mailing a 72 | context diff will do. The e-mail address to be used is 73 | 74 | 75 | IV) It is not allowed to remove this license from the distribution of the Vim 76 | sources, parts of it or from a modified version. You may use this 77 | license for previous Vim releases instead of the license that they came 78 | with, at your option. 79 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env rake 2 | 3 | task :ci => [:dump, :test] 4 | 5 | task :dump do 6 | sh 'vim --version' 7 | end 8 | 9 | task :test do 10 | sh 'bundle exec vim-flavor test' 11 | end 12 | -------------------------------------------------------------------------------- /addon-info.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "javacomplete", 3 | "description": "Updated version of the original javacomplete plugin", 4 | "author": "artur shaik" 5 | } 6 | 7 | -------------------------------------------------------------------------------- /autoload/classpath.py: -------------------------------------------------------------------------------- 1 | import os 2 | from xml.etree.ElementTree import * 3 | 4 | def ReadClasspathFile(fn): 5 | cp = [] 6 | for a in parse(fn).findall('classpathentry'): 7 | kind = a.get('kind') 8 | if kind == 'src' and 'output' in a.keys(): 9 | cp.append(os.path.abspath(a.get('output'))) 10 | elif kind == 'lib' and 'path' in a.keys(): 11 | cp.append(os.path.abspath(a.get('path'))) 12 | elif kind == 'output' and 'path' in a.keys(): 13 | cp.append(os.path.abspath(a.get('path'))) 14 | return cp 15 | -------------------------------------------------------------------------------- /autoload/cm/sources/java.vim: -------------------------------------------------------------------------------- 1 | func! cm#sources#java#register() 2 | " the omnifunc pattern is PCRE 3 | call cm#register_source({'name' : 'java', 4 | \ 'priority': 9, 5 | \ 'scopes': ['java'], 6 | \ 'abbreviation': 'java', 7 | \ 'cm_refresh_patterns':['\.', '::'], 8 | \ 'cm_refresh': {'omnifunc': 'javacomplete#Complete' }, 9 | \ }) 10 | 11 | endfunc 12 | -------------------------------------------------------------------------------- /autoload/javacomplete/classpath/classpath.vim: -------------------------------------------------------------------------------- 1 | function! s:Log(log) 2 | let log = type(a:log) == type("") ? a:log : string(a:log) 3 | call javacomplete#logger#Log("[classpath] ". log) 4 | endfunction 5 | 6 | function! javacomplete#classpath#classpath#BuildClassPath() 7 | call s:BuildClassPath(0) 8 | endfunction 9 | 10 | function! javacomplete#classpath#classpath#RebuildClassPath() 11 | call s:BuildClassPath(1) 12 | endfunction 13 | 14 | function! s:BuildClassPath(force) 15 | if !g:JavaComplete_MavenRepositoryDisabled 16 | if empty('g:JavaComplete_PomPath') 17 | let g:JavaComplete_PomPath = javacomplete#util#FindFile('pom.xml') 18 | if g:JavaComplete_PomPath != "" 19 | let g:JavaComplete_PomPath = fnamemodify(g:JavaComplete_PomPath, ':p') 20 | call s:Log("found maven file: ". g:JavaComplete_PomPath) 21 | endif 22 | endif 23 | endif 24 | 25 | if !get(g:, 'JavaComplete_GradleRepositoryDisabled', 0) 26 | if !exists('g:JavaComplete_GradlePath') 27 | if filereadable(getcwd(). g:FILE_SEP. "build.gradle") 28 | let g:JavaComplete_GradlePath = getcwd(). g:FILE_SEP. "build.gradle" 29 | else 30 | let g:JavaComplete_GradlePath = javacomplete#util#FindFile('build.gradle', '**3') 31 | endif 32 | if g:JavaComplete_GradlePath != "" 33 | let g:JavaComplete_GradlePath = fnamemodify(g:JavaComplete_GradlePath, ':p') 34 | call s:Log("found gradle file: ". g:JavaComplete_GradlePath) 35 | endif 36 | endif 37 | endif 38 | 39 | if !get(g:, 'JavaComplete_AntRepositoryDisabled', 0) 40 | if !exists('g:JavaComplete_AntPath') 41 | if filereadable(getcwd(). g:FILE_SEP. "build.xml") 42 | let g:JavaComplete_AntPath = getcwd(). g:FILE_SEP. "build.xml" 43 | else 44 | let g:JavaComplete_AntPath = javacomplete#util#FindFile('build.xml', '**3') 45 | endif 46 | if g:JavaComplete_AntPath != "" 47 | let g:JavaComplete_AntPath = fnamemodify(g:JavaComplete_AntPath, ':p') 48 | call s:Log("found ant file: ". g:JavaComplete_AntPath) 49 | endif 50 | endif 51 | endif 52 | 53 | let g:JavaComplete_LibsPath .= s:FindClassPath(a:force) 54 | 55 | call s:Log("libs found: ". g:JavaComplete_LibsPath) 56 | endfunction 57 | 58 | function! s:ReadClassPathFile(classpathFile) 59 | let cp = '' 60 | let file = g:JavaComplete_Home. join(['', 'autoload', 'classpath.py'], g:FILE_SEP) 61 | execute "JavacompletePyfile" file 62 | JavacompletePy import vim 63 | JavacompletePy vim.command("let cp = '%s'" % os.pathsep.join(ReadClasspathFile(vim.eval('a:classpathFile'))).replace('\\', '/')) 64 | return cp 65 | endfunction 66 | 67 | function! s:UseEclipse(force) 68 | if has('python') || has('python3') 69 | let classpathFile = fnamemodify(findfile('.classpath', escape(expand('.'), '*[]?{}, ') . ';'), ':p') 70 | if !empty(classpathFile) && filereadable(classpathFile) 71 | return s:ReadClassPathFile(classpathFile) 72 | endif 73 | endif 74 | 75 | return "" 76 | endf 77 | 78 | function! s:UseMaven(force) 79 | if javacomplete#classpath#maven#IfMaven() 80 | return javacomplete#classpath#maven#Generate(a:force) 81 | endif 82 | 83 | return "" 84 | endf 85 | 86 | function! s:UseGradle(force) 87 | if javacomplete#classpath#gradle#IfGradle() 88 | return javacomplete#classpath#gradle#Generate(a:force) 89 | endif 90 | 91 | return "" 92 | endf 93 | 94 | function! s:UseAnt(force) 95 | if javacomplete#classpath#ant#IfAnt() 96 | return javacomplete#classpath#ant#Generate(a:force) 97 | endif 98 | 99 | return "" 100 | endf 101 | 102 | function! s:FindClassPath(force) abort 103 | for classpathSourceType in g:JavaComplete_ClasspathGenerationOrder 104 | try 105 | let cp = '' 106 | exec "let cp .= s:Use". classpathSourceType. "(". a:force. ")" 107 | if !empty(cp) 108 | call s:Log("found ". classpathSourceType. " project") 109 | return '.' . g:PATH_SEP . cp 110 | endif 111 | catch 112 | endtry 113 | endfor 114 | 115 | return '.' 116 | endfunction 117 | 118 | " vim:set fdm=marker sw=2 nowrap: 119 | -------------------------------------------------------------------------------- /autoload/javacomplete/classpath/gradle.vim: -------------------------------------------------------------------------------- 1 | function! javacomplete#classpath#gradle#IfGradle() 2 | if !empty(g:JavaComplete_GradleExecutable) 3 | if executable(g:JavaComplete_GradleExecutable) && g:JavaComplete_GradlePath != "" 4 | return 1 5 | else 6 | return 0 7 | end 8 | endif 9 | 10 | if g:JavaComplete_GradlePath != "" && s:IsGradleExecutable() && g:JavaComplete_GradlePath != "" 11 | return 1 12 | endif 13 | return 0 14 | endfunction 15 | 16 | function! s:IsGradleExecutable() 17 | let osExec = javacomplete#util#IsWindows() ? '\gradlew.bat' : '/gradlew' 18 | let path = fnamemodify(g:JavaComplete_GradlePath, ':p:h') 19 | return executable('gradle') || executable(path. osExec) 20 | endfunction 21 | 22 | function! javacomplete#classpath#gradle#BuildClasspathHandler(data, event) 23 | if a:event == 'exit' 24 | if a:data == "0" 25 | let cp = '' 26 | for i in range(len(s:gradleOutput)) 27 | if s:gradleOutput[i] =~ '^CLASSPATH:' 28 | let cp .= s:gradleOutput[i][10:] 29 | for j in range(i, len(s:gradleOutput) - 1) 30 | if s:gradleOutput[j] !~ '^END CLASSPATH GENERATION' 31 | let cp .= s:gradleOutput[j] 32 | else 33 | break 34 | endif 35 | endfor 36 | break 37 | endif 38 | endfor 39 | let g:JavaComplete_LibsPath .= ':'. cp 40 | 41 | call writefile([cp], s:gradlePath) 42 | 43 | call javacomplete#util#RemoveFile(javacomplete#util#GetBase('cache'). g:FILE_SEP. 'class_packages_'. g:JavaComplete_ProjectKey. '.dat') 44 | 45 | call javacomplete#server#UnblockStart() 46 | call javacomplete#server#Terminate() 47 | call javacomplete#server#Start() 48 | 49 | echomsg "Gradle classpath built successfully" 50 | else 51 | echohl WarningMsg | echomsg "Failed to build gradle classpath" | echohl None 52 | endif 53 | 54 | call delete(s:temporaryGradleFile) 55 | 56 | unlet s:temporaryGradleFile 57 | unlet s:gradleOutput 58 | unlet s:gradlePath 59 | 60 | elseif a:event == 'stdout' 61 | for data in filter(a:data,'v:val !~ "^\\s*$"') 62 | if g:JavaComplete_ShowExternalCommandsOutput 63 | echomsg data 64 | endif 65 | endfor 66 | if exists('s:gradleOutput') 67 | call extend(s:gradleOutput, a:data) 68 | endif 69 | elseif a:event == 'stderr' 70 | for data in filter(a:data,'v:val !~ "^\\s*$"') 71 | echoerr data 72 | endfor 73 | endif 74 | endfunction 75 | 76 | function! javacomplete#classpath#gradle#Generate(force) abort 77 | let base = javacomplete#util#GetBase("classpath". g:FILE_SEP) 78 | let g:JavaComplete_ProjectKey = substitute(g:JavaComplete_GradlePath, '[\\/:;.]', '_', 'g') 79 | 80 | let path = base . g:JavaComplete_ProjectKey 81 | if filereadable(path) 82 | if a:force == 0 && getftime(path) >= getftime(g:JavaComplete_GradlePath) 83 | return join(readfile(path), '') 84 | endif 85 | call javacomplete#util#RemoveFile(javacomplete#util#GetBase('cache'). g:FILE_SEP. 'class_packages_'. g:JavaComplete_ProjectKey. '.dat') 86 | endif 87 | call s:GenerateClassPath(path) 88 | return '' 89 | endfunction 90 | 91 | function! s:GenerateClassPath(path) abort 92 | let s:temporaryGradleFile = tempname() 93 | let s:gradleOutput = [] 94 | let s:gradlePath = a:path 95 | if exists(g:JavaComplete_GradleExecutable) 96 | let gradle = g:JavaComplete_GradleExecutable 97 | else 98 | let gradle = fnamemodify( 99 | \ g:JavaComplete_GradlePath, ':p:h') 100 | \ . (javacomplete#util#IsWindows() 101 | \ ? 102 | \ '\gradlew.bat' 103 | \ : 104 | \ '/gradlew') 105 | if !executable(gradle) 106 | let gradle = 'gradle' 107 | endif 108 | endif 109 | call writefile( 110 | \ ["rootProject{apply from: '" 111 | \ . g:JavaComplete_Home. g:FILE_SEP. "classpath.gradle'}"], 112 | \ s:temporaryGradleFile) 113 | let cmd = [ 114 | \ gradle, 115 | \ '-p', 116 | \ fnamemodify(g:JavaComplete_GradlePath, ':p:h'), 117 | \ '-I', 118 | \ s:temporaryGradleFile, 119 | \ ':classpath'] 120 | call javacomplete#server#BlockStart() 121 | call javacomplete#util#RunSystem( 122 | \ cmd, 123 | \ 'gradle classpath build process', 124 | \ 'javacomplete#classpath#gradle#BuildClasspathHandler') 125 | endfunction 126 | 127 | " vim:set fdm=marker sw=2 nowrap: 128 | -------------------------------------------------------------------------------- /autoload/javacomplete/classpath/maven.vim: -------------------------------------------------------------------------------- 1 | let s:pomProperties={} "maven project properties 2 | let s:pomTags = ['build', 'properties'] 3 | let s:mavenErrors = [] 4 | 5 | function! javacomplete#classpath#maven#IfMaven() 6 | if executable('mvn') && g:JavaComplete_PomPath != "" 7 | return 1 8 | endif 9 | return 0 10 | endfunction 11 | 12 | function! javacomplete#classpath#maven#Generate(force) abort 13 | if a:force != 0 14 | let s:pomProperties = {} 15 | endif 16 | let g:JavaComplete_ProjectKey = substitute(g:JavaComplete_PomPath, '[\\/:;.]', '_', 'g') 17 | let path = javacomplete#util#GetBase("classpath". g:FILE_SEP). g:JavaComplete_ProjectKey 18 | 19 | if filereadable(path) 20 | if a:force == 0 && getftime(path) >= getftime(g:JavaComplete_PomPath) 21 | return join(readfile(path), '') 22 | endif 23 | call javacomplete#util#RemoveFile(javacomplete#util#GetBase('cache'). g:FILE_SEP. 'class_packages_'. g:JavaComplete_ProjectKey. '.dat') 24 | endif 25 | 26 | if !has_key(s:pomProperties, g:JavaComplete_PomPath) 27 | let s:mavenPath = path 28 | let s:mavenPom = g:JavaComplete_PomPath 29 | let s:mavenSettingsOutput = [] 30 | let mvnCmd = ['mvn', '-B', '--file', g:JavaComplete_PomPath, 'dependency:build-classpath', '-DincludeScope=test'] 31 | call javacomplete#server#BlockStart() 32 | call javacomplete#util#RunSystem(mvnCmd, 'maven classpath build process', 'javacomplete#classpath#maven#BuildClasspathHandler') 33 | return "" 34 | endif 35 | 36 | return s:GetMavenClasspath(path, g:JavaComplete_PomPath) 37 | endfunction 38 | 39 | function! s:GetMavenClasspath(path, pom) 40 | let mvnProperties = s:pomProperties[a:pom] 41 | let cp = get(mvnProperties, 'project.dependencybuildclasspath', '.') 42 | let cp .= g:PATH_SEP . get(mvnProperties, 'project.build.outputDirectory', join([fnamemodify(a:pom, ':h'), 'target', 'classes'], g:FILE_SEP)) 43 | let cp .= g:PATH_SEP . get(mvnProperties, 'project.build.testOutputDirectory', join([fnamemodify(a:pom, ':h'), 'target', 'test-classes'], g:FILE_SEP)) 44 | if cp != '.' 45 | call writefile([cp], a:path) 46 | endif 47 | return cp 48 | endfunction 49 | 50 | function! s:ParseMavenOutput() 51 | let mvnProperties = {} 52 | let mvnIsManagedTag = 1 53 | let currentPath = 'project' 54 | for i in range(len(s:mavenSettingsOutput)) 55 | if s:mavenSettingsOutput[i] =~ 'Dependencies classpath:' 56 | let mvnProperties['project.dependencybuildclasspath'] = s:mavenSettingsOutput[i + 1] 57 | let offset = 2 58 | while s:mavenSettingsOutput[i + offset] !~ '^[INFO.*' 59 | let mvnProperties['project.dependencybuildclasspath'] .= s:mavenSettingsOutput[i + offset] 60 | let offset += 1 61 | endwhile 62 | endif 63 | let matches = matchlist(s:mavenSettingsOutput[i], '\m^\s*<\([a-zA-Z0-9\-\.]\+\)>\s*$') 64 | if mvnIsManagedTag && !empty(matches) 65 | let mvnIsManagedTag = index(s:pomTags, matches[1]) >= 0 66 | let currentPath .= '.'. matches[1] 67 | else 68 | let matches = matchlist(s:mavenSettingsOutput[i], '\m^\s*\s*$') 69 | if !empty(matches) 70 | let mvnIsManagedTag = index(s:pomTags, matches[1]) < 0 71 | let currentPath = substitute(currentPath, '\m\.'. matches[1]. '$', '', '') 72 | else 73 | let matches = matchlist(s:mavenSettingsOutput[i], '\m^\s*<\([a-zA-Z0-9\-\.]\+\)>\(.\+\)\s*$') 74 | if mvnIsManagedTag && !empty(matches) 75 | let mvnProperties[currentPath. '.'. matches[1]] = matches[2] 76 | endif 77 | endif 78 | endif 79 | endfor 80 | let s:pomProperties[s:mavenPom] = mvnProperties 81 | endfunction 82 | 83 | function! javacomplete#classpath#maven#BuildClasspathHandler(data, event) 84 | if a:event == 'exit' 85 | if a:data == "0" 86 | call s:ParseMavenOutput() 87 | 88 | let g:JavaComplete_LibsPath .= s:GetMavenClasspath(s:mavenPath, s:mavenPom) 89 | 90 | call javacomplete#util#RemoveFile(javacomplete#util#GetBase('cache'). g:FILE_SEP. 'class_packages_'. g:JavaComplete_ProjectKey. '.dat') 91 | 92 | call javacomplete#server#UnblockStart() 93 | call javacomplete#server#Terminate() 94 | call javacomplete#server#Start() 95 | 96 | echomsg "Maven classpath built successfully" 97 | else 98 | echoerr join(s:mavenErrors, "\n") 99 | let s:mavenErrors = [] 100 | echohl WarningMsg | echomsg "Failed to build maven classpath" | echohl None 101 | endif 102 | 103 | unlet s:mavenPath 104 | unlet s:mavenPom 105 | unlet s:mavenSettingsOutput 106 | elseif a:event == 'stdout' 107 | for data in filter(a:data,'v:val !~ "^\\s*$"') 108 | if g:JavaComplete_ShowExternalCommandsOutput 109 | echomsg data 110 | elseif data =~ '^\[ERROR\]\w*' || data =~ '^\[WARNING\]\w*' 111 | echohl WarningMsg | echomsg data | echohl None 112 | endif 113 | endfor 114 | call extend(s:mavenSettingsOutput, a:data) 115 | elseif a:event == 'stderr' 116 | for data in filter(a:data,'v:val !~ "^\\s*$"') 117 | call add(s:mavenErrors, data) 118 | endfor 119 | endif 120 | endfunction 121 | 122 | " vim:set fdm=marker sw=2 nowrap: 123 | -------------------------------------------------------------------------------- /autoload/javacomplete/highlights.vim: -------------------------------------------------------------------------------- 1 | " Vim completion script for java 2 | " Maintainer: artur shaik 3 | " 4 | " Work with attention highlights 5 | 6 | let s:matchesCount = 0 7 | let s:signId = 271992 8 | sign define jc2signparseproblem text=-> 9 | 10 | function! s:Log(log) 11 | let log = type(a:log) == type("") ? a:log : string(a:log) 12 | call javacomplete#logger#Log("[highlights] ". log) 13 | endfunction 14 | 15 | function! javacomplete#highlights#Drop() 16 | if s:matchesCount > 0 && !empty(getmatches()) 17 | lclose 18 | exe "sign unplace * file=". expand("%:p") 19 | call clearmatches() 20 | call setloclist(0, [], 'f') 21 | let s:matchesCount = len(getmatches()) 22 | endif 23 | endfunction 24 | 25 | function! javacomplete#highlights#ShowProblems(problems) 26 | let loclist = [] 27 | let matchposlist = [] 28 | for problem in a:problems 29 | call extend(loclist,[{ 30 | \ 'bufnr':bufnr('%'), 31 | \ 'lnum': problem['lnum'], 32 | \ 'col': problem['col'], 33 | \ 'text': problem['message']}]) 34 | call add(matchposlist,[problem['lnum'], problem['col']]) 35 | exe ":sign place ".s:signId." line=".problem['lnum']. 36 | \ " name=jc2signparseproblem file=" . expand("%:p") 37 | endfor 38 | if !empty(matchposlist) 39 | let s:matchesCount = len(matchposlist) 40 | call setloclist(0, loclist, 'r') 41 | call matchaddpos("SpellBad", matchposlist) 42 | lopen 43 | endif 44 | endfunction 45 | -------------------------------------------------------------------------------- /autoload/javacomplete/logger.vim: -------------------------------------------------------------------------------- 1 | " Vim completion script for java 2 | " Maintainer: artur shaik 3 | " 4 | " Debug methods 5 | 6 | let s:log = [] 7 | let s:loglevel = 1 8 | if !exists('s:startupDate') 9 | let s:startupDate = reltime() 10 | endif 11 | 12 | function! javacomplete#logger#Enable() 13 | let s:loglevel = 0 14 | endfunction 15 | 16 | function! javacomplete#logger#Disable() 17 | let s:loglevel = 1 18 | endfunction 19 | 20 | function! javacomplete#logger#GetContent() 21 | new 22 | set modifiable 23 | put =s:log 24 | set nomodifiable 25 | set nomodified 26 | endfunction 27 | 28 | function! javacomplete#logger#Log(log) 29 | if 0 >= s:loglevel 30 | let log = type(a:log) == type("") ? a:log : string(a:log) 31 | call add(s:log, reltimestr(reltime(s:startupDate)). " ". log) 32 | endif 33 | endfunction 34 | 35 | " vim:set fdm=marker sw=2 nowrap: 36 | -------------------------------------------------------------------------------- /autoload/javacomplete/version.vim: -------------------------------------------------------------------------------- 1 | " Vim completion script for java 2 | " Maintainer: artur shaik 3 | " 4 | " Version control 5 | 6 | let g:JavaComplete_ServerCompatibilityVersion = "2.4.1" 7 | 8 | function! javacomplete#version#GetCompatibilityVerison() 9 | return g:JavaComplete_ServerCompatibilityVersion 10 | endfunction 11 | 12 | function! javacomplete#version#CompareVersions(scriptVersion, serverVersion) 13 | let scriptVersion = split(a:scriptVersion, '\.') 14 | let serverVersion = split(a:serverVersion, '\.') 15 | while len(scriptVersion) < len(serverVersion) 16 | call add(scriptVersion, '0') 17 | endwhile 18 | while len(serverVersion) < len(scriptVersion) 19 | call add(serverVersion, '0') 20 | endwhile 21 | let i = 0 22 | while i < len(scriptVersion) 23 | if i < len(serverVersion) 24 | if str2nr(scriptVersion[i]) < str2nr(serverVersion[i]) 25 | return -1 26 | elseif str2nr(scriptVersion[i]) > str2nr(serverVersion[i]) 27 | return 1 28 | endif 29 | else 30 | return 1 31 | endif 32 | let i += 1 33 | endwhile 34 | return 0 35 | endfunction 36 | 37 | function! javacomplete#version#CheckServerCompatibility(serverVersion) 38 | return 39 | \ javacomplete#version#CompareVersions( 40 | \ g:JavaComplete_ServerCompatibilityVersion, 41 | \ a:serverVersion) <= 0 42 | endfunction 43 | 44 | " vim:set fdm=marker sw=2 nowrap: 45 | -------------------------------------------------------------------------------- /autoload/javavibridge.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # encoding: utf-8 3 | 4 | import socket 5 | import sys 6 | import tempfile 7 | import time 8 | import subprocess 9 | import os 10 | 11 | # function to get free port from ycmd 12 | def GetUnusedLocalhostPort(): 13 | sock = socket.socket() 14 | # This tells the OS to give us any free port in the range [1024 - 65535] 15 | sock.bind(('', 0)) 16 | port = sock.getsockname()[1] 17 | sock.close() 18 | return port 19 | 20 | SERVER = ('127.0.0.1', GetUnusedLocalhostPort()) 21 | 22 | # A wrapper for subprocess.Popen that works around a Popen bug on Windows. 23 | def SafePopen(args, **kwargs): 24 | if kwargs.get('stdin') is None: 25 | kwargs['stdin'] = subprocess.PIPE if sys.platform == 'win32' else None 26 | 27 | return subprocess.Popen(args, **kwargs) 28 | 29 | class JavaviBridge(): 30 | 31 | pythonVersion = sys.version_info.major 32 | sock = None 33 | popen = None 34 | logfile = None 35 | 36 | def setupServer(self, javabin, args, classpath): 37 | is_win = sys.platform == 'win32' 38 | separator = (';' if is_win else ':') 39 | fileSeparator = ('\\' if is_win else '/') 40 | 41 | classpathset = set(classpath.split(separator)) 42 | 43 | environ = os.environ.copy() 44 | if 'CLASSPATH' in environ: 45 | classpathset.union(environ['CLASSPATH'].split(separator)) 46 | 47 | environ['CLASSPATH'] = separator.join(classpathset) 48 | 49 | if vim.eval('get(g:, "JavaComplete_JavaviLogLevel", 0)') != 0: 50 | defaulttmp = tempfile.gettempdir() + fileSeparator + 'javavi_log' 51 | logdir = vim.eval( 52 | "empty(g:JavaComplete_JavaviLogDirectory) ? '%s' : g:JavaComplete_JavaviLogDirectory" 53 | % defaulttmp) 54 | if not os.path.isdir(logdir): 55 | os.mkdir(logdir) 56 | self.logfile = open("%s%s%s" % ( 57 | logdir, fileSeparator, "javavi_stdout.log"), 58 | "a") 59 | output = self.logfile 60 | else: 61 | output = subprocess.PIPE 62 | 63 | args = [javabin] + args + ['-D', str(SERVER[1])] 64 | if is_win and vim.eval('has("gui_running")'): 65 | info = subprocess.STARTUPINFO() 66 | info.dwFlags = 1 67 | info.wShowWindow = 0 68 | self.popen = SafePopen(args, env=environ, stdout = output, stderr = output, startupinfo = info) 69 | else: 70 | self.popen = SafePopen(args, env=environ, stdout = output, stderr = output) 71 | 72 | def pid(self): 73 | return self.popen.pid 74 | 75 | def port(self): 76 | return SERVER[1] 77 | 78 | def poll(self): 79 | if self.popen: 80 | return self.popen.poll() is None 81 | else: 82 | return 0 83 | 84 | def terminateServer(self): 85 | if self.popen: 86 | self.popen.terminate() 87 | self.popen.wait() 88 | 89 | if self.logfile: 90 | self.logfile.close() 91 | 92 | def makeSocket(self): 93 | try: 94 | self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 95 | except socket.error as msg: 96 | self.sock = None 97 | 98 | try: 99 | self.sock.connect(SERVER) 100 | time.sleep(.1) 101 | except socket.error as msg: 102 | self.sock.close() 103 | self.sock = None 104 | 105 | if self.sock is None: 106 | print('could not open socket, try again') 107 | return 108 | 109 | self.sock.setblocking(0) 110 | 111 | 112 | def send(self, data): 113 | if self.sock is None: 114 | self.makeSocket() 115 | if self.sock is None: 116 | return '' 117 | 118 | if self.pythonVersion == 3: 119 | self.sock.sendall((str(data) + '\n').encode('UTF-8')) 120 | else: 121 | self.sock.sendall((data.decode('UTF-8') + '\n').encode('UTF-8')) 122 | 123 | totalData = [] 124 | while 1: 125 | try: 126 | data = self.sock.recv(4096) 127 | if not data or len(data) == 0: 128 | break 129 | 130 | totalData.append(data.decode('UTF-8')) 131 | time.sleep(0.0001) 132 | except: 133 | if totalData: break 134 | 135 | self.sock.close() 136 | self.sock = None 137 | return ''.join(totalData) 138 | -------------------------------------------------------------------------------- /classpath.gradle: -------------------------------------------------------------------------------- 1 | task classpath { 2 | doLast { 3 | HashSet classpathFiles = new HashSet() 4 | for (project in allprojects) { 5 | if (project.hasProperty('android')) { 6 | project.android.getBootClasspath().each { 7 | classpathFiles += it 8 | } 9 | if (project.android.hasProperty('applicationVariants')) { 10 | project.android.applicationVariants.all { variant -> 11 | 12 | def variantBase = variant.baseName.replaceAll("-", File.separator) 13 | 14 | def buildClasses = project.getBuildDir().absolutePath + 15 | File.separator + "intermediates" + 16 | File.separator + "classes" + 17 | File.separator + variantBase 18 | 19 | classpathFiles += buildClasses 20 | 21 | def userClasses = project.getBuildDir().absolutePath + 22 | File.separator + "intermediates" + 23 | File.separator + "javac" + 24 | File.separator + variant.baseName.replaceAll("-", File.separator) + 25 | File.separator + "compile" + variantBase.capitalize() + "JavaWithJavac" + File.separator + "classes" 26 | 27 | classpathFiles += userClasses 28 | 29 | variant.getCompileClasspath().each { 30 | classpathFiles += it 31 | } 32 | } 33 | } 34 | } else { 35 | // Print the list of all dependencies jar files. 36 | project.configurations.findAll { 37 | it.metaClass.respondsTo(it, "isCanBeResolved") ? it.isCanBeResolved() : false 38 | }.each { 39 | it.resolve().each { 40 | if (it.inspect().endsWith("jar")) { 41 | classpathFiles += it 42 | } else if (it.inspect().endsWith("aar")) { 43 | // If the dependency is an AAR file we try to determine the location 44 | // of the classes.jar file in the exploded aar folder. 45 | def splitted = it.inspect().split("/") 46 | def namespace = splitted[-5] 47 | def name = splitted[-4] 48 | def version = splitted[-3] 49 | def explodedPath = "$project.buildDir/intermediates/exploded-aar/$namespace/$name/$version/jars/classes.jar" 50 | classpathFiles += explodedPath 51 | } 52 | } 53 | } 54 | } 55 | } 56 | def classpath = classpathFiles.join(File.pathSeparator) 57 | println "CLASSPATH:" + classpath 58 | println "END CLASSPATH GENERATION" 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /doc/demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/artur-shaik/vim-javacomplete2/a716e32bbe36daaed6ebc9aae76525aad9536245/doc/demo.gif -------------------------------------------------------------------------------- /doc/generics_demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/artur-shaik/vim-javacomplete2/a716e32bbe36daaed6ebc9aae76525aad9536245/doc/generics_demo.gif -------------------------------------------------------------------------------- /libs/javaparser-core-3.5.20.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/artur-shaik/vim-javacomplete2/a716e32bbe36daaed6ebc9aae76525aad9536245/libs/javaparser-core-3.5.20.jar -------------------------------------------------------------------------------- /libs/javavi/pom.xml: -------------------------------------------------------------------------------- 1 | 4 | 4.0.0 5 | 6 | kg.ash.javavi 7 | javavi 8 | 1.0-SNAPSHOT 9 | jar 10 | 11 | javavi 12 | http://maven.apache.org 13 | 14 | 15 | UTF-8 16 | 17 | 18 | 19 | 20 | com.github.javaparser 21 | javaparser-core 22 | 3.5.20 23 | 24 | 25 | kg.ash.javavi.apache.logging.log4j 26 | log4j-api 27 | 2.7 28 | system 29 | ${basedir}/../javavi_log4j-api.jar 30 | 31 | 32 | kg.ash.javavi.apache.logging.log4j 33 | log4j-core 34 | 2.7 35 | system 36 | ${basedir}/../javavi_log4j-core.jar 37 | 38 | 39 | junit 40 | junit 41 | 4.13.1 42 | test 43 | 44 | 45 | org.json 46 | json 47 | 20150729 48 | test 49 | 50 | 51 | org.jmockit 52 | jmockit 53 | 1.20 54 | test 55 | 56 | 57 | 58 | 59 | 60 | 61 | org.apache.maven.plugins 62 | maven-compiler-plugin 63 | 3.1 64 | 65 | 1.8 66 | 1.8 67 | 68 | 69 | 70 | org.codehaus.mojo 71 | exec-maven-plugin 72 | 1.3.2 73 | 74 | java 75 | 76 | -Xms512m 77 | -Xmx512m 78 | -XX:NewRatio=3 79 | -XX:+PrintGCTimeStamps 80 | -XX:+PrintGCDetails 81 | -Xloggc:gc.log 82 | -classpath 83 | 84 | kg.ash.javavi.Javavi 85 | 86 | 87 | 88 | 89 | 90 | org.apache.maven.plugins 91 | maven-jar-plugin 92 | 2.4 93 | 94 | 95 | 96 | true 97 | lib/ 98 | kg.ash.javavi.Javavi 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | -------------------------------------------------------------------------------- /libs/javavi/src/main/java/kg/ash/javavi/Daemon.java: -------------------------------------------------------------------------------- 1 | package kg.ash.javavi; 2 | 3 | import kg.ash.javavi.apache.logging.log4j.LogManager; 4 | import kg.ash.javavi.apache.logging.log4j.Logger; 5 | import kg.ash.javavi.cache.Cache; 6 | 7 | import java.io.BufferedReader; 8 | import java.io.IOException; 9 | import java.io.InputStreamReader; 10 | import java.io.PrintStream; 11 | import java.net.ServerSocket; 12 | import java.net.Socket; 13 | import java.util.LinkedList; 14 | import java.util.List; 15 | import java.util.Timer; 16 | import java.util.TimerTask; 17 | 18 | public class Daemon extends Thread { 19 | 20 | public static final Logger logger = LogManager.getLogger(); 21 | 22 | private int port; 23 | private int timeoutSeconds; 24 | private Timer timeoutTimer = new Timer(); 25 | private TimerTask timeoutTask; 26 | 27 | public Daemon(int port, int timeoutSeconds) { 28 | this.port = port; 29 | this.timeoutSeconds = timeoutSeconds; 30 | } 31 | 32 | public void run() { 33 | ServerSocket echoServer = null; 34 | Cache.getInstance().collectPackages(); 35 | 36 | while (true) { 37 | if (timeoutSeconds > 0) { 38 | timeoutTask = new TimeoutTask(); 39 | timeoutTimer.schedule(timeoutTask, timeoutSeconds * 1000); 40 | } 41 | 42 | try { 43 | if (echoServer == null) { 44 | echoServer = new ServerSocket(port); 45 | } 46 | } catch (IOException e) { 47 | logger.warn(e); 48 | break; 49 | } 50 | 51 | try (Socket clientSocket = echoServer.accept()) { 52 | if (timeoutTask != null) { 53 | timeoutTask.cancel(); 54 | } 55 | 56 | try (BufferedReader is = new BufferedReader( 57 | new InputStreamReader(clientSocket.getInputStream())); 58 | PrintStream os = new PrintStream(clientSocket.getOutputStream())) { 59 | while (true) { 60 | String[] request = parseRequest(is.readLine()); 61 | if (request != null) { 62 | os.print(Javavi.makeResponse(request)); 63 | } 64 | break; 65 | } 66 | } catch (Throwable e) { 67 | logger.error(e, e); 68 | } 69 | } catch (IOException e) { 70 | logger.error(e); 71 | break; 72 | } 73 | } 74 | } 75 | 76 | public String[] parseRequest(String request) { 77 | if (request == null) { 78 | return null; 79 | } 80 | 81 | List args = new LinkedList<>(); 82 | 83 | StringBuilder buff = new StringBuilder(); 84 | boolean quoteFlag = false; 85 | boolean slashFlag = false; 86 | for (char ch : request.toCharArray()) { 87 | if (quoteFlag) { 88 | if (ch == '\\') { 89 | if (slashFlag) { 90 | buff.append("\\"); 91 | slashFlag = false; 92 | } else { 93 | slashFlag = true; 94 | } 95 | continue; 96 | } 97 | if (ch == '"' && !slashFlag) { 98 | if (buff.length() == 0) { 99 | args.add(""); 100 | } 101 | quoteFlag = false; 102 | continue; 103 | } 104 | } 105 | 106 | if (ch == '"' && !slashFlag) { 107 | quoteFlag = true; 108 | } 109 | 110 | if (!quoteFlag) { 111 | if (ch == ' ') { 112 | if (buff.length() > 0) { 113 | args.add(buff.toString()); 114 | buff = new StringBuilder(); 115 | } 116 | continue; 117 | } 118 | } 119 | 120 | if ((ch != '"' && !slashFlag) || ((ch == '"' || ch == 'n') && slashFlag)) { 121 | if (slashFlag && ch != '"') { 122 | buff.append('\\'); 123 | } 124 | buff.append(ch); 125 | } 126 | 127 | if (slashFlag) { 128 | slashFlag = false; 129 | } 130 | } 131 | if (buff.length() > 0) { 132 | args.add(buff.toString()); 133 | } 134 | 135 | return args.toArray(new String[0]); 136 | } 137 | 138 | class TimeoutTask extends TimerTask { 139 | public void run() { 140 | logger.info("Shutdown by timeout timer."); 141 | System.exit(0); 142 | } 143 | } 144 | } 145 | -------------------------------------------------------------------------------- /libs/javavi/src/main/java/kg/ash/javavi/Javavi.java: -------------------------------------------------------------------------------- 1 | package kg.ash.javavi; 2 | 3 | import kg.ash.javavi.actions.Action; 4 | import kg.ash.javavi.actions.ActionFactory; 5 | import kg.ash.javavi.apache.logging.log4j.LogManager; 6 | import kg.ash.javavi.apache.logging.log4j.Logger; 7 | import kg.ash.javavi.searchers.ClasspathCollector; 8 | 9 | import java.util.HashMap; 10 | 11 | public class Javavi { 12 | 13 | public static final String VERSION = "2.4.3"; 14 | 15 | public static String NEWLINE = ""; 16 | 17 | public static final Logger logger = LogManager.getLogger(); 18 | 19 | static void output(String s) { 20 | System.out.print(s); 21 | } 22 | 23 | private static void usage() { 24 | version(); 25 | System.out.println( 26 | " java [-classpath] kg.ash.javavi.Javavi [-sources sourceDirs] [-h] [-v] [-d] [-D " 27 | + "port] [action]"); 28 | System.out.println("Options:"); 29 | System.out.println(" -h help"); 30 | System.out.println(" -v version"); 31 | System.out.println(" -sources sources directory"); 32 | System.out.println(" -d enable debug mode"); 33 | System.out.println(" -D port start daemon on specified port"); 34 | } 35 | 36 | private static void version() { 37 | System.out.println("Reflection and parsing for javavi " + "vim plugin (" + VERSION + ")"); 38 | } 39 | 40 | public static HashMap system = new HashMap<>(); 41 | public static Daemon daemon = null; 42 | 43 | public static void main(String[] args) { 44 | logger.info("starting javavi server on port: {}", System.getProperty("daemon.port", "0")); 45 | 46 | if (logger.isTraceEnabled()) { 47 | logger.trace("output included libraries"); 48 | new ClasspathCollector().collectClassPath().forEach(logger::trace); 49 | } 50 | 51 | String response = makeResponse(args); 52 | 53 | output(response); 54 | } 55 | 56 | public static String makeResponse(String[] args) { 57 | 58 | long ms = System.currentTimeMillis(); 59 | Action action = null; 60 | boolean asyncRun = false; 61 | for (int i = 0; i < args.length; i++) { 62 | String arg = args[i]; 63 | logger.debug("argument: {}", arg); 64 | switch (arg) { 65 | case "-h": 66 | usage(); 67 | return ""; 68 | case "-v": 69 | version(); 70 | return ""; 71 | case "-sources": 72 | system.put("sources", args[++i]); 73 | break; 74 | case "-n": 75 | NEWLINE = "\n"; 76 | break; 77 | case "-base": 78 | system.put("base", args[++i]); 79 | break; 80 | case "-project": 81 | system.put("project", args[++i]); 82 | break; 83 | case "-compiler": 84 | system.put("compiler", args[++i]); 85 | break; 86 | case "-async": 87 | asyncRun = true; 88 | break; 89 | default: 90 | if (action == null) { 91 | action = ActionFactory.get(arg); 92 | } 93 | } 94 | 95 | if (action != null) { 96 | break; 97 | } 98 | } 99 | 100 | String result = ""; 101 | if (action != null) { 102 | logger.debug("new {} action: \"{}\"", asyncRun ? "async" : "", 103 | action.getClass().getSimpleName()); 104 | 105 | if (asyncRun) { 106 | final Action a = action; 107 | new Thread(() -> a.perform(args)).start(); 108 | } else { 109 | result = action.perform(args); 110 | } 111 | } 112 | logger.debug("action time: {}ms", (System.currentTimeMillis() - ms)); 113 | return result; 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /libs/javavi/src/main/java/kg/ash/javavi/TargetParser.java: -------------------------------------------------------------------------------- 1 | package kg.ash.javavi; 2 | 3 | import kg.ash.javavi.searchers.ClassSearcher; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | import java.util.regex.Matcher; 8 | import java.util.regex.Pattern; 9 | 10 | public class TargetParser { 11 | 12 | private final Pattern pattern = Pattern.compile("^(.*?)<(.*)>$"); 13 | private final Pattern extendsPattern = Pattern.compile("^?[\\s]+(super|extends)\\s+(.*)$"); 14 | private final ClassSearcher seacher = new ClassSearcher(); 15 | 16 | private final List typeArguments = new ArrayList<>(); 17 | private String sources; 18 | 19 | public TargetParser(String sources) { 20 | this.sources = sources; 21 | } 22 | 23 | public String parse(String target) { 24 | typeArguments.clear(); 25 | 26 | Matcher matcher = pattern.matcher(target); 27 | if (matcher.find()) { 28 | target = matcher.group(1); 29 | String ta = markSplits(matcher.group(2)); 30 | for (String arguments : ta.split("<_split_>")) { 31 | parseArguments(arguments); 32 | } 33 | } 34 | 35 | return target; 36 | } 37 | 38 | private void parseArguments(String arguments) { 39 | arguments = arguments.replaceAll("(\\(|\\))", ""); 40 | String[] argumentVariants = arguments.split("\\|"); 41 | boolean added = false; 42 | for (String arg : argumentVariants) { 43 | Matcher argMatcher = pattern.matcher(arg); 44 | boolean matchResult = argMatcher.find(); 45 | if (matchResult) { 46 | arg = argMatcher.group(1); 47 | } 48 | String name = getExactName(arg); 49 | if (seacher.find(name.replaceAll("(\\[|\\])", ""), sources)) { 50 | if (matchResult && !argMatcher.group(2).equals("?")) { 51 | typeArguments.add(String.format("%s<%s>", name, argMatcher.group(2))); 52 | } else { 53 | typeArguments.add(name); 54 | } 55 | added = true; 56 | break; 57 | } 58 | } 59 | 60 | if (!added) { 61 | typeArguments.add("java.lang.Object"); 62 | } 63 | } 64 | 65 | private String getExactName(String name) { 66 | Matcher matcher = extendsPattern.matcher(name); 67 | if (matcher.find()) { 68 | name = matcher.group(2); 69 | } 70 | 71 | return name; 72 | } 73 | 74 | private String markSplits(String ta) { 75 | int i = 0; 76 | int lbr = 0; 77 | while (i < ta.length()) { 78 | char c = ta.charAt(i); 79 | if (c == '<') { 80 | lbr++; 81 | } else if (c == '>') { 82 | lbr--; 83 | } else if (c == ',' && lbr == 0) { 84 | ta = ta.substring(0, i) + "<_split_>" + ta.substring(i + 1, ta.length()); 85 | i += 9; 86 | } 87 | 88 | i++; 89 | } 90 | 91 | return ta; 92 | } 93 | 94 | public List getTypeArguments() { 95 | return typeArguments; 96 | } 97 | 98 | public String getTypeArgumentsString() { 99 | return getTypeArgumentsString(this.typeArguments); 100 | } 101 | 102 | public static String getTypeArgumentsString(List typeArguments) { 103 | if (typeArguments.isEmpty()) { 104 | return ""; 105 | } 106 | 107 | StringBuilder builder = new StringBuilder("<"); 108 | for (String arg : typeArguments) { 109 | builder.append(arg).append(","); 110 | } 111 | builder.setCharAt(builder.length() - 1, '>'); 112 | return builder.toString(); 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /libs/javavi/src/main/java/kg/ash/javavi/actions/Action.java: -------------------------------------------------------------------------------- 1 | package kg.ash.javavi.actions; 2 | 3 | public interface Action { 4 | String perform(String[] args); 5 | } 6 | -------------------------------------------------------------------------------- /libs/javavi/src/main/java/kg/ash/javavi/actions/ActionFactory.java: -------------------------------------------------------------------------------- 1 | package kg.ash.javavi.actions; 2 | 3 | import java.util.Map; 4 | 5 | public class ActionFactory { 6 | public static Action get(String action) { 7 | switch (action) { 8 | case "-E": 9 | return new GetClassInfoAction(); 10 | case "-p": 11 | return new GetPackageInfoAction(); 12 | case "-s": 13 | return new GetClassInfoFromSourceAction(); 14 | case "-class-packages": 15 | return new GetClassPackagesAction(); 16 | case "-similar-classes": 17 | return new FilterSimilarClassesAction(); 18 | case "-similar-annotations": 19 | return new FilterSimilarAnnotationsAction(); 20 | case "-D": 21 | return new ExecuteDaemonAction(); 22 | case "-unused-imports": 23 | return new GetUnusedImportsAction(); 24 | case "-missing-imports": 25 | return new GetMissingImportsAction(); 26 | case "-clear-from-cache": 27 | return new RemoveClassInfoFromCache(); 28 | case "-recompile-class": 29 | return new ClassRecompileAction(); 30 | case "-collect-packages": 31 | return new CollectPackagesAction(); 32 | case "-fetch-class-archives": 33 | return new GetClassesArchiveNamesAction(); 34 | case "-class-info-by-content": 35 | return new ParseByContentAction(); 36 | case "-get-debug-log-path": 37 | return new GetDebugLogPath(); 38 | case "-version": 39 | return new GetAppVersion(); 40 | case "-add-source-to-cache": 41 | return new AddClassToCacheAction(); 42 | } 43 | return null; 44 | } 45 | 46 | public static String getJavaViSources(Map javaViSystem) { 47 | String sources = javaViSystem.get("sources"); 48 | return sources != null ? sources.replace('\\', '/') : ""; 49 | } 50 | 51 | public static String getArgWithName(String[] args, String name) { 52 | for (int i = 0; i < args.length; i++) { 53 | if (args[i].equals(name)) { 54 | return args[i + 1]; 55 | } 56 | } 57 | return ""; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /libs/javavi/src/main/java/kg/ash/javavi/actions/ActionWithTarget.java: -------------------------------------------------------------------------------- 1 | package kg.ash.javavi.actions; 2 | 3 | import static kg.ash.javavi.actions.ActionFactory.getJavaViSources; 4 | 5 | import kg.ash.javavi.Javavi; 6 | import kg.ash.javavi.TargetParser; 7 | 8 | public abstract class ActionWithTarget implements Action { 9 | 10 | protected TargetParser targetParser; 11 | protected String sources; 12 | 13 | public ActionWithTarget() { 14 | sources = getJavaViSources(Javavi.system); 15 | targetParser = new TargetParser(sources); 16 | } 17 | 18 | protected String parseTarget(String[] args) { 19 | if (args.length > 0) { 20 | return targetParser.parse(args[args.length - 1]); 21 | } 22 | return ""; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /libs/javavi/src/main/java/kg/ash/javavi/actions/AddClassToCacheAction.java: -------------------------------------------------------------------------------- 1 | package kg.ash.javavi.actions; 2 | 3 | import static kg.ash.javavi.actions.ActionFactory.getArgWithName; 4 | 5 | import kg.ash.javavi.apache.logging.log4j.LogManager; 6 | import kg.ash.javavi.apache.logging.log4j.Logger; 7 | import kg.ash.javavi.cache.Cache; 8 | import kg.ash.javavi.searchers.ClassNameMap; 9 | import kg.ash.javavi.searchers.JavaClassMap; 10 | 11 | public class AddClassToCacheAction implements Action { 12 | 13 | public static final Logger logger = LogManager.getLogger(); 14 | 15 | @Override 16 | public String perform(String[] args) { 17 | String sourceFileArg = getArgWithName(args, "-source"); 18 | String classNameArg = getArgWithName(args, "-class"); 19 | String packageNameArg = getArgWithName(args, "-package"); 20 | 21 | ClassNameMap cnm = (ClassNameMap) Cache.getInstance().getClassPackages().get(classNameArg); 22 | if (cnm == null) { 23 | cnm = new ClassNameMap(classNameArg); 24 | } 25 | 26 | cnm.setJavaFile(sourceFileArg); 27 | cnm.add(packageNameArg, JavaClassMap.SOURCETYPE_SOURCES, JavaClassMap.TYPE_SUBPACKAGE, 28 | null); 29 | 30 | Cache.getInstance().getClassPackages().put(classNameArg, cnm); 31 | return ""; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /libs/javavi/src/main/java/kg/ash/javavi/actions/ClassRecompileAction.java: -------------------------------------------------------------------------------- 1 | package kg.ash.javavi.actions; 2 | 3 | import kg.ash.javavi.Javavi; 4 | import kg.ash.javavi.apache.logging.log4j.LogManager; 5 | import kg.ash.javavi.apache.logging.log4j.Logger; 6 | import kg.ash.javavi.cache.Cache; 7 | import kg.ash.javavi.searchers.ClassNameMap; 8 | import kg.ash.javavi.searchers.JavaClassMap; 9 | 10 | import java.io.File; 11 | 12 | public class ClassRecompileAction extends ActionWithTarget { 13 | 14 | public static final Logger logger = LogManager.getLogger(); 15 | 16 | @Override 17 | public String perform(String[] args) { 18 | String target = parseTarget(args); 19 | String[] splitted = target.split("\\."); 20 | 21 | ClassNameMap classMap = findClass(splitted[splitted.length - 1]); 22 | if (classMap != null && classMap.getClassFile() != null && classMap.getJavaFile() != null) { 23 | String classFile = classMap.getClassFile(); 24 | String sourceFile = classMap.getJavaFile(); 25 | String classDir = classFile.substring(0, classFile.lastIndexOf(File.separator)); 26 | 27 | int offset = findOffset(sourceFile.substring(0, sourceFile.lastIndexOf(File.separator)), 28 | classDir); 29 | classDir = classFile.substring(0, offset); 30 | 31 | if (classDir.isEmpty()) { 32 | return ""; 33 | } 34 | 35 | String compiler = Javavi.system.get("compiler"); 36 | String classPath = System.getProperty("java.class.path"); 37 | 38 | execute(String.format("%s -cp %s -d %s %s", compiler, classPath, classDir, sourceFile)); 39 | } 40 | 41 | return ""; 42 | } 43 | 44 | private void execute(String command) { 45 | try { 46 | Process p = Runtime.getRuntime().exec(command); 47 | p.waitFor(); 48 | } catch (Exception e) { 49 | logger.error(e); 50 | } 51 | } 52 | 53 | private int findOffset(String sourceFile, String classDir) { 54 | int offset = 0; 55 | while (!sourceFile.endsWith(classDir)) { 56 | int index = classDir.indexOf(File.separator, 2); 57 | if (index == 0) { 58 | return 0; 59 | } 60 | 61 | classDir = classDir.substring(index); 62 | offset += index; 63 | } 64 | return offset; 65 | } 66 | 67 | private ClassNameMap findClass(String name) { 68 | JavaClassMap classMap = Cache.getInstance().getClassPackages().get(name); 69 | if (classMap != null && classMap instanceof ClassNameMap) { 70 | return (ClassNameMap) classMap; 71 | } 72 | return null; 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /libs/javavi/src/main/java/kg/ash/javavi/actions/CollectPackagesAction.java: -------------------------------------------------------------------------------- 1 | package kg.ash.javavi.actions; 2 | 3 | import kg.ash.javavi.cache.Cache; 4 | 5 | public class CollectPackagesAction implements Action { 6 | 7 | @Override 8 | public String perform(String[] args) { 9 | Cache.getInstance().getClassPackages().clear(); 10 | Cache.getInstance().collectPackages(); 11 | return ""; 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /libs/javavi/src/main/java/kg/ash/javavi/actions/ExecuteDaemonAction.java: -------------------------------------------------------------------------------- 1 | package kg.ash.javavi.actions; 2 | 3 | import kg.ash.javavi.Daemon; 4 | import kg.ash.javavi.Javavi; 5 | import kg.ash.javavi.apache.logging.log4j.LogManager; 6 | import kg.ash.javavi.apache.logging.log4j.Logger; 7 | 8 | public class ExecuteDaemonAction implements Action { 9 | 10 | public static final Logger logger = LogManager.getLogger(); 11 | 12 | @Override 13 | public String perform(String[] args) { 14 | if (Javavi.daemon != null) { 15 | return ""; 16 | } 17 | 18 | Integer daemonPort = Integer.valueOf(System.getProperty("daemon.port", "0")); 19 | if (daemonPort == 0) { 20 | return "Error: daemonPort is null"; 21 | } 22 | 23 | logger.debug("starting daemon mode"); 24 | Javavi.daemon = new Daemon(daemonPort, -1); 25 | Javavi.daemon.start(); 26 | 27 | return ""; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /libs/javavi/src/main/java/kg/ash/javavi/actions/FilterSimilarAnnotationsAction.java: -------------------------------------------------------------------------------- 1 | package kg.ash.javavi.actions; 2 | 3 | import kg.ash.javavi.cache.Cache; 4 | import kg.ash.javavi.output.OutputSimilarAnnotations; 5 | 6 | public class FilterSimilarAnnotationsAction extends ActionWithTarget { 7 | 8 | @Override 9 | public String perform(String[] args) { 10 | return new OutputSimilarAnnotations(Cache.getInstance().getClassPackages()).get( 11 | parseTarget(args)); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /libs/javavi/src/main/java/kg/ash/javavi/actions/FilterSimilarClassesAction.java: -------------------------------------------------------------------------------- 1 | package kg.ash.javavi.actions; 2 | 3 | import kg.ash.javavi.cache.Cache; 4 | import kg.ash.javavi.output.OutputSimilarClasses; 5 | 6 | public class FilterSimilarClassesAction extends ActionWithTarget { 7 | 8 | @Override 9 | public String perform(String[] args) { 10 | return new OutputSimilarClasses(Cache.getInstance().getClassPackages()).get( 11 | parseTarget(args)); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /libs/javavi/src/main/java/kg/ash/javavi/actions/GetAppVersion.java: -------------------------------------------------------------------------------- 1 | package kg.ash.javavi.actions; 2 | 3 | import kg.ash.javavi.Javavi; 4 | 5 | public class GetAppVersion implements Action { 6 | 7 | @Override 8 | public String perform(String[] args) { 9 | return Javavi.VERSION; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /libs/javavi/src/main/java/kg/ash/javavi/actions/GetClassInfoAction.java: -------------------------------------------------------------------------------- 1 | package kg.ash.javavi.actions; 2 | 3 | import kg.ash.javavi.clazz.SourceClass; 4 | import kg.ash.javavi.output.OutputClassInfo; 5 | import kg.ash.javavi.readers.ClassReader; 6 | import kg.ash.javavi.searchers.ClassSearcher; 7 | 8 | public class GetClassInfoAction extends ActionWithTarget { 9 | 10 | @Override 11 | public String perform(String[] args) { 12 | String target = parseTarget(args); 13 | 14 | ClassSearcher searcher = new ClassSearcher(); 15 | boolean found = true; 16 | while (!searcher.find(target, sources)) { 17 | if (!target.contains(".")) { 18 | found = false; 19 | break; 20 | } 21 | target = target.substring(0, target.lastIndexOf(".")); 22 | } 23 | 24 | if (found) { 25 | ClassReader reader = searcher.getReader(); 26 | reader.setTypeArguments(targetParser.getTypeArguments()); 27 | SourceClass clazz = reader.read(target); 28 | if (clazz != null) { 29 | return new OutputClassInfo().get(clazz); 30 | } 31 | } 32 | return ""; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /libs/javavi/src/main/java/kg/ash/javavi/actions/GetClassInfoFromSourceAction.java: -------------------------------------------------------------------------------- 1 | package kg.ash.javavi.actions; 2 | 3 | import kg.ash.javavi.output.OutputClassInfo; 4 | import kg.ash.javavi.readers.Parser; 5 | 6 | public class GetClassInfoFromSourceAction extends ActionWithTarget { 7 | 8 | @Override 9 | public String perform(String[] args) { 10 | Parser parser = new Parser(sources, parseTarget(args)); 11 | return new OutputClassInfo().get(parser.read(null)); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /libs/javavi/src/main/java/kg/ash/javavi/actions/GetClassPackagesAction.java: -------------------------------------------------------------------------------- 1 | package kg.ash.javavi.actions; 2 | 3 | import kg.ash.javavi.cache.Cache; 4 | import kg.ash.javavi.output.OutputClassPackages; 5 | 6 | public class GetClassPackagesAction extends ActionWithTarget { 7 | 8 | @Override 9 | public String perform(String[] args) { 10 | return new OutputClassPackages(Cache.getInstance().getClassPackages()).get( 11 | parseTarget(args)); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /libs/javavi/src/main/java/kg/ash/javavi/actions/GetClassesArchiveNamesAction.java: -------------------------------------------------------------------------------- 1 | package kg.ash.javavi.actions; 2 | 3 | import kg.ash.javavi.apache.logging.log4j.LogManager; 4 | import kg.ash.javavi.apache.logging.log4j.Logger; 5 | import kg.ash.javavi.cache.Cache; 6 | import kg.ash.javavi.searchers.JavaClassMap; 7 | 8 | import java.util.ArrayList; 9 | import java.util.Arrays; 10 | import java.util.HashMap; 11 | import java.util.List; 12 | import java.util.Map; 13 | 14 | public class GetClassesArchiveNamesAction extends ActionWithTarget { 15 | 16 | public static final Logger logger = LogManager.getLogger(); 17 | 18 | @Override 19 | public String perform(String[] args) { 20 | String classes = parseTarget(args); 21 | 22 | Map> result = new HashMap<>(); 23 | for (String _classFqn : classes.split(",")) { 24 | final String classFqn = removeStaticKeyword(_classFqn); 25 | 26 | String[] classFqnArray = classFqn.split("\\."); 27 | String className = classFqnArray[classFqnArray.length - 1]; 28 | 29 | logger.debug("class name: {}", className); 30 | 31 | HashMap classPackages = getClassPackages(); 32 | if (classPackages.containsKey(className)) { 33 | String classPackage = removeLastElementAndJoin(classFqnArray); 34 | 35 | logger.debug("class name: {}", className); 36 | 37 | JavaClassMap cm = classPackages.get(className); 38 | Arrays.stream(new String[] { "", "$" }).forEach(s -> { 39 | if (cm.getSubpackages().get(classPackage + s) != null) { 40 | String fileName = cm.getSubpackages().get(classPackage + s); 41 | if (result.containsKey(fileName)) { 42 | result.get(fileName).add(classFqn); 43 | } else { 44 | result.put(fileName, new ArrayList<>(Arrays.asList(classFqn))); 45 | } 46 | } 47 | }); 48 | } 49 | } 50 | return String.format("[%s]", buildResult(result)); 51 | } 52 | 53 | private String removeStaticKeyword(String classFqn) { 54 | if (classFqn.contains(" ")) { 55 | return classFqn.split(" ")[1]; 56 | } 57 | return classFqn; 58 | } 59 | 60 | private HashMap getClassPackages() { 61 | return Cache.getInstance().getClassPackages(); 62 | } 63 | 64 | private String removeLastElementAndJoin(String[] array) { 65 | String[] newArray = new String[array.length - 1]; 66 | System.arraycopy(array, 0, newArray, 0, newArray.length); 67 | return String.join(".", newArray); 68 | } 69 | 70 | private StringBuilder buildResult(Map> result) { 71 | StringBuilder builder = new StringBuilder(); 72 | result.forEach((s, l) -> { 73 | builder.append("['").append(s).append("',["); 74 | l.forEach(classFqn -> builder.append("'").append(classFqn).append("',")); 75 | builder.append("]],"); 76 | }); 77 | return builder; 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /libs/javavi/src/main/java/kg/ash/javavi/actions/GetDebugLogPath.java: -------------------------------------------------------------------------------- 1 | package kg.ash.javavi.actions; 2 | 3 | import kg.ash.javavi.apache.logging.log4j.LogManager; 4 | import kg.ash.javavi.apache.logging.log4j.core.LoggerContext; 5 | import kg.ash.javavi.apache.logging.log4j.core.lookup.StrLookup; 6 | 7 | public class GetDebugLogPath implements Action { 8 | 9 | @Override 10 | public String perform(String[] args) { 11 | LoggerContext ctx = (LoggerContext) LogManager.getContext(); 12 | StrLookup lookup = (ctx.getConfiguration()).getStrSubstitutor().getVariableResolver(); 13 | String timeId = lookup.lookup("log.time_id"); 14 | String logsDirectory = System.getProperty("log.directory", lookup.lookup("log.directory")); 15 | String daemonPort = System.getProperty("daemon.port", lookup.lookup("daemon.port")); 16 | return String.format("%s/%s-%s.log", logsDirectory, timeId, daemonPort); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /libs/javavi/src/main/java/kg/ash/javavi/actions/GetMissingImportsAction.java: -------------------------------------------------------------------------------- 1 | package kg.ash.javavi.actions; 2 | 3 | import com.github.javaparser.ast.ImportDeclaration; 4 | import com.github.javaparser.ast.Node; 5 | import com.github.javaparser.printer.PrettyPrinter; 6 | import com.github.javaparser.printer.PrettyPrinterConfiguration; 7 | import kg.ash.javavi.clazz.ClassImport; 8 | 9 | import java.util.ArrayList; 10 | import java.util.List; 11 | 12 | public class GetMissingImportsAction extends ImportsAction { 13 | 14 | // TODO(joshleeb): Move this somewhere nice. 15 | private static String removeComments(Node n) { 16 | PrettyPrinterConfiguration config = new PrettyPrinterConfiguration(); 17 | config.setPrintComments(false); 18 | return new PrettyPrinter(config).print(n); 19 | } 20 | 21 | @Override 22 | public String action() { 23 | List importTails = new ArrayList<>(); 24 | List asteriskImports = new ArrayList<>(); 25 | if (compilationUnit.getImports() != null) { 26 | for (ImportDeclaration importDeclaration : 27 | compilationUnit.getImports()) { 28 | ClassImport classImport = new ClassImport( 29 | removeComments( 30 | importDeclaration.getName()), 31 | importDeclaration.isStatic(), 32 | importDeclaration.isAsterisk()); 33 | if (classImport.isAsterisk()) { 34 | asteriskImports.add(classImport.getName()); 35 | } else { 36 | importTails.add(classImport.getTail()); 37 | } 38 | } 39 | } 40 | 41 | if (compilationUnit.getPackageDeclaration().isPresent()) { 42 | asteriskImports.add( 43 | removeComments( 44 | compilationUnit.getPackageDeclaration(). 45 | get().getName())); 46 | } 47 | 48 | StringBuilder result = new StringBuilder("{'imports':["); 49 | for (String classname : classnames) { 50 | if (!importTails.contains(classname)) { 51 | GetClassPackagesAction getPackagesAction = 52 | new GetClassPackagesAction(); 53 | String packages = getPackagesAction.perform( 54 | new String[] { classname }); 55 | 56 | if (packages.startsWith("message:")) { 57 | return packages; 58 | } else if (packages.length() == 2) { 59 | continue; 60 | } 61 | 62 | String[] splitted = packages.substring( 63 | 1, packages.length() - 1).split(","); 64 | boolean found = false; 65 | for (String foundPackage : splitted) { 66 | if (foundPackage.trim().isEmpty()) { 67 | continue; 68 | } 69 | 70 | for (String asteriskImport : asteriskImports) { 71 | if (isolatePackage(foundPackage) 72 | .equals(asteriskImport)) { 73 | found = true; 74 | break; 75 | } 76 | } 77 | } 78 | if (!found) { 79 | if (declarations.contains(classname)) { 80 | found = true; 81 | } 82 | } 83 | if (!found) { 84 | result.append(packages).append(","); 85 | } 86 | } 87 | } 88 | return result.append("]}").toString(); 89 | } 90 | 91 | private static String isolatePackage(String pkg) { 92 | pkg = pkg.trim().substring(1, pkg.length() - 1); 93 | return pkg.substring(0, pkg.lastIndexOf(".")); 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /libs/javavi/src/main/java/kg/ash/javavi/actions/GetPackageInfoAction.java: -------------------------------------------------------------------------------- 1 | package kg.ash.javavi.actions; 2 | 3 | import kg.ash.javavi.cache.Cache; 4 | import kg.ash.javavi.output.OutputPackageInfo; 5 | 6 | public class GetPackageInfoAction extends ActionWithTarget { 7 | 8 | @Override 9 | public String perform(String[] args) { 10 | return new OutputPackageInfo(Cache.getInstance().getClassPackages()).get(parseTarget(args)); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /libs/javavi/src/main/java/kg/ash/javavi/actions/GetUnusedImportsAction.java: -------------------------------------------------------------------------------- 1 | package kg.ash.javavi.actions; 2 | 3 | import com.github.javaparser.ast.ImportDeclaration; 4 | import com.github.javaparser.ast.Node; 5 | import com.github.javaparser.printer.PrettyPrinter; 6 | import com.github.javaparser.printer.PrettyPrinterConfiguration; 7 | import kg.ash.javavi.clazz.ClassImport; 8 | 9 | public class GetUnusedImportsAction extends ImportsAction { 10 | 11 | @Override 12 | public String action() { 13 | StringBuilder result = new StringBuilder("{'imports':["); 14 | for (ImportDeclaration importDeclaration : 15 | compilationUnit.getImports()) { 16 | if (importDeclaration.isAsterisk()) { 17 | continue; 18 | } 19 | 20 | ClassImport classImport = new ClassImport( 21 | removeComments(importDeclaration.getName()), 22 | importDeclaration.isStatic(), 23 | importDeclaration.isAsterisk()); 24 | 25 | String classname = classImport.getTail(); 26 | if (!classnames.contains(classname)) { 27 | result.append("'") 28 | .append(classImport.getHead()) 29 | .append(classImport.isStatic() ? "$" : ".") 30 | .append(classname) 31 | .append("',"); 32 | } 33 | } 34 | return result.append("]}").toString(); 35 | } 36 | 37 | private static String removeComments(Node n) { 38 | PrettyPrinterConfiguration config = 39 | new PrettyPrinterConfiguration(); 40 | config.setPrintComments(false); 41 | return new PrettyPrinter(config).print(n); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /libs/javavi/src/main/java/kg/ash/javavi/actions/ImportsAction.java: -------------------------------------------------------------------------------- 1 | package kg.ash.javavi.actions; 2 | 3 | import com.github.javaparser.Range; 4 | import com.github.javaparser.ast.CompilationUnit; 5 | 6 | import java.io.UnsupportedEncodingException; 7 | import java.util.Base64; 8 | import java.util.HashSet; 9 | import java.util.Optional; 10 | import java.util.Set; 11 | 12 | import kg.ash.javavi.readers.source.ClassNamesFetcher; 13 | import kg.ash.javavi.readers.source.CompilationUnitCreator; 14 | import kg.ash.javavi.readers.source.CompilationUnitResult; 15 | 16 | public abstract class ImportsAction implements Action { 17 | 18 | protected Set classnames; 19 | protected Set declarations; 20 | protected CompilationUnit compilationUnit; 21 | 22 | @Override 23 | public String perform(String[] args) { 24 | try { 25 | String base64Content = getContent(args); 26 | String content = new String( 27 | Base64.getDecoder().decode(base64Content), "UTF-8"); 28 | 29 | CompilationUnitResult compilationUnitResult = 30 | CompilationUnitCreator.createFromContent(content); 31 | if (compilationUnitResult == null) { 32 | return "Couldn't parse file"; 33 | } else if (compilationUnitResult.getProblems() != null) { 34 | StringBuilder result = 35 | new StringBuilder("{'parse-problems':["); 36 | Set ranges = new HashSet<>(); 37 | compilationUnitResult.getProblems().stream().forEach(p -> { 38 | p.getLocation().get().getBegin().getRange() 39 | .filter(range -> !ranges.contains(range)) 40 | .ifPresent(range -> { 41 | result.append("{'message':'").append(p.getMessage()).append("'"); 42 | result.append(",'lnum':'") 43 | .append(range.begin.line).append("'"); 44 | result.append(",'col':'") 45 | .append(range.begin.column).append("'},"); 46 | ranges.add(range); 47 | }); 48 | }); 49 | return result.append("]}").toString(); 50 | } else { 51 | compilationUnit = compilationUnitResult.getCompilationUnit(); 52 | } 53 | 54 | ClassNamesFetcher classnamesFetcher = 55 | new ClassNamesFetcher(compilationUnit); 56 | classnames = classnamesFetcher.getNames(); 57 | declarations = classnamesFetcher.getDeclarationList(); 58 | 59 | return action(); 60 | } catch (UnsupportedEncodingException ex) { 61 | return ex.getMessage(); 62 | } 63 | } 64 | 65 | private String getContent(String[] args) { 66 | for (int i = 0; i < args.length; i++) { 67 | if (args[i].equals("-content")) { 68 | return args[i + 1]; 69 | } 70 | } 71 | return ""; 72 | } 73 | 74 | public abstract String action(); 75 | } 76 | -------------------------------------------------------------------------------- /libs/javavi/src/main/java/kg/ash/javavi/actions/ParseByContentAction.java: -------------------------------------------------------------------------------- 1 | package kg.ash.javavi.actions; 2 | 3 | import static kg.ash.javavi.actions.ActionFactory.getArgWithName; 4 | import static kg.ash.javavi.actions.ActionFactory.getJavaViSources; 5 | 6 | import kg.ash.javavi.Javavi; 7 | import kg.ash.javavi.output.OutputClassInfo; 8 | import kg.ash.javavi.readers.Parser; 9 | 10 | import java.io.UnsupportedEncodingException; 11 | import java.util.Base64; 12 | 13 | public class ParseByContentAction implements Action { 14 | 15 | @Override 16 | public String perform(String[] args) { 17 | try { 18 | String targetClass = getArgWithName(args, "-target"); 19 | String base64Content = getArgWithName(args, "-content"); 20 | 21 | String content = new String(Base64.getDecoder().decode(base64Content), "UTF-8"); 22 | Parser parser = new Parser(getJavaViSources(Javavi.system)); 23 | parser.setSourceContent(content); 24 | 25 | return new OutputClassInfo().get(parser.read(targetClass)); 26 | } catch (UnsupportedEncodingException ex) { 27 | return ex.getMessage(); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /libs/javavi/src/main/java/kg/ash/javavi/actions/RemoveClassInfoFromCache.java: -------------------------------------------------------------------------------- 1 | package kg.ash.javavi.actions; 2 | 3 | import kg.ash.javavi.cache.Cache; 4 | 5 | public class RemoveClassInfoFromCache extends ActionWithTarget { 6 | 7 | @Override 8 | public String perform(String[] args) { 9 | String target = parseTarget(args); 10 | if (Cache.getInstance().getClasses().containsKey(target)) { 11 | Cache.getInstance().getClasses().remove(target); 12 | } 13 | return ""; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /libs/javavi/src/main/java/kg/ash/javavi/cache/Cache.java: -------------------------------------------------------------------------------- 1 | package kg.ash.javavi.cache; 2 | 3 | import kg.ash.javavi.Javavi; 4 | import kg.ash.javavi.apache.logging.log4j.LogManager; 5 | import kg.ash.javavi.apache.logging.log4j.Logger; 6 | import kg.ash.javavi.clazz.SourceClass; 7 | import kg.ash.javavi.searchers.JavaClassMap; 8 | import kg.ash.javavi.searchers.PackagesLoader; 9 | 10 | import java.util.HashMap; 11 | import java.util.Timer; 12 | import java.util.TimerTask; 13 | 14 | public class Cache { 15 | 16 | public static final Logger logger = LogManager.getLogger(); 17 | public static final String PACKAGES_EMPTY_ERROR 18 | = "message: packages still empty, try later. indexing..."; 19 | 20 | private CacheSerializator serializator = new CacheSerializator(); 21 | private HashMap classPackages = new HashMap<>(); 22 | private HashMap classes = new HashMap<>(); 23 | private Timer autosaveCacheTimer = new Timer(); 24 | private boolean collectIsRunning = false; 25 | private int autosavePeriod = 60; 26 | private int cacheCode; 27 | 28 | private static Cache instance; 29 | 30 | public static Cache getInstance() { 31 | if (instance == null) { 32 | instance = new Cache(); 33 | } 34 | return instance; 35 | } 36 | 37 | public synchronized void collectPackages() { 38 | if (collectIsRunning) { 39 | return; 40 | } 41 | 42 | collectIsRunning = true; 43 | new Thread(() -> { 44 | logger.info("start collecting cache"); 45 | loadCache(); 46 | 47 | if (classPackages.isEmpty()) { 48 | logger.info("collecting empty cache"); 49 | 50 | HashMap classPackagesTemp = new HashMap<>(); 51 | new PackagesLoader(Javavi.system.get("sources")).collectPackages(classPackagesTemp); 52 | classPackages.putAll(classPackagesTemp); 53 | 54 | saveCache(); 55 | } 56 | 57 | cacheCode = getClassPackages().hashCode(); 58 | collectIsRunning = false; 59 | 60 | autosaveCacheTimer.schedule(new AutosaveTask(this), autosavePeriod * 1000); 61 | }).start(); 62 | } 63 | 64 | @SuppressWarnings("unchecked") 65 | public void loadCache() { 66 | Object o = serializator.loadCache("class_packages"); 67 | if (o != null) { 68 | try { 69 | classPackages = (HashMap) o; 70 | } catch (ClassCastException e) { 71 | logger.warn("Couldn't load cache"); 72 | } 73 | } 74 | } 75 | 76 | public void saveCache() { 77 | serializator.saveCache("class_packages", classPackages); 78 | } 79 | 80 | public HashMap getClassPackages() { 81 | if (classPackages.isEmpty()) { 82 | collectPackages(); 83 | } 84 | return classPackages; 85 | } 86 | 87 | public HashMap getClasses() { 88 | return classes; 89 | } 90 | 91 | class AutosaveTask extends TimerTask { 92 | private final Cache cache; 93 | 94 | public AutosaveTask(Cache cache) { 95 | this.cache = cache; 96 | } 97 | 98 | public void run() { 99 | int newCode = cache.getClassPackages().hashCode(); 100 | if (newCode != cache.cacheCode) { 101 | logger.info("autosave cache: {} != {}", newCode, cache.cacheCode); 102 | cache.saveCache(); 103 | cache.cacheCode = cache.getClassPackages().hashCode(); 104 | } 105 | cache.autosaveCacheTimer.schedule(new AutosaveTask(cache), cache.autosavePeriod * 1000); 106 | } 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /libs/javavi/src/main/java/kg/ash/javavi/cache/CacheSerializator.java: -------------------------------------------------------------------------------- 1 | package kg.ash.javavi.cache; 2 | 3 | import kg.ash.javavi.Javavi; 4 | import kg.ash.javavi.apache.logging.log4j.LogManager; 5 | import kg.ash.javavi.apache.logging.log4j.Logger; 6 | 7 | import java.io.File; 8 | import java.io.FileInputStream; 9 | import java.io.FileOutputStream; 10 | import java.io.ObjectInputStream; 11 | import java.io.ObjectOutputStream; 12 | import java.util.Map; 13 | 14 | public class CacheSerializator { 15 | 16 | public static final Logger logger = LogManager.getLogger(); 17 | 18 | private String base = null; 19 | private String project = null; 20 | 21 | public CacheSerializator() { 22 | if (Javavi.system.containsKey("base")) { 23 | Map system = Javavi.system; 24 | 25 | base = system.get("base"); 26 | if (system.containsKey("project")) { 27 | project = Javavi.system.get("project"); 28 | } 29 | 30 | File cacheFile = new File(base + File.separator + "cache"); 31 | if (!cacheFile.exists()) { 32 | cacheFile.mkdir(); 33 | } 34 | } 35 | } 36 | 37 | public void saveCache(String name, Object data) { 38 | if (base != null && project != null) { 39 | String filename = String.format( 40 | "%s%scache%s%s_%s.dat", 41 | base, 42 | File.separator, 43 | File.separator, 44 | name, 45 | project); 46 | logger.info("saving cache {} to file {}", name, filename); 47 | try (FileOutputStream fout = new FileOutputStream(filename); 48 | ObjectOutputStream oos = new ObjectOutputStream(fout)) { 49 | oos.writeObject(data); 50 | } catch (Throwable e) { 51 | logger.error(e); 52 | } 53 | } 54 | } 55 | 56 | public Object loadCache(String name) { 57 | if (base != null && project != null) { 58 | String filename = String.format( 59 | "%s%scache%s%s_%s.dat", 60 | base, 61 | File.separator, 62 | File.separator, 63 | name, 64 | project); 65 | logger.info("loading cache {} from file {}", name, filename); 66 | try (FileInputStream fin = new FileInputStream(filename); 67 | ObjectInputStream ois = new ObjectInputStream(fin)) { 68 | return ois.readObject(); 69 | } catch (Throwable e) { 70 | logger.warn("Couldn't load cache"); 71 | } 72 | } 73 | return null; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /libs/javavi/src/main/java/kg/ash/javavi/clazz/ClassConstructor.java: -------------------------------------------------------------------------------- 1 | package kg.ash.javavi.clazz; 2 | 3 | import com.github.javaparser.ast.Modifier; 4 | 5 | import java.util.EnumSet; 6 | import java.util.LinkedList; 7 | import java.util.List; 8 | import java.util.Objects; 9 | 10 | public class ClassConstructor { 11 | 12 | private String declaration = ""; 13 | private EnumSet modifiers; 14 | private List typeParameters = new LinkedList<>(); 15 | 16 | public void setDeclaration(String declaration) { 17 | this.declaration = declaration; 18 | } 19 | 20 | public String getDeclaration() { 21 | return declaration; 22 | } 23 | 24 | public void setModifiers(EnumSet modifiers) { 25 | this.modifiers = modifiers; 26 | } 27 | 28 | public EnumSet getModifiers() { 29 | return modifiers; 30 | } 31 | 32 | public void addTypeParameter(ClassTypeParameter parameter) { 33 | typeParameters.add(parameter); 34 | } 35 | 36 | public List getTypeParameters() { 37 | return typeParameters; 38 | } 39 | 40 | @Override 41 | public boolean equals(Object obj) { 42 | if (obj == null) { 43 | return false; 44 | } 45 | if (getClass() != obj.getClass()) { 46 | return false; 47 | } 48 | 49 | final ClassConstructor other = (ClassConstructor) obj; 50 | if (!Objects.equals(this.declaration, other.declaration) && (this.declaration == null 51 | || !this.declaration.equals(other.declaration))) { 52 | return false; 53 | } 54 | return this.modifiers == other.modifiers; 55 | } 56 | 57 | @Override 58 | public int hashCode() { 59 | int hash = 7; 60 | hash = 17 * hash + (modifiers.hashCode()); 61 | hash = 17 * hash + (this.declaration != null ? this.declaration.hashCode() : 0); 62 | return hash; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /libs/javavi/src/main/java/kg/ash/javavi/clazz/ClassField.java: -------------------------------------------------------------------------------- 1 | package kg.ash.javavi.clazz; 2 | 3 | import com.github.javaparser.ast.Modifier; 4 | 5 | import java.util.EnumSet; 6 | import java.util.Objects; 7 | 8 | public class ClassField { 9 | 10 | private String name; 11 | private EnumSet modifiers; 12 | private String typeName; 13 | 14 | public void setName(String name) { 15 | this.name = name; 16 | } 17 | 18 | public String getName() { 19 | return name; 20 | } 21 | 22 | public void setModifiers(EnumSet modifiers) { 23 | this.modifiers = modifiers; 24 | } 25 | 26 | public EnumSet getModifiers() { 27 | return modifiers; 28 | } 29 | 30 | public void setTypeName(String typeName) { 31 | this.typeName = typeName; 32 | } 33 | 34 | public String getTypeName() { 35 | return typeName; 36 | } 37 | 38 | @Override 39 | public boolean equals(Object obj) { 40 | if (obj == null) { 41 | return false; 42 | } 43 | if (getClass() != obj.getClass()) { 44 | return false; 45 | } 46 | 47 | final ClassField other = (ClassField) obj; 48 | if (!Objects.equals(this.name, other.name) && (this.name == null || !this.name.equals( 49 | other.name))) { 50 | return false; 51 | } 52 | return this.typeName == other.typeName || (this.typeName != null && this.typeName.equals( 53 | other.typeName)); 54 | } 55 | 56 | @Override 57 | public int hashCode() { 58 | int hash = 7; 59 | hash = 17 * hash + (this.name != null ? this.name.hashCode() : 0); 60 | hash = 17 * hash + (this.typeName != null ? this.typeName.hashCode() : 0); 61 | return hash; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /libs/javavi/src/main/java/kg/ash/javavi/clazz/ClassImport.java: -------------------------------------------------------------------------------- 1 | package kg.ash.javavi.clazz; 2 | 3 | public class ClassImport { 4 | private String name; 5 | private boolean isStatic; 6 | private boolean isAsterisk; 7 | 8 | public ClassImport(String name, boolean isStatic, boolean isAsterisk) { 9 | this.name = name; 10 | this.isStatic = isStatic; 11 | this.isAsterisk = isAsterisk; 12 | } 13 | 14 | public void setName(String name) { 15 | this.name = name; 16 | } 17 | 18 | public String getName() { 19 | return name; 20 | } 21 | 22 | public boolean isStatic() { 23 | return isStatic; 24 | } 25 | 26 | public boolean isAsterisk() { 27 | return isAsterisk; 28 | } 29 | 30 | public String getHead() { 31 | return name.substring(0, name.lastIndexOf(".")); 32 | } 33 | 34 | public String getTail() { 35 | if (name.contains(".")) { 36 | String[] splitted = name.split("\\."); 37 | return splitted[splitted.length - 1]; 38 | } 39 | return name; 40 | } 41 | 42 | public String toString() { 43 | return String.format("%s, isStatic: %b", name, isStatic); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /libs/javavi/src/main/java/kg/ash/javavi/clazz/ClassMethod.java: -------------------------------------------------------------------------------- 1 | package kg.ash.javavi.clazz; 2 | 3 | import com.github.javaparser.ast.Modifier; 4 | 5 | import java.util.EnumSet; 6 | import java.util.LinkedList; 7 | import java.util.List; 8 | import java.util.Objects; 9 | 10 | public class ClassMethod { 11 | 12 | private String name; 13 | private EnumSet modifiers; 14 | private String declaration; 15 | private String typeName; 16 | private List typeParameters = new LinkedList<>(); 17 | private boolean deprecated = false; 18 | 19 | public void setName(String name) { 20 | this.name = name; 21 | } 22 | 23 | public String getName() { 24 | return name; 25 | } 26 | 27 | public void setModifiers(EnumSet modifiers) { 28 | this.modifiers = modifiers; 29 | } 30 | 31 | public EnumSet getModifiers() { 32 | return modifiers; 33 | } 34 | 35 | public void setDeclaration(String declaration) { 36 | this.declaration = declaration; 37 | } 38 | 39 | public String getDeclaration() { 40 | return declaration; 41 | } 42 | 43 | public void setTypeName(String typeName) { 44 | this.typeName = typeName; 45 | } 46 | 47 | public String getTypeName() { 48 | return typeName; 49 | } 50 | 51 | public void addTypeParameter(ClassTypeParameter typeParameter) { 52 | typeParameters.add(typeParameter); 53 | } 54 | 55 | public List getTypeParameters() { 56 | return typeParameters; 57 | } 58 | 59 | public void setDeprecated(boolean deprecated) { 60 | this.deprecated = deprecated; 61 | } 62 | 63 | public boolean getDeprecated() { 64 | return deprecated; 65 | } 66 | 67 | @Override 68 | public boolean equals(Object obj) { 69 | if (obj == null) { 70 | return false; 71 | } 72 | if (getClass() != obj.getClass()) { 73 | return false; 74 | } 75 | 76 | final ClassMethod other = (ClassMethod) obj; 77 | if (!Objects.equals(this.name, other.name) && (this.name == null || !this.name.equals( 78 | other.name))) { 79 | return false; 80 | } 81 | if (!Objects.equals(this.typeName, other.typeName) && (this.typeName == null 82 | || !this.typeName.equals(other.typeName))) { 83 | return false; 84 | } 85 | return this.declaration == other.declaration || (this.declaration != null 86 | && this.declaration.equals(other.declaration)); 87 | } 88 | 89 | @Override 90 | public int hashCode() { 91 | int hash = 7; 92 | hash = 17 * hash + (this.name != null ? this.name.hashCode() : 0); 93 | hash = 17 * hash + (this.typeName != null ? this.typeName.hashCode() : 0); 94 | hash = 17 * hash + (this.declaration != null ? this.declaration.hashCode() : 0); 95 | return hash; 96 | } 97 | 98 | @Override 99 | public String toString() { 100 | return name; 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /libs/javavi/src/main/java/kg/ash/javavi/clazz/ClassTypeParameter.java: -------------------------------------------------------------------------------- 1 | package kg.ash.javavi.clazz; 2 | 3 | public class ClassTypeParameter { 4 | 5 | private String name; 6 | 7 | public ClassTypeParameter(String name) { 8 | this.name = name; 9 | } 10 | 11 | public void setName(String name) { 12 | this.name = name; 13 | } 14 | 15 | public String getName() { 16 | return name; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /libs/javavi/src/main/java/kg/ash/javavi/clazz/CodeRegion.java: -------------------------------------------------------------------------------- 1 | package kg.ash.javavi.clazz; 2 | 3 | public class CodeRegion { 4 | 5 | private int beginLine = -1; 6 | private int beginColumn = -1; 7 | private int endLine = -1; 8 | private int endColumn = -1; 9 | 10 | public CodeRegion() { 11 | } 12 | 13 | public CodeRegion(int beginLine, int beginColumn, int endLine, int endColumn) { 14 | this.beginLine = beginLine; 15 | this.beginColumn = beginColumn; 16 | this.endLine = endLine; 17 | this.endColumn = endColumn; 18 | } 19 | 20 | public int getBeginLine() { 21 | return beginLine; 22 | } 23 | 24 | public int getBeginColumn() { 25 | return beginColumn; 26 | } 27 | 28 | public int getEndLine() { 29 | return endLine; 30 | } 31 | 32 | public int getEndColumn() { 33 | return endColumn; 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /libs/javavi/src/main/java/kg/ash/javavi/clazz/SourceClass.java: -------------------------------------------------------------------------------- 1 | package kg.ash.javavi.clazz; 2 | 3 | import com.github.javaparser.ast.Modifier; 4 | import kg.ash.javavi.TargetParser; 5 | 6 | import java.util.ArrayList; 7 | import java.util.EnumSet; 8 | import java.util.List; 9 | 10 | public class SourceClass { 11 | 12 | private String pkg = null; 13 | private String name = null; 14 | private EnumSet modifiers; 15 | private boolean isInterface = false; 16 | private List constructors = new ArrayList<>(); 17 | private List methods = new ArrayList<>(); 18 | private List fields = new ArrayList<>(); 19 | private List imports = new ArrayList<>(); 20 | 21 | private String superclass = null; 22 | private List interfaces = new ArrayList<>(); 23 | 24 | private List linkedClasses = new ArrayList<>(); 25 | private List typeArguments = new ArrayList<>(); 26 | 27 | private List nestedClasses = new ArrayList<>(); 28 | 29 | private CodeRegion region = new CodeRegion(); 30 | 31 | public String getName() { 32 | StringBuilder sb = new StringBuilder(); 33 | 34 | if (pkg != null) { 35 | sb.append(pkg).append("."); 36 | } 37 | sb.append(name).append(TargetParser.getTypeArgumentsString(typeArguments)); 38 | 39 | return sb.toString(); 40 | } 41 | 42 | public void setName(String name) { 43 | this.name = name; 44 | } 45 | 46 | public String getSimpleName() { 47 | return name; 48 | } 49 | 50 | public List getConstructors() { 51 | return constructors; 52 | } 53 | 54 | public void addConstructor(ClassConstructor constructor) { 55 | if (constructor != null && !constructors.contains(constructor)) { 56 | constructors.add(constructor); 57 | } 58 | } 59 | 60 | public List getMethods() { 61 | return methods; 62 | } 63 | 64 | public void addMethod(ClassMethod method) { 65 | if (method != null && !methods.contains(method)) { 66 | methods.add(method); 67 | } 68 | } 69 | 70 | public List getFields() { 71 | return fields; 72 | } 73 | 74 | public void addField(ClassField field) { 75 | if (field != null && !fields.contains(field)) { 76 | fields.add(field); 77 | } 78 | } 79 | 80 | public EnumSet getModifiers() { 81 | return modifiers; 82 | } 83 | 84 | public void setModifiers(EnumSet modifiers) { 85 | this.modifiers = modifiers; 86 | } 87 | 88 | public String getPackage() { 89 | return pkg; 90 | } 91 | 92 | public void setPackage(String pakage) { 93 | this.pkg = pakage; 94 | } 95 | 96 | public void setSuperclass(String superclass) { 97 | this.superclass = superclass; 98 | } 99 | 100 | public String getSuperclass() { 101 | return superclass; 102 | } 103 | 104 | public void addImport(ClassImport classImport) { 105 | imports.add(classImport); 106 | } 107 | 108 | public List getImports() { 109 | return imports; 110 | } 111 | 112 | public void addInterface(String interfaceName) { 113 | interfaces.add(interfaceName); 114 | } 115 | 116 | public List getInterfaces() { 117 | return interfaces; 118 | } 119 | 120 | public void setIsInterface(boolean isInterface) { 121 | this.isInterface = isInterface; 122 | } 123 | 124 | public boolean isInterface() { 125 | return isInterface; 126 | } 127 | 128 | public void addLinkedClass(SourceClass clazz) { 129 | linkedClasses.add(clazz); 130 | methods.addAll(clazz.getMethods()); 131 | fields.addAll(clazz.getFields()); 132 | } 133 | 134 | public List getLinkedClasses() { 135 | return linkedClasses; 136 | } 137 | 138 | public void addTypeArgument(String type) { 139 | typeArguments.add(type); 140 | } 141 | 142 | public void addNestedClass(String cls) { 143 | nestedClasses.add(cls); 144 | } 145 | 146 | public List getNestedClasses() { 147 | return nestedClasses; 148 | } 149 | 150 | public void setRegion(int beginLine, int beginColumn, int endLine, int endColumn) { 151 | setRegion(new CodeRegion(beginLine, beginColumn, endLine, endColumn)); 152 | } 153 | 154 | public void setRegion(CodeRegion region) { 155 | this.region = region; 156 | } 157 | 158 | public CodeRegion getRegion() { 159 | return region; 160 | } 161 | } 162 | -------------------------------------------------------------------------------- /libs/javavi/src/main/java/kg/ash/javavi/output/OutputClassPackages.java: -------------------------------------------------------------------------------- 1 | package kg.ash.javavi.output; 2 | 3 | import com.github.javaparser.ast.Modifier; 4 | import kg.ash.javavi.Javavi; 5 | import kg.ash.javavi.cache.Cache; 6 | import kg.ash.javavi.clazz.SourceClass; 7 | import kg.ash.javavi.readers.ClassReader; 8 | import kg.ash.javavi.searchers.ClassSearcher; 9 | import kg.ash.javavi.searchers.JavaClassMap; 10 | 11 | import java.util.HashMap; 12 | 13 | public class OutputClassPackages { 14 | 15 | private HashMap classPackages; 16 | private String sources = Javavi.system.get("sources").replace('\\', '/'); 17 | 18 | public OutputClassPackages(HashMap classPackages) { 19 | this.classPackages = classPackages; 20 | } 21 | 22 | public String get(String targetClass) { 23 | if (classPackages == null || classPackages.isEmpty()) { 24 | return Cache.PACKAGES_EMPTY_ERROR; 25 | } 26 | 27 | StringBuilder builder = new StringBuilder(""); 28 | if (classPackages.containsKey(targetClass)) { 29 | JavaClassMap cm = classPackages.get(targetClass); 30 | if (cm.getType() == JavaClassMap.TYPE_CLASS) { 31 | cm.getSubpackages().keySet().forEach((String scope) -> { 32 | if (scope.endsWith("$")) { 33 | String target = scope + targetClass; 34 | ClassSearcher seacher = new ClassSearcher(); 35 | if (seacher.find(target, sources)) { 36 | ClassReader reader = seacher.getReader(); 37 | SourceClass clazz = reader.read(target); 38 | if (clazz != null && clazz.getModifiers().contains(Modifier.STATIC)) { 39 | scope = "static " + scope; 40 | } 41 | } 42 | } 43 | builder.append("'") 44 | .append(scope) 45 | .append(scope.endsWith("$") ? "" : ".") 46 | .append(targetClass) 47 | .append("',") 48 | .append(Javavi.NEWLINE); 49 | }); 50 | } 51 | } 52 | 53 | return String.format("[%s]", builder); 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /libs/javavi/src/main/java/kg/ash/javavi/output/OutputPackageInfo.java: -------------------------------------------------------------------------------- 1 | package kg.ash.javavi.output; 2 | 3 | import kg.ash.javavi.cache.Cache; 4 | import kg.ash.javavi.searchers.JavaClassMap; 5 | 6 | import java.util.HashMap; 7 | 8 | public class OutputPackageInfo { 9 | 10 | private HashMap classPackages; 11 | 12 | public OutputPackageInfo(HashMap classPackages) { 13 | this.classPackages = classPackages; 14 | } 15 | 16 | public String get(String targetPackage) { 17 | if (classPackages == null || classPackages.isEmpty()) { 18 | return Cache.PACKAGES_EMPTY_ERROR; 19 | } 20 | 21 | StringBuilder sb = new StringBuilder(); 22 | if (classPackages.containsKey(targetPackage)) { 23 | JavaClassMap classMap = classPackages.get(targetPackage); 24 | 25 | sb.append("'") 26 | .append(targetPackage) 27 | .append("':") 28 | .append("{'tag':'PACKAGE'") 29 | .append(",'subpackages':[") 30 | .append(classMap.getCachedSubpackages()) 31 | .append("]") 32 | .append(",'classes':[") 33 | .append(classMap.getCachedClasses().toString()) 34 | .append("]") 35 | .append("},"); 36 | } 37 | 38 | return String.format("{%s}", sb); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /libs/javavi/src/main/java/kg/ash/javavi/output/OutputSimilar.java: -------------------------------------------------------------------------------- 1 | package kg.ash.javavi.output; 2 | 3 | import kg.ash.javavi.Javavi; 4 | import kg.ash.javavi.cache.Cache; 5 | import kg.ash.javavi.searchers.JavaClassMap; 6 | 7 | import java.util.Collections; 8 | import java.util.HashMap; 9 | import java.util.List; 10 | 11 | public abstract class OutputSimilar { 12 | 13 | protected String wordPrefix = ""; 14 | 15 | protected HashMap classPackages; 16 | 17 | public OutputSimilar(HashMap classPackages) { 18 | this.classPackages = classPackages; 19 | } 20 | 21 | public String get(String target) { 22 | if (target == null) { 23 | target = ""; 24 | } 25 | 26 | if (classPackages == null || classPackages.isEmpty()) { 27 | return Cache.PACKAGES_EMPTY_ERROR; 28 | } 29 | 30 | List keys = getKeys(target); 31 | Collections.sort(keys); 32 | 33 | StringBuilder builder = new StringBuilder(); 34 | for (String key : keys) { 35 | classPackages.get(key) 36 | .getPaths() 37 | .forEach(scope -> builder.append("{") 38 | .append("'word':'") 39 | .append(wordPrefix) 40 | .append(key) 41 | .append("', 'menu':'") 42 | .append(scope) 43 | .append("', 'type': 'c'},") 44 | .append(Javavi.NEWLINE)); 45 | } 46 | return String.format("[%s]", builder); 47 | } 48 | 49 | protected abstract List getKeys(String target); 50 | 51 | } 52 | -------------------------------------------------------------------------------- /libs/javavi/src/main/java/kg/ash/javavi/output/OutputSimilarAnnotations.java: -------------------------------------------------------------------------------- 1 | package kg.ash.javavi.output; 2 | 3 | import kg.ash.javavi.searchers.JavaClassMap; 4 | 5 | import java.util.ArrayList; 6 | import java.util.HashMap; 7 | import java.util.List; 8 | import java.util.function.Predicate; 9 | 10 | public class OutputSimilarAnnotations extends OutputSimilar { 11 | 12 | public OutputSimilarAnnotations(HashMap classPackages) { 13 | super(classPackages); 14 | wordPrefix = "@"; 15 | } 16 | 17 | @Override 18 | protected List getKeys(String target) { 19 | List keysResult = new ArrayList<>(); 20 | 21 | classPackages.forEach((key, value) -> { 22 | if (target.isEmpty() || key.startsWith(target)) { 23 | value.getPaths() 24 | .stream() 25 | .filter(isFromClasspath(value)) 26 | .forEach(fqn -> addIfAnnotation(keysResult, fqn, key)); 27 | } 28 | }); 29 | 30 | return keysResult; 31 | } 32 | 33 | private void addIfAnnotation(List keys, String fqn, String key) { 34 | try { 35 | String fullFqn = String.format("%s.%s", fqn, key); 36 | ClassLoader loader = getClass().getClassLoader(); 37 | Class cls = Class.forName(fullFqn, false, loader); 38 | if (cls.isAnnotation()) { 39 | keys.add(key); 40 | } 41 | } catch (NoClassDefFoundError | ClassNotFoundException ex) { 42 | } 43 | } 44 | 45 | private Predicate isFromClasspath(JavaClassMap map) { 46 | return s -> map.getSourceType(s) == JavaClassMap.SOURCETYPE_CLASSPATH; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /libs/javavi/src/main/java/kg/ash/javavi/output/OutputSimilarClasses.java: -------------------------------------------------------------------------------- 1 | package kg.ash.javavi.output; 2 | 3 | import kg.ash.javavi.searchers.JavaClassMap; 4 | 5 | import java.util.ArrayList; 6 | import java.util.HashMap; 7 | import java.util.List; 8 | import java.util.stream.Collectors; 9 | 10 | public class OutputSimilarClasses extends OutputSimilar { 11 | 12 | public OutputSimilarClasses(HashMap classPackages) { 13 | super(classPackages); 14 | } 15 | 16 | @Override 17 | protected List getKeys(String target) { 18 | if (target.isEmpty()) { 19 | return new ArrayList<>(); 20 | } 21 | return classPackages.keySet() 22 | .stream() 23 | .filter(k -> k.startsWith(target)) 24 | .collect(Collectors.toList()); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /libs/javavi/src/main/java/kg/ash/javavi/readers/ClassReader.java: -------------------------------------------------------------------------------- 1 | package kg.ash.javavi.readers; 2 | 3 | import kg.ash.javavi.clazz.SourceClass; 4 | 5 | import java.util.List; 6 | 7 | public interface ClassReader { 8 | SourceClass read(String fqn); 9 | 10 | ClassReader setTypeArguments(List typeArguments); 11 | 12 | ClassReader addKnown(List knownClasses); 13 | } 14 | -------------------------------------------------------------------------------- /libs/javavi/src/main/java/kg/ash/javavi/readers/FileClassLoader.java: -------------------------------------------------------------------------------- 1 | package kg.ash.javavi.readers; 2 | 3 | import java.io.ByteArrayOutputStream; 4 | import java.io.File; 5 | import java.io.FileInputStream; 6 | 7 | public class FileClassLoader extends ClassLoader { 8 | 9 | private String classFile; 10 | 11 | public FileClassLoader(ClassLoader parent, String classFile) { 12 | super(parent); 13 | this.classFile = classFile; 14 | } 15 | 16 | // TODO: Handle throwables. 17 | public Class loadClass(String name) { 18 | try { 19 | if (name.startsWith("java.")) { 20 | return Class.forName(name); 21 | } 22 | 23 | File file = new File(classFile); 24 | if (file.exists()) { 25 | FileInputStream fileInputStream = new FileInputStream(file); 26 | ByteArrayOutputStream buffer = new ByteArrayOutputStream(); 27 | int data = fileInputStream.read(); 28 | 29 | while (data != -1) { 30 | buffer.write(data); 31 | data = fileInputStream.read(); 32 | } 33 | 34 | fileInputStream.close(); 35 | 36 | byte[] classData = buffer.toByteArray(); 37 | return defineClass(name, classData, 0, classData.length); 38 | } 39 | } catch (Throwable t) { 40 | try { 41 | return Class.forName(name); 42 | } catch (Throwable t2) { 43 | } 44 | } 45 | 46 | return null; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /libs/javavi/src/main/java/kg/ash/javavi/readers/source/CompilationUnitCreator.java: -------------------------------------------------------------------------------- 1 | package kg.ash.javavi.readers.source; 2 | 3 | import com.github.javaparser.JavaParser; 4 | import com.github.javaparser.ParseProblemException; 5 | import com.github.javaparser.TokenMgrException; 6 | import com.github.javaparser.ast.CompilationUnit; 7 | 8 | import java.io.FileNotFoundException; 9 | import java.io.FileReader; 10 | import java.io.StringReader; 11 | 12 | import kg.ash.javavi.apache.logging.log4j.LogManager; 13 | import kg.ash.javavi.apache.logging.log4j.Logger; 14 | 15 | public class CompilationUnitCreator { 16 | 17 | public static final Logger logger = LogManager.getLogger(); 18 | 19 | public static CompilationUnitResult createFromFile(String fileName) { 20 | try { 21 | return new CompilationUnitResult( 22 | JavaParser.parse(new FileReader(fileName))); 23 | } catch (TokenMgrException | FileNotFoundException e) { 24 | logger.error(e, e); 25 | return null; 26 | } catch (ParseProblemException ex) { 27 | logger.debug("parse error", ex); 28 | return new CompilationUnitResult( 29 | ex.getProblems()); 30 | } 31 | } 32 | 33 | public static CompilationUnitResult createFromContent(String content) { 34 | try { 35 | return new CompilationUnitResult( 36 | JavaParser.parse(new StringReader(content))); 37 | } catch (TokenMgrException ex) { 38 | logger.error(ex, ex); 39 | return null; 40 | } catch (ParseProblemException ex) { 41 | logger.debug("parse error", ex); 42 | return new CompilationUnitResult( 43 | ex.getProblems()); 44 | } 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /libs/javavi/src/main/java/kg/ash/javavi/readers/source/CompilationUnitResult.java: -------------------------------------------------------------------------------- 1 | package kg.ash.javavi.readers.source; 2 | 3 | import com.github.javaparser.Problem; 4 | import com.github.javaparser.ast.CompilationUnit; 5 | 6 | import java.util.List; 7 | 8 | public class CompilationUnitResult { 9 | 10 | private CompilationUnit compilationUnit; 11 | private List problems; 12 | 13 | public CompilationUnitResult(CompilationUnit compilationUnit) { 14 | this.compilationUnit = compilationUnit; 15 | } 16 | 17 | public CompilationUnitResult(List problems) { 18 | this.problems = problems; 19 | } 20 | 21 | public CompilationUnit getCompilationUnit() { 22 | return compilationUnit; 23 | } 24 | 25 | public void setCompilationUnit(CompilationUnit compilationUnit) { 26 | this.compilationUnit = compilationUnit; 27 | } 28 | 29 | public List getProblems() { 30 | return problems; 31 | } 32 | 33 | public void setProblems(List problems) { 34 | this.problems = problems; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /libs/javavi/src/main/java/kg/ash/javavi/searchers/ByExtensionVisitor.java: -------------------------------------------------------------------------------- 1 | package kg.ash.javavi.searchers; 2 | 3 | import java.io.IOException; 4 | import java.nio.file.FileSystems; 5 | import java.nio.file.FileVisitResult; 6 | import java.nio.file.Path; 7 | import java.nio.file.PathMatcher; 8 | import java.nio.file.SimpleFileVisitor; 9 | import java.nio.file.attribute.BasicFileAttributes; 10 | import java.util.ArrayList; 11 | import java.util.List; 12 | import java.util.stream.Collectors; 13 | 14 | public class ByExtensionVisitor extends SimpleFileVisitor { 15 | 16 | private final List matchers = new ArrayList<>(); 17 | private List resultList = new ArrayList<>(); 18 | 19 | public ByExtensionVisitor(List patterns) { 20 | matchers.addAll(getMatchers(patterns)); 21 | } 22 | 23 | private List getMatchers(List patterns) { 24 | return patterns.stream() 25 | .map(p -> FileSystems.getDefault().getPathMatcher("glob:" + p)) 26 | .collect(Collectors.toList()); 27 | } 28 | 29 | public List getResultList() { 30 | return resultList; 31 | } 32 | 33 | private void find(Path file) { 34 | Path name = file.getFileName(); 35 | if (name != null) { 36 | for (PathMatcher matcher : matchers) { 37 | if (matcher.matches(name)) { 38 | resultList.add(file.toFile().getPath().replace('\\', '/')); 39 | return; 40 | } 41 | } 42 | } 43 | } 44 | 45 | @Override 46 | public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) { 47 | find(file); 48 | return FileVisitResult.CONTINUE; 49 | } 50 | 51 | @Override 52 | public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) { 53 | return FileVisitResult.CONTINUE; 54 | } 55 | 56 | @Override 57 | public FileVisitResult visitFileFailed(Path file, IOException exc) { 58 | return FileVisitResult.CONTINUE; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /libs/javavi/src/main/java/kg/ash/javavi/searchers/ClassNameMap.java: -------------------------------------------------------------------------------- 1 | package kg.ash.javavi.searchers; 2 | 3 | public class ClassNameMap extends JavaClassMap { 4 | 5 | public String javaFile = null; 6 | public String classFile = null; 7 | 8 | public ClassNameMap(String name) { 9 | super(name); 10 | } 11 | 12 | @Override 13 | public int getType() { 14 | return JavaClassMap.TYPE_CLASS; 15 | } 16 | 17 | public void setJavaFile(String javaFile) { 18 | this.javaFile = javaFile; 19 | } 20 | 21 | public String getJavaFile() { 22 | return javaFile; 23 | } 24 | 25 | public void setClassFile(String classFile) { 26 | this.classFile = classFile; 27 | } 28 | 29 | public String getClassFile() { 30 | return classFile; 31 | } 32 | 33 | @Override 34 | public String toString() { 35 | return String.format("name = %s, type = %d, javaFile = %s, classFile = %s", name, getType(), 36 | javaFile, classFile); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /libs/javavi/src/main/java/kg/ash/javavi/searchers/ClassSearcher.java: -------------------------------------------------------------------------------- 1 | package kg.ash.javavi.searchers; 2 | 3 | import kg.ash.javavi.apache.logging.log4j.LogManager; 4 | import kg.ash.javavi.apache.logging.log4j.Logger; 5 | import kg.ash.javavi.readers.ClassReader; 6 | import kg.ash.javavi.readers.Parser; 7 | import kg.ash.javavi.readers.Reflection; 8 | 9 | import java.io.File; 10 | import java.io.IOException; 11 | import java.nio.file.Files; 12 | import java.nio.file.Paths; 13 | 14 | public class ClassSearcher { 15 | 16 | public static final Logger logger = LogManager.getLogger(); 17 | 18 | private boolean isReflected = false; 19 | private String sources; 20 | private String sourceFile = null; 21 | 22 | public boolean find(String targetClass, String sources) { 23 | logger.debug("executing search of \"{}\"", targetClass); 24 | 25 | this.sources = sources; 26 | if (Reflection.exist(targetClass) || Reflection.exist("java.lang." + targetClass)) { 27 | isReflected = true; 28 | return true; 29 | } else { 30 | String[] sourcesArray = sources.split(File.pathSeparator); 31 | for (String sourceDir : sourcesArray) { 32 | if (targetClass.contains("$")) { 33 | targetClass = targetClass.split("\\$")[0]; 34 | } 35 | targetClass = targetClass.replaceAll("[\\[\\]]", ""); 36 | SourceFileVisitor visitor = new SourceFileVisitor(targetClass); 37 | try { 38 | Files.walkFileTree(Paths.get(sourceDir), visitor); 39 | 40 | if (visitor.getTargetFile() != null) { 41 | sourceFile = visitor.getTargetFile().replace('\\', '/'); 42 | return true; 43 | } 44 | } catch (IOException e) { 45 | logger.error(e, e); 46 | } 47 | } 48 | } 49 | 50 | return false; 51 | } 52 | 53 | public ClassReader getReader() { 54 | if (isReflected()) { 55 | return new Reflection(sources); 56 | } else { 57 | return new Parser(sources, getSourceFile()); 58 | } 59 | } 60 | 61 | public boolean isReflected() { 62 | return isReflected; 63 | } 64 | 65 | public String getSourceFile() { 66 | return sourceFile; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /libs/javavi/src/main/java/kg/ash/javavi/searchers/ClasspathCollector.java: -------------------------------------------------------------------------------- 1 | package kg.ash.javavi.searchers; 2 | 3 | import kg.ash.javavi.apache.logging.log4j.LogManager; 4 | import kg.ash.javavi.apache.logging.log4j.Logger; 5 | 6 | import java.io.File; 7 | import java.io.IOException; 8 | import java.nio.file.Files; 9 | import java.nio.file.Paths; 10 | import java.util.ArrayList; 11 | import java.util.Arrays; 12 | import java.util.List; 13 | import java.util.stream.Stream; 14 | 15 | public class ClasspathCollector { 16 | 17 | public static final Logger logger = LogManager.getLogger(); 18 | 19 | private ByExtensionVisitor finder = new ByExtensionVisitor( 20 | Arrays.asList("*.jar", "*.JAR", "*.zip", "*.ZIP", "*.class", 21 | "*.jmod", "classlist")); 22 | 23 | private String pSep = File.pathSeparator; 24 | 25 | public List collectClassPath() { 26 | List result = new ArrayList<>(); 27 | 28 | String extdirs = System.getProperty("java.ext.dirs"); 29 | if (extdirs != null) { 30 | Stream.of(extdirs.split(pSep)) 31 | .map(path -> addPathFromDir(path + File.separator)) 32 | .forEach(result::addAll); 33 | } 34 | 35 | result.addAll(addPathFromDir(System.getProperty("java.home"))); 36 | 37 | String classPath = System.getProperty("java.class.path"); 38 | Stream.of(classPath.split(pSep)) 39 | .filter(p -> p.length() >= 4).forEach(path -> { 40 | if (path.contains("vim-javacomplete2/libs/")) { 41 | return; 42 | } 43 | String ext = path.substring(path.length() - 4) 44 | .toLowerCase(); 45 | if (ext.endsWith(".jar") || ext.endsWith(".zip")) { 46 | result.add(path); 47 | } else { 48 | result.addAll(addPathFromDir(path)); 49 | } 50 | }); 51 | 52 | return result; 53 | } 54 | 55 | private List addPathFromDir(String dirpath) { 56 | List result = new ArrayList<>(); 57 | File dir = new File(dirpath); 58 | if (dir.isDirectory()) { 59 | try { 60 | Files.walkFileTree(Paths.get(dir.getPath()), finder); 61 | result.addAll(finder.getResultList()); 62 | } catch (IOException e) { 63 | logger.error(e, e); 64 | } 65 | } 66 | 67 | return result; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /libs/javavi/src/main/java/kg/ash/javavi/searchers/ClasspathPackageSearcher.java: -------------------------------------------------------------------------------- 1 | package kg.ash.javavi.searchers; 2 | 3 | import java.io.File; 4 | import java.io.IOException; 5 | import java.nio.file.Files; 6 | import java.nio.file.Paths; 7 | import java.util.ArrayList; 8 | import java.util.Enumeration; 9 | import java.util.List; 10 | import java.util.Optional; 11 | import java.util.stream.Stream; 12 | import java.util.zip.ZipFile; 13 | 14 | import kg.ash.javavi.apache.logging.log4j.LogManager; 15 | import kg.ash.javavi.apache.logging.log4j.Logger; 16 | 17 | public class ClasspathPackageSearcher implements PackageSeacherIFace { 18 | 19 | public static final Logger logger = LogManager.getLogger(); 20 | 21 | public List loadEntries() { 22 | List result = new ArrayList<>(); 23 | 24 | List knownPaths = new ArrayList<>(); 25 | new ClasspathCollector().collectClassPath() 26 | .stream() 27 | .forEach(filePath -> { 28 | if (filePath.toLowerCase().endsWith(".class")) { 29 | String path = filePath.substring( 30 | 0, filePath.length() - 6) 31 | .replaceAll("/", "."); 32 | String newPath = path.substring( 33 | 0, path.lastIndexOf(".")); 34 | String fileName = path.substring( 35 | path.lastIndexOf(".") + 1, path.length()); 36 | Optional kp = knownPaths.parallelStream() 37 | .filter(s -> newPath.endsWith(s)) 38 | .findFirst() 39 | .map(p -> p + File.separator + fileName + ".class") 40 | .map(p -> new PackageEntry( 41 | p, 42 | JavaClassMap.SOURCETYPE_CLASSPATH, 43 | filePath, 44 | PackageEntry.FILETYPE_CLASS)); 45 | if (kp.isPresent()) { 46 | result.add(kp.get()); 47 | return; 48 | } 49 | 50 | String[] split = path.split("\\."); 51 | int j = split.length - 2; 52 | while (j > 0) { 53 | path = ""; 54 | for (int i = j; i <= split.length - 2; i++) { 55 | path += split[i] + "."; 56 | } 57 | String pkg = getPackageByFile(path + fileName); 58 | if (pkg != null) { 59 | result.add( 60 | new PackageEntry( 61 | pkg + File.separator + 62 | fileName + ".class", 63 | JavaClassMap.SOURCETYPE_CLASSPATH, 64 | filePath, 65 | PackageEntry.FILETYPE_CLASS)); 66 | knownPaths.add(pkg); 67 | break; 68 | } else { 69 | j--; 70 | } 71 | } 72 | } else if (filePath.endsWith("classlist")) { 73 | try (Stream stream = 74 | Files.lines(Paths.get(filePath))) { 75 | stream.forEach(l -> { 76 | result.add( 77 | new PackageEntry(l + ".class", 78 | JavaClassMap.SOURCETYPE_CLASSPATH, 79 | filePath)); 80 | }); 81 | } catch (IOException ex) { 82 | logger.warn("error read classlist file", ex); 83 | } 84 | } else { 85 | try { 86 | for (Enumeration entries = 87 | new ZipFile(filePath).entries(); 88 | entries.hasMoreElements(); ) { 89 | String entry = entries.nextElement().toString(); 90 | if (filePath.endsWith(".jmod") 91 | && entry.startsWith("classes/")) { 92 | entry = entry.substring(8); 93 | } 94 | result.add( 95 | new PackageEntry(entry, 96 | JavaClassMap.SOURCETYPE_CLASSPATH, 97 | filePath)); 98 | } 99 | } catch (Exception e) { 100 | logger.error(e, e); 101 | } 102 | } 103 | }); 104 | 105 | return result; 106 | } 107 | 108 | private String getPackageByFile(String path) { 109 | try { 110 | Class clazz = Class.forName(path); 111 | return clazz.getPackage().getName(); 112 | } catch (ExceptionInInitializerError | 113 | ClassNotFoundException | 114 | NoClassDefFoundError ex) { 115 | return null; 116 | } 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /libs/javavi/src/main/java/kg/ash/javavi/searchers/FqnSearcher.java: -------------------------------------------------------------------------------- 1 | package kg.ash.javavi.searchers; 2 | 3 | import kg.ash.javavi.TargetParser; 4 | import kg.ash.javavi.clazz.ClassImport; 5 | import kg.ash.javavi.clazz.SourceClass; 6 | 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | 10 | public class FqnSearcher { 11 | 12 | private String sources; 13 | 14 | public FqnSearcher(String sources) { 15 | this.sources = sources; 16 | if (this.sources != null) { 17 | this.sources = this.sources.replace('\\', '/'); 18 | } 19 | } 20 | 21 | public String getFqn(SourceClass clazz, String name) { 22 | TargetParser targetParser = new TargetParser(sources); 23 | name = targetParser.parse(name); 24 | 25 | List fqns = new ArrayList<>(); 26 | for (ClassImport ci : clazz.getImports()) { 27 | if (!ci.isAsterisk()) { 28 | if (ci.getTail().equals(name)) { 29 | fqns.add(ci.getName()); 30 | break; 31 | } 32 | } else { 33 | fqns.add(replaceAsterisk(ci.getName()) + name); 34 | } 35 | } 36 | 37 | if (clazz.getPackage() != null) { 38 | fqns.add(clazz.getPackage().concat(".").concat(name)); 39 | } 40 | 41 | String result = searchForRealClass(fqns); 42 | if (result == null) { 43 | result = name; 44 | } 45 | 46 | return result.concat(searchForTypeArguments(clazz, targetParser.getTypeArguments())); 47 | } 48 | 49 | private String searchForRealClass(List fqns) { 50 | ClassSearcher seacher = new ClassSearcher(); 51 | for (String fqn : fqns) { 52 | if (seacher.find(fqn, sources)) { 53 | return fqn; 54 | } 55 | } 56 | 57 | return null; 58 | } 59 | 60 | private String searchForTypeArguments(SourceClass clazz, List typeArguments) { 61 | if (typeArguments.isEmpty()) { 62 | return ""; 63 | } 64 | 65 | StringBuilder arguments = new StringBuilder("<"); 66 | for (String arg : typeArguments) { 67 | String fqn = getFqn(clazz, arg); 68 | arguments.append(fqn).append(","); 69 | } 70 | arguments.setCharAt(arguments.length() - 1, '>'); 71 | 72 | return arguments.toString(); 73 | } 74 | 75 | private String replaceAsterisk(String asteriskImport) { 76 | String[] splitted = asteriskImport.split("\\."); 77 | String importName = ""; 78 | for (String s : splitted) { 79 | if (!s.equals("*")) { 80 | importName += s.concat("."); 81 | } 82 | } 83 | 84 | return importName; 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /libs/javavi/src/main/java/kg/ash/javavi/searchers/JavaClassMap.java: -------------------------------------------------------------------------------- 1 | package kg.ash.javavi.searchers; 2 | 3 | import java.io.Serializable; 4 | import java.util.ArrayList; 5 | import java.util.HashMap; 6 | import java.util.List; 7 | import java.util.Map; 8 | import java.util.Set; 9 | 10 | public abstract class JavaClassMap implements Serializable { 11 | 12 | public static final int SOURCETYPE_CLASSPATH = 0; 13 | public static final int SOURCETYPE_SOURCES = 1; 14 | 15 | public static final int TYPE_CLASS = 0; 16 | public static final int TYPE_SUBPACKAGE = 1; 17 | 18 | protected String name = null; 19 | protected HashMap pathsMap = new HashMap<>(); 20 | protected List classes = new ArrayList<>(); 21 | protected Map subpackages = new HashMap<>(); 22 | 23 | public JavaClassMap(String name) { 24 | setName(name); 25 | } 26 | 27 | public boolean contains(String path) { 28 | return pathsMap.containsKey(path); 29 | } 30 | 31 | public Set getPaths() { 32 | return pathsMap.keySet(); 33 | } 34 | 35 | public int getSourceType(String path) { 36 | return pathsMap.get(path); 37 | } 38 | 39 | public String getName() { 40 | return name; 41 | } 42 | 43 | public void setName(String name) { 44 | this.name = name; 45 | } 46 | 47 | public void add(String path, int source, int type, String filename) { 48 | if (!contains(path)) { 49 | pathsMap.put(path, source); 50 | if (type == TYPE_CLASS) { 51 | classes.add(path); 52 | } else { 53 | subpackages.put(path, filename); 54 | } 55 | } 56 | } 57 | 58 | public StringBuilder getCachedClasses() { 59 | StringBuilder cachedClasses = new StringBuilder(); 60 | classes.stream() 61 | .sorted() 62 | .forEach(path -> cachedClasses.append("'").append(path).append("',")); 63 | return cachedClasses; 64 | } 65 | 66 | public StringBuilder getCachedSubpackages() { 67 | StringBuilder cachedSubpackages = new StringBuilder(); 68 | subpackages.keySet() 69 | .stream() 70 | .sorted() 71 | .forEach(path -> cachedSubpackages.append("'").append(path).append("',")); 72 | return cachedSubpackages; 73 | } 74 | 75 | 76 | public Map getSubpackages() { 77 | return subpackages; 78 | } 79 | 80 | public abstract int getType(); 81 | 82 | @Override 83 | public String toString() { 84 | return String.format("name: %s, type: %d", name, getType()); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /libs/javavi/src/main/java/kg/ash/javavi/searchers/PackageEntry.java: -------------------------------------------------------------------------------- 1 | package kg.ash.javavi.searchers; 2 | 3 | public class PackageEntry { 4 | 5 | public final static int FILETYPE_JAVA = 0; 6 | public final static int FILETYPE_CLASS = 1; 7 | 8 | private String entry; 9 | private int source; 10 | private String javaFile = null; 11 | private String classFile = null; 12 | private String archiveName = null; 13 | 14 | public PackageEntry(String entry, int source) { 15 | this.entry = entry; 16 | this.source = source; 17 | } 18 | 19 | public PackageEntry(String entry, int source, String archiveName) { 20 | this.entry = entry; 21 | this.source = source; 22 | this.archiveName = archiveName; 23 | } 24 | 25 | public PackageEntry(String entry, int source, String filePath, int fileType) { 26 | this.entry = entry; 27 | this.source = source; 28 | if (fileType == FILETYPE_JAVA) { 29 | this.javaFile = filePath; 30 | } else { 31 | this.classFile = filePath; 32 | } 33 | } 34 | 35 | public String getEntry() { 36 | return entry; 37 | } 38 | 39 | public int getSource() { 40 | return source; 41 | } 42 | 43 | public String getJavaFile() { 44 | return javaFile; 45 | } 46 | 47 | public String getClassFile() { 48 | return classFile; 49 | } 50 | 51 | public String getArchiveName() { 52 | return archiveName; 53 | } 54 | 55 | @Override 56 | public String toString() { 57 | return String.format("{%s, %d, %s, %s}", entry, source, javaFile, classFile); 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /libs/javavi/src/main/java/kg/ash/javavi/searchers/PackageNameMap.java: -------------------------------------------------------------------------------- 1 | package kg.ash.javavi.searchers; 2 | 3 | public class PackageNameMap extends JavaClassMap { 4 | 5 | public PackageNameMap(String name) { 6 | super(name); 7 | } 8 | 9 | @Override 10 | public int getType() { 11 | return JavaClassMap.TYPE_SUBPACKAGE; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /libs/javavi/src/main/java/kg/ash/javavi/searchers/PackageSeacherIFace.java: -------------------------------------------------------------------------------- 1 | package kg.ash.javavi.searchers; 2 | 3 | import java.util.List; 4 | 5 | public interface PackageSeacherIFace { 6 | List loadEntries(); 7 | } 8 | -------------------------------------------------------------------------------- /libs/javavi/src/main/java/kg/ash/javavi/searchers/PackagesLoader.java: -------------------------------------------------------------------------------- 1 | package kg.ash.javavi.searchers; 2 | 3 | import java.util.ArrayList; 4 | import java.util.HashMap; 5 | import java.util.List; 6 | 7 | public class PackagesLoader { 8 | 9 | private HashMap classPackages; 10 | private List searchers = new ArrayList<>(); 11 | 12 | public PackagesLoader(String sourceDirectories) { 13 | searchers.add(new ClasspathPackageSearcher()); 14 | searchers.add(new SourcePackageSearcher(sourceDirectories)); 15 | } 16 | 17 | public void collectPackages(HashMap classPackages) { 18 | this.classPackages = classPackages; 19 | 20 | List entries = new ArrayList<>(); 21 | searchers.parallelStream().forEach(s -> entries.addAll(s.loadEntries())); 22 | 23 | entries.forEach(entry -> appendEntry(entry)); 24 | } 25 | 26 | public void setSearchers(List searchers) { 27 | this.searchers = searchers; 28 | } 29 | 30 | private void appendEntry(PackageEntry entry) { 31 | String name = entry.getEntry(); 32 | if (isClassFile(name)) { 33 | int seppos = name.lastIndexOf('$'); 34 | if (seppos < 0) { 35 | seppos = name.replace('\\', '/').lastIndexOf('/'); 36 | } 37 | if (seppos != -1) { 38 | processClass(entry, seppos); 39 | } 40 | } 41 | } 42 | 43 | private JavaClassMap getClassMap(String name, int type) { 44 | if (classPackages.containsKey(name) && classPackages.get(name).getType() == type) { 45 | return classPackages.get(name); 46 | } 47 | 48 | JavaClassMap jcm; 49 | if (type == JavaClassMap.TYPE_CLASS) { 50 | jcm = new ClassNameMap(name); 51 | } else { 52 | jcm = new PackageNameMap(name); 53 | } 54 | 55 | classPackages.put(name, jcm); 56 | return jcm; 57 | } 58 | 59 | private void processClass(PackageEntry entry, int seppos) { 60 | String name = entry.getEntry(); 61 | String parent = name.substring(0, seppos); 62 | String child = name.substring(seppos + 1, name.length() - 6); 63 | 64 | boolean nested = false; 65 | String parentDots = makeDots(parent); 66 | if (name.contains("$")) { 67 | nested = true; 68 | parentDots += "$"; 69 | } 70 | 71 | int source = entry.getSource(); 72 | 73 | if (!child.isEmpty() && !parentDots.isEmpty()) { 74 | ClassNameMap classMap = (ClassNameMap) getClassMap(child, JavaClassMap.TYPE_CLASS); 75 | classMap.add(parentDots, source, JavaClassMap.TYPE_SUBPACKAGE, entry.getArchiveName()); 76 | if (entry.getJavaFile() != null) { 77 | classMap.setJavaFile(entry.getJavaFile()); 78 | } 79 | if (entry.getClassFile() != null) { 80 | classMap.setClassFile(entry.getClassFile()); 81 | } 82 | 83 | if (!nested) { 84 | getClassMap(parentDots, JavaClassMap.TYPE_SUBPACKAGE).add(child, source, 85 | JavaClassMap.TYPE_CLASS, null); 86 | } 87 | 88 | addToParent(parent, source); 89 | } 90 | } 91 | 92 | private boolean isClassFile(String name) { 93 | return name.endsWith(".class"); 94 | } 95 | 96 | private void addToParent(String name, int source) { 97 | int seppos = name.replace('\\', '/').lastIndexOf('/'); 98 | if (seppos == -1) { 99 | return; 100 | } 101 | 102 | String parent = name.substring(0, seppos); 103 | String child = name.substring(seppos + 1); 104 | 105 | getClassMap(makeDots(parent), JavaClassMap.TYPE_SUBPACKAGE).add(child, source, 106 | JavaClassMap.TYPE_SUBPACKAGE, null); 107 | 108 | addToParent(parent, source); 109 | } 110 | 111 | private String makeDots(String name) { 112 | return name.replaceAll("/", ".").replaceAll("[.]{2,}", ""); 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /libs/javavi/src/main/java/kg/ash/javavi/searchers/SourceFileVisitor.java: -------------------------------------------------------------------------------- 1 | package kg.ash.javavi.searchers; 2 | 3 | import kg.ash.javavi.apache.logging.log4j.LogManager; 4 | import kg.ash.javavi.apache.logging.log4j.Logger; 5 | 6 | import java.io.IOException; 7 | import java.nio.file.FileSystems; 8 | import java.nio.file.FileVisitResult; 9 | import java.nio.file.Path; 10 | import java.nio.file.PathMatcher; 11 | import java.nio.file.SimpleFileVisitor; 12 | import java.nio.file.attribute.BasicFileAttributes; 13 | 14 | public class SourceFileVisitor extends SimpleFileVisitor { 15 | 16 | public static final Logger logger = LogManager.getLogger(); 17 | 18 | private final PathMatcher matcher; 19 | private String targetFile; 20 | private String pattern; 21 | 22 | public SourceFileVisitor(String pattern) { 23 | String path; 24 | pattern = pattern != null ? pattern : ""; 25 | 26 | if (pattern.contains(".")) { 27 | String[] splitted = pattern.split("\\."); 28 | path = splitted[splitted.length - 1]; 29 | } else { 30 | path = pattern; 31 | } 32 | 33 | logger.info("visit source: {}", path); 34 | matcher = FileSystems.getDefault().getPathMatcher(String.format("glob:%s.java", path)); 35 | 36 | this.pattern = pattern; 37 | } 38 | 39 | public String getTargetFile() { 40 | return targetFile; 41 | } 42 | 43 | private boolean find(Path file) { 44 | Path name = file.getFileName(); 45 | 46 | if (name != null && matcher.matches(name)) { 47 | if (pattern.contains(".")) { 48 | return checkPattern(file); 49 | } 50 | return true; 51 | } 52 | return false; 53 | } 54 | 55 | private boolean checkPattern(Path file) { 56 | String[] splitted = pattern.split("\\."); 57 | for (int i = splitted.length - 2; i >= 0; i--) { 58 | file = file.getParent(); 59 | if (file != null) { 60 | String filename = file.getFileName().toString(); 61 | if (!filename.equals(splitted[i])) { 62 | return false; 63 | } 64 | } else { 65 | return false; 66 | } 67 | } 68 | return true; 69 | } 70 | 71 | @Override 72 | public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) { 73 | if (!find(file)) { 74 | return FileVisitResult.CONTINUE; 75 | } 76 | 77 | targetFile = file.toFile().getPath().replace('\\', '/'); 78 | return FileVisitResult.TERMINATE; 79 | } 80 | 81 | @Override 82 | public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) { 83 | if (!find(dir)) { 84 | return FileVisitResult.CONTINUE; 85 | } 86 | 87 | return FileVisitResult.TERMINATE; 88 | } 89 | 90 | @Override 91 | public FileVisitResult visitFileFailed(Path file, IOException exc) { 92 | return FileVisitResult.CONTINUE; 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /libs/javavi/src/main/java/kg/ash/javavi/searchers/SourcePackageSearcher.java: -------------------------------------------------------------------------------- 1 | package kg.ash.javavi.searchers; 2 | 3 | import com.github.javaparser.JavaParser; 4 | import com.github.javaparser.ast.CompilationUnit; 5 | import kg.ash.javavi.apache.logging.log4j.LogManager; 6 | import kg.ash.javavi.apache.logging.log4j.Logger; 7 | 8 | import java.io.File; 9 | import java.io.FileInputStream; 10 | import java.io.IOException; 11 | import java.nio.file.Files; 12 | import java.nio.file.Paths; 13 | import java.util.ArrayList; 14 | import java.util.Arrays; 15 | import java.util.List; 16 | import java.util.stream.Collectors; 17 | 18 | public class SourcePackageSearcher implements PackageSeacherIFace { 19 | 20 | public static final Logger logger = LogManager.getLogger(); 21 | 22 | private String sourceDirectories = ""; 23 | private ByExtensionVisitor finder = new ByExtensionVisitor(Arrays.asList("*.java")); 24 | 25 | public SourcePackageSearcher(String sourceDirectories) { 26 | if (sourceDirectories != null) { 27 | this.sourceDirectories = sourceDirectories; 28 | } 29 | } 30 | 31 | public List loadEntries() { 32 | List result = new ArrayList<>(); 33 | for (String directory : getExistDirectories()) { 34 | try { 35 | logger.debug("search source files"); 36 | 37 | Files.walkFileTree(Paths.get(directory), finder); 38 | for (String path : finder.getResultList()) { 39 | String packagePath = fetchPackagePath(path); 40 | if (packagePath != null) { 41 | logger.trace(path); 42 | 43 | packagePath = packagePath.substring(0, packagePath.length() - 4) + "class"; 44 | result.add( 45 | new PackageEntry(packagePath, JavaClassMap.SOURCETYPE_SOURCES, path, 46 | PackageEntry.FILETYPE_JAVA)); 47 | } 48 | } 49 | } catch (IOException e) { 50 | logger.error(e, e); 51 | } 52 | } 53 | 54 | return result; 55 | } 56 | 57 | private List getExistDirectories() { 58 | String[] splitted = sourceDirectories.split(File.pathSeparator); 59 | return Arrays.asList(splitted) 60 | .stream() 61 | .filter(d -> new File(d).isDirectory()) 62 | .collect(Collectors.toList()); 63 | } 64 | 65 | private String fetchPackagePath(String sourcePath) { 66 | CompilationUnit cu; 67 | try (FileInputStream in = new FileInputStream(sourcePath)) { 68 | cu = JavaParser.parse(in); 69 | } catch (Exception ex) { 70 | return null; 71 | } 72 | 73 | if (cu.getPackageDeclaration().isPresent()) { 74 | int lastslash = sourcePath.replace('\\', '/').lastIndexOf('/'); 75 | if (lastslash >= 0) { 76 | String className = sourcePath.substring(lastslash + 1); 77 | String path = cu.getPackageDeclaration() 78 | .get() 79 | .getNameAsString() 80 | .replace(".", File.separator); 81 | return path + File.separator + className; 82 | } 83 | } 84 | 85 | return null; 86 | } 87 | } 88 | 89 | -------------------------------------------------------------------------------- /libs/javavi/src/main/resources/log4j2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 0 5 | off 6 | /tmp/javavi_log 7 | ${date:yyMMddHHmm} 8 | 9 | 10 | 11 | 12 | 13 | 14 | 16 | 17 | %d{MMdd HH:mm:ss.SSS} %p{length=1} [%t] %m [%c{-3}]%n 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /libs/javavi/src/test/java/kg/ash/javavi/DaemonTest.java: -------------------------------------------------------------------------------- 1 | package kg.ash.javavi; 2 | 3 | import org.junit.Assert; 4 | import org.junit.Test; 5 | 6 | public class DaemonTest { 7 | 8 | private Daemon daemon = new Daemon(0, -1); 9 | 10 | @Test 11 | public void testParseLine() { 12 | Assert.assertArrayEquals(new String[] { "-v" }, daemon.parseRequest("-v")); 13 | Assert.assertArrayEquals(new String[] { "-E", "java.util.List" }, 14 | daemon.parseRequest("-E \"java.util.List\"")); 15 | Assert.assertArrayEquals(new String[] { "-E", "java.util.List" }, 16 | daemon.parseRequest("-E java.util.List")); 17 | Assert.assertArrayEquals(new String[] { "-E", "java.util.List>" }, 18 | daemon.parseRequest("-E java.util.List>")); 19 | Assert.assertArrayEquals(new String[0], daemon.parseRequest("")); 20 | Assert.assertArrayEquals(new String[] { "-E", "" }, daemon.parseRequest("-E \"\"")); 21 | Assert.assertEquals("\\n", daemon.parseRequest("\"\\\\n\"")[0]); 22 | } 23 | 24 | @Test 25 | public void testParseEmptyValue() { 26 | Assert.assertEquals(new String[] { "-sources", "" }, daemon.parseRequest("-sources \"\"")); 27 | } 28 | 29 | @Test 30 | public void testWindowsDirectoryValue() { 31 | Assert.assertEquals(new String[] { "-base", "C:\\Documents and Settings\\directory\\" }, 32 | daemon.parseRequest("-base \"C:\\\\Documents and Settings\\\\directory\\\\\"")); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /libs/javavi/src/test/java/kg/ash/javavi/TargetParserTest.java: -------------------------------------------------------------------------------- 1 | package kg.ash.javavi; 2 | 3 | import org.junit.Assert; 4 | import org.junit.Test; 5 | 6 | public class TargetParserTest { 7 | 8 | @Test 9 | public void testParse() { 10 | TargetParser parser = new TargetParser(""); 11 | Assert.assertEquals("", parser.parse("")); 12 | Assert.assertEquals("java.util.List", parser.parse("java.util.List")); 13 | Assert.assertEquals(0, parser.getTypeArguments().size()); 14 | 15 | Assert.assertEquals("java.util.List", 16 | parser.parse("java.util.List>>")); 17 | Assert.assertEquals(1, parser.getTypeArguments().size()); 18 | Assert.assertEquals("java.util.List>", 19 | parser.getTypeArguments().get(0)); 20 | 21 | Assert.assertEquals("HashMap", parser.parse("HashMap>")); 22 | 23 | Assert.assertEquals("java.util.HashMap", parser.parse( 24 | "java.util.HashMap<(kg.ash.demo.String|java.lang.String),java.math.BigDecimal>")); 25 | Assert.assertEquals(2, parser.getTypeArguments().size()); 26 | Assert.assertEquals("java.lang.String", parser.getTypeArguments().get(0)); 27 | Assert.assertEquals("java.math.BigDecimal", parser.getTypeArguments().get(1)); 28 | 29 | Assert.assertEquals("java.util.List", parser.parse("java.util.List")); 30 | Assert.assertEquals("Integer", parser.getTypeArguments().get(0)); 31 | 32 | Assert.assertEquals("java.util.List", parser.parse("java.util.List")); 33 | Assert.assertEquals("Integer[]", parser.getTypeArguments().get(0)); 34 | 35 | Assert.assertEquals("java.util.List", parser.parse("java.util.List")); 36 | Assert.assertEquals("Integer", parser.getTypeArguments().get(0)); 37 | 38 | Assert.assertEquals("java.lang.Class", parser.parse("java.lang.Class")); 39 | 40 | Assert.assertEquals("java.util.HashMap$KeySet", parser.parse( 41 | "java.util.HashMap$KeySet<(kg.ash.demo.String|java.lang.String),java.math" 42 | + ".BigDecimal>")); 43 | Assert.assertEquals(2, parser.getTypeArguments().size()); 44 | Assert.assertEquals("java.lang.String", parser.getTypeArguments().get(0)); 45 | Assert.assertEquals("java.math.BigDecimal", parser.getTypeArguments().get(1)); 46 | 47 | Assert.assertEquals("java.util.List", 48 | parser.parse("java.util.List")); 49 | Assert.assertEquals("java.util.List", parser.parse( 50 | "java.util.List<(kg.test.Object|java.lang.Object),(kg.test.Object|java.lang.Object)," 51 | + "(kg.test.String|java.lang.String|java.lang.Object)>")); 52 | } 53 | 54 | @Test 55 | public void testTypeArgumentsToString() { 56 | TargetParser parser = new TargetParser(""); 57 | parser.parse("java.util.List"); 58 | Assert.assertEquals("", parser.getTypeArgumentsString()); 59 | parser.parse("java.util.List"); 60 | Assert.assertEquals("", parser.getTypeArgumentsString()); 61 | parser.parse("java.util.List"); 62 | Assert.assertEquals("", parser.getTypeArgumentsString()); 63 | parser.parse( 64 | "java.util.HashMap<(kg.ash.demo.String|java.lang.String),java.math.BigDecimal>"); 65 | Assert.assertEquals("", 66 | parser.getTypeArgumentsString()); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /libs/javavi/src/test/java/kg/ash/javavi/actions/ClassRecompileActionTest.java: -------------------------------------------------------------------------------- 1 | package kg.ash.javavi.actions; 2 | 3 | import kg.ash.javavi.Javavi; 4 | import kg.ash.javavi.searchers.ClassNameMap; 5 | import mockit.integration.junit4.JMockit; 6 | import org.junit.Test; 7 | import org.junit.runner.RunWith; 8 | 9 | @RunWith(JMockit.class) 10 | public class ClassRecompileActionTest { 11 | 12 | @Test 13 | public void testRecompilationCommandBuild() { 14 | ClassNameMap classMap = new ClassNameMap("foo.bar.Test"); 15 | classMap.setJavaFile("/path/to/src/foo/bar/Test.java"); 16 | classMap.setClassFile("/another/path/target/foo/bar/Test.class"); 17 | 18 | Javavi.system.put("compiler", "javac"); 19 | new ClassRecompileAction().perform(new String[] { classMap.getName() }); 20 | } 21 | 22 | @Test 23 | public void testBadTargetClass() { 24 | ClassNameMap classMap = new ClassNameMap("foo.bar.Test"); 25 | classMap.setJavaFile("/path/to/src/foo/bar/Test.java"); 26 | classMap.setClassFile("/bar/Test.class"); 27 | 28 | new ClassRecompileAction().perform(new String[] { classMap.getName() }); 29 | 30 | } 31 | 32 | @Test 33 | public void testBadSrcFile() { 34 | ClassNameMap classMap = new ClassNameMap("baz.Test"); 35 | classMap.setJavaFile("/bar/baz/Test.java"); 36 | classMap.setClassFile("/another/path/target/foo/bar/Test.class"); 37 | 38 | new ClassRecompileAction().perform(new String[] { classMap.getName() }); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /libs/javavi/src/test/java/kg/ash/javavi/actions/GetClassInfoActionTest.java: -------------------------------------------------------------------------------- 1 | package kg.ash.javavi.actions; 2 | 3 | import kg.ash.javavi.Javavi; 4 | import org.json.JSONObject; 5 | import org.junit.Assert; 6 | import org.junit.Ignore; 7 | import org.junit.Test; 8 | 9 | public class GetClassInfoActionTest { 10 | 11 | @Ignore 12 | @Test 13 | public void testCorrect() { 14 | Javavi.system.put("sources", ""); 15 | GetClassInfoAction cia = new GetClassInfoAction(); 16 | 17 | JSONObject json = new JSONObject( 18 | "{'java.lang.Object':{'implements':[],'fqn':'java.lang.Object','classpath':'1'," 19 | + "'ctors':[{'d':'public java.lang.Object()','m':'1'}],'methods':[{'r':'void'," 20 | + "'c':'void','d':'protected void java.lang.Object.finalize() throws java.lang" 21 | + ".Throwable','m':'100','n':'finalize'},{'p':['long','int'],'r':'void'," 22 | + "'c':'void','d':'public final void java.lang.Object.wait(long,int) throws java" 23 | + ".lang.InterruptedException','m':'10001','n':'wait'},{'p':['long'],'r':'void'," 24 | + "'c':'void','d':'public final native void java.lang.Object.wait(long) throws " 25 | + "java.lang.InterruptedException','m':'100010001','n':'wait'},{'r':'void'," 26 | + "'c':'void','d':'public final void java.lang.Object.wait() throws java.lang" 27 | + ".InterruptedException','m':'10001','n':'wait'},{'p':['java.lang.Object']," 28 | + "'r':'boolean','c':'boolean','d':'public boolean java.lang.Object.equals(java" 29 | + ".lang.Object)','m':'1','n':'equals'},{'r':'java.lang.String','c':'java.lang" 30 | + ".String','d':'public java.lang.String java.lang.Object.toString()','m':'1'," 31 | + "'n':'toString'},{'r':'int','c':'int','d':'public native int java.lang.Object" 32 | + ".hashCode()','m':'100000001','n':'hashCode'},{'r':'java.lang.Class'," 33 | + "'c':'java.lang.Class','d':'public final native java.lang.Class java.lang" 34 | + ".Object.getClass()','m':'100010001','n':'getClass'},{'r':'java.lang.Object'," 35 | + "'d':'protected native java.lang.Object java.lang.Object.clone() throws java" 36 | + ".lang.CloneNotSupportedException','m':'100000100','n':'clone'},{'r':'void'," 37 | + "'c':'void','d':'private static native void java.lang.Object.registerNatives()" 38 | + "','m':'100001010','n':'registerNatives'},{'r':'void','c':'void','d':'public " 39 | + "final native void java.lang.Object.notify()','m':'100010001','n':'notify'}," 40 | + "{'r':'void','c':'void','d':'public final native void java.lang.Object" 41 | + ".notifyAll()','m':'100010001','n':'notifyAll'}],'flags':'1','name':'java.lang" 42 | + ".Object','tag':'CLASSDEF','fields':[],'nested':[]}}"); 43 | Assert.assertTrue( 44 | json.similar(new JSONObject(cia.perform(new String[] { "-E", "java.lang.Object" })))); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /libs/javavi/src/test/java/kg/ash/javavi/actions/GetClassesArchiveNamesActionTest.java: -------------------------------------------------------------------------------- 1 | package kg.ash.javavi.actions; 2 | 3 | import kg.ash.javavi.searchers.ClassNameMap; 4 | import kg.ash.javavi.searchers.JavaClassMap; 5 | import mockit.Mock; 6 | import mockit.MockUp; 7 | import mockit.integration.junit4.JMockit; 8 | import org.junit.Assert; 9 | import org.junit.Test; 10 | import org.junit.runner.RunWith; 11 | 12 | import java.util.HashMap; 13 | 14 | @RunWith(JMockit.class) 15 | public class GetClassesArchiveNamesActionTest { 16 | 17 | @Test 18 | public void testArchiveNamesFetch() { 19 | new MockUp() { 20 | @Mock 21 | private HashMap getClassPackages() { 22 | HashMap map = new HashMap<>(); 23 | 24 | JavaClassMap jc = new ClassNameMap("List"); 25 | jc.add("java.util", JavaClassMap.SOURCETYPE_CLASSPATH, JavaClassMap.TYPE_SUBPACKAGE, 26 | "/dir/lib.jar"); 27 | map.put("List", jc); 28 | 29 | jc = new ClassNameMap("HashMap"); 30 | jc.add("java.util", JavaClassMap.SOURCETYPE_CLASSPATH, JavaClassMap.TYPE_SUBPACKAGE, 31 | "/dir/lib.jar"); 32 | map.put("HashMap", jc); 33 | 34 | return map; 35 | } 36 | }; 37 | 38 | GetClassesArchiveNamesAction action = new GetClassesArchiveNamesAction(); 39 | String result = action.perform(new String[] { "java.util.List,java.util.HashMap" }); 40 | Assert.assertEquals("[['/dir/lib.jar',['java.util.List','java.util.HashMap',]],]", result); 41 | } 42 | 43 | @Test 44 | public void testNoResult() { 45 | GetClassesArchiveNamesAction action = new GetClassesArchiveNamesAction(); 46 | Assert.assertEquals("[]", 47 | action.perform(new String[] { "java.util.List, java.util.HashMap" })); 48 | } 49 | 50 | @Test 51 | public void testEmptyRequest() { 52 | GetClassesArchiveNamesAction action = new GetClassesArchiveNamesAction(); 53 | Assert.assertEquals("[]", action.perform(new String[] { "" })); 54 | } 55 | 56 | @Test 57 | public void testNoArgs() { 58 | GetClassesArchiveNamesAction action = new GetClassesArchiveNamesAction(); 59 | Assert.assertEquals("[]", action.perform(new String[0])); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /libs/javavi/src/test/java/kg/ash/javavi/output/OutputClassPackagesTest.java: -------------------------------------------------------------------------------- 1 | package kg.ash.javavi.output; 2 | 3 | import kg.ash.javavi.Javavi; 4 | import kg.ash.javavi.cache.Cache; 5 | import kg.ash.javavi.searchers.ClassNameMap; 6 | import kg.ash.javavi.searchers.JavaClassMap; 7 | import org.junit.Assert; 8 | import org.junit.Before; 9 | import org.junit.Test; 10 | 11 | import java.util.HashMap; 12 | 13 | public class OutputClassPackagesTest { 14 | 15 | private String target = "Bar"; 16 | private HashMap classPackages; 17 | 18 | @Before 19 | public void Init() { 20 | Javavi.system.put("sources", ""); 21 | JavaClassMap classMap = new ClassNameMap(target); 22 | classMap.add("bar.baz", JavaClassMap.SOURCETYPE_CLASSPATH, JavaClassMap.TYPE_SUBPACKAGE, 23 | null); 24 | classMap.add("foo.bar", JavaClassMap.SOURCETYPE_CLASSPATH, JavaClassMap.TYPE_SUBPACKAGE, 25 | null); 26 | 27 | classPackages = new HashMap<>(); 28 | classPackages.put(target, classMap); 29 | } 30 | 31 | @Test 32 | public void testCorrect() { 33 | Assert.assertEquals("['foo.bar.Bar','bar.baz.Bar',]", 34 | new OutputClassPackages(classPackages).get(target)); 35 | } 36 | 37 | @Test 38 | public void testCorrectUknownTarget() { 39 | Assert.assertEquals("[]", new OutputClassPackages(classPackages).get("Baz")); 40 | } 41 | 42 | @Test 43 | public void testNullTarget() { 44 | Assert.assertEquals("[]", new OutputClassPackages(classPackages).get(null)); 45 | } 46 | 47 | @Test 48 | public void testNullPackages() { 49 | Assert.assertEquals(Cache.PACKAGES_EMPTY_ERROR, new OutputClassPackages(null).get(target)); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /libs/javavi/src/test/java/kg/ash/javavi/output/OutputPackageInfoTest.java: -------------------------------------------------------------------------------- 1 | package kg.ash.javavi.output; 2 | 3 | import kg.ash.javavi.cache.Cache; 4 | import kg.ash.javavi.searchers.ClassNameMap; 5 | import kg.ash.javavi.searchers.JavaClassMap; 6 | import org.junit.Assert; 7 | import org.junit.Before; 8 | import org.junit.Test; 9 | 10 | import java.util.HashMap; 11 | 12 | public class OutputPackageInfoTest { 13 | 14 | private String target = "foo.bar"; 15 | private HashMap classPackages; 16 | 17 | @Before 18 | public void Init() { 19 | JavaClassMap classMap = new ClassNameMap(target); 20 | classMap.add("baz", JavaClassMap.SOURCETYPE_CLASSPATH, JavaClassMap.TYPE_SUBPACKAGE, null); 21 | classMap.add("bax", JavaClassMap.SOURCETYPE_CLASSPATH, JavaClassMap.TYPE_SUBPACKAGE, null); 22 | classMap.add("Bat", JavaClassMap.SOURCETYPE_CLASSPATH, JavaClassMap.TYPE_CLASS, null); 23 | 24 | classPackages = new HashMap<>(); 25 | classPackages.put(target, classMap); 26 | } 27 | 28 | @Test 29 | public void testCorrect() { 30 | OutputPackageInfo opi = new OutputPackageInfo(classPackages); 31 | String result = opi.get(target); 32 | 33 | Assert.assertEquals(String.format( 34 | "{'%s':{'tag':'PACKAGE','subpackages':['bax','baz',],'classes':['Bat',]},}", target), 35 | result); 36 | } 37 | 38 | @Test 39 | public void testCorrectUknownTarget() { 40 | Assert.assertEquals("{}", new OutputPackageInfo(classPackages).get("foo.baa")); 41 | } 42 | 43 | @Test 44 | public void testNullTarget() { 45 | Assert.assertEquals("{}", new OutputPackageInfo(classPackages).get(null)); 46 | } 47 | 48 | @Test 49 | public void testNullPackages() { 50 | Assert.assertEquals(Cache.PACKAGES_EMPTY_ERROR, new OutputPackageInfo(null).get(target)); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /libs/javavi/src/test/java/kg/ash/javavi/output/OutputSimilarClassesTest.java: -------------------------------------------------------------------------------- 1 | package kg.ash.javavi.output; 2 | 3 | import kg.ash.javavi.cache.Cache; 4 | import kg.ash.javavi.searchers.ClassNameMap; 5 | import kg.ash.javavi.searchers.JavaClassMap; 6 | import org.junit.Assert; 7 | import org.junit.Before; 8 | import org.junit.Test; 9 | 10 | import java.util.HashMap; 11 | 12 | public class OutputSimilarClassesTest { 13 | 14 | private String target = "Bar"; 15 | private HashMap classPackages; 16 | 17 | @Before 18 | public void Init() { 19 | classPackages = new HashMap<>(); 20 | 21 | JavaClassMap classMap = new ClassNameMap("Barabaz"); 22 | classMap.add("bar", JavaClassMap.SOURCETYPE_CLASSPATH, JavaClassMap.TYPE_SUBPACKAGE, null); 23 | classPackages.put("Barabaz", classMap); 24 | 25 | classMap = new ClassNameMap("Bara"); 26 | classMap.add("bar.bara", JavaClassMap.SOURCETYPE_CLASSPATH, JavaClassMap.TYPE_SUBPACKAGE, 27 | null); 28 | classPackages.put("Bara", classMap); 29 | 30 | classMap = new ClassNameMap("Bazaraz"); 31 | classMap.add("bar.baz", JavaClassMap.SOURCETYPE_CLASSPATH, JavaClassMap.TYPE_SUBPACKAGE, 32 | null); 33 | classPackages.put("Bazaraz", classMap); 34 | 35 | classMap = new ClassNameMap("Foobar"); 36 | classMap.add("bar.bas", JavaClassMap.SOURCETYPE_CLASSPATH, JavaClassMap.TYPE_SUBPACKAGE, 37 | null); 38 | classPackages.put("Foobar", classMap); 39 | } 40 | 41 | @Test 42 | public void testCorrect() { 43 | String result = new OutputSimilarClasses(classPackages).get(target); 44 | 45 | Assert.assertEquals( 46 | "[{'word':'Bara', 'menu':'bar.bara', 'type': 'c'},{'word':'Barabaz', 'menu':'bar', " 47 | + "'type': 'c'},]", result); 48 | } 49 | 50 | @Test 51 | public void testCorrectUknownTarget() { 52 | Assert.assertEquals("[]", new OutputSimilarClasses(classPackages).get("Tar")); 53 | } 54 | 55 | @Test 56 | public void testNullTarget() { 57 | Assert.assertEquals("[]", new OutputSimilarClasses(classPackages).get(null)); 58 | } 59 | 60 | @Test 61 | public void testNullPackages() { 62 | Assert.assertEquals(Cache.PACKAGES_EMPTY_ERROR, new OutputSimilarClasses(null).get(target)); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /libs/javavi/src/test/java/kg/ash/javavi/readers/source/ClassNamesFetcherTest.java: -------------------------------------------------------------------------------- 1 | package kg.ash.javavi.readers.source; 2 | 3 | import com.github.javaparser.ast.CompilationUnit; 4 | import org.junit.Assert; 5 | import org.junit.Test; 6 | 7 | import java.util.Arrays; 8 | import java.util.HashSet; 9 | import java.util.Set; 10 | 11 | public class ClassNamesFetcherTest { 12 | 13 | 14 | @Test 15 | public void testClassnamesFetch() { 16 | String testClassDeclarationPath = 17 | "src/test/resources/kg/ash/javavi/ClassWithClasses.java"; 18 | 19 | CompilationUnitResult cur = CompilationUnitCreator.createFromFile( 20 | testClassDeclarationPath); 21 | Assert.assertNull(cur.getProblems()); 22 | CompilationUnit cu = cur.getCompilationUnit(); 23 | ClassNamesFetcher parser = new ClassNamesFetcher(cu); 24 | Set result = parser.getNames(); 25 | 26 | Assert.assertTrue(result.contains("BigDecimal")); 27 | Assert.assertTrue(result.contains("String")); 28 | Assert.assertTrue(result.contains("List")); 29 | Assert.assertTrue(result.contains("ArrayList")); 30 | Assert.assertTrue(result.contains("LinkedList")); 31 | Assert.assertEquals(5, result.size()); 32 | } 33 | 34 | @Test 35 | public void testClassnamesFetchComplex() { 36 | String fetcherTestClassDeclarationPath 37 | = "src/test/resources/kg/ash/javavi/ResourceClassForClassFetcherTest.java"; 38 | String waitFor = "UserTransaction, TestException, WebService, " 39 | + "HashMap, TestResponse, Resource, TestClass, String, " 40 | + "Logger, WebMethod, TestClassForbiddenException, Long, " 41 | + "EJB, BeanClass1, InterceptorRefs, InterceptorRef, BeanClass2, " 42 | + "WebParam, HashSet, Set, List, Map, Attr, ArrayList, HashLine, " 43 | + "SomeClass, unusualClassName, FakeAttr, StaticClassName, " 44 | + "AnotherStatic, ParentAnnotation, ChildAnnotation, format, " 45 | + "AnnotationForConstractor"; 46 | Set waitForList = new HashSet<>(); 47 | waitForList.addAll(Arrays.asList(waitFor.split(", "))); 48 | 49 | CompilationUnitResult cur = CompilationUnitCreator.createFromFile( 50 | fetcherTestClassDeclarationPath); 51 | Assert.assertNull(cur.getProblems()); 52 | CompilationUnit cu = cur.getCompilationUnit(); 53 | ClassNamesFetcher parser = new ClassNamesFetcher(cu); 54 | Set result = parser.getNames(); 55 | 56 | Assert.assertEquals(waitForList, result); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /libs/javavi/src/test/java/kg/ash/javavi/searchers/ClasspathPackageSearcherTest.java: -------------------------------------------------------------------------------- 1 | package kg.ash.javavi.searchers; 2 | 3 | import mockit.Mock; 4 | import mockit.MockUp; 5 | import mockit.integration.junit4.JMockit; 6 | import org.junit.Assert; 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import java.util.Arrays; 11 | import java.util.List; 12 | 13 | @RunWith(JMockit.class) 14 | public class ClasspathPackageSearcherTest { 15 | 16 | @Test 17 | public void testLoadClassFileEntries() { 18 | new MockUp() { 19 | @Mock 20 | private List collectClassPath() { 21 | return Arrays.asList("/directory/foo/bar/Classname.class", 22 | "/directory/foo/bar/Classname2.class", "/directory/foo/baz/Classname.class", 23 | ""); 24 | } 25 | 26 | }; 27 | 28 | new MockUp() { 29 | @Mock 30 | private String getPackageByFile(String path) { 31 | if (path.split("\\.").length > 2) { 32 | return path.substring(0, path.lastIndexOf('.')); 33 | } 34 | return null; 35 | } 36 | }; 37 | 38 | List entries = new ClasspathPackageSearcher().loadEntries(); 39 | Assert.assertEquals(3, entries.size()); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /libs/javavi/src/test/java/kg/ash/javavi/searchers/FqnSeacherTest.java: -------------------------------------------------------------------------------- 1 | package kg.ash.javavi.searchers; 2 | 3 | import kg.ash.javavi.clazz.ClassImport; 4 | import kg.ash.javavi.clazz.SourceClass; 5 | import org.junit.Assert; 6 | import org.junit.Test; 7 | 8 | public class FqnSeacherTest { 9 | 10 | @Test 11 | public void testGetFqn() { 12 | SourceClass clazz = new SourceClass(); 13 | clazz.getImports().add(new ClassImport("kg.ash.javavi.clazz.SourceClass", false, false)); 14 | clazz.getImports().add(new ClassImport("java.util.List", false, false)); 15 | 16 | String sourcesDirectory = System.getProperty("user.dir") + "/src/main/java/"; 17 | FqnSearcher seacher = new FqnSearcher(sourcesDirectory); 18 | 19 | Assert.assertEquals("FakeClass", seacher.getFqn(new SourceClass(), "FakeClass")); 20 | Assert.assertEquals("kg.ash.javavi.clazz.SourceClass", 21 | seacher.getFqn(clazz, "SourceClass")); 22 | Assert.assertEquals("java.util.List", seacher.getFqn(clazz, "List")); 23 | Assert.assertEquals("java.util.List", 24 | seacher.getFqn(clazz, "List")); 25 | 26 | clazz = new SourceClass(); 27 | clazz.setPackage("kg.ash.javavi.clazz"); 28 | clazz.getImports().add(new ClassImport("java.util.*", false, true)); 29 | 30 | Assert.assertEquals("kg.ash.javavi.clazz.SourceClass", 31 | seacher.getFqn(clazz, "SourceClass")); 32 | Assert.assertEquals("java.util.List", seacher.getFqn(clazz, "List")); 33 | Assert.assertEquals("java.util.List", 34 | seacher.getFqn(clazz, "List")); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /libs/javavi/src/test/java/kg/ash/javavi/searchers/PackagesLoaderTest.java: -------------------------------------------------------------------------------- 1 | package kg.ash.javavi.searchers; 2 | 3 | import org.junit.Assert; 4 | import org.junit.Before; 5 | import org.junit.Test; 6 | 7 | import java.util.ArrayList; 8 | import java.util.HashMap; 9 | import java.util.List; 10 | 11 | public class PackagesLoaderTest { 12 | 13 | private PackagesLoader ps; 14 | private HashMap result; 15 | private List searchers; 16 | 17 | @Before 18 | public void init() { 19 | result = new HashMap<>(); 20 | ps = new PackagesLoader(""); 21 | searchers = new ArrayList<>(); 22 | ps.setSearchers(searchers); 23 | } 24 | 25 | @Test 26 | public void testCorrect() { 27 | PackageSeacherIFace searcher = () -> { 28 | List entries = new ArrayList<>(); 29 | entries.add( 30 | new PackageEntry("java/util/List.class", JavaClassMap.SOURCETYPE_CLASSPATH)); 31 | entries.add( 32 | new PackageEntry("java/util/ArrayList.class", JavaClassMap.SOURCETYPE_CLASSPATH)); 33 | entries.add(new PackageEntry("foo.bar.class", JavaClassMap.SOURCETYPE_CLASSPATH)); 34 | entries.add( 35 | new PackageEntry("kg/ash/javavi/Javavi.class", JavaClassMap.SOURCETYPE_CLASSPATH)); 36 | return entries; 37 | }; 38 | 39 | searchers.add(searcher); 40 | ps.collectPackages(result); 41 | 42 | Assert.assertTrue(result.get("List").contains("java.util")); 43 | Assert.assertTrue(result.get("ArrayList").contains("java.util")); 44 | Assert.assertTrue(result.get("Javavi").contains("kg.ash.javavi")); 45 | Assert.assertNotEquals(null, result.get("java")); 46 | Assert.assertEquals(2, result.get("java.util").getPaths().size()); 47 | Assert.assertEquals(1, result.get("kg.ash.javavi").getPaths().size()); 48 | Assert.assertEquals(1, result.get("kg.ash").getPaths().size()); 49 | Assert.assertEquals(null, result.get("foo.bar")); 50 | } 51 | 52 | @Test 53 | public void testHandleEmpty() { 54 | PackageSeacherIFace searcher = () -> { 55 | List entries = new ArrayList<>(); 56 | entries.add(new PackageEntry("", JavaClassMap.SOURCETYPE_CLASSPATH)); 57 | return entries; 58 | }; 59 | 60 | searchers.add(searcher); 61 | ps.collectPackages(result); 62 | 63 | Assert.assertTrue(result.isEmpty()); 64 | } 65 | 66 | @Test 67 | public void testHandleTooManySlashes() { 68 | PackageSeacherIFace searcher = () -> { 69 | List entries = new ArrayList<>(); 70 | entries.add(new PackageEntry("/////", JavaClassMap.SOURCETYPE_CLASSPATH)); 71 | entries.add(new PackageEntry("/////.class", JavaClassMap.SOURCETYPE_CLASSPATH)); 72 | entries.add(new PackageEntry("/////a.class", JavaClassMap.SOURCETYPE_CLASSPATH)); 73 | return entries; 74 | }; 75 | 76 | searchers.add(searcher); 77 | ps.collectPackages(result); 78 | 79 | Assert.assertTrue(result.isEmpty()); 80 | } 81 | 82 | @Test 83 | public void testNestedClasses() { 84 | PackageSeacherIFace searcher = () -> { 85 | List entries = new ArrayList<>(); 86 | entries.add(new PackageEntry("java/util/HashMap$KeySet.class", 87 | JavaClassMap.SOURCETYPE_CLASSPATH)); 88 | entries.add(new PackageEntry("java/util/HashMap$TreeNode.class", 89 | JavaClassMap.SOURCETYPE_CLASSPATH)); 90 | entries.add( 91 | new PackageEntry("foo/bar/TreeNode.class", JavaClassMap.SOURCETYPE_CLASSPATH)); 92 | entries.add( 93 | new PackageEntry("java/util/ArrayList.class", JavaClassMap.SOURCETYPE_CLASSPATH)); 94 | return entries; 95 | }; 96 | 97 | searchers.add(searcher); 98 | ps.collectPackages(result); 99 | 100 | Assert.assertTrue(result.get("KeySet").contains("java.util.HashMap$")); 101 | Assert.assertTrue(result.get("TreeNode").contains("java.util.HashMap$")); 102 | Assert.assertTrue(result.get("TreeNode").contains("foo.bar")); 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /libs/javavi/src/test/java/kg/ash/javavi/searchers/SourceFileVisitorTest.java: -------------------------------------------------------------------------------- 1 | package kg.ash.javavi.searchers; 2 | 3 | import org.junit.Assert; 4 | import org.junit.Test; 5 | 6 | import java.io.File; 7 | 8 | public class SourceFileVisitorTest { 9 | 10 | @Test 11 | public void testCorrectPackageClass() { 12 | SourceFileVisitor visitor = new SourceFileVisitor("foo.bar.Baz"); 13 | visitor.visitFile(new File("src/foo/bar/Baz.java").toPath(), null); 14 | 15 | Assert.assertEquals("src/foo/bar/Baz.java", visitor.getTargetFile()); 16 | } 17 | 18 | @Test 19 | public void testCorrectClass() { 20 | SourceFileVisitor visitor = new SourceFileVisitor("Baz"); 21 | visitor.visitFile(new File("/root/src/foo/bar/Baz.java").toPath(), null); 22 | 23 | Assert.assertEquals("/root/src/foo/bar/Baz.java", visitor.getTargetFile()); 24 | } 25 | 26 | @Test 27 | public void testEmptyClassname() { 28 | SourceFileVisitor visitor = new SourceFileVisitor(""); 29 | visitor.visitFile(new File("src/foo/bar/Baz.java").toPath(), null); 30 | 31 | Assert.assertEquals(null, visitor.getTargetFile()); 32 | } 33 | 34 | @Test 35 | public void testSimilarPackageShouldNotBeFound() { 36 | SourceFileVisitor visitor = new SourceFileVisitor("foo.baz.Baz"); 37 | visitor.visitFile(new File("src/foo/bar/Baz.java").toPath(), null); 38 | 39 | Assert.assertEquals(null, visitor.getTargetFile()); 40 | } 41 | 42 | @Test 43 | public void testNullClassname() { 44 | SourceFileVisitor visitor = new SourceFileVisitor(null); 45 | visitor.visitFile(new File("src/foo/bar/Baz.java").toPath(), null); 46 | 47 | Assert.assertEquals(null, visitor.getTargetFile()); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /libs/javavi/src/test/resources/kg/ash/javavi/ClassWithClasses.java: -------------------------------------------------------------------------------- 1 | package kg.ash.javavi; 2 | 3 | import java.math.BigDecimal; 4 | import java.util.ArrayList; 5 | import java.util.LinkedList; 6 | import java.util.List; 7 | 8 | public class ClassWithClasses extends LinkedList { 9 | 10 | List list = new ArrayList(); 11 | 12 | public String method() { 13 | BigDecimal bd = BigDecimal.ONE; 14 | return "return"; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /libs/javavi/src/test/resources/kg/ash/javavi/ResourceClassForClassFetcherTest.java: -------------------------------------------------------------------------------- 1 | package kg.ash.javavi; 2 | 3 | import static java.text.MessageFormat.format; 4 | 5 | import org.apache.log4j.Logger; 6 | 7 | import java.util.ArrayList; 8 | import java.util.HashMap; 9 | import java.util.List; 10 | import java.util.Map; 11 | import javax.annotation.Resource; 12 | import javax.ejb.EJB; 13 | import javax.jws.WebMethod; 14 | import javax.jws.WebParam; 15 | import javax.jws.WebService; 16 | 17 | /** 18 | * @author Artur Shaikhullin 19 | */ 20 | 21 | @WebService(serviceName = "ResourceClassForClassFetcherTest") 22 | @InterceptorRefs({ 23 | @InterceptorRef("authStack"), @InterceptorRef("loggingStack") 24 | }) 25 | public class ResourceClassForClassFetcherTest { 26 | 27 | @Resource(attr = Attr.SOME_ATTR) private UserTransaction tx; 28 | 29 | @ParentAnnotation({ 30 | @ChildAnnotation 31 | }) private static final Logger logger = Logger.getLogger( 32 | ResourceClassForClassFetcherTest.class.getName()); 33 | private static final HashMap hashMap1 = new HashMap(); 34 | private static final HashMap hashMap2 = new HashMap(); 35 | 36 | @EJB private BeanClass1 bean1; 37 | @EJB private BeanClass2 bean2; 38 | 39 | @AnnotationForConstractor 40 | public ResourceClassForClassFetcherTest() { 41 | 42 | } 43 | 44 | private TestClass getTestClass(SomeClass source, String hash) 45 | throws TestClassForbiddenException { 46 | try { 47 | TestClass testClass = bean1.getByUniq(format()); 48 | String result = StaticClassName.staticMethod(); 49 | String result2 = AnotherStatic.staticReference; 50 | return testClass; 51 | } catch (TestClassForbiddenException ex) { 52 | logger.warn(String.format("Wrong testClass: %s %s", format(hash), source)); 53 | throw ex; 54 | } 55 | } 56 | 57 | /** 58 | * @return TestResponse 59 | */ 60 | @WebMethod(operationName = "test") 61 | public TestResponse test( 62 | @WebParam(name = "testClassID", fake = FakeAttr.ATTR) final String testClassID, 63 | @WebParam(name = "username") final String username, 64 | @WebParam(name = "hash") final HashLine hash) throws TestException { 65 | 66 | List myList = new ArrayList<>(); 67 | Set mySet = new HashSet<>(); 68 | Map.Entry.Fake e; 69 | logger.info( 70 | String.format("Test(id: %s, username: %s, hash: %s)", testClassID, username, hash)); 71 | Map.Entry e; 72 | logger.info(ar); 73 | return ar; 74 | } 75 | 76 | private class InnerClass { 77 | private unusualClassName UnusualObjectName; 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /libs/javavi_log4j-api.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/artur-shaik/vim-javacomplete2/a716e32bbe36daaed6ebc9aae76525aad9536245/libs/javavi_log4j-api.jar -------------------------------------------------------------------------------- /libs/javavi_log4j-core.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/artur-shaik/vim-javacomplete2/a716e32bbe36daaed6ebc9aae76525aad9536245/libs/javavi_log4j-core.jar -------------------------------------------------------------------------------- /plugin/res/gen__class.tpl: -------------------------------------------------------------------------------- 1 | function! s:__class(class, options) 2 | let result = "package ". a:options.package .";\n\n" 3 | let result .= "public class ". a:options.name 4 | if has_key(a:options, 'extends') 5 | let result .= " extends ". a:options['extends'] 6 | endif 7 | if has_key(a:options, 'implements') 8 | let result .= " implements ". a:options['implements'] 9 | endif 10 | let result .= " {\n" 11 | for fieldKey in keys(get(a:options, 'fields', {})) 12 | let field = a:options['fields'][fieldKey] 13 | let result .= field['mod']. " ". field['type']. " ". field['name']. ";\n" 14 | endfor 15 | return result . "\n}" 16 | endfunction 17 | -------------------------------------------------------------------------------- /plugin/res/gen__class_android_activity.tpl: -------------------------------------------------------------------------------- 1 | function! s:__class_android_activity(class, options) 2 | let result = "package ". a:options.package .";\n\n" 3 | let result .= "public class ". a:options.name 4 | if has_key(a:options, 'extends') 5 | let result .= " extends ". a:options['extends'] 6 | else 7 | let result .= " extends Activity" 8 | endif 9 | if has_key(a:options, 'implements') 10 | let result .= " implements ". a:options['implements'] 11 | endif 12 | let result .= " {\n" 13 | for fieldKey in keys(get(a:options, 'fields', {})) 14 | let field = a:options['fields'][fieldKey] 15 | let result .= field['mod']. " ". field['type']. " ". field['name']. ";\n" 16 | endfor 17 | let result .= "\n@Override\n" 18 | let result .= "public void onCreate(Bundle savedInstanceState) {\n" 19 | let result .= "super.onCreate(savedInstanceBundle);\n}\n" 20 | return result . "\n}" 21 | endfunction 22 | -------------------------------------------------------------------------------- /plugin/res/gen__class_android_broadcast_receiver.tpl: -------------------------------------------------------------------------------- 1 | function! s:__class_android_broadcast_receiver(class, options) 2 | let result = "package ". a:options.package .";\n\n" 3 | let result .= "public class ". a:options.name 4 | if has_key(a:options, 'extends') 5 | let result .= " extends ". a:options['extends'] 6 | else 7 | let result .= " extends BroadcastReceiver" 8 | endif 9 | if has_key(a:options, 'implements') 10 | let result .= " implements ". a:options['implements'] 11 | endif 12 | let result .= " {\n" 13 | for fieldKey in keys(get(a:options, 'fields', {})) 14 | let field = a:options['fields'][fieldKey] 15 | let result .= field['mod']. " ". field['type']. " ". field['name']. ";\n" 16 | endfor 17 | let result .= "\n@Override\n" 18 | let result .= "public void onReceive(Context context, Intent intent) {\n" 19 | let result .= "return null;\n}\n" 20 | return result . "\n}" 21 | endfunction 22 | -------------------------------------------------------------------------------- /plugin/res/gen__class_android_fragment.tpl: -------------------------------------------------------------------------------- 1 | function! s:__class_android_fragment(class, options) 2 | let result = "package ". a:options.package .";\n\n" 3 | let result .= "public class ". a:options.name 4 | if has_key(a:options, 'extends') 5 | let result .= " extends ". a:options['extends'] 6 | else 7 | let result .= " extends Fragment" 8 | endif 9 | if has_key(a:options, 'implements') 10 | let result .= " implements ". a:options['implements'] 11 | endif 12 | let result .= " {\n" 13 | for fieldKey in keys(get(a:options, 'fields', {})) 14 | let field = a:options['fields'][fieldKey] 15 | let result .= field['mod']. " ". field['type']. " ". field['name']. ";\n" 16 | endfor 17 | let result .= "\n@Override\n" 18 | let result .= "public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {\n" 19 | let result .= "return null;\n}\n" 20 | return result . "\n}" 21 | endfunction 22 | -------------------------------------------------------------------------------- /plugin/res/gen__class_android_service.tpl: -------------------------------------------------------------------------------- 1 | function! s:__class_android_service(class, options) 2 | let result = "package ". a:options.package .";\n\n" 3 | let result .= "public class ". a:options.name 4 | if has_key(a:options, 'extends') 5 | let result .= " extends ". a:options['extends'] 6 | else 7 | let result .= " extends Service" 8 | endif 9 | if has_key(a:options, 'implements') 10 | let result .= " implements ". a:options['implements'] 11 | endif 12 | let result .= " {\n" 13 | for fieldKey in keys(get(a:options, 'fields', {})) 14 | let field = a:options['fields'][fieldKey] 15 | let result .= field['mod']. " ". field['type']. " ". field['name']. ";\n" 16 | endfor 17 | let result .= "\n@Override\n" 18 | let result .= "public IBinder onBind(Intent intent) {\n" 19 | let result .= "return null;\n}\n" 20 | return result . "\n}" 21 | endfunction 22 | -------------------------------------------------------------------------------- /plugin/res/gen__class_annotation.tpl: -------------------------------------------------------------------------------- 1 | function! s:__class_annotation(class, options) 2 | let result = "package ". a:options.package .";\n\n" 3 | let result .= "public @interface ". a:options.name 4 | if has_key(a:options, 'extends') 5 | let result .= " extends ". a:options['extends'] 6 | endif 7 | if has_key(a:options, 'implements') 8 | let result .= " implements ". a:options['implements'] 9 | endif 10 | let result .= " {\n" 11 | for fieldKey in keys(get(a:options, 'fields', {})) 12 | let field = a:options['fields'][fieldKey] 13 | let result .= field['mod']. " ". field['type']. " ". field['name']. ";\n" 14 | endfor 15 | return result . "\n}" 16 | endfunction 17 | -------------------------------------------------------------------------------- /plugin/res/gen__class_enum.tpl: -------------------------------------------------------------------------------- 1 | function! s:__class_enum(class, options) 2 | let result = "package ". a:options.package .";\n\n" 3 | let result .= "public enum ". a:options.name 4 | let result .= " {\n" 5 | for fieldKey in keys(get(a:options, 'fields', {})) 6 | let field = a:options['fields'][fieldKey] 7 | let result .= field['mod']. " ". field['type']. " ". field['name']. ";\n" 8 | endfor 9 | return result . "\n}" 10 | endfunction 11 | -------------------------------------------------------------------------------- /plugin/res/gen__class_exception.tpl: -------------------------------------------------------------------------------- 1 | function! s:__class_exception(class, options) 2 | let result = "package ". a:options.package .";\n\n" 3 | let result .= "public class ". a:options.name 4 | if has_key(a:options, 'extends') 5 | let result .= " extends ". a:options['extends'] 6 | else 7 | let result .= " extends Exception" 8 | endif 9 | if has_key(a:options, 'implements') 10 | let result .= " implements ". a:options['implements'] 11 | endif 12 | let result .= " {\n" 13 | for fieldKey in keys(get(a:options, 'fields', {})) 14 | let field = a:options['fields'][fieldKey] 15 | let result .= field['mod']. " ". field['type']. " ". field['name']. ";\n" 16 | endfor 17 | let result .= "\npublic ". a:options.name. "() {\n\n}\n" 18 | let result .= "\npublic ". a:options.name. "(String msg) {\nsuper(msg);\n}\n" 19 | return result . "\n}" 20 | endfunction 21 | -------------------------------------------------------------------------------- /plugin/res/gen__class_interface.tpl: -------------------------------------------------------------------------------- 1 | function! s:__class_interface(class, options) 2 | let result = "package ". a:options.package .";\n\n" 3 | let result .= "public interface ". a:options.name 4 | if has_key(a:options, 'extends') 5 | let result .= " extends ". a:options['extends'] 6 | endif 7 | let result .= " {\n" 8 | for fieldKey in keys(get(a:options, 'fields', {})) 9 | let field = a:options['fields'][fieldKey] 10 | let result .= field['mod']. " ". field['type']. " ". field['name']. "();\n" 11 | endfor 12 | return result . "\n}" 13 | endfunction 14 | -------------------------------------------------------------------------------- /plugin/res/gen__class_junit.tpl: -------------------------------------------------------------------------------- 1 | function! s:__class_junit(class, options) 2 | let result = "package ". a:options.package .";\n\n" 3 | let result .= "import static org.junit.Assert.*;\n\n" 4 | let result .= "public class ". a:options.name 5 | if has_key(a:options, 'extends') 6 | let result .= " extends ". a:options['extends'] 7 | endif 8 | if has_key(a:options, 'implements') 9 | let result .= " implements ". a:options['implements'] 10 | endif 11 | let result .= " {\n" 12 | for fieldKey in keys(get(a:options, 'fields', {})) 13 | let field = a:options['fields'][fieldKey] 14 | let result .= field['mod']. " ". field['type']. " ". field['name']. ";\n" 15 | endfor 16 | let result .= "\n@Before\npublic void setUp() {\n\n}\n" 17 | return result . "\n}" 18 | endfunction 19 | -------------------------------------------------------------------------------- /plugin/res/gen__class_main.tpl: -------------------------------------------------------------------------------- 1 | function! s:__class_main(class, options) 2 | let result = "package ". a:options.package .";\n\n" 3 | let result .= "public class ". a:options.name 4 | if has_key(a:options, 'extends') 5 | let result .= " extends ". a:options['extends'] 6 | endif 7 | if has_key(a:options, 'implements') 8 | let result .= " implements ". a:options['implements'] 9 | endif 10 | let result .= " {\n" 11 | for fieldKey in keys(get(a:options, 'fields', {})) 12 | let field = a:options['fields'][fieldKey] 13 | let result .= field['mod']. " ". field['type']. " ". field['name']. ";\n" 14 | endfor 15 | let result .= "\npublic static void main(String[] args) {\n\n}\n" 16 | return result . "\n}" 17 | endfunction 18 | -------------------------------------------------------------------------------- /plugin/res/gen__class_servlet.tpl: -------------------------------------------------------------------------------- 1 | function! s:__class_servlet(class, options) 2 | let name = a:options.name 3 | let url = tolower(substitute(name, '\C\([A-Z]\)', '/\1', 'g')) 4 | let result = "package ". a:options.package .";\n\n" 5 | let result .= "@WebServlet(name = \"". name. "\", urlPatterns = {\"". url. "\"})\n" 6 | let result .= "public class ". name 7 | if has_key(a:options, 'extends') 8 | let result .= " extends ". a:options['extends'] 9 | else 10 | let result .= " extends HttpServlet" 11 | endif 12 | if has_key(a:options, 'implements') 13 | let result .= " implements ". a:options['implements'] 14 | endif 15 | let result .= " {\n" 16 | for fieldKey in keys(get(a:options, 'fields', {})) 17 | let field = a:options['fields'][fieldKey] 18 | let result .= field['mod']. " ". field['type']. " ". field['name']. ";\n" 19 | endfor 20 | let result .= "\nprotected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {\n" 21 | let result .= "response.setContentType(\"text/html;charset=UTF-8\");\n" 22 | let result .= "try (PrintWriter out = response.getWriter()) {\n" 23 | let result .= "try (PrintWriter out = response.getWriter()) {\n" 24 | let result .= "out.println(\"\");\n" 26 | let result .= "out.println(\"\");\n" 27 | let result .= "out.println(\"Servlet ". name. "\"); \n" 28 | let result .= "out.println(\"\");\n" 29 | let result .= "out.println(\"\");\n" 30 | let result .= "out.println(\"

Servlet ". name. " at ". url. "

\");\n" 31 | let result .= "out.println(\"\");\n" 32 | let result .= "out.println(\"\");\n" 33 | let result .= "} finally {\n" 34 | let result .= "out.close();\n" 35 | let result .= "}\n" 36 | let result .= "}\n" 37 | let result .= "}\n" 38 | let result .= "\nprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {\n" 39 | let result .= "processRequest(request, response);\n" 40 | let result .= "}\n" 41 | let result .= "\nprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {\n" 42 | let result .= "processRequest(request, response);\n" 43 | let result .= "}\n" 44 | return result . "\n}" 45 | endfunction 46 | -------------------------------------------------------------------------------- /plugin/res/gen__class_singleton.tpl: -------------------------------------------------------------------------------- 1 | function! s:__class_singleton(class, options) 2 | let result = "package ". a:options.package .";\n\n" 3 | let result .= "public class ". a:options.name 4 | if has_key(a:options, 'extends') 5 | let result .= " extends ". a:options['extends'] 6 | endif 7 | if has_key(a:options, 'implements') 8 | let result .= " implements ". a:options['implements'] 9 | endif 10 | let result .= " {\n" 11 | for fieldKey in keys(get(a:options, 'fields', {})) 12 | let field = a:options['fields'][fieldKey] 13 | let result .= field['mod']. " ". field['type']. " ". field['name']. ";\n" 14 | endfor 15 | let name = a:options['name'] 16 | let result .= "\nprivate ". name. "() {\n\n}\n" 17 | let result .= "\npublic static ". name. " getInstance() {\n" 18 | let result .= "return ". name. "Holder.INSTANCE;\n" 19 | let result .= "}\n" 20 | let result .= "\nprivate static class ". name. "Holder {\n" 21 | let result .= "private static final ". name. " INSTANCE = new ". name. "();\n" 22 | let result .= "}\n" 23 | return result . "\n}" 24 | endfunction 25 | -------------------------------------------------------------------------------- /plugin/res/gen__constructor.tpl: -------------------------------------------------------------------------------- 1 | function! s:__constructor(class, ...) 2 | let parameters = "" 3 | let body = "" 4 | let idx = 0 5 | if a:0 == 0 || a:1.default != 1 6 | for field in a:class.fields 7 | if idx != 0 8 | let parameters .= ", " 9 | endif 10 | let parameters .= field.type . " ". field.name 11 | let body .= "this.". field.name ." = ". field.name .";\n" 12 | let idx += 1 13 | endfor 14 | endif 15 | let result = "public ". a:class.name ."(". parameters. ") {\n" 16 | let result .= body 17 | return result . "}" 18 | endfunction 19 | -------------------------------------------------------------------------------- /plugin/res/gen__equals.tpl: -------------------------------------------------------------------------------- 1 | function! s:__equals(class) 2 | let result = "@Override\n" 3 | let result .= "public boolean equals(Object o) {\n" 4 | let result .= "if (this == o) return true;\n" 5 | let result .= "if (o == null || getClass() != o.getClass()) return false;\n\n" 6 | let result .= a:class.name ." object = (". a:class.name .") o;\n\n" 7 | let idx = 0 8 | for field in a:class.fields 9 | if idx != len(a:class.fields) - 1 10 | let result .= "if " 11 | else 12 | let result .= "return !" 13 | endif 14 | if index(g:J_PRIMITIVE_TYPES, field.type) > -1 15 | if field.type == "double" 16 | let result .= "(Double.compare(". field.name .", object.". field.name .") != 0)" 17 | elseif field.type == "float" 18 | let result .= "(Float.compare(". field.name .", object.". field.name .") != 0)" 19 | else 20 | let result .= "(". field.name ." != object.". field.name .")" 21 | endif 22 | elseif field.isArray 23 | let result .= "(!java.util.Arrays.equals(". field.name .", object.". field.name ."))" 24 | else 25 | let result .= "(". field.name ." != null ? !". field.name .".equals(object.". field.name .") : object.". field.name ." != null)" 26 | endif 27 | if idx != len(a:class.fields) - 1 28 | let result .= " return false;\n" 29 | else 30 | let result .= ";\n" 31 | endif 32 | let idx += 1 33 | endfor 34 | return result. "}" 35 | endfunction' 36 | -------------------------------------------------------------------------------- /plugin/res/gen__hashCode.tpl: -------------------------------------------------------------------------------- 1 | function! s:__hashCode(class) 2 | let result = "@Override\n" 3 | let result .= "public int hashCode() {\n" 4 | let result .= "int result = 17;\n" 5 | for field in a:class.fields 6 | if index(g:J_PRIMITIVE_TYPES, field.type) > -1 7 | if field.type == "boolean" 8 | let result .= "result = 31 * result + (". field.name . " ? 0 : 1);\n" 9 | elseif field.type == "long" 10 | let result .= "result = 31 * result + (int)(". field.name . " ^ (". field.name . " >>> 32));\n" 11 | elseif field.type == "float" 12 | let result .= "result = 31 * result + Float.floatToIntBits(". field.name . ");\n" 13 | elseif field.type == "double" 14 | let result .= "long ". field.name . "Long = Double.doubleToLongBits(". field.name .");\n" 15 | let result .= "result = 31 * result + (int)(". field.name . "Long ^ (". field.name . "Long >>> 32));\n" 16 | else 17 | let result .= "result = 31 * result + (int)". field.name . ";\n" 18 | endif 19 | elseif field.isArray 20 | let result .= "result = 31 * result + java.util.Arrays.hashCode(". field.name . ");\n" 21 | else 22 | let result .= "result = 31 * result + (". field.name . " != null ? ". field.name .".hashCode() : 0);\n" 23 | endif 24 | endfor 25 | return result. "return result;\n}" 26 | endfunction' 27 | -------------------------------------------------------------------------------- /plugin/res/gen__toString_StringBuilder.tpl: -------------------------------------------------------------------------------- 1 | function! s:__toString_StringBuilder(class) 2 | let result = "@Override\n" 3 | let result .= "public String toString() {\n" 4 | let result .= "final StringBuilder sb = new StringBuilder(\"". a:class.name . "{\");\n" 5 | let i = 0 6 | for field in a:class.fields 7 | if i > 0 8 | let result .= "\nsb.append(\", " 9 | else 10 | let result .= "sb.append(\"" 11 | let i += 1 12 | endif 13 | if has_key(field, "getter") 14 | let f = field.getter 15 | else 16 | let f = field.name 17 | endif 18 | let f = field.isArray ? "java.util.Arrays.toString(". f .")" : f 19 | let result .= field.name ." = \").append(". f. ");" 20 | endfor 21 | return result . "\nreturn sb.append(\"}\").toString();\n}" 22 | endfunction' 23 | -------------------------------------------------------------------------------- /plugin/res/gen__toString_concat.tpl: -------------------------------------------------------------------------------- 1 | function! s:__toString_concat(class) 2 | let result = "@Override\n" 3 | let result .= "public String toString() {\n" 4 | let result .= "return \"". a:class.name ."{\" +\n" 5 | let i = 0 6 | for field in a:class.fields 7 | if i > 0 8 | let result .= "\n\", " 9 | else 10 | let result .= "\"" 11 | let i += 1 12 | endif 13 | if has_key(field, "getter") 14 | let f = field.getter 15 | else 16 | let f = field.name 17 | endif 18 | let f = field.isArray ? "java.util.Arrays.toString(". f .")" : f 19 | let result .= field.name ." = \" + ". f. " +" 20 | endfor 21 | return result . "\n\"}\";\n}" 22 | endfunction' 23 | -------------------------------------------------------------------------------- /rplugin/python3/deoplete/sources/javacomplete2.py: -------------------------------------------------------------------------------- 1 | import pynvim 2 | from deoplete.base.source import Base 3 | 4 | class Source(Base): 5 | def __init__(self, vim): 6 | Base.__init__(self, vim) 7 | 8 | self.name = 'javacomplete2' 9 | self.mark = '[jc]' 10 | self.filetypes = ['java', 'jsp'] 11 | self.is_bytepos = True 12 | self.input_pattern = '[^. \t0-9]\.\w*' 13 | self.rank = 500 14 | self.max_pattern_length = -1 15 | self.matchers = ['matcher_full_fuzzy'] 16 | 17 | def get_complete_position(self, context): 18 | return self.vim.call('javacomplete#complete#complete#Complete', 19 | 1, '', 0) 20 | 21 | def gather_candidates(self, context): 22 | try: 23 | return self.vim.call('javacomplete#complete#complete#Complete', 24 | 0, context['complete_str'], 0) 25 | except pynvim.api.common.NvimError as er: 26 | print(er) 27 | raise er 28 | -------------------------------------------------------------------------------- /t/collector.vim: -------------------------------------------------------------------------------- 1 | source plugin/javacomplete.vim 2 | source autoload/javacomplete.vim 3 | source autoload/javacomplete/collector.vim 4 | source t/javacomplete.vim 5 | 6 | call vspec#hint({'sid': 'g:SID("collector")', 'scope': 'SScope()'}) 7 | 8 | describe 'javacomplete-test' 9 | it 'CollectFQNs test' 10 | Expect Call('s:CollectFQNs', 'List', 'kg.ash.foo', '', '') == ['kg.ash.foo.List','java.lang.List', 'java.lang.Object'] 11 | Expect Call('s:CollectFQNs', 'java.util.List', 'kg.ash.foo', '', '') == ['java.util.List'] 12 | Expect Call('s:CollectFQNs', 'Object', 'kg.ash.foo', '', '') == ['kg.ash.foo.Object','java.lang.Object'] 13 | 14 | new 15 | source autoload/javacomplete.vim 16 | put ='import java.util.List;' 17 | Expect Call('s:CollectFQNs', 'List', '', '', '') == ['java.util.List'] 18 | 19 | new 20 | source autoload/javacomplete.vim 21 | put ='import java.util.*;' 22 | put ='import java.foo.*;' 23 | Expect Call('s:CollectFQNs', 'List', '', '', '') == ['List', 'java.lang.List', 'java.util.List', 'java.foo.List', 'java.lang.Object'] 24 | Expect Call('s:CollectFQNs', 'List', 'kg.ash.foo', '', '') == ['kg.ash.foo.List', 'java.lang.List', 'java.util.List', 'java.foo.List', 'java.lang.Object'] 25 | end 26 | 27 | it 'GetPackageName test' 28 | 29 | Expect Call('javacomplete#collector#GetPackageName') == '' 30 | 31 | new 32 | put ='package foo.bar.baz' 33 | Expect Call('javacomplete#collector#GetPackageName') == '' 34 | 35 | new 36 | put ='package foo.bar.baz;' 37 | Expect Call('javacomplete#collector#GetPackageName') == 'foo.bar.baz' 38 | end 39 | 40 | it 'CollectTypeArguments test' 41 | source autoload/javacomplete.vim 42 | Expect Call('s:CollectTypeArguments', '', '', '') == '' 43 | 44 | Expect Call('s:CollectTypeArguments', 'Integer', '', '') == '<(Integer|java.lang.Integer|java.lang.Object)>' 45 | Expect Call('s:CollectTypeArguments', 'Integer[]', '', '') == '<(Integer[]|java.lang.Integer[]|java.lang.Object)>' 46 | Expect Call('s:CollectTypeArguments', '? super Integer[]', '', '') == '<(Integer[]|java.lang.Integer[]|java.lang.Object)>' 47 | 48 | new 49 | source autoload/javacomplete.vim 50 | put ='import java.util.List;' 51 | put ='import java.util.HashMap;' 52 | Expect Call('s:CollectTypeArguments', 'List>', '', '') == '>>' 53 | Expect Call('s:CollectTypeArguments', 'HashMap', '', '') == '>' 54 | Expect Call('s:CollectTypeArguments', 'String,BigDecimal', '', '') == '<(String|java.lang.String|java.lang.Object),(BigDecimal|java.lang.BigDecimal|java.lang.Object)>' 55 | put ='import java.math.BigDecimal;' 56 | Expect Call('s:CollectTypeArguments', 'String,BigDecimal', '', '') == '<(String|java.lang.String|java.lang.Object),java.math.BigDecimal>' 57 | 58 | Expect Call('s:CollectTypeArguments', 'MyClass', '', '') == '<(MyClass|java.lang.MyClass|java.lang.Object)>' 59 | Expect Call('s:CollectTypeArguments', 'MyClass', 'foo.bar.baz', '') == '<(foo.bar.baz.MyClass|java.lang.MyClass|java.lang.Object)>' 60 | 61 | Expect Call('s:CollectTypeArguments', 'Object,Object,String', 'kg.test', '') == '<(kg.test.Object|java.lang.Object),(kg.test.Object|java.lang.Object),(kg.test.String|java.lang.String|java.lang.Object)>' 62 | end 63 | 64 | it 'SplitTypeArguments test' 65 | Expect Call('s:SplitTypeArguments', 'java.util.List') == ['java.util.List', 'Integer'] 66 | Expect Call('s:SplitTypeArguments', 'java.util.List') == ['java.util.List', 'java.lang.Integer'] 67 | Expect Call('s:SplitTypeArguments', 'java.util.HashMap') == ['java.util.HashMap', 'Integer,String'] 68 | Expect Call('s:SplitTypeArguments', 'java.util.List') == ['java.util.List', '? extends java.lang.Integer[]'] 69 | Expect Call('s:SplitTypeArguments', 'List') == ['List', '? extends java.lang.Integer[]'] 70 | Expect Call('s:SplitTypeArguments', 'java.util.HashMap') == ['java.util.HashMap', '? super Integer,? extends String'] 71 | Expect Call('s:SplitTypeArguments', 'java.util.function.ToIntFunction') == ['java.util.function.ToIntFunction', '? super java.lang.Integer[]'] 72 | Expect Call('s:SplitTypeArguments', 'java.lang.Class') == ['java.lang.Class', 0] 73 | end 74 | 75 | end 76 | -------------------------------------------------------------------------------- /t/complete.vim: -------------------------------------------------------------------------------- 1 | source plugin/javacomplete.vim 2 | source autoload/javacomplete.vim 3 | source autoload/javacomplete/complete/complete.vim 4 | source t/javacomplete.vim 5 | 6 | call vspec#hint({'sid': 'g:SID("complete/complete")', 'scope': 'SScope()'}) 7 | 8 | describe 'javacomplete-test' 9 | it 'Regexps test' 10 | let reTypeArgument = g:RE_TYPE_ARGUMENT 11 | let reTypeArgumentExtends = g:RE_TYPE_ARGUMENT_EXTENDS 12 | Expect 'Integer[]' =~ reTypeArgument 13 | Expect 'Integer[]' !~ reTypeArgumentExtends 14 | Expect '? super Integer[]' =~ reTypeArgument 15 | Expect '? super Integer[]' =~ reTypeArgumentExtends 16 | 17 | let qualid = g:RE_QUALID 18 | Expect 'java.util.function.ToIntFunction' =~ '^\s*' . qualid . '\s*$' 19 | end 20 | 21 | end 22 | -------------------------------------------------------------------------------- /t/data/LambdaAnonClass.java: -------------------------------------------------------------------------------- 1 | package kg.ash.demo; 2 | 3 | import java.util.ArrayList; 4 | import java.util.HashMap; 5 | import java.util.List; 6 | import java.math.BigDecimal; 7 | 8 | public class LambdaAnonClass { 9 | 10 | public LambdaAnonClass() { 11 | List lint = new ArrayList<>(); 12 | 13 | lint.stream().filter(t -> { 14 | Integer i = new Integer(); 15 | t.; 16 | }); 17 | 18 | lint.stream().filter((t, d) -> { 19 | Integer i = new Integer(); 20 | d. 21 | }); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /t/data/LambdaNamedClass.java: -------------------------------------------------------------------------------- 1 | package kg.ash.demo; 2 | 3 | import java.util.ArrayList; 4 | import java.util.HashMap; 5 | import java.util.List; 6 | import java.math.BigDecimal; 7 | 8 | public class LambdaNamedClass { 9 | 10 | public LambdaNamedClass() { 11 | List lint = new ArrayList<>(); 12 | List>> list 13 | = new ArrayList<>(); 14 | 15 | lint.stream().filter((String t, BigDecimal d) -> { 16 | Integer i = new Integer(); 17 | t. 18 | d. 19 | }); 20 | 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /t/data/LambdaReturnClass.java: -------------------------------------------------------------------------------- 1 | package kg.ash.javavi; 2 | 3 | import java.util.function.Predicate; 4 | 5 | public class LambdaReturnClass { 6 | 7 | public Predicate getCondition() { 8 | return p -> p. 9 | } 10 | 11 | } 12 | -------------------------------------------------------------------------------- /t/imports.vim: -------------------------------------------------------------------------------- 1 | source autoload/javacomplete/imports.vim 2 | source plugin/javacomplete.vim 3 | source t/javacomplete.vim 4 | 5 | call vspec#hint({'sid': 'g:SID("imports")', 'scope': 'SScope()'}) 6 | 7 | describe 'javacomplete imports test' 8 | it 'AddImport test' 9 | new 10 | source autoload/javacomplete.vim 11 | put! ='package kg.ash.foo;' 12 | 13 | call Call('s:AddImport', 'java.util.List') 14 | Expect getline(3) == 'import java.util.List;' 15 | 16 | call Call('s:AddImport', 'java.util.ArrayList') 17 | Expect getline(3) == 'import java.util.List;' 18 | 19 | call Call('s:AddImport', 'foo.bar.Baz') 20 | Expect getline(5) == 'import foo.bar.Baz;' 21 | 22 | call Call('s:AddImport', 'zoo.bar.Baz') 23 | Expect getline(5) == 'import zoo.bar.Baz;' 24 | 25 | call Call('s:AddImport', 'zoo.bar.Baz') 26 | Expect getline(5) == 'import zoo.bar.Baz;' 27 | 28 | new 29 | 30 | source autoload/javacomplete.vim 31 | call Call('s:AddImport', 'java.util.List') 32 | Expect getline(1) == 'import java.util.List;' 33 | 34 | call Call('s:AddImport', 'java.util.ArrayList') 35 | Expect getline(2) == 'import java.util.ArrayList;' 36 | 37 | call Call('s:AddImport', 'foo.bar.Baz') 38 | Expect getline(3) == 'import foo.bar.Baz;' 39 | 40 | call Call('s:AddImport', 'zoo.bar.Baz') 41 | Expect getline(3) == 'import zoo.bar.Baz;' 42 | 43 | end 44 | end 45 | -------------------------------------------------------------------------------- /t/java_parser.vim: -------------------------------------------------------------------------------- 1 | source autoload/java_parser.vim 2 | source t/javacomplete.vim 3 | 4 | function! SID() abort 5 | redir => l:scriptnames 6 | silent scriptnames 7 | redir END 8 | for line in split(l:scriptnames, '\n') 9 | let [l:sid, l:path] = matchlist(line, '^\s*\(\d\+\):\s*\(.*\)$')[1:2] 10 | if l:path =~# '\' . l:sid . '_' 12 | endif 13 | endfor 14 | endfunction 15 | call vspec#hint({'sid': 'SID()', 'scope': 'java_parser#SScope()'}) 16 | 17 | 18 | describe 'javaparser test' 19 | it 'test' 20 | call Call('java_parser#InitParser', []) 21 | call Call('java_parser#compilationUnit') 22 | Expect Call('java_parser#expression') == {"tag": "ERRONEOUS", "errs": [], "pos": 0} 23 | 24 | let source = ['package foo.bar.baz;', 25 | \ 'public class DemoClass {', 26 | \ ' String str = new String();', 27 | \ ' public DemoClass() {', 28 | \ ' Integer in = new Integer();', 29 | \ ' }', 30 | \ '}'] 31 | 32 | call Call('java_parser#InitParser', source) 33 | Expect Call('java_parser#compilationUnit') != 0 34 | call Call('java_parser#GotoPosition', '96') 35 | Expect Call('java_parser#statement') != 0 36 | Expect Call('java_parser#nextToken') == 0 37 | end 38 | 39 | it 'GetInnerText test' 40 | let tree = Call('javacomplete#parseradapter#Parse', 't/data/LambdaNamedClass.java') 41 | 42 | call Call('java_parser#GotoPosition', 380) 43 | Expect Call('s:GetInnerText', '(') == '(String t, BigDecimal d)' 44 | 45 | call Call('java_parser#GotoPosition', 400) 46 | Expect Call('s:GetInnerText', '{') == '{ Integer i = new Integer(); t. d. }' 47 | end 48 | end 49 | -------------------------------------------------------------------------------- /t/javacomplete.vim: -------------------------------------------------------------------------------- 1 | source plugin/javacomplete.vim 2 | source autoload/javacomplete.vim 3 | source autoload/java_parser.vim 4 | 5 | function! g:SID(file) abort 6 | redir => l:scriptnames 7 | silent scriptnames 8 | redir END 9 | for line in split(l:scriptnames, '\n') 10 | let [l:sid, l:path] = matchlist(line, '^\s*\(\d\+\):\s*\(.*\)$')[1:2] 11 | if l:path =~# '\' . l:sid . '_' 13 | endif 14 | endfor 15 | endfunction 16 | -------------------------------------------------------------------------------- /t/parseradapter.vim: -------------------------------------------------------------------------------- 1 | source plugin/javacomplete.vim 2 | source autoload/javacomplete.vim 3 | source autoload/javacomplete/parseradapter.vim 4 | source t/javacomplete.vim 5 | 6 | call vspec#hint({'sid': 'g:SID("parseradapter")', 'scope': 'SScope()'}) 7 | 8 | describe 'javacomplete parseradapter test' 9 | it 'Lambdas anonym argument search test' 10 | let tree = Call('javacomplete#parseradapter#Parse', 't/data/LambdaAnonClass.java') 11 | 12 | let result = Call('javacomplete#parseradapter#SearchNameInAST', tree, 't', 388, 1) 13 | Expect result[0].tag == 'LAMBDA' 14 | Expect result[0].args.tag == 'IDENT' 15 | Expect result[0].args.name == 't' 16 | 17 | let result = Call('javacomplete#parseradapter#SearchNameInAST', tree, 'd', 463, 1) 18 | Expect result[1].tag == 'LAMBDA' 19 | Expect result[1].args[0].tag == 'IDENT' 20 | Expect result[1].args[0].name == 't' 21 | end 22 | 23 | it 'Lambdas in method return' 24 | let tree = Call('javacomplete#parseradapter#Parse', 't/data/LambdaReturnClass.java') 25 | 26 | let result = Call('javacomplete#parseradapter#SearchNameInAST', tree, 'p', 171, 1) 27 | Expect result[0].tag == 'LAMBDA' 28 | Expect result[0].args.tag == 'IDENT' 29 | Expect result[0].args.name == 'p' 30 | end 31 | 32 | end 33 | -------------------------------------------------------------------------------- /t/scanner.vim: -------------------------------------------------------------------------------- 1 | source autoload/javacomplete/scanner.vim 2 | source t/javacomplete.vim 3 | 4 | call vspec#hint({'sid': 'g:SID("scanner")', 'scope': 'SScope()'}) 5 | 6 | describe 'javacomplete scanner test' 7 | it 'ParseExpr test' 8 | Expect Call('javacomplete#scanner#ParseExpr', 'var') == ['var'] 9 | Expect Call('javacomplete#scanner#ParseExpr', 'var.') == ['var'] 10 | Expect Call('javacomplete#scanner#ParseExpr', 'var.method().') == ['var', 'method()'] 11 | Expect Call('javacomplete#scanner#ParseExpr', 'var.vari') == ['var', 'vari'] 12 | Expect Call('javacomplete#scanner#ParseExpr', 'var.vari.') == ['var', 'vari'] 13 | Expect Call('javacomplete#scanner#ParseExpr', 'var[].') == ['var[]'] 14 | Expect Call('javacomplete#scanner#ParseExpr', '(Boolean) var.') == [' var'] 15 | Expect Call('javacomplete#scanner#ParseExpr', '((Boolean) var).') == ['(Boolean)obj.'] 16 | Expect Call('javacomplete#scanner#ParseExpr', '((Boolean) var).method()') == ['(Boolean)obj.', 'method()'] 17 | Expect Call('javacomplete#scanner#ParseExpr', 'System.out::') == ['System', 'out'] 18 | Expect Call('javacomplete#scanner#ParseExpr', 'System.out:') == ['System', 'out'] 19 | end 20 | 21 | it 'ExtractCleanExpr test' 22 | Expect Call('javacomplete#scanner#ExtractCleanExpr', 'var') == 'var' 23 | Expect Call('javacomplete#scanner#ExtractCleanExpr', ' var.') == 'var.' 24 | Expect Call('javacomplete#scanner#ExtractCleanExpr', 'var [ 0 ].') == 'var[0].' 25 | Expect Call('javacomplete#scanner#ExtractCleanExpr', 'Boolean b = ((Boolean) var).method()') == '((Boolean)var).method()' 26 | Expect Call('javacomplete#scanner#ExtractCleanExpr', 'List::') == 'List::' 27 | Expect Call('javacomplete#scanner#ExtractCleanExpr', 'import ="java.util') == 'java.util' 28 | Expect Call('javacomplete#scanner#ExtractCleanExpr', 'import = "java.util') == 'java.util' 29 | Expect Call('javacomplete#scanner#ExtractCleanExpr', '? super java.lang.String') == 'java.lang.String' 30 | end 31 | 32 | end 33 | -------------------------------------------------------------------------------- /t/utils.vim: -------------------------------------------------------------------------------- 1 | source autoload/javacomplete/util.vim 2 | source t/javacomplete.vim 3 | 4 | call vspec#hint({'sid': 'g:SID("util")'}) 5 | 6 | 7 | describe 'javacomplete utils test' 8 | it 'CountDims test' 9 | Expect Call('javacomplete#util#CountDims', '') == 0 10 | Expect Call('javacomplete#util#CountDims', 'String[]') == 1 11 | Expect Call('javacomplete#util#CountDims', 'String[][]') == 2 12 | Expect Call('javacomplete#util#CountDims', 'String[][][][][]') == 5 13 | Expect Call('javacomplete#util#CountDims', 'String]') == 1 14 | Expect Call('javacomplete#util#CountDims', 'String[') == 0 15 | Expect Call('javacomplete#util#CountDims', 'String[[') == 0 16 | Expect Call('javacomplete#util#CountDims', 'String]]') == 1 17 | end 18 | 19 | it 'GetClassNameWithScope test' 20 | new 21 | put ='ArrayLi' 22 | Expect Call('javacomplete#util#GetClassNameWithScope') == 'ArrayLi' 23 | 24 | new 25 | put ='ArrayList ' 26 | Expect Call('javacomplete#util#GetClassNameWithScope') == 'ArrayList' 27 | 28 | new 29 | put ='ArrayList l' 30 | call cursor(0, 10) 31 | Expect Call('javacomplete#util#GetClassNameWithScope') == 'ArrayList' 32 | 33 | new 34 | call cursor(1, 1) 35 | put! ='ArrayList l' 36 | call cursor(1, 11) 37 | Expect Call('javacomplete#util#GetClassNameWithScope') == 'String' 38 | 39 | new 40 | call cursor(1, 1) 41 | put! ='List l = new ArrayList()' 42 | call cursor(1, 1) 43 | Expect Call('javacomplete#util#GetClassNameWithScope') == 'List' 44 | call cursor(1, 14) 45 | Expect Call('javacomplete#util#GetClassNameWithScope') == 'ArrayList' 46 | call cursor(1, 31) 47 | Expect Call('javacomplete#util#GetClassNameWithScope') == '' 48 | 49 | new 50 | call cursor(1, 1) 51 | put! ='@Annotation' 52 | call cursor(1, 2) 53 | Expect Call('javacomplete#util#GetClassNameWithScope') == '@Annotation' 54 | 55 | new 56 | call cursor(1, 1) 57 | put! ='ArrayList. ' 58 | call cursor(1, 12) 59 | Expect Call('javacomplete#util#GetClassNameWithScope') == 'ArrayList' 60 | 61 | end 62 | 63 | it 'CleanFQN test' 64 | Expect Call('javacomplete#util#CleanFQN', '') == '' 65 | Expect Call('javacomplete#util#CleanFQN', 'java.lang.Object') == 'Object' 66 | Expect Call('javacomplete#util#CleanFQN', 'java.lang.Object java.util.HashMap.get()') == 'Object get()' 67 | Expect Call('javacomplete#util#CleanFQN', 'public java.math.BigDecimal java.util.HashMap.computeIfAbsent(java.lang.String,java.util.function.Function)') == 'public BigDecimal computeIfAbsent(String,Function)' 68 | 69 | Expect Call('javacomplete#util#CleanFQN', 'public boolean scala.Tuple2.specInstance$()') == 'public boolean specInstance$()' 70 | end 71 | 72 | it 'Prune test' 73 | Expect Call('javacomplete#util#Prune', ' sb. /* block comment*/ append( "stringliteral" ) // comment ') == 'sb. append( "" ) ' 74 | Expect Call('javacomplete#util#Prune', ' list.stream(\n\t\ts -> {System.out.println(s)}).') == 'list.stream(\n\t\ts -> {System.out.println(s)}). ' 75 | end 76 | 77 | it 'HasKeyword test' 78 | Expect Call('javacomplete#util#HasKeyword', 'java.util.function.ToIntFunction') == 0 79 | end 80 | 81 | it 'GenMethodParamsDeclaration test' 82 | let m = {'p': ['int', 'int'], 'r': 'java.util.List', 'c': 'java.util.List', 'd': 'public abstract java.util.List java.util.List.subList(int,int)', 'm': '10000000001', 'n': 'subList'} 83 | Expect Call('javacomplete#util#GenMethodParamsDeclaration', m) == 'public abstract java.util.List java.util.List.subList(int i1, int i2)' 84 | 85 | let m = {'p': ['java.lang.Object'], 'r': 'int', 'c': 'int', 'd': 'public abstract int java.util.List.indexOf(java.lang.Object)', 'm': '10000000001', 'n': 'indexOf'} 86 | Expect Call('javacomplete#util#GenMethodParamsDeclaration', m) == 'public abstract int java.util.List.indexOf(Object object)' 87 | 88 | let m = {'p': ['java.util.Collection'], 'r': 'boolean', 'c': 'boolean', 'd': 'public abstract boolean java.util.List.addAll(java.util.Collection)', 'm': '10000000001', 'n': 'addAll'} 89 | Expect Call('javacomplete#util#GenMethodParamsDeclaration', m) == 'public abstract boolean java.util.List.addAll(Collection collection)' 90 | 91 | let m = {'p': ['T[]'], 'r': 'T[]', 'c': 'T[]', 'd': 'public abstract T[] java.util.List.toArray(T[])', 'm': '10000000001', 'n': 'toArray'} 92 | Expect Call('javacomplete#util#GenMethodParamsDeclaration', m) == 'public abstract T[] java.util.List.toArray(T[] t)' 93 | 94 | let m = {'p': ['java.math.BigDecimal', 'java.math.BigDecimal'], 'r': 'int', 'c': 'int', 'd': 'public abstract int indexOf(java.math.BigDecimal,java.math.BigDecimal)', 'm': '10000000001', 'n': 'indexOf'} 95 | Expect Call('javacomplete#util#GenMethodParamsDeclaration', m) == 'public abstract int indexOf(BigDecimal bigDecimal1, BigDecimal bigDecimal2)' 96 | 97 | let m = {'p': ['java.math.BigDecimal', 'java.math.BigDecimal'], 'r': 'int', 'c': 'int', 'd': 'public abstract int indexOf(java.math.BigDecimal,java.math.BigDecimal) throws java.lang.Exception', 'm': '10000000001', 'n': 'indexOf'} 98 | Expect Call('javacomplete#util#GenMethodParamsDeclaration', m) == 'public abstract int indexOf(BigDecimal bigDecimal1, BigDecimal bigDecimal2) throws java.lang.Exception' 99 | end 100 | end 101 | -------------------------------------------------------------------------------- /t/version.vim: -------------------------------------------------------------------------------- 1 | source autoload/javacomplete/version.vim 2 | source t/javacomplete.vim 3 | 4 | call vspec#hint({'sid': 'g:SID("util")'}) 5 | 6 | 7 | describe 'javacomplete utils test' 8 | it 'ServerAccordance test' 9 | Expect Call('javacomplete#version#CompareVersions', '2.5.6', '2.5.6') == 0 10 | Expect Call('javacomplete#version#CompareVersions', '2.5.6', '2.5.5') == 1 11 | Expect Call('javacomplete#version#CompareVersions', '2.5.6', '2.5.7') == -1 12 | Expect Call('javacomplete#version#CompareVersions', '2.5.6', '2.5.6.1') == -1 13 | Expect Call('javacomplete#version#CompareVersions', '2.5.6', '2.4.7') == 1 14 | end 15 | end 16 | --------------------------------------------------------------------------------