diff --git a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/OperatorConventions.java b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/OperatorConventions.java index d7adeeb6fcd..3a19ea56290 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/OperatorConventions.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/OperatorConventions.java @@ -33,6 +33,8 @@ public class OperatorConventions { public static final Name CONTAINS = Name.identifier("contains"); public static final Name INVOKE = Name.identifier("invoke"); public static final Name ITERATOR = Name.identifier("iterator"); + public static final Name GET = Name.identifier("get"); + public static final Name SET = Name.identifier("set"); public static final Name NEXT = Name.identifier("next"); public static final Name HAS_NEXT = Name.identifier("hasNext"); diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/usagesSearch/conventions.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/usagesSearch/conventions.kt index 876ef78109d..e42278060a1 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/usagesSearch/conventions.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/usagesSearch/conventions.kt @@ -41,10 +41,7 @@ public val ALL_SEARCHABLE_OPERATIONS: ImmutableSet = ImmutableSet public val ALL_SEARCHABLE_OPERATION_PATTERNS: Set = ALL_SEARCHABLE_OPERATIONS.map { (it as JetSingleValueToken).getValue() }.toSet() -public val INDEXING_OPERATION_NAMES: ImmutableSet = - ImmutableSet.of(Name.identifier("get"), Name.identifier("set")) - -public val ITERATOR_OPERATION_NAME: Name = Name.identifier("iterator") +public val INDEXING_OPERATION_NAMES: ImmutableSet = ImmutableSet.of(GET, SET) public val IN_OPERATIONS_TO_SEARCH: ImmutableSet = ImmutableSet.of(JetTokens.IN_KEYWORD) @@ -56,7 +53,7 @@ public fun Name.getOperationSymbolsToSearch(): Set { EQUALS -> return EQUALS_OPERATIONS IDENTITY_EQUALS -> return IDENTITY_EQUALS_OPERATIONS CONTAINS -> return IN_OPERATIONS_TO_SEARCH - ITERATOR_OPERATION_NAME -> return ImmutableSet.of(JetTokens.IN_KEYWORD) + ITERATOR -> return ImmutableSet.of(JetTokens.IN_KEYWORD) in INDEXING_OPERATION_NAMES -> return ImmutableSet.of(JetTokens.LBRACKET, JetTokens.BY_KEYWORD) DelegatedPropertyResolver.PROPERTY_DELEGATED_FUNCTION_NAME -> return ImmutableSet.of(JetTokens.BY_KEYWORD) } diff --git a/idea/resources/inspectionDescriptions/OperatorModifier.html b/idea/resources/inspectionDescriptions/OperatorModifier.html new file mode 100644 index 00000000000..545754bde2d --- /dev/null +++ b/idea/resources/inspectionDescriptions/OperatorModifier.html @@ -0,0 +1,6 @@ + + +This inspection reports functions that were overloading operators according to pre-M14 naming conventions +but are not annotated with the 'operator' modifier. The quickfix for the inspection adds the modifier. + + diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml index 4005251520f..311bc2dd450 100644 --- a/idea/src/META-INF/plugin.xml +++ b/idea/src/META-INF/plugin.xml @@ -1199,6 +1199,14 @@ level="WARNING" /> + + = 1 && nameAsName == OperatorConventions.GET) { + return true + } + if (arity >= 2 && nameAsName == OperatorConventions.SET) { + return true + } + return false + } +} + +class AddModifierLocalQuickFix(val modifier: JetModifierKeywordToken) : LocalQuickFix { + override fun getName(): String = "Add '${modifier.value}' modifier" + override fun getFamilyName(): String = getName() + + override fun applyFix(project: Project, descriptor: ProblemDescriptor) { + val modifierListOwner = descriptor.psiElement.getNonStrictParentOfType() + modifierListOwner?.addModifier(modifier) + } +} diff --git a/idea/testData/quickfix/migration/operatorModifier/.inspection b/idea/testData/quickfix/migration/operatorModifier/.inspection new file mode 100644 index 00000000000..c9bccbc41b6 --- /dev/null +++ b/idea/testData/quickfix/migration/operatorModifier/.inspection @@ -0,0 +1 @@ +org.jetbrains.kotlin.idea.inspections.OperatorModifierInspection \ No newline at end of file diff --git a/idea/testData/quickfix/migration/operatorModifier/simple.kt b/idea/testData/quickfix/migration/operatorModifier/simple.kt new file mode 100644 index 00000000000..05a4e3489a0 --- /dev/null +++ b/idea/testData/quickfix/migration/operatorModifier/simple.kt @@ -0,0 +1,4 @@ +// "Add 'operator' modifier" "true" +class A { + fun plus(other: A): A = A() +} \ No newline at end of file diff --git a/idea/testData/quickfix/migration/operatorModifier/simple.kt.after b/idea/testData/quickfix/migration/operatorModifier/simple.kt.after new file mode 100644 index 00000000000..0f22a4c9624 --- /dev/null +++ b/idea/testData/quickfix/migration/operatorModifier/simple.kt.after @@ -0,0 +1,4 @@ +// "Add 'operator' modifier" "true" +class A { + operator fun plus(other: A): A = A() +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java index a58b13ce1e7..576926bc968 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java @@ -4187,6 +4187,21 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { } } + @TestMetadata("idea/testData/quickfix/migration/operatorModifier") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class OperatorModifier extends AbstractQuickFixTest { + public void testAllFilesPresentInOperatorModifier() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/quickfix/migration/operatorModifier"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), true); + } + + @TestMetadata("simple.kt") + public void testSimple() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/migration/operatorModifier/simple.kt"); + doTest(fileName); + } + } + @TestMetadata("idea/testData/quickfix/migration/removeNameFromFunctionExpression") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class)