Rename: Drop 'operator' keyword if new name doesn't correspond to any convention

#KT-9357 Fixed
This commit is contained in:
Alexey Sedunov
2015-09-29 20:27:55 +03:00
parent 1f6f617546
commit 2f251b9216
16 changed files with 42 additions and 28 deletions
@@ -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<T extends KotlinStubWithFqName<?>> extends JetDeclarationStub<T> implements JetNamedDeclaration {
public JetNamedDeclarationStub(@NotNull T stub, @NotNull IStubElementType nodeType) {
@@ -79,7 +80,16 @@ abstract class JetNamedDeclarationStub<T extends KotlinStubWithFqName<?>> 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
@@ -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,
@@ -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<Name> CONVENTION_NAMES = ImmutableSet.<Name>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());
}
}
@@ -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() {
@@ -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() {
@@ -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() {
@@ -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() {
@@ -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() {
+1 -1
View File
@@ -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() {
+1 -1
View File
@@ -1,5 +1,5 @@
class A(val n: Int) {
fun inc(): A = A(n + 1)
operator fun inc(): A = A(n + 1)
}
fun test() {
@@ -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() {
@@ -1,5 +1,5 @@
class A {
public fun iterator(): Iterator<String> = throw IllegalStateException("")
public operator fun iterator(): Iterator<String> = throw IllegalStateException("")
}
fun test() {
+1 -1
View File
@@ -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() {
@@ -1,5 +1,5 @@
class A(var n: Int) {
fun plusAssign(m: Int) {
operator fun plusAssign(m: Int) {
n += m
}
}
+1 -1
View File
@@ -1,5 +1,5 @@
class A(val n: Int) {
fun set(i: Int, a: A) {}
operator fun set(i: Int, a: A) {}
}
fun test() {
@@ -1,5 +1,5 @@
class A(val n: Int) {
fun minus(): A = this
operator fun minus(): A = this
}
fun test() {