quickfix for usages of operators that don't have the proper annotation
This commit is contained in:
@@ -1204,8 +1204,7 @@
|
|||||||
groupName="Kotlin"
|
groupName="Kotlin"
|
||||||
language="jet"
|
language="jet"
|
||||||
enabledByDefault="true"
|
enabledByDefault="true"
|
||||||
level="WARNING"
|
level="WARNING"/>
|
||||||
cleanupTool="true"/>
|
|
||||||
|
|
||||||
<localInspection implementationClass="org.jetbrains.kotlin.idea.inspections.ConflictingExtensionPropertyInspection"
|
<localInspection implementationClass="org.jetbrains.kotlin.idea.inspections.ConflictingExtensionPropertyInspection"
|
||||||
displayName="Extension property conflicts with synthetic one"
|
displayName="Extension property conflicts with synthetic one"
|
||||||
|
|||||||
@@ -91,7 +91,8 @@ public class KotlinCleanupInspection(): LocalInspectionTool(), CleanupLocalInspe
|
|||||||
Errors.DEPRECATED_SYMBOL_WITH_MESSAGE,
|
Errors.DEPRECATED_SYMBOL_WITH_MESSAGE,
|
||||||
Errors.ACCESS_TO_PRIVATE_TOP_LEVEL_FROM_ANOTHER_FILE,
|
Errors.ACCESS_TO_PRIVATE_TOP_LEVEL_FROM_ANOTHER_FILE,
|
||||||
Errors.NON_CONST_VAL_USED_IN_CONSTANT_EXPRESSION,
|
Errors.NON_CONST_VAL_USED_IN_CONSTANT_EXPRESSION,
|
||||||
Errors.BACKING_FIELD_SYNTAX_DEPRECATED
|
Errors.BACKING_FIELD_SYNTAX_DEPRECATED,
|
||||||
|
Errors.OPERATOR_MODIFIER_REQUIRED
|
||||||
)
|
)
|
||||||
|
|
||||||
private fun Diagnostic.isObsoleteLabel(): Boolean {
|
private fun Diagnostic.isObsoleteLabel(): Boolean {
|
||||||
|
|||||||
@@ -16,23 +16,31 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.idea.inspections
|
package org.jetbrains.kotlin.idea.inspections
|
||||||
|
|
||||||
import com.intellij.codeInspection.*
|
import com.intellij.codeInsight.intention.IntentionAction
|
||||||
|
import com.intellij.codeInspection.LocalInspectionToolSession
|
||||||
|
import com.intellij.codeInspection.LocalQuickFix
|
||||||
|
import com.intellij.codeInspection.ProblemDescriptor
|
||||||
|
import com.intellij.codeInspection.ProblemsHolder
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.psi.PsiElementVisitor
|
import com.intellij.psi.PsiElementVisitor
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
|
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||||
|
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
||||||
|
import org.jetbrains.kotlin.diagnostics.DiagnosticWithParameters2
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||||
|
import org.jetbrains.kotlin.idea.quickfix.AddModifierFix
|
||||||
|
import org.jetbrains.kotlin.idea.quickfix.CleanupFix
|
||||||
|
import org.jetbrains.kotlin.idea.quickfix.JetSingleIntentionActionFactory
|
||||||
import org.jetbrains.kotlin.lexer.JetTokens
|
import org.jetbrains.kotlin.lexer.JetTokens
|
||||||
import org.jetbrains.kotlin.psi.JetClassOrObject
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.JetModifierListOwner
|
|
||||||
import org.jetbrains.kotlin.psi.JetNamedFunction
|
|
||||||
import org.jetbrains.kotlin.psi.JetVisitorVoid
|
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
|
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
||||||
import org.jetbrains.kotlin.resolve.dataClassUtils.isComponentLike
|
import org.jetbrains.kotlin.resolve.dataClassUtils.isComponentLike
|
||||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||||
|
import org.jetbrains.kotlin.resolve.source.PsiSourceElement
|
||||||
import org.jetbrains.kotlin.types.expressions.OperatorConventions
|
import org.jetbrains.kotlin.types.expressions.OperatorConventions
|
||||||
|
|
||||||
public class OperatorModifierInspection : AbstractKotlinInspection(), CleanupLocalInspectionTool {
|
public class OperatorModifierInspection : AbstractKotlinInspection() {
|
||||||
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean, session: LocalInspectionToolSession): PsiElementVisitor {
|
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean, session: LocalInspectionToolSession): PsiElementVisitor {
|
||||||
return object : JetVisitorVoid() {
|
return object : JetVisitorVoid() {
|
||||||
override fun visitNamedFunction(function: JetNamedFunction) {
|
override fun visitNamedFunction(function: JetNamedFunction) {
|
||||||
@@ -99,3 +107,11 @@ private class AddModifierLocalQuickFix() : LocalQuickFix {
|
|||||||
modifierListOwner?.addModifier(JetTokens.OPERATOR_KEYWORD)
|
modifierListOwner?.addModifier(JetTokens.OPERATOR_KEYWORD)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object OperatorModifierFixFactory : JetSingleIntentionActionFactory() {
|
||||||
|
override fun createAction(diagnostic: Diagnostic): IntentionAction? {
|
||||||
|
val param = (diagnostic as? DiagnosticWithParameters2<*, *, *>)?.a as? FunctionDescriptor ?: return null
|
||||||
|
val target = (param.source as? PsiSourceElement)?.psi as? JetDeclaration ?: return null
|
||||||
|
return object : AddModifierFix(target, JetTokens.OPERATOR_KEYWORD), CleanupFix {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.diagnostics.DiagnosticFactory
|
|||||||
import org.jetbrains.kotlin.diagnostics.Errors.*
|
import org.jetbrains.kotlin.diagnostics.Errors.*
|
||||||
import org.jetbrains.kotlin.idea.core.overrideImplement.ImplementMembersHandler
|
import org.jetbrains.kotlin.idea.core.overrideImplement.ImplementMembersHandler
|
||||||
import org.jetbrains.kotlin.idea.inspections.AddReflectionQuickFix
|
import org.jetbrains.kotlin.idea.inspections.AddReflectionQuickFix
|
||||||
|
import org.jetbrains.kotlin.idea.inspections.OperatorModifierFixFactory
|
||||||
import org.jetbrains.kotlin.idea.intentions.IntroduceBackingPropertyFix
|
import org.jetbrains.kotlin.idea.intentions.IntroduceBackingPropertyFix
|
||||||
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.createCallable.*
|
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.createCallable.*
|
||||||
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.createClass.CreateClassFromCallWithConstructorCalleeActionFactory
|
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.createClass.CreateClassFromCallWithConstructorCalleeActionFactory
|
||||||
@@ -326,5 +327,7 @@ public class QuickFixRegistrar : QuickFixContributor {
|
|||||||
BACKING_FIELD_SYNTAX_DEPRECATED.registerFactory(MigrateBackingFieldSyntaxFix)
|
BACKING_FIELD_SYNTAX_DEPRECATED.registerFactory(MigrateBackingFieldSyntaxFix)
|
||||||
BACKING_FIELD_USAGE_DEPRECATED.registerFactory(MigrateBackingFieldUsageFix)
|
BACKING_FIELD_USAGE_DEPRECATED.registerFactory(MigrateBackingFieldUsageFix)
|
||||||
BACKING_FIELD_USAGE_DEPRECATED.registerFactory(IntroduceBackingPropertyFix)
|
BACKING_FIELD_USAGE_DEPRECATED.registerFactory(IntroduceBackingPropertyFix)
|
||||||
|
|
||||||
|
OPERATOR_MODIFIER_REQUIRED.registerFactory(OperatorModifierFixFactory)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+10
@@ -47,3 +47,13 @@ class Foo {
|
|||||||
get = $x
|
get = $x
|
||||||
set(value) { $x = value }
|
set(value) { $x = value }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class B {
|
||||||
|
fun plus(a: A): A = A()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun foo() {
|
||||||
|
B() + B()
|
||||||
|
B() + B()
|
||||||
|
B() + B()
|
||||||
|
}
|
||||||
|
|||||||
@@ -46,3 +46,13 @@ class Foo {
|
|||||||
get = field
|
get = field
|
||||||
set(value) { field = value }
|
set(value) { field = value }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class B {
|
||||||
|
operator fun plus(a: A): A = A()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun foo() {
|
||||||
|
B() + B()
|
||||||
|
B() + B()
|
||||||
|
B() + B()
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
// "Add 'operator' modifier" "true"
|
||||||
|
class A {
|
||||||
|
fun plus(a: A): A = A()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun foo() {
|
||||||
|
A() <caret>+ A()
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
// "Add 'operator' modifier" "true"
|
||||||
|
class A {
|
||||||
|
operator fun plus(a: A): A = A()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun foo() {
|
||||||
|
A() <caret>+ A()
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
// "Add 'operator' modifier" "true"
|
||||||
|
class A {
|
||||||
|
fun contains(x: Any): Boolean = false
|
||||||
|
}
|
||||||
|
|
||||||
|
fun foo() = 0 i<caret>n A()
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
// "Add 'operator' modifier" "true"
|
||||||
|
class A {
|
||||||
|
operator fun contains(x: Any): Boolean = false
|
||||||
|
}
|
||||||
|
|
||||||
|
fun foo() = 0 in A()
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
// "Add 'operator' modifier" "true"
|
||||||
|
class A {
|
||||||
|
fun component1(): Int = 0
|
||||||
|
fun component2(): Int = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
fun foo() {
|
||||||
|
val (<caret>zero, one) = A()
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
// "Add 'operator' modifier" "true"
|
||||||
|
class A {
|
||||||
|
operator fun component1(): Int = 0
|
||||||
|
fun component2(): Int = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
fun foo() {
|
||||||
|
val (zero, one) = A()
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
// "Add 'operator' modifier" "true"
|
||||||
|
class A {
|
||||||
|
fun get(i: Int): String = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
fun foo() = A()<caret>[0]
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
// "Add 'operator' modifier" "true"
|
||||||
|
class A {
|
||||||
|
operator fun get(i: Int): String = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
fun foo() = A()[0]
|
||||||
@@ -4316,6 +4316,30 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("operatorModifier.kt")
|
||||||
|
public void testOperatorModifier() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/modifiers/operatorModifier.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("operatorModifierCollection.kt")
|
||||||
|
public void testOperatorModifierCollection() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/modifiers/operatorModifierCollection.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("operatorModifierComponent.kt")
|
||||||
|
public void testOperatorModifierComponent() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/modifiers/operatorModifierComponent.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("operatorModifierGet.kt")
|
||||||
|
public void testOperatorModifierGet() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/modifiers/operatorModifierGet.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("packageMemberCannotBeProtected.kt")
|
@TestMetadata("packageMemberCannotBeProtected.kt")
|
||||||
public void testPackageMemberCannotBeProtected() throws Exception {
|
public void testPackageMemberCannotBeProtected() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/modifiers/packageMemberCannotBeProtected.kt");
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/modifiers/packageMemberCannotBeProtected.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user