Implement FIR loading for Java (classes, supertypes, parameters, funs)

Properties aren't implemented yet
FIR symbol provider functions return more specialized types now
Related to KT-28918, KT-29636, KT-29218

#KT-28788 Fixed
This commit is contained in:
Simon Ogorodnik
2019-02-07 11:43:12 +03:00
committed by Mikhail Glukhikh
parent 4ea3df53cc
commit 3a237416c9
21 changed files with 331 additions and 70 deletions
@@ -6,11 +6,14 @@
package org.jetbrains.kotlin.fir.symbols
import org.jetbrains.kotlin.fir.types.ConeKotlinType
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
// NB: with className == null we are at top level
data class CallableId(val packageName: FqName, val className: FqName?, val callableName: Name) {
val classId: ClassId? get() = className?.let { ClassId(packageName, it, false) }
constructor(packageName: FqName, callableName: Name): this(packageName, null, callableName)
override fun toString(): String {
@@ -27,7 +27,7 @@ class FirJavaModuleBasedSession(
FirCompositeSymbolProvider(
listOf(
service<FirProvider>(),
JavaSymbolProvider(sessionProvider.project, scope),
JavaSymbolProvider(this, sessionProvider.project, scope),
FirDependenciesSymbolProviderImpl(this)
)
)
@@ -47,7 +47,7 @@ class FirLibrarySession(
FirCompositeSymbolProvider(
listOf(
FirLibrarySymbolProviderImpl(this),
JavaSymbolProvider(sessionProvider.project, scope),
JavaSymbolProvider(this, sessionProvider.project, scope),
FirDependenciesSymbolProviderImpl(this)
)
)
@@ -7,29 +7,212 @@ package org.jetbrains.kotlin.fir.java
import com.intellij.openapi.project.Project
import com.intellij.psi.search.GlobalSearchScope
import org.jetbrains.kotlin.fir.java.symbols.JavaClassSymbol
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirNamedFunction
import org.jetbrains.kotlin.fir.declarations.impl.*
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
import org.jetbrains.kotlin.fir.expressions.FirExpression
import org.jetbrains.kotlin.fir.expressions.impl.*
import org.jetbrains.kotlin.fir.resolve.AbstractFirSymbolProvider
import org.jetbrains.kotlin.fir.resolve.FirSymbolProvider
import org.jetbrains.kotlin.fir.service
import org.jetbrains.kotlin.fir.symbols.CallableId
import org.jetbrains.kotlin.fir.symbols.ConeSymbol
import org.jetbrains.kotlin.fir.symbols.ConeCallableSymbol
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeSymbol
import org.jetbrains.kotlin.fir.symbols.ConeClassSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
import org.jetbrains.kotlin.fir.types.ConeClassErrorType
import org.jetbrains.kotlin.fir.types.ConeKotlinTypeProjection
import org.jetbrains.kotlin.fir.types.FirResolvedType
import org.jetbrains.kotlin.fir.types.impl.ConeClassTypeImpl
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
import org.jetbrains.kotlin.fir.types.impl.FirResolvedTypeImpl
import org.jetbrains.kotlin.ir.expressions.IrConstKind
import org.jetbrains.kotlin.load.java.JavaClassFinder
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 org.jetbrains.kotlin.resolve.jvm.KotlinJavaPsiFacade
import org.jetbrains.kotlin.types.Variance
class JavaSymbolProvider(
val session: FirSession,
val project: Project,
private val searchScope: GlobalSearchScope
) : AbstractFirSymbolProvider() {
override fun getCallableSymbols(callableId: CallableId): List<ConeSymbol> {
// TODO
return emptyList()
private val facade: KotlinJavaPsiFacade get() = KotlinJavaPsiFacade.getInstance(project)
private fun JavaAnnotation.toFirAnnotationCall(): FirAnnotationCall {
return FirAnnotationCallImpl(
session, psi = null, useSiteTarget = null,
annotationType = FirResolvedTypeImpl(
session = session,
psi = null,
type = ConeClassTypeImpl(FirClassSymbol(classId!!), emptyArray()),
isNullable = true,
annotations = emptyList()
)
).apply {
for (argument in this@toFirAnnotationCall.arguments) {
arguments += argument.toFirExpression()
}
}
}
override fun getClassLikeSymbolByFqName(classId: ClassId): ConeSymbol? {
return classCache.lookupCacheOrCalculate(classId) {
val facade = KotlinJavaPsiFacade.getInstance(project)
val foundClass = facade.findClass(JavaClassFinder.Request(classId), searchScope)
foundClass?.let { javaClass -> JavaClassSymbol(javaClass) }
private fun JavaAnnotationArgument.toFirExpression(): FirExpression {
// TODO: this.name
return when (this) {
is JavaLiteralAnnotationArgument -> when (value) {
null -> FirConstExpressionImpl(session, null, IrConstKind.Null, null)
else -> FirErrorExpressionImpl(session, null, "Unknown value in JavaLiteralAnnotationArgument: $value")
}
is JavaArrayAnnotationArgument -> FirArrayOfCallImpl(session, null).apply {
for (element in getElements()) {
arguments += element.toFirExpression()
}
}
// TODO
//is JavaEnumValueAnnotationArgument -> {}
is JavaClassObjectAnnotationArgument -> FirGetClassCallImpl(session, null).apply {
// TODO
//arguments += getReferencedType().toFirType()
}
is JavaAnnotationAsAnnotationArgument -> getAnnotation().toFirAnnotationCall()
else -> FirErrorExpressionImpl(session, null, "Unknown JavaAnnotationArgument: ${this::class.java}")
}
}
private fun JavaClassifierType.toFirResolvedType(): FirResolvedType {
val coneType = when (val classifier = classifier) {
is JavaClass -> {
val symbol = session.service<FirSymbolProvider>().getClassLikeSymbolByFqName(classifier.classId!!) as ConeClassSymbol
ConeClassTypeImpl(symbol, typeArguments = typeArguments.map { it.toConeProjection() }.toTypedArray())
}
is JavaTypeParameter -> {
// TODO: it's unclear how to identify type parameter by the symbol
// TODO: some type parameter cache (provider?)
val symbol = createTypeParameterSymbol(classifier.name)
ConeTypeParameterTypeImpl(symbol)
}
else -> ConeClassErrorType(reason = "Unexpected classifier: $classifier")
}
return FirResolvedTypeImpl(
session, psi = null, type = coneType,
isNullable = false, annotations = annotations.map { it.toFirAnnotationCall() }
)
}
private fun JavaType.toFirResolvedType(): FirResolvedType {
if (this is JavaClassifierType) return toFirResolvedType()
return FirResolvedTypeImpl(
session, psi = null, type = ConeClassErrorType("Unexpected JavaType: $this"),
isNullable = false, annotations = emptyList()
)
}
private fun JavaType.toConeProjection(): ConeKotlinTypeProjection {
if (this is JavaClassifierType) {
return toFirResolvedType().type
}
return ConeClassErrorType("Unexpected type argument: $this")
}
private fun createTypeParameterSymbol(name: Name): FirTypeParameterSymbol {
val firSymbol = FirTypeParameterSymbol()
FirTypeParameterImpl(session, null, firSymbol, name, variance = Variance.INVARIANT, isReified = false)
return firSymbol
}
private fun FirAbstractAnnotatedElement.addAnnotationsFrom(javaAnnotationOwner: JavaAnnotationOwner) {
for (annotation in javaAnnotationOwner.annotations) {
annotations += annotation.toFirAnnotationCall()
}
}
private fun findClass(classId: ClassId): JavaClass? = facade.findClass(JavaClassFinder.Request(classId), searchScope)
override fun getCallableSymbols(callableId: CallableId): List<ConeCallableSymbol> {
return callableCache.lookupCacheOrCalculate(callableId) {
val classId = callableId.classId ?: return@lookupCacheOrCalculate emptyList()
val classSymbol = getClassLikeSymbolByFqName(classId) as? FirClassSymbol
?: return@lookupCacheOrCalculate emptyList()
val firClass = classSymbol.fir as FirModifiableClass
val callableSymbols = mutableListOf<ConeCallableSymbol>()
findClass(classId)?.let { javaClass ->
if (firClass.declarations.isEmpty()) {
for (javaMethod in javaClass.methods) {
val methodName = javaMethod.name
val methodId = CallableId(callableId.packageName, callableId.className, methodName)
val methodSymbol = FirFunctionSymbol(methodId)
val memberFunction = FirMemberFunctionImpl(
session, null, methodSymbol, methodName,
javaMethod.visibility, javaMethod.modality,
isExpect = false, isActual = false, isOverride = false,
isOperator = true, isInfix = false, isInline = false,
isTailRec = false, isExternal = false, isSuspend = false,
receiverType = null, returnType = javaMethod.returnType.toFirResolvedType()
).apply {
for (typeParameter in javaMethod.typeParameters) {
typeParameters += createTypeParameterSymbol(typeParameter.name).fir
}
addAnnotationsFrom(javaMethod)
for (valueParameter in javaMethod.valueParameters) {
valueParameters += FirValueParameterImpl(
session, null, valueParameter.name ?: Name.special("<anonymous Java parameter>"),
returnType = valueParameter.type.toFirResolvedType(),
defaultValue = null, isCrossinline = false, isNoinline = false,
isVararg = valueParameter.isVararg
)
}
}
firClass.declarations += memberFunction
}
}
for (declaration in firClass.declarations) {
if (declaration is FirNamedFunction) {
val methodId = CallableId(callableId.packageName, callableId.className, declaration.name)
if (methodId == callableId) {
val symbol = declaration.symbol as ConeCallableSymbol
callableSymbols += symbol
}
}
}
}
callableSymbols
}.orEmpty()
}
override fun getClassLikeSymbolByFqName(classId: ClassId): ConeClassLikeSymbol? {
return classCache.lookupCacheOrCalculateWithPostCompute(classId, {
val foundClass = findClass(classId)
if (foundClass == null) {
null to null
} else {
FirClassSymbol(classId) to foundClass
}
}) { firSymbol, foundClass ->
foundClass?.let { javaClass ->
FirClassImpl(
session, null, firSymbol as FirClassSymbol, javaClass.name,
javaClass.visibility, javaClass.modality,
isExpect = false, isActual = false,
classKind = javaClass.classKind,
isInner = !javaClass.isStatic, isCompanion = false,
isData = false, isInline = false
).apply {
for (typeParameter in javaClass.typeParameters) {
typeParameters += createTypeParameterSymbol(typeParameter.name).fir
}
addAnnotationsFrom(javaClass)
for (supertype in javaClass.supertypes) {
superTypes += supertype.toFirResolvedType()
}
}
}
}
}
@@ -0,0 +1,26 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. 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.fir.java
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.load.java.structure.JavaClass
import org.jetbrains.kotlin.load.java.structure.JavaModifierListOwner
internal val JavaModifierListOwner.modality: Modality
get() = when {
isAbstract -> Modality.ABSTRACT
isFinal -> Modality.FINAL
else -> Modality.OPEN
}
internal val JavaClass.classKind: ClassKind
get() = when {
isAnnotationType -> ClassKind.ANNOTATION_CLASS
isInterface -> ClassKind.INTERFACE
isEnum -> ClassKind.ENUM_CLASS
else -> ClassKind.CLASS
}
@@ -1,17 +0,0 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. 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.fir.java.symbols
import org.jetbrains.kotlin.fir.symbols.ConeClassSymbol
import org.jetbrains.kotlin.load.java.structure.JavaClass
import org.jetbrains.kotlin.load.java.structure.classId
import org.jetbrains.kotlin.name.ClassId
class JavaClassSymbol(javaClass: JavaClass) : ConeClassSymbol {
override val classId: ClassId = javaClass.classId ?: error("!")
}
@@ -1,11 +0,0 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. 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.fir.java.symbols
import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterSymbol
import org.jetbrains.kotlin.name.Name
class JavaTypeParameterSymbol(override val name: Name) : ConeTypeParameterSymbol
@@ -5,12 +5,15 @@
package org.jetbrains.kotlin.fir.resolve
import org.jetbrains.kotlin.fir.symbols.ConeSymbol
import org.jetbrains.kotlin.fir.symbols.CallableId
import org.jetbrains.kotlin.fir.symbols.ConeCallableSymbol
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeSymbol
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
abstract class AbstractFirSymbolProvider : FirSymbolProvider {
protected val classCache = mutableMapOf<ClassId, ConeSymbol?>()
protected val classCache = mutableMapOf<ClassId, ConeClassLikeSymbol?>()
protected val callableCache = mutableMapOf<CallableId, List<ConeCallableSymbol>>()
protected val packageCache = mutableMapOf<FqName, FqName?>()
protected inline fun <K, V : Any?> MutableMap<K, V>.lookupCacheOrCalculate(key: K, crossinline l: (K) -> V): V? {
@@ -22,4 +25,17 @@ abstract class AbstractFirSymbolProvider : FirSymbolProvider {
calculated
}
}
protected inline fun <K, V : Any?, T> MutableMap<K, V>.lookupCacheOrCalculateWithPostCompute(
key: K, crossinline l: (K) -> Pair<V, T>, postCompute: (V, T) -> Unit
): V? {
return if (key in this.keys) {
this[key]
} else {
val calculated = l(key)
this[key] = calculated.first
postCompute(calculated.first, calculated.second)
calculated.first
}
}
}
@@ -10,6 +10,9 @@ import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration
import org.jetbrains.kotlin.fir.declarations.FirNamedDeclaration
import org.jetbrains.kotlin.fir.service
import org.jetbrains.kotlin.fir.symbols.CallableId
import org.jetbrains.kotlin.fir.symbols.ConeCallableSymbol
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeSymbol
import org.jetbrains.kotlin.fir.symbols.ConeSymbol
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
@@ -17,7 +20,9 @@ import org.jetbrains.kotlin.name.FqName
interface FirProvider : FirSymbolProvider {
fun getFirClassifierByFqName(fqName: ClassId): FirMemberDeclaration?
override fun getClassLikeSymbolByFqName(classId: ClassId): ConeSymbol?
override fun getClassLikeSymbolByFqName(classId: ClassId): ConeClassLikeSymbol?
override fun getCallableSymbols(callableId: CallableId): List<ConeCallableSymbol>
override fun getPackage(fqName: FqName): FqName? {
if (getFirFilesByPackage(fqName).isNotEmpty()) return fqName
@@ -8,15 +8,16 @@ package org.jetbrains.kotlin.fir.resolve
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.service
import org.jetbrains.kotlin.fir.symbols.CallableId
import org.jetbrains.kotlin.fir.symbols.ConeSymbol
import org.jetbrains.kotlin.fir.symbols.ConeCallableSymbol
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeSymbol
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
interface FirSymbolProvider {
fun getClassLikeSymbolByFqName(classId: ClassId): ConeSymbol?
fun getClassLikeSymbolByFqName(classId: ClassId): ConeClassLikeSymbol?
fun getCallableSymbols(callableId: CallableId): List<ConeSymbol>
fun getCallableSymbols(callableId: CallableId): List<ConeCallableSymbol>
fun getPackage(fqName: FqName): FqName? // TODO: Replace to symbol sometime
@@ -7,13 +7,14 @@ package org.jetbrains.kotlin.fir.resolve.impl
import org.jetbrains.kotlin.fir.resolve.FirSymbolProvider
import org.jetbrains.kotlin.fir.symbols.CallableId
import org.jetbrains.kotlin.fir.symbols.ConeSymbol
import org.jetbrains.kotlin.fir.symbols.ConeCallableSymbol
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeSymbol
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult
class FirCompositeSymbolProvider(val providers: List<FirSymbolProvider>) : FirSymbolProvider {
override fun getCallableSymbols(callableId: CallableId): List<ConeSymbol> {
override fun getCallableSymbols(callableId: CallableId): List<ConeCallableSymbol> {
for (provider in providers) {
val symbols = provider.getCallableSymbols(callableId)
if (symbols.isNotEmpty()) return symbols
@@ -25,7 +26,7 @@ class FirCompositeSymbolProvider(val providers: List<FirSymbolProvider>) : FirSy
return providers.firstNotNullResult { it.getPackage(fqName) }
}
override fun getClassLikeSymbolByFqName(classId: ClassId): ConeSymbol? {
override fun getClassLikeSymbolByFqName(classId: ClassId): ConeClassLikeSymbol? {
return providers.firstNotNullResult { it.getClassLikeSymbolByFqName(classId) }
}
}
@@ -11,12 +11,13 @@ import org.jetbrains.kotlin.fir.resolve.AbstractFirSymbolProvider
import org.jetbrains.kotlin.fir.resolve.FirSymbolProvider
import org.jetbrains.kotlin.fir.service
import org.jetbrains.kotlin.fir.symbols.CallableId
import org.jetbrains.kotlin.fir.symbols.ConeSymbol
import org.jetbrains.kotlin.fir.symbols.ConeCallableSymbol
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeSymbol
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
class FirDependenciesSymbolProviderImpl(val session: FirSession) : AbstractFirSymbolProvider() {
override fun getCallableSymbols(callableId: CallableId): List<ConeSymbol> {
override fun getCallableSymbols(callableId: CallableId): List<ConeCallableSymbol> {
// TODO
return emptyList()
}
@@ -28,7 +29,7 @@ class FirDependenciesSymbolProviderImpl(val session: FirSession) : AbstractFirSy
}.toList()
}
override fun getClassLikeSymbolByFqName(classId: ClassId): ConeSymbol? {
override fun getClassLikeSymbolByFqName(classId: ClassId): ConeClassLikeSymbol? {
return classCache.lookupCacheOrCalculate(classId) {
for (provider in dependencyProviders) {
provider.getClassLikeSymbolByFqName(classId)?.let {
@@ -14,8 +14,7 @@ import org.jetbrains.kotlin.fir.declarations.impl.FirTypeParameterImpl
import org.jetbrains.kotlin.fir.deserialization.FirTypeDeserializer
import org.jetbrains.kotlin.fir.resolve.FirSymbolProvider
import org.jetbrains.kotlin.fir.resolve.getOrPut
import org.jetbrains.kotlin.fir.symbols.CallableId
import org.jetbrains.kotlin.fir.symbols.ConeSymbol
import org.jetbrains.kotlin.fir.symbols.*
import org.jetbrains.kotlin.fir.symbols.impl.FictitiousFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
@@ -38,7 +37,7 @@ import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult
import java.io.InputStream
class FirLibrarySymbolProviderImpl(val session: FirSession) : FirSymbolProvider {
override fun getCallableSymbols(callableId: CallableId): List<ConeSymbol> {
override fun getCallableSymbols(callableId: CallableId): List<ConeCallableSymbol> {
// TODO
return emptyList()
}
@@ -67,7 +66,7 @@ class FirLibrarySymbolProviderImpl(val session: FirSession) : FirSymbolProvider
val classDataFinder = ProtoBasedClassDataFinder(packageProto, nameResolver, version) { SourceElement.NO_SOURCE }
val lookup = mutableMapOf<ClassId, ConeSymbol>()
val lookup = mutableMapOf<ClassId, ConeClassLikeSymbol>()
private fun createTypeParameterSymbol(name: Name): FirTypeParameterSymbol {
val firSymbol = FirTypeParameterSymbol()
@@ -75,7 +74,7 @@ class FirLibrarySymbolProviderImpl(val session: FirSession) : FirSymbolProvider
return firSymbol
}
fun getSymbolByFqName(classId: ClassId, provider: FirSymbolProvider): ConeSymbol? {
fun getClassLikeSymbolByFqName(classId: ClassId, provider: FirSymbolProvider): ConeClassLikeSymbol? {
if (classId !in classDataFinder.allClassIds) return null
return lookup.getOrPut(classId, { FirClassSymbol(classId) }) { symbol ->
@@ -142,11 +141,11 @@ class FirLibrarySymbolProviderImpl(val session: FirSession) : FirSymbolProvider
private val allPackageFragments = loadBuiltIns().groupBy { it.fqName }
private val fictitiousFunctionSymbols = mutableMapOf<Int, ConeSymbol>()
private val fictitiousFunctionSymbols = mutableMapOf<Int, ConeClassSymbol>()
override fun getClassLikeSymbolByFqName(classId: ClassId): ConeSymbol? {
override fun getClassLikeSymbolByFqName(classId: ClassId): ConeClassLikeSymbol? {
return allPackageFragments[classId.packageFqName]?.firstNotNullResult {
it.getSymbolByFqName(classId, this)
it.getClassLikeSymbolByFqName(classId, this)
} ?: with(classId) {
val className = relativeClassName.asString()
val kind = FunctionClassDescriptor.Kind.byClassNamePrefix(packageFqName, className) ?: return@with null
@@ -24,12 +24,14 @@ class FirProviderImpl(val session: FirSession) : FirProvider {
}
}
override fun getClassLikeSymbolByFqName(classId: ClassId): ConeSymbol? {
return (getFirClassifierByFqName(classId) as? FirSymbolOwner<*>)?.symbol
override fun getClassLikeSymbolByFqName(classId: ClassId): ConeClassLikeSymbol? {
return (getFirClassifierByFqName(classId) as? FirSymbolOwner<*>)?.symbol as? ConeClassLikeSymbol
}
override fun getCallableSymbols(callableId: CallableId): List<ConeSymbol> {
return (callableMap[callableId] ?: emptyList()).filterIsInstance<FirSymbolOwner<*>>().map { it.symbol }
override fun getCallableSymbols(callableId: CallableId): List<ConeCallableSymbol> {
return (callableMap[callableId] ?: emptyList())
.filterIsInstance<FirSymbolOwner<*>>()
.mapNotNull { it.symbol as? ConeCallableSymbol }
}
override fun getFirClassifierContainerFile(fqName: ClassId): FirFile {
@@ -66,12 +66,7 @@ open class FirTypeResolveTransformer(
val firProvider = FirProvider.getInstance(regularClass.session)
val classId = regularClass.symbol.classId
lookupSuperTypes(regularClass, lookupInterfaces = false, deep = true).asReversed().mapTo(towerScope.scopes) {
val symbol = it.symbol
if (symbol is FirBasedSymbol<*>) {
FirNestedClassifierScope(symbol.classId, FirProvider.getInstance(symbol.fir.session))
} else {
FirNestedClassifierScope(symbol.classId, FirSymbolProvider.getInstance(regularClass.session))
}
FirNestedClassifierScope(it.symbol.classId, FirSymbolProvider.getInstance(regularClass.session))
}
val companionObjects = regularClass.declarations.filterIsInstance<FirRegularClass>().filter { it.isCompanion }
for (companionObject in companionObjects) {
@@ -0,0 +1,3 @@
public class Some {
}
@@ -0,0 +1,3 @@
class A : Some()
@@ -0,0 +1,5 @@
FILE: jvm.kt
public final class A : R|Some| {
public constructor(): super<R|Some|>()
}
@@ -0,0 +1,9 @@
public class A {
public A foo() {
return this;
}
public A bar() {
return this;
}
}
@@ -0,0 +1,9 @@
class B : A() {
override fun foo(): B = this
fun bar(): B = this // Ambiguity, no override here
fun test() {
foo()
bar()
}
}
@@ -0,0 +1,18 @@
FILE: B.kt
public final class B : R|A| {
public constructor(): super<R|A|>()
public final override function foo(): R|B| {
return@@@foo this#
}
public final function bar(): R|B| {
return@@@bar this#
}
public final function test(): R|kotlin/Unit| {
R|/B.foo|()
<Ambiguity: bar, [/B.bar, /A.bar]>#()
}
}
@@ -34,6 +34,11 @@ public class FirMultiModuleResolveTestGenerated extends AbstractFirMultiModuleRe
runTest("idea/testData/fir/multiModule/basic/");
}
@TestMetadata("basicWithJava")
public void testBasicWithJava() throws Exception {
runTest("idea/testData/fir/multiModule/basicWithJava/");
}
@TestMetadata("mppFakeOverrides")
public void testMppFakeOverrides() throws Exception {
runTest("idea/testData/fir/multiModule/mppFakeOverrides/");
@@ -53,4 +58,9 @@ public class FirMultiModuleResolveTestGenerated extends AbstractFirMultiModuleRe
public void testMppSuperTypes() throws Exception {
runTest("idea/testData/fir/multiModule/mppSuperTypes/");
}
@TestMetadata("overrideWithJava")
public void testOverrideWithJava() throws Exception {
runTest("idea/testData/fir/multiModule/overrideWithJava/");
}
}