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:
committed by
Mikhail Glukhikh
parent
4ea3df53cc
commit
3a237416c9
@@ -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("!")
|
||||
}
|
||||
|
||||
|
||||
-11
@@ -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
|
||||
+18
-2
@@ -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
|
||||
|
||||
|
||||
+4
-3
@@ -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) }
|
||||
}
|
||||
}
|
||||
+4
-3
@@ -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 {
|
||||
|
||||
+7
-8
@@ -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 {
|
||||
|
||||
+1
-6
@@ -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]>#()
|
||||
}
|
||||
|
||||
}
|
||||
+10
@@ -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/");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user