Report 'free function called as extension' on Function subclasses

You can't make a value of some type invokable as an extension by adding
'extension' annotation to the type
This commit is contained in:
Alexander Udalov
2015-05-26 17:34:43 +03:00
parent 596d378962
commit 12a6461006
3 changed files with 28 additions and 3 deletions
@@ -87,7 +87,14 @@ private fun createSynthesizedFunctionWithFirstParameterAsReceiver(descriptor: Fu
}
fun isSynthesizedInvoke(descriptor: DeclarationDescriptor): Boolean {
return descriptor.getName() == OperatorConventions.INVOKE &&
(descriptor as? FunctionDescriptor)?.getKind() == CallableMemberDescriptor.Kind.SYNTHESIZED &&
descriptor.getContainingDeclaration() is FunctionClassDescriptor
if (descriptor.getName() != OperatorConventions.INVOKE || descriptor !is FunctionDescriptor) return false
var real: FunctionDescriptor = descriptor
while (!real.getKind().isReal()) {
// You can't override two different synthesized invokes at the same time
real = real.getOverriddenDescriptors().singleOrNull() ?: return false
}
return real.getKind() == CallableMemberDescriptor.Kind.SYNTHESIZED &&
real.getContainingDeclaration() is FunctionClassDescriptor
}
@@ -1,3 +1,13 @@
fun foo(a: (String) -> Unit) {
"".<!FREE_FUNCTION_CALLED_AS_EXTENSION!>a<!>()
}
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<!>()
}
@@ -1,3 +1,11 @@
package
internal fun foo(/*0*/ a: (kotlin.String) -> kotlin.Unit): kotlin.Unit
internal fun foo(/*0*/ a: @[kotlin.extension()] A): kotlin.Unit
internal interface A : (kotlin.String) -> kotlin.Unit {
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 abstract override /*1*/ /*fake_override*/ fun invoke(/*0*/ p1: kotlin.String): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}