Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
硅谷海盗
kotlin
提交
6cea8434
K
kotlin
项目概览
硅谷海盗
/
kotlin
与 Fork 源项目一致
从无法访问的项目Fork
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
kotlin
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
6cea8434
编写于
6月 01, 2018
作者:
P
Pavel V. Talanov
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
J2K JavaElementFinder: autoconvert and fix compilation errors
上级
00b1e928
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
131 addition
and
156 deletion
+131
-156
compiler/light-classes/src/org/jetbrains/kotlin/asJava/finder/JavaElementFinder.kt
...c/org/jetbrains/kotlin/asJava/finder/JavaElementFinder.kt
+130
-155
compiler/tests/org/jetbrains/kotlin/asJava/KotlinAsJavaTestBase.java
...sts/org/jetbrains/kotlin/asJava/KotlinAsJavaTestBase.java
+1
-1
未找到文件。
compiler/light-classes/src/org/jetbrains/kotlin/asJava/finder/JavaElementFinder.kt
浏览文件 @
6cea8434
...
...
@@ -14,230 +14,205 @@
* limitations under the License.
*/
package
org.jetbrains.kotlin.asJava.finder;
import
com.google.common.collect.Collections2;
import
com.google.common.collect.Sets;
import
com.intellij.openapi.extensions.Extensions;
import
com.intellij.openapi.project.Project;
import
com.intellij.openapi.util.Condition;
import
com.intellij.openapi.vfs.VirtualFile;
import
com.intellij.psi.*;
import
com.intellij.psi.search.GlobalSearchScope;
import
com.intellij.psi.util.PsiUtilCore;
import
com.intellij.util.SmartList;
import
com.intellij.util.containers.ContainerUtil;
import
org.jetbrains.annotations.NotNull;
import
org.jetbrains.annotations.Nullable;
import
org.jetbrains.kotlin.asJava.KotlinAsJavaSupport;
import
org.jetbrains.kotlin.load.java.JvmAbi;
import
org.jetbrains.kotlin.name.FqName;
import
org.jetbrains.kotlin.name.FqNamesUtilKt;
import
org.jetbrains.kotlin.psi.KtClass;
import
org.jetbrains.kotlin.psi.KtClassOrObject;
import
org.jetbrains.kotlin.psi.KtEnumEntry;
import
org.jetbrains.kotlin.psi.KtFile;
import
org.jetbrains.kotlin.resolve.jvm.KotlinFinderMarker;
import
java.util.Collection;
import
java.util.Comparator;
import
java.util.List;
import
java.util.Set;
import
static
org
.
jetbrains
.
kotlin
.
asJava
.
LightClassUtilsKt
.
toLightClass
;
public
class
JavaElementFinder
extends
PsiElementFinder
implements
KotlinFinderMarker
{
@NotNull
public
static
JavaElementFinder
getInstance
(
@NotNull
Project
project
)
{
PsiElementFinder
[]
extensions
=
Extensions
.
getArea
(
project
).
getExtensionPoint
(
PsiElementFinder
.
EP_NAME
).
getExtensions
();
for
(
PsiElementFinder
extension
:
extensions
)
{
if
(
extension
instanceof
JavaElementFinder
)
{
return
(
JavaElementFinder
)
extension
;
}
}
throw
new
IllegalStateException
(
JavaElementFinder
.
class
.
getSimpleName
()
+
" is not found for project "
+
project
);
package
org.jetbrains.kotlin.asJava.finder
import
com.google.common.collect.Collections2
import
com.google.common.collect.Sets
import
com.intellij.openapi.extensions.Extensions
import
com.intellij.openapi.project.Project
import
com.intellij.openapi.util.Condition
import
com.intellij.psi.*
import
com.intellij.psi.search.GlobalSearchScope
import
com.intellij.psi.util.PsiUtilCore
import
com.intellij.util.SmartList
import
com.intellij.util.containers.ContainerUtil
import
org.jetbrains.kotlin.asJava.KotlinAsJavaSupport
import
org.jetbrains.kotlin.asJava.toLightClass
import
org.jetbrains.kotlin.load.java.JvmAbi
import
org.jetbrains.kotlin.name.FqName
import
org.jetbrains.kotlin.name.isValidJavaFqName
import
org.jetbrains.kotlin.psi.KtClass
import
org.jetbrains.kotlin.psi.KtEnumEntry
import
org.jetbrains.kotlin.psi.KtFile
import
org.jetbrains.kotlin.resolve.jvm.KotlinFinderMarker
import
java.util.*
class
JavaElementFinder
(
private
val
project
:
Project
,
private
val
kotlinAsJavaSupport
:
KotlinAsJavaSupport
)
:
PsiElementFinder
(),
KotlinFinderMarker
{
private
val
psiManager
:
PsiManager
init
{
this
.
psiManager
=
PsiManager
.
getInstance
(
project
)
}
private
final
Project
project
;
private
final
PsiManager
psiManager
;
private
final
KotlinAsJavaSupport
kotlinAsJavaSupport
;
public
JavaElementFinder
(
@NotNull
Project
project
,
@NotNull
KotlinAsJavaSupport
kotlinAsJavaSupport
)
{
this
.
project
=
project
;
this
.
psiManager
=
PsiManager
.
getInstance
(
project
);
this
.
kotlinAsJavaSupport
=
kotlinAsJavaSupport
;
override
fun
findClass
(
qualifiedName
:
String
,
scope
:
GlobalSearchScope
):
PsiClass
?
{
val
allClasses
=
findClasses
(
qualifiedName
,
scope
)
return
if
(
allClasses
.
size
>
0
)
allClasses
[
0
]
else
null
}
@Override
public
PsiClass
findClass
(
@NotNull
String
qualifiedName
,
@NotNull
GlobalSearchScope
scope
)
{
PsiClass
[]
allClasses
=
findClasses
(
qualifiedName
,
scope
);
return
allClasses
.
length
>
0
?
allClasses
[
0
]
:
null
;
}
@NotNull
@Override
public
PsiClass
[]
findClasses
(
@NotNull
String
qualifiedNameString
,
@NotNull
GlobalSearchScope
scope
)
{
if
(!
FqNamesUtilKt
.
isValidJavaFqName
(
qualifiedNameString
))
{
return
PsiClass
.
EMPTY_ARRAY
;
override
fun
findClasses
(
qualifiedNameString
:
String
,
scope
:
GlobalSearchScope
):
Array
<
PsiClass
>
{
if
(!
isValidJavaFqName
(
qualifiedNameString
))
{
return
PsiClass
.
EMPTY_ARRAY
}
List
<
PsiClass
>
answer
=
new
SmartList
<>();
val
answer
=
SmartList
<
PsiClass
>()
FqName
qualifiedName
=
new
FqName
(
qualifiedNameString
);
val
qualifiedName
=
FqName
(
qualifiedNameString
)
findClassesAndObjects
(
qualifiedName
,
scope
,
answer
)
;
answer
.
addAll
(
kotlinAsJavaSupport
.
getFacadeClasses
(
qualifiedName
,
scope
))
;
answer
.
addAll
(
kotlinAsJavaSupport
.
getKotlinInternalClasses
(
qualifiedName
,
scope
))
;
findClassesAndObjects
(
qualifiedName
,
scope
,
answer
)
answer
.
addAll
(
kotlinAsJavaSupport
.
getFacadeClasses
(
qualifiedName
,
scope
))
answer
.
addAll
(
kotlinAsJavaSupport
.
getKotlinInternalClasses
(
qualifiedName
,
scope
))
return
sortByClasspath
(
answer
,
scope
).
to
Array
(
new
PsiClass
[
answer
.
size
()]);
return
sortByClasspath
(
answer
,
scope
).
to
TypedArray
()
}
// Finds explicitly declared classes and objects, not package classes
// Also DefaultImpls classes of interfaces
private
void
findClassesAndObjects
(
FqName
qualifiedName
,
GlobalSearchScope
scope
,
List
<
PsiClass
>
answer
)
{
findInterfaceDefaultImpls
(
qualifiedName
,
scope
,
answer
)
;
private
fun
findClassesAndObjects
(
qualifiedName
:
FqName
,
scope
:
GlobalSearchScope
,
answer
:
MutableList
<
PsiClass
>
)
{
findInterfaceDefaultImpls
(
qualifiedName
,
scope
,
answer
)
Collection
<
KtClassOrObject
>
classOrObjectDeclarations
=
kotlinAsJavaSupport
.
findClassOrObjectDeclarations
(
qualifiedName
,
scope
);
val
classOrObjectDeclarations
=
kotlinAsJavaSupport
.
findClassOrObjectDeclarations
(
qualifiedName
,
scope
)
for
(
KtClassOrObject
declaration
:
classOrObjectDeclarations
)
{
if
(
!(
declaration
instanceof
KtEnumEntry
)
)
{
PsiClass
lightClass
=
toLightClass
(
declaration
);
for
(
declaration
in
classOrObjectDeclarations
)
{
if
(
declaration
!
is
KtEnumEntry
)
{
val
lightClass
=
declaration
.
toLightClass
()
if
(
lightClass
!=
null
)
{
answer
.
add
(
lightClass
)
;
answer
.
add
(
lightClass
)
}
}
}
}
private
void
findInterfaceDefaultImpls
(
FqName
qualifiedName
,
GlobalSearchScope
scope
,
List
<
PsiClass
>
answer
)
{
if
(
qualifiedName
.
isRoot
())
return
;
private
fun
findInterfaceDefaultImpls
(
qualifiedName
:
FqName
,
scope
:
GlobalSearchScope
,
answer
:
MutableList
<
PsiClass
>
)
{
if
(
qualifiedName
.
isRoot
)
return
if
(
!
qualifiedName
.
shortName
().
asString
().
equals
(
JvmAbi
.
DEFAULT_IMPLS_CLASS_NAME
))
return
;
if
(
qualifiedName
.
shortName
().
asString
()
!=
JvmAbi
.
DEFAULT_IMPLS_CLASS_NAME
)
return
for
(
KtClassOrObject
classOrObject
:
kotlinAsJavaSupport
.
findClassOrObjectDeclarations
(
qualifiedName
.
parent
(),
scope
))
{
for
(
classOrObject
in
kotlinAsJavaSupport
.
findClassOrObjectDeclarations
(
qualifiedName
.
parent
(),
scope
))
{
//NOTE: can't filter out more interfaces right away because decompiled declarations do not have member bodies
if
(
classOrObject
i
nstanceof
KtClass
&&
((
KtClass
)
classOrObject
)
.
isInterface
())
{
PsiClass
interfaceClass
=
toLightClass
(
classOrObject
);
if
(
classOrObject
i
s
KtClass
&&
classOrObject
.
isInterface
())
{
val
interfaceClass
=
classOrObject
.
toLightClass
()
if
(
interfaceClass
!=
null
)
{
PsiClass
implsClass
=
interfaceClass
.
findInnerClassByName
(
JvmAbi
.
DEFAULT_IMPLS_CLASS_NAME
,
false
);
val
implsClass
=
interfaceClass
!!
.
findInnerClassByName
(
JvmAbi
.
DEFAULT_IMPLS_CLASS_NAME
,
false
)
if
(
implsClass
!=
null
)
{
answer
.
add
(
implsClass
)
;
answer
.
add
(
implsClass
)
}
}
}
}
}
@NotNull
@Override
public
Set
<
String
>
getClassNames
(
@NotNull
PsiPackage
psiPackage
,
@NotNull
GlobalSearchScope
scope
)
{
FqName
packageFQN
=
new
FqName
(
psiPackage
.
getQualifiedName
());
override
fun
getClassNames
(
psiPackage
:
PsiPackage
,
scope
:
GlobalSearchScope
):
Set
<
String
>
{
val
packageFQN
=
FqName
(
psiPackage
.
qualifiedName
)
Collection
<
KtClassOrObject
>
declarations
=
kotlinAsJavaSupport
.
findClassOrObjectDeclarationsInPackage
(
packageFQN
,
scope
);
val
declarations
=
kotlinAsJavaSupport
.
findClassOrObjectDeclarationsInPackage
(
packageFQN
,
scope
)
Set
<
String
>
answer
=
Sets
.
newHashSet
();
answer
.
addAll
(
kotlinAsJavaSupport
.
getFacadeNames
(
packageFQN
,
scope
))
;
val
answer
=
Sets
.
newHashSet
<
String
>()
answer
.
addAll
(
kotlinAsJavaSupport
.
getFacadeNames
(
packageFQN
,
scope
))
for
(
KtClassOrObject
declaration
:
declarations
)
{
String
name
=
declaration
.
getName
();
for
(
declaration
in
declarations
)
{
val
name
=
declaration
.
name
if
(
name
!=
null
)
{
answer
.
add
(
name
)
;
answer
.
add
(
name
)
}
}
return
answer
;
return
answer
}
@Override
public
PsiPackage
findPackage
(
@NotNull
String
qualifiedNameString
)
{
if
(!
FqNamesUtilKt
.
isValidJavaFqName
(
qualifiedNameString
))
{
return
null
;
override
fun
findPackage
(
qualifiedNameString
:
String
):
PsiPackage
?
{
if
(!
isValidJavaFqName
(
qualifiedNameString
))
{
return
null
}
FqName
fqName
=
new
FqName
(
qualifiedNameString
);
val
fqName
=
FqName
(
qualifiedNameString
)
// allScope() because the contract says that the whole project
GlobalSearchScope
allScope
=
GlobalSearchScope
.
allScope
(
project
);
if
(
kotlinAsJavaSupport
.
packageExists
(
fqName
,
allScope
))
{
return
new
KtLightPackage
(
psiManager
,
fqName
,
allScope
);
}
val
allScope
=
GlobalSearchScope
.
allScope
(
project
)
return
if
(
kotlinAsJavaSupport
.
packageExists
(
fqName
,
allScope
))
{
KtLightPackage
(
psiManager
,
fqName
,
allScope
)
}
else
null
return
null
;
}
@NotNull
@Override
public
PsiPackage
[]
getSubPackages
(
@NotNull
PsiPackage
psiPackage
,
@NotNull
GlobalSearchScope
scope
)
{
FqName
packageFQN
=
new
FqName
(
psiPackage
.
getQualifiedName
());
override
fun
getSubPackages
(
psiPackage
:
PsiPackage
,
scope
:
GlobalSearchScope
):
Array
<
PsiPackage
>
{
val
packageFQN
=
FqName
(
psiPackage
.
qualifiedName
)
Collection
<
FqName
>
subpackages
=
kotlinAsJavaSupport
.
getSubPackages
(
packageFQN
,
scope
);
val
subpackages
=
kotlinAsJavaSupport
.
getSubPackages
(
packageFQN
,
scope
)
Collection
<
PsiPackage
>
answer
=
Collections2
.
transform
(
subpackages
,
input
->
new
KtLightPackage
(
psiManager
,
input
,
scope
));
val
answer
=
Collections2
.
transform
<
FqName
,
PsiPackage
>(
subpackages
)
{
input
->
KtLightPackage
(
psiManager
,
input
,
scope
)
}
return
answer
.
to
Array
(
new
PsiPackage
[
answer
.
size
()]);
return
answer
.
to
TypedArray
()
}
@NotNull
@Override
public
PsiClass
[]
getClasses
(
@NotNull
PsiPackage
psiPackage
,
@NotNull
GlobalSearchScope
scope
)
{
List
<
PsiClass
>
answer
=
new
SmartList
<>();
FqName
packageFQN
=
new
FqName
(
psiPackage
.
getQualifiedName
());
override
fun
getClasses
(
psiPackage
:
PsiPackage
,
scope
:
GlobalSearchScope
):
Array
<
PsiClass
>
{
val
answer
=
SmartList
<
PsiClass
>()
val
packageFQN
=
FqName
(
psiPackage
.
qualifiedName
)
answer
.
addAll
(
kotlinAsJavaSupport
.
getFacadeClassesInPackage
(
packageFQN
,
scope
))
;
answer
.
addAll
(
kotlinAsJavaSupport
.
getFacadeClassesInPackage
(
packageFQN
,
scope
))
Collection
<
KtClassOrObject
>
declarations
=
kotlinAsJavaSupport
.
findClassOrObjectDeclarationsInPackage
(
packageFQN
,
scope
);
for
(
KtClassOrObject
declaration
:
declarations
)
{
PsiClass
aClass
=
toLightClass
(
declaration
);
val
declarations
=
kotlinAsJavaSupport
.
findClassOrObjectDeclarationsInPackage
(
packageFQN
,
scope
)
for
(
declaration
in
declarations
)
{
val
aClass
=
declaration
.
toLightClass
()
if
(
aClass
!=
null
)
{
answer
.
add
(
aClass
)
;
answer
.
add
(
aClass
)
}
}
return
sortByClasspath
(
answer
,
scope
).
to
Array
(
new
PsiClass
[
answer
.
size
()]);
return
sortByClasspath
(
answer
,
scope
).
to
TypedArray
()
}
@Override
@NotNull
public
PsiFile
[]
getPackageFiles
(
@NotNull
PsiPackage
psiPackage
,
@NotNull
GlobalSearchScope
scope
)
{
FqName
packageFQN
=
new
FqName
(
psiPackage
.
getQualifiedName
());
override
fun
getPackageFiles
(
psiPackage
:
PsiPackage
,
scope
:
GlobalSearchScope
):
Array
<
PsiFile
>
{
val
packageFQN
=
FqName
(
psiPackage
.
qualifiedName
)
// TODO: this does not take into account JvmPackageName annotation
Collection
<
KtFile
>
result
=
kotlinAsJavaSupport
.
findFilesForPackage
(
packageFQN
,
scope
);
return
result
.
to
Array
(
new
PsiFile
[
result
.
size
()]);
val
result
=
kotlinAsJavaSupport
.
findFilesForPackage
(
packageFQN
,
scope
)
return
result
.
to
TypedArray
()
}
@Override
@Nullable
public
Condition
<
PsiFile
>
getPackageFilesFilter
(
@NotNull
PsiPackage
psiPackage
,
@NotNull
GlobalSearchScope
scope
)
{
return
input
->
{
if
(!(
input
instanceof
KtFile
))
{
return
true
;
override
fun
getPackageFilesFilter
(
psiPackage
:
PsiPackage
,
scope
:
GlobalSearchScope
):
Condition
<
PsiFile
>?
{
return
Condition
{
input
->
if
(
input
!
is
KtFile
)
{
true
}
return
psiPackage
.
getQualifiedName
().
equals
(((
KtFile
)
input
).
getPackageFqName
().
asString
());
};
else
{
psiPackage
.
qualifiedName
==
(
input
as
KtFile
).
packageFqName
.
asString
()
}
}
}
@NotNull
public
static
Comparator
<
PsiElement
>
byClasspathComparator
(
@NotNull
GlobalSearchScope
searchScope
)
{
return
(
o1
,
o2
)
->
{
VirtualFile
f1
=
PsiUtilCore
.
getVirtualFile
(
o1
);
VirtualFile
f2
=
PsiUtilCore
.
getVirtualFile
(
o2
);
if
(
f1
==
f2
)
return
0
;
if
(
f1
==
null
)
return
-
1
;
if
(
f2
==
null
)
return
1
;
return
searchScope
.
compare
(
f2
,
f1
);
};
}
companion
object
{
private
static
Collection
<
PsiClass
>
sortByClasspath
(
@NotNull
List
<
PsiClass
>
classes
,
@NotNull
GlobalSearchScope
searchScope
)
{
if
(
classes
.
size
()
>
1
)
{
ContainerUtil
.
quickSort
(
classes
,
byClasspathComparator
(
searchScope
));
fun
getInstance
(
project
:
Project
):
JavaElementFinder
{
val
extensions
=
Extensions
.
getArea
(
project
).
getExtensionPoint
(
PsiElementFinder
.
EP_NAME
).
extensions
for
(
extension
in
extensions
)
{
if
(
extension
is
JavaElementFinder
)
{
return
extension
}
}
throw
IllegalStateException
(
JavaElementFinder
::
class
.
java
.
simpleName
+
" is not found for project "
+
project
)
}
fun
byClasspathComparator
(
searchScope
:
GlobalSearchScope
):
Comparator
<
PsiElement
>
{
return
Comparator
{
o1
,
o2
->
val
f1
=
PsiUtilCore
.
getVirtualFile
(
o1
)
val
f2
=
PsiUtilCore
.
getVirtualFile
(
o2
)
when
{
f1
===
f2
->
0
f1
==
null
->
-
1
f2
==
null
->
1
else
->
searchScope
.
compare
(
f2
!!
,
f1
!!
)
}
}
}
return
classes
;
private
fun
sortByClasspath
(
classes
:
List
<
PsiClass
>,
searchScope
:
GlobalSearchScope
):
Collection
<
PsiClass
>
{
if
(
classes
.
size
>
1
)
{
ContainerUtil
.
quickSort
(
classes
,
byClasspathComparator
(
searchScope
))
}
return
classes
}
}
}
compiler/tests/org/jetbrains/kotlin/asJava/KotlinAsJavaTestBase.java
浏览文件 @
6cea8434
...
...
@@ -56,7 +56,7 @@ public abstract class KotlinAsJavaTestBase extends KotlinTestWithEnvironment {
super
.
setUp
();
KotlinCoreEnvironment
environment
=
getEnvironment
();
KotlinTestUtils
.
resolveAllKotlinFiles
(
environment
);
finder
=
JavaElementFinder
.
getInstance
(
environment
.
getProject
());
finder
=
JavaElementFinder
.
Companion
.
getInstance
(
environment
.
getProject
());
}
@Override
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录