Function expressions can be now annotated with expression-targeted annotation #KT-9323 Fixed
This commit is contained in:
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.resolve
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.*
|
import org.jetbrains.kotlin.descriptors.annotations.*
|
||||||
import org.jetbrains.kotlin.diagnostics.Errors
|
import org.jetbrains.kotlin.diagnostics.Errors
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
@@ -28,14 +29,12 @@ import org.jetbrains.kotlin.types.JetType
|
|||||||
import org.jetbrains.kotlin.types.TypeUtils
|
import org.jetbrains.kotlin.types.TypeUtils
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.isRepeatableAnnotation
|
import org.jetbrains.kotlin.resolve.descriptorUtil.isRepeatableAnnotation
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget.*
|
import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.getAnnotationRetention
|
import org.jetbrains.kotlin.resolve.descriptorUtil.getAnnotationRetention
|
||||||
import org.jetbrains.kotlin.resolve.inline.InlineUtil
|
import org.jetbrains.kotlin.resolve.inline.InlineUtil
|
||||||
|
|
||||||
public class AnnotationChecker(private val additionalCheckers: Iterable<AdditionalAnnotationChecker>) {
|
public class AnnotationChecker(private val additionalCheckers: Iterable<AdditionalAnnotationChecker>) {
|
||||||
|
|
||||||
public fun check(annotated: JetAnnotated, trace: BindingTrace, descriptor: ClassDescriptor? = null) {
|
public fun check(annotated: JetAnnotated, trace: BindingTrace, descriptor: DeclarationDescriptor? = null) {
|
||||||
if (annotated is JetTypeParameter) return // TODO: support type parameter annotations
|
if (annotated is JetTypeParameter) return // TODO: support type parameter annotations
|
||||||
val actualTargets = getActualTargetList(annotated, descriptor)
|
val actualTargets = getActualTargetList(annotated, descriptor)
|
||||||
checkEntries(annotated.annotationEntries, actualTargets, trace)
|
checkEntries(annotated.annotationEntries, actualTargets, trace)
|
||||||
@@ -157,9 +156,10 @@ public class AnnotationChecker(private val additionalCheckers: Iterable<Addition
|
|||||||
return getActualTargetList(annotated, descriptor).defaultTargets
|
return getActualTargetList(annotated, descriptor).defaultTargets
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getActualTargetList(annotated: JetElement, descriptor: ClassDescriptor?): TargetList {
|
private fun getActualTargetList(annotated: JetElement, descriptor: DeclarationDescriptor?): TargetList {
|
||||||
return when (annotated) {
|
return when (annotated) {
|
||||||
is JetClassOrObject -> descriptor?.let { TargetList(KotlinTarget.classActualTargets(it)) } ?: TargetLists.T_CLASSIFIER
|
is JetClassOrObject ->
|
||||||
|
(descriptor as? ClassDescriptor)?.let { TargetList(KotlinTarget.classActualTargets(it)) } ?: TargetLists.T_CLASSIFIER
|
||||||
is JetMultiDeclarationEntry -> TargetLists.T_LOCAL_VARIABLE
|
is JetMultiDeclarationEntry -> TargetLists.T_LOCAL_VARIABLE
|
||||||
is JetProperty -> {
|
is JetProperty -> {
|
||||||
if (annotated.isLocal)
|
if (annotated.isLocal)
|
||||||
@@ -177,7 +177,9 @@ public class AnnotationChecker(private val additionalCheckers: Iterable<Addition
|
|||||||
}
|
}
|
||||||
is JetConstructor<*> -> TargetLists.T_CONSTRUCTOR
|
is JetConstructor<*> -> TargetLists.T_CONSTRUCTOR
|
||||||
is JetFunction -> {
|
is JetFunction -> {
|
||||||
if (annotated.isLocal)
|
if (DescriptorUtils.isFunctionExpression(descriptor))
|
||||||
|
TargetLists.T_FUNCTION_EXPRESSION
|
||||||
|
else if (annotated.isLocal)
|
||||||
TargetLists.T_LOCAL_FUNCTION
|
TargetLists.T_LOCAL_FUNCTION
|
||||||
else if (annotated.parent is JetClassOrObject || annotated.parent is JetClassBody)
|
else if (annotated.parent is JetClassOrObject || annotated.parent is JetClassBody)
|
||||||
TargetLists.T_MEMBER_FUNCTION
|
TargetLists.T_MEMBER_FUNCTION
|
||||||
@@ -250,6 +252,8 @@ public class AnnotationChecker(private val additionalCheckers: Iterable<Addition
|
|||||||
|
|
||||||
val T_FUNCTION_LITERAL = targetList(FUNCTION_LITERAL, FUNCTION, EXPRESSION)
|
val T_FUNCTION_LITERAL = targetList(FUNCTION_LITERAL, FUNCTION, EXPRESSION)
|
||||||
|
|
||||||
|
val T_FUNCTION_EXPRESSION = targetList(FUNCTION_EXPRESSION, FUNCTION, EXPRESSION)
|
||||||
|
|
||||||
val T_OBJECT_LITERAL = targetList(OBJECT_LITERAL, CLASS, EXPRESSION)
|
val T_OBJECT_LITERAL = targetList(OBJECT_LITERAL, CLASS, EXPRESSION)
|
||||||
|
|
||||||
val T_TYPE_REFERENCE = targetList(TYPE) {
|
val T_TYPE_REFERENCE = targetList(TYPE) {
|
||||||
|
|||||||
@@ -182,8 +182,7 @@ public class ModifiersChecker {
|
|||||||
private void checkModifierListCommon(@NotNull JetDeclaration modifierListOwner, @NotNull DeclarationDescriptor descriptor) {
|
private void checkModifierListCommon(@NotNull JetDeclaration modifierListOwner, @NotNull DeclarationDescriptor descriptor) {
|
||||||
AnnotationUseSiteTargetChecker.INSTANCE$.check(modifierListOwner, descriptor, trace);
|
AnnotationUseSiteTargetChecker.INSTANCE$.check(modifierListOwner, descriptor, trace);
|
||||||
runDeclarationCheckers(modifierListOwner, descriptor);
|
runDeclarationCheckers(modifierListOwner, descriptor);
|
||||||
ClassDescriptor classDescriptor = descriptor instanceof ClassDescriptor ? (ClassDescriptor) descriptor : null;
|
annotationChecker.check(modifierListOwner, trace, descriptor);
|
||||||
annotationChecker.check(modifierListOwner, trace, classDescriptor);
|
|
||||||
ModifierCheckerCore.INSTANCE$.check(modifierListOwner, trace, descriptor);
|
ModifierCheckerCore.INSTANCE$.check(modifierListOwner, trace, descriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
@Target(AnnotationTarget.EXPRESSION)
|
||||||
|
annotation class ExprAnn
|
||||||
|
|
||||||
|
@Target(AnnotationTarget.FUNCTION)
|
||||||
|
annotation class FunAnn
|
||||||
|
|
||||||
|
fun foo(): Int {
|
||||||
|
val x = @ExprAnn fun() = 1
|
||||||
|
val y = @FunAnn fun() = 2
|
||||||
|
return x() + y()
|
||||||
|
}
|
||||||
+17
@@ -0,0 +1,17 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun foo(): kotlin.Int
|
||||||
|
|
||||||
|
@kotlin.annotation.Target(allowedTargets = {AnnotationTarget.EXPRESSION}) @kotlin.annotation.annotation() public final class ExprAnn : kotlin.Annotation {
|
||||||
|
public constructor ExprAnn()
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
@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
|
||||||
|
}
|
||||||
@@ -1052,6 +1052,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("functionExpression.kt")
|
||||||
|
public void testFunctionExpression() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/annotations/options/functionExpression.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("functions.kt")
|
@TestMetadata("functions.kt")
|
||||||
public void testFunctions() throws Exception {
|
public void testFunctions() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/annotations/options/functions.kt");
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/annotations/options/functions.kt");
|
||||||
|
|||||||
@@ -62,6 +62,7 @@ public enum class KotlinTarget(val description: String, val isDefault: Boolean =
|
|||||||
INITIALIZER("initializer", false),
|
INITIALIZER("initializer", false),
|
||||||
MULTI_DECLARATION("multi declaration", false),
|
MULTI_DECLARATION("multi declaration", false),
|
||||||
FUNCTION_LITERAL("function literal", false),
|
FUNCTION_LITERAL("function literal", false),
|
||||||
|
FUNCTION_EXPRESSION("function expression", false),
|
||||||
OBJECT_LITERAL("object literal", false)
|
OBJECT_LITERAL("object literal", false)
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user