SymbolBasedClassifierType: fix exception in case with not found class
This can arise with non-transitive dependencies #KT-33932 Fixed
This commit is contained in:
+85
@@ -0,0 +1,85 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.javac.wrappers.symbols
|
||||||
|
|
||||||
|
import com.intellij.openapi.vfs.VirtualFile
|
||||||
|
import com.intellij.psi.search.SearchScope
|
||||||
|
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||||
|
import org.jetbrains.kotlin.descriptors.Visibility
|
||||||
|
import org.jetbrains.kotlin.javac.JavaClassWithClassId
|
||||||
|
import org.jetbrains.kotlin.javac.JavacWrapper
|
||||||
|
import org.jetbrains.kotlin.load.java.structure.*
|
||||||
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
import javax.lang.model.element.TypeElement
|
||||||
|
import javax.lang.model.type.TypeKind
|
||||||
|
import javax.tools.JavaFileObject
|
||||||
|
|
||||||
|
// This represents Java class for which we don't have resolved classifier.
|
||||||
|
// The situation when it is useful is described in KT-33932.
|
||||||
|
// Mostly it's a stub.
|
||||||
|
class FakeSymbolBasedClass(
|
||||||
|
element: TypeElement,
|
||||||
|
javac: JavacWrapper,
|
||||||
|
override val classId: ClassId?,
|
||||||
|
val file: JavaFileObject?
|
||||||
|
) : SymbolBasedClassifier<TypeElement>(element, javac), JavaClassWithClassId {
|
||||||
|
|
||||||
|
override val name: Name get() = Name.identifier(element.simpleName.toString())
|
||||||
|
|
||||||
|
override val isAbstract: Boolean get() = true
|
||||||
|
|
||||||
|
override val isStatic: Boolean get() = false
|
||||||
|
|
||||||
|
override val isFinal: Boolean get() = false
|
||||||
|
|
||||||
|
override val visibility: Visibility get() = Visibilities.PUBLIC
|
||||||
|
|
||||||
|
override val typeParameters: List<JavaTypeParameter> get() = emptyList()
|
||||||
|
|
||||||
|
override val fqName: FqName get() = FqName(element.qualifiedName.toString())
|
||||||
|
|
||||||
|
override val supertypes: Collection<JavaClassifierType> get() = emptyList()
|
||||||
|
|
||||||
|
val innerClasses: Map<Name, JavaClass> get() = emptyMap()
|
||||||
|
|
||||||
|
override val outerClass: JavaClass?
|
||||||
|
by lazy {
|
||||||
|
element.enclosingElement?.let {
|
||||||
|
if (it.asType().kind != TypeKind.DECLARED) null else FakeSymbolBasedClass(
|
||||||
|
it as TypeElement,
|
||||||
|
javac,
|
||||||
|
classId?.outerClassId,
|
||||||
|
file
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override val isInterface: Boolean get() = true
|
||||||
|
|
||||||
|
override val isAnnotationType: Boolean get() = false
|
||||||
|
|
||||||
|
override val isEnum: Boolean get() = false
|
||||||
|
|
||||||
|
override val lightClassOriginKind: LightClassOriginKind? get() = null
|
||||||
|
|
||||||
|
override val methods: Collection<JavaMethod> get() = emptyList()
|
||||||
|
|
||||||
|
override val fields: Collection<JavaField> get() = emptyList()
|
||||||
|
|
||||||
|
override val constructors: Collection<JavaConstructor> get() = emptyList()
|
||||||
|
|
||||||
|
override val innerClassNames: Collection<Name> get() = emptyList()
|
||||||
|
|
||||||
|
override val virtualFile: VirtualFile? by lazy {
|
||||||
|
file?.let { javac.toVirtualFile(it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun isFromSourceCodeInScope(scope: SearchScope): Boolean = false
|
||||||
|
|
||||||
|
override fun findInnerClass(name: Name): JavaClass? = null
|
||||||
|
}
|
||||||
+9
-2
@@ -71,13 +71,17 @@ class SymbolBasedClassifierType<out T : TypeMirror>(
|
|||||||
javac: JavacWrapper
|
javac: JavacWrapper
|
||||||
) : SymbolBasedType<T>(typeMirror, javac), JavaClassifierType {
|
) : SymbolBasedType<T>(typeMirror, javac), JavaClassifierType {
|
||||||
|
|
||||||
|
private val isFake get() = classifier is FakeSymbolBasedClass
|
||||||
|
|
||||||
|
// TODO: we should replace this with a "link" to classifier, not an actual classifier itself
|
||||||
|
// It should be something like ConeClassifierLookupTag (see compiler:fir:cones)
|
||||||
override val classifier: JavaClassifier?
|
override val classifier: JavaClassifier?
|
||||||
by lazy {
|
by lazy {
|
||||||
when (typeMirror.kind) {
|
when (typeMirror.kind) {
|
||||||
TypeKind.DECLARED -> ((typeMirror as DeclaredType).asElement() as Symbol.ClassSymbol).let { symbol ->
|
TypeKind.DECLARED -> ((typeMirror as DeclaredType).asElement() as Symbol.ClassSymbol).let { symbol ->
|
||||||
// try to find cached javaClass
|
// try to find cached javaClass
|
||||||
val classId = symbol.computeClassId()
|
val classId = symbol.computeClassId()
|
||||||
classId?.let { javac.findClass(it) } ?: SymbolBasedClass(symbol, javac, classId, symbol.classfile)
|
classId?.let { javac.findClass(it) } ?: FakeSymbolBasedClass(symbol, javac, classId, symbol.classfile)
|
||||||
}
|
}
|
||||||
TypeKind.TYPEVAR -> SymbolBasedTypeParameter((typeMirror as TypeVariable).asElement() as TypeParameterElement, javac)
|
TypeKind.TYPEVAR -> SymbolBasedTypeParameter((typeMirror as TypeVariable).asElement() as TypeParameterElement, javac)
|
||||||
else -> null
|
else -> null
|
||||||
@@ -86,7 +90,7 @@ class SymbolBasedClassifierType<out T : TypeMirror>(
|
|||||||
|
|
||||||
override val typeArguments: List<JavaType>
|
override val typeArguments: List<JavaType>
|
||||||
get() {
|
get() {
|
||||||
if (typeMirror.kind != TypeKind.DECLARED) return emptyList()
|
if (typeMirror.kind != TypeKind.DECLARED || isFake) return emptyList()
|
||||||
|
|
||||||
val arguments = arrayListOf<JavaType>()
|
val arguments = arrayListOf<JavaType>()
|
||||||
var type = typeMirror as DeclaredType
|
var type = typeMirror as DeclaredType
|
||||||
@@ -106,6 +110,7 @@ class SymbolBasedClassifierType<out T : TypeMirror>(
|
|||||||
override val isRaw: Boolean
|
override val isRaw: Boolean
|
||||||
get() = when {
|
get() = when {
|
||||||
typeMirror !is DeclaredType -> false
|
typeMirror !is DeclaredType -> false
|
||||||
|
isFake -> false
|
||||||
(classifier as? JavaClass)?.typeParameters?.isEmpty() == true -> false
|
(classifier as? JavaClass)?.typeParameters?.isEmpty() == true -> false
|
||||||
else -> typeMirror.typeArguments.isEmpty() || (classifier as? JavaClass)?.typeParameters?.size != typeMirror.typeArguments.size
|
else -> typeMirror.typeArguments.isEmpty() || (classifier as? JavaClass)?.typeParameters?.size != typeMirror.typeArguments.size
|
||||||
}
|
}
|
||||||
@@ -116,6 +121,8 @@ class SymbolBasedClassifierType<out T : TypeMirror>(
|
|||||||
override val presentableText: String
|
override val presentableText: String
|
||||||
get() = typeMirror.toString()
|
get() = typeMirror.toString()
|
||||||
|
|
||||||
|
override val isDeprecatedInJavaDoc: Boolean
|
||||||
|
get() = !isFake && super.isDeprecatedInJavaDoc
|
||||||
}
|
}
|
||||||
|
|
||||||
class SymbolBasedWildcardType(
|
class SymbolBasedWildcardType(
|
||||||
|
|||||||
Reference in New Issue
Block a user