Rename unary plus() and minus() to unaryPlus() and unaryMinus()

This commit is contained in:
Yan Zhulanow
2015-10-07 19:25:32 +03:00
parent 1f2b4e20fe
commit ed5c059cea
59 changed files with 210 additions and 88 deletions
@@ -518,6 +518,8 @@ public interface Errors {
DiagnosticFactory0<JetArrayAccessExpression> NO_GET_METHOD = DiagnosticFactory0.create(ERROR, ARRAY_ACCESS); DiagnosticFactory0<JetArrayAccessExpression> NO_GET_METHOD = DiagnosticFactory0.create(ERROR, ARRAY_ACCESS);
DiagnosticFactory0<JetArrayAccessExpression> NO_SET_METHOD = DiagnosticFactory0.create(ERROR, ARRAY_ACCESS); DiagnosticFactory0<JetArrayAccessExpression> NO_SET_METHOD = DiagnosticFactory0.create(ERROR, ARRAY_ACCESS);
DiagnosticFactory2<JetUnaryExpression, FunctionDescriptor, String> DEPRECATED_UNARY_PLUS_MINUS = DiagnosticFactory2.create(WARNING);
DiagnosticFactory0<JetSimpleNameExpression> INC_DEC_SHOULD_NOT_RETURN_UNIT = DiagnosticFactory0.create(ERROR); DiagnosticFactory0<JetSimpleNameExpression> INC_DEC_SHOULD_NOT_RETURN_UNIT = DiagnosticFactory0.create(ERROR);
DiagnosticFactory2<JetSimpleNameExpression, DeclarationDescriptor, JetSimpleNameExpression> ASSIGNMENT_OPERATOR_SHOULD_RETURN_UNIT = DiagnosticFactory2<JetSimpleNameExpression, DeclarationDescriptor, JetSimpleNameExpression> ASSIGNMENT_OPERATOR_SHOULD_RETURN_UNIT =
DiagnosticFactory2.create(ERROR); DiagnosticFactory2.create(ERROR);
@@ -310,6 +310,8 @@ public class DefaultErrorMessages {
MAP.put(NO_GET_METHOD, "No get method providing array access"); MAP.put(NO_GET_METHOD, "No get method providing array access");
MAP.put(NO_SET_METHOD, "No set method providing array access"); MAP.put(NO_SET_METHOD, "No set method providing array access");
MAP.put(DEPRECATED_UNARY_PLUS_MINUS, "Deprecated convention for ''{0}''. Rename to ''{1}''", NAME, STRING);
MAP.put(INC_DEC_SHOULD_NOT_RETURN_UNIT, "Functions inc(), dec() shouldn't return Unit to be used by operators ++, --"); MAP.put(INC_DEC_SHOULD_NOT_RETURN_UNIT, "Functions inc(), dec() shouldn't return Unit to be used by operators ++, --");
MAP.put(ASSIGNMENT_OPERATOR_SHOULD_RETURN_UNIT, "Function ''{0}'' should return Unit to be used by corresponding operator ''{1}''", MAP.put(ASSIGNMENT_OPERATOR_SHOULD_RETURN_UNIT, "Function ''{0}'' should return Unit to be used by corresponding operator ''{1}''",
NAME, ELEMENT_TEXT); NAME, ELEMENT_TEXT);
@@ -28,9 +28,9 @@ import org.jetbrains.kotlin.types.expressions.OperatorConventions
public class JetOperationReferenceExpression(node: ASTNode) : JetSimpleNameExpressionImpl(node) { public class JetOperationReferenceExpression(node: ASTNode) : JetSimpleNameExpressionImpl(node) {
override fun getReferencedNameElement() = (findChildByType(JetExpressionParsing.ALL_OPERATIONS): PsiElement?) ?: this override fun getReferencedNameElement() = (findChildByType(JetExpressionParsing.ALL_OPERATIONS): PsiElement?) ?: this
fun getNameForConventionalOperation(): Name? { fun getNameForConventionalOperation(unaryOperations: Boolean = true, binaryOperations: Boolean = true): Name? {
val operator = (firstChild as? TreeElement)?.elementType as? JetToken ?: return null val operator = (firstChild as? TreeElement)?.elementType as? JetToken ?: return null
return OperatorConventions.getNameForOperationSymbol(operator) return OperatorConventions.getNameForOperationSymbol(operator, unaryOperations, binaryOperations)
} }
fun isPredefinedOperator() = (firstChild as? TreeElement)?.elementType is JetSingleValueToken fun isPredefinedOperator() = (firstChild as? TreeElement)?.elementType is JetSingleValueToken
@@ -371,6 +371,10 @@ public class JetPsiUtil {
IElementType elementType = firstChild.getNode().getElementType(); IElementType elementType = firstChild.getNode().getElementType();
if (elementType instanceof JetToken) { if (elementType instanceof JetToken) {
JetToken jetToken = (JetToken) elementType; JetToken jetToken = (JetToken) elementType;
boolean isPrefixExpression = simpleNameExpression.getParent() instanceof JetPrefixExpression;
if (isPrefixExpression) {
return OperatorConventions.getNameForOperationSymbol(jetToken, true, false);
}
return OperatorConventions.getNameForOperationSymbol(jetToken); return OperatorConventions.getNameForOperationSymbol(jetToken);
} }
} }
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.calls.CallTransformer import org.jetbrains.kotlin.resolve.calls.CallTransformer
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystem import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystem
@@ -31,6 +32,7 @@ import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.Constrain
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.TypeUtils.DONT_CARE import org.jetbrains.kotlin.types.TypeUtils.DONT_CARE
import org.jetbrains.kotlin.util.OperatorNameConventions
public enum class ResolveArgumentsMode { public enum class ResolveArgumentsMode {
RESOLVE_FUNCTION_ARGUMENTS, RESOLVE_FUNCTION_ARGUMENTS,
@@ -120,6 +122,13 @@ fun isConventionCall(call: Call): Boolean {
return calleeExpression.getNameForConventionalOperation() != null return calleeExpression.getNameForConventionalOperation() != null
} }
fun getUnaryPlusOrMinusOperatorFunctionName(call: Call): Name? {
if (call.callElement !is JetPrefixExpression) return null
val calleeExpression = call.calleeExpression as? JetOperationReferenceExpression ?: return null
val name = calleeExpression.getNameForConventionalOperation(unaryOperations = true, binaryOperations = false)
return if (name == OperatorNameConventions.UNARY_PLUS || name == OperatorNameConventions.UNARY_MINUS) name else null
}
public fun isInvokeCallOnVariable(call: Call): Boolean { public fun isInvokeCallOnVariable(call: Call): Boolean {
if (call.getCallType() !== Call.CallType.INVOKE) return false if (call.getCallType() !== Call.CallType.INVOKE) return false
val dispatchReceiver = call.getDispatchReceiver() val dispatchReceiver = call.getDispatchReceiver()
@@ -23,9 +23,9 @@ import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.calls.CallTransformer
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isConventionCall import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isConventionCall
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isOrOverridesSynthesized import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isOrOverridesSynthesized
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.getUnaryPlusOrMinusOperatorFunctionName
import org.jetbrains.kotlin.resolve.calls.context.BasicCallResolutionContext import org.jetbrains.kotlin.resolve.calls.context.BasicCallResolutionContext
import org.jetbrains.kotlin.resolve.calls.context.ResolutionContext import org.jetbrains.kotlin.resolve.calls.context.ResolutionContext
import org.jetbrains.kotlin.resolve.calls.smartcasts.SmartCastManager import org.jetbrains.kotlin.resolve.calls.smartcasts.SmartCastManager
@@ -51,6 +51,7 @@ import org.jetbrains.kotlin.types.JetType
import org.jetbrains.kotlin.types.checker.JetTypeChecker import org.jetbrains.kotlin.types.checker.JetTypeChecker
import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils
import org.jetbrains.kotlin.types.isDynamic import org.jetbrains.kotlin.types.isDynamic
import org.jetbrains.kotlin.util.OperatorNameConventions
public class TaskPrioritizer( public class TaskPrioritizer(
private val storageManager: StorageManager, private val storageManager: StorageManager,
@@ -76,6 +77,18 @@ public class TaskPrioritizer(
} }
else { else {
doComputeTasks(explicitReceiver, taskPrioritizerContext) doComputeTasks(explicitReceiver, taskPrioritizerContext)
// Temporary fix for code migration (unaryPlus()/unaryMinus())
val unaryConventionName = getUnaryPlusOrMinusOperatorFunctionName(context.call)
if (unaryConventionName != null) {
val deprecatedName = if (name == OperatorNameConventions.UNARY_PLUS)
OperatorNameConventions.PLUS
else
OperatorNameConventions.MINUS
val additionalContext = TaskPrioritizerContext(deprecatedName, result, context, context.scope, callableDescriptorCollectors)
doComputeTasks(explicitReceiver, additionalContext)
}
} }
return result.getTasks() return result.getTasks()
@@ -17,6 +17,7 @@
package org.jetbrains.kotlin.types.expressions; package org.jetbrains.kotlin.types.expressions;
import com.google.common.collect.ImmutableBiMap; import com.google.common.collect.ImmutableBiMap;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@@ -24,6 +25,9 @@ import org.jetbrains.kotlin.lexer.JetSingleValueToken;
import org.jetbrains.kotlin.lexer.JetToken; import org.jetbrains.kotlin.lexer.JetToken;
import org.jetbrains.kotlin.lexer.JetTokens; import org.jetbrains.kotlin.lexer.JetTokens;
import org.jetbrains.kotlin.name.Name; import org.jetbrains.kotlin.name.Name;
import java.util.Map;
import static org.jetbrains.kotlin.util.OperatorNameConventions.*; import static org.jetbrains.kotlin.util.OperatorNameConventions.*;
public class OperatorConventions { public class OperatorConventions {
@@ -49,11 +53,21 @@ public class OperatorConventions {
public static final ImmutableBiMap<JetSingleValueToken, Name> UNARY_OPERATION_NAMES = ImmutableBiMap.<JetSingleValueToken, Name>builder() public static final ImmutableBiMap<JetSingleValueToken, Name> UNARY_OPERATION_NAMES = ImmutableBiMap.<JetSingleValueToken, Name>builder()
.put(JetTokens.PLUSPLUS, INC) .put(JetTokens.PLUSPLUS, INC)
.put(JetTokens.MINUSMINUS, DEC) .put(JetTokens.MINUSMINUS, DEC)
.put(JetTokens.PLUS, PLUS) .put(JetTokens.PLUS, UNARY_PLUS)
.put(JetTokens.MINUS, MINUS) .put(JetTokens.MINUS, UNARY_MINUS)
.put(JetTokens.EXCL, NOT) .put(JetTokens.EXCL, NOT)
.build(); .build();
public static final ImmutableMap<Name, JetSingleValueToken> UNARY_OPERATION_NAMES_WITH_DEPRECATED_INVERTED = ImmutableMap.<Name, JetSingleValueToken>builder()
.put(INC, JetTokens.PLUSPLUS)
.put(DEC, JetTokens.MINUSMINUS)
.put(UNARY_PLUS, JetTokens.PLUS)
.put(PLUS, JetTokens.PLUS)
.put(UNARY_MINUS, JetTokens.MINUS)
.put(MINUS, JetTokens.MINUS)
.put(NOT, JetTokens.EXCL)
.build();
public static final ImmutableBiMap<JetSingleValueToken, Name> BINARY_OPERATION_NAMES = ImmutableBiMap.<JetSingleValueToken, Name>builder() public static final ImmutableBiMap<JetSingleValueToken, Name> BINARY_OPERATION_NAMES = ImmutableBiMap.<JetSingleValueToken, Name>builder()
.put(JetTokens.MUL, TIMES) .put(JetTokens.MUL, TIMES)
.put(JetTokens.PLUS, PLUS) .put(JetTokens.PLUS, PLUS)
@@ -111,10 +125,23 @@ public class OperatorConventions {
@Nullable @Nullable
public static Name getNameForOperationSymbol(@NotNull JetToken token) { public static Name getNameForOperationSymbol(@NotNull JetToken token) {
Name name = UNARY_OPERATION_NAMES.get(token); return getNameForOperationSymbol(token, true, true);
if (name != null) return name; }
name = BINARY_OPERATION_NAMES.get(token);
if (name != null) return name; @Nullable
public static Name getNameForOperationSymbol(@NotNull JetToken token, boolean unaryOperations, boolean binaryOperations) {
Name name;
if (binaryOperations) {
name = BINARY_OPERATION_NAMES.get(token);
if (name != null) return name;
}
if (unaryOperations) {
name = UNARY_OPERATION_NAMES.get(token);
if (name != null) return name;
}
name = ASSIGNMENT_OPERATIONS.get(token); name = ASSIGNMENT_OPERATIONS.get(token);
if (name != null) return name; if (name != null) return name;
if (COMPARISON_OPERATIONS.contains(token)) return COMPARE_TO; if (COMPARISON_OPERATIONS.contains(token)) return COMPARE_TO;
@@ -0,0 +1,22 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER
class Example {
operator fun plus(): String = ""
operator fun unaryPlus(): Int = 0
}
class ExampleDeprecated {
operator fun plus(): String = ""
}
operator fun String.plus(): String = this
operator fun String.unaryPlus(): Int = 0
fun test() {
requireInt(+ "")
requireInt(+ Example())
requireString(+ ExampleDeprecated())
}
fun requireInt(n: Int) {}
fun requireString(s: String) {}
@@ -0,0 +1,24 @@
package
public fun requireInt(/*0*/ n: kotlin.Int): kotlin.Unit
public fun requireString(/*0*/ s: kotlin.String): kotlin.Unit
public fun test(): kotlin.Unit
public operator fun kotlin.String.plus(): kotlin.String
public operator fun kotlin.String.unaryPlus(): kotlin.Int
public final class Example {
public constructor Example()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public final operator fun plus(): kotlin.String
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
public final operator fun unaryPlus(): kotlin.Int
}
public final class ExampleDeprecated {
public constructor ExampleDeprecated()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public final operator fun plus(): kotlin.String
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -1,5 +1,5 @@
public final fun plus(): dynamic public final fun unaryPlus(): dynamic
public final fun minus(): dynamic public final fun unaryMinus(): dynamic
public final fun not(): dynamic public final fun not(): dynamic
public final fun plus(/*0*/ p0: dynamic): dynamic public final fun plus(/*0*/ p0: dynamic): dynamic
public final fun plus(/*0*/ p0: dynamic): dynamic public final fun plus(/*0*/ p0: dynamic): dynamic
@@ -187,6 +187,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
doTest(fileName); doTest(fileName);
} }
@TestMetadata("DeprecatedUnaryOperatorConventions.kt")
public void testDeprecatedUnaryOperatorConventions() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/DeprecatedUnaryOperatorConventions.kt");
doTest(fileName);
}
@TestMetadata("DiamondFunction.kt") @TestMetadata("DiamondFunction.kt")
public void testDiamondFunction() throws Exception { public void testDiamondFunction() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/DiamondFunction.kt"); String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/DiamondFunction.kt");
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.util
import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import java.util.*
import kotlin.text.Regex import kotlin.text.Regex
object OperatorNameConventions { object OperatorNameConventions {
@@ -44,6 +45,9 @@ object OperatorNameConventions {
val MINUS = Name.identifier("minus") val MINUS = Name.identifier("minus")
val NOT = Name.identifier("not") val NOT = Name.identifier("not")
val UNARY_MINUS = Name.identifier("unaryMinus")
val UNARY_PLUS = Name.identifier("unaryPlus")
val TIMES = Name.identifier("times") val TIMES = Name.identifier("times")
val DIV = Name.identifier("div") val DIV = Name.identifier("div")
val MOD = Name.identifier("mod") val MOD = Name.identifier("mod")
@@ -57,7 +61,8 @@ object OperatorNameConventions {
// If you add new unary, binary or assignment operators, add it to OperatorConventions as well // If you add new unary, binary or assignment operators, add it to OperatorConventions as well
private val UNARY_OPERATION_NAMES = setOf(INC, DEC, PLUS, MINUS, NOT) val UNARY_OPERATION_NAMES_WITH_DEPRECATED = Collections.unmodifiableSet(setOf(INC, DEC, UNARY_PLUS, PLUS, UNARY_MINUS, MINUS, NOT))
private val UNARY_OPERATION_NAMES = setOf(INC, DEC, UNARY_PLUS, UNARY_MINUS, NOT)
private val BINARY_OPERATION_NAMES = setOf(TIMES, PLUS, MINUS, DIV, MOD, RANGE_TO) private val BINARY_OPERATION_NAMES = setOf(TIMES, PLUS, MINUS, DIV, MOD, RANGE_TO)
private val ASSIGNMENT_OPERATIONS = setOf(TIMES_ASSIGN, DIV_ASSIGN, MOD_ASSIGN, PLUS_ASSIGN, MINUS_ASSIGN) private val ASSIGNMENT_OPERATIONS = setOf(TIMES_ASSIGN, DIV_ASSIGN, MOD_ASSIGN, PLUS_ASSIGN, MINUS_ASSIGN)
@@ -76,6 +81,7 @@ object OperatorNameConventions {
COMPARE_TO == name -> true COMPARE_TO == name -> true
UNARY_OPERATION_NAMES.any { it == name } && functionDescriptor.valueParameters.isEmpty() -> true UNARY_OPERATION_NAMES.any { it == name } && functionDescriptor.valueParameters.isEmpty() -> true
BINARY_OPERATION_NAMES.any { it == name } && functionDescriptor.valueParameters.size() == 1 -> true BINARY_OPERATION_NAMES.any { it == name } && functionDescriptor.valueParameters.size() == 1 -> true
(PLUS == name) || (MINUS == name) -> true //temporary fix for deprecated unaryPlus()/unaryMinus()
ASSIGNMENT_OPERATIONS.any { it == name } -> true ASSIGNMENT_OPERATIONS.any { it == name } -> true
name.asString().matches(COMPONENT_REGEX) -> true name.asString().matches(COMPONENT_REGEX) -> true
else -> false else -> false
@@ -60,7 +60,7 @@ public fun Name.getOperationSymbolsToSearch(): Set<JetToken> {
if (isComponentLike(this)) return setOf(JetTokens.LPAR) if (isComponentLike(this)) return setOf(JetTokens.LPAR)
val unaryOp = UNARY_OPERATION_NAMES.inverse()[this] val unaryOp = UNARY_OPERATION_NAMES_WITH_DEPRECATED_INVERTED[this]
if (unaryOp != null) return setOf(unaryOp) if (unaryOp != null) return setOf(unaryOp)
val binaryOp = BINARY_OPERATION_NAMES.inverse()[this] val binaryOp = BINARY_OPERATION_NAMES.inverse()[this]
@@ -143,7 +143,12 @@ private fun getCallNameFromPsi(element: JetElement): Name? {
if (element == operationReference) { if (element == operationReference) {
val node = operationReference.getReferencedNameElementType() val node = operationReference.getReferencedNameElementType()
return if (node is JetToken) { return if (node is JetToken) {
OperatorConventions.getNameForOperationSymbol(node) ?: Name.identifierNoValidate(element.getText()) val conventionName = if (elementParent is JetPrefixExpression)
OperatorConventions.getNameForOperationSymbol(node, true, false)
else
OperatorConventions.getNameForOperationSymbol(node)
conventionName ?: Name.identifierNoValidate(element.getText())
} }
else { else {
Name.identifierNoValidate(element.getText()) Name.identifierNoValidate(element.getText())
@@ -69,6 +69,7 @@ public class OperatorModifierInspection : AbstractKotlinInspection() {
val arity = valueParameters.size() val arity = valueParameters.size()
if (arity == 0 && if (arity == 0 &&
(name in OperatorConventions.UNARY_OPERATION_NAMES.values() || (name in OperatorConventions.UNARY_OPERATION_NAMES.values() ||
name == OperatorNameConventions.PLUS || name == OperatorNameConventions.MINUS || // temporary
name == OperatorNameConventions.ITERATOR || name == OperatorNameConventions.ITERATOR ||
isComponentLike(name) || isComponentLike(name) ||
name == OperatorNameConventions.NEXT || name == OperatorNameConventions.NEXT ||
@@ -35,7 +35,7 @@ public object CreateBinaryOperationActionFactory: CreateCallableMemberFromUsageF
val token = element.operationToken as JetToken val token = element.operationToken as JetToken
val operationName = when (token) { val operationName = when (token) {
JetTokens.IDENTIFIER -> element.operationReference.getReferencedName() JetTokens.IDENTIFIER -> element.operationReference.getReferencedName()
else -> OperatorConventions.getNameForOperationSymbol(token)?.asString() else -> OperatorConventions.getNameForOperationSymbol(token, false, true)?.asString()
} ?: return null } ?: return null
val inOperation = token in OperatorConventions.IN_OPERATIONS val inOperation = token in OperatorConventions.IN_OPERATIONS
val comparisonOperation = token in OperatorConventions.COMPARISON_OPERATIONS val comparisonOperation = token in OperatorConventions.COMPARISON_OPERATIONS
@@ -32,7 +32,7 @@ public object CreateUnaryOperationActionFactory: CreateCallableMemberFromUsageFa
override fun createCallableInfo(element: JetUnaryExpression, diagnostic: Diagnostic): CallableInfo? { override fun createCallableInfo(element: JetUnaryExpression, diagnostic: Diagnostic): CallableInfo? {
val token = element.operationToken as JetToken val token = element.operationToken as JetToken
val operationName = OperatorConventions.getNameForOperationSymbol(token) ?: return null val operationName = OperatorConventions.getNameForOperationSymbol(token, true, false) ?: return null
val incDec = token in OperatorConventions.INCREMENT_OPERATIONS val incDec = token in OperatorConventions.INCREMENT_OPERATIONS
val receiverExpr = element.baseExpression ?: return null val receiverExpr = element.baseExpression ?: return null
@@ -22,11 +22,11 @@ class A {
return 1 return 1
} }
fun plus() { fun unaryPlus() {
<lineMarker descr="Recursive call">+</lineMarker>this <lineMarker descr="Recursive call">+</lineMarker>this
} }
fun minus() { fun unaryMinus() {
<lineMarker descr="Recursive call">-</lineMarker>this <lineMarker descr="Recursive call">-</lineMarker>this
} }
@@ -1,7 +1,7 @@
fun test() { fun test() {
class Test { class Test {
fun plus(vararg a: Int): Test = Test() fun unaryPlus(vararg a: Int): Test = Test()
} }
val test = Test() val test = Test()
test.pl<caret>us() test.unaryPl<caret>us()
} }
@@ -1,6 +1,6 @@
fun test() { fun test() {
class Test { class Test {
fun plus(vararg a: Int): Test = Test() fun unaryPlus(vararg a: Int): Test = Test()
} }
val test = Test() val test = Test()
+test +test
@@ -2,10 +2,10 @@ fun doSomething<T>(a: T) {}
fun test() { fun test() {
class Test { class Test {
fun plus(): Test = Test() fun unaryPlus(): Test = Test()
fun plus(a: Test): Test = Test() fun plus(a: Test): Test = Test()
fun minus(): Test = Test() fun unaryMinus(): Test = Test()
} }
val test = Test() val test = Test()
doSomething((-((test + test).pl<caret>us())).toString()) doSomething((-((test + test).unaryPl<caret>us())).toString())
} }
@@ -2,9 +2,9 @@ fun doSomething<T>(a: T) {}
fun test() { fun test() {
class Test { class Test {
fun plus(): Test = Test() fun unaryPlus(): Test = Test()
fun plus(a: Test): Test = Test() fun plus(a: Test): Test = Test()
fun minus(): Test = Test() fun unaryMinus(): Test = Test()
} }
val test = Test() val test = Test()
doSomething((-(+(test + test))).toString()) doSomething((-(+(test + test))).toString())
@@ -1,7 +1,7 @@
fun test() { fun test() {
class Test { class Test {
fun plus(a: Int=1): Test = Test() fun unaryPlus(a: Int=1): Test = Test()
} }
val test = Test() val test = Test()
test.pl<caret>us() test.unaryPl<caret>us()
} }
@@ -1,6 +1,6 @@
fun test() { fun test() {
class Test { class Test {
fun plus(a: Int=1): Test = Test() fun unaryPlus(a: Int=1): Test = Test()
} }
val test = Test() val test = Test()
+test +test
@@ -1,8 +1,8 @@
fun test() { fun test() {
class Test() class Test()
fun Test.plus(): Test = Test() fun Test.unaryPlus(): Test = Test()
val test = Test() val test = Test()
test.pl<caret>us() test.unaryPl<caret>us()
} }
@@ -1,7 +1,7 @@
fun test() { fun test() {
class Test() class Test()
fun Test.plus(): Test = Test() fun Test.unaryPlus(): Test = Test()
val test = Test() val test = Test()
+test +test
@@ -1,8 +1,8 @@
// IS_APPLICABLE: false // IS_APPLICABLE: false
fun test() { fun test() {
class Test { class Test {
fun plus(fn: () -> Unit): Test = Test() fun unaryPlus(fn: () -> Unit): Test = Test()
} }
val test = Test() val test = Test()
test.pl<caret>us {} test.unaryPl<caret>us {}
} }
@@ -1,8 +1,8 @@
// INTENTION_TEXT: Replace with '-' operator // INTENTION_TEXT: Replace with '-' operator
fun test() { fun test() {
class Test { class Test {
fun minus(): Test = Test() fun unaryMinus(): Test = Test()
} }
val test = Test() val test = Test()
test.min<caret>us() test.unaryMin<caret>us()
} }
@@ -1,7 +1,7 @@
// INTENTION_TEXT: Replace with '-' operator // INTENTION_TEXT: Replace with '-' operator
fun test() { fun test() {
class Test { class Test {
fun minus(): Test = Test() fun unaryMinus(): Test = Test()
} }
val test = Test() val test = Test()
-test -test
@@ -1,8 +1,8 @@
// IS_APPLICABLE: false // IS_APPLICABLE: false
fun test() { fun test() {
class Test { class Test {
fun plus(a: Int): Test = Test() fun unaryPlus(a: Int): Test = Test()
} }
val test = Test() val test = Test()
test.pl<caret>us(a=1) test.unaryPl<caret>us(a=1)
} }
@@ -1,7 +1,7 @@
fun test() { fun test() {
class Test { class Test {
fun plus(): Test = Test() fun unaryPlus(): Test = Test()
} }
val test = Test() val test = Test()
+test.p<caret>lus() +test.unaryP<caret>lus()
} }
@@ -1,6 +1,6 @@
fun test() { fun test() {
class Test { class Test {
fun plus(): Test = Test() fun unaryPlus(): Test = Test()
} }
val test = Test() val test = Test()
+(+test) +(+test)
@@ -1,8 +1,8 @@
// INTENTION_TEXT: Replace with '+' operator // INTENTION_TEXT: Replace with '+' operator
fun test() { fun test() {
class Test { class Test {
fun plus(): Test = Test() fun unaryPlus(): Test = Test()
} }
val test = Test() val test = Test()
test.pl<caret>us() test.unaryPl<caret>us()
} }
@@ -1,7 +1,7 @@
// INTENTION_TEXT: Replace with '+' operator // INTENTION_TEXT: Replace with '+' operator
fun test() { fun test() {
class Test { class Test {
fun plus(): Test = Test() fun unaryPlus(): Test = Test()
} }
val test = Test() val test = Test()
+test +test
@@ -1,9 +1,9 @@
class C { class C {
companion object { companion object {
fun minus(): C = C() fun unaryMinus(): C = C()
} }
} }
fun foo() { fun foo() {
C.<caret>minus() C.<caret>unaryMinus()
} }
@@ -1,6 +1,6 @@
class C { class C {
companion object { companion object {
fun minus(): C = C() fun unaryMinus(): C = C()
} }
} }
@@ -1,11 +1,11 @@
// IS_APPLICABLE: false // IS_APPLICABLE: false
open class Base { open class Base {
open fun minus() = this open fun unaryMinus() = this
} }
class C : Base() { class C : Base() {
override fun minus(): Base { override fun unaryMinus(): Base {
return super.<caret>minus() return super.<caret>unaryMinus()
} }
} }
@@ -1,8 +1,8 @@
// IS_APPLICABLE: false // IS_APPLICABLE: false
fun test() { fun test() {
class Test { class Test {
fun plus<T>(): T? = this as? T fun unaryPlus<T>(): T? = this as? T
} }
val test = Test() val test = Test()
test.p<caret>lus<Int>() test.unaryP<caret>lus<Int>()
} }
@@ -1,8 +1,8 @@
// IS_APPLICABLE: false // IS_APPLICABLE: false
fun test() { fun test() {
class Test { class Test {
fun plus(vararg a: Int): Test = Test() fun unaryPlus(vararg a: Int): Test = Test()
} }
val test = Test() val test = Test()
test.pl<caret>us(0) test.unaryPl<caret>us(0)
} }
@@ -1,8 +1,8 @@
// IS_APPLICABLE: false // IS_APPLICABLE: false
fun test() { fun test() {
class Test { class Test {
fun plus(a: Int): Test = Test() fun unaryPlus(a: Int): Test = Test()
} }
val test = Test() val test = Test()
test.pl<caret>us(1) test.unaryPl<caret>us(1)
} }
@@ -1,7 +1,7 @@
// WITH_RUNTIME // WITH_RUNTIME
// IS_APPLICABLE: false // IS_APPLICABLE: false
class A(val n: Int) { class A(val n: Int) {
fun <caret>minus(): A = A(-n) fun <caret>unaryMinus(): A = A(-n)
} }
fun test() { fun test() {
@@ -3,7 +3,7 @@
package h package h
import util.minus import util.unaryMinus
interface H interface H
@@ -1,3 +1,3 @@
package util package util
operator fun h.H?.minus() = "" operator fun h.H?.unaryMinus() = ""
@@ -1,9 +1,9 @@
// "Import" "true" // "Import" "true"
// ERROR: <html>Unresolved reference. <br/> None of the following candidates is applicable because of receiver type mismatch: <ul><li><b>public</b> operator <b>fun</b> h.A.plus(): kotlin.Int <i>defined in</i> h</li><li><b>public</b> operator <b>fun</b> kotlin.String?.plus(other: kotlin.Any?): kotlin.String <i>defined in</i> kotlin</li></ul></html> // ERROR: <html>Unresolved reference. <br/> None of the following candidates is applicable because of receiver type mismatch: <ul><li><b>public</b> operator <b>fun</b> h.A.unaryPlus(): kotlin.Int <i>defined in</i> h</li></ul></html>
package h package h
import util.plus import util.unaryPlus
interface H interface H
@@ -13,4 +13,4 @@ fun f(h: H?) {
class A() class A()
operator fun A.plus(): Int = 3 operator fun A.unaryPlus(): Int = 3
@@ -1,3 +1,3 @@
package util package util
operator fun h.H.plus() = "" operator fun h.H.unaryPlus() = ""
@@ -1,5 +1,5 @@
// "Import" "true" // "Import" "true"
// ERROR: <html>Unresolved reference. <br/> None of the following candidates is applicable because of receiver type mismatch: <ul><li><b>public</b> operator <b>fun</b> h.A.plus(): kotlin.Int <i>defined in</i> h</li><li><b>public</b> operator <b>fun</b> kotlin.String?.plus(other: kotlin.Any?): kotlin.String <i>defined in</i> kotlin</li></ul></html> // ERROR: <html>Unresolved reference. <br/> None of the following candidates is applicable because of receiver type mismatch: <ul><li><b>public</b> operator <b>fun</b> h.A.unaryPlus(): kotlin.Int <i>defined in</i> h</li></ul></html>
package h package h
@@ -11,4 +11,4 @@ fun f(h: H?) {
class A() class A()
operator fun A.plus(): Int = 3 operator fun A.unaryPlus(): Int = 3
@@ -1,9 +1,9 @@
// "Create member function 'plus'" "true" // "Create member function 'plus'" "true"
class A<T>(val n: T) { class A<T>(val n: T) {
fun plus(): A<T> = throw Exception() operator fun unaryPlus(): A<T> = throw Exception()
} }
fun test() { fun test() {
val a: A<Int> = A(1) + <caret>2 val a: A<Int> = A(1) +<caret> 2
} }
@@ -1,7 +1,7 @@
// "Create member function 'plus'" "true" // "Create member function 'plus'" "true"
class A<T>(val n: T) { class A<T>(val n: T) {
fun plus(): A<T> = throw Exception() operator fun unaryPlus(): A<T> = throw Exception()
operator fun plus(t: T): A<T> { operator fun plus(t: T): A<T> {
throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates. throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates.
@@ -1,4 +1,4 @@
// "Create member function 'getValue', function 'set'" "true" // "Create member function 'getValue', function 'setValue'" "true"
class F { class F {
} }
@@ -1,8 +1,8 @@
// "Create member function 'setValue'" "true" // "Create member function 'setValue'" "true"
class F { class F {
fun get(x: X, propertyMetadata: PropertyMetadata): Int = 1 fun getValue(x: X, propertyMetadata: PropertyMetadata): Int = 1
fun set(x: X, propertyMetadata: PropertyMetadata, i: Int) { fun setValue(x: X, propertyMetadata: PropertyMetadata, i: Int) {
throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates. throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates.
} }
} }
@@ -1,7 +1,7 @@
// "Create member function 'minus'" "true" // "Create member function 'unaryMinus'" "true"
class A<T>(val n: T) { class A<T>(val n: T) {
fun minus(n: Int): A<T> = throw Exception() operator fun minus(n: Int): A<T> = throw Exception()
} }
fun test() { fun test() {
@@ -1,9 +1,9 @@
// "Create member function 'minus'" "true" // "Create member function 'unaryMinus'" "true"
class A<T>(val n: T) { class A<T>(val n: T) {
fun minus(n: Int): A<T> = throw Exception() operator fun minus(n: Int): A<T> = throw Exception()
operator fun minus(): A<T> { operator fun unaryMinus(): A<T> {
throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates. throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates.
} }
} }
@@ -1,4 +1,4 @@
// "Create extension function 'minus'" "true" // "Create extension function 'unaryMinus'" "true"
fun test() { fun test() {
val a = <caret>-false val a = <caret>-false
@@ -1,9 +1,9 @@
// "Create extension function 'minus'" "true" // "Create extension function 'unaryMinus'" "true"
fun test() { fun test() {
val a = -false val a = -false
} }
operator fun Boolean.minus(): Any { operator fun Boolean.unaryMinus(): Any {
throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates. throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates.
} }
@@ -1,4 +1,4 @@
// "Create member function 'minus'" "true" // "Create member function 'unaryMinus'" "true"
class A<T>(val n: T) class A<T>(val n: T)
@@ -1,7 +1,7 @@
// "Create member function 'minus'" "true" // "Create member function 'unaryMinus'" "true"
class A<T>(val n: T) { class A<T>(val n: T) {
operator fun minus(): Any { operator fun unaryMinus(): Any {
throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates. throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates.
} }
} }
@@ -1,4 +1,4 @@
// "Create member function 'minus'" "true" // "Create member function 'unaryMinus'" "true"
class A<T>(val n: T) class A<T>(val n: T)
@@ -1,7 +1,7 @@
// "Create member function 'minus'" "true" // "Create member function 'unaryMinus'" "true"
class A<T>(val n: T) { class A<T>(val n: T) {
operator fun minus(): A<T> { operator fun unaryMinus(): A<T> {
throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates. throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates.
} }
} }
@@ -32,6 +32,7 @@ import org.jetbrains.kotlin.js.translate.utils.JsDescriptorUtils;
import org.jetbrains.kotlin.lexer.JetToken; import org.jetbrains.kotlin.lexer.JetToken;
import org.jetbrains.kotlin.name.Name; import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.types.expressions.OperatorConventions; import org.jetbrains.kotlin.types.expressions.OperatorConventions;
import org.jetbrains.kotlin.util.OperatorNameConventions;
import java.util.List; import java.util.List;
@@ -42,7 +43,7 @@ public enum PrimitiveUnaryOperationFIF implements FunctionIntrinsicFactory {
INSTANCE; INSTANCE;
private static final NamePredicate UNARY_OPERATIONS = new NamePredicate(OperatorConventions.UNARY_OPERATION_NAMES.values()); private static final NamePredicate UNARY_OPERATIONS = new NamePredicate(OperatorNameConventions.UNARY_OPERATION_NAMES_WITH_DEPRECATED);
@NotNull @NotNull
private static final DescriptorPredicate UNARY_OPERATION_FOR_PRIMITIVE_NUMBER = private static final DescriptorPredicate UNARY_OPERATION_FOR_PRIMITIVE_NUMBER =
pattern(NamePredicate.PRIMITIVE_NUMBERS_MAPPED_TO_PRIMITIVE_JS, UNARY_OPERATIONS); pattern(NamePredicate.PRIMITIVE_NUMBERS_MAPPED_TO_PRIMITIVE_JS, UNARY_OPERATIONS);
@@ -192,7 +193,7 @@ public enum PrimitiveUnaryOperationFIF implements FunctionIntrinsicFactory {
jsOperator = JsUnaryOperator.BIT_NOT; jsOperator = JsUnaryOperator.BIT_NOT;
} }
else { else {
JetToken jetToken = OperatorConventions.UNARY_OPERATION_NAMES.inverse().get(name); JetToken jetToken = OperatorConventions.UNARY_OPERATION_NAMES_WITH_DEPRECATED_INVERTED.get(name);
jsOperator = OperatorTable.getUnaryOperator(jetToken); jsOperator = OperatorTable.getUnaryOperator(jetToken);
} }