diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/util/modifierListModifactor.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/util/modifierListModifactor.kt index 93ee365802c..51815acf6df 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/util/modifierListModifactor.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/util/modifierListModifactor.kt @@ -72,6 +72,10 @@ fun KtAnnotated.findAnnotation(annotationFqName: FqName): KtAnnotationEntry? { if (annotationEntries.isEmpty()) return null val context = analyze(bodyResolveMode = BodyResolveMode.PARTIAL) + val descriptor = context[BindingContext.DECLARATION_TO_DESCRIPTOR, this] ?: return null + + // Make sure all annotations are resolved + descriptor.annotations.toList() return annotationEntries.firstOrNull { entry -> context.get(BindingContext.ANNOTATION, entry)?.fqName == annotationFqName } } diff --git a/idea/idea-android/idea-android.iml b/idea/idea-android/idea-android.iml index 07755e96533..18a8cf1641d 100644 --- a/idea/idea-android/idea-android.iml +++ b/idea/idea-android/idea-android.iml @@ -27,5 +27,6 @@ + \ No newline at end of file diff --git a/idea/idea-android/src/org/jetbrains/kotlin/android/ParcelableUtil.kt b/idea/idea-android/src/org/jetbrains/kotlin/android/ParcelableUtil.kt index a8583676775..fc9d6139a6d 100644 --- a/idea/idea-android/src/org/jetbrains/kotlin/android/ParcelableUtil.kt +++ b/idea/idea-android/src/org/jetbrains/kotlin/android/ParcelableUtil.kt @@ -20,6 +20,7 @@ import com.android.SdkConstants.CLASS_PARCEL import com.android.SdkConstants.CLASS_PARCELABLE import com.intellij.openapi.fileEditor.FileDocumentManager import com.intellij.psi.PsiDocumentManager +import kotlinx.android.parcel.Parcelize import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.PrimitiveType import org.jetbrains.kotlin.descriptors.ParameterDescriptor @@ -30,6 +31,7 @@ import org.jetbrains.kotlin.idea.codeInsight.shorten.performDelayedRefactoringRe import org.jetbrains.kotlin.idea.intentions.getLeftMostReceiverExpression import org.jetbrains.kotlin.idea.search.usagesSearch.descriptor import org.jetbrains.kotlin.idea.search.usagesSearch.propertyDescriptor +import org.jetbrains.kotlin.idea.util.findAnnotation import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.psi.* @@ -57,6 +59,10 @@ private val WRITE_TO_PARCEL_WITH_SUPER_TEXT = private val DESCRIBE_CONTENTS_TEXT = "override fun describeContents(): Int {\nreturn 0\n}" private val CONSTRUCTOR_TEXT = "constructor($PARCEL_NAME: $CLASS_PARCEL)" +private val PARCELIZE_FQNAME = FqName(Parcelize::class.java.name) + +//TODO add test +fun KtClass.isParcelize() = findAnnotation(PARCELIZE_FQNAME) != null fun KtClass.canAddParcelable(): Boolean = findParcelableSupertype() == null diff --git a/idea/idea-android/src/org/jetbrains/kotlin/android/intention/ImplementParcelableAction.kt b/idea/idea-android/src/org/jetbrains/kotlin/android/intention/ImplementParcelableAction.kt index 375adfc40c4..6bdb56f2436 100644 --- a/idea/idea-android/src/org/jetbrains/kotlin/android/intention/ImplementParcelableAction.kt +++ b/idea/idea-android/src/org/jetbrains/kotlin/android/intention/ImplementParcelableAction.kt @@ -23,6 +23,7 @@ import org.jetbrains.android.util.AndroidBundle import org.jetbrains.kotlin.android.canAddParcelable import org.jetbrains.kotlin.android.implementParcelable import org.jetbrains.kotlin.android.insideBody +import org.jetbrains.kotlin.android.isParcelize import org.jetbrains.kotlin.idea.intentions.SelfTargetingIntention import org.jetbrains.kotlin.psi.KtClass @@ -33,6 +34,7 @@ class ImplementParcelableAction : override fun isApplicableTo(element: KtClass, caretOffset: Int): Boolean = AndroidFacet.getInstance(element) != null && !element.insideBody(caretOffset) && + !element.isParcelize() && element.canAddParcelable() override fun applyTo(element: KtClass, editor: Editor?) { diff --git a/idea/idea-android/src/org/jetbrains/kotlin/android/intention/RedoParcelableAction.kt b/idea/idea-android/src/org/jetbrains/kotlin/android/intention/RedoParcelableAction.kt index 22365e859e9..aad7634fab8 100644 --- a/idea/idea-android/src/org/jetbrains/kotlin/android/intention/RedoParcelableAction.kt +++ b/idea/idea-android/src/org/jetbrains/kotlin/android/intention/RedoParcelableAction.kt @@ -22,6 +22,7 @@ import org.jetbrains.android.facet.AndroidFacet import org.jetbrains.android.util.AndroidBundle import org.jetbrains.kotlin.android.canRedoParcelable import org.jetbrains.kotlin.android.insideBody +import org.jetbrains.kotlin.android.isParcelize import org.jetbrains.kotlin.android.reimplementParcelable import org.jetbrains.kotlin.idea.intentions.SelfTargetingIntention import org.jetbrains.kotlin.psi.KtClass @@ -33,6 +34,7 @@ class RedoParcelableAction : override fun isApplicableTo(element: KtClass, caretOffset: Int): Boolean = AndroidFacet.getInstance(element) != null && !element.insideBody(caretOffset) && + !element.isParcelize() && element.canRedoParcelable() override fun applyTo(element: KtClass, editor: Editor?) { diff --git a/idea/idea-android/src/org/jetbrains/kotlin/android/intention/RemoveParcelableAction.kt b/idea/idea-android/src/org/jetbrains/kotlin/android/intention/RemoveParcelableAction.kt index 59c6d119cd7..f69c205cabd 100644 --- a/idea/idea-android/src/org/jetbrains/kotlin/android/intention/RemoveParcelableAction.kt +++ b/idea/idea-android/src/org/jetbrains/kotlin/android/intention/RemoveParcelableAction.kt @@ -22,6 +22,7 @@ import org.jetbrains.android.facet.AndroidFacet import org.jetbrains.android.util.AndroidBundle import org.jetbrains.kotlin.android.canRemoveParcelable import org.jetbrains.kotlin.android.insideBody +import org.jetbrains.kotlin.android.isParcelize import org.jetbrains.kotlin.android.removeParcelableImplementation import org.jetbrains.kotlin.idea.intentions.SelfTargetingIntention import org.jetbrains.kotlin.psi.KtClass @@ -33,6 +34,7 @@ class RemoveParcelableAction : override fun isApplicableTo(element: KtClass, caretOffset: Int): Boolean = AndroidFacet.getInstance(element) != null && !element.insideBody(caretOffset) && + !element.isParcelize() && element.canRemoveParcelable() override fun applyTo(element: KtClass, editor: Editor?) { diff --git a/idea/idea-android/tests/org/jetbrains/kotlin/android/intention/AbstractAndroidIntentionTest.kt b/idea/idea-android/tests/org/jetbrains/kotlin/android/intention/AbstractAndroidIntentionTest.kt index 480dfc42500..0612df43ce6 100644 --- a/idea/idea-android/tests/org/jetbrains/kotlin/android/intention/AbstractAndroidIntentionTest.kt +++ b/idea/idea-android/tests/org/jetbrains/kotlin/android/intention/AbstractAndroidIntentionTest.kt @@ -38,6 +38,8 @@ abstract class AbstractAndroidIntentionTest : KotlinAndroidTestCase() { val checkManifest = InTextDirectivesUtils.isDirectiveDefined(testFileText, "// CHECK_MANIFEST") try { + ConfigLibraryUtil.addLibrary(myModule, "androidExtensionsRuntime", + "dist/kotlinc/lib", arrayOf("android-extensions-runtime.jar")) if (withRuntime) { ConfigLibraryUtil.configureKotlinRuntime(myFixture.module) } @@ -74,6 +76,7 @@ abstract class AbstractAndroidIntentionTest : KotlinAndroidTestCase() { } } finally { + ConfigLibraryUtil.removeLibrary(myModule, "androidExtensionsRuntime") if (withRuntime) { ConfigLibraryUtil.unConfigureKotlinRuntime(myFixture.module) } diff --git a/idea/idea-android/tests/org/jetbrains/kotlin/android/intention/AndroidIntentionTestGenerated.java b/idea/idea-android/tests/org/jetbrains/kotlin/android/intention/AndroidIntentionTestGenerated.java index 3fed8d821fb..66d92fedc16 100644 --- a/idea/idea-android/tests/org/jetbrains/kotlin/android/intention/AndroidIntentionTestGenerated.java +++ b/idea/idea-android/tests/org/jetbrains/kotlin/android/intention/AndroidIntentionTestGenerated.java @@ -356,6 +356,12 @@ public class AndroidIntentionTestGenerated extends AbstractAndroidIntentionTest doTest(fileName); } + @TestMetadata("parcelize.kt") + public void testParcelize() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/android/intention/redoParcelable/parcelize.kt"); + doTest(fileName); + } + @TestMetadata("simple.kt") public void testSimple() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/android/intention/redoParcelable/simple.kt"); @@ -395,6 +401,12 @@ public class AndroidIntentionTestGenerated extends AbstractAndroidIntentionTest doTest(fileName); } + @TestMetadata("parcelize.kt") + public void testParcelize() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/android/intention/removeParcelable/parcelize.kt"); + doTest(fileName); + } + @TestMetadata("simple.kt") public void testSimple() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/android/intention/removeParcelable/simple.kt"); diff --git a/idea/testData/android/intention/redoParcelable/parcelize.kt b/idea/testData/android/intention/redoParcelable/parcelize.kt new file mode 100644 index 00000000000..6660033cc99 --- /dev/null +++ b/idea/testData/android/intention/redoParcelable/parcelize.kt @@ -0,0 +1,8 @@ +// INTENTION_CLASS: org.jetbrains.kotlin.android.intention.RedoParcelableAction +// NOT_AVAILABLE + +import android.os.Parcelable +import kotlinx.android.parcel.Parcelize + +@Parcelize +class Simple(val a: String) : Parcelable \ No newline at end of file diff --git a/idea/testData/android/intention/removeParcelable/parcelize.kt b/idea/testData/android/intention/removeParcelable/parcelize.kt new file mode 100644 index 00000000000..6bcbf11c246 --- /dev/null +++ b/idea/testData/android/intention/removeParcelable/parcelize.kt @@ -0,0 +1,8 @@ +// INTENTION_CLASS: org.jetbrains.kotlin.android.intention.RemoveParcelableAction +// NOT_AVAILABLE + +import android.os.Parcelable +import kotlinx.android.parcel.Parcelize + +@Parcelize +class Simple(val a: String) : Parcelable \ No newline at end of file