diff --git a/compiler/fir/cones/src/org/jetbrains/kotlin/fir/symbols/Callables.kt b/compiler/fir/cones/src/org/jetbrains/kotlin/fir/symbols/Callables.kt index b0a21a87256..24020a89640 100644 --- a/compiler/fir/cones/src/org/jetbrains/kotlin/fir/symbols/Callables.kt +++ b/compiler/fir/cones/src/org/jetbrains/kotlin/fir/symbols/Callables.kt @@ -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 { diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/FirJavaModuleBasedSession.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/FirJavaModuleBasedSession.kt index e6497751955..c4908b9a497 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/FirJavaModuleBasedSession.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/FirJavaModuleBasedSession.kt @@ -27,7 +27,7 @@ class FirJavaModuleBasedSession( FirCompositeSymbolProvider( listOf( service(), - 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) ) ) diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaSymbolProvider.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaSymbolProvider.kt index 6e41f1dddd1..7d9db664102 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaSymbolProvider.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaSymbolProvider.kt @@ -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 { - // 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().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 { + 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() + 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(""), + 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() + } + } + } } } diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaUtils.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaUtils.kt new file mode 100644 index 00000000000..e06ec8e6d1c --- /dev/null +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaUtils.kt @@ -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 + } diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/symbols/JavaClassSymbol.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/symbols/JavaClassSymbol.kt deleted file mode 100644 index 4ce49de1967..00000000000 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/symbols/JavaClassSymbol.kt +++ /dev/null @@ -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("!") -} - - diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/symbols/JavaTypeParameterSymbol.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/symbols/JavaTypeParameterSymbol.kt deleted file mode 100644 index d5deef4e1ab..00000000000 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/symbols/JavaTypeParameterSymbol.kt +++ /dev/null @@ -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 \ No newline at end of file diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/AbstractFirSymbolProvider.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/AbstractFirSymbolProvider.kt index 8119e294ba8..41e0169631b 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/AbstractFirSymbolProvider.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/AbstractFirSymbolProvider.kt @@ -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() + protected val classCache = mutableMapOf() + protected val callableCache = mutableMapOf>() protected val packageCache = mutableMapOf() protected inline fun MutableMap.lookupCacheOrCalculate(key: K, crossinline l: (K) -> V): V? { @@ -22,4 +25,17 @@ abstract class AbstractFirSymbolProvider : FirSymbolProvider { calculated } } + + protected inline fun MutableMap.lookupCacheOrCalculateWithPostCompute( + key: K, crossinline l: (K) -> Pair, 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 + } + } } \ No newline at end of file diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/FirProvider.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/FirProvider.kt index 99b6ea79568..7ece672164a 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/FirProvider.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/FirProvider.kt @@ -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 override fun getPackage(fqName: FqName): FqName? { if (getFirFilesByPackage(fqName).isNotEmpty()) return fqName diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/FirSymbolProvider.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/FirSymbolProvider.kt index 195e2c20007..0d5e473b6d3 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/FirSymbolProvider.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/FirSymbolProvider.kt @@ -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 + fun getCallableSymbols(callableId: CallableId): List fun getPackage(fqName: FqName): FqName? // TODO: Replace to symbol sometime diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/impl/FirCompositeSymbolProvider.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/impl/FirCompositeSymbolProvider.kt index 886a88e8978..e4b1be75d97 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/impl/FirCompositeSymbolProvider.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/impl/FirCompositeSymbolProvider.kt @@ -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 { - override fun getCallableSymbols(callableId: CallableId): List { + override fun getCallableSymbols(callableId: CallableId): List { for (provider in providers) { val symbols = provider.getCallableSymbols(callableId) if (symbols.isNotEmpty()) return symbols @@ -25,7 +26,7 @@ class FirCompositeSymbolProvider(val providers: List) : 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) } } } \ No newline at end of file diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/impl/FirDependenciesSymbolProviderImpl.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/impl/FirDependenciesSymbolProviderImpl.kt index 97cbfc44cfe..9f1c4cf55cc 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/impl/FirDependenciesSymbolProviderImpl.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/impl/FirDependenciesSymbolProviderImpl.kt @@ -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 { + override fun getCallableSymbols(callableId: CallableId): List { // 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 { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/impl/FirLibrarySymbolProviderImpl.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/impl/FirLibrarySymbolProviderImpl.kt index 65bc67abf4c..599723f157e 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/impl/FirLibrarySymbolProviderImpl.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/impl/FirLibrarySymbolProviderImpl.kt @@ -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 { + override fun getCallableSymbols(callableId: CallableId): List { // 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() + val lookup = mutableMapOf() 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() + private val fictitiousFunctionSymbols = mutableMapOf() - 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 diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/impl/FirProviderImpl.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/impl/FirProviderImpl.kt index 60b37320269..4035c91cb7f 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/impl/FirProviderImpl.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/impl/FirProviderImpl.kt @@ -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 { - return (callableMap[callableId] ?: emptyList()).filterIsInstance>().map { it.symbol } + override fun getCallableSymbols(callableId: CallableId): List { + return (callableMap[callableId] ?: emptyList()) + .filterIsInstance>() + .mapNotNull { it.symbol as? ConeCallableSymbol } } override fun getFirClassifierContainerFile(fqName: ClassId): FirFile { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirTypeResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirTypeResolveTransformer.kt index 8a1e76ab102..784039b04f9 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirTypeResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirTypeResolveTransformer.kt @@ -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().filter { it.isCompanion } for (companionObject in companionObjects) { diff --git a/idea/testData/fir/multiModule/basicWithJava/jvm/Some.java b/idea/testData/fir/multiModule/basicWithJava/jvm/Some.java new file mode 100644 index 00000000000..d57bf6af7d4 --- /dev/null +++ b/idea/testData/fir/multiModule/basicWithJava/jvm/Some.java @@ -0,0 +1,3 @@ +public class Some { + +} \ No newline at end of file diff --git a/idea/testData/fir/multiModule/basicWithJava/jvm/jvm.kt b/idea/testData/fir/multiModule/basicWithJava/jvm/jvm.kt new file mode 100644 index 00000000000..6aedbcf25b5 --- /dev/null +++ b/idea/testData/fir/multiModule/basicWithJava/jvm/jvm.kt @@ -0,0 +1,3 @@ + + +class A : Some() \ No newline at end of file diff --git a/idea/testData/fir/multiModule/basicWithJava/jvm/jvm.txt b/idea/testData/fir/multiModule/basicWithJava/jvm/jvm.txt new file mode 100644 index 00000000000..212a376584b --- /dev/null +++ b/idea/testData/fir/multiModule/basicWithJava/jvm/jvm.txt @@ -0,0 +1,5 @@ +FILE: jvm.kt + public final class A : R|Some| { + public constructor(): super() + + } diff --git a/idea/testData/fir/multiModule/overrideWithJava/jvm/A.java b/idea/testData/fir/multiModule/overrideWithJava/jvm/A.java new file mode 100644 index 00000000000..be6f30c8a5c --- /dev/null +++ b/idea/testData/fir/multiModule/overrideWithJava/jvm/A.java @@ -0,0 +1,9 @@ +public class A { + public A foo() { + return this; + } + + public A bar() { + return this; + } +} \ No newline at end of file diff --git a/idea/testData/fir/multiModule/overrideWithJava/jvm/B.kt b/idea/testData/fir/multiModule/overrideWithJava/jvm/B.kt new file mode 100644 index 00000000000..897fbd4c8c6 --- /dev/null +++ b/idea/testData/fir/multiModule/overrideWithJava/jvm/B.kt @@ -0,0 +1,9 @@ +class B : A() { + override fun foo(): B = this + fun bar(): B = this // Ambiguity, no override here + + fun test() { + foo() + bar() + } +} diff --git a/idea/testData/fir/multiModule/overrideWithJava/jvm/B.txt b/idea/testData/fir/multiModule/overrideWithJava/jvm/B.txt new file mode 100644 index 00000000000..cdad2d7fc14 --- /dev/null +++ b/idea/testData/fir/multiModule/overrideWithJava/jvm/B.txt @@ -0,0 +1,18 @@ +FILE: B.kt + public final class B : R|A| { + public constructor(): super() + + 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|() + #() + } + + } diff --git a/idea/tests/org/jetbrains/kotlin/idea/fir/FirMultiModuleResolveTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/fir/FirMultiModuleResolveTestGenerated.java index 237bf5d1f22..de474c90690 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/fir/FirMultiModuleResolveTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/fir/FirMultiModuleResolveTestGenerated.java @@ -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/"); + } }