From 2f251b92161958db49e287cf82620ff5fadb0337 Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Tue, 29 Sep 2015 20:27:55 +0300 Subject: [PATCH] Rename: Drop 'operator' keyword if new name doesn't correspond to any convention #KT-9357 Fixed --- .../kotlin/psi/JetNamedDeclarationStub.java | 18 ++++++++++++++---- .../kotlin/resolve/OperatorModifierChecker.kt | 9 --------- .../types/expressions/OperatorConventions.java | 13 +++++++++++++ .../rename/renameCompareTo/before/compareTo.kt | 2 +- .../rename/renameContains/before/contains.kt | 2 +- .../before/containsWithConflicts.kt | 2 +- .../rename/renameEquals/before/equals.kt | 2 +- .../before/explicitComponentFunction.kt | 6 +++--- .../refactoring/rename/renameGet/before/get.kt | 2 +- .../refactoring/rename/renameInc/before/inc.kt | 2 +- .../rename/renameInvoke/before/invoke.kt | 2 +- .../rename/renameIterator/before/iterator.kt | 2 +- .../rename/renamePlus/before/plus.kt | 2 +- .../renamePlusAssign/before/plusAssign.kt | 2 +- .../refactoring/rename/renameSet/before/set.kt | 2 +- .../renameUnaryMinus/before/unaryMinus.kt | 2 +- 16 files changed, 42 insertions(+), 28 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/psi/JetNamedDeclarationStub.java b/compiler/frontend/src/org/jetbrains/kotlin/psi/JetNamedDeclarationStub.java index 3b9d0479f45..e8236a4d6de 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/psi/JetNamedDeclarationStub.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/psi/JetNamedDeclarationStub.java @@ -26,12 +26,13 @@ import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.kotlin.psi.stubs.KotlinStubWithFqName; +import org.jetbrains.kotlin.lexer.JetTokens; import org.jetbrains.kotlin.name.FqName; import org.jetbrains.kotlin.name.Name; -import org.jetbrains.kotlin.lexer.JetTokens; +import org.jetbrains.kotlin.psi.stubs.KotlinStubWithFqName; +import org.jetbrains.kotlin.types.expressions.OperatorConventions; -import static org.jetbrains.kotlin.psi.PsiPackage.JetPsiFactory; +import static org.jetbrains.kotlin.psi.JetPsiFactoryKt.JetPsiFactory; abstract class JetNamedDeclarationStub> extends JetDeclarationStub implements JetNamedDeclaration { public JetNamedDeclarationStub(@NotNull T stub, @NotNull IStubElementType nodeType) { @@ -79,7 +80,16 @@ abstract class JetNamedDeclarationStub> extend @Override public PsiElement setName(@NonNls @NotNull String name) throws IncorrectOperationException { PsiElement identifier = getNameIdentifier(); - return identifier != null ? identifier.replace(JetPsiFactory(this).createNameIdentifier(name)) : null; + if (identifier == null) return null; + + JetModifierList modifierList = getModifierList(); + if (modifierList != null && + modifierList.hasModifier(JetTokens.OPERATOR_KEYWORD) && + !OperatorConventions.isConventionName(Name.identifierNoValidate(name))) { + removeModifier(JetTokens.OPERATOR_KEYWORD); + } + + return identifier.replace(JetPsiFactory(this).createNameIdentifier(name)); } @Override diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/OperatorModifierChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/OperatorModifierChecker.kt index 92929e5df3a..8efa089ee96 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/OperatorModifierChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/OperatorModifierChecker.kt @@ -37,19 +37,10 @@ import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.diagnostics.DiagnosticSink import org.jetbrains.kotlin.diagnostics.Errors import org.jetbrains.kotlin.lexer.JetTokens -import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.JetDeclaration import org.jetbrains.kotlin.types.expressions.OperatorConventions.* public class OperatorModifierChecker : DeclarationChecker { - - private companion object { - private val GET = Name.identifier("get") - private val SET = Name.identifier("set") - - private val COMPONENT_REGEX = "component\\d+".toRegex() - } - override fun check( declaration: JetDeclaration, descriptor: DeclarationDescriptor, 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 3a19ea56290..c6526670977 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/OperatorConventions.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/OperatorConventions.java @@ -18,6 +18,7 @@ package org.jetbrains.kotlin.types.expressions; import com.google.common.collect.ImmutableBiMap; import com.google.common.collect.ImmutableSet; +import kotlin.text.Regex; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.lexer.JetSingleValueToken; @@ -37,6 +38,7 @@ public class OperatorConventions { 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"); + public static final Regex COMPONENT_REGEX = new Regex("component\\d+"); private OperatorConventions() {} @@ -110,6 +112,13 @@ public class OperatorConventions { .put(JetTokens.OROR, Name.identifier("or")) .build(); + public static final ImmutableSet CONVENTION_NAMES = ImmutableSet.builder() + .add(GET, SET, INVOKE, CONTAINS, ITERATOR, NEXT, HAS_NEXT, EQUALS, COMPARE_TO) + .addAll(UNARY_OPERATION_NAMES.values()) + .addAll(BINARY_OPERATION_NAMES.values()) + .addAll(ASSIGNMENT_OPERATIONS.values()) + .build(); + @Nullable public static Name getNameForOperationSymbol(@NotNull JetToken token) { Name name = UNARY_OPERATION_NAMES.get(token); @@ -123,4 +132,8 @@ public class OperatorConventions { if (IN_OPERATIONS.contains(token)) return CONTAINS; return null; } + + public static boolean isConventionName(@NotNull Name name) { + return CONVENTION_NAMES.contains(name) || COMPONENT_REGEX.matches(name.asString()); + } } diff --git a/idea/testData/refactoring/rename/renameCompareTo/before/compareTo.kt b/idea/testData/refactoring/rename/renameCompareTo/before/compareTo.kt index 11886186fa1..42b0b3b85dc 100644 --- a/idea/testData/refactoring/rename/renameCompareTo/before/compareTo.kt +++ b/idea/testData/refactoring/rename/renameCompareTo/before/compareTo.kt @@ -1,5 +1,5 @@ class A(val n: Int) { - fun compareTo(other: A): Int = n.compareTo(other.n) + operator fun compareTo(other: A): Int = n.compareTo(other.n) } fun test() { diff --git a/idea/testData/refactoring/rename/renameContains/before/contains.kt b/idea/testData/refactoring/rename/renameContains/before/contains.kt index 0163dd5e1ba..9a313c7ef08 100644 --- a/idea/testData/refactoring/rename/renameContains/before/contains.kt +++ b/idea/testData/refactoring/rename/renameContains/before/contains.kt @@ -1,5 +1,5 @@ class A(val n: Int) { - fun contains(k: Int): Boolean = k <= n + operator fun contains(k: Int): Boolean = k <= n } fun test() { diff --git a/idea/testData/refactoring/rename/renameContainsWithConflicts/before/containsWithConflicts.kt b/idea/testData/refactoring/rename/renameContainsWithConflicts/before/containsWithConflicts.kt index ab1e6d6a826..1d7b54730fb 100644 --- a/idea/testData/refactoring/rename/renameContainsWithConflicts/before/containsWithConflicts.kt +++ b/idea/testData/refactoring/rename/renameContainsWithConflicts/before/containsWithConflicts.kt @@ -1,5 +1,5 @@ class A(val n: Int) { - fun contains(k: Int): Boolean = k <= n + operator fun contains(k: Int): Boolean = k <= n } fun test() { diff --git a/idea/testData/refactoring/rename/renameEquals/before/equals.kt b/idea/testData/refactoring/rename/renameEquals/before/equals.kt index 0a3dd16e317..d4915dfdfce 100644 --- a/idea/testData/refactoring/rename/renameEquals/before/equals.kt +++ b/idea/testData/refactoring/rename/renameEquals/before/equals.kt @@ -1,5 +1,5 @@ class A(val n: Int) { - override fun equals(other: Any?): Boolean = other is A && other.n == n + override operator fun equals(other: Any?): Boolean = other is A && other.n == n } fun test() { diff --git a/idea/testData/refactoring/rename/renameExplicitComponentFunction/before/explicitComponentFunction.kt b/idea/testData/refactoring/rename/renameExplicitComponentFunction/before/explicitComponentFunction.kt index 64c676ef4d1..381e600c75a 100644 --- a/idea/testData/refactoring/rename/renameExplicitComponentFunction/before/explicitComponentFunction.kt +++ b/idea/testData/refactoring/rename/renameExplicitComponentFunction/before/explicitComponentFunction.kt @@ -1,7 +1,7 @@ class A(val n: Int, val s: String, val o: Any) { - fun component1(): Int = n - fun component2(): String = s - fun component3(): Any = o + operator fun component1(): Int = n + operator fun component2(): String = s + operator fun component3(): Any = o } fun test() { diff --git a/idea/testData/refactoring/rename/renameGet/before/get.kt b/idea/testData/refactoring/rename/renameGet/before/get.kt index 0d6c8ad4f08..c1a14c2b153 100644 --- a/idea/testData/refactoring/rename/renameGet/before/get.kt +++ b/idea/testData/refactoring/rename/renameGet/before/get.kt @@ -1,5 +1,5 @@ class A(val n: Int) { - fun get(i: Int): A = A(i) + operator fun get(i: Int): A = A(i) } fun test() { diff --git a/idea/testData/refactoring/rename/renameInc/before/inc.kt b/idea/testData/refactoring/rename/renameInc/before/inc.kt index 6fd9af98845..14bcaf0f81f 100644 --- a/idea/testData/refactoring/rename/renameInc/before/inc.kt +++ b/idea/testData/refactoring/rename/renameInc/before/inc.kt @@ -1,5 +1,5 @@ class A(val n: Int) { - fun inc(): A = A(n + 1) + operator fun inc(): A = A(n + 1) } fun test() { diff --git a/idea/testData/refactoring/rename/renameInvoke/before/invoke.kt b/idea/testData/refactoring/rename/renameInvoke/before/invoke.kt index a589143887e..d0bc0815fcc 100644 --- a/idea/testData/refactoring/rename/renameInvoke/before/invoke.kt +++ b/idea/testData/refactoring/rename/renameInvoke/before/invoke.kt @@ -1,5 +1,5 @@ class A(val n: Int) { - fun invoke(i: Int): A = A(i) + operator fun invoke(i: Int): A = A(i) } fun test() { diff --git a/idea/testData/refactoring/rename/renameIterator/before/iterator.kt b/idea/testData/refactoring/rename/renameIterator/before/iterator.kt index 9a8c721a05f..b3d6fa07a68 100644 --- a/idea/testData/refactoring/rename/renameIterator/before/iterator.kt +++ b/idea/testData/refactoring/rename/renameIterator/before/iterator.kt @@ -1,5 +1,5 @@ class A { - public fun iterator(): Iterator = throw IllegalStateException("") + public operator fun iterator(): Iterator = throw IllegalStateException("") } fun test() { diff --git a/idea/testData/refactoring/rename/renamePlus/before/plus.kt b/idea/testData/refactoring/rename/renamePlus/before/plus.kt index c202a28b32f..a442f8962ff 100644 --- a/idea/testData/refactoring/rename/renamePlus/before/plus.kt +++ b/idea/testData/refactoring/rename/renamePlus/before/plus.kt @@ -1,5 +1,5 @@ class A(val n: Int) { - fun plus(m: Int): A = A(n + m) + operator fun plus(m: Int): A = A(n + m) } fun test() { diff --git a/idea/testData/refactoring/rename/renamePlusAssign/before/plusAssign.kt b/idea/testData/refactoring/rename/renamePlusAssign/before/plusAssign.kt index f0a0b17069a..e7a1455bf4b 100644 --- a/idea/testData/refactoring/rename/renamePlusAssign/before/plusAssign.kt +++ b/idea/testData/refactoring/rename/renamePlusAssign/before/plusAssign.kt @@ -1,5 +1,5 @@ class A(var n: Int) { - fun plusAssign(m: Int) { + operator fun plusAssign(m: Int) { n += m } } diff --git a/idea/testData/refactoring/rename/renameSet/before/set.kt b/idea/testData/refactoring/rename/renameSet/before/set.kt index 9a9f4b61f51..09a8b07123e 100644 --- a/idea/testData/refactoring/rename/renameSet/before/set.kt +++ b/idea/testData/refactoring/rename/renameSet/before/set.kt @@ -1,5 +1,5 @@ class A(val n: Int) { - fun set(i: Int, a: A) {} + operator fun set(i: Int, a: A) {} } fun test() { diff --git a/idea/testData/refactoring/rename/renameUnaryMinus/before/unaryMinus.kt b/idea/testData/refactoring/rename/renameUnaryMinus/before/unaryMinus.kt index fc104dc18ff..62ed0d6422a 100644 --- a/idea/testData/refactoring/rename/renameUnaryMinus/before/unaryMinus.kt +++ b/idea/testData/refactoring/rename/renameUnaryMinus/before/unaryMinus.kt @@ -1,5 +1,5 @@ class A(val n: Int) { - fun minus(): A = this + operator fun minus(): A = this } fun test() {