FIR: Support this resolve
This commit is contained in:
+1
-1
@@ -7,6 +7,6 @@ FILE: noPrimaryConstructor.kt
|
||||
this#.x# = x#
|
||||
}
|
||||
|
||||
public? constructor(): this<NoPrimary>(String())
|
||||
public? constructor(): this<R|NoPrimary|>(String())
|
||||
|
||||
}
|
||||
|
||||
+56
-12
@@ -5,6 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.fir.resolve.transformers
|
||||
|
||||
import com.google.common.collect.LinkedHashMultimap
|
||||
import org.jetbrains.kotlin.fir.*
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.expressions.*
|
||||
@@ -27,6 +28,7 @@ import org.jetbrains.kotlin.fir.visitors.compose
|
||||
import org.jetbrains.kotlin.ir.expressions.IrConstKind
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.fir.types.impl.ConeClassTypeImpl
|
||||
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
|
||||
import org.jetbrains.kotlin.fir.types.impl.FirErrorTypeRefImpl
|
||||
import org.jetbrains.kotlin.fir.types.impl.FirResolvedTypeRefImpl
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
@@ -103,21 +105,45 @@ class FirBodyResolveTransformer(val session: FirSession) : FirTransformer<Any?>(
|
||||
}
|
||||
|
||||
fun ConeKotlinType.scope(useSiteSession: FirSession): FirScope {
|
||||
when (this) {
|
||||
is ConeClassTypeImpl -> return (this.lookupTag.toSymbol(useSiteSession) as FirBasedSymbol<FirRegularClass>).fir.buildUseSiteScope(
|
||||
return when (this) {
|
||||
is ConeAbbreviatedType -> directExpansion.scope(useSiteSession)
|
||||
is ConeClassLikeType -> (this.lookupTag.toSymbol(useSiteSession) as FirBasedSymbol<FirRegularClass>).fir.buildUseSiteScope(
|
||||
useSiteSession
|
||||
)
|
||||
else -> error("Failed type ${this}")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
inline fun <T> withLabel(labelName: Name, type: ConeKotlinType, block: () -> T): T {
|
||||
labels.put(labelName, type)
|
||||
val result = block()
|
||||
labels.remove(labelName, type)
|
||||
return result
|
||||
}
|
||||
|
||||
override fun transformRegularClass(regularClass: FirRegularClass, data: Any?): CompositeTransformResult<FirDeclaration> {
|
||||
return withScopeCleanup(scopes) {
|
||||
scopes += regularClass.buildUseSiteScope()
|
||||
super.transformRegularClass(regularClass, data)
|
||||
withLabel(regularClass.name, regularClass.defaultType()) {
|
||||
super.transformRegularClass(regularClass, data)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun FirRegularClass.defaultType(): ConeClassTypeImpl {
|
||||
return ConeClassTypeImpl(
|
||||
symbol.toLookupTag(),
|
||||
typeParameters.map {
|
||||
ConeTypeParameterTypeImpl(
|
||||
it.symbol.toLookupTag(),
|
||||
isNullable = false
|
||||
)
|
||||
}.toTypedArray(),
|
||||
isNullable = false
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
protected inline fun <T> withScopeCleanup(scopes: MutableList<*>, crossinline l: () -> T): T {
|
||||
val sizeBefore = scopes.size
|
||||
@@ -133,6 +159,8 @@ class FirBodyResolveTransformer(val session: FirSession) : FirTransformer<Any?>(
|
||||
val scopes = mutableListOf<FirScope>()
|
||||
val localScopes = mutableListOf<FirLocalScope>()
|
||||
|
||||
val labels = LinkedHashMultimap.create<Name, ConeKotlinType>()
|
||||
|
||||
enum class CandidateApplicability {
|
||||
HIDDEN,
|
||||
PARAMETER_MAPPING_ERROR,
|
||||
@@ -416,6 +444,15 @@ class FirBodyResolveTransformer(val session: FirSession) : FirTransformer<Any?>(
|
||||
data: Any?
|
||||
): CompositeTransformResult<FirStatement> {
|
||||
|
||||
when (val callee = qualifiedAccessExpression.calleeReference) {
|
||||
is FirThisReference -> {
|
||||
|
||||
val labelName = callee.labelName
|
||||
val types = if (labelName == null) labels.values() else labels[Name.identifier(labelName)]
|
||||
val type = types.lastOrNull() ?: ConeKotlinErrorType("Unresolved this@$labelName")
|
||||
bindingContext[qualifiedAccessExpression] = FirResolvedTypeRefImpl(session, null, type, false, emptyList())
|
||||
}
|
||||
}
|
||||
val callee = qualifiedAccessExpression.calleeReference as? FirSimpleNamedReference ?: return qualifiedAccessExpression.compose()
|
||||
|
||||
qualifiedAccessExpression.explicitReceiver?.visitNoTransform(this, null)
|
||||
@@ -574,19 +611,26 @@ class FirBodyResolveTransformer(val session: FirSession) : FirTransformer<Any?>(
|
||||
|
||||
|
||||
override fun transformNamedFunction(namedFunction: FirNamedFunction, data: Any?): CompositeTransformResult<FirDeclaration> {
|
||||
val receiverTypeRef = namedFunction.receiverTypeRef
|
||||
fun transform(): CompositeTransformResult<FirDeclaration> {
|
||||
localScopes.lastOrNull()?.storeDeclaration(namedFunction)
|
||||
return withScopeCleanup(scopes) {
|
||||
scopes.addIfNotNull(receiverTypeRef?.coneTypeSafe()?.scope(session))
|
||||
val body = namedFunction.body
|
||||
if (namedFunction.returnTypeRef is FirImplicitTypeRef && body != null) {
|
||||
body.visitNoTransform(this, namedFunction.returnTypeRef)
|
||||
namedFunction.transformReturnTypeRef(this, body.resultType)
|
||||
}
|
||||
|
||||
localScopes.lastOrNull()?.storeDeclaration(namedFunction)
|
||||
return withScopeCleanup(scopes) {
|
||||
scopes.addIfNotNull(namedFunction.receiverTypeRef?.coneTypeSafe()?.scope(session))
|
||||
val body = namedFunction.body
|
||||
if (namedFunction.returnTypeRef is FirImplicitTypeRef && body != null) {
|
||||
body.visitNoTransform(this, namedFunction.returnTypeRef)
|
||||
namedFunction.transformReturnTypeRef(this, body.resultType)
|
||||
super.transformNamedFunction(namedFunction, data)
|
||||
}
|
||||
|
||||
super.transformNamedFunction(namedFunction, data)
|
||||
}
|
||||
|
||||
return if (receiverTypeRef != null) {
|
||||
withLabel(namedFunction.name, receiverTypeRef.coneTypeUnsafe()) { transform() }
|
||||
} else {
|
||||
transform()
|
||||
}
|
||||
}
|
||||
|
||||
override fun transformVariable(variable: FirVariable, data: Any?): CompositeTransformResult<FirDeclaration> {
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
|
||||
class Bar
|
||||
|
||||
class Foo {
|
||||
fun bar() = this
|
||||
fun Bar.buz() = this
|
||||
fun Bar.foo() = this@Foo
|
||||
fun Bar.foobar() = this@foobar
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
FILE: this.kt
|
||||
public final class Bar {
|
||||
public constructor(): super<R|kotlin/Any|>()
|
||||
|
||||
}
|
||||
public final class Foo {
|
||||
public constructor(): super<R|kotlin/Any|>()
|
||||
|
||||
public final function bar(): R|Foo| {
|
||||
return@@@bar this#
|
||||
}
|
||||
|
||||
public final function buz R|Bar|.(): R|Bar| {
|
||||
return@@@buz this#
|
||||
}
|
||||
|
||||
public final function foo R|Bar|.(): R|Foo| {
|
||||
return@@@foo this@Foo
|
||||
}
|
||||
|
||||
public final function foobar R|Bar|.(): R|Bar| {
|
||||
return@@@foobar this@foobar
|
||||
}
|
||||
|
||||
}
|
||||
+5
@@ -164,6 +164,11 @@ public class FirResolveTestCaseGenerated extends AbstractFirResolveTestCase {
|
||||
runTest("compiler/fir/resolve/testData/resolve/expresssions/simple.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("this.kt")
|
||||
public void testThis() throws Exception {
|
||||
runTest("compiler/fir/resolve/testData/resolve/expresssions/this.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("when.kt")
|
||||
public void testWhen() throws Exception {
|
||||
runTest("compiler/fir/resolve/testData/resolve/expresssions/when.kt");
|
||||
|
||||
Reference in New Issue
Block a user