Use 'symbol' instead of 'classId' in FirResolvedQualifier

This commit solves problem with resolved qualifier of local class
#KT-36758 Fixed
This commit is contained in:
Mikhail Glukhikh
2020-02-18 14:14:13 +03:00
parent 3d51af2935
commit ace259314b
25 changed files with 47 additions and 54 deletions
@@ -1411,11 +1411,10 @@ class HtmlFirDump internal constructor(private var linkResolver: FirLinkResolver
private fun FlowContent.generate(resolvedQualifier: FirResolvedQualifier) { private fun FlowContent.generate(resolvedQualifier: FirResolvedQualifier) {
resolved { resolved {
val symbolProvider = session.firSymbolProvider val symbol = resolvedQualifier.symbol
val classId = resolvedQualifier.classId if (symbol != null) {
if (classId != null) { symbolRef(symbol) {
symbolRef(symbolProvider.getClassLikeSymbolByFqName(classId)) { fqn(resolvedQualifier.classId?.relativeClassName ?: FqName("<???>"))
fqn(classId.relativeClassName)
} }
} else { } else {
fqn(resolvedQualifier.packageFqName) fqn(resolvedQualifier.packageFqName)
@@ -1442,9 +1442,8 @@ class Fir2IrVisitor(
} }
override fun visitResolvedQualifier(resolvedQualifier: FirResolvedQualifier, data: Any?): IrElement { override fun visitResolvedQualifier(resolvedQualifier: FirResolvedQualifier, data: Any?): IrElement {
val classId = resolvedQualifier.classId val classSymbol = resolvedQualifier.symbol
if (classId != null) { if (classSymbol != null) {
val classSymbol = ConeClassLikeLookupTagImpl(classId).toSymbol(session)!!
return resolvedQualifier.convertWithOffsets { startOffset, endOffset -> return resolvedQualifier.convertWithOffsets { startOffset, endOffset ->
IrGetObjectValueImpl( IrGetObjectValueImpl(
startOffset, endOffset, startOffset, endOffset,
@@ -223,6 +223,7 @@ class FirCallResolver(
relativeClassFqName = classId.relativeClassName relativeClassFqName = classId.relativeClassName
safe = false safe = false
typeArguments.addAll(qualifiedAccess.typeArguments) typeArguments.addAll(qualifiedAccess.typeArguments)
symbol = referencedSymbol
}.apply { }.apply {
resultType = if (classId.isLocal) { resultType = if (classId.isLocal) {
typeForQualifierByDeclaration(referencedSymbol.fir, resultType, session) typeForQualifierByDeclaration(referencedSymbol.fir, resultType, session)
@@ -79,6 +79,7 @@ class FirQualifiedNameResolver(components: BodyResolveComponents) : BodyResolveC
packageFqName = resolved.packageFqName packageFqName = resolved.packageFqName
relativeClassFqName = resolved.relativeClassFqName relativeClassFqName = resolved.relativeClassFqName
safe = false safe = false
symbol = resolved.classSymbol
}.apply { }.apply {
resultType = typeForQualifier(this) resultType = typeForQualifier(this)
} }
@@ -119,8 +119,7 @@ class FirDoubleColonExpressionResolver(
} }
private fun FirResolvedQualifier.expandedRegularClassIfAny(): FirRegularClass? { private fun FirResolvedQualifier.expandedRegularClassIfAny(): FirRegularClass? {
val classId = classId ?: return null var fir = symbol?.fir ?: return null
var fir = session.firSymbolProvider.getClassLikeSymbolByFqName(classId)?.fir
while (fir is FirTypeAlias) { while (fir is FirTypeAlias) {
fir = fir.expandedConeType?.lookupTag?.toSymbol(session)?.fir ?: return null fir = fir.expandedConeType?.lookupTag?.toSymbol(session)?.fir ?: return null
} }
@@ -240,13 +240,9 @@ fun createKPropertyType(
} }
fun BodyResolveComponents.typeForQualifier(resolvedQualifier: FirResolvedQualifier): FirTypeRef { fun BodyResolveComponents.typeForQualifier(resolvedQualifier: FirResolvedQualifier): FirTypeRef {
val classId = resolvedQualifier.classId val classSymbol = resolvedQualifier.symbol
val resultType = resolvedQualifier.resultType val resultType = resolvedQualifier.resultType
if (classId != null) { if (classSymbol != null) {
val classSymbol = symbolProvider.getClassLikeSymbolByFqName(classId)
?: return buildErrorTypeRef {
diagnostic = FirSimpleDiagnostic("No type for qualifier", DiagnosticKind.Other)
}
val declaration = classSymbol.phasedFir val declaration = classSymbol.phasedFir
if (declaration !is FirTypeAlias || resolvedQualifier.typeArguments.isEmpty()) { if (declaration !is FirTypeAlias || resolvedQualifier.typeArguments.isEmpty()) {
typeForQualifierByDeclaration(declaration, resultType, session)?.let { return it } typeForQualifierByDeclaration(declaration, resultType, session)?.let { return it }
@@ -124,7 +124,7 @@ class FirTowerResolver(
} }
if (resolvedQualifier.classId != null) { if (resolvedQualifier.symbol != null) {
val typeRef = resolvedQualifier.typeRef val typeRef = resolvedQualifier.typeRef
// NB: yet built-in Unit is used for "no-value" type // NB: yet built-in Unit is used for "no-value" type
if (info.callKind == CallKind.CallableReference) { if (info.callKind == CallKind.CallableReference) {
@@ -10,19 +10,16 @@ import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.expressions.FirExpression
import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier
import org.jetbrains.kotlin.fir.resolve.ScopeSession import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.firSymbolProvider
import org.jetbrains.kotlin.fir.resolve.lookupSuperTypes import org.jetbrains.kotlin.fir.resolve.lookupSuperTypes
import org.jetbrains.kotlin.fir.resolve.toSymbol import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.scopes.FirScope import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.scopes.KotlinScopeProvider import org.jetbrains.kotlin.fir.scopes.KotlinScopeProvider
import org.jetbrains.kotlin.fir.scopes.impl.* import org.jetbrains.kotlin.fir.scopes.impl.*
import org.jetbrains.kotlin.fir.scopes.impl.FirCompositeScope
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeAliasSymbol
import org.jetbrains.kotlin.fir.types.ConeClassErrorType import org.jetbrains.kotlin.fir.types.ConeClassErrorType
import org.jetbrains.kotlin.fir.types.ConeClassLikeType import org.jetbrains.kotlin.fir.types.ConeClassLikeType
import org.jetbrains.kotlin.name.ClassId
import java.util.ArrayDeque import java.util.ArrayDeque
@@ -38,10 +35,9 @@ fun createQualifierReceiver(
scopeSession: ScopeSession, scopeSession: ScopeSession,
): QualifierReceiver? { ): QualifierReceiver? {
val classId = explicitReceiver.classId val classLikeSymbol = explicitReceiver.symbol
when { when {
classId != null -> { classLikeSymbol != null -> {
val classLikeSymbol = useSiteSession.firSymbolProvider.getClassLikeSymbolByFqName(classId) ?: return null
val classSymbol = classLikeSymbol.fir.fullyExpandedClass(useSiteSession)?.symbol ?: return null val classSymbol = classLikeSymbol.fir.fullyExpandedClass(useSiteSession)?.symbol ?: return null
return ClassQualifierReceiver(explicitReceiver, classSymbol, classLikeSymbol, useSiteSession, scopeSession) return ClassQualifierReceiver(explicitReceiver, classSymbol, classLikeSymbol, useSiteSession, scopeSession)
} }
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.fir.declarations.FirImport
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.fir.declarations.builder.buildResolvedImport import org.jetbrains.kotlin.fir.declarations.builder.buildResolvedImport
import org.jetbrains.kotlin.fir.resolve.FirSymbolProvider import org.jetbrains.kotlin.fir.resolve.FirSymbolProvider
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
import org.jetbrains.kotlin.fir.visitors.CompositeTransformResult import org.jetbrains.kotlin.fir.visitors.CompositeTransformResult
import org.jetbrains.kotlin.fir.visitors.compose import org.jetbrains.kotlin.fir.visitors.compose
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
@@ -73,14 +74,14 @@ fun resolveToPackageOrClass(symbolProvider: FirSymbolProvider, fqName: FqName):
prefixSize-- prefixSize--
} }
if (currentPackage == fqName) return PackageOrClass(currentPackage, null) if (currentPackage == fqName) return PackageOrClass(currentPackage, null, null)
val relativeClassFqName = val relativeClassFqName =
FqName.fromSegments((prefixSize until pathSegments.size).map { pathSegments[it].asString() }) FqName.fromSegments((prefixSize until pathSegments.size).map { pathSegments[it].asString() })
val classId = ClassId(currentPackage, relativeClassFqName, false) val classId = ClassId(currentPackage, relativeClassFqName, false)
if (symbolProvider.getClassLikeSymbolByFqName(classId) == null) return null val symbol = symbolProvider.getClassLikeSymbolByFqName(classId) ?: return null
return PackageOrClass(currentPackage, relativeClassFqName) return PackageOrClass(currentPackage, relativeClassFqName, symbol)
} }
data class PackageOrClass(val packageFqName: FqName, val relativeClassFqName: FqName?) data class PackageOrClass(val packageFqName: FqName, val relativeClassFqName: FqName?, val classSymbol: FirClassLikeSymbol<*>?)
@@ -446,19 +446,13 @@ class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransformer) :
val typeOfExpression = when (val lhs = transformedGetClassCall.argument) { val typeOfExpression = when (val lhs = transformedGetClassCall.argument) {
is FirResolvedQualifier -> { is FirResolvedQualifier -> {
val classId = lhs.classId val symbol = lhs.symbol
if (classId != null) { symbol?.constructType(
val symbol = symbolProvider.getClassLikeSymbolByFqName(classId) Array((symbol.phasedFir as? FirTypeParametersOwner)?.typeParameters?.size ?: 0) {
// TODO: Unify logic? ConeStarProjection
symbol?.constructType( },
Array((symbol.phasedFir as? FirTypeParametersOwner)?.typeParameters?.size ?: 0) { isNullable = false,
ConeStarProjection ) ?: lhs.resultType.coneTypeUnsafe()
},
isNullable = false,
)
} else {
null
} ?: lhs.resultType.coneTypeUnsafe()
} }
is FirResolvedReifiedParameterReference -> { is FirResolvedReifiedParameterReference -> {
val symbol = lhs.symbol val symbol = lhs.symbol
@@ -3,5 +3,5 @@ fun <T, R> List<T>.myMap(block: (T) -> R): List<R> = null!!
fun test_1() { fun test_1() {
class Data(val x: Int) class Data(val x: Int)
val datas: List<Data> = null!! val datas: List<Data> = null!!
val xs = datas.<!INAPPLICABLE_CANDIDATE!>myMap<!>(<!UNRESOLVED_REFERENCE!>Data::x<!>) val xs = datas.myMap(Data::x)
} }
@@ -14,5 +14,5 @@ FILE: callableReferenceToLocalClass.kt
} }
lval datas: R|kotlin/collections/List<Data>| = Null(null)!! lval datas: R|kotlin/collections/List<Data>| = Null(null)!!
lval xs: <ERROR TYPE REF: Inapplicable(INAPPLICABLE): [/myMap]> = R|<local>/datas|.<Inapplicable(INAPPLICABLE): [/myMap]>#(Q|Data|::<Unresolved name: x>#) lval xs: R|kotlin/collections/List<kotlin/Int>| = R|<local>/datas|.R|/myMap|<R|Data|, R|kotlin/Int|>(Q|Data|::R|/Data.x|)
} }
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.fir.expressions package org.jetbrains.kotlin.fir.expressions
import org.jetbrains.kotlin.fir.FirSourceElement import org.jetbrains.kotlin.fir.FirSourceElement
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
import org.jetbrains.kotlin.fir.types.FirTypeProjection import org.jetbrains.kotlin.fir.types.FirTypeProjection
import org.jetbrains.kotlin.fir.types.FirTypeRef import org.jetbrains.kotlin.fir.types.FirTypeRef
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
@@ -24,6 +25,7 @@ abstract class FirResolvedQualifier : FirExpression() {
abstract val packageFqName: FqName abstract val packageFqName: FqName
abstract val relativeClassFqName: FqName? abstract val relativeClassFqName: FqName?
abstract val classId: ClassId? abstract val classId: ClassId?
abstract val symbol: FirClassLikeSymbol<*>?
abstract val safe: Boolean abstract val safe: Boolean
abstract val typeArguments: List<FirTypeProjection> abstract val typeArguments: List<FirTypeProjection>
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier
import org.jetbrains.kotlin.fir.expressions.builder.FirExpressionBuilder import org.jetbrains.kotlin.fir.expressions.builder.FirExpressionBuilder
import org.jetbrains.kotlin.fir.expressions.impl.FirResolvedQualifierImpl import org.jetbrains.kotlin.fir.expressions.impl.FirResolvedQualifierImpl
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
import org.jetbrains.kotlin.fir.types.FirTypeProjection import org.jetbrains.kotlin.fir.types.FirTypeProjection
import org.jetbrains.kotlin.fir.types.FirTypeRef import org.jetbrains.kotlin.fir.types.FirTypeRef
import org.jetbrains.kotlin.fir.types.impl.FirImplicitTypeRefImpl import org.jetbrains.kotlin.fir.types.impl.FirImplicitTypeRefImpl
@@ -32,6 +33,7 @@ class FirResolvedQualifierBuilder : FirAnnotationContainerBuilder, FirExpression
override val annotations: MutableList<FirAnnotationCall> = mutableListOf() override val annotations: MutableList<FirAnnotationCall> = mutableListOf()
lateinit var packageFqName: FqName lateinit var packageFqName: FqName
var relativeClassFqName: FqName? = null var relativeClassFqName: FqName? = null
var symbol: FirClassLikeSymbol<*>? = null
var safe: Boolean by kotlin.properties.Delegates.notNull<Boolean>() var safe: Boolean by kotlin.properties.Delegates.notNull<Boolean>()
val typeArguments: MutableList<FirTypeProjection> = mutableListOf() val typeArguments: MutableList<FirTypeProjection> = mutableListOf()
@@ -42,6 +44,7 @@ class FirResolvedQualifierBuilder : FirAnnotationContainerBuilder, FirExpression
annotations, annotations,
packageFqName, packageFqName,
relativeClassFqName, relativeClassFqName,
symbol,
safe, safe,
typeArguments, typeArguments,
) )
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.expressions.impl
import org.jetbrains.kotlin.fir.FirSourceElement import org.jetbrains.kotlin.fir.FirSourceElement
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
import org.jetbrains.kotlin.fir.types.FirTypeProjection import org.jetbrains.kotlin.fir.types.FirTypeProjection
import org.jetbrains.kotlin.fir.types.FirTypeRef import org.jetbrains.kotlin.fir.types.FirTypeRef
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
@@ -25,6 +26,7 @@ internal class FirResolvedQualifierImpl(
override val annotations: MutableList<FirAnnotationCall>, override val annotations: MutableList<FirAnnotationCall>,
override var packageFqName: FqName, override var packageFqName: FqName,
override var relativeClassFqName: FqName?, override var relativeClassFqName: FqName?,
override val symbol: FirClassLikeSymbol<*>?,
override var safe: Boolean, override var safe: Boolean,
override val typeArguments: MutableList<FirTypeProjection>, override val typeArguments: MutableList<FirTypeProjection>,
) : FirResolvedQualifier() { ) : FirResolvedQualifier() {
@@ -6,7 +6,6 @@
package org.jetbrains.kotlin.fir.tree.generator package org.jetbrains.kotlin.fir.tree.generator
import org.jetbrains.kotlin.fir.tree.generator.context.AbstractBuilderConfigurator import org.jetbrains.kotlin.fir.tree.generator.context.AbstractBuilderConfigurator
import org.jetbrains.kotlin.fir.tree.generator.context.AbstractFirTreeImplementationConfigurator
import org.jetbrains.kotlin.fir.tree.generator.model.Element import org.jetbrains.kotlin.fir.tree.generator.model.Element
import org.jetbrains.kotlin.fir.tree.generator.model.Field import org.jetbrains.kotlin.fir.tree.generator.model.Field
import org.jetbrains.kotlin.fir.tree.generator.model.Implementation import org.jetbrains.kotlin.fir.tree.generator.model.Implementation
@@ -6,10 +6,8 @@
package org.jetbrains.kotlin.fir.tree.generator package org.jetbrains.kotlin.fir.tree.generator
import org.jetbrains.kotlin.fir.tree.generator.context.AbstractFirTreeImplementationConfigurator import org.jetbrains.kotlin.fir.tree.generator.context.AbstractFirTreeImplementationConfigurator
import org.jetbrains.kotlin.fir.tree.generator.model.Implementation
import org.jetbrains.kotlin.fir.tree.generator.model.Implementation.Kind.Object import org.jetbrains.kotlin.fir.tree.generator.model.Implementation.Kind.Object
import org.jetbrains.kotlin.fir.tree.generator.model.Implementation.Kind.OpenClass import org.jetbrains.kotlin.fir.tree.generator.model.Implementation.Kind.OpenClass
import org.jetbrains.kotlin.fir.tree.generator.util.traverseParents
object ImplementationConfigurator : AbstractFirTreeImplementationConfigurator() { object ImplementationConfigurator : AbstractFirTreeImplementationConfigurator() {
fun configureImplementations() { fun configureImplementations() {
@@ -431,6 +431,7 @@ object NodeConfigurator : AbstractFieldConfigurator<FirTreeBuilder>(FirTreeBuild
+field("packageFqName", fqNameType) +field("packageFqName", fqNameType)
+field("relativeClassFqName", fqNameType, nullable = true) +field("relativeClassFqName", fqNameType, nullable = true)
+field("classId", classIdType, nullable = true) +field("classId", classIdType, nullable = true)
+field("symbol", classLikeSymbolType, nullable = true)
+booleanField("safe", withReplace = true) +booleanField("safe", withReplace = true)
+typeArguments.withTransform() +typeArguments.withTransform()
} }
@@ -58,6 +58,7 @@ val abstractFirBasedSymbolType = type("fir.symbols", "AbstractFirBasedSymbol")
val backingFieldSymbolType = type("fir.symbols.impl", "FirBackingFieldSymbol") val backingFieldSymbolType = type("fir.symbols.impl", "FirBackingFieldSymbol")
val delegateFieldSymbolType = type("fir.symbols.impl", "FirDelegateFieldSymbol") val delegateFieldSymbolType = type("fir.symbols.impl", "FirDelegateFieldSymbol")
val classSymbolType = type("fir.symbols.impl", "FirClassSymbol") val classSymbolType = type("fir.symbols.impl", "FirClassSymbol")
val classLikeSymbolType = type("fir.symbols.impl", "FirClassLikeSymbol<*>")
val typeParameterSymbolType = type("fir.symbols.impl", "FirTypeParameterSymbol") val typeParameterSymbolType = type("fir.symbols.impl", "FirTypeParameterSymbol")
val firScopeProviderType = type("fir.scopes", "FirScopeProvider") val firScopeProviderType = type("fir.scopes", "FirScopeProvider")
@@ -98,7 +98,10 @@ fun SmartPrinter.printImplementation(implementation: Implementation) {
} }
element.allFields.filter { it.type.contains("Symbol") && it !is FieldList } element.allFields.filter { it.type.contains("Symbol") && it !is FieldList }
.takeIf { it.isNotEmpty() && !isInterface && !isAbstract && !element.type.contains("Reference") } .takeIf {
it.isNotEmpty() && !isInterface && !isAbstract &&
!element.type.contains("Reference") && !element.type.contains("ResolvedQualifier")
}
?.let { symbolFields -> ?.let { symbolFields ->
println("init {") println("init {")
for (symbolField in symbolFields) { for (symbolField in symbolFields) {
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
fun box(): String { fun box(): String {
class Local { class Local {
fun foo() = "OK" fun foo() = "OK"
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
fun box(): String { fun box(): String {
val result = "OK" val result = "OK"
@@ -2,8 +2,8 @@
fun test() { fun test() {
data class Pair<F, S>(val first: F, val second: S) data class Pair<F, S>(val first: F, val second: S)
val (<!UNRESOLVED_REFERENCE!>x<!>, <!UNRESOLVED_REFERENCE!>y<!>) = val (x, y) =
<!INAPPLICABLE_CANDIDATE!>Pair<!>(1, Pair(1,
if (1 == 1) if (1 == 1)
Pair<String, String>::first Pair<String, String>::first
else else
+1 -1
View File
@@ -5,7 +5,7 @@ fun foo() {
FOO, FOO,
BAR BAR
} }
val foo = A.<!UNRESOLVED_REFERENCE!>FOO<!> val foo = A.FOO
val b = object { val b = object {
enum class B {} enum class B {}
} }
@@ -429,8 +429,8 @@ class FirVisualizer(private val firFile: FirFile) : BaseRenderer() {
} }
override fun visitResolvedQualifier(resolvedQualifier: FirResolvedQualifier, data: StringBuilder) { override fun visitResolvedQualifier(resolvedQualifier: FirResolvedQualifier, data: StringBuilder) {
resolvedQualifier.classId?.let { resolvedQualifier.symbol?.let {
val fir = symbolProvider.getClassLikeSymbolByFqName(it)?.fir val fir = it.fir
if (fir is FirClass) { if (fir is FirClass) {
data.append(fir.classKind.name.toLowerCase()).append(" ") data.append(fir.classKind.name.toLowerCase()).append(" ")
data.append((fir as? FirRegularClass)?.name ?: Name.special("<anonymous>")) data.append((fir as? FirRegularClass)?.name ?: Name.special("<anonymous>"))