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) {
resolved {
val symbolProvider = session.firSymbolProvider
val classId = resolvedQualifier.classId
if (classId != null) {
symbolRef(symbolProvider.getClassLikeSymbolByFqName(classId)) {
fqn(classId.relativeClassName)
val symbol = resolvedQualifier.symbol
if (symbol != null) {
symbolRef(symbol) {
fqn(resolvedQualifier.classId?.relativeClassName ?: FqName("<???>"))
}
} else {
fqn(resolvedQualifier.packageFqName)
@@ -1442,9 +1442,8 @@ class Fir2IrVisitor(
}
override fun visitResolvedQualifier(resolvedQualifier: FirResolvedQualifier, data: Any?): IrElement {
val classId = resolvedQualifier.classId
if (classId != null) {
val classSymbol = ConeClassLikeLookupTagImpl(classId).toSymbol(session)!!
val classSymbol = resolvedQualifier.symbol
if (classSymbol != null) {
return resolvedQualifier.convertWithOffsets { startOffset, endOffset ->
IrGetObjectValueImpl(
startOffset, endOffset,
@@ -223,6 +223,7 @@ class FirCallResolver(
relativeClassFqName = classId.relativeClassName
safe = false
typeArguments.addAll(qualifiedAccess.typeArguments)
symbol = referencedSymbol
}.apply {
resultType = if (classId.isLocal) {
typeForQualifierByDeclaration(referencedSymbol.fir, resultType, session)
@@ -79,6 +79,7 @@ class FirQualifiedNameResolver(components: BodyResolveComponents) : BodyResolveC
packageFqName = resolved.packageFqName
relativeClassFqName = resolved.relativeClassFqName
safe = false
symbol = resolved.classSymbol
}.apply {
resultType = typeForQualifier(this)
}
@@ -119,8 +119,7 @@ class FirDoubleColonExpressionResolver(
}
private fun FirResolvedQualifier.expandedRegularClassIfAny(): FirRegularClass? {
val classId = classId ?: return null
var fir = session.firSymbolProvider.getClassLikeSymbolByFqName(classId)?.fir
var fir = symbol?.fir ?: return null
while (fir is FirTypeAlias) {
fir = fir.expandedConeType?.lookupTag?.toSymbol(session)?.fir ?: return null
}
@@ -240,13 +240,9 @@ fun createKPropertyType(
}
fun BodyResolveComponents.typeForQualifier(resolvedQualifier: FirResolvedQualifier): FirTypeRef {
val classId = resolvedQualifier.classId
val classSymbol = resolvedQualifier.symbol
val resultType = resolvedQualifier.resultType
if (classId != null) {
val classSymbol = symbolProvider.getClassLikeSymbolByFqName(classId)
?: return buildErrorTypeRef {
diagnostic = FirSimpleDiagnostic("No type for qualifier", DiagnosticKind.Other)
}
if (classSymbol != null) {
val declaration = classSymbol.phasedFir
if (declaration !is FirTypeAlias || resolvedQualifier.typeArguments.isEmpty()) {
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
// NB: yet built-in Unit is used for "no-value" type
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.FirResolvedQualifier
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.toSymbol
import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.scopes.KotlinScopeProvider
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.FirClassSymbol
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.ConeClassLikeType
import org.jetbrains.kotlin.name.ClassId
import java.util.ArrayDeque
@@ -38,10 +35,9 @@ fun createQualifierReceiver(
scopeSession: ScopeSession,
): QualifierReceiver? {
val classId = explicitReceiver.classId
val classLikeSymbol = explicitReceiver.symbol
when {
classId != null -> {
val classLikeSymbol = useSiteSession.firSymbolProvider.getClassLikeSymbolByFqName(classId) ?: return null
classLikeSymbol != null -> {
val classSymbol = classLikeSymbol.fir.fullyExpandedClass(useSiteSession)?.symbol ?: return null
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.builder.buildResolvedImport
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.compose
import org.jetbrains.kotlin.name.ClassId
@@ -73,14 +74,14 @@ fun resolveToPackageOrClass(symbolProvider: FirSymbolProvider, fqName: FqName):
prefixSize--
}
if (currentPackage == fqName) return PackageOrClass(currentPackage, null)
if (currentPackage == fqName) return PackageOrClass(currentPackage, null, null)
val relativeClassFqName =
FqName.fromSegments((prefixSize until pathSegments.size).map { pathSegments[it].asString() })
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) {
is FirResolvedQualifier -> {
val classId = lhs.classId
if (classId != null) {
val symbol = symbolProvider.getClassLikeSymbolByFqName(classId)
// TODO: Unify logic?
symbol?.constructType(
Array((symbol.phasedFir as? FirTypeParametersOwner)?.typeParameters?.size ?: 0) {
ConeStarProjection
},
isNullable = false,
)
} else {
null
} ?: lhs.resultType.coneTypeUnsafe()
val symbol = lhs.symbol
symbol?.constructType(
Array((symbol.phasedFir as? FirTypeParametersOwner)?.typeParameters?.size ?: 0) {
ConeStarProjection
},
isNullable = false,
) ?: lhs.resultType.coneTypeUnsafe()
}
is FirResolvedReifiedParameterReference -> {
val symbol = lhs.symbol
@@ -3,5 +3,5 @@ fun <T, R> List<T>.myMap(block: (T) -> R): List<R> = null!!
fun test_1() {
class Data(val x: Int)
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 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
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.FirTypeRef
import org.jetbrains.kotlin.name.ClassId
@@ -24,6 +25,7 @@ abstract class FirResolvedQualifier : FirExpression() {
abstract val packageFqName: FqName
abstract val relativeClassFqName: FqName?
abstract val classId: ClassId?
abstract val symbol: FirClassLikeSymbol<*>?
abstract val safe: Boolean
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.builder.FirExpressionBuilder
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.FirTypeRef
import org.jetbrains.kotlin.fir.types.impl.FirImplicitTypeRefImpl
@@ -32,6 +33,7 @@ class FirResolvedQualifierBuilder : FirAnnotationContainerBuilder, FirExpression
override val annotations: MutableList<FirAnnotationCall> = mutableListOf()
lateinit var packageFqName: FqName
var relativeClassFqName: FqName? = null
var symbol: FirClassLikeSymbol<*>? = null
var safe: Boolean by kotlin.properties.Delegates.notNull<Boolean>()
val typeArguments: MutableList<FirTypeProjection> = mutableListOf()
@@ -42,6 +44,7 @@ class FirResolvedQualifierBuilder : FirAnnotationContainerBuilder, FirExpression
annotations,
packageFqName,
relativeClassFqName,
symbol,
safe,
typeArguments,
)
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.expressions.impl
import org.jetbrains.kotlin.fir.FirSourceElement
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
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.FirTypeRef
import org.jetbrains.kotlin.name.ClassId
@@ -25,6 +26,7 @@ internal class FirResolvedQualifierImpl(
override val annotations: MutableList<FirAnnotationCall>,
override var packageFqName: FqName,
override var relativeClassFqName: FqName?,
override val symbol: FirClassLikeSymbol<*>?,
override var safe: Boolean,
override val typeArguments: MutableList<FirTypeProjection>,
) : FirResolvedQualifier() {
@@ -6,7 +6,6 @@
package org.jetbrains.kotlin.fir.tree.generator
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.Field
import org.jetbrains.kotlin.fir.tree.generator.model.Implementation
@@ -6,10 +6,8 @@
package org.jetbrains.kotlin.fir.tree.generator
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.OpenClass
import org.jetbrains.kotlin.fir.tree.generator.util.traverseParents
object ImplementationConfigurator : AbstractFirTreeImplementationConfigurator() {
fun configureImplementations() {
@@ -431,6 +431,7 @@ object NodeConfigurator : AbstractFieldConfigurator<FirTreeBuilder>(FirTreeBuild
+field("packageFqName", fqNameType)
+field("relativeClassFqName", fqNameType, nullable = true)
+field("classId", classIdType, nullable = true)
+field("symbol", classLikeSymbolType, nullable = true)
+booleanField("safe", withReplace = true)
+typeArguments.withTransform()
}
@@ -58,6 +58,7 @@ val abstractFirBasedSymbolType = type("fir.symbols", "AbstractFirBasedSymbol")
val backingFieldSymbolType = type("fir.symbols.impl", "FirBackingFieldSymbol")
val delegateFieldSymbolType = type("fir.symbols.impl", "FirDelegateFieldSymbol")
val classSymbolType = type("fir.symbols.impl", "FirClassSymbol")
val classLikeSymbolType = type("fir.symbols.impl", "FirClassLikeSymbol<*>")
val typeParameterSymbolType = type("fir.symbols.impl", "FirTypeParameterSymbol")
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 }
.takeIf { it.isNotEmpty() && !isInterface && !isAbstract && !element.type.contains("Reference") }
.takeIf {
it.isNotEmpty() && !isInterface && !isAbstract &&
!element.type.contains("Reference") && !element.type.contains("ResolvedQualifier")
}
?.let { symbolFields ->
println("init {")
for (symbolField in symbolFields) {
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
fun box(): String {
class Local {
fun foo() = "OK"
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
fun box(): String {
val result = "OK"
@@ -2,8 +2,8 @@
fun test() {
data class Pair<F, S>(val first: F, val second: S)
val (<!UNRESOLVED_REFERENCE!>x<!>, <!UNRESOLVED_REFERENCE!>y<!>) =
<!INAPPLICABLE_CANDIDATE!>Pair<!>(1,
val (x, y) =
Pair(1,
if (1 == 1)
Pair<String, String>::first
else
+1 -1
View File
@@ -5,7 +5,7 @@ fun foo() {
FOO,
BAR
}
val foo = A.<!UNRESOLVED_REFERENCE!>FOO<!>
val foo = A.FOO
val b = object {
enum class B {}
}
@@ -429,8 +429,8 @@ class FirVisualizer(private val firFile: FirFile) : BaseRenderer() {
}
override fun visitResolvedQualifier(resolvedQualifier: FirResolvedQualifier, data: StringBuilder) {
resolvedQualifier.classId?.let {
val fir = symbolProvider.getClassLikeSymbolByFqName(it)?.fir
resolvedQualifier.symbol?.let {
val fir = it.fir
if (fir is FirClass) {
data.append(fir.classKind.name.toLowerCase()).append(" ")
data.append((fir as? FirRegularClass)?.name ?: Name.special("<anonymous>"))