Function literal is now expression and function simultaneously for purposes of annotation target checking
This commit is contained in:
@@ -54,7 +54,7 @@ public class AnnotationChecker(private val additionalCheckers: Iterable<Addition
|
||||
}
|
||||
|
||||
public fun checkExpression(expression: JetExpression, trace: BindingTrace) {
|
||||
checkEntries(expression.getAnnotationEntries(), TargetLists.T_EXPRESSION, trace)
|
||||
checkEntries(expression.getAnnotationEntries(), getActualTargetList(expression, null), trace)
|
||||
if (expression is JetFunctionLiteralExpression) {
|
||||
for (parameter in expression.valueParameters) {
|
||||
parameter.typeReference?.let { check(it, trace) }
|
||||
@@ -172,6 +172,8 @@ public class AnnotationChecker(private val additionalCheckers: Iterable<Addition
|
||||
if (annotated.projectionKind == JetProjectionKind.STAR) TargetLists.T_STAR_PROJECTION else TargetLists.T_TYPE_PROJECTION
|
||||
is JetClassInitializer -> TargetLists.T_INITIALIZER
|
||||
is JetMultiDeclaration -> TargetLists.T_MULTI_DECLARATION
|
||||
is JetFunctionLiteralExpression -> TargetLists.T_FUNCTION_LITERAL
|
||||
is JetExpression -> TargetLists.T_EXPRESSION
|
||||
else -> TargetLists.EMPTY
|
||||
}
|
||||
}
|
||||
@@ -225,6 +227,8 @@ public class AnnotationChecker(private val additionalCheckers: Iterable<Addition
|
||||
|
||||
val T_EXPRESSION = targetList(EXPRESSION)
|
||||
|
||||
val T_FUNCTION_LITERAL = targetList(FUNCTION_LITERAL, FUNCTION, EXPRESSION)
|
||||
|
||||
val T_TYPE_REFERENCE = targetList(TYPE) {
|
||||
onlyWithUseSiteTarget(VALUE_PARAMETER)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
@Target(AnnotationTarget.FUNCTION)
|
||||
annotation class FunAnn
|
||||
|
||||
fun bar(arg: () -> Int) = arg()
|
||||
|
||||
@FunAnn fun gav() = 13
|
||||
|
||||
fun foo(arg: Int) {
|
||||
// Literal is annotatable
|
||||
bar @FunAnn { arg }
|
||||
// Function expression too
|
||||
val f = @FunAnn fun(): Int { return 42 }
|
||||
// But here, f and gav should be annotated instead
|
||||
bar(<!WRONG_ANNOTATION_TARGET!>@FunAnn<!> f)
|
||||
bar(<!WRONG_ANNOTATION_TARGET!>@FunAnn<!> ::gav)
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package
|
||||
|
||||
public fun bar(/*0*/ arg: () -> kotlin.Int): kotlin.Int
|
||||
public fun foo(/*0*/ arg: kotlin.Int): kotlin.Unit
|
||||
@FunAnn() public fun gav(): kotlin.Int
|
||||
|
||||
@kotlin.annotation.Target(allowedTargets = {AnnotationTarget.FUNCTION}) @kotlin.annotation.annotation() public final class FunAnn : kotlin.Annotation {
|
||||
public constructor FunAnn()
|
||||
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
|
||||
}
|
||||
@@ -7,5 +7,5 @@ fun transform(i: Int, tr: (Int) -> Int): Int = <!WRONG_ANNOTATION_TARGET!>@base<
|
||||
@base <!WRONG_ANNOTATION_TARGET!>@special<!> fun foo(i: Int): Int {
|
||||
val j = <!WRONG_ANNOTATION_TARGET!>@base<!> @special i + 1
|
||||
if (j == 1) return foo(@special <!WRONG_ANNOTATION_TARGET!>@base<!> 42)
|
||||
return transform(@special j, <!WRONG_ANNOTATION_TARGET!>@base<!> @special { @special it * 2 })
|
||||
return transform(@special j, @base @special { @special it * 2 })
|
||||
}
|
||||
|
||||
@@ -1034,6 +1034,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("functions.kt")
|
||||
public void testFunctions() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/annotations/options/functions.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("javaDocumented.kt")
|
||||
public void testJavaDocumented() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/annotations/options/javaDocumented.kt");
|
||||
|
||||
@@ -32,11 +32,11 @@ public enum class KotlinTarget(val description: String, val isDefault: Boolean =
|
||||
LOCAL_VARIABLE("local variable"),
|
||||
VALUE_PARAMETER("value parameter"),
|
||||
CONSTRUCTOR("constructor"),
|
||||
FUNCTION("function"), // includes *_FUNCTION
|
||||
FUNCTION("function"), // includes *_FUNCTION and FUNCTION_LITERAL
|
||||
PROPERTY_GETTER("getter"),
|
||||
PROPERTY_SETTER("setter"),
|
||||
TYPE("type usage", false),
|
||||
EXPRESSION("expression", false),
|
||||
EXPRESSION("expression", false), // includes FUNCTION_LITERAL
|
||||
FILE("file", false),
|
||||
|
||||
TYPE_PROJECTION("type projection", false),
|
||||
@@ -60,7 +60,8 @@ public enum class KotlinTarget(val description: String, val isDefault: Boolean =
|
||||
TOP_LEVEL_PROPERTY("top level property", false),
|
||||
|
||||
INITIALIZER("initializer", false),
|
||||
MULTI_DECLARATION("multi declaration", false)
|
||||
MULTI_DECLARATION("multi declaration", false),
|
||||
FUNCTION_LITERAL("function literal", false)
|
||||
;
|
||||
|
||||
companion object {
|
||||
|
||||
Reference in New Issue
Block a user