diff --git a/compiler/frontend/src/org/jetbrains/kotlin/cfg/ControlFlowInformationProvider.kt b/compiler/frontend/src/org/jetbrains/kotlin/cfg/ControlFlowInformationProvider.kt index 90fcc7d9327..618cedcc757 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/cfg/ControlFlowInformationProvider.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/cfg/ControlFlowInformationProvider.kt @@ -32,6 +32,7 @@ import org.jetbrains.kotlin.idea.MainFunctionDetector import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject +import org.jetbrains.kotlin.psi.psiUtil.forEachDescendantOfType import org.jetbrains.kotlin.resolve.* import org.jetbrains.kotlin.resolve.BindingContext.* import org.jetbrains.kotlin.resolve.bindingContextUtil.isUsedAsExpression @@ -97,6 +98,7 @@ class ControlFlowInformationProvider private constructor( } markStatements() + markAnnotationArguments() markUnusedExpressions() @@ -799,6 +801,21 @@ class ControlFlowInformationProvider private constructor( } } + private fun markAnnotationArguments() { + when (subroutine) { + is KtAnnotationEntry -> markAnnotationArguments(subroutine) + is KtAnnotated -> subroutine.annotationEntries.forEach { markAnnotationArguments(it) } + } + } + + private fun markAnnotationArguments(entry: KtAnnotationEntry) { + for (argument in entry.valueArguments) { + argument.getArgumentExpression()?.forEachDescendantOfType { + trace.record(USED_AS_EXPRESSION, it, true) + } + } + } + private fun checkIfExpressions() = pseudocode.traverse(TraversalOrder.FORWARD) { instruction -> val value = (instruction as? InstructionWithValue)?.outputValue for (element in instruction.owner.getValueElements(value)) { diff --git a/idea/testData/refactoring/inline/inlineVariableOrProperty/InAnnotation.kt b/idea/testData/refactoring/inline/inlineVariableOrProperty/InAnnotation.kt new file mode 100644 index 00000000000..8ee9304aa7f --- /dev/null +++ b/idea/testData/refactoring/inline/inlineVariableOrProperty/InAnnotation.kt @@ -0,0 +1,25 @@ +private const val TAG = "Tagged" + +annotation class InAnn(val value: String) + +@InAnn(TAG) class AnnHolder + +@InAnn(value = TAG) class AnotherAnnHolder + +@InAnn("This is $TAG") class ComplexAnnHolder { + @InAnn("That is $TAG") fun foo() {} +} + +@InAnn("This is also $TAG") fun bar() {} + +fun baz(@InAnn("This is $TAG too") x: Int) {} + +@Target(AnnotationTarget.EXPRESSION) +@Retention(AnnotationRetention.SOURCE) +annotation class ExprAnn(val value: String) + +val inProperty = TAG + +fun foo() { + val x = @ExprAnn(TAG) inProperty +} \ No newline at end of file diff --git a/idea/testData/refactoring/inline/inlineVariableOrProperty/InAnnotation.kt.after b/idea/testData/refactoring/inline/inlineVariableOrProperty/InAnnotation.kt.after new file mode 100644 index 00000000000..2ee4102b508 --- /dev/null +++ b/idea/testData/refactoring/inline/inlineVariableOrProperty/InAnnotation.kt.after @@ -0,0 +1,23 @@ +annotation class InAnn(val value: String) + +@InAnn("Tagged") class AnnHolder + +@InAnn(value = "Tagged") class AnotherAnnHolder + +@InAnn("This is Tagged") class ComplexAnnHolder { + @InAnn("That is Tagged") fun foo() {} +} + +@InAnn("This is also Tagged") fun bar() {} + +fun baz(@InAnn("This is ${} too") x: Int) {} + +@Target(AnnotationTarget.EXPRESSION) +@Retention(AnnotationRetention.SOURCE) +annotation class ExprAnn(val value: String) + +val inProperty = "Tagged" + +fun foo() { + val x = @ExprAnn() inProperty +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/refactoring/inline/InlineTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/refactoring/inline/InlineTestGenerated.java index 38f149ce343..78bea31475f 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/refactoring/inline/InlineTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/refactoring/inline/InlineTestGenerated.java @@ -521,6 +521,11 @@ public class InlineTestGenerated extends AbstractInlineTest { runTest("idea/testData/refactoring/inline/inlineVariableOrProperty/ifInQualifiedExpression.kt"); } + @TestMetadata("InAnnotation.kt") + public void testInAnnotation() throws Exception { + runTest("idea/testData/refactoring/inline/inlineVariableOrProperty/InAnnotation.kt"); + } + @TestMetadata("InFunctionLiteral.kt") public void testInFunctionLiteral() throws Exception { runTest("idea/testData/refactoring/inline/inlineVariableOrProperty/InFunctionLiteral.kt");