AddThrowsAnnotationIntention: improve for mpp
#KT-38391 Fixed
This commit is contained in:
@@ -6,6 +6,8 @@
|
|||||||
package org.jetbrains.kotlin.idea.intentions
|
package org.jetbrains.kotlin.idea.intentions
|
||||||
|
|
||||||
import com.intellij.openapi.editor.Editor
|
import com.intellij.openapi.editor.Editor
|
||||||
|
import com.intellij.openapi.module.Module
|
||||||
|
import com.intellij.psi.search.GlobalSearchScope
|
||||||
import org.jetbrains.kotlin.config.ApiVersion
|
import org.jetbrains.kotlin.config.ApiVersion
|
||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithVisibility
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithVisibility
|
||||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||||
@@ -17,8 +19,11 @@ import org.jetbrains.kotlin.idea.core.replaced
|
|||||||
import org.jetbrains.kotlin.idea.project.languageVersionSettings
|
import org.jetbrains.kotlin.idea.project.languageVersionSettings
|
||||||
import org.jetbrains.kotlin.idea.project.platform
|
import org.jetbrains.kotlin.idea.project.platform
|
||||||
import org.jetbrains.kotlin.idea.refactoring.fqName.fqName
|
import org.jetbrains.kotlin.idea.refactoring.fqName.fqName
|
||||||
|
import org.jetbrains.kotlin.idea.stubindex.KotlinFullClassNameIndex
|
||||||
import org.jetbrains.kotlin.idea.util.addAnnotation
|
import org.jetbrains.kotlin.idea.util.addAnnotation
|
||||||
|
import org.jetbrains.kotlin.idea.util.module
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
import org.jetbrains.kotlin.platform.js.isJs
|
||||||
import org.jetbrains.kotlin.platform.jvm.isJvm
|
import org.jetbrains.kotlin.platform.jvm.isJvm
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getParentOfTypesAndPredicate
|
import org.jetbrains.kotlin.psi.psiUtil.getParentOfTypesAndPredicate
|
||||||
@@ -35,14 +40,18 @@ class AddThrowsAnnotationIntention : SelfTargetingIntention<KtThrowExpression>(
|
|||||||
KtThrowExpression::class.java, KotlinBundle.lazyMessage("add.throws.annotation")
|
KtThrowExpression::class.java, KotlinBundle.lazyMessage("add.throws.annotation")
|
||||||
) {
|
) {
|
||||||
override fun isApplicableTo(element: KtThrowExpression, caretOffset: Int): Boolean {
|
override fun isApplicableTo(element: KtThrowExpression, caretOffset: Int): Boolean {
|
||||||
if (!element.platform.isJvm()) return false
|
if (element.platform.isJs()) return false
|
||||||
val containingDeclaration = element.getContainingDeclaration() ?: return false
|
val containingDeclaration = element.getContainingDeclaration() ?: return false
|
||||||
|
|
||||||
val type = element.thrownExpression?.resolveToCall()?.resultingDescriptor?.returnType ?: return false
|
val type = element.thrownExpression?.resolveToCall()?.resultingDescriptor?.returnType ?: return false
|
||||||
if ((type.constructor.declarationDescriptor as? DeclarationDescriptorWithVisibility)?.visibility == Visibilities.LOCAL) return false
|
if ((type.constructor.declarationDescriptor as? DeclarationDescriptorWithVisibility)?.visibility == Visibilities.LOCAL) return false
|
||||||
|
|
||||||
val context = element.analyze(BodyResolveMode.PARTIAL)
|
val module = element.module ?: return false
|
||||||
|
if (!KOTLIN_THROWS_ANNOTATION_FQ_NAME.fqNameIsExists(module) &&
|
||||||
|
!(element.platform.isJvm() && JVM_THROWS_ANNOTATION_FQ_NAME.fqNameIsExists(module))
|
||||||
|
) return false
|
||||||
|
|
||||||
|
val context = element.analyze(BodyResolveMode.PARTIAL)
|
||||||
val annotationEntry = containingDeclaration.findThrowsAnnotation(context) ?: return true
|
val annotationEntry = containingDeclaration.findThrowsAnnotation(context) ?: return true
|
||||||
val valueArguments = annotationEntry.valueArguments
|
val valueArguments = annotationEntry.valueArguments
|
||||||
if (valueArguments.isEmpty()) return true
|
if (valueArguments.isEmpty()) return true
|
||||||
@@ -140,3 +149,9 @@ private fun KtPsiFactory.createCollectionLiteral(expressions: List<KtExpression>
|
|||||||
appendFixedText(lastExpression)
|
appendFixedText(lastExpression)
|
||||||
appendFixedText("]")
|
appendFixedText("]")
|
||||||
} as KtCollectionLiteralExpression
|
} as KtCollectionLiteralExpression
|
||||||
|
|
||||||
|
private fun FqName.fqNameIsExists(module: Module): Boolean = KotlinFullClassNameIndex.getInstance()[
|
||||||
|
asString(),
|
||||||
|
module.project,
|
||||||
|
GlobalSearchScope.moduleWithLibrariesScope(module)
|
||||||
|
].isNotEmpty()
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
// "Add '@Throws' annotation" "true"
|
||||||
|
|
||||||
|
class FooException : Exception()
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
<caret>throw FooException()
|
||||||
|
}
|
||||||
Vendored
+8
@@ -0,0 +1,8 @@
|
|||||||
|
// "Add '@Throws' annotation" "true"
|
||||||
|
|
||||||
|
class FooException : Exception()
|
||||||
|
|
||||||
|
@Throws(FooException::class)
|
||||||
|
fun test() {
|
||||||
|
throw FooException()
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
// "Add '@Throws' annotation" "false"
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
<caret>throw Throwable()
|
||||||
|
}
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
// "Add '@Throws' annotation" "true"
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
<caret>throw Throwable()
|
||||||
|
}
|
||||||
+6
@@ -0,0 +1,6 @@
|
|||||||
|
// "Add '@Throws' annotation" "true"
|
||||||
|
|
||||||
|
@Throws(Throwable::class)
|
||||||
|
fun test() {
|
||||||
|
<caret>throw Throwable()
|
||||||
|
}
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
// "Add '@Throws' annotation" "false"
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
<caret>throw Throwable()
|
||||||
|
}
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
// "Add 'return' before the expression" "false"
|
// "Add 'return' before the expression" "false"
|
||||||
// ACTION: Add '@Throws' annotation
|
|
||||||
|
|
||||||
fun test(): Nothing {
|
fun test(): Nothing {
|
||||||
<caret>throw Throwable("Error")
|
<caret>throw Throwable("Error")
|
||||||
|
|||||||
+33
@@ -209,6 +209,39 @@ public class QuickFixMultiModuleTestGenerated extends AbstractQuickFixMultiModul
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("idea/testData/multiModuleQuickFix/addThrowAnnotation")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class AddThrowAnnotation extends AbstractQuickFixMultiModuleTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInAddThrowAnnotation() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("idea/testData/multiModuleQuickFix/addThrowAnnotation"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("common")
|
||||||
|
public void testCommon() throws Exception {
|
||||||
|
runTest("idea/testData/multiModuleQuickFix/addThrowAnnotation/common/");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("js")
|
||||||
|
public void testJs() throws Exception {
|
||||||
|
runTest("idea/testData/multiModuleQuickFix/addThrowAnnotation/js/");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("jvm")
|
||||||
|
public void testJvm() throws Exception {
|
||||||
|
runTest("idea/testData/multiModuleQuickFix/addThrowAnnotation/jvm/");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("jvmWithoutStdlib")
|
||||||
|
public void testJvmWithoutStdlib() throws Exception {
|
||||||
|
runTest("idea/testData/multiModuleQuickFix/addThrowAnnotation/jvmWithoutStdlib/");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("idea/testData/multiModuleQuickFix/changeModifier")
|
@TestMetadata("idea/testData/multiModuleQuickFix/changeModifier")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
|||||||
Reference in New Issue
Block a user