Get rid of wrong assumption that Java* classes are always PSI-based

See org.jetbrains.kotlin.load.java.structure.impl.classFiles.BinaryJavaClass
as a counter-example, these classes may be used now in CLI too and they
aren't built upon Java PSI
This commit is contained in:
Denis Zharkov
2017-04-06 10:44:49 +03:00
parent d65af8f951
commit af202ef5bc
4 changed files with 24 additions and 11 deletions
@@ -20,6 +20,7 @@ import com.intellij.psi.impl.JavaConstantExpressionEvaluator
import com.intellij.psi.util.PsiUtil
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.load.java.structure.JavaField
import org.jetbrains.kotlin.load.java.structure.impl.classFiles.BinaryJavaField
import org.jetbrains.kotlin.load.java.structure.impl.JavaFieldImpl
import org.jetbrains.kotlin.resolve.constants.ConstantValue
import org.jetbrains.kotlin.resolve.constants.ConstantValueFactory
@@ -27,8 +28,12 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
class JavaPropertyInitializerEvaluatorImpl : JavaPropertyInitializerEvaluator {
override fun getInitializerConstant(field: JavaField, descriptor: PropertyDescriptor): ConstantValue<*>? {
val initializer = (field as JavaFieldImpl).initializer
val evaluated = JavaConstantExpressionEvaluator.computeConstantExpression(initializer, false) ?: return null
val evaluated = when (field) {
is JavaFieldImpl -> JavaConstantExpressionEvaluator.computeConstantExpression(field.initializer, false)
is BinaryJavaField -> field.compiledValue
else -> null
} ?: return null
val factory = ConstantValueFactory(descriptor.builtIns)
when (evaluated) {
//Note: evaluated expression may be of class that does not match field type in some cases
@@ -43,6 +48,10 @@ class JavaPropertyInitializerEvaluatorImpl : JavaPropertyInitializerEvaluator {
}
override fun isNotNullCompileTimeConstant(field: JavaField): Boolean {
if (field is BinaryJavaField) {
return field.compiledValue != null
}
// PsiUtil.isCompileTimeConstant returns false for null-initialized fields,
// see com.intellij.psi.util.IsConstantExpressionVisitor.visitLiteralExpression()
return PsiUtil.isCompileTimeConstant((field as JavaFieldImpl).psi)
@@ -16,16 +16,16 @@
package org.jetbrains.kotlin.load.java.components
import org.jetbrains.kotlin.resolve.source.PsiSourceElement
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.load.java.sources.JavaSourceElement
import org.jetbrains.kotlin.load.java.sources.JavaSourceElementFactory
import org.jetbrains.kotlin.load.java.structure.JavaElement
import org.jetbrains.kotlin.load.java.structure.impl.JavaElementImpl
import org.jetbrains.kotlin.load.java.sources.JavaSourceElementFactory
import org.jetbrains.kotlin.load.java.sources.JavaSourceElement
import org.jetbrains.kotlin.resolve.source.PsiSourceElement
private class JavaSourceElementImpl(override val javaElement: JavaElement) : PsiSourceElement, JavaSourceElement {
override val psi: PsiElement?
get() = (javaElement as JavaElementImpl<*>).psi
get() = (javaElement as? JavaElementImpl<*>)?.psi
}
class JavaSourceElementFactoryImpl : JavaSourceElementFactory {
@@ -45,19 +45,19 @@ class LazyResolveBasedCache(private val resolveSession: ResolveSession) : JavaRe
}
override fun recordMethod(method: JavaMethod, descriptor: SimpleFunctionDescriptor) {
BindingContextUtils.recordFunctionDeclarationToDescriptor(trace, (method as JavaMethodImpl).psi, descriptor)
BindingContextUtils.recordFunctionDeclarationToDescriptor(trace, (method as? JavaMethodImpl)?.psi ?: return, descriptor)
}
override fun recordConstructor(element: JavaElement, descriptor: ConstructorDescriptor) {
trace.record(CONSTRUCTOR, (element as JavaElementImpl<*>).psi, descriptor)
trace.record(CONSTRUCTOR, (element as? JavaElementImpl<*>)?.psi ?: return, descriptor)
}
override fun recordField(field: JavaField, descriptor: PropertyDescriptor) {
trace.record(VARIABLE, (field as JavaFieldImpl).psi, descriptor)
trace.record(VARIABLE, (field as? JavaFieldImpl)?.psi ?: return, descriptor)
}
override fun recordClass(javaClass: JavaClass, descriptor: ClassDescriptor) {
trace.record(CLASS, (javaClass as JavaClassImpl).psi, descriptor)
trace.record(CLASS, (javaClass as? JavaClassImpl)?.psi ?: return, descriptor)
}
private fun findInPackageFragments(fullFqName: FqName): ClassDescriptor? {
@@ -21,6 +21,7 @@ import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.search.GlobalSearchScope
import org.jetbrains.kotlin.load.java.structure.JavaClass
import org.jetbrains.kotlin.load.java.structure.impl.JavaClassImpl
import org.jetbrains.kotlin.load.java.structure.impl.classFiles.BinaryJavaClass
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.utils.sure
@@ -33,7 +34,10 @@ abstract class VirtualFileFinder : KotlinClassFinder {
}
override fun findKotlinClass(javaClass: JavaClass): KotlinJvmBinaryClass? {
var file = (javaClass as JavaClassImpl).psi.containingFile?.virtualFile ?: return null
var file =
(javaClass as? JavaClassImpl)?.psi?.containingFile?.virtualFile
?: (javaClass as? BinaryJavaClass)?.virtualFile
?: return null
if (javaClass.outerClass != null) {
// For nested classes we get a file of the containing class, to get the actual class file for A.B.C,
// we take the file for A, take its parent directory, then in this directory we look for A$B$C.class