FIR: partial implementation of delegate resolve #KT-32217 Fixed

This commit is contained in:
Mikhail Glukhikh
2019-07-11 19:21:11 +03:00
parent 63b7fa70f9
commit 213f951da3
56 changed files with 753 additions and 266 deletions
@@ -173,14 +173,14 @@ class FirMemberDeserializer(private val c: FirDeserializationContext) {
returnTypeRef = returnTypeRef,
isVar = isVar,
initializer = null,
getter = FirDefaultPropertyGetter(c.session, null, returnTypeRef, ProtoEnumFlags.visibility(Flags.VISIBILITY.get(getterFlags))),
setter = if (isVar) {
FirDefaultPropertySetter(c.session, null, returnTypeRef, ProtoEnumFlags.visibility(Flags.VISIBILITY.get(setterFlags)))
} else null,
delegate = null
).apply {
typeParameters += local.typeDeserializer.ownTypeParameters.map { it.fir }
annotations += c.annotationDeserializer.loadPropertyAnnotations(proto, local.nameResolver)
getter = FirDefaultPropertyGetter(c.session, null, returnTypeRef, ProtoEnumFlags.visibility(Flags.VISIBILITY.get(getterFlags)))
setter = if (isVar) {
FirDefaultPropertySetter(c.session, null, returnTypeRef, ProtoEnumFlags.visibility(Flags.VISIBILITY.get(setterFlags)))
} else null
}
}
@@ -61,10 +61,11 @@ class FirSyntheticPropertiesScope(
returnTypeRef = returnTypeRef,
isVar = true,
initializer = null,
getter = FirDefaultPropertyGetter(session, null, returnTypeRef, fir.visibility),
setter = FirDefaultPropertySetter(session, null, returnTypeRef, fir.visibility),
delegate = null
)
).apply {
getter = FirDefaultPropertyGetter(this@FirSyntheticPropertiesScope.session, null, returnTypeRef, fir.visibility)
setter = FirDefaultPropertySetter(this@FirSyntheticPropertiesScope.session, null, returnTypeRef, fir.visibility)
}
return processor(synthetic)
}
@@ -414,6 +414,11 @@ open class FirBodyResolveTransformer(
}
return qualifiedAccessExpression.compose()
}
is FirDelegateFieldReference -> {
val delegateFieldSymbol = callee.coneSymbol
qualifiedAccessExpression.resultType = delegateFieldSymbol.delegate.typeRef
return qualifiedAccessExpression.compose()
}
is FirResolvedCallableReference -> {
if (qualifiedAccessExpression.typeRef !is FirResolvedTypeRef) {
storeTypeFromCallee(qualifiedAccessExpression)
@@ -1020,21 +1025,10 @@ open class FirBodyResolveTransformer(
}
)
}
variable.delegate != null -> {
// TODO: type from delegate
variable.getter != null && variable.getter !is FirDefaultPropertyAccessor -> {
variable.transformReturnTypeRef(
this,
FirErrorTypeRefImpl(
session,
null,
"Not supported: type from delegate"
)
)
}
variable is FirProperty && variable.getter !is FirDefaultPropertyAccessor -> {
variable.transformReturnTypeRef(
this,
when (val resultType = variable.getter.returnTypeRef) {
when (val resultType = variable.getter?.returnTypeRef) {
is FirImplicitTypeRef -> FirErrorTypeRefImpl(
session,
null,
@@ -1050,15 +1044,31 @@ open class FirBodyResolveTransformer(
)
}
}
if (variable is FirProperty && variable.getter.returnTypeRef is FirImplicitTypeRef) {
variable.getter.transformReturnTypeRef(this, variable.returnTypeRef)
if (variable.getter?.returnTypeRef is FirImplicitTypeRef) {
variable.getter?.transformReturnTypeRef(this, variable.returnTypeRef)
}
}
}
private fun <F : FirVariable<F>> FirVariable<F>.transformAccessors() {
var enhancedTypeRef = returnTypeRef
getter?.transform<FirDeclaration, Any?>(this@FirBodyResolveTransformer, enhancedTypeRef)
if (returnTypeRef is FirImplicitTypeRef) {
storeVariableReturnType(this)
enhancedTypeRef = returnTypeRef
}
setter?.let {
it.transform<FirDeclaration, Any?>(this@FirBodyResolveTransformer, enhancedTypeRef)
it.valueParameters[0].transformReturnTypeRef(StoreType, enhancedTypeRef)
}
}
override fun <F : FirVariable<F>> transformVariable(variable: FirVariable<F>, data: Any?): CompositeTransformResult<FirDeclaration> {
val variable = super.transformVariable(variable, variable.returnTypeRef).single as FirVariable<*>
storeVariableReturnType(variable)
variable.transformChildrenWithoutAccessors(this, variable.returnTypeRef)
if (variable.initializer != null) {
storeVariableReturnType(variable)
}
variable.transformAccessors()
if (variable !is FirProperty) {
localScopes.lastOrNull()?.storeDeclaration(variable)
}
@@ -1075,23 +1085,14 @@ open class FirBodyResolveTransformer(
localScopes.addIfNotNull(primaryConstructorParametersScope)
withContainer(property) {
property.transformChildrenWithoutAccessors(this, returnTypeRef)
if (property.returnTypeRef is FirImplicitTypeRef && property.initializer != null) {
if (property.initializer != null) {
storeVariableReturnType(property)
}
withScopeCleanup(localScopes) {
localScopes.add(FirLocalScope().apply {
storeBackingField(property)
})
var enhancedTypeRef = property.returnTypeRef
property.getter.transform<FirDeclaration, Any?>(this, enhancedTypeRef)
if (property.returnTypeRef is FirImplicitTypeRef) {
storeVariableReturnType(property)
enhancedTypeRef = property.returnTypeRef
}
property.setter?.let {
it.transform<FirDeclaration, Any?>(this, enhancedTypeRef)
it.valueParameters[0].transformReturnTypeRef(StoreType, enhancedTypeRef)
}
property.transformAccessors()
}
}
property.compose()
@@ -43,7 +43,7 @@ class FirStatusResolveTransformer : FirAbstractTreeTransformer() {
Modality.FINAL
this is FirNamedFunction && body == null ->
Modality.ABSTRACT
this is FirProperty && initializer == null && getter.body == null && setter?.body == null ->
this is FirProperty && initializer == null && getter?.body == null && setter?.body == null ->
Modality.ABSTRACT
else ->
Modality.OPEN
@@ -0,0 +1,5 @@
class C(val map: MutableMap<String, Any>) {
var foo by map
}
var bar by hashMapOf<String, Any>()
@@ -0,0 +1,25 @@
FILE: simpleDelegatedToMap.kt
public final class C : R|kotlin/Any| {
public constructor(map: R|kotlin/collections/MutableMap<kotlin/String, kotlin/Any>|): R|C| {
super<R|kotlin/Any|>()
}
public final val map: R|kotlin/collections/MutableMap<kotlin/String, kotlin/Any>| = R|<local>/map|
public get(): R|kotlin/collections/MutableMap<kotlin/String, kotlin/Any>|
public final var foo: <ERROR TYPE REF: Ambiguity: getValue, [kotlin/collections/getValue, kotlin/collections/getValue, kotlin/collections/getValue]>by R|<local>/map|
public get(): <ERROR TYPE REF: Ambiguity: getValue, [kotlin/collections/getValue, kotlin/collections/getValue, kotlin/collections/getValue]> {
^ D|/C.foo|.<Ambiguity: getValue, [kotlin/collections/getValue, kotlin/collections/getValue, kotlin/collections/getValue]>#(this#, ::R|/C.foo|)
}
public set(<set-?>: <ERROR TYPE REF: Ambiguity: getValue, [kotlin/collections/getValue, kotlin/collections/getValue, kotlin/collections/getValue]>): R|kotlin/Unit| {
D|/C.foo|.<Inapplicable(INAPPLICABLE): [kotlin/collections/setValue]>#(this#, ::R|/C.foo|, R|<local>/<set-?>|)
}
}
public final var bar: <ERROR TYPE REF: Inapplicable(PARAMETER_MAPPING_ERROR): [kotlin/collections/getValue]>by R|kotlin/collections/hashMapOf|<R|kotlin/String|, R|kotlin/Any|>()
public get(): <ERROR TYPE REF: Inapplicable(PARAMETER_MAPPING_ERROR): [kotlin/collections/getValue]> {
^ D|/bar|.<Inapplicable(PARAMETER_MAPPING_ERROR): [kotlin/collections/getValue]>#(Null(null), ::R|/bar|)
}
public set(<set-?>: <ERROR TYPE REF: Inapplicable(PARAMETER_MAPPING_ERROR): [kotlin/collections/getValue]>): R|kotlin/Unit| {
D|/bar|.<Inapplicable(WRONG_RECEIVER): [kotlin/collections/setValue]>#(Null(null), ::R|/bar|, R|<local>/<set-?>|)
}
@@ -0,0 +1,9 @@
//val x = lazy { "Hello" }.getValue(null, throw null)
val x by lazy { "Hello" }
fun foo() {
x.length
val y by lazy { "Bye" }
y.length
}
@@ -0,0 +1,16 @@
FILE: simpleLazy.kt
public final val x: R|kotlin/String|by R|kotlin/lazy|<R|kotlin/String|>(<L> = lazy@fun <anonymous>(): R|kotlin/String| {
String(Hello)
}
)
public get(): R|kotlin/String| {
^ D|/x|.R|kotlin/getValue|<R|kotlin/String|>(Null(null), ::R|/x|)
}
public final fun foo(): R|kotlin/Unit| {
R|/x|.R|kotlin/String.length|
lval y: R|kotlin/String|by R|kotlin/lazy|<R|kotlin/String|>(<L> = lazy@fun <anonymous>(): R|kotlin/String| {
String(Bye)
}
)
R|<local>/y|.R|kotlin/String.length|
}
@@ -94,6 +94,16 @@ public class FirResolveTestCaseWithStdlibGenerated extends AbstractFirResolveTes
runTest("compiler/fir/resolve/testData/resolve/stdlib/reflectionClass.kt");
}
@TestMetadata("simpleDelegatedToMap.kt")
public void testSimpleDelegatedToMap() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/stdlib/simpleDelegatedToMap.kt");
}
@TestMetadata("simpleLazy.kt")
public void testSimpleLazy() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/stdlib/simpleLazy.kt");
}
@TestMetadata("topLevelResolve.kt")
public void testTopLevelResolve() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/stdlib/topLevelResolve.kt");