AddThrowsAnnotationIntention: improve for mpp
#KT-38391 Fixed
This commit is contained in:
@@ -6,6 +6,8 @@
|
||||
package org.jetbrains.kotlin.idea.intentions
|
||||
|
||||
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.descriptors.DeclarationDescriptorWithVisibility
|
||||
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.platform
|
||||
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.module
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.platform.js.isJs
|
||||
import org.jetbrains.kotlin.platform.jvm.isJvm
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getParentOfTypesAndPredicate
|
||||
@@ -35,14 +40,18 @@ class AddThrowsAnnotationIntention : SelfTargetingIntention<KtThrowExpression>(
|
||||
KtThrowExpression::class.java, KotlinBundle.lazyMessage("add.throws.annotation")
|
||||
) {
|
||||
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 type = element.thrownExpression?.resolveToCall()?.resultingDescriptor?.returnType ?: 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 valueArguments = annotationEntry.valueArguments
|
||||
if (valueArguments.isEmpty()) return true
|
||||
@@ -140,3 +149,9 @@ private fun KtPsiFactory.createCollectionLiteral(expressions: List<KtExpression>
|
||||
appendFixedText(lastExpression)
|
||||
appendFixedText("]")
|
||||
} 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"
|
||||
// ACTION: Add '@Throws' annotation
|
||||
|
||||
fun test(): Nothing {
|
||||
<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")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
Reference in New Issue
Block a user