Add intentions for registering Android components in manifest
Activity, Service, BroadcastReceiver #KT-17389 Fixed
This commit is contained in:
@@ -23,5 +23,6 @@
|
||||
<orderEntry type="module" module-name="lint-idea" scope="TEST" />
|
||||
<orderEntry type="library" name="uast-java" level="project" />
|
||||
<orderEntry type="library" name="kotlin-reflect" level="project" />
|
||||
<orderEntry type="module" module-name="light-classes" />
|
||||
</component>
|
||||
</module>
|
||||
+54
@@ -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>(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)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
+45
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
+18
-1
@@ -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) {
|
||||
|
||||
+207
@@ -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)
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
<application>
|
||||
<activity android:name=".MyActivity"/>
|
||||
</application>
|
||||
@@ -0,0 +1,2 @@
|
||||
<application>
|
||||
</application>
|
||||
@@ -0,0 +1,5 @@
|
||||
<html>
|
||||
<body>
|
||||
Add an activity class to AndroidManifest.xml
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,3 @@
|
||||
<application>
|
||||
<receiver android:name=".MyReceiver"/>
|
||||
</application>
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
<application>
|
||||
</application>
|
||||
@@ -0,0 +1,5 @@
|
||||
<html>
|
||||
<body>
|
||||
Add a subclass of BroadcastReceiver to AndroidManifest.xml
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,3 @@
|
||||
<application>
|
||||
<service android:name=".MyService"/>
|
||||
</application>
|
||||
@@ -0,0 +1,2 @@
|
||||
<application>
|
||||
</application>
|
||||
@@ -0,0 +1,5 @@
|
||||
<html>
|
||||
<body>
|
||||
Add a service subclass to AndroidManifest.xml
|
||||
</body>
|
||||
</html>
|
||||
@@ -23,6 +23,20 @@
|
||||
<category>Kotlin Android</category>
|
||||
</intentionAction>
|
||||
|
||||
<intentionAction>
|
||||
<className>org.jetbrains.kotlin.android.intention.AddActivityToManifest</className>
|
||||
<category>Kotlin Android</category>
|
||||
</intentionAction>
|
||||
|
||||
<intentionAction>
|
||||
<className>org.jetbrains.kotlin.android.intention.AddServiceToManifest</className>
|
||||
<category>Kotlin Android</category>
|
||||
</intentionAction>
|
||||
|
||||
<intentionAction>
|
||||
<className>org.jetbrains.kotlin.android.intention.AddBroadcastReceiverToManifest</className>
|
||||
<category>Kotlin Android</category>
|
||||
</intentionAction>
|
||||
<intentionAction>
|
||||
<className>org.jetbrains.kotlin.android.intention.ImplementParcelableAction</className>
|
||||
<category>Kotlin Android</category>
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
// INTENTION_CLASS: org.jetbrains.kotlin.android.intention.AddActivityToManifest
|
||||
// NOT_AVAILABLE
|
||||
package com.myapp
|
||||
|
||||
import android.app.Activity
|
||||
|
||||
|
||||
abstract class <caret>MyActivity : Activity()
|
||||
@@ -0,0 +1,8 @@
|
||||
// INTENTION_CLASS: org.jetbrains.kotlin.android.intention.AddActivityToManifest
|
||||
// NOT_AVAILABLE
|
||||
package com.myapp
|
||||
|
||||
import android.app.Activity
|
||||
|
||||
|
||||
class <caret>MyActivity : Activity()
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.myapp"
|
||||
android:versionCode="1"
|
||||
android:versionName="1.0" >
|
||||
|
||||
|
||||
<application>
|
||||
<activity android:name=".MyActivity"/>
|
||||
</application>
|
||||
</manifest>
|
||||
@@ -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 <caret>MyActivity : Activity()
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
// INTENTION_CLASS: org.jetbrains.kotlin.android.intention.AddActivityToManifest
|
||||
// NOT_AVAILABLE
|
||||
package com.myapp
|
||||
|
||||
import android.app.Activity
|
||||
|
||||
|
||||
class MyActivity : Activity() {
|
||||
<caret>
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
// INTENTION_CLASS: org.jetbrains.kotlin.android.intention.AddActivityToManifest
|
||||
// NOT_AVAILABLE
|
||||
package com.myapp
|
||||
|
||||
import android.app.Activity
|
||||
|
||||
|
||||
fun test() {
|
||||
class <caret>MyActivity : Activity()
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
// INTENTION_CLASS: org.jetbrains.kotlin.android.intention.AddActivityToManifest
|
||||
// CHECK_MANIFEST
|
||||
package com.myapp
|
||||
|
||||
import android.app.Activity
|
||||
|
||||
class Test {
|
||||
class <caret>MyActivity : Activity()
|
||||
}
|
||||
Vendored
+10
@@ -0,0 +1,10 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.myapp"
|
||||
android:versionCode="1"
|
||||
android:versionName="1.0" >
|
||||
|
||||
|
||||
<application>
|
||||
<activity android:name=".Test$MyActivity"/>
|
||||
</application>
|
||||
</manifest>
|
||||
@@ -0,0 +1,6 @@
|
||||
// INTENTION_CLASS: org.jetbrains.kotlin.android.intention.AddActivityToManifest
|
||||
// NOT_AVAILABLE
|
||||
package com.myapp
|
||||
|
||||
|
||||
class <caret>MyActivity
|
||||
@@ -0,0 +1,8 @@
|
||||
// INTENTION_CLASS: org.jetbrains.kotlin.android.intention.AddActivityToManifest
|
||||
// NOT_AVAILABLE
|
||||
package com.myapp
|
||||
|
||||
import android.app.Activity
|
||||
|
||||
|
||||
private class <caret>MyActivity : Activity()
|
||||
@@ -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 <caret>MyActivity : Activity()
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
// INTENTION_CLASS: org.jetbrains.kotlin.android.intention.AddActivityToManifest
|
||||
// CHECK_MANIFEST
|
||||
package com.myapp
|
||||
|
||||
import android.app.Activity
|
||||
|
||||
|
||||
class <caret>MyActivity : Activity()
|
||||
Vendored
+10
@@ -0,0 +1,10 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.myapp"
|
||||
android:versionCode="1"
|
||||
android:versionName="1.0" >
|
||||
|
||||
|
||||
<application>
|
||||
<activity android:name=".MyActivity"/>
|
||||
</application>
|
||||
</manifest>
|
||||
@@ -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 <caret>MyReceiver : BroadcastReceiver() {
|
||||
override fun onReceive(context: Context?, intent: Intent?) {
|
||||
}
|
||||
}
|
||||
+12
@@ -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 <caret>MyReceiver : BroadcastReceiver() {
|
||||
override fun onReceive(context: Context?, intent: Intent?) {
|
||||
}
|
||||
}
|
||||
Vendored
+10
@@ -0,0 +1,10 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.myapp"
|
||||
android:versionCode="1"
|
||||
android:versionName="1.0" >
|
||||
|
||||
|
||||
<application>
|
||||
<receiver android:name=".MyReceiver"/>
|
||||
</application>
|
||||
</manifest>
|
||||
@@ -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?) {
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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?) {
|
||||
<caret>
|
||||
}
|
||||
}
|
||||
@@ -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 <caret>MyReceiver : BroadcastReceiver() {
|
||||
override fun onReceive(context: Context?, intent: Intent?) {
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 <caret>MyReceiver : BroadcastReceiver() {
|
||||
override fun onReceive(context: Context?, intent: Intent?) {
|
||||
}
|
||||
}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.myapp"
|
||||
android:versionCode="1"
|
||||
android:versionName="1.0" >
|
||||
|
||||
|
||||
<application>
|
||||
<receiver android:name=".Test$MyReceiver"/>
|
||||
</application>
|
||||
</manifest>
|
||||
@@ -0,0 +1,6 @@
|
||||
// INTENTION_CLASS: org.jetbrains.kotlin.android.intention.AddBroadcastReceiverToManifest
|
||||
// NOT_AVAILABLE
|
||||
package com.myapp
|
||||
|
||||
|
||||
class <caret>MyReceiver
|
||||
@@ -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 <caret>MyReceiver : BroadcastReceiver() {
|
||||
override fun onReceive(context: Context?, intent: Intent?) {
|
||||
}
|
||||
}
|
||||
@@ -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 <caret>MyReceiver : BroadcastReceiver() {
|
||||
override fun onReceive(context: Context?, intent: Intent?) {
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 <caret>MyReceiver : BroadcastReceiver() {
|
||||
override fun onReceive(context: Context?, intent: Intent?) {
|
||||
}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.myapp"
|
||||
android:versionCode="1"
|
||||
android:versionName="1.0" >
|
||||
|
||||
|
||||
<application>
|
||||
<receiver android:name=".MyReceiver"/>
|
||||
</application>
|
||||
</manifest>
|
||||
@@ -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 <caret>MyService : Service() {
|
||||
override fun onBind(intent: Intent?): IBinder {
|
||||
TODO("not implemented")
|
||||
}
|
||||
}
|
||||
@@ -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 <caret>MyService : Service() {
|
||||
override fun onBind(intent: Intent?): IBinder {
|
||||
TODO("not implemented")
|
||||
}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.myapp"
|
||||
android:versionCode="1"
|
||||
android:versionName="1.0" >
|
||||
|
||||
|
||||
<application>
|
||||
<service android:name=".MyService"/>
|
||||
</application>
|
||||
</manifest>
|
||||
@@ -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 <caret>MyService : Service() {
|
||||
override fun onBind(intent: Intent?): IBinder {
|
||||
TODO("not implemented")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 {
|
||||
<caret>
|
||||
TODO("not implemented")
|
||||
}
|
||||
}
|
||||
@@ -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 <caret>MyService : Service() {
|
||||
override fun onBind(intent: Intent?): IBinder {
|
||||
TODO("not implemented")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 <caret>MyService : Service() {
|
||||
override fun onBind(intent: Intent?): IBinder {
|
||||
TODO("not implemented")
|
||||
}
|
||||
}
|
||||
}
|
||||
Vendored
+10
@@ -0,0 +1,10 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.myapp"
|
||||
android:versionCode="1"
|
||||
android:versionName="1.0" >
|
||||
|
||||
|
||||
<application>
|
||||
<service android:name=".Test$MyService"/>
|
||||
</application>
|
||||
</manifest>
|
||||
@@ -0,0 +1,6 @@
|
||||
// INTENTION_CLASS: org.jetbrains.kotlin.android.intention.AddServiceToManifest
|
||||
// NOT_AVAILABLE
|
||||
package com.myapp
|
||||
|
||||
|
||||
class <caret>MyService
|
||||
@@ -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 <caret>MyService : Service() {
|
||||
override fun onBind(intent: Intent?): IBinder {
|
||||
TODO("not implemented")
|
||||
}
|
||||
}
|
||||
@@ -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 <caret>MyService : Service() {
|
||||
override fun onBind(intent: Intent?): IBinder {
|
||||
TODO("not implemented")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 <caret>MyService : Service() {
|
||||
override fun onBind(intent: Intent?): IBinder {
|
||||
TODO("not implemented")
|
||||
}
|
||||
}
|
||||
Vendored
+10
@@ -0,0 +1,10 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.myapp"
|
||||
android:versionCode="1"
|
||||
android:versionName="1.0" >
|
||||
|
||||
|
||||
<application>
|
||||
<service android:name=".MyService"/>
|
||||
</application>
|
||||
</manifest>
|
||||
@@ -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<IntentionActionBean> {
|
||||
val extensionPoint = Extensions.getArea(null).getExtensionPoint(IntentionManager.EP_INTENTION_ACTIONS)
|
||||
return extensionPoint.extensions.toList().filter {
|
||||
|
||||
Reference in New Issue
Block a user