FIR: do not allow to resolve to type parameters in supertype position

This commit is contained in:
Mikhail Glukhikh
2018-03-22 09:33:43 +03:00
parent e46074dee6
commit d16303342e
12 changed files with 88 additions and 45 deletions
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.render
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.transformSingle
@@ -33,7 +34,6 @@ class FirTypeResolveTransformer(val superTypesOnly: Boolean = false) : FirTransf
lateinit var scope: FirCompositeScope
lateinit var packageFqName: FqName
lateinit var file: FirFile
private var classLikeName: FqName = FqName.ROOT
override fun transformFile(file: FirFile, data: Nothing?): CompositeTransformResult<FirFile> {
@@ -44,7 +44,6 @@ class FirTypeResolveTransformer(val superTypesOnly: Boolean = false) : FirTransf
)
)
packageFqName = file.packageFqName
this.file = file
return super.transformFile(file, data)
}
@@ -105,7 +104,7 @@ class FirTypeResolveTransformer(val superTypesOnly: Boolean = false) : FirTransf
override fun transformType(type: FirType, data: Nothing?): CompositeTransformResult<FirType> {
val typeResolver = FirTypeResolver.getInstance(type.session)
type.transformChildren(this, null)
return transformType(type, typeResolver.resolveType(type, scope))
return transformType(type, typeResolver.resolveType(type, scope, position = FirPosition.OTHER))
}
private fun transformType(type: FirType, resolvedType: ConeKotlinType): CompositeTransformResult<FirType> {
@@ -138,7 +137,7 @@ class FirTypeResolveTransformer(val superTypesOnly: Boolean = false) : FirTransf
override fun transformType(type: FirType, data: Nothing?): CompositeTransformResult<FirType> {
val typeResolver = FirTypeResolver.getInstance(type.session)
val symbol = typeResolver.resolveToSymbol(type, scope)
val symbol = typeResolver.resolveToSymbol(type, scope, position = FirPosition.SUPER_TYPE_OR_EXPANSION)
val myTransformer = this@FirTypeResolveTransformer
if (type !is FirUserType) return myTransformer.transformType(type, data)
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.fir.resolve
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.scopes.FirPosition
import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.service
import org.jetbrains.kotlin.fir.symbols.ConeSymbol
@@ -15,8 +16,8 @@ import org.jetbrains.kotlin.fir.types.FirUserType
interface FirTypeResolver {
fun resolveType(type: FirType, scope: FirScope): ConeKotlinType
fun resolveToSymbol(type: FirType, scope: FirScope): ConeSymbol?
fun resolveType(type: FirType, scope: FirScope, position: FirPosition): ConeKotlinType
fun resolveToSymbol(type: FirType, scope: FirScope, position: FirPosition): ConeSymbol?
companion object {
fun getInstance(session: FirSession): FirTypeResolver = session.service()
@@ -9,10 +9,10 @@ import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirClass
import org.jetbrains.kotlin.fir.declarations.FirTypeAlias
import org.jetbrains.kotlin.fir.declarations.FirTypeParameter
import org.jetbrains.kotlin.fir.render
import org.jetbrains.kotlin.fir.resolve.FirProvider
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
@@ -53,9 +53,7 @@ class FirTypeResolverImpl : FirTypeResolver {
}
is FirTypeAlias -> {
val coneTypeSafe = fir.expandedType.coneTypeSafe<ConeClassLikeType>()
val expansion = if (coneTypeSafe != null) coneTypeSafe else {
return ConeKotlinErrorType("Couldn't resolve expansion")
}
val expansion = coneTypeSafe ?: return ConeKotlinErrorType("Couldn't resolve expansion")
ConeAbbreviatedTypeImpl(
abbreviationSymbol = this as ConeClassLikeSymbol,
@@ -67,7 +65,11 @@ class FirTypeResolverImpl : FirTypeResolver {
}
}
override fun resolveToSymbol(type: FirType, scope: FirScope): ConeSymbol? {
override fun resolveToSymbol(
type: FirType,
scope: FirScope,
position: FirPosition
): ConeSymbol? {
return when (type) {
is FirResolvedType -> type.coneTypeSafe<ConeSymbolBasedType>()?.symbol
is FirUserType -> {
@@ -75,7 +77,7 @@ class FirTypeResolverImpl : FirTypeResolver {
val qualifierResolver = FirQualifierResolver.getInstance(type.session)
var resolvedSymbol: ConeSymbol? = null
scope.processClassifiersByName(type.qualifier.first().name) { symbol ->
scope.processClassifiersByName(type.qualifier.first().name, position) { symbol ->
resolvedSymbol = when (symbol) {
is ConeClassLikeSymbol -> {
qualifierResolver.resolveSymbolWithPrefix(type.qualifier, symbol.classId)
@@ -101,11 +103,15 @@ class FirTypeResolverImpl : FirTypeResolver {
return symbol.toConeKotlinType(type.qualifier, type.session) ?: ConeKotlinErrorType("Failed to resolve qualified type")
}
override fun resolveType(type: FirType, scope: FirScope): ConeKotlinType {
override fun resolveType(
type: FirType,
scope: FirScope,
position: FirPosition
): ConeKotlinType {
return when (type) {
is FirResolvedType -> type.type
is FirUserType -> {
resolveUserType(type, resolveToSymbol(type, scope), scope)
resolveUserType(type, resolveToSymbol(type, scope, position), scope)
}
is FirErrorType -> {
ConeKotlinErrorType(type.reason)
@@ -9,5 +9,14 @@ import org.jetbrains.kotlin.fir.symbols.ConeSymbol
import org.jetbrains.kotlin.name.Name
interface FirScope {
fun processClassifiersByName(name: Name, processor: (ConeSymbol) -> Boolean): Boolean
fun processClassifiersByName(
name: Name,
position: FirPosition,
processor: (ConeSymbol) -> Boolean
): Boolean
}
enum class FirPosition(val allowTypeParameters: Boolean = true) {
SUPER_TYPE_OR_EXPANSION(allowTypeParameters = false),
OTHER
}
@@ -0,0 +1,24 @@
/*
* 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.declarations.FirTypeParameter
import org.jetbrains.kotlin.fir.symbols.ConeSymbol
import org.jetbrains.kotlin.name.Name
interface FirTypeParameterScope : FirScope {
val typeParameters: Map<Name, List<FirTypeParameter>>
override fun processClassifiersByName(
name: Name,
position: FirPosition,
processor: (ConeSymbol) -> Boolean
): Boolean {
val matchedTypeParameters = typeParameters[name] ?: return true
return matchedTypeParameters.all { processor(it.symbol) }
}
}
@@ -6,17 +6,8 @@
package org.jetbrains.kotlin.fir.scopes.impl
import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration
import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.symbols.ConeSymbol
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.fir.scopes.FirTypeParameterScope
class FirClassLikeTypeParameterScope(classLike: FirMemberDeclaration) : FirScope {
val typeParameters = classLike.typeParameters.groupBy { it.name }
override fun processClassifiersByName(name: Name, processor: (ConeSymbol) -> Boolean): Boolean {
val matchedTypeParameters = typeParameters[name] ?: return true
return matchedTypeParameters.all { processor(it.symbol) }
}
class FirClassLikeTypeParameterScope(classLike: FirMemberDeclaration) : FirTypeParameterScope {
override val typeParameters = classLike.typeParameters.groupBy { it.name }
}
@@ -5,14 +5,21 @@
package org.jetbrains.kotlin.fir.scopes.impl
import org.jetbrains.kotlin.fir.scopes.FirPosition
import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.scopes.FirTypeParameterScope
import org.jetbrains.kotlin.fir.symbols.ConeSymbol
import org.jetbrains.kotlin.name.Name
class FirCompositeScope(val scopes: MutableList<FirScope>) : FirScope {
override fun processClassifiersByName(name: Name, processor: (ConeSymbol) -> Boolean): Boolean {
override fun processClassifiersByName(
name: Name,
position: FirPosition,
processor: (ConeSymbol) -> Boolean
): Boolean {
for (scope in scopes) {
if (!scope.processClassifiersByName(name, processor)) {
if (!position.allowTypeParameters && scope is FirTypeParameterScope) continue
if (!scope.processClassifiersByName(name, position, processor)) {
return false
}
}
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.fir.scopes.impl
import org.jetbrains.kotlin.fir.declarations.FirImport
import org.jetbrains.kotlin.fir.declarations.FirResolvedImport
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.toSymbol
@@ -20,7 +21,11 @@ class FirExplicitImportingScope(imports: List<FirImport>) : FirScope {
.filter { !it.isAllUnder }
.groupBy { it.aliasName ?: it.resolvedFqName.shortClassName }
override fun processClassifiersByName(name: Name, processor: (ConeSymbol) -> Boolean): Boolean {
override fun processClassifiersByName(
name: Name,
position: FirPosition,
processor: (ConeSymbol) -> Boolean
): Boolean {
val imports = simpleImports[name] ?: return true
for (import in imports) {
if (!processor(import.resolvedFqName.toSymbol())) {
@@ -6,17 +6,8 @@
package org.jetbrains.kotlin.fir.scopes.impl
import org.jetbrains.kotlin.fir.declarations.FirNamedFunction
import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.symbols.ConeSymbol
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.fir.scopes.FirTypeParameterScope
class FirFunctionTypeParameterScope(function: FirNamedFunction) : FirScope {
val typeParameters = function.typeParameters.groupBy { it.name }
override fun processClassifiersByName(name: Name, processor: (ConeSymbol) -> Boolean): Boolean {
val matchedTypeParameters = typeParameters[name] ?: return true
return matchedTypeParameters.all { processor(it.symbol) }
}
class FirFunctionTypeParameterScope(function: FirNamedFunction) : FirTypeParameterScope {
override val typeParameters = function.typeParameters.groupBy { it.name }
}
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.scopes.impl
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration
import org.jetbrains.kotlin.fir.resolve.FirProvider
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.toSymbol
@@ -22,7 +23,11 @@ class FirNestedClassifierScope(val classId: ClassId, val session: FirSession) :
return firProvider.getFirClassifierByFqName(this)
}
override fun processClassifiersByName(name: Name, processor: (ConeSymbol) -> Boolean): Boolean {
override fun processClassifiersByName(
name: Name,
position: FirPosition,
processor: (ConeSymbol) -> Boolean
): Boolean {
val child = ClassId(classId.packageFqName, classId.relativeClassName.child(name), false)
return child.getFir() == null || processor(child.toSymbol())
}
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.fir.scopes.impl
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.resolve.FirProvider
import org.jetbrains.kotlin.fir.scopes.FirPosition
import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.service
import org.jetbrains.kotlin.fir.symbols.ConeSymbol
@@ -16,7 +17,11 @@ import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
class FirSelfImportingScope(val fqName: FqName, val session: FirSession) : FirScope {
override fun processClassifiersByName(name: Name, processor: (ConeSymbol) -> Boolean): Boolean {
override fun processClassifiersByName(
name: Name,
position: FirPosition,
processor: (ConeSymbol) -> Boolean
): Boolean {
val unambiguousFqName = ClassId(fqName, name)
val firProvider = session.service<FirProvider>()
+1 -1
View File
@@ -16,7 +16,7 @@ FILE: typeParameterVsNested.kt
public? abstract property z(val): R/test/My.T/
public? get(): R/test/My.T/
(resolved) public? final class Some() : R/T/ {
(resolved) public? final class Some() : R/test/My.T/ {
}
}