Delegated Properties: allowing type parameters for get/set methods
#KT-6253 Fixed
This commit is contained in:
+15
-7
@@ -184,7 +184,7 @@ public class DelegatedPropertyResolver {
|
|||||||
if (trace.getBindingContext().get(DELEGATED_PROPERTY_CALL, accessor) != null) return;
|
if (trace.getBindingContext().get(DELEGATED_PROPERTY_CALL, accessor) != null) return;
|
||||||
|
|
||||||
OverloadResolutionResults<FunctionDescriptor> functionResults = getDelegatedPropertyConventionMethod(
|
OverloadResolutionResults<FunctionDescriptor> functionResults = getDelegatedPropertyConventionMethod(
|
||||||
propertyDescriptor, delegateExpression, delegateType, trace, scope, isGet);
|
propertyDescriptor, delegateExpression, delegateType, trace, scope, isGet, true);
|
||||||
Call call = trace.getBindingContext().get(DELEGATED_PROPERTY_CALL, accessor);
|
Call call = trace.getBindingContext().get(DELEGATED_PROPERTY_CALL, accessor);
|
||||||
assert call != null : "'getDelegatedPropertyConventionMethod' didn't record a call";
|
assert call != null : "'getDelegatedPropertyConventionMethod' didn't record a call";
|
||||||
|
|
||||||
@@ -218,14 +218,18 @@ public class DelegatedPropertyResolver {
|
|||||||
@NotNull JetType delegateType,
|
@NotNull JetType delegateType,
|
||||||
@NotNull BindingTrace trace,
|
@NotNull BindingTrace trace,
|
||||||
@NotNull JetScope scope,
|
@NotNull JetScope scope,
|
||||||
boolean isGet
|
boolean isGet,
|
||||||
|
boolean isComplete
|
||||||
) {
|
) {
|
||||||
PropertyAccessorDescriptor accessor = isGet ? propertyDescriptor.getGetter() : propertyDescriptor.getSetter();
|
PropertyAccessorDescriptor accessor = isGet ? propertyDescriptor.getGetter() : propertyDescriptor.getSetter();
|
||||||
assert accessor != null : "Delegated property should have getter/setter " + propertyDescriptor + " " + delegateExpression.getText();
|
assert accessor != null : "Delegated property should have getter/setter " + propertyDescriptor + " " + delegateExpression.getText();
|
||||||
|
|
||||||
|
JetType expectedType = isComplete && isGet && !(propertyDescriptor.getType() instanceof DeferredType)
|
||||||
|
? propertyDescriptor.getType() : TypeUtils.NO_EXPECTED_TYPE;
|
||||||
|
|
||||||
ExpressionTypingContext context = ExpressionTypingContext.newContext(
|
ExpressionTypingContext context = ExpressionTypingContext.newContext(
|
||||||
expressionTypingServices, trace, scope,
|
expressionTypingServices, trace, scope,
|
||||||
DataFlowInfo.EMPTY, TypeUtils.NO_EXPECTED_TYPE);
|
DataFlowInfo.EMPTY, expectedType);
|
||||||
|
|
||||||
boolean hasThis = propertyDescriptor.getExtensionReceiverParameter() != null || propertyDescriptor.getDispatchReceiverParameter() != null;
|
boolean hasThis = propertyDescriptor.getExtensionReceiverParameter() != null || propertyDescriptor.getDispatchReceiverParameter() != null;
|
||||||
|
|
||||||
@@ -318,7 +322,9 @@ public class DelegatedPropertyResolver {
|
|||||||
TemporaryBindingTrace.create(trace, "Trace to resolve delegated property convention methods");
|
TemporaryBindingTrace.create(trace, "Trace to resolve delegated property convention methods");
|
||||||
OverloadResolutionResults<FunctionDescriptor>
|
OverloadResolutionResults<FunctionDescriptor>
|
||||||
getMethodResults = getDelegatedPropertyConventionMethod(
|
getMethodResults = getDelegatedPropertyConventionMethod(
|
||||||
propertyDescriptor, delegateExpression, returnType, traceToResolveConventionMethods, accessorScope, true);
|
propertyDescriptor, delegateExpression, returnType, traceToResolveConventionMethods, accessorScope,
|
||||||
|
true, false
|
||||||
|
);
|
||||||
|
|
||||||
if (conventionMethodFound(getMethodResults)) {
|
if (conventionMethodFound(getMethodResults)) {
|
||||||
FunctionDescriptor descriptor = getMethodResults.getResultingDescriptor();
|
FunctionDescriptor descriptor = getMethodResults.getResultingDescriptor();
|
||||||
@@ -335,9 +341,11 @@ public class DelegatedPropertyResolver {
|
|||||||
// But if the type isn't known yet, the constraint shouldn't be added (we try to infer the type of 'v' here as well).
|
// But if the type isn't known yet, the constraint shouldn't be added (we try to infer the type of 'v' here as well).
|
||||||
if (propertyDescriptor.getReturnType() instanceof DeferredType) return;
|
if (propertyDescriptor.getReturnType() instanceof DeferredType) return;
|
||||||
|
|
||||||
OverloadResolutionResults<FunctionDescriptor> setMethodResults =
|
OverloadResolutionResults<FunctionDescriptor>
|
||||||
getDelegatedPropertyConventionMethod(
|
setMethodResults = getDelegatedPropertyConventionMethod(
|
||||||
propertyDescriptor, delegateExpression, returnType, traceToResolveConventionMethods, accessorScope, false);
|
propertyDescriptor, delegateExpression, returnType, traceToResolveConventionMethods, accessorScope,
|
||||||
|
false, false
|
||||||
|
);
|
||||||
|
|
||||||
if (conventionMethodFound(setMethodResults)) {
|
if (conventionMethodFound(setMethodResults)) {
|
||||||
FunctionDescriptor descriptor = setMethodResults.getResultingDescriptor();
|
FunctionDescriptor descriptor = setMethodResults.getResultingDescriptor();
|
||||||
|
|||||||
+25
@@ -0,0 +1,25 @@
|
|||||||
|
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||||
|
|
||||||
|
class A<R>() {
|
||||||
|
fun <T> get(t: Any?, p: PropertyMetadata): T = null!!
|
||||||
|
fun <T> set(t: Any?, p: PropertyMetadata, x: T) = Unit
|
||||||
|
}
|
||||||
|
|
||||||
|
var a1: Int by <!TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>A<!>()
|
||||||
|
var a2: Int by A<String>()
|
||||||
|
|
||||||
|
class B<R>() {
|
||||||
|
fun <T> get(t: Any?, p: PropertyMetadata): T = null!!
|
||||||
|
fun set(t: Any?, p: PropertyMetadata, x: R) = Unit
|
||||||
|
}
|
||||||
|
|
||||||
|
var b1: Int by B()
|
||||||
|
var b2: Int by B<Number>()
|
||||||
|
|
||||||
|
class C<R>() {
|
||||||
|
fun get(t: Any?, p: PropertyMetadata): R = null!!
|
||||||
|
fun <T> set(t: Any?, p: PropertyMetadata, x: T) = Unit
|
||||||
|
}
|
||||||
|
|
||||||
|
var c1: Int by C()
|
||||||
|
var c2: Int by <!DELEGATE_SPECIAL_FUNCTION_RETURN_TYPE_MISMATCH!>C<Number>()<!>
|
||||||
+35
@@ -0,0 +1,35 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
internal var a1: kotlin.Int
|
||||||
|
internal var a2: kotlin.Int
|
||||||
|
internal var b1: kotlin.Int
|
||||||
|
internal var b2: kotlin.Int
|
||||||
|
internal var c1: kotlin.Int
|
||||||
|
internal var c2: kotlin.Int
|
||||||
|
|
||||||
|
internal final class A</*0*/ R> {
|
||||||
|
public constructor A</*0*/ R>()
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
internal final fun </*0*/ T> get(/*0*/ t: kotlin.Any?, /*1*/ p: kotlin.PropertyMetadata): T
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
internal final fun </*0*/ T> set(/*0*/ t: kotlin.Any?, /*1*/ p: kotlin.PropertyMetadata, /*2*/ x: T): kotlin.Unit
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
internal final class B</*0*/ R> {
|
||||||
|
public constructor B</*0*/ R>()
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
internal final fun </*0*/ T> get(/*0*/ t: kotlin.Any?, /*1*/ p: kotlin.PropertyMetadata): T
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
internal final fun set(/*0*/ t: kotlin.Any?, /*1*/ p: kotlin.PropertyMetadata, /*2*/ x: R): kotlin.Unit
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
internal final class C</*0*/ R> {
|
||||||
|
public constructor C</*0*/ R>()
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
internal final fun get(/*0*/ t: kotlin.Any?, /*1*/ p: kotlin.PropertyMetadata): R
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
internal final fun </*0*/ T> set(/*0*/ t: kotlin.Any?, /*1*/ p: kotlin.PropertyMetadata, /*2*/ x: T): kotlin.Unit
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||||
|
var a: Int by A()
|
||||||
|
var a1 by <!DELEGATE_SPECIAL_FUNCTION_MISSING, DELEGATE_SPECIAL_FUNCTION_MISSING!>A()<!>
|
||||||
|
|
||||||
|
var b: Int by B()
|
||||||
|
|
||||||
|
val cObj = C()
|
||||||
|
var c: String by cObj
|
||||||
|
|
||||||
|
class A {
|
||||||
|
fun <T> get(t: Any?, p: PropertyMetadata): T = null!!
|
||||||
|
fun <T> set(t: Any?, p: PropertyMetadata, x: T) = Unit
|
||||||
|
}
|
||||||
|
|
||||||
|
class B
|
||||||
|
|
||||||
|
fun <T> B.get(t: Any?, p: PropertyMetadata): T = null!!
|
||||||
|
fun <T> B.set(t: Any?, p: PropertyMetadata, x: T) = Unit
|
||||||
|
|
||||||
|
class C
|
||||||
|
|
||||||
|
inline fun <reified T> C.get(t: Any?, p: PropertyMetadata): T = null!!
|
||||||
|
inline fun <reified T> C.set(t: Any?, p: PropertyMetadata, x: T) = Unit
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
internal var a: kotlin.Int
|
||||||
|
internal var a1: [ERROR : Type from delegate]
|
||||||
|
internal var b: kotlin.Int
|
||||||
|
internal var c: kotlin.String
|
||||||
|
internal val cObj: C
|
||||||
|
internal fun </*0*/ T> B.get(/*0*/ t: kotlin.Any?, /*1*/ p: kotlin.PropertyMetadata): T
|
||||||
|
kotlin.inline() internal fun </*0*/ reified T> C.get(/*0*/ t: kotlin.Any?, /*1*/ p: kotlin.PropertyMetadata): T
|
||||||
|
internal fun </*0*/ T> B.set(/*0*/ t: kotlin.Any?, /*1*/ p: kotlin.PropertyMetadata, /*2*/ x: T): kotlin.Unit
|
||||||
|
kotlin.inline() internal fun </*0*/ reified T> C.set(/*0*/ t: kotlin.Any?, /*1*/ p: kotlin.PropertyMetadata, /*2*/ x: T): kotlin.Unit
|
||||||
|
|
||||||
|
internal final class A {
|
||||||
|
public constructor A()
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
internal final fun </*0*/ T> get(/*0*/ t: kotlin.Any?, /*1*/ p: kotlin.PropertyMetadata): T
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
internal final fun </*0*/ T> set(/*0*/ t: kotlin.Any?, /*1*/ p: kotlin.PropertyMetadata, /*2*/ x: T): kotlin.Unit
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
internal final class B {
|
||||||
|
public constructor B()
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
internal final class C {
|
||||||
|
public constructor C()
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
@@ -3147,6 +3147,18 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("genericMethodInGenericClass.kt")
|
||||||
|
public void testGenericMethodInGenericClass() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/delegatedProperty/inference/genericMethodInGenericClass.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("genericMethods.kt")
|
||||||
|
public void testGenericMethods() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/delegatedProperty/inference/genericMethods.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("labeledDelegatedExpression.kt")
|
@TestMetadata("labeledDelegatedExpression.kt")
|
||||||
public void testLabeledDelegatedExpression() throws Exception {
|
public void testLabeledDelegatedExpression() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/delegatedProperty/inference/labeledDelegatedExpression.kt");
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/delegatedProperty/inference/labeledDelegatedExpression.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user