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
|
||||
) : 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?
|
||||
by lazy {
|
||||
when (typeMirror.kind) {
|
||||
TypeKind.DECLARED -> ((typeMirror as DeclaredType).asElement() as Symbol.ClassSymbol).let { symbol ->
|
||||
// try to find cached javaClass
|
||||
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)
|
||||
else -> null
|
||||
@@ -86,7 +90,7 @@ class SymbolBasedClassifierType<out T : TypeMirror>(
|
||||
|
||||
override val typeArguments: List<JavaType>
|
||||
get() {
|
||||
if (typeMirror.kind != TypeKind.DECLARED) return emptyList()
|
||||
if (typeMirror.kind != TypeKind.DECLARED || isFake) return emptyList()
|
||||
|
||||
val arguments = arrayListOf<JavaType>()
|
||||
var type = typeMirror as DeclaredType
|
||||
@@ -106,6 +110,7 @@ class SymbolBasedClassifierType<out T : TypeMirror>(
|
||||
override val isRaw: Boolean
|
||||
get() = when {
|
||||
typeMirror !is DeclaredType -> false
|
||||
isFake -> false
|
||||
(classifier as? JavaClass)?.typeParameters?.isEmpty() == true -> false
|
||||
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
|
||||
get() = typeMirror.toString()
|
||||
|
||||
override val isDeprecatedInJavaDoc: Boolean
|
||||
get() = !isFake && super.isDeprecatedInJavaDoc
|
||||
}
|
||||
|
||||
class SymbolBasedWildcardType(
|
||||
|
||||
Reference in New Issue
Block a user