diff --git a/idea/idea-android/idea-android.iml b/idea/idea-android/idea-android.iml
index 021e5defa29..2a5b3985a11 100644
--- a/idea/idea-android/idea-android.iml
+++ b/idea/idea-android/idea-android.iml
@@ -23,5 +23,6 @@
+
\ No newline at end of file
diff --git a/idea/idea-android/src/org/jetbrains/kotlin/android/intention/AbstractRegisterComponentAction.kt b/idea/idea-android/src/org/jetbrains/kotlin/android/intention/AbstractRegisterComponentAction.kt
new file mode 100644
index 00000000000..fe9a39b88cc
--- /dev/null
+++ b/idea/idea-android/src/org/jetbrains/kotlin/android/intention/AbstractRegisterComponentAction.kt
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2010-2017 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jetbrains.kotlin.android.intention
+
+import com.intellij.openapi.editor.Editor
+import org.jetbrains.android.dom.manifest.Manifest
+import org.jetbrains.android.facet.AndroidFacet
+import org.jetbrains.kotlin.android.insideBody
+import org.jetbrains.kotlin.idea.intentions.SelfTargetingIntention
+import org.jetbrains.kotlin.psi.KtClass
+import org.jetbrains.kotlin.psi.psiUtil.isAbstract
+import org.jetbrains.kotlin.psi.psiUtil.isPrivate
+import org.jetbrains.kotlin.psi.psiUtil.isProtected
+
+
+abstract class AbstractRegisterComponentAction(text: String) : SelfTargetingIntention(KtClass::class.java, text) {
+
+ abstract fun isApplicableTo(element: KtClass, manifest: Manifest): Boolean
+
+ abstract fun applyTo(element: KtClass, manifest: Manifest)
+
+ final override fun isApplicableTo(element: KtClass, caretOffset: Int): Boolean {
+ val androidFacet = AndroidFacet.getInstance(element.containingFile) ?: return false
+ val manifest = androidFacet.manifest ?: return false
+ return !element.isLocal &&
+ !element.isAbstract() &&
+ !element.isPrivate() &&
+ !element.isProtected() &&
+ !element.isInner() &&
+ !element.name.isNullOrEmpty() &&
+ !element.insideBody(caretOffset) &&
+ isApplicableTo(element, manifest)
+ }
+
+ final override fun applyTo(element: KtClass, editor: Editor?) {
+ AndroidFacet.getInstance(element.containingFile)?.manifest?.let {
+ applyTo(element, it)
+ }
+ }
+}
\ No newline at end of file
diff --git a/idea/idea-android/src/org/jetbrains/kotlin/android/intention/AddActivityToManifest.kt b/idea/idea-android/src/org/jetbrains/kotlin/android/intention/AddActivityToManifest.kt
new file mode 100644
index 00000000000..9208e76bc37
--- /dev/null
+++ b/idea/idea-android/src/org/jetbrains/kotlin/android/intention/AddActivityToManifest.kt
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2010-2017 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jetbrains.kotlin.android.intention
+
+import com.android.SdkConstants
+import org.jetbrains.android.dom.manifest.Manifest
+import org.jetbrains.kotlin.android.isSubclassOf
+import org.jetbrains.kotlin.descriptors.ClassDescriptor
+import org.jetbrains.kotlin.idea.search.usagesSearch.descriptor
+import org.jetbrains.kotlin.idea.util.application.runWriteAction
+import org.jetbrains.kotlin.name.FqName
+import org.jetbrains.kotlin.psi.KtClass
+import org.jetbrains.kotlin.asJava.toLightClass
+
+
+class AddActivityToManifest : AbstractRegisterComponentAction("Add activity to manifest") {
+ override fun isApplicableTo(element: KtClass, manifest: Manifest): Boolean =
+ element.isSubclassOfActivity() && !element.isRegisteredActivity(manifest)
+
+ override fun applyTo(element: KtClass, manifest: Manifest) = runWriteAction {
+ val psiClass = element.toLightClass() ?: return@runWriteAction
+ manifest.application.addActivity().activityClass.value = psiClass
+ }
+
+ private fun KtClass.isRegisteredActivity(manifest: Manifest) = manifest.application.activities.any {
+ it.activityClass.value?.qualifiedName == fqName?.asString()
+ }
+
+ private fun KtClass.isSubclassOfActivity() =
+ (descriptor as? ClassDescriptor)?.defaultType?.isSubclassOf(FqName(SdkConstants.CLASS_ACTIVITY), true) ?: false
+}
\ No newline at end of file
diff --git a/idea/idea-android/src/org/jetbrains/kotlin/android/intention/AddBroadcastReceiverToManifest.kt b/idea/idea-android/src/org/jetbrains/kotlin/android/intention/AddBroadcastReceiverToManifest.kt
new file mode 100644
index 00000000000..abff7180a6e
--- /dev/null
+++ b/idea/idea-android/src/org/jetbrains/kotlin/android/intention/AddBroadcastReceiverToManifest.kt
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2010-2017 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jetbrains.kotlin.android.intention
+
+import com.android.SdkConstants
+import org.jetbrains.android.dom.manifest.Manifest
+import org.jetbrains.kotlin.android.isSubclassOf
+import org.jetbrains.kotlin.asJava.toLightClass
+import org.jetbrains.kotlin.descriptors.ClassDescriptor
+import org.jetbrains.kotlin.idea.search.usagesSearch.descriptor
+import org.jetbrains.kotlin.idea.util.application.runWriteAction
+import org.jetbrains.kotlin.name.FqName
+import org.jetbrains.kotlin.psi.KtClass
+
+
+class AddBroadcastReceiverToManifest : AbstractRegisterComponentAction("Add broadcast receiver to manifest") {
+ override fun isApplicableTo(element: KtClass, manifest: Manifest): Boolean =
+ element.isSubclassOfBroadcastReceiver() && !element.isRegisteredBroadcastReceiver(manifest)
+
+ override fun applyTo(element: KtClass, manifest: Manifest) = runWriteAction {
+ val psiClass = element.toLightClass() ?: return@runWriteAction
+ manifest.application.addReceiver().receiverClass.value = psiClass
+ }
+
+ private fun KtClass.isRegisteredBroadcastReceiver(manifest: Manifest) = manifest.application.receivers.any {
+ it.receiverClass.value?.qualifiedName == fqName?.asString()
+ }
+
+ private fun KtClass.isSubclassOfBroadcastReceiver() =
+ (descriptor as? ClassDescriptor)?.defaultType?.isSubclassOf(FqName(SdkConstants.CLASS_BROADCASTRECEIVER), true) ?: false
+}
\ No newline at end of file
diff --git a/idea/idea-android/src/org/jetbrains/kotlin/android/intention/AddServiceToManifest.kt b/idea/idea-android/src/org/jetbrains/kotlin/android/intention/AddServiceToManifest.kt
new file mode 100644
index 00000000000..08aaa1e6da1
--- /dev/null
+++ b/idea/idea-android/src/org/jetbrains/kotlin/android/intention/AddServiceToManifest.kt
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2010-2017 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jetbrains.kotlin.android.intention
+
+import com.android.SdkConstants
+import org.jetbrains.android.dom.manifest.Manifest
+import org.jetbrains.kotlin.android.isSubclassOf
+import org.jetbrains.kotlin.asJava.toLightClass
+import org.jetbrains.kotlin.descriptors.ClassDescriptor
+import org.jetbrains.kotlin.idea.search.usagesSearch.descriptor
+import org.jetbrains.kotlin.idea.util.application.runWriteAction
+import org.jetbrains.kotlin.name.FqName
+import org.jetbrains.kotlin.psi.KtClass
+
+
+class AddServiceToManifest : AbstractRegisterComponentAction("Add service to manifest") {
+ override fun isApplicableTo(element: KtClass, manifest: Manifest): Boolean =
+ element.isSubclassOfService() && !element.isRegisteredService(manifest)
+
+ override fun applyTo(element: KtClass, manifest: Manifest) = runWriteAction {
+ val psiClass = element.toLightClass() ?: return@runWriteAction
+ manifest.application.addService().serviceClass.value = psiClass
+ }
+
+ private fun KtClass.isRegisteredService(manifest: Manifest) = manifest.application.services.any {
+ it.serviceClass.value?.qualifiedName == fqName?.asString()
+ }
+
+ private fun KtClass.isSubclassOfService() =
+ (descriptor as? ClassDescriptor)?.defaultType?.isSubclassOf(FqName(SdkConstants.CLASS_SERVICE), true) ?: false
+}
\ No newline at end of file
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 382b4003960..7644439c22d 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
@@ -37,12 +37,19 @@ abstract class AbstractAndroidIntentionTest : KotlinAndroidTestCase() {
val notAvailable = InTextDirectivesUtils.isDirectiveDefined(testFileText, "// NOT_AVAILABLE")
val withRuntime = InTextDirectivesUtils.isDirectiveDefined(testFileText, "// WITH_RUNTIME")
+ val checkManifest = InTextDirectivesUtils.isDirectiveDefined(testFileText, "// CHECK_MANIFEST")
try {
if (withRuntime) {
ConfigLibraryUtil.configureKotlinRuntime(myFixture.module)
}
+ val customManifestPath = "${testFile.path}.AndroidManifest.xml"
+ if (FileUtil.exists("$testDataPath/$customManifestPath")) {
+ deleteManifest()
+ myFixture.copyFileToProject(customManifestPath, SdkConstants.FN_ANDROID_MANIFEST_XML)
+ }
+
val sourceFile = myFixture.copyFileToProject(path, "src/${PathUtil.getFileName(path)}")
myFixture.configureFromExistingVirtualFile(sourceFile)
@@ -55,8 +62,18 @@ abstract class AbstractAndroidIntentionTest : KotlinAndroidTestCase() {
error("Intention is not available!")
}
+ if (notAvailable) {
+ error("Intention should not be available!")
+ }
+
myFixture.launchAction(intention)
- myFixture.checkResultByFile("$path.expected")
+
+ if (checkManifest) {
+ myFixture.checkResultByFile("AndroidManifest.xml", "$customManifestPath.expected", true)
+ }
+ else {
+ myFixture.checkResultByFile("$path.expected")
+ }
}
finally {
if (withRuntime) {
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 408662396fd..3fed8d821fb 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
@@ -36,6 +36,213 @@ public class AndroidIntentionTestGenerated extends AbstractAndroidIntentionTest
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/android/intention"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), TargetBackend.ANY, true);
}
+ @TestMetadata("idea/testData/android/intention/addActivityToManifest")
+ @TestDataPath("$PROJECT_ROOT")
+ @RunWith(JUnit3RunnerWithInners.class)
+ public static class AddActivityToManifest extends AbstractAndroidIntentionTest {
+ @TestMetadata("abstract.kt")
+ public void testAbstract() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/android/intention/addActivityToManifest/abstract.kt");
+ doTest(fileName);
+ }
+
+ public void testAllFilesPresentInAddActivityToManifest() throws Exception {
+ KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/android/intention/addActivityToManifest"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), TargetBackend.ANY, true);
+ }
+
+ @TestMetadata("alreadyExists.kt")
+ public void testAlreadyExists() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/android/intention/addActivityToManifest/alreadyExists.kt");
+ doTest(fileName);
+ }
+
+ @TestMetadata("inner.kt")
+ public void testInner() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/android/intention/addActivityToManifest/inner.kt");
+ doTest(fileName);
+ }
+
+ @TestMetadata("insideBody.kt")
+ public void testInsideBody() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/android/intention/addActivityToManifest/insideBody.kt");
+ doTest(fileName);
+ }
+
+ @TestMetadata("local.kt")
+ public void testLocal() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/android/intention/addActivityToManifest/local.kt");
+ doTest(fileName);
+ }
+
+ @TestMetadata("nested.kt")
+ public void testNested() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/android/intention/addActivityToManifest/nested.kt");
+ doTest(fileName);
+ }
+
+ @TestMetadata("notActivity.kt")
+ public void testNotActivity() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/android/intention/addActivityToManifest/notActivity.kt");
+ doTest(fileName);
+ }
+
+ @TestMetadata("private.kt")
+ public void testPrivate() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/android/intention/addActivityToManifest/private.kt");
+ doTest(fileName);
+ }
+
+ @TestMetadata("protected.kt")
+ public void testProtected() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/android/intention/addActivityToManifest/protected.kt");
+ doTest(fileName);
+ }
+
+ @TestMetadata("simple.kt")
+ public void testSimple() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/android/intention/addActivityToManifest/simple.kt");
+ doTest(fileName);
+ }
+ }
+
+ @TestMetadata("idea/testData/android/intention/addBroadcastReceiverToManifest")
+ @TestDataPath("$PROJECT_ROOT")
+ @RunWith(JUnit3RunnerWithInners.class)
+ public static class AddBroadcastReceiverToManifest extends AbstractAndroidIntentionTest {
+ @TestMetadata("abstract.kt")
+ public void testAbstract() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/android/intention/addBroadcastReceiverToManifest/abstract.kt");
+ doTest(fileName);
+ }
+
+ public void testAllFilesPresentInAddBroadcastReceiverToManifest() throws Exception {
+ KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/android/intention/addBroadcastReceiverToManifest"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), TargetBackend.ANY, true);
+ }
+
+ @TestMetadata("alreadyExists.kt")
+ public void testAlreadyExists() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/android/intention/addBroadcastReceiverToManifest/alreadyExists.kt");
+ doTest(fileName);
+ }
+
+ @TestMetadata("inner.kt")
+ public void testInner() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/android/intention/addBroadcastReceiverToManifest/inner.kt");
+ doTest(fileName);
+ }
+
+ @TestMetadata("insideBody.kt")
+ public void testInsideBody() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/android/intention/addBroadcastReceiverToManifest/insideBody.kt");
+ doTest(fileName);
+ }
+
+ @TestMetadata("local.kt")
+ public void testLocal() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/android/intention/addBroadcastReceiverToManifest/local.kt");
+ doTest(fileName);
+ }
+
+ @TestMetadata("nested.kt")
+ public void testNested() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/android/intention/addBroadcastReceiverToManifest/nested.kt");
+ doTest(fileName);
+ }
+
+ @TestMetadata("notReceiver.kt")
+ public void testNotReceiver() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/android/intention/addBroadcastReceiverToManifest/notReceiver.kt");
+ doTest(fileName);
+ }
+
+ @TestMetadata("private.kt")
+ public void testPrivate() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/android/intention/addBroadcastReceiverToManifest/private.kt");
+ doTest(fileName);
+ }
+
+ @TestMetadata("protected.kt")
+ public void testProtected() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/android/intention/addBroadcastReceiverToManifest/protected.kt");
+ doTest(fileName);
+ }
+
+ @TestMetadata("simple.kt")
+ public void testSimple() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/android/intention/addBroadcastReceiverToManifest/simple.kt");
+ doTest(fileName);
+ }
+ }
+
+ @TestMetadata("idea/testData/android/intention/addServiceToManifest")
+ @TestDataPath("$PROJECT_ROOT")
+ @RunWith(JUnit3RunnerWithInners.class)
+ public static class AddServiceToManifest extends AbstractAndroidIntentionTest {
+ @TestMetadata("abstract.kt")
+ public void testAbstract() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/android/intention/addServiceToManifest/abstract.kt");
+ doTest(fileName);
+ }
+
+ public void testAllFilesPresentInAddServiceToManifest() throws Exception {
+ KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/android/intention/addServiceToManifest"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), TargetBackend.ANY, true);
+ }
+
+ @TestMetadata("alreadyExists.kt")
+ public void testAlreadyExists() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/android/intention/addServiceToManifest/alreadyExists.kt");
+ doTest(fileName);
+ }
+
+ @TestMetadata("inner.kt")
+ public void testInner() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/android/intention/addServiceToManifest/inner.kt");
+ doTest(fileName);
+ }
+
+ @TestMetadata("insideBody.kt")
+ public void testInsideBody() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/android/intention/addServiceToManifest/insideBody.kt");
+ doTest(fileName);
+ }
+
+ @TestMetadata("local.kt")
+ public void testLocal() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/android/intention/addServiceToManifest/local.kt");
+ doTest(fileName);
+ }
+
+ @TestMetadata("nested.kt")
+ public void testNested() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/android/intention/addServiceToManifest/nested.kt");
+ doTest(fileName);
+ }
+
+ @TestMetadata("notService.kt")
+ public void testNotService() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/android/intention/addServiceToManifest/notService.kt");
+ doTest(fileName);
+ }
+
+ @TestMetadata("private.kt")
+ public void testPrivate() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/android/intention/addServiceToManifest/private.kt");
+ doTest(fileName);
+ }
+
+ @TestMetadata("protected.kt")
+ public void testProtected() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/android/intention/addServiceToManifest/protected.kt");
+ doTest(fileName);
+ }
+
+ @TestMetadata("simple.kt")
+ public void testSimple() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/android/intention/addServiceToManifest/simple.kt");
+ doTest(fileName);
+ }
+ }
+
@TestMetadata("idea/testData/android/intention/implementParcelable")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
diff --git a/idea/resources/intentionDescriptions/AddActivityToManifest/after.xml.template b/idea/resources/intentionDescriptions/AddActivityToManifest/after.xml.template
new file mode 100644
index 00000000000..31ebfe9448d
--- /dev/null
+++ b/idea/resources/intentionDescriptions/AddActivityToManifest/after.xml.template
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/idea/resources/intentionDescriptions/AddActivityToManifest/before.xml.template b/idea/resources/intentionDescriptions/AddActivityToManifest/before.xml.template
new file mode 100644
index 00000000000..e1704c98c4c
--- /dev/null
+++ b/idea/resources/intentionDescriptions/AddActivityToManifest/before.xml.template
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/idea/resources/intentionDescriptions/AddActivityToManifest/description.html b/idea/resources/intentionDescriptions/AddActivityToManifest/description.html
new file mode 100644
index 00000000000..d198328f0e2
--- /dev/null
+++ b/idea/resources/intentionDescriptions/AddActivityToManifest/description.html
@@ -0,0 +1,5 @@
+
+
+Add an activity class to AndroidManifest.xml
+
+
\ No newline at end of file
diff --git a/idea/resources/intentionDescriptions/AddBroadcastReceiverToManifest/after.xml.template b/idea/resources/intentionDescriptions/AddBroadcastReceiverToManifest/after.xml.template
new file mode 100644
index 00000000000..35f79e2d42e
--- /dev/null
+++ b/idea/resources/intentionDescriptions/AddBroadcastReceiverToManifest/after.xml.template
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/idea/resources/intentionDescriptions/AddBroadcastReceiverToManifest/before.xml.template b/idea/resources/intentionDescriptions/AddBroadcastReceiverToManifest/before.xml.template
new file mode 100644
index 00000000000..e1704c98c4c
--- /dev/null
+++ b/idea/resources/intentionDescriptions/AddBroadcastReceiverToManifest/before.xml.template
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/idea/resources/intentionDescriptions/AddBroadcastReceiverToManifest/description.html b/idea/resources/intentionDescriptions/AddBroadcastReceiverToManifest/description.html
new file mode 100644
index 00000000000..1c69d12109b
--- /dev/null
+++ b/idea/resources/intentionDescriptions/AddBroadcastReceiverToManifest/description.html
@@ -0,0 +1,5 @@
+
+
+Add a subclass of BroadcastReceiver to AndroidManifest.xml
+
+
\ No newline at end of file
diff --git a/idea/resources/intentionDescriptions/AddServiceToManifest/after.xml.template b/idea/resources/intentionDescriptions/AddServiceToManifest/after.xml.template
new file mode 100644
index 00000000000..50236a76229
--- /dev/null
+++ b/idea/resources/intentionDescriptions/AddServiceToManifest/after.xml.template
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/idea/resources/intentionDescriptions/AddServiceToManifest/before.xml.template b/idea/resources/intentionDescriptions/AddServiceToManifest/before.xml.template
new file mode 100644
index 00000000000..e1704c98c4c
--- /dev/null
+++ b/idea/resources/intentionDescriptions/AddServiceToManifest/before.xml.template
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/idea/resources/intentionDescriptions/AddServiceToManifest/description.html b/idea/resources/intentionDescriptions/AddServiceToManifest/description.html
new file mode 100644
index 00000000000..611f6a09985
--- /dev/null
+++ b/idea/resources/intentionDescriptions/AddServiceToManifest/description.html
@@ -0,0 +1,5 @@
+
+
+Add a service subclass to AndroidManifest.xml
+
+
\ No newline at end of file
diff --git a/idea/src/META-INF/android.xml b/idea/src/META-INF/android.xml
index d7f85eb3540..c12d4cc1c6c 100644
--- a/idea/src/META-INF/android.xml
+++ b/idea/src/META-INF/android.xml
@@ -23,6 +23,20 @@
Kotlin Android
+
+ org.jetbrains.kotlin.android.intention.AddActivityToManifest
+ Kotlin Android
+
+
+
+ org.jetbrains.kotlin.android.intention.AddServiceToManifest
+ Kotlin Android
+
+
+
+ org.jetbrains.kotlin.android.intention.AddBroadcastReceiverToManifest
+ Kotlin Android
+
org.jetbrains.kotlin.android.intention.ImplementParcelableAction
Kotlin Android
diff --git a/idea/testData/android/intention/addActivityToManifest/abstract.kt b/idea/testData/android/intention/addActivityToManifest/abstract.kt
new file mode 100644
index 00000000000..dac9b51bd6f
--- /dev/null
+++ b/idea/testData/android/intention/addActivityToManifest/abstract.kt
@@ -0,0 +1,8 @@
+// INTENTION_CLASS: org.jetbrains.kotlin.android.intention.AddActivityToManifest
+// NOT_AVAILABLE
+package com.myapp
+
+import android.app.Activity
+
+
+abstract class MyActivity : Activity()
\ No newline at end of file
diff --git a/idea/testData/android/intention/addActivityToManifest/alreadyExists.kt b/idea/testData/android/intention/addActivityToManifest/alreadyExists.kt
new file mode 100644
index 00000000000..a8028c7e10f
--- /dev/null
+++ b/idea/testData/android/intention/addActivityToManifest/alreadyExists.kt
@@ -0,0 +1,8 @@
+// INTENTION_CLASS: org.jetbrains.kotlin.android.intention.AddActivityToManifest
+// NOT_AVAILABLE
+package com.myapp
+
+import android.app.Activity
+
+
+class MyActivity : Activity()
\ No newline at end of file
diff --git a/idea/testData/android/intention/addActivityToManifest/alreadyExists.kt.AndroidManifest.xml b/idea/testData/android/intention/addActivityToManifest/alreadyExists.kt.AndroidManifest.xml
new file mode 100644
index 00000000000..d357760073e
--- /dev/null
+++ b/idea/testData/android/intention/addActivityToManifest/alreadyExists.kt.AndroidManifest.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/idea/testData/android/intention/addActivityToManifest/inner.kt b/idea/testData/android/intention/addActivityToManifest/inner.kt
new file mode 100644
index 00000000000..eb07e131742
--- /dev/null
+++ b/idea/testData/android/intention/addActivityToManifest/inner.kt
@@ -0,0 +1,10 @@
+// INTENTION_CLASS: org.jetbrains.kotlin.android.intention.AddActivityToManifest
+// NOT_AVAILABLE
+package com.myapp
+
+import android.app.Activity
+
+
+class Test {
+ inner class MyActivity : Activity()
+}
\ No newline at end of file
diff --git a/idea/testData/android/intention/addActivityToManifest/insideBody.kt b/idea/testData/android/intention/addActivityToManifest/insideBody.kt
new file mode 100644
index 00000000000..e7070fcc1d3
--- /dev/null
+++ b/idea/testData/android/intention/addActivityToManifest/insideBody.kt
@@ -0,0 +1,10 @@
+// INTENTION_CLASS: org.jetbrains.kotlin.android.intention.AddActivityToManifest
+// NOT_AVAILABLE
+package com.myapp
+
+import android.app.Activity
+
+
+class MyActivity : Activity() {
+
+}
\ No newline at end of file
diff --git a/idea/testData/android/intention/addActivityToManifest/local.kt b/idea/testData/android/intention/addActivityToManifest/local.kt
new file mode 100644
index 00000000000..444a4dc37b7
--- /dev/null
+++ b/idea/testData/android/intention/addActivityToManifest/local.kt
@@ -0,0 +1,10 @@
+// INTENTION_CLASS: org.jetbrains.kotlin.android.intention.AddActivityToManifest
+// NOT_AVAILABLE
+package com.myapp
+
+import android.app.Activity
+
+
+fun test() {
+ class MyActivity : Activity()
+}
\ No newline at end of file
diff --git a/idea/testData/android/intention/addActivityToManifest/nested.kt b/idea/testData/android/intention/addActivityToManifest/nested.kt
new file mode 100644
index 00000000000..c7e3c6ee1e6
--- /dev/null
+++ b/idea/testData/android/intention/addActivityToManifest/nested.kt
@@ -0,0 +1,9 @@
+// INTENTION_CLASS: org.jetbrains.kotlin.android.intention.AddActivityToManifest
+// CHECK_MANIFEST
+package com.myapp
+
+import android.app.Activity
+
+class Test {
+ class MyActivity : Activity()
+}
\ No newline at end of file
diff --git a/idea/testData/android/intention/addActivityToManifest/nested.kt.AndroidManifest.xml.expected b/idea/testData/android/intention/addActivityToManifest/nested.kt.AndroidManifest.xml.expected
new file mode 100644
index 00000000000..67606787f90
--- /dev/null
+++ b/idea/testData/android/intention/addActivityToManifest/nested.kt.AndroidManifest.xml.expected
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/idea/testData/android/intention/addActivityToManifest/notActivity.kt b/idea/testData/android/intention/addActivityToManifest/notActivity.kt
new file mode 100644
index 00000000000..ba0a34b19f2
--- /dev/null
+++ b/idea/testData/android/intention/addActivityToManifest/notActivity.kt
@@ -0,0 +1,6 @@
+// INTENTION_CLASS: org.jetbrains.kotlin.android.intention.AddActivityToManifest
+// NOT_AVAILABLE
+package com.myapp
+
+
+class MyActivity
\ No newline at end of file
diff --git a/idea/testData/android/intention/addActivityToManifest/private.kt b/idea/testData/android/intention/addActivityToManifest/private.kt
new file mode 100644
index 00000000000..2c8548aeb7e
--- /dev/null
+++ b/idea/testData/android/intention/addActivityToManifest/private.kt
@@ -0,0 +1,8 @@
+// INTENTION_CLASS: org.jetbrains.kotlin.android.intention.AddActivityToManifest
+// NOT_AVAILABLE
+package com.myapp
+
+import android.app.Activity
+
+
+private class MyActivity : Activity()
\ No newline at end of file
diff --git a/idea/testData/android/intention/addActivityToManifest/protected.kt b/idea/testData/android/intention/addActivityToManifest/protected.kt
new file mode 100644
index 00000000000..079f22e9700
--- /dev/null
+++ b/idea/testData/android/intention/addActivityToManifest/protected.kt
@@ -0,0 +1,10 @@
+// INTENTION_CLASS: org.jetbrains.kotlin.android.intention.AddActivityToManifest
+// NOT_AVAILABLE
+package com.myapp
+
+import android.app.Activity
+
+
+class Test {
+ protected class MyActivity : Activity()
+}
\ No newline at end of file
diff --git a/idea/testData/android/intention/addActivityToManifest/simple.kt b/idea/testData/android/intention/addActivityToManifest/simple.kt
new file mode 100644
index 00000000000..c94b81bb32e
--- /dev/null
+++ b/idea/testData/android/intention/addActivityToManifest/simple.kt
@@ -0,0 +1,8 @@
+// INTENTION_CLASS: org.jetbrains.kotlin.android.intention.AddActivityToManifest
+// CHECK_MANIFEST
+package com.myapp
+
+import android.app.Activity
+
+
+class MyActivity : Activity()
\ No newline at end of file
diff --git a/idea/testData/android/intention/addActivityToManifest/simple.kt.AndroidManifest.xml.expected b/idea/testData/android/intention/addActivityToManifest/simple.kt.AndroidManifest.xml.expected
new file mode 100644
index 00000000000..d357760073e
--- /dev/null
+++ b/idea/testData/android/intention/addActivityToManifest/simple.kt.AndroidManifest.xml.expected
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/idea/testData/android/intention/addBroadcastReceiverToManifest/abstract.kt b/idea/testData/android/intention/addBroadcastReceiverToManifest/abstract.kt
new file mode 100644
index 00000000000..e70809a034d
--- /dev/null
+++ b/idea/testData/android/intention/addBroadcastReceiverToManifest/abstract.kt
@@ -0,0 +1,12 @@
+// INTENTION_CLASS: org.jetbrains.kotlin.android.intention.AddBroadcastReceiverToManifest
+// NOT_AVAILABLE
+package com.myapp
+
+import android.content.BroadcastReceiver
+import android.content.Context
+import android.content.Intent
+
+abstract class MyReceiver : BroadcastReceiver() {
+ override fun onReceive(context: Context?, intent: Intent?) {
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/android/intention/addBroadcastReceiverToManifest/alreadyExists.kt b/idea/testData/android/intention/addBroadcastReceiverToManifest/alreadyExists.kt
new file mode 100644
index 00000000000..7b977917e5d
--- /dev/null
+++ b/idea/testData/android/intention/addBroadcastReceiverToManifest/alreadyExists.kt
@@ -0,0 +1,12 @@
+// INTENTION_CLASS: org.jetbrains.kotlin.android.intention.AddBroadcastReceiverToManifest
+// NOT_AVAILABLE
+package com.myapp
+
+import android.content.BroadcastReceiver
+import android.content.Context
+import android.content.Intent
+
+class MyReceiver : BroadcastReceiver() {
+ override fun onReceive(context: Context?, intent: Intent?) {
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/android/intention/addBroadcastReceiverToManifest/alreadyExists.kt.AndroidManifest.xml b/idea/testData/android/intention/addBroadcastReceiverToManifest/alreadyExists.kt.AndroidManifest.xml
new file mode 100644
index 00000000000..413772c9367
--- /dev/null
+++ b/idea/testData/android/intention/addBroadcastReceiverToManifest/alreadyExists.kt.AndroidManifest.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/idea/testData/android/intention/addBroadcastReceiverToManifest/inner.kt b/idea/testData/android/intention/addBroadcastReceiverToManifest/inner.kt
new file mode 100644
index 00000000000..18e7dc84a9e
--- /dev/null
+++ b/idea/testData/android/intention/addBroadcastReceiverToManifest/inner.kt
@@ -0,0 +1,14 @@
+// INTENTION_CLASS: org.jetbrains.kotlin.android.intention.AddBroadcastReceiverToManifest
+// NOT_AVAILABLE
+package com.myapp
+
+import android.content.BroadcastReceiver
+import android.content.Context
+import android.content.Intent
+
+class Test {
+ inner class MyReceiver : BroadcastReceiver() {
+ override fun onReceive(context: Context?, intent: Intent?) {
+ }
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/android/intention/addBroadcastReceiverToManifest/insideBody.kt b/idea/testData/android/intention/addBroadcastReceiverToManifest/insideBody.kt
new file mode 100644
index 00000000000..6fa7a4bf974
--- /dev/null
+++ b/idea/testData/android/intention/addBroadcastReceiverToManifest/insideBody.kt
@@ -0,0 +1,13 @@
+// INTENTION_CLASS: org.jetbrains.kotlin.android.intention.AddBroadcastReceiverToManifest
+// NOT_AVAILABLE
+package com.myapp
+
+import android.content.BroadcastReceiver
+import android.content.Context
+import android.content.Intent
+
+class MyReceiver : BroadcastReceiver() {
+ override fun onReceive(context: Context?, intent: Intent?) {
+
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/android/intention/addBroadcastReceiverToManifest/local.kt b/idea/testData/android/intention/addBroadcastReceiverToManifest/local.kt
new file mode 100644
index 00000000000..231ebc6e496
--- /dev/null
+++ b/idea/testData/android/intention/addBroadcastReceiverToManifest/local.kt
@@ -0,0 +1,15 @@
+// INTENTION_CLASS: org.jetbrains.kotlin.android.intention.AddBroadcastReceiverToManifest
+// NOT_AVAILABLE
+package com.myapp
+
+import android.content.BroadcastReceiver
+import android.content.Context
+import android.content.Intent
+
+
+fun test() {
+ class MyReceiver : BroadcastReceiver() {
+ override fun onReceive(context: Context?, intent: Intent?) {
+ }
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/android/intention/addBroadcastReceiverToManifest/nested.kt b/idea/testData/android/intention/addBroadcastReceiverToManifest/nested.kt
new file mode 100644
index 00000000000..c1123b0279d
--- /dev/null
+++ b/idea/testData/android/intention/addBroadcastReceiverToManifest/nested.kt
@@ -0,0 +1,15 @@
+// INTENTION_CLASS: org.jetbrains.kotlin.android.intention.AddBroadcastReceiverToManifest
+// CHECK_MANIFEST
+package com.myapp
+
+import android.content.BroadcastReceiver
+import android.content.Context
+import android.content.Intent
+
+
+class Test {
+ class MyReceiver : BroadcastReceiver() {
+ override fun onReceive(context: Context?, intent: Intent?) {
+ }
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/android/intention/addBroadcastReceiverToManifest/nested.kt.AndroidManifest.xml.expected b/idea/testData/android/intention/addBroadcastReceiverToManifest/nested.kt.AndroidManifest.xml.expected
new file mode 100644
index 00000000000..80e688c5193
--- /dev/null
+++ b/idea/testData/android/intention/addBroadcastReceiverToManifest/nested.kt.AndroidManifest.xml.expected
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/idea/testData/android/intention/addBroadcastReceiverToManifest/notReceiver.kt b/idea/testData/android/intention/addBroadcastReceiverToManifest/notReceiver.kt
new file mode 100644
index 00000000000..87b23039bae
--- /dev/null
+++ b/idea/testData/android/intention/addBroadcastReceiverToManifest/notReceiver.kt
@@ -0,0 +1,6 @@
+// INTENTION_CLASS: org.jetbrains.kotlin.android.intention.AddBroadcastReceiverToManifest
+// NOT_AVAILABLE
+package com.myapp
+
+
+class MyReceiver
\ No newline at end of file
diff --git a/idea/testData/android/intention/addBroadcastReceiverToManifest/private.kt b/idea/testData/android/intention/addBroadcastReceiverToManifest/private.kt
new file mode 100644
index 00000000000..7fef0a780cf
--- /dev/null
+++ b/idea/testData/android/intention/addBroadcastReceiverToManifest/private.kt
@@ -0,0 +1,12 @@
+// INTENTION_CLASS: org.jetbrains.kotlin.android.intention.AddBroadcastReceiverToManifest
+// NOT_AVAILABLE
+package com.myapp
+
+import android.content.BroadcastReceiver
+import android.content.Context
+import android.content.Intent
+
+private class MyReceiver : BroadcastReceiver() {
+ override fun onReceive(context: Context?, intent: Intent?) {
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/android/intention/addBroadcastReceiverToManifest/protected.kt b/idea/testData/android/intention/addBroadcastReceiverToManifest/protected.kt
new file mode 100644
index 00000000000..396f5a3c1c7
--- /dev/null
+++ b/idea/testData/android/intention/addBroadcastReceiverToManifest/protected.kt
@@ -0,0 +1,14 @@
+// INTENTION_CLASS: org.jetbrains.kotlin.android.intention.AddBroadcastReceiverToManifest
+// NOT_AVAILABLE
+package com.myapp
+
+import android.content.BroadcastReceiver
+import android.content.Context
+import android.content.Intent
+
+class Test {
+ protected class MyReceiver : BroadcastReceiver() {
+ override fun onReceive(context: Context?, intent: Intent?) {
+ }
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/android/intention/addBroadcastReceiverToManifest/simple.kt b/idea/testData/android/intention/addBroadcastReceiverToManifest/simple.kt
new file mode 100644
index 00000000000..8e2b0668738
--- /dev/null
+++ b/idea/testData/android/intention/addBroadcastReceiverToManifest/simple.kt
@@ -0,0 +1,12 @@
+// INTENTION_CLASS: org.jetbrains.kotlin.android.intention.AddBroadcastReceiverToManifest
+// CHECK_MANIFEST
+package com.myapp
+
+import android.content.BroadcastReceiver
+import android.content.Context
+import android.content.Intent
+
+class MyReceiver : BroadcastReceiver() {
+ override fun onReceive(context: Context?, intent: Intent?) {
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/android/intention/addBroadcastReceiverToManifest/simple.kt.AndroidManifest.xml.expected b/idea/testData/android/intention/addBroadcastReceiverToManifest/simple.kt.AndroidManifest.xml.expected
new file mode 100644
index 00000000000..413772c9367
--- /dev/null
+++ b/idea/testData/android/intention/addBroadcastReceiverToManifest/simple.kt.AndroidManifest.xml.expected
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/idea/testData/android/intention/addServiceToManifest/abstract.kt b/idea/testData/android/intention/addServiceToManifest/abstract.kt
new file mode 100644
index 00000000000..96edff4c3fd
--- /dev/null
+++ b/idea/testData/android/intention/addServiceToManifest/abstract.kt
@@ -0,0 +1,14 @@
+// INTENTION_CLASS: org.jetbrains.kotlin.android.intention.AddServiceToManifest
+// NOT_AVAILABLE
+package com.myapp
+
+import android.app.Service
+import android.content.Intent
+import android.os.IBinder
+
+
+abstract class MyService : Service() {
+ override fun onBind(intent: Intent?): IBinder {
+ TODO("not implemented")
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/android/intention/addServiceToManifest/alreadyExists.kt b/idea/testData/android/intention/addServiceToManifest/alreadyExists.kt
new file mode 100644
index 00000000000..051cab465ce
--- /dev/null
+++ b/idea/testData/android/intention/addServiceToManifest/alreadyExists.kt
@@ -0,0 +1,14 @@
+// INTENTION_CLASS: org.jetbrains.kotlin.android.intention.AddServiceToManifest
+// NOT_AVAILABLE
+package com.myapp
+
+import android.app.Service
+import android.content.Intent
+import android.os.IBinder
+
+
+class MyService : Service() {
+ override fun onBind(intent: Intent?): IBinder {
+ TODO("not implemented")
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/android/intention/addServiceToManifest/alreadyExists.kt.AndroidManifest.xml b/idea/testData/android/intention/addServiceToManifest/alreadyExists.kt.AndroidManifest.xml
new file mode 100644
index 00000000000..64b5f5bd7b7
--- /dev/null
+++ b/idea/testData/android/intention/addServiceToManifest/alreadyExists.kt.AndroidManifest.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/idea/testData/android/intention/addServiceToManifest/inner.kt b/idea/testData/android/intention/addServiceToManifest/inner.kt
new file mode 100644
index 00000000000..25b28d674cc
--- /dev/null
+++ b/idea/testData/android/intention/addServiceToManifest/inner.kt
@@ -0,0 +1,16 @@
+// INTENTION_CLASS: org.jetbrains.kotlin.android.intention.AddServiceToManifest
+// NOT_AVAILABLE
+package com.myapp
+
+import android.app.Service
+import android.content.Intent
+import android.os.IBinder
+
+
+class Test {
+ inner class MyService : Service() {
+ override fun onBind(intent: Intent?): IBinder {
+ TODO("not implemented")
+ }
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/android/intention/addServiceToManifest/insideBody.kt b/idea/testData/android/intention/addServiceToManifest/insideBody.kt
new file mode 100644
index 00000000000..afb893a4f9a
--- /dev/null
+++ b/idea/testData/android/intention/addServiceToManifest/insideBody.kt
@@ -0,0 +1,15 @@
+// INTENTION_CLASS: org.jetbrains.kotlin.android.intention.AddServiceToManifest
+// NOT_AVAILABLE
+package com.myapp
+
+import android.app.Service
+import android.content.Intent
+import android.os.IBinder
+
+
+class MyService : Service() {
+ override fun onBind(intent: Intent?): IBinder {
+
+ TODO("not implemented")
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/android/intention/addServiceToManifest/local.kt b/idea/testData/android/intention/addServiceToManifest/local.kt
new file mode 100644
index 00000000000..23f90491a39
--- /dev/null
+++ b/idea/testData/android/intention/addServiceToManifest/local.kt
@@ -0,0 +1,16 @@
+// INTENTION_CLASS: org.jetbrains.kotlin.android.intention.AddServiceToManifest
+// NOT_AVAILABLE
+package com.myapp
+
+import android.app.Service
+import android.content.Intent
+import android.os.IBinder
+
+
+fun test() {
+ class MyService : Service() {
+ override fun onBind(intent: Intent?): IBinder {
+ TODO("not implemented")
+ }
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/android/intention/addServiceToManifest/nested.kt b/idea/testData/android/intention/addServiceToManifest/nested.kt
new file mode 100644
index 00000000000..17fd277394d
--- /dev/null
+++ b/idea/testData/android/intention/addServiceToManifest/nested.kt
@@ -0,0 +1,16 @@
+// INTENTION_CLASS: org.jetbrains.kotlin.android.intention.AddServiceToManifest
+// CHECK_MANIFEST
+package com.myapp
+
+import android.app.Service
+import android.content.Intent
+import android.os.IBinder
+
+
+class Test {
+ class MyService : Service() {
+ override fun onBind(intent: Intent?): IBinder {
+ TODO("not implemented")
+ }
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/android/intention/addServiceToManifest/nested.kt.AndroidManifest.xml.expected b/idea/testData/android/intention/addServiceToManifest/nested.kt.AndroidManifest.xml.expected
new file mode 100644
index 00000000000..0e2a7618c27
--- /dev/null
+++ b/idea/testData/android/intention/addServiceToManifest/nested.kt.AndroidManifest.xml.expected
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/idea/testData/android/intention/addServiceToManifest/notService.kt b/idea/testData/android/intention/addServiceToManifest/notService.kt
new file mode 100644
index 00000000000..ac58893927d
--- /dev/null
+++ b/idea/testData/android/intention/addServiceToManifest/notService.kt
@@ -0,0 +1,6 @@
+// INTENTION_CLASS: org.jetbrains.kotlin.android.intention.AddServiceToManifest
+// NOT_AVAILABLE
+package com.myapp
+
+
+class MyService
\ No newline at end of file
diff --git a/idea/testData/android/intention/addServiceToManifest/private.kt b/idea/testData/android/intention/addServiceToManifest/private.kt
new file mode 100644
index 00000000000..ea7ff4214c4
--- /dev/null
+++ b/idea/testData/android/intention/addServiceToManifest/private.kt
@@ -0,0 +1,14 @@
+// INTENTION_CLASS: org.jetbrains.kotlin.android.intention.AddServiceToManifest
+// NOT_AVAILABLE
+package com.myapp
+
+import android.app.Service
+import android.content.Intent
+import android.os.IBinder
+
+
+private class MyService : Service() {
+ override fun onBind(intent: Intent?): IBinder {
+ TODO("not implemented")
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/android/intention/addServiceToManifest/protected.kt b/idea/testData/android/intention/addServiceToManifest/protected.kt
new file mode 100644
index 00000000000..2fbeb80e008
--- /dev/null
+++ b/idea/testData/android/intention/addServiceToManifest/protected.kt
@@ -0,0 +1,16 @@
+// INTENTION_CLASS: org.jetbrains.kotlin.android.intention.AddServiceToManifest
+// NOT_AVAILABLE
+package com.myapp
+
+import android.app.Service
+import android.content.Intent
+import android.os.IBinder
+
+
+class Test {
+ protected class MyService : Service() {
+ override fun onBind(intent: Intent?): IBinder {
+ TODO("not implemented")
+ }
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/android/intention/addServiceToManifest/simple.kt b/idea/testData/android/intention/addServiceToManifest/simple.kt
new file mode 100644
index 00000000000..9982c76ab8e
--- /dev/null
+++ b/idea/testData/android/intention/addServiceToManifest/simple.kt
@@ -0,0 +1,14 @@
+// INTENTION_CLASS: org.jetbrains.kotlin.android.intention.AddServiceToManifest
+// CHECK_MANIFEST
+package com.myapp
+
+import android.app.Service
+import android.content.Intent
+import android.os.IBinder
+
+
+class MyService : Service() {
+ override fun onBind(intent: Intent?): IBinder {
+ TODO("not implemented")
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/android/intention/addServiceToManifest/simple.kt.AndroidManifest.xml.expected b/idea/testData/android/intention/addServiceToManifest/simple.kt.AndroidManifest.xml.expected
new file mode 100644
index 00000000000..64b5f5bd7b7
--- /dev/null
+++ b/idea/testData/android/intention/addServiceToManifest/simple.kt.AndroidManifest.xml.expected
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionDescriptionTest.kt b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionDescriptionTest.kt
index 0bb772f5c22..961386bbdbf 100644
--- a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionDescriptionTest.kt
+++ b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionDescriptionTest.kt
@@ -27,6 +27,7 @@ import java.io.File
class IntentionDescriptionTest : LightPlatformTestCase() {
val necessaryNormalNames = listOf("description.html", "before.kt.template", "after.kt.template")
+ val necessaryXmlNames = listOf("description.html", "before.xml.template", "after.xml.template")
val necessaryMavenNames = listOf("description.html")
fun testDescriptionsAndShortNames() {
@@ -40,7 +41,11 @@ class IntentionDescriptionTest : LightPlatformTestCase() {
errors.append("No description directory for intention '").append(className).append("'\n")
}
else {
- val necessaryNames = if (shortName.startsWith("MavenPlugin")) necessaryMavenNames else necessaryNormalNames
+ val necessaryNames = when {
+ shortName.isMavenIntentionName() -> necessaryMavenNames
+ shortName.isXmlIntentionName() -> necessaryXmlNames
+ else -> necessaryNormalNames
+ }
for (fileName in necessaryNames) {
val file = directory.resolve(fileName)
if (!file.exists() || !file.isFile) {
@@ -52,6 +57,10 @@ class IntentionDescriptionTest : LightPlatformTestCase() {
UsefulTestCase.assertEmpty(errors.toString())
}
+ private fun String.isMavenIntentionName() = startsWith("MavenPlugin")
+
+ private fun String.isXmlIntentionName() = startsWith("Add") && endsWith("ToManifest")
+
private fun loadKotlinIntentions(): List {
val extensionPoint = Extensions.getArea(null).getExtensionPoint(IntentionManager.EP_INTENTION_ACTIONS)
return extensionPoint.extensions.toList().filter {