FIR: built-in resolve, preliminary version #KT-24091 Fixed

This commit is contained in:
Mikhail Glukhikh
2018-03-22 16:58:39 +03:00
parent ce113fbe2e
commit 8035be07e2
30 changed files with 556 additions and 122 deletions
@@ -5,21 +5,29 @@
package org.jetbrains.kotlin.fir.symbols
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name
interface ConeSymbol
interface ConeTypeParameterSymbol : ConeSymbol
interface ConeTypeParameterSymbol : ConeSymbol {
val name: Name
}
interface ConeClassLikeSymbol : ConeSymbol {
val classId: ClassId
val typeParameters: List<ConeTypeParameterSymbol>
}
interface ConeTypeAliasSymbol : ConeClassLikeSymbol {
val expansionType: ConeClassLikeType
val expansionType: ConeClassLikeType?
}
interface ConeClassSymbol : ConeClassLikeSymbol {
val kind: ClassKind
val superTypes: List<ConeClassLikeType>
}
@@ -35,6 +35,14 @@ class ConeKotlinErrorType(val reason: String) : ConeKotlinType() {
}
}
class ConeClassErrorType(val reason: String): ConeClassLikeType() {
override val symbol: ConeClassLikeSymbol
get() = error("!")
override val typeArguments: List<ConeKotlinTypeProjection>
get() = emptyList()
}
sealed class ConeSymbolBasedType : ConeKotlinType() {
abstract val symbol: ConeSymbol
}
+1
View File
@@ -12,6 +12,7 @@ jvmTarget = "1.6"
dependencies {
compile(project(":core:descriptors"))
compile(project(":core:deserialization"))
compile(project(":compiler:fir:cones"))
compile(project(":compiler:fir:tree"))
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.fir.declarations.FirImport
import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedImportImpl
import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedPackageStarImport
import org.jetbrains.kotlin.fir.resolve.FirProvider
import org.jetbrains.kotlin.fir.resolve.FirSymbolProvider
import org.jetbrains.kotlin.fir.visitors.CompositeTransformResult
import org.jetbrains.kotlin.fir.visitors.FirTransformer
import org.jetbrains.kotlin.fir.visitors.compose
@@ -28,13 +29,13 @@ class FirImportResolveTransformer : FirTransformer<Nothing?>() {
override fun transformImport(import: FirImport, data: Nothing?): CompositeTransformResult<FirImport> {
val fqName = import.importedFqName ?: return import.compose()
val firProvider = FirProvider.getInstance(import.session)
val firProvider = FirSymbolProvider.getInstance(import.session)
if (!fqName.isRoot) {
val lastPart = mutableListOf<String>()
var firstPart = fqName
if (import.isAllUnder && firProvider.getFirFilesByPackage(firstPart).isNotEmpty()) {
if (import.isAllUnder && firProvider.getPackage(firstPart) != null) {
return FirResolvedPackageStarImport(import, firstPart).compose()
}
@@ -43,9 +44,9 @@ class FirImportResolveTransformer : FirTransformer<Nothing?>() {
firstPart = firstPart.parent()
val resolvedFqName = ClassId(firstPart, FqName.fromSegments(lastPart), false)
val foundClassifier = firProvider.getFirClassifierByFqName(resolvedFqName)
val foundSymbol = firProvider.getSymbolByFqName(resolvedFqName)
if (foundClassifier != null) {
if (foundSymbol != null) {
return FirResolvedImportImpl(import, resolvedFqName).compose()
}
}
@@ -12,24 +12,19 @@ import org.jetbrains.kotlin.fir.resolve.FirProvider
import org.jetbrains.kotlin.fir.resolve.FirTypeResolver
import org.jetbrains.kotlin.fir.scopes.FirPosition
import org.jetbrains.kotlin.fir.scopes.impl.*
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeSymbol
import org.jetbrains.kotlin.fir.symbols.*
import org.jetbrains.kotlin.fir.transformSingle
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.impl.FirResolvedTypeImpl
import org.jetbrains.kotlin.fir.visitors.CompositeTransformResult
import org.jetbrains.kotlin.fir.visitors.FirTransformer
import org.jetbrains.kotlin.fir.visitors.FirVisitor
import org.jetbrains.kotlin.fir.visitors.compose
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
class FirTypeResolveTransformer(val superTypesOnly: Boolean = false) : FirTransformer<Nothing?>() {
open class FirTypeResolveTransformer : FirTransformer<Nothing?>() {
override fun <E : FirElement> transformElement(element: E, data: Nothing?): CompositeTransformResult<E> {
return if (superTypesOnly) {
element.compose()
} else {
(element.transformChildren(this, data) as E).compose()
}
return (element.transformChildren(this, data) as E).compose()
}
lateinit var scope: FirCompositeScope
@@ -50,9 +45,7 @@ class FirTypeResolveTransformer(val superTypesOnly: Boolean = false) : FirTransf
}
private fun lookupSuperTypes(klass: FirClass): List<ClassId> {
val superTypesBuilder = SuperClassHierarchyBuilder()
klass.superTypes.any { it.accept(superTypesBuilder, null) }
return superTypesBuilder.classes
return mutableListOf<ConeClassLikeType>().also { klass.symbol.collectSuperTypes(it) }.map { it.symbol.classId }
}
private fun resolveSuperTypesAndExpansions(element: FirMemberDeclaration) {
@@ -140,31 +133,55 @@ class FirTypeResolveTransformer(val superTypesOnly: Boolean = false) : FirTransf
return typeProjectionWithVariance.compose()
}
private class SuperTypeResolveTransformer(val elementIterator: Iterator<FirElement>) : FirTypeResolveTransformer() {
override fun <E : FirElement> transformElement(element: E, data: Nothing?): CompositeTransformResult<E> {
if (elementIterator.hasNext()) elementIterator.next().transformSingle(this, data)
return element.compose()
}
}
private inner class SuperTypeResolver : FirTransformer<Nothing?>() {
override fun <E : FirElement> transformElement(element: E, data: Nothing?): CompositeTransformResult<E> {
return element.compose()
}
private fun walkSymbols(symbol: ConeSymbol) {
if (symbol is ConeClassLikeSymbol) {
if (symbol is FirBasedSymbol<*>) {
val classId = symbol.classId
val firProvider = FirProvider.getInstance(symbol.fir.session)
val classes = generateSequence(classId) { it.outerClassId }.toList().asReversed()
val file = firProvider.getFirClassifierContainerFile(classes.first())
val firElementsToVisit = classes.asSequence().map {
firProvider.getFirClassifierByFqName(it)!!
}
val transformer = SuperTypeResolveTransformer(firElementsToVisit.iterator())
file.transformSingle(transformer, null)
} else {
if (symbol is ConeTypeAliasSymbol) {
symbol.expansionType?.let { walkSymbols(it.symbol) }
} else if (symbol is ConeClassSymbol) {
symbol.superTypes.forEach { walkSymbols(it.symbol) }
}
}
}
}
override fun transformType(type: FirType, data: Nothing?): CompositeTransformResult<FirType> {
val typeResolver = FirTypeResolver.getInstance(type.session)
val symbol = typeResolver.resolveToSymbol(type, scope, position = FirPosition.SUPER_TYPE_OR_EXPANSION)
val myTransformer = this@FirTypeResolveTransformer
if (symbol != null) walkSymbols(symbol)
if (type !is FirUserType) return myTransformer.transformType(type, data)
val classId = (symbol as? ConeClassLikeSymbol)?.classId ?: return myTransformer.transformType(type, data)
val firProvider = FirProvider.getInstance(type.session)
val classes = generateSequence(classId) { it.outerClassId }.toList()
val transformer = FirTypeResolveTransformer(superTypesOnly = true)
val file = firProvider.getFirClassifierContainerFile(classes.last())
file.transformSingle(transformer, null)
classes.forEach {
firProvider.getFirClassifierByFqName(it)!!.transformSingle(transformer, data)
}
type.transformChildren(myTransformer, null)
@@ -172,36 +189,29 @@ class FirTypeResolveTransformer(val superTypesOnly: Boolean = false) : FirTransf
}
}
private inner class SuperClassHierarchyBuilder : FirVisitor<Boolean, Nothing?>() {
override fun visitElement(element: FirElement, data: Nothing?): Boolean {
return false
private tailrec fun ConeClassLikeType.computePartialExpansion(): ConeClassLikeType? {
return when (this) {
is ConeAbbreviatedType -> directExpansion.takeIf { it !is ConeClassErrorType }?.computePartialExpansion()
else -> return this
}
private tailrec fun ConeClassLikeType.computePartialExpansion(): ClassId {
return when (this) {
!is ConeAbbreviatedType -> this.symbol.classId
else -> this.directExpansion.computePartialExpansion()
}
}
val classes = mutableListOf<ClassId>()
override fun visitResolvedType(resolvedType: FirResolvedType, data: Nothing?): Boolean {
val provider = FirProvider.getInstance(resolvedType.session)
val targetClassId = resolvedType.coneTypeSafe<ConeClassLikeType>()?.computePartialExpansion() ?: return false
val classifier = provider.getFirClassifierByFqName(targetClassId)!!
when (classifier) {
is FirClass -> {
if (classifier.classKind == ClassKind.CLASS) {
classes += targetClassId
classifier.superTypes.any { it.accept(this, data) }
}
}
is FirTypeAlias -> classifier.expandedType.accept(this, data)
}
return true
}
}
private tailrec fun ConeClassLikeSymbol.collectSuperTypes(list: MutableList<ConeClassLikeType>) {
return when (this) {
is ConeClassSymbol -> {
val superClassType =
this.superTypes
.map { it.computePartialExpansion() }
.firstOrNull { (it?.symbol as? ConeClassSymbol)?.kind == ClassKind.CLASS } ?: return
list += superClassType
superClassType.symbol.collectSuperTypes(list)
}
is ConeTypeAliasSymbol -> {
val expansion = expansionType?.computePartialExpansion() ?: return
expansion.symbol.collectSuperTypes(list)
}
else -> error("?!id:1")
}
}
}
@@ -0,0 +1,129 @@
/*
* 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.deserialization
import org.jetbrains.kotlin.fir.resolve.FirSymbolProvider
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeSymbol
import org.jetbrains.kotlin.fir.symbols.ConeSymbol
import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterSymbol
import org.jetbrains.kotlin.fir.symbols.LibraryTypeParameterSymbol
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.impl.ConeAbbreviatedTypeImpl
import org.jetbrains.kotlin.fir.types.impl.ConeClassTypeImpl
import org.jetbrains.kotlin.fir.types.impl.ConeKotlinTypeProjectionInImpl
import org.jetbrains.kotlin.fir.types.impl.ConeKotlinTypeProjectionOutImpl
import org.jetbrains.kotlin.metadata.ProtoBuf
import org.jetbrains.kotlin.metadata.deserialization.*
import org.jetbrains.kotlin.serialization.deserialization.ProtoEnumFlags
import org.jetbrains.kotlin.serialization.deserialization.getClassId
import org.jetbrains.kotlin.serialization.deserialization.getName
import org.jetbrains.kotlin.types.Variance
import java.util.*
class FirTypeDeserializer(
val nameResolver: NameResolver,
val typeTable: TypeTable,
val symbolProvider: FirSymbolProvider,
typeParameterProtos: List<ProtoBuf.TypeParameter>,
val parent: FirTypeDeserializer?
) {
private fun computeClassifier(fqNameIndex: Int): ConeSymbol? {
val id = nameResolver.getClassId(fqNameIndex)
return symbolProvider.getSymbolByFqName(id)
}
fun type(proto: ProtoBuf.Type): ConeKotlinType {
if (proto.hasFlexibleTypeCapabilitiesId()) {
val id = nameResolver.getString(proto.flexibleTypeCapabilitiesId)
val lowerBound = classLikeType(proto)
val upperBound = classLikeType(proto.flexibleUpperBound(typeTable)!!)
return ConeKotlinErrorType("Not supported: Flexible types")//c.components.flexibleTypeDeserializer.create(proto, id, lowerBound, upperBound)
}
return classLikeType(proto) ?: ConeKotlinErrorType("?!id:0")
}
private fun typeParameterSymbol(typeParameterId: Int): ConeTypeParameterSymbol? =
typeParameterDescriptors[typeParameterId] ?: parent?.typeParameterSymbol(typeParameterId)
private val typeParameterDescriptors =
if (typeParameterProtos.isEmpty()) {
mapOf<Int, ConeTypeParameterSymbol>()
} else {
val result = LinkedHashMap<Int, ConeTypeParameterSymbol>()
for ((index, proto) in typeParameterProtos.withIndex()) {
result[proto.id] = LibraryTypeParameterSymbol(nameResolver.getName(proto.name))
}
result
}
val ownTypeParameters: List<ConeTypeParameterSymbol>
get() = typeParameterDescriptors.values.toList()
fun classLikeType(proto: ProtoBuf.Type): ConeClassLikeType? {
val constructor = typeSymbol(proto) as? ConeClassLikeSymbol ?: return null
// if (ErrorUtils.isError(constructor.declarationDescriptor)) {
// return ErrorUtils.createErrorTypeWithCustomConstructor(constructor.toString(), constructor)
// }
fun ProtoBuf.Type.collectAllArguments(): List<ProtoBuf.Type.Argument> =
argumentList + outerType(typeTable)?.collectAllArguments().orEmpty()
val arguments = proto.collectAllArguments().mapIndexed { index, proto ->
typeArgument(constructor.typeParameters.getOrNull(index), proto)
}.toList()
val simpleType = if (Flags.SUSPEND_TYPE.get(proto.flags)) {
//createSuspendFunctionType(annotations, constructor, arguments, proto.nullable)
ConeClassErrorType("createSuspendFunctionType not supported")
} else {
ConeClassTypeImpl(constructor, arguments)
}
val abbreviatedTypeProto = proto.abbreviatedType(typeTable) ?: return simpleType
return ConeAbbreviatedTypeImpl(typeSymbol(abbreviatedTypeProto) as ConeClassLikeSymbol, arguments, simpleType)
}
private fun typeSymbol(proto: ProtoBuf.Type): ConeSymbol? {
return when {
proto.hasClassName() -> computeClassifier(proto.className)
proto.hasTypeAliasName() -> computeClassifier(proto.typeAliasName)
proto.hasTypeParameter() -> typeParameterSymbol(proto.typeParameter)
proto.hasTypeParameterName() -> {
val name = nameResolver.getString(proto.typeParameterName)
// TODO: Optimize
ownTypeParameters.find { it.name.asString() == name }
}
else -> null
}
}
private fun typeArgument(parameter: ConeTypeParameterSymbol?, typeArgumentProto: ProtoBuf.Type.Argument): ConeKotlinTypeProjection {
if (typeArgumentProto.projection == ProtoBuf.Type.Argument.Projection.STAR) {
return StarProjection
}
val projection = ProtoEnumFlags.variance(typeArgumentProto.projection)
val type = typeArgumentProto.type(typeTable) ?: return ConeKotlinErrorType("No type recorded")
val coneType = type(type)
return when (projection) {
Variance.INVARIANT -> coneType
Variance.IN_VARIANCE -> ConeKotlinTypeProjectionInImpl(coneType)
Variance.OUT_VARIANCE -> ConeKotlinTypeProjectionOutImpl(coneType)
}
}
}
@@ -14,10 +14,15 @@ import org.jetbrains.kotlin.fir.symbols.ConeSymbol
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
interface FirProvider {
interface FirProvider : FirSymbolProvider {
fun getFirClassifierByFqName(fqName: ClassId): FirMemberDeclaration?
fun getSymbolByFqName(fqName: ClassId): ConeSymbol?
override fun getSymbolByFqName(classId: ClassId): ConeSymbol?
override fun getPackage(fqName: FqName): FqName? {
if (getFirFilesByPackage(fqName).isNotEmpty()) return fqName
return null
}
fun getFirClassifierContainerFile(fqName: ClassId): FirFile
@@ -0,0 +1,23 @@
/*
* 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.resolve
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.service
import org.jetbrains.kotlin.fir.symbols.ConeSymbol
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
interface FirSymbolProvider {
fun getSymbolByFqName(classId: ClassId): ConeSymbol?
fun getPackage(fqName: FqName): FqName? // TODO: Replace to symbol sometime
companion object {
fun getInstance(session: FirSession) = session.service<FirSymbolProvider>()
}
}
@@ -0,0 +1,22 @@
/*
* 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.resolve.impl
import org.jetbrains.kotlin.fir.resolve.FirSymbolProvider
import org.jetbrains.kotlin.fir.symbols.ConeSymbol
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 getPackage(fqName: FqName): FqName? {
return providers.firstNotNullResult { it.getPackage(fqName) }
}
override fun getSymbolByFqName(classId: ClassId): ConeSymbol? {
return providers.firstNotNullResult { it.getSymbolByFqName(classId) }
}
}
@@ -0,0 +1,96 @@
/*
* 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.resolve.impl
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.SourceElement
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.deserialization.FirTypeDeserializer
import org.jetbrains.kotlin.fir.resolve.FirSymbolProvider
import org.jetbrains.kotlin.fir.symbols.ConeSymbol
import org.jetbrains.kotlin.fir.symbols.LibraryClassSymbol
import org.jetbrains.kotlin.metadata.ProtoBuf
import org.jetbrains.kotlin.metadata.builtins.BuiltInsBinaryVersion
import org.jetbrains.kotlin.metadata.deserialization.NameResolverImpl
import org.jetbrains.kotlin.metadata.deserialization.TypeTable
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.serialization.deserialization.ProtoBasedClassDataFinder
import org.jetbrains.kotlin.serialization.deserialization.builtins.BuiltInSerializerProtocol
import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult
import java.io.InputStream
class FirLibrarySymbolProviderImpl(val session: FirSession) : FirSymbolProvider {
private class BuiltInsPackageFragment(stream: InputStream, val fqName: FqName) {
lateinit var version: BuiltInsBinaryVersion
val packageProto = run {
version = BuiltInsBinaryVersion.readFrom(stream)
if (!version.isCompatible()) {
// TODO: report a proper diagnostic
throw UnsupportedOperationException(
"Kotlin built-in definition format version is not supported: " +
"expected ${BuiltInsBinaryVersion.INSTANCE}, actual $version. " +
"Please update Kotlin"
)
}
ProtoBuf.PackageFragment.parseFrom(stream, BuiltInSerializerProtocol.extensionRegistry)
}
protected val nameResolver = NameResolverImpl(packageProto.strings, packageProto.qualifiedNames)
val classDataFinder = ProtoBasedClassDataFinder(packageProto, nameResolver, version) { SourceElement.NO_SOURCE }
val lookup = mutableMapOf<ClassId, ConeSymbol>()
fun getSymbolByFqName(classId: ClassId, provider: FirSymbolProvider): ConeSymbol? {
if (classId !in classDataFinder.allClassIds) return null
return lookup.getOrPut(classId) {
val classData = classDataFinder.findClassData(classId)!!
LibraryClassSymbol(
classData.classProto, classData.nameResolver,
FirTypeDeserializer(
classData.nameResolver,
TypeTable(classData.classProto.typeTable),
provider,
classData.classProto.typeParameterList,
null
)
)
}
}
}
override fun getPackage(fqName: FqName): FqName? {
if (allPackageFragments.containsKey(fqName)) return fqName
return null
}
private fun loadBuiltIns(): List<BuiltInsPackageFragment> {
val classLoader = this::class.java.classLoader
val streamProvider = { path: String -> classLoader?.getResourceAsStream(path) ?: ClassLoader.getSystemResourceAsStream(path) }
val packageFqNames = KotlinBuiltIns.BUILT_INS_PACKAGE_FQ_NAMES
return packageFqNames.map { fqName ->
val resourcePath = BuiltInSerializerProtocol.getBuiltInsFilePath(fqName)
val inputStream = streamProvider(resourcePath) ?: throw IllegalStateException("Resource not found in classpath: $resourcePath")
BuiltInsPackageFragment(inputStream, fqName)
}
}
private val allPackageFragments = loadBuiltIns().groupBy { it.fqName }
override fun getSymbolByFqName(classId: ClassId): ConeSymbol? {
return allPackageFragments[classId.packageFqName]?.firstNotNullResult { it.getSymbolByFqName(classId, this) }
}
}
@@ -26,8 +26,8 @@ class FirProviderImpl(val session: FirSession) : FirProvider {
}
}
override fun getSymbolByFqName(fqName: ClassId): ConeSymbol? {
return (getFirClassifierByFqName(fqName) as? FirSymbolOwner<*>)?.symbol
override fun getSymbolByFqName(classId: ClassId): ConeSymbol? {
return (getFirClassifierByFqName(classId) as? FirSymbolOwner<*>)?.symbol
}
override fun getFirClassifierContainerFile(fqName: ClassId): FirFile {
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.resolve.impl
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.resolve.FirProvider
import org.jetbrains.kotlin.fir.resolve.FirQualifierResolver
import org.jetbrains.kotlin.fir.resolve.FirSymbolProvider
import org.jetbrains.kotlin.fir.symbols.ConeSymbol
import org.jetbrains.kotlin.fir.symbols.FirSymbolOwner
import org.jetbrains.kotlin.fir.types.FirQualifierPart
@@ -17,20 +18,18 @@ import org.jetbrains.kotlin.name.FqName
class FirQualifierResolverImpl(val session: FirSession) : FirQualifierResolver {
override fun resolveSymbolWithPrefix(parts: List<FirQualifierPart>, prefix: ClassId): ConeSymbol? {
val firProvider = FirProvider.getInstance(session)
val symbolProvider = FirSymbolProvider.getInstance(session)
val fqName = ClassId(
prefix.packageFqName,
parts.drop(1).fold(prefix.relativeClassName) { prefix, suffix -> prefix.child(suffix.name) },
false
)
val classifier = firProvider.getFirClassifierByFqName(fqName) ?: return null
return (classifier as? FirSymbolOwner<*>)?.symbol
return symbolProvider.getSymbolByFqName(fqName) ?: return null
}
override fun resolveSymbol(parts: List<FirQualifierPart>): ConeSymbol? {
val firProvider = FirProvider.getInstance(session)
val firProvider = FirSymbolProvider.getInstance(session)
if (parts.isNotEmpty()) {
val lastPart = mutableListOf<FirQualifierPart>()
@@ -41,9 +40,9 @@ class FirQualifierResolverImpl(val session: FirSession) : FirQualifierResolver {
firstPart.removeAt(firstPart.lastIndex)
val fqName = ClassId(firstPart.toFqName(), lastPart.toFqName(), false)
val foundClassifier = firProvider.getFirClassifierByFqName(fqName)
if (foundClassifier != null) {
return (foundClassifier as? FirSymbolOwner<*>)?.symbol
val foundSymbol = firProvider.getSymbolByFqName(fqName)
if (foundSymbol != null) {
return foundSymbol
}
}
}
@@ -14,9 +14,7 @@ import org.jetbrains.kotlin.fir.resolve.FirQualifierResolver
import org.jetbrains.kotlin.fir.resolve.FirTypeResolver
import org.jetbrains.kotlin.fir.scopes.FirPosition
import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeSymbol
import org.jetbrains.kotlin.fir.symbols.ConeSymbol
import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterSymbol
import org.jetbrains.kotlin.fir.symbols.*
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.impl.*
import org.jetbrains.kotlin.types.Variance
@@ -42,23 +40,19 @@ class FirTypeResolverImpl : FirTypeResolver {
}
private fun ConeSymbol.toConeKotlinType(parts: List<FirQualifierPart>, session: FirSession): ConeKotlinType? {
val firProvider = FirProvider.getInstance(session)
val fir = firProvider.getFirClassifierBySymbol(this) ?: return null
return when (fir) {
is FirTypeParameter -> {
ConeTypeParameterTypeImpl(this as ConeTypeParameterSymbol)
}
is FirClass -> {
ConeClassTypeImpl(this as ConeClassLikeSymbol, parts.toTypeProjections())
}
is FirTypeAlias -> {
val coneTypeSafe = fir.expandedType.coneTypeSafe<ConeClassLikeType>()
val expansion = coneTypeSafe ?: return ConeKotlinErrorType("Couldn't resolve expansion")
return when (this) {
is ConeTypeParameterSymbol -> {
ConeTypeParameterTypeImpl(this)
}
is ConeClassSymbol -> {
ConeClassTypeImpl(this, parts.toTypeProjections())
}
is ConeTypeAliasSymbol -> {
ConeAbbreviatedTypeImpl(
abbreviationSymbol = this as ConeClassLikeSymbol,
typeArguments = parts.toTypeProjections(),
directExpansion = expansion
directExpansion = expansionType ?: ConeClassErrorType("Unresolved expansion")
)
}
else -> error("!")
@@ -7,7 +7,7 @@ package org.jetbrains.kotlin.fir.scopes.impl
import org.jetbrains.kotlin.fir.declarations.FirImport
import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedImportImpl
import org.jetbrains.kotlin.fir.resolve.FirProvider
import org.jetbrains.kotlin.fir.resolve.FirSymbolProvider
import org.jetbrains.kotlin.fir.scopes.FirPosition
import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.symbols.ConeSymbol
@@ -27,7 +27,7 @@ class FirExplicitImportingScope(imports: List<FirImport>) : FirScope {
): Boolean {
val imports = simpleImports[name] ?: return true
if (imports.isEmpty()) return true
val provider = FirProvider.getInstance(imports.first().session)
val provider = FirSymbolProvider.getInstance(imports.first().session)
for (import in imports) {
val symbol = provider.getSymbolByFqName(import.resolvedFqName) ?: continue
if (!processor(symbol)) {
@@ -8,11 +8,10 @@ package org.jetbrains.kotlin.fir.scopes.impl
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirImport
import org.jetbrains.kotlin.fir.declarations.FirResolvedImport
import org.jetbrains.kotlin.fir.resolve.FirProvider
import org.jetbrains.kotlin.fir.resolve.FirSymbolProvider
import org.jetbrains.kotlin.fir.scopes.FirPosition
import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.symbols.ConeSymbol
import org.jetbrains.kotlin.fir.symbols.FirSymbolOwner
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name
@@ -25,7 +24,7 @@ class FirStarImportingScope(imports: List<FirImport>, val session: FirSession) :
position: FirPosition,
processor: (ConeSymbol) -> Boolean
): Boolean {
val provider = FirProvider.getInstance(session)
val provider = FirSymbolProvider.getInstance(session)
for (import in starImports) {
val relativeClassName = import.relativeClassName
val classId = if (relativeClassName == null) {
@@ -0,0 +1,41 @@
/*
* 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.symbols
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.fir.deserialization.FirTypeDeserializer
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
import org.jetbrains.kotlin.metadata.ProtoBuf
import org.jetbrains.kotlin.metadata.deserialization.Flags
import org.jetbrains.kotlin.metadata.deserialization.NameResolver
import org.jetbrains.kotlin.metadata.deserialization.TypeTable
import org.jetbrains.kotlin.metadata.deserialization.supertypes
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.serialization.deserialization.ProtoEnumFlags
import org.jetbrains.kotlin.serialization.deserialization.getClassId
class LibraryClassSymbol(
val classProto: ProtoBuf.Class,
nameResolver: NameResolver,
val typeDeserializer: FirTypeDeserializer
) : ConeClassSymbol {
override val kind: ClassKind = ProtoEnumFlags.classKind(Flags.CLASS_KIND[classProto.flags])
override val typeParameters: List<ConeTypeParameterSymbol> by lazy { typeDeserializer.ownTypeParameters }
override val classId: ClassId = nameResolver.getClassId(classProto.fqName)
val typeTable = TypeTable(classProto.typeTable)
override val superTypes: List<ConeClassLikeType>
get() {
val result = classProto.supertypes(typeTable).map { supertypeProto ->
typeDeserializer.classLikeType(supertypeProto)
}// TODO: + c.components.additionalClassPartsProvider.getSupertypes(this@DeserializedClassDescriptor)
return result.filterNotNull()
}
}
@@ -0,0 +1,12 @@
/*
* 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.symbols
import org.jetbrains.kotlin.name.Name
class LibraryTypeParameterSymbol(override val name: Name) : ConeTypeParameterSymbol {
}
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.declarations
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.fir.BaseTransformedType
import org.jetbrains.kotlin.fir.symbols.FirSymbolOwner
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
import org.jetbrains.kotlin.fir.types.FirType
import org.jetbrains.kotlin.fir.visitors.FirVisitor
@@ -26,6 +27,8 @@ interface FirClass : FirDeclarationContainer, FirMemberDeclaration, FirSymbolOwn
val isData: Boolean
override val symbol: FirClassSymbol
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R =
visitor.visitClass(this, data)
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.fir.declarations.FirClass
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.fir.declarations.FirMemberPlatformStatus
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
import org.jetbrains.kotlin.fir.transformInplace
import org.jetbrains.kotlin.fir.types.FirType
import org.jetbrains.kotlin.name.Name
@@ -22,7 +23,7 @@ import org.jetbrains.kotlin.fir.visitors.FirTransformer
open class FirClassImpl(
session: FirSession,
psi: PsiElement?,
final override val symbol: FirBasedSymbol<FirClass>,
final override val symbol: FirClassSymbol,
name: Name,
visibility: Visibility,
modality: Modality?,
@@ -5,14 +5,24 @@
package org.jetbrains.kotlin.fir.symbols.impl
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.fir.declarations.FirClass
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.ConeClassSymbol
import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterSymbol
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
import org.jetbrains.kotlin.fir.types.ConeTypeParameterType
import org.jetbrains.kotlin.fir.types.coneTypeSafe
import org.jetbrains.kotlin.fir.types.coneTypeUnsafe
import org.jetbrains.kotlin.name.ClassId
class FirClassSymbol(override val classId: ClassId) : ConeClassSymbol, AbstractFirBasedSymbol<FirClass>() {
override val kind: ClassKind
get() = fir.classKind
override val superTypes: List<ConeClassLikeType>
get() = fir.superTypes.map { it.coneTypeUnsafe<ConeClassLikeType>() }
get() = fir.superTypes.mapNotNull { it.coneTypeSafe<ConeClassLikeType>() }
override val typeParameters: List<ConeTypeParameterSymbol>
get() = fir.typeParameters.map { it.symbol }
}
@@ -8,12 +8,15 @@ package org.jetbrains.kotlin.fir.symbols.impl
import org.jetbrains.kotlin.fir.declarations.FirTypeAlias
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.ConeTypeAliasSymbol
import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterSymbol
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
import org.jetbrains.kotlin.fir.types.coneTypeUnsafe
import org.jetbrains.kotlin.fir.types.coneTypeSafe
import org.jetbrains.kotlin.name.ClassId
class FirTypeAliasSymbol(override val classId: ClassId) : ConeTypeAliasSymbol, AbstractFirBasedSymbol<FirTypeAlias>() {
override val expansionType: ConeClassLikeType
get() = fir.expandedType.coneTypeUnsafe()
override val typeParameters: List<ConeTypeParameterSymbol>
get() = fir.typeParameters.map { it.symbol }
override val expansionType: ConeClassLikeType?
get() = fir.expandedType.coneTypeSafe()
}
@@ -8,5 +8,9 @@ package org.jetbrains.kotlin.fir.symbols.impl
import org.jetbrains.kotlin.fir.declarations.FirTypeParameter
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterSymbol
import org.jetbrains.kotlin.name.Name
class FirTypeParameterSymbol : AbstractFirBasedSymbol<FirTypeParameter>(), ConeTypeParameterSymbol
class FirTypeParameterSymbol : AbstractFirBasedSymbol<FirTypeParameter>(), ConeTypeParameterSymbol {
override val name: Name
get() = fir.name
}
+8
View File
@@ -0,0 +1,8 @@
import kotlin.*
import kotlin.collections.*
abstract class MyStringList : List<String>
abstract class MyMutableStringList : MutableList<String>
fun List<String>.convert(): MyStringList = this as MyStringList
fun ret(l: MutableList<String>): MyMutableStringList = this as MyMutableStringList
+11
View File
@@ -0,0 +1,11 @@
FILE: lists.kt
(resolved) public? abstract class MyStringList() : R/kotlin/collections/List<kotlin/String>/ {
}
(resolved) public? abstract class MyMutableStringList() : R/kotlin/collections/MutableList<kotlin/String>/ {
}
public? final? function convertR/kotlin/collections/List<kotlin/String>/.(): R/MyStringList/ {
STUB
}
public? final? function ret(l: R/kotlin/collections/MutableList<kotlin/String>/): R/MyMutableStringList/ {
STUB
}
+2
View File
@@ -1,3 +1,5 @@
import kotlin.*
interface SomeInterface {
fun foo(x: Int, y: String): String
+9 -9
View File
@@ -1,27 +1,27 @@
FILE: simpleClass.kt
(resolved) public? abstract interface SomeInterface() {
public? final? function foo(x: R/error: Symbol not found/, y: R/error: Symbol not found/): R/error: Symbol not found/
public? final? function foo(x: R/kotlin/Int/, y: R/kotlin/String/): R/kotlin/String/
public? final? property bar(val): R/error: Symbol not found/
public? get(): R/error: Symbol not found/
public? final? property bar(val): R/kotlin/Boolean/
public? get(): R/kotlin/Boolean/
}
(resolved) public? final class SomeClass() : R/SomeInterface/ {
private final? property baz(val): R/error: Not supported: FirImplicitTypeImpl/ = STUB
public? get(): R/error: Not supported: FirImplicitTypeImpl/
public? open? override function foo(x: R/error: Symbol not found/, y: R/error: Symbol not found/): R/error: Symbol not found/ {
public? open? override function foo(x: R/kotlin/Int/, y: R/kotlin/String/): R/kotlin/String/ {
}
public? open? override property bar(var): R/error: Symbol not found/
public? open? override property bar(var): R/kotlin/Boolean/
public? get(): R/error: Not supported: FirImplicitTypeImpl/ {
STUB
}
public? set(value: R/error: Symbol not found/): R/error: Not supported: FirImplicitTypeImpl/ {
public? set(value: R/kotlin/Boolean/): R/error: Not supported: FirImplicitTypeImpl/ {
}
public? final? property fau(var): R/error: Symbol not found/
public? get(): R/error: Symbol not found/
public? set(value: R/error: Symbol not found/): R/kotlin/Unit/
public? final? property fau(var): R/kotlin/Double/
public? get(): R/kotlin/Double/
public? set(value: R/kotlin/Double/): R/kotlin/Unit/
}
@@ -11,29 +11,22 @@ import org.jetbrains.kotlin.fir.builder.RawFirBuilder
import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.resolve.FirProvider
import org.jetbrains.kotlin.fir.resolve.FirQualifierResolver
import org.jetbrains.kotlin.fir.resolve.FirSymbolProvider
import org.jetbrains.kotlin.fir.resolve.FirTypeResolver
import org.jetbrains.kotlin.fir.resolve.impl.FirProviderImpl
import org.jetbrains.kotlin.fir.resolve.impl.FirQualifierResolverImpl
import org.jetbrains.kotlin.fir.resolve.impl.FirTypeResolverImpl
import org.jetbrains.kotlin.fir.resolve.impl.*
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.test.ConfigurationKind
import org.jetbrains.kotlin.test.KotlinTestUtils
import org.jetbrains.kotlin.test.KotlinTestWithEnvironment
import java.io.File
abstract class AbstractFirResolveTestCase : KotlinTestWithEnvironment() {
abstract class AbstractFirResolveTestCase : AbstractFirResolveWithSessionTestCase() {
override fun createEnvironment(): KotlinCoreEnvironment {
return createEnvironmentWithMockJdk(ConfigurationKind.JDK_NO_RUNTIME)
}
fun doCreateAndProcessFir(ktFiles: List<KtFile>): List<FirFile> {
val session = object : FirSessionBase() {
init {
registerComponent(FirProvider::class, FirProviderImpl(this))
registerComponent(FirQualifierResolver::class, FirQualifierResolverImpl(this))
registerComponent(FirTypeResolver::class, FirTypeResolverImpl())
}
}
val session = createSession()
val builder = RawFirBuilder(session)
@@ -43,7 +36,12 @@ abstract class AbstractFirResolveTestCase : KotlinTestWithEnvironment() {
(session.service<FirProvider>() as FirProviderImpl).recordFile(firFile)
firFile
}.also {
transformer.processFiles(it)
try {
transformer.processFiles(it)
} catch (e: Exception) {
it.forEach { println(it.render()) }
throw e
}
}
return firFiles
@@ -0,0 +1,31 @@
/*
* 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
import org.jetbrains.kotlin.fir.resolve.FirProvider
import org.jetbrains.kotlin.fir.resolve.FirQualifierResolver
import org.jetbrains.kotlin.fir.resolve.FirSymbolProvider
import org.jetbrains.kotlin.fir.resolve.FirTypeResolver
import org.jetbrains.kotlin.fir.resolve.impl.*
import org.jetbrains.kotlin.test.KotlinTestWithEnvironment
abstract class AbstractFirResolveWithSessionTestCase : KotlinTestWithEnvironment() {
fun createSession(): FirSession {
return object : FirSessionBase() {
init {
val firProvider = FirProviderImpl(this)
registerComponent(FirProvider::class, firProvider)
registerComponent(
FirSymbolProvider::class,
FirCompositeSymbolProvider(listOf(firProvider, FirLibrarySymbolProviderImpl(this)))
)
registerComponent(FirQualifierResolver::class, FirQualifierResolverImpl(this))
registerComponent(FirTypeResolver::class, FirTypeResolverImpl())
}
}
}
}
@@ -85,6 +85,21 @@ public class FirResolveTestCaseGenerated extends AbstractFirResolveTestCase {
doTest(fileName);
}
@TestMetadata("compiler/testData/fir/resolve/builtins")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class Builtins extends AbstractFirResolveTestCase {
public void testAllFilesPresentInBuiltins() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/fir/resolve/builtins"), Pattern.compile("^([^.]+)\\.kt$"), TargetBackend.ANY, true);
}
@TestMetadata("lists.kt")
public void testLists() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/fir/resolve/builtins/lists.kt");
doTest(fileName);
}
}
@TestMetadata("compiler/testData/fir/resolve/multifile")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
@@ -33,7 +33,7 @@ class ProtoBasedClassDataFinder(
nameResolver.getClassId(klass.fqName)
}
internal val allClassIds: Collection<ClassId> get() = classIdToProto.keys
val allClassIds: Collection<ClassId> get() = classIdToProto.keys
override fun findClassData(classId: ClassId): ClassData? {
val classProto = classIdToProto[classId] ?: return null