FIR: introduce FIR importing scopes #KT-24096 Fixed
This commit is contained in:
committed by
Mikhail Glukhikh
parent
e6cd07b46e
commit
8933c9035b
+17
-1
@@ -13,6 +13,10 @@ import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedClassImpl
|
|||||||
import org.jetbrains.kotlin.fir.descriptors.ConeClassifierDescriptor
|
import org.jetbrains.kotlin.fir.descriptors.ConeClassifierDescriptor
|
||||||
import org.jetbrains.kotlin.fir.descriptors.ConeTypeParameterDescriptor
|
import org.jetbrains.kotlin.fir.descriptors.ConeTypeParameterDescriptor
|
||||||
import org.jetbrains.kotlin.fir.resolve.FirTypeResolver
|
import org.jetbrains.kotlin.fir.resolve.FirTypeResolver
|
||||||
|
import org.jetbrains.kotlin.fir.scopes.FirImportingScope
|
||||||
|
import org.jetbrains.kotlin.fir.scopes.impl.FirCompositeImportingScope
|
||||||
|
import org.jetbrains.kotlin.fir.scopes.impl.FirExplicitImportingScope
|
||||||
|
import org.jetbrains.kotlin.fir.scopes.impl.FirSelfImportingScope
|
||||||
import org.jetbrains.kotlin.fir.types.FirResolvedType
|
import org.jetbrains.kotlin.fir.types.FirResolvedType
|
||||||
import org.jetbrains.kotlin.fir.types.FirType
|
import org.jetbrains.kotlin.fir.types.FirType
|
||||||
import org.jetbrains.kotlin.fir.types.impl.FirResolvedTypeImpl
|
import org.jetbrains.kotlin.fir.types.impl.FirResolvedTypeImpl
|
||||||
@@ -29,15 +33,27 @@ class FirClassifierResolveTransformer : FirTransformer<Nothing?>() {
|
|||||||
|
|
||||||
lateinit var packageFqName: FqNameUnsafe
|
lateinit var packageFqName: FqNameUnsafe
|
||||||
|
|
||||||
|
lateinit var importingScope: FirImportingScope
|
||||||
|
|
||||||
override fun transformFile(file: FirFile, data: Nothing?): CompositeTransformResult<FirFile> {
|
override fun transformFile(file: FirFile, data: Nothing?): CompositeTransformResult<FirFile> {
|
||||||
packageFqName = file.packageFqName.toUnsafe()
|
packageFqName = file.packageFqName.toUnsafe()
|
||||||
|
importingScope = FirCompositeImportingScope(
|
||||||
|
FirExplicitImportingScope(file.imports),
|
||||||
|
FirSelfImportingScope(file.packageFqName.toUnsafe(), file.session)
|
||||||
|
)
|
||||||
return file.also { it.acceptChildren(this, null) }.compose()
|
return file.also { it.acceptChildren(this, null) }.compose()
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Extract to separate transformer?
|
// TODO: Extract to separate transformer?
|
||||||
override fun transformType(type: FirType, data: Nothing?): CompositeTransformResult<FirType> {
|
override fun transformType(type: FirType, data: Nothing?): CompositeTransformResult<FirType> {
|
||||||
val typeResolver = FirTypeResolver.getInstance(type.session)
|
val typeResolver = FirTypeResolver.getInstance(type.session)
|
||||||
return FirResolvedTypeImpl(type.session, type.psi, typeResolver.resolveType(type), false, type.annotations).compose()
|
return FirResolvedTypeImpl(
|
||||||
|
type.session,
|
||||||
|
type.psi,
|
||||||
|
typeResolver.resolveType(type, importingScope),
|
||||||
|
false,
|
||||||
|
type.annotations
|
||||||
|
).compose()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun transformResolvedType(resolvedType: FirResolvedType, data: Nothing?): CompositeTransformResult<FirType> {
|
override fun transformResolvedType(resolvedType: FirResolvedType, data: Nothing?): CompositeTransformResult<FirType> {
|
||||||
|
|||||||
@@ -6,14 +6,19 @@
|
|||||||
package org.jetbrains.kotlin.fir.resolve
|
package org.jetbrains.kotlin.fir.resolve
|
||||||
|
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
|
import org.jetbrains.kotlin.fir.UnambiguousFqName
|
||||||
import org.jetbrains.kotlin.fir.service
|
import org.jetbrains.kotlin.fir.service
|
||||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||||
import org.jetbrains.kotlin.fir.types.FirQualifierPart
|
import org.jetbrains.kotlin.fir.types.FirQualifierPart
|
||||||
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
|
||||||
interface FirQualifierResolver {
|
interface FirQualifierResolver {
|
||||||
|
fun resolveTypeWithPrefix(parts: List<FirQualifierPart>, prefix: UnambiguousFqName): ConeKotlinType?
|
||||||
|
|
||||||
fun resolveType(parts: List<FirQualifierPart>): ConeKotlinType?
|
fun resolveType(parts: List<FirQualifierPart>): ConeKotlinType?
|
||||||
|
|
||||||
|
fun resolveImport(fqName: FqName): UnambiguousFqName?
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun getInstance(session: FirSession): FirQualifierResolver = session.service()
|
fun getInstance(session: FirSession): FirQualifierResolver = session.service()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,61 +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.resolve
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
|
||||||
import org.jetbrains.kotlin.fir.UnambiguousFqName
|
|
||||||
import org.jetbrains.kotlin.fir.types.*
|
|
||||||
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.name.FqName
|
|
||||||
import org.jetbrains.kotlin.types.Variance
|
|
||||||
|
|
||||||
class FirQualifierResolverImpl(val session: FirSession) : FirQualifierResolver {
|
|
||||||
override fun resolveType(parts: List<FirQualifierPart>): ConeKotlinType? {
|
|
||||||
val firProvider = FirProvider.getInstance(session)
|
|
||||||
|
|
||||||
if (parts.isNotEmpty()) {
|
|
||||||
val lastPart = mutableListOf<FirQualifierPart>()
|
|
||||||
val firstPart = parts.toMutableList()
|
|
||||||
|
|
||||||
while (firstPart.isNotEmpty()) {
|
|
||||||
lastPart.add(0, firstPart.last())
|
|
||||||
firstPart.removeAt(firstPart.lastIndex)
|
|
||||||
|
|
||||||
val fqName = UnambiguousFqName(firstPart.toFqNameUnsafe(), lastPart.toFqName())
|
|
||||||
val foundClassifier = firProvider.getFirClassifierByFqName(fqName)
|
|
||||||
|
|
||||||
if (foundClassifier != null) {
|
|
||||||
return ConeClassTypeImpl(fqName, parts.flatMap {
|
|
||||||
it.typeArguments.map {
|
|
||||||
when (it) {
|
|
||||||
is FirStarProjection -> StarProjection
|
|
||||||
is FirTypeProjectionWithVariance -> {
|
|
||||||
val type = (it.type as FirResolvedType).type
|
|
||||||
when (it.variance) {
|
|
||||||
Variance.INVARIANT -> type
|
|
||||||
Variance.IN_VARIANCE -> ConeKotlinTypeProjectionInImpl(type)
|
|
||||||
Variance.OUT_VARIANCE -> ConeKotlinTypeProjectionOutImpl(type)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else -> error("!")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null
|
|
||||||
} else {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun List<FirQualifierPart>.toFqNameUnsafe() = toFqName().toUnsafe()
|
|
||||||
private fun List<FirQualifierPart>.toFqName() = fold(FqName.ROOT) { a, b -> a.child(b.name) }
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -6,13 +6,14 @@
|
|||||||
package org.jetbrains.kotlin.fir.resolve
|
package org.jetbrains.kotlin.fir.resolve
|
||||||
|
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
|
import org.jetbrains.kotlin.fir.scopes.FirImportingScope
|
||||||
import org.jetbrains.kotlin.fir.service
|
import org.jetbrains.kotlin.fir.service
|
||||||
import org.jetbrains.kotlin.fir.types.FirType
|
import org.jetbrains.kotlin.fir.types.FirType
|
||||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||||
|
|
||||||
interface FirTypeResolver {
|
interface FirTypeResolver {
|
||||||
|
|
||||||
fun resolveType(type: FirType): ConeKotlinType
|
fun resolveType(type: FirType, importingScope: FirImportingScope): ConeKotlinType
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun getInstance(session: FirSession): FirTypeResolver = session.service()
|
fun getInstance(session: FirSession): FirTypeResolver = session.service()
|
||||||
|
|||||||
+103
@@ -0,0 +1,103 @@
|
|||||||
|
/*
|
||||||
|
* 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.FirSession
|
||||||
|
import org.jetbrains.kotlin.fir.UnambiguousFqName
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.FirProvider
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.FirQualifierResolver
|
||||||
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
|
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.name.FqName
|
||||||
|
import org.jetbrains.kotlin.types.Variance
|
||||||
|
|
||||||
|
class FirQualifierResolverImpl(val session: FirSession) : FirQualifierResolver {
|
||||||
|
|
||||||
|
private fun FirMemberDeclaration.toConeKotlinType(fqName: UnambiguousFqName, parts: List<FirQualifierPart>): ConeKotlinType? {
|
||||||
|
return ConeClassTypeImpl(fqName, parts.flatMap {
|
||||||
|
it.typeArguments.map {
|
||||||
|
when (it) {
|
||||||
|
is FirStarProjection -> StarProjection
|
||||||
|
is FirTypeProjectionWithVariance -> {
|
||||||
|
val type = (it.type as FirResolvedType).type
|
||||||
|
when (it.variance) {
|
||||||
|
Variance.INVARIANT -> type
|
||||||
|
Variance.IN_VARIANCE -> ConeKotlinTypeProjectionInImpl(type)
|
||||||
|
Variance.OUT_VARIANCE -> ConeKotlinTypeProjectionOutImpl(type)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else -> error("!")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun resolveTypeWithPrefix(parts: List<FirQualifierPart>, prefix: UnambiguousFqName): ConeKotlinType? {
|
||||||
|
val firProvider = FirProvider.getInstance(session)
|
||||||
|
|
||||||
|
val fqName = UnambiguousFqName(prefix.packageFqName, parts.fold(prefix.classFqName) { prefix, suffix -> prefix.child(suffix.name) })
|
||||||
|
val foundClassifier = firProvider.getFirClassifierByFqName(fqName)
|
||||||
|
|
||||||
|
return foundClassifier?.toConeKotlinType(fqName, parts)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun resolveType(parts: List<FirQualifierPart>): ConeKotlinType? {
|
||||||
|
val firProvider = FirProvider.getInstance(session)
|
||||||
|
|
||||||
|
if (parts.isNotEmpty()) {
|
||||||
|
val lastPart = mutableListOf<FirQualifierPart>()
|
||||||
|
val firstPart = parts.toMutableList()
|
||||||
|
|
||||||
|
while (firstPart.isNotEmpty()) {
|
||||||
|
lastPart.add(0, firstPart.last())
|
||||||
|
firstPart.removeAt(firstPart.lastIndex)
|
||||||
|
|
||||||
|
val fqName = UnambiguousFqName(firstPart.toFqNameUnsafe(), lastPart.toFqName())
|
||||||
|
val foundClassifier = firProvider.getFirClassifierByFqName(fqName)
|
||||||
|
|
||||||
|
if (foundClassifier != null) {
|
||||||
|
return foundClassifier.toConeKotlinType(fqName, parts)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
} else {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: extract common part from resolveType/Import
|
||||||
|
override fun resolveImport(fqName: FqName): UnambiguousFqName? {
|
||||||
|
val firProvider = FirProvider.getInstance(session)
|
||||||
|
|
||||||
|
if (!fqName.isRoot) {
|
||||||
|
val lastPart = mutableListOf<String>()
|
||||||
|
var firstPart = fqName
|
||||||
|
|
||||||
|
while (!firstPart.isRoot) {
|
||||||
|
lastPart.add(0, firstPart.shortName().asString())
|
||||||
|
firstPart = firstPart.parent()
|
||||||
|
|
||||||
|
val fqName = UnambiguousFqName(firstPart.toUnsafe(), FqName.fromSegments(lastPart))
|
||||||
|
val foundClassifier = firProvider.getFirClassifierByFqName(fqName)
|
||||||
|
|
||||||
|
if (foundClassifier != null) {
|
||||||
|
return fqName
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
} else {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun List<FirQualifierPart>.toFqNameUnsafe() = toFqName().toUnsafe()
|
||||||
|
private fun List<FirQualifierPart>.toFqName() = fold(FqName.ROOT) { a, b -> a.child(b.name) }
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
+11
-2
@@ -7,17 +7,26 @@ package org.jetbrains.kotlin.fir.resolve.impl
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.fir.resolve.FirQualifierResolver
|
import org.jetbrains.kotlin.fir.resolve.FirQualifierResolver
|
||||||
import org.jetbrains.kotlin.fir.resolve.FirTypeResolver
|
import org.jetbrains.kotlin.fir.resolve.FirTypeResolver
|
||||||
|
import org.jetbrains.kotlin.fir.scopes.FirImportingScope
|
||||||
import org.jetbrains.kotlin.fir.types.*
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
import org.jetbrains.kotlin.fir.types.impl.ConeKotlinErrorType
|
import org.jetbrains.kotlin.fir.types.impl.ConeKotlinErrorType
|
||||||
|
|
||||||
class FirTypeResolverImpl : FirTypeResolver {
|
class FirTypeResolverImpl : FirTypeResolver {
|
||||||
override fun resolveType(type: FirType): ConeKotlinType {
|
override fun resolveType(type: FirType, importingScope: FirImportingScope): ConeKotlinType {
|
||||||
return when (type) {
|
return when (type) {
|
||||||
is FirResolvedType -> type.type
|
is FirResolvedType -> type.type
|
||||||
is FirUserType -> {
|
is FirUserType -> {
|
||||||
|
|
||||||
val qualifierResolver = FirQualifierResolver.getInstance(type.session)
|
val qualifierResolver = FirQualifierResolver.getInstance(type.session)
|
||||||
|
|
||||||
|
var resolvedType: ConeKotlinType? = null
|
||||||
|
importingScope.processClassifiersByName(type.qualifier.first().name) { fqName ->
|
||||||
|
resolvedType = qualifierResolver.resolveTypeWithPrefix(type.qualifier.drop(1), fqName)
|
||||||
|
resolvedType == null
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Imports
|
// TODO: Imports
|
||||||
qualifierResolver.resolveType(type.qualifier) ?: ConeKotlinErrorType("Failed to resolve qualified type")
|
resolvedType ?: qualifierResolver.resolveType(type.qualifier) ?: ConeKotlinErrorType("Failed to resolve qualified type")
|
||||||
}
|
}
|
||||||
is FirErrorType -> {
|
is FirErrorType -> {
|
||||||
ConeKotlinErrorType(type.reason)
|
ConeKotlinErrorType(type.reason)
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
/*
|
||||||
|
* 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.scopes
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.fir.UnambiguousFqName
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
|
||||||
|
interface FirImportingScope {
|
||||||
|
fun processClassifiersByName(name: Name, processor: (UnambiguousFqName) -> Boolean): Boolean
|
||||||
|
}
|
||||||
+21
@@ -0,0 +1,21 @@
|
|||||||
|
/*
|
||||||
|
* 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.scopes.impl
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.fir.UnambiguousFqName
|
||||||
|
import org.jetbrains.kotlin.fir.scopes.FirImportingScope
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
|
||||||
|
class FirCompositeImportingScope(vararg val scopes: FirImportingScope) : FirImportingScope {
|
||||||
|
override fun processClassifiersByName(name: Name, processor: (UnambiguousFqName) -> Boolean): Boolean {
|
||||||
|
for (scope in scopes) {
|
||||||
|
if (!scope.processClassifiersByName(name, processor)) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
+38
@@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* 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.scopes.impl
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.fir.UnambiguousFqName
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.FirImport
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.FirQualifierResolver
|
||||||
|
import org.jetbrains.kotlin.fir.scopes.FirImportingScope
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
|
||||||
|
class FirExplicitImportingScope(imports: List<FirImport>) : FirImportingScope {
|
||||||
|
|
||||||
|
// TODO: Resolve imports! Instead of computing it resolution results here
|
||||||
|
private val simpleImports =
|
||||||
|
imports.filter { !it.isAllUnder && it.aliasName == null && it.importedFqName != null }
|
||||||
|
.mapNotNull { it.resolve() }
|
||||||
|
.groupBy { it.classFqName.shortName() }
|
||||||
|
|
||||||
|
private fun FirImport.resolve(): UnambiguousFqName? {
|
||||||
|
val session = session
|
||||||
|
val qualifierResolver = FirQualifierResolver.getInstance(session)
|
||||||
|
return qualifierResolver.resolveImport(importedFqName!!)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun processClassifiersByName(name: Name, processor: (UnambiguousFqName) -> Boolean): Boolean {
|
||||||
|
val imports = simpleImports[name] ?: return true
|
||||||
|
for (import in imports) {
|
||||||
|
if (!processor(import)) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+32
@@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* 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.scopes.impl
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
|
import org.jetbrains.kotlin.fir.UnambiguousFqName
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.FirProvider
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.FirQualifierResolver
|
||||||
|
import org.jetbrains.kotlin.fir.scopes.FirImportingScope
|
||||||
|
import org.jetbrains.kotlin.fir.service
|
||||||
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
import org.jetbrains.kotlin.name.FqNameUnsafe
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
|
||||||
|
class FirSelfImportingScope(val fqName: FqNameUnsafe, val session: FirSession) : FirImportingScope {
|
||||||
|
override fun processClassifiersByName(name: Name, processor: (UnambiguousFqName) -> Boolean): Boolean {
|
||||||
|
|
||||||
|
|
||||||
|
val unambiguousFqName = UnambiguousFqName(fqName, FqName.topLevel(name))
|
||||||
|
|
||||||
|
val firProvider = session.service<FirProvider>()
|
||||||
|
|
||||||
|
if (firProvider.getFirClassifierByFqName(unambiguousFqName) != null) {
|
||||||
|
return processor(unambiguousFqName)
|
||||||
|
} else {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package p
|
||||||
|
|
||||||
|
abstract class My {
|
||||||
|
abstract class NestedOne : My() {
|
||||||
|
abstract class NestedTwo : NestedOne() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
FILE: NestedSuperType.kt
|
||||||
|
unknown abstract class My() {
|
||||||
|
unknown abstract class NestedOne() : R/p.My/ {
|
||||||
|
unknown abstract class NestedTwo() : R/error: Failed to resolve qualified type/ {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
package p
|
||||||
|
|
||||||
|
|
||||||
|
open class A
|
||||||
|
|
||||||
|
class B : A()
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
FILE: TwoDeclarationsInSameFile.kt
|
||||||
|
unknown open class A() {
|
||||||
|
}
|
||||||
|
unknown final class B() : R/p.A/ {
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
package b
|
||||||
|
|
||||||
|
abstract class MyClass
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
package a
|
||||||
|
import b.MyClass
|
||||||
|
|
||||||
|
class YourClass : MyClass
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
FILE: simpleImport.kt
|
||||||
|
unknown final class YourClass() : R/b.MyClass/ {
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package a
|
||||||
|
|
||||||
|
class MyClass {
|
||||||
|
open class MyNested
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package b
|
||||||
|
|
||||||
|
import a.MyClass.MyNested
|
||||||
|
|
||||||
|
class YourClass : MyNested()
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
FILE: simpleImportNested.kt
|
||||||
|
unknown final class YourClass() : R/a.MyClass.MyNested/ {
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package a
|
||||||
|
|
||||||
|
class Outer {
|
||||||
|
open class Nested
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package b
|
||||||
|
|
||||||
|
import a.Outer
|
||||||
|
|
||||||
|
class My : Outer.Nested()
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
FILE: simpleImportOuter.kt
|
||||||
|
unknown final class My() : R/a.Outer.Nested/ {
|
||||||
|
}
|
||||||
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.fir.builder.RawFirBuilder
|
|||||||
import org.jetbrains.kotlin.fir.declarations.FirFile
|
import org.jetbrains.kotlin.fir.declarations.FirFile
|
||||||
import org.jetbrains.kotlin.fir.resolve.*
|
import org.jetbrains.kotlin.fir.resolve.*
|
||||||
import org.jetbrains.kotlin.fir.resolve.impl.FirProviderImpl
|
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.FirTypeResolverImpl
|
||||||
import org.jetbrains.kotlin.test.ConfigurationKind
|
import org.jetbrains.kotlin.test.ConfigurationKind
|
||||||
import org.jetbrains.kotlin.test.KotlinTestUtils
|
import org.jetbrains.kotlin.test.KotlinTestUtils
|
||||||
@@ -24,11 +25,18 @@ abstract class AbstractFirResolveTestCase : KotlinTestWithEnvironment() {
|
|||||||
|
|
||||||
fun doTest(path: String) {
|
fun doTest(path: String) {
|
||||||
val file = File(path)
|
val file = File(path)
|
||||||
val text = KotlinTestUtils.doLoadFile(file)
|
|
||||||
|
|
||||||
val ktFile = KotlinTestUtils.createFile(file.name, text, project)
|
val allFiles = listOf(file) + file.parentFile.listFiles { sibling ->
|
||||||
|
sibling.name.removePrefix(file.nameWithoutExtension).removeSuffix(file.extension).matches("\\.[0-9]+\\.".toRegex())
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
val ktFiles = allFiles.map {
|
||||||
|
val text = KotlinTestUtils.doLoadFile(it)
|
||||||
|
KotlinTestUtils.createFile(it.name, text, project)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
val session = object : FirSessionBase() {
|
val session = object : FirSessionBase() {
|
||||||
init {
|
init {
|
||||||
registerComponent(FirProvider::class, FirProviderImpl(this))
|
registerComponent(FirProvider::class, FirProviderImpl(this))
|
||||||
@@ -38,14 +46,17 @@ abstract class AbstractFirResolveTestCase : KotlinTestWithEnvironment() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val builder = RawFirBuilder(session)
|
val builder = RawFirBuilder(session)
|
||||||
val firFile = builder.buildFirFile(ktFile)
|
|
||||||
|
|
||||||
(session.service<FirProvider>() as FirProviderImpl).recordFile(firFile)
|
|
||||||
|
|
||||||
val transformer = FirClassifierResolveTransformer()
|
val transformer = FirClassifierResolveTransformer()
|
||||||
firFile.transform<FirFile, Nothing?>(transformer, null)
|
val firFiles = ktFiles.map {
|
||||||
|
val firFile = builder.buildFirFile(it)
|
||||||
|
(session.service<FirProvider>() as FirProviderImpl).recordFile(firFile)
|
||||||
|
firFile
|
||||||
|
}.onEach {
|
||||||
|
it.transform<FirFile, Nothing?>(transformer, null)
|
||||||
|
}
|
||||||
|
|
||||||
val firFileDump = StringBuilder().also { firFile.accept(FirRenderer(it), null) }.toString()
|
val firFileDump = StringBuilder().also { firFiles.first().accept(FirRenderer(it), null) }.toString()
|
||||||
val expectedPath = path.replace(".kt", ".txt")
|
val expectedPath = path.replace(".kt", ".txt")
|
||||||
KotlinTestUtils.assertEqualsToFile(File(expectedPath), firFileDump)
|
KotlinTestUtils.assertEqualsToFile(File(expectedPath), firFileDump)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ import java.util.regex.Pattern;
|
|||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
public class FirResolveTestCaseGenerated extends AbstractFirResolveTestCase {
|
public class FirResolveTestCaseGenerated extends AbstractFirResolveTestCase {
|
||||||
public void testAllFilesPresentInResolve() throws Exception {
|
public void testAllFilesPresentInResolve() throws Exception {
|
||||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/fir/resolve"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/fir/resolve"), Pattern.compile("^([^.]+)\\.kt$"), TargetBackend.ANY, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("F.kt")
|
@TestMetadata("F.kt")
|
||||||
@@ -30,4 +30,43 @@ public class FirResolveTestCaseGenerated extends AbstractFirResolveTestCase {
|
|||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/fir/resolve/F.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/fir/resolve/F.kt");
|
||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("NestedSuperType.kt")
|
||||||
|
public void testNestedSuperType() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/fir/resolve/NestedSuperType.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("TwoDeclarationsInSameFile.kt")
|
||||||
|
public void testTwoDeclarationsInSameFile() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/fir/resolve/TwoDeclarationsInSameFile.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/fir/resolve/multifile")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class Multifile extends AbstractFirResolveTestCase {
|
||||||
|
public void testAllFilesPresentInMultifile() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/fir/resolve/multifile"), Pattern.compile("^([^.]+)\\.kt$"), TargetBackend.ANY, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("simpleImport.kt")
|
||||||
|
public void testSimpleImport() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/fir/resolve/multifile/simpleImport.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("simpleImportNested.kt")
|
||||||
|
public void testSimpleImportNested() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/fir/resolve/multifile/simpleImportNested.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("simpleImportOuter.kt")
|
||||||
|
public void testSimpleImportOuter() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/fir/resolve/multifile/simpleImportOuter.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.fir.AbstractFirResolveTestCase
|
|||||||
import org.jetbrains.kotlin.fir.builder.AbstractRawFirBuilderTestCase
|
import org.jetbrains.kotlin.fir.builder.AbstractRawFirBuilderTestCase
|
||||||
import org.jetbrains.kotlin.generators.tests.generator.testGroup
|
import org.jetbrains.kotlin.generators.tests.generator.testGroup
|
||||||
import org.jetbrains.kotlin.generators.util.KT_OR_KTS_WITHOUT_DOTS_IN_NAME
|
import org.jetbrains.kotlin.generators.util.KT_OR_KTS_WITHOUT_DOTS_IN_NAME
|
||||||
|
import org.jetbrains.kotlin.generators.util.KT_WITHOUT_DOTS_IN_NAME
|
||||||
import org.jetbrains.kotlin.integration.AbstractAntTaskTest
|
import org.jetbrains.kotlin.integration.AbstractAntTaskTest
|
||||||
import org.jetbrains.kotlin.ir.AbstractIrCfgTestCase
|
import org.jetbrains.kotlin.ir.AbstractIrCfgTestCase
|
||||||
import org.jetbrains.kotlin.ir.AbstractIrJsTextTestCase
|
import org.jetbrains.kotlin.ir.AbstractIrJsTextTestCase
|
||||||
@@ -204,7 +205,7 @@ fun main(args: Array<String>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
testClass<AbstractFirResolveTestCase> {
|
testClass<AbstractFirResolveTestCase> {
|
||||||
model("fir/resolve")
|
model("fir/resolve", pattern = KT_WITHOUT_DOTS_IN_NAME)
|
||||||
}
|
}
|
||||||
|
|
||||||
testClass<AbstractBytecodeListingTest> {
|
testClass<AbstractBytecodeListingTest> {
|
||||||
|
|||||||
Reference in New Issue
Block a user