Forbidden old invokeExtension convention.
This commit is contained in:
@@ -453,8 +453,6 @@ public interface Errors {
|
||||
DiagnosticFactory1<JetExpression, JetType> MISSING_RECEIVER = DiagnosticFactory1.create(ERROR);
|
||||
DiagnosticFactory0<JetExpression> NO_RECEIVER_ALLOWED = DiagnosticFactory0.create(ERROR);
|
||||
|
||||
DiagnosticFactory0<JetExpression> FREE_FUNCTION_CALLED_AS_EXTENSION = DiagnosticFactory0.create(ERROR);
|
||||
|
||||
// Call resolution
|
||||
|
||||
DiagnosticFactory1<JetExpression, String> ILLEGAL_SELECTOR = DiagnosticFactory1.create(ERROR);
|
||||
@@ -475,6 +473,7 @@ public interface Errors {
|
||||
DiagnosticFactory1<PsiElement, Collection<? extends ResolvedCall<?>>> NONE_APPLICABLE = DiagnosticFactory1.create(ERROR);
|
||||
DiagnosticFactory1<PsiElement, Collection<? extends ResolvedCall<?>>> CANNOT_COMPLETE_RESOLVE = DiagnosticFactory1.create(ERROR);
|
||||
DiagnosticFactory1<PsiElement, Collection<? extends ResolvedCall<?>>> UNRESOLVED_REFERENCE_WRONG_RECEIVER = DiagnosticFactory1.create(ERROR);
|
||||
DiagnosticFactory1<PsiElement, JetExpression> INVOKE_EXTENSION_ON_NOT_EXTENSION_FUNCTION = DiagnosticFactory1.create(ERROR);
|
||||
|
||||
DiagnosticFactory1<PsiElement, TypeParameterDescriptor> TYPE_PARAMETER_AS_REIFIED = DiagnosticFactory1.create(ERROR);
|
||||
DiagnosticFactory1<PsiElement, JetType> REIFIED_TYPE_FORBIDDEN_SUBSTITUTION = DiagnosticFactory1.create(ERROR);
|
||||
|
||||
+1
-2
@@ -591,13 +591,12 @@ public class DefaultErrorMessages {
|
||||
MAP.put(NONE_APPLICABLE, "None of the following functions can be called with the arguments supplied: {0}", AMBIGUOUS_CALLS);
|
||||
MAP.put(CANNOT_COMPLETE_RESOLVE, "Cannot choose among the following candidates without completing type inference: {0}", AMBIGUOUS_CALLS);
|
||||
MAP.put(UNRESOLVED_REFERENCE_WRONG_RECEIVER, "Unresolved reference. None of the following candidates is applicable because of receiver type mismatch: {0}", AMBIGUOUS_CALLS);
|
||||
MAP.put(INVOKE_EXTENSION_ON_NOT_EXTENSION_FUNCTION, "Impossible call as extension because {0} is not an extension function.", ELEMENT_TEXT);
|
||||
|
||||
MAP.put(NO_VALUE_FOR_PARAMETER, "No value passed for parameter {0}", NAME);
|
||||
MAP.put(MISSING_RECEIVER, "A receiver of type {0} is required", RENDER_TYPE);
|
||||
MAP.put(NO_RECEIVER_ALLOWED, "No receiver can be passed to this function or property");
|
||||
|
||||
MAP.put(FREE_FUNCTION_CALLED_AS_EXTENSION, "The function cannot be called as an extension function");
|
||||
|
||||
MAP.put(CREATING_AN_INSTANCE_OF_ABSTRACT_CLASS, "Cannot create an instance of an abstract class");
|
||||
|
||||
MAP.put(TYPE_INFERENCE_CONFLICTING_SUBSTITUTIONS, "Type inference failed: {0}", TYPE_INFERENCE_CONFLICTING_SUBSTITUTIONS_RENDERER);
|
||||
|
||||
@@ -267,14 +267,18 @@ public class CandidateResolver(
|
||||
}
|
||||
|
||||
private fun CallCandidateResolutionContext<*>.checkNonExtensionCalledWithReceiver() = checkAndReport {
|
||||
if (isSynthesizedInvoke(candidateCall.getCandidateDescriptor())
|
||||
&& !KotlinBuiltIns.isExtensionFunctionType(candidateCall.getDispatchReceiver().getType())
|
||||
val call = candidateCall.call
|
||||
if (call is CallTransformer.CallForImplicitInvoke && candidateCall.extensionReceiver.exists()
|
||||
&& candidateCall.dispatchReceiver.exists()
|
||||
) {
|
||||
tracing.freeFunctionCalledAsExtension(trace)
|
||||
OTHER_ERROR
|
||||
} else {
|
||||
SUCCESS
|
||||
if (call.dispatchReceiver == candidateCall.dispatchReceiver
|
||||
&& !KotlinBuiltIns.isExactExtensionFunctionType(call.dispatchReceiver.type)
|
||||
) {
|
||||
tracing.nonExtensionFunctionCalledAsExtension(trace)
|
||||
return@checkAndReport OTHER_ERROR
|
||||
}
|
||||
}
|
||||
SUCCESS
|
||||
}
|
||||
|
||||
private fun getReceiverSuper(receiver: ReceiverValue): JetSuperExpression? {
|
||||
|
||||
+2
-2
@@ -253,7 +253,7 @@ public abstract class AbstractTracingStrategy implements TracingStrategy {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void freeFunctionCalledAsExtension(@NotNull BindingTrace trace) {
|
||||
trace.report(FREE_FUNCTION_CALLED_AS_EXTENSION.on(reference));
|
||||
public void nonExtensionFunctionCalledAsExtension(@NotNull BindingTrace trace) {
|
||||
trace.report(INVOKE_EXTENSION_ON_NOT_EXTENSION_FUNCTION.on(reference, reference));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,7 +101,7 @@ public interface TracingStrategy {
|
||||
public void typeInferenceFailed(@NotNull BindingTrace trace, @NotNull InferenceErrorData inferenceErrorData) {}
|
||||
|
||||
@Override
|
||||
public void freeFunctionCalledAsExtension(@NotNull BindingTrace trace) { }
|
||||
public void nonExtensionFunctionCalledAsExtension(@NotNull BindingTrace trace) { }
|
||||
};
|
||||
|
||||
void bindCall(@NotNull BindingTrace trace, @NotNull Call call);
|
||||
@@ -153,5 +153,5 @@ public interface TracingStrategy {
|
||||
|
||||
void typeInferenceFailed(@NotNull BindingTrace trace, @NotNull InferenceErrorData inferenceErrorData);
|
||||
|
||||
void freeFunctionCalledAsExtension(@NotNull BindingTrace trace);
|
||||
void nonExtensionFunctionCalledAsExtension(@NotNull BindingTrace trace);
|
||||
}
|
||||
|
||||
+1
-1
@@ -534,7 +534,7 @@ public class ControlStructureTypingUtils {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void freeFunctionCalledAsExtension(@NotNull BindingTrace trace) {
|
||||
public void nonExtensionFunctionCalledAsExtension(@NotNull BindingTrace trace) {
|
||||
logError();
|
||||
}
|
||||
}
|
||||
|
||||
+2
-15
@@ -1,16 +1,4 @@
|
||||
class A() {
|
||||
fun A.invoke(a: A) = "$this ${this@A} $a"
|
||||
}
|
||||
|
||||
fun test1() {
|
||||
val a = A()
|
||||
val b = A()
|
||||
val c = A()
|
||||
a.b(c)
|
||||
a b c
|
||||
}
|
||||
|
||||
fun test2() {
|
||||
fun test() {
|
||||
val a: (@Extension Function2<*, *, *>).(@Extension Function2<*, *, *>)->Unit = {}
|
||||
val b: (@Extension Function2<*, *, *>).(@Extension Function2<*, *, *>)->Unit = {"$this $it"}
|
||||
val c: (@Extension Function2<*, *, *>).(@Extension Function2<*, *, *>)->Unit = {}
|
||||
@@ -22,8 +10,7 @@ fun Int.foo(a: Int) = this * a
|
||||
val boo = fun Int.(a: Int): Int = this + a
|
||||
|
||||
fun box(): String {
|
||||
test1()
|
||||
test2()
|
||||
test()
|
||||
1 foo 2
|
||||
3 boo 4
|
||||
return "OK"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
fun foo(a: (String) -> Unit) {
|
||||
"".<!FREE_FUNCTION_CALLED_AS_EXTENSION!>a<!>()
|
||||
"".<!INVOKE_EXTENSION_ON_NOT_EXTENSION_FUNCTION!>a<!>()
|
||||
}
|
||||
|
||||
|
||||
@@ -9,5 +9,5 @@ interface A : (String) -> Unit {}
|
||||
fun foo(a: @Extension A) {
|
||||
// @Extension annotation on an unrelated type shouldn't have any effect on this diagnostic.
|
||||
// Only kotlin.Function{n} type annotated with @Extension should
|
||||
"".<!FREE_FUNCTION_CALLED_AS_EXTENSION!>a<!>()
|
||||
}
|
||||
"".<!INVOKE_EXTENSION_ON_NOT_EXTENSION_FUNCTION!>a<!>()
|
||||
}
|
||||
+4
-4
@@ -1,13 +1,13 @@
|
||||
fun <E : String?, T : ((CharSequence).() -> Unit)?> foo(x: E, y: T) {
|
||||
if (x != null) {
|
||||
<!DEBUG_INFO_SMARTCAST!>x<!>.<!UNSAFE_CALL!>y<!>()
|
||||
<!DEBUG_INFO_SMARTCAST!>x<!>.<!UNSAFE_CALL, INVOKE_EXTENSION_ON_NOT_EXTENSION_FUNCTION!>y<!>()
|
||||
}
|
||||
|
||||
if (y != null) {
|
||||
x<!UNSAFE_CALL!>.<!><!DEBUG_INFO_SMARTCAST!>y<!>()
|
||||
x<!UNSAFE_CALL!>.<!><!INVOKE_EXTENSION_ON_NOT_EXTENSION_FUNCTION, DEBUG_INFO_SMARTCAST!>y<!>()
|
||||
}
|
||||
|
||||
if (x != null && y != null) {
|
||||
<!DEBUG_INFO_SMARTCAST!>x<!>.<!DEBUG_INFO_SMARTCAST!>y<!>()
|
||||
<!DEBUG_INFO_SMARTCAST!>x<!>.<!INVOKE_EXTENSION_ON_NOT_EXTENSION_FUNCTION, DEBUG_INFO_SMARTCAST!>y<!>()
|
||||
}
|
||||
}
|
||||
}
|
||||
Vendored
+3
-3
@@ -5,7 +5,7 @@ fun test1(f: String.() -> Unit) {
|
||||
}
|
||||
|
||||
fun test2(f: (Int) -> Int) {
|
||||
1.<!FREE_FUNCTION_CALLED_AS_EXTENSION!>f<!>(<!TOO_MANY_ARGUMENTS!>2<!>)
|
||||
1.<!INVOKE_EXTENSION_ON_NOT_EXTENSION_FUNCTION!>f<!>(<!TOO_MANY_ARGUMENTS!>2<!>)
|
||||
|
||||
2.<!FREE_FUNCTION_CALLED_AS_EXTENSION!>(f)<!>(<!TOO_MANY_ARGUMENTS!>2<!>)
|
||||
}
|
||||
2.<!INVOKE_EXTENSION_ON_NOT_EXTENSION_FUNCTION!>(f)<!>(<!TOO_MANY_ARGUMENTS!>2<!>)
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
class B
|
||||
|
||||
class A {
|
||||
operator fun B.invoke() = 4
|
||||
}
|
||||
|
||||
class X {
|
||||
operator fun invoke() = 3
|
||||
}
|
||||
|
||||
fun test(a: A, b: B) {
|
||||
with (a) {
|
||||
b()
|
||||
(b)()
|
||||
}
|
||||
|
||||
X()()
|
||||
val x = X()
|
||||
x()
|
||||
(x)()
|
||||
}
|
||||
|
||||
fun test(c: () -> String, e: Int.() -> String) {
|
||||
c()
|
||||
(c)()
|
||||
|
||||
3.e()
|
||||
3.(e)()
|
||||
with(3) {
|
||||
e()
|
||||
(e)()
|
||||
}
|
||||
}
|
||||
|
||||
fun <T, R> with(receiver: T, f: T.() -> R): R = receiver.f()
|
||||
@@ -0,0 +1,28 @@
|
||||
package
|
||||
|
||||
public fun test(/*0*/ c: () -> kotlin.String, /*1*/ e: kotlin.Int.() -> kotlin.String): kotlin.Unit
|
||||
public fun test(/*0*/ a: A, /*1*/ b: B): kotlin.Unit
|
||||
public fun </*0*/ T, /*1*/ R> with(/*0*/ receiver: T, /*1*/ f: T.() -> R): R
|
||||
|
||||
public final class A {
|
||||
public constructor A()
|
||||
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
|
||||
public final operator fun B.invoke(): kotlin.Int
|
||||
}
|
||||
|
||||
public 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
|
||||
}
|
||||
|
||||
public final class X {
|
||||
public constructor X()
|
||||
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 final operator fun invoke(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
Vendored
+1
-1
@@ -4,7 +4,7 @@ interface Foo {
|
||||
}
|
||||
|
||||
fun test(a: A, foo: Foo) {
|
||||
a.foo()
|
||||
a.<!INVOKE_EXTENSION_ON_NOT_EXTENSION_FUNCTION!>foo<!>()
|
||||
}
|
||||
|
||||
fun test(a: Int, foo: Int.()->Unit) {
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
class B
|
||||
|
||||
class A {
|
||||
operator fun B.invoke() {}
|
||||
}
|
||||
|
||||
val B.a: () -> Int get() = { 5 }
|
||||
|
||||
fun test(a: A, b: B) {
|
||||
val <!UNUSED_VARIABLE!>x<!>: Int = b.a()
|
||||
|
||||
b.<!INVOKE_EXTENSION_ON_NOT_EXTENSION_FUNCTION!>(a)<!>()
|
||||
|
||||
with(b) {
|
||||
val <!UNUSED_VARIABLE!>y<!>: Int = a()
|
||||
<!MISSING_RECEIVER!>(a)<!>()
|
||||
}
|
||||
}
|
||||
|
||||
fun <T, R> with(receiver: T, f: T.() -> R): R = receiver.f()
|
||||
@@ -0,0 +1,20 @@
|
||||
package
|
||||
|
||||
public val B.a: () -> kotlin.Int
|
||||
public fun test(/*0*/ a: A, /*1*/ b: B): kotlin.Unit
|
||||
public fun </*0*/ T, /*1*/ R> with(/*0*/ receiver: T, /*1*/ f: T.() -> R): R
|
||||
|
||||
public final class A {
|
||||
public constructor A()
|
||||
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
|
||||
public final operator fun B.invoke(): kotlin.Unit
|
||||
}
|
||||
|
||||
public 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
|
||||
}
|
||||
@@ -1,9 +1,5 @@
|
||||
class Foo() {
|
||||
fun Int.invoke() {}
|
||||
}
|
||||
|
||||
fun bar(f: Foo, i: Int) {
|
||||
fun bar(f: Int.() -> Unit, i: Int) {
|
||||
with (i) {
|
||||
f<caret>()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,4 @@
|
||||
class Foo() {
|
||||
fun Int.invoke() {}
|
||||
}
|
||||
|
||||
fun bar(f: Foo, i: Int) {
|
||||
fun bar(f: Int.() -> Unit, i: Int) {
|
||||
with (i) {
|
||||
f<caret>()
|
||||
}
|
||||
@@ -11,8 +7,8 @@ fun bar(f: Foo, i: Int) {
|
||||
|
||||
Resolved call:
|
||||
|
||||
Resulting descriptor: fun Int.invoke(): Unit defined in Foo
|
||||
Resulting descriptor: operator fun Int.invoke(): Unit defined in kotlin.Function1
|
||||
|
||||
Explicit receiver kind = DISPATCH_RECEIVER
|
||||
Dispatch receiver = f {Foo}
|
||||
Dispatch receiver = f {[@kotlin.Extension] Function1<Int, Unit>}
|
||||
Extension receiver = IntExt{fun Int.<anonymous>(): Unit defined in bar}
|
||||
|
||||
@@ -12815,6 +12815,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
|
||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/tests/resolve/invoke"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("implicitInvoke.kt")
|
||||
public void testImplicitInvoke() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/resolve/invoke/implicitInvoke.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("invokeAsExtension.kt")
|
||||
public void testInvokeAsExtension() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/resolve/invoke/invokeAsExtension.kt");
|
||||
@@ -12881,6 +12887,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("wrongInvokeExtension.kt")
|
||||
public void testWrongInvokeExtension() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/resolve/invoke/wrongInvokeExtension.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/diagnostics/tests/resolve/invoke/errors")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
class A {
|
||||
fun test(b: B) {
|
||||
fun test(b: A.() -> Unit) {
|
||||
<selection>this.b()</selection>
|
||||
}
|
||||
}
|
||||
|
||||
class B() {
|
||||
fun A.invoke() {}
|
||||
}
|
||||
@@ -1,9 +1,5 @@
|
||||
class A {
|
||||
fun test(b: B) {
|
||||
fun test(b: A.() -> Unit) {
|
||||
b()
|
||||
}
|
||||
}
|
||||
|
||||
class B() {
|
||||
fun A.invoke() {}
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
class Bar {
|
||||
init {
|
||||
Foo()()
|
||||
}
|
||||
}
|
||||
|
||||
class Foo() {
|
||||
fun Bar.invoke() {}
|
||||
}
|
||||
|
||||
fun foobar(f: Foo) {
|
||||
<selection>Bar().f()</selection>
|
||||
Bar().f()
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
Bar().f()
|
||||
|
||||
Bar().f()
|
||||
@@ -365,12 +365,6 @@ public class JetPsiUnifierTestGenerated extends AbstractJetPsiUnifierTest {
|
||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/unifier/equivalence/expressions/calls"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("bothReceivers.kt")
|
||||
public void testBothReceivers() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/unifier/equivalence/expressions/calls/bothReceivers.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("callAndCalleeRuntime.kt")
|
||||
public void testCallAndCalleeRuntime() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/unifier/equivalence/expressions/calls/callAndCalleeRuntime.kt");
|
||||
|
||||
@@ -1,20 +1,7 @@
|
||||
// KT-3998 Infix call doesn't work for function literals and another classes which implements invoke convention (in JS backend)
|
||||
package foo
|
||||
|
||||
class A(val s: String) {
|
||||
fun A.invoke(a: A) = "${this.s} ${this@A.s} ${a.s}"
|
||||
}
|
||||
|
||||
fun test1(): String {
|
||||
val a = A("a")
|
||||
val b = A("b")
|
||||
val c = A("c")
|
||||
val f = a.b(c) // works
|
||||
val s = a b c //compiler crashes
|
||||
return "$f | $s"
|
||||
}
|
||||
|
||||
fun test2(): String {
|
||||
fun test(): String {
|
||||
val a: (@Extension Function2<*, *, *>).(@Extension Function2<*, *, *>)->String = { "a" }
|
||||
val b: (@Extension Function2<*, *, *>).(@Extension Function2<*, *, *>)->String = {
|
||||
val aa = this as @Extension Function2<Any?, Any?, Any?>;
|
||||
@@ -29,8 +16,7 @@ fun test2(): String {
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
assertEquals("a b c | a b c", test1())
|
||||
assertEquals("a b c | a b c", test2())
|
||||
assertEquals("a b c | a b c", test())
|
||||
|
||||
return "OK"
|
||||
}
|
||||
|
||||
+2
-19
@@ -4,6 +4,7 @@
|
||||
* This led to runtime errors (see KT-7692), so the test is temporarily disabled.
|
||||
*
|
||||
* TODO: support inheritance from function types and re-enable this test
|
||||
* NOTE: inheritance from extension function is forbidden now
|
||||
*/
|
||||
|
||||
package foo
|
||||
@@ -16,42 +17,24 @@ class Baz/* : Function2<Int, Boolean, String>*/ {
|
||||
fun invoke(i: Int, b: Boolean) = "Baz.invoke($i, $b)"
|
||||
}
|
||||
|
||||
class ExtBar/* : ExtensionFunction0<String, String>*/ {
|
||||
fun String.invoke() = "ExtBar.invoke($this)"
|
||||
}
|
||||
|
||||
class ExtBaz/* : ExtensionFunction2<String, Int, Boolean, String>*/ {
|
||||
fun String.invoke(i: Int, b: Boolean) = "ExtBaz.invoke($this, $i, $b)"
|
||||
}
|
||||
|
||||
class Mixed/* :
|
||||
Function1<Int, String>,
|
||||
Function2<Int, Boolean, String>,
|
||||
ExtensionFunction1<Int, Boolean, String>,
|
||||
ExtensionFunction2<Int, Int, Boolean, String>*/
|
||||
Function2<Int, Boolean, String>*/
|
||||
{
|
||||
fun invoke(i: Int) = "Mixed.invoke($i)"
|
||||
fun invoke(i: Int, b: Boolean) = "Mixed.invoke($i, $b)"
|
||||
fun Int.invoke(b: Boolean) = "ext Mixed.invoke($this, $b)"
|
||||
fun Int.invoke(i: Int, b: Boolean) = "ext Mixed.invoke($this, $i, $b)"
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val bar = Bar()
|
||||
val baz = Baz()
|
||||
val extBar = ExtBar()
|
||||
val extBaz = ExtBaz()
|
||||
val mixed = Mixed()
|
||||
|
||||
assertEquals("Bar.invoke()", bar())
|
||||
assertEquals("Baz.invoke(2, false)", baz(2, false))
|
||||
assertEquals("ExtBar.invoke(2e2)", "2e2".extBar())
|
||||
assertEquals("ExtBaz.invoke(29, 34, true)", "29".extBaz(34, true))
|
||||
|
||||
assertEquals("Mixed.invoke(45)", mixed(45))
|
||||
assertEquals("Mixed.invoke(552, true)", mixed(552, true))
|
||||
assertEquals("ext Mixed.invoke(21, true)", 21.mixed(true))
|
||||
assertEquals("ext Mixed.invoke(29, 304, false)", 29.mixed(304, false))
|
||||
|
||||
return "OK"
|
||||
}
|
||||
|
||||
Vendored
+1
-4
@@ -1,12 +1,9 @@
|
||||
package foo
|
||||
|
||||
class A
|
||||
class B {
|
||||
fun A.invoke(i: Int) = i
|
||||
}
|
||||
|
||||
fun box(): Boolean {
|
||||
val a = A()
|
||||
val b = B()
|
||||
val b = fun A.(i: Int) = i
|
||||
return a.(b)(1) == 1
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user