Added second quickfix on conflicting extension to mark it hidden and deprecated
This commit is contained in:
+51
-9
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea.inspections
|
||||
|
||||
import com.intellij.codeInsight.intention.LowPriorityAction
|
||||
import com.intellij.codeInspection.*
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
import com.intellij.openapi.editor.Editor
|
||||
@@ -44,6 +45,7 @@ import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
||||
import org.jetbrains.kotlin.renderer.render
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.isAnnotatedAsHidden
|
||||
import org.jetbrains.kotlin.resolve.scopes.FileScope
|
||||
@@ -67,12 +69,25 @@ public class ConflictingExtensionPropertyInspection : AbstractKotlinInspection()
|
||||
// don't report on hidden declarations
|
||||
if (propertyDescriptor.isAnnotatedAsHidden()) return
|
||||
|
||||
val fixes = if (isSameAsSynthetic(property, conflictingExtension)) {
|
||||
val fix1 = IntentionWrapper(DeleteRedundantExtensionAction(property), file)
|
||||
// don't add the second fix when on the fly to allow code cleanup
|
||||
val fix2 = if (isOnTheFly)
|
||||
object : IntentionWrapper(MarkHiddenAndDeprecatedAction(property), file), LowPriorityAction {}
|
||||
else
|
||||
null
|
||||
listOf(fix1, fix2).filterNotNull().toTypedArray()
|
||||
}
|
||||
else {
|
||||
emptyArray()
|
||||
}
|
||||
|
||||
val problemDescriptor = holder.manager.createProblemDescriptor(
|
||||
nameElement,
|
||||
"This property conflicts with synthetic extension and should be removed to avoid breaking code by future changes in the compiler",
|
||||
createQuickFix(property, conflictingExtension),
|
||||
ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
|
||||
true
|
||||
true,
|
||||
fixes,
|
||||
ProblemHighlightType.GENERIC_ERROR_OR_WARNING
|
||||
)
|
||||
holder.registerProblem(problemDescriptor)
|
||||
}
|
||||
@@ -88,18 +103,18 @@ public class ConflictingExtensionPropertyInspection : AbstractKotlinInspection()
|
||||
.firstIsInstanceOrNull()
|
||||
}
|
||||
|
||||
private fun createQuickFix(declaration: JetProperty, syntheticProperty: SyntheticJavaPropertyDescriptor): LocalQuickFix? {
|
||||
val getter = declaration.getter ?: return null
|
||||
private fun isSameAsSynthetic(declaration: JetProperty, syntheticProperty: SyntheticJavaPropertyDescriptor): Boolean {
|
||||
val getter = declaration.getter ?: return false
|
||||
val setter = declaration.setter
|
||||
|
||||
if (!checkGetterBodyIsGetMethodCall(getter, syntheticProperty.getMethod)) return null
|
||||
if (!checkGetterBodyIsGetMethodCall(getter, syntheticProperty.getMethod)) return false
|
||||
|
||||
if (setter != null) {
|
||||
val setMethod = syntheticProperty.setMethod ?: return null // synthetic property is val but our property is var
|
||||
if (!checkSetterBodyIsSetMethodCall(setter, setMethod)) return null
|
||||
val setMethod = syntheticProperty.setMethod ?: return false // synthetic property is val but our property is var
|
||||
if (!checkSetterBodyIsSetMethodCall(setter, setMethod)) return false
|
||||
}
|
||||
|
||||
return IntentionWrapper(DeleteRedundantExtensionAction(declaration), declaration.containingFile)
|
||||
return true
|
||||
}
|
||||
|
||||
private fun checkGetterBodyIsGetMethodCall(getter: JetPropertyAccessor, getMethod: FunctionDescriptor): Boolean {
|
||||
@@ -196,4 +211,31 @@ public class ConflictingExtensionPropertyInspection : AbstractKotlinInspection()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class MarkHiddenAndDeprecatedAction(property: JetProperty) : JetIntentionAction<JetProperty>(property) {
|
||||
override fun getFamilyName() = "Mark with @HiddenDeclaration and @deprecated"
|
||||
override fun getText() = familyName
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: JetFile) {
|
||||
val factory = JetPsiFactory(project)
|
||||
val name = element.nameAsName!!.render()
|
||||
element.addAnnotationWithLineBreak(factory.createAnnotationEntry("@deprecated(\"Is replaced with automatic synthetic extension\", ReplaceWith(\"$name\"))"))
|
||||
element.addAnnotationWithLineBreak(factory.createAnnotationEntry("@HiddenDeclaration"))
|
||||
}
|
||||
|
||||
//TODO: move into PSI?
|
||||
private fun JetNamedDeclaration.addAnnotationWithLineBreak(annotationEntry: JetAnnotationEntry): JetAnnotationEntry {
|
||||
val newLine = JetPsiFactory(this).createNewLine()
|
||||
if (modifierList != null) {
|
||||
val result = addAnnotationEntry(annotationEntry)
|
||||
modifierList!!.addAfter(newLine, result)
|
||||
return result
|
||||
}
|
||||
else {
|
||||
val result = addAnnotationEntry(annotationEntry)
|
||||
addAfter(newLine, modifierList)
|
||||
return result
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
// "Mark with @HiddenDeclaration and @deprecated" "true"
|
||||
import java.io.File
|
||||
|
||||
val File.<caret>name: String
|
||||
get() = getName()
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
// "Mark with @HiddenDeclaration and @deprecated" "true"
|
||||
import java.io.File
|
||||
|
||||
@HiddenDeclaration
|
||||
@deprecated("Is replaced with automatic synthetic extension", ReplaceWith("name"))
|
||||
val File.<caret>name: String
|
||||
get() = getName()
|
||||
@@ -990,23 +990,23 @@ public class QuickFixMultiFileTestGenerated extends AbstractQuickFixMultiFileTes
|
||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/quickfix/migration"), Pattern.compile("^(\\w+)\\.before\\.Main\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("idea/testData/quickfix/migration/deleteRedundantExtension")
|
||||
@TestMetadata("idea/testData/quickfix/migration/conflictingExtension")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class DeleteRedundantExtension extends AbstractQuickFixMultiFileTest {
|
||||
public void testAllFilesPresentInDeleteRedundantExtension() throws Exception {
|
||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/quickfix/migration/deleteRedundantExtension"), Pattern.compile("^(\\w+)\\.before\\.Main\\.kt$"), true);
|
||||
public static class ConflictingExtension extends AbstractQuickFixMultiFileTest {
|
||||
public void testAllFilesPresentInConflictingExtension() throws Exception {
|
||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/quickfix/migration/conflictingExtension"), Pattern.compile("^(\\w+)\\.before\\.Main\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("removeImports.before.Main.kt")
|
||||
public void testRemoveImports() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/migration/deleteRedundantExtension/removeImports.before.Main.kt");
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/migration/conflictingExtension/removeImports.before.Main.kt");
|
||||
doTestWithExtraFile(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("removeImportsOverloads.before.Main.kt")
|
||||
public void testRemoveImportsOverloads() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/migration/deleteRedundantExtension/removeImportsOverloads.before.Main.kt");
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/migration/conflictingExtension/removeImportsOverloads.before.Main.kt");
|
||||
doTestWithExtraFile(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3923,83 +3923,89 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
|
||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/quickfix/migration"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("idea/testData/quickfix/migration/deleteRedundantExtension")
|
||||
@TestMetadata("idea/testData/quickfix/migration/conflictingExtension")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class DeleteRedundantExtension extends AbstractQuickFixTest {
|
||||
public void testAllFilesPresentInDeleteRedundantExtension() throws Exception {
|
||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/quickfix/migration/deleteRedundantExtension"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), true);
|
||||
public static class ConflictingExtension extends AbstractQuickFixTest {
|
||||
public void testAllFilesPresentInConflictingExtension() throws Exception {
|
||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/quickfix/migration/conflictingExtension"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("explicitThis.kt")
|
||||
public void testExplicitThis() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/migration/deleteRedundantExtension/explicitThis.kt");
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/migration/conflictingExtension/explicitThis.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("markHiddenAndDeprecated.kt")
|
||||
public void testMarkHiddenAndDeprecated() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/migration/conflictingExtension/markHiddenAndDeprecated.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("memberExtension.kt")
|
||||
public void testMemberExtension() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/migration/deleteRedundantExtension/memberExtension.kt");
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/migration/conflictingExtension/memberExtension.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("returnInGetter.kt")
|
||||
public void testReturnInGetter() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/migration/deleteRedundantExtension/returnInGetter.kt");
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/migration/conflictingExtension/returnInGetter.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("simple.kt")
|
||||
public void testSimple() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/migration/deleteRedundantExtension/simple.kt");
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/migration/conflictingExtension/simple.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("valInsteadOfVar.kt")
|
||||
public void testValInsteadOfVar() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/migration/deleteRedundantExtension/valInsteadOfVar.kt");
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/migration/conflictingExtension/valInsteadOfVar.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("varInsteadOfVal.kt")
|
||||
public void testVarInsteadOfVal() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/migration/deleteRedundantExtension/varInsteadOfVal.kt");
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/migration/conflictingExtension/varInsteadOfVal.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("withSetter.kt")
|
||||
public void testWithSetter() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/migration/deleteRedundantExtension/withSetter.kt");
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/migration/conflictingExtension/withSetter.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("wrongExplicitThis.kt")
|
||||
public void testWrongExplicitThis() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/migration/deleteRedundantExtension/wrongExplicitThis.kt");
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/migration/conflictingExtension/wrongExplicitThis.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("wrongExplicitThis2.kt")
|
||||
public void testWrongExplicitThis2() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/migration/deleteRedundantExtension/wrongExplicitThis2.kt");
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/migration/conflictingExtension/wrongExplicitThis2.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("wrongGetter.kt")
|
||||
public void testWrongGetter() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/migration/deleteRedundantExtension/wrongGetter.kt");
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/migration/conflictingExtension/wrongGetter.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("wrongGetter2.kt")
|
||||
public void testWrongGetter2() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/migration/deleteRedundantExtension/wrongGetter2.kt");
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/migration/conflictingExtension/wrongGetter2.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("wrongSetter.kt")
|
||||
public void testWrongSetter() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/migration/deleteRedundantExtension/wrongSetter.kt");
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/migration/conflictingExtension/wrongSetter.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user