diff --git a/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/symbols/FakeSymbolBasedClass.kt b/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/symbols/FakeSymbolBasedClass.kt new file mode 100644 index 00000000000..abaee504a9b --- /dev/null +++ b/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/symbols/FakeSymbolBasedClass.kt @@ -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(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 get() = emptyList() + + override val fqName: FqName get() = FqName(element.qualifiedName.toString()) + + override val supertypes: Collection get() = emptyList() + + val innerClasses: Map 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 get() = emptyList() + + override val fields: Collection get() = emptyList() + + override val constructors: Collection get() = emptyList() + + override val innerClassNames: Collection 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 +} diff --git a/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/symbols/symbolBasedTypes.kt b/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/symbols/symbolBasedTypes.kt index 8ca0cd83c93..759ad1ba9f9 100644 --- a/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/symbols/symbolBasedTypes.kt +++ b/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/symbols/symbolBasedTypes.kt @@ -71,13 +71,17 @@ class SymbolBasedClassifierType( javac: JavacWrapper ) : SymbolBasedType(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( override val typeArguments: List get() { - if (typeMirror.kind != TypeKind.DECLARED) return emptyList() + if (typeMirror.kind != TypeKind.DECLARED || isFake) return emptyList() val arguments = arrayListOf() var type = typeMirror as DeclaredType @@ -106,6 +110,7 @@ class SymbolBasedClassifierType( 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( override val presentableText: String get() = typeMirror.toString() + override val isDeprecatedInJavaDoc: Boolean + get() = !isFake && super.isDeprecatedInJavaDoc } class SymbolBasedWildcardType(