Gradual migration of operator 'mod' to 'rem'

- Introduce new 'rem' operator convention
 - Prefer 'rem()' to 'mod()' when both are available, even if mod() is a
   member, and rem() -- an extension
 - Place operator 'rem' under the language feature
This commit is contained in:
Mikhail Zarechenskiy
2016-12-05 22:42:16 +03:00
parent 2df9daab1f
commit 97ca51381a
29 changed files with 528 additions and 28 deletions
@@ -1,21 +1,5 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* Copyright 2010-2015 JetBrains s.r.o.
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -40,6 +24,7 @@ import org.jetbrains.kotlin.diagnostics.DiagnosticSink
import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.types.expressions.OperatorConventions.REM_TO_MOD_OPERATION_NAMES
import org.jetbrains.kotlin.util.CheckResult
import org.jetbrains.kotlin.util.OperatorChecks
import org.jetbrains.kotlin.util.OperatorNameConventions
@@ -57,10 +42,20 @@ object OperatorModifierChecker {
val checkResult = OperatorChecks.check(functionDescriptor)
if (checkResult.isSuccess) {
if (functionDescriptor.name in COROUTINE_OPERATOR_NAMES
&& !languageVersionSettings.supportsFeature(LanguageFeature.Coroutines)) {
diagnosticHolder.report(Errors.UNSUPPORTED_FEATURE.on(modifier, LanguageFeature.Coroutines))
when (functionDescriptor.name) {
in COROUTINE_OPERATOR_NAMES -> {
if (!languageVersionSettings.supportsFeature(LanguageFeature.Coroutines)) {
diagnosticHolder.report(Errors.UNSUPPORTED_FEATURE.on(modifier, LanguageFeature.Coroutines))
}
}
in REM_TO_MOD_OPERATION_NAMES.keys -> {
if (!languageVersionSettings.supportsFeature(LanguageFeature.OperatorRem)) {
diagnosticHolder.report(Errors.UNSUPPORTED_FEATURE.on(modifier, LanguageFeature.OperatorRem))
}
}
}
return
}
@@ -23,9 +23,9 @@ import org.jetbrains.kotlin.builtins.getReceiverTypeFromFunctionType
import org.jetbrains.kotlin.builtins.isExtensionFunctionType
import org.jetbrains.kotlin.coroutines.getExpectedTypeForCoroutineControllerHandleResult
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor
import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptorImpl
import org.jetbrains.kotlin.incremental.KotlinLookupLocation
import org.jetbrains.kotlin.lexer.KtToken
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.calls.CallTransformer
@@ -45,6 +45,7 @@ import org.jetbrains.kotlin.resolve.scopes.utils.getImplicitReceiversHierarchy
import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.TypeUtils.DONT_CARE
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
import org.jetbrains.kotlin.types.expressions.OperatorConventions
import org.jetbrains.kotlin.types.typeUtil.asTypeProjection
import org.jetbrains.kotlin.types.typeUtil.contains
import org.jetbrains.kotlin.util.OperatorNameConventions
@@ -127,6 +128,14 @@ fun isOrOverridesSynthesized(descriptor: CallableMemberDescriptor): Boolean {
return false
}
fun isBinaryRemOperator(call: Call): Boolean {
val callElement = call.callElement as? KtBinaryExpression ?: return false
val operator = callElement.operationToken
if (operator !is KtToken) return false
val name = OperatorConventions.getNameForOperationSymbol(operator, true, true)
return name in OperatorConventions.REM_TO_MOD_OPERATION_NAMES.keys
}
fun isConventionCall(call: Call): Boolean {
if (call is CallTransformer.CallForImplicitInvoke) return true
@@ -29,6 +29,7 @@ import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.TemporaryBindingTrace
import org.jetbrains.kotlin.resolve.calls.CallTransformer
import org.jetbrains.kotlin.resolve.calls.CandidateResolver
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isBinaryRemOperator
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isConventionCall
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isInfixCall
import org.jetbrains.kotlin.resolve.calls.callUtil.createLookupLocation
@@ -49,6 +50,7 @@ import org.jetbrains.kotlin.resolve.scopes.SyntheticScopes
import org.jetbrains.kotlin.resolve.scopes.receivers.*
import org.jetbrains.kotlin.types.DeferredType
import org.jetbrains.kotlin.types.ErrorUtils
import org.jetbrains.kotlin.types.expressions.OperatorConventions
import org.jetbrains.kotlin.types.isDynamic
import org.jetbrains.kotlin.util.OperatorNameConventions
import org.jetbrains.kotlin.utils.addToStdlib.check
@@ -159,7 +161,18 @@ class NewResolutionOldInference(
return allCandidatesResult(towerResolver.collectAllCandidates(scopeTower, processor))
}
val candidates = towerResolver.runResolve(scopeTower, processor, useOrder = kind != ResolutionKind.CallableReference)
var candidates = towerResolver.runResolve(scopeTower, processor, useOrder = kind != ResolutionKind.CallableReference)
// Temporary hack to resolve 'rem' as 'mod' if the first is do not present
val emptyOrInapplicableCandidates = candidates.isEmpty() ||
candidates.all {
it.candidateStatus.resultingApplicability == ResolutionCandidateApplicability.INAPPLICABLE
}
if (emptyOrInapplicableCandidates && isBinaryRemOperator(context.call)) {
val deprecatedName = OperatorConventions.REM_TO_MOD_OPERATION_NAMES[name]
val processorForDeprecatedName = kind.createTowerProcessor(this, deprecatedName!!, tracing, scopeTower, detailedReceiver, context)
candidates = towerResolver.runResolve(scopeTower, processorForDeprecatedName, useOrder = kind != ResolutionKind.CallableReference)
}
if (candidates.isEmpty()) {
if (reportAdditionalDiagnosticIfNoCandidates(context, name, kind, scopeTower, detailedReceiver)) {
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -60,10 +60,15 @@ public class OperatorConventions {
.put(KtTokens.PLUS, PLUS)
.put(KtTokens.MINUS, MINUS)
.put(KtTokens.DIV, DIV)
.put(KtTokens.PERC, MOD)
.put(KtTokens.PERC, REM)
.put(KtTokens.RANGE, RANGE_TO)
.build();
public static final ImmutableBiMap<Name, Name> REM_TO_MOD_OPERATION_NAMES = ImmutableBiMap.<Name, Name>builder()
.put(REM, MOD)
.put(REM_ASSIGN, MOD_ASSIGN)
.build();
public static final ImmutableSet<KtSingleValueToken> NOT_OVERLOADABLE =
ImmutableSet.of(KtTokens.ANDAND, KtTokens.OROR, KtTokens.ELVIS, KtTokens.EQEQEQ, KtTokens.EXCLEQEQEQ);
@@ -85,7 +90,7 @@ public class OperatorConventions {
public static final ImmutableBiMap<KtSingleValueToken, Name> ASSIGNMENT_OPERATIONS = ImmutableBiMap.<KtSingleValueToken, Name>builder()
.put(KtTokens.MULTEQ, TIMES_ASSIGN)
.put(KtTokens.DIVEQ, DIV_ASSIGN)
.put(KtTokens.PERCEQ, MOD_ASSIGN)
.put(KtTokens.PERCEQ, REM_ASSIGN)
.put(KtTokens.PLUSEQ, PLUS_ASSIGN)
.put(KtTokens.MINUSEQ, MINUS_ASSIGN)
.build();
@@ -0,0 +1,17 @@
class A() {
var x = 5
}
operator fun A.modAssign(y: Int) { throw RuntimeException("mod has been called instead of rem") }
operator fun A.remAssign(y: Int) { x %= y + 1 }
fun box(): String {
val original = A()
val a = original
a %= 2
if (a !== original) return "Fail 1: $a !== $original"
if (a.x != 2) return "Fail 2: ${a.x} != 2"
return "OK"
}
@@ -0,0 +1,18 @@
class A() {
var x = 5
operator fun mod(y: Int) { throw RuntimeException("mod has been called instead of rem") }
operator fun rem(y: Int) { x -= y }
}
fun box(): String {
val a = A()
a % 5
if (a.x != 0) {
return "Fail: a.x(${a.x}) != 0"
}
return "OK"
}
@@ -0,0 +1,13 @@
public final class A {
private field x: int
public method <init>(): void
public final method getX(): int
public final method setX(p0: int): void
}
public final class RemAssignmentOperationKt {
public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String
public final static method modAssign(@org.jetbrains.annotations.NotNull p0: A, p1: int): void
public final static method remAssign(@org.jetbrains.annotations.NotNull p0: A, p1: int): void
}
@@ -0,0 +1,13 @@
public final class A {
private field x: int
public method <init>(): void
public final method getX(): int
public final method mod(p0: int): void
public final method rem(p0: int): void
public final method setX(p0: int): void
}
public final class RemOverModOperationKt {
public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String
}
@@ -0,0 +1,41 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER
class OldAndNew {
operator fun modAssign(x: Int) {}
operator fun remAssign(x: Int) {}
}
class OnlyOld {
operator fun modAssign(x: Int) {}
}
class OnlyNew {
operator fun remAssign(x: Int) {}
}
class Sample
operator fun Sample.modAssign(x: Int) {}
operator fun Sample.remAssign(x: Int) {}
class ModAndRemAssign {
operator fun mod(x: Int): ModAndRemAssign = ModAndRemAssign()
operator fun remAssign(x: Int) {}
}
fun test() {
val oldAndNew = OldAndNew()
oldAndNew %= 1
val onlyOld = OnlyOld()
onlyOld %= 1
val onlyNew = OnlyNew()
onlyNew %= 1
val sample = Sample()
sample %= 1
var modAndRemAssign = ModAndRemAssign()
modAndRemAssign <!ASSIGN_OPERATOR_AMBIGUITY!>%=<!> 1
}
@@ -0,0 +1,46 @@
package
public fun test(): kotlin.Unit
public operator fun Sample.modAssign(/*0*/ x: kotlin.Int): kotlin.Unit
public operator fun Sample.remAssign(/*0*/ x: kotlin.Int): kotlin.Unit
public final class ModAndRemAssign {
public constructor ModAndRemAssign()
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 mod(/*0*/ x: kotlin.Int): ModAndRemAssign
public final operator fun remAssign(/*0*/ x: kotlin.Int): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public final class OldAndNew {
public constructor OldAndNew()
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 modAssign(/*0*/ x: kotlin.Int): kotlin.Unit
public final operator fun remAssign(/*0*/ x: kotlin.Int): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public final class OnlyNew {
public constructor OnlyNew()
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 remAssign(/*0*/ x: kotlin.Int): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public final class OnlyOld {
public constructor OnlyOld()
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 modAssign(/*0*/ x: kotlin.Int): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public final class Sample {
public constructor Sample()
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 open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -0,0 +1,35 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER
class OldAndNew {
operator fun mod(x: Int) {}
operator fun rem(x: Int) {}
}
class OnlyOld {
operator fun mod(x: Int) {}
}
class OnlyNew {
operator fun rem(x: Int) {}
}
class Sample
operator fun Sample.mod(x: Int) {}
operator fun Sample.rem(x: Int) {}
class IntAndUnit {
operator fun mod(x: Int): Int = 0
operator fun rem(x: Int) {}
}
fun test() {
OldAndNew() % 1
OnlyOld() % 1
OnlyNew() % 1
Sample() % 1
takeInt(<!TYPE_MISMATCH!>IntAndUnit() % 1<!>)
}
fun takeInt(x: Int) {}
@@ -0,0 +1,47 @@
package
public fun takeInt(/*0*/ x: kotlin.Int): kotlin.Unit
public fun test(): kotlin.Unit
public operator fun Sample.mod(/*0*/ x: kotlin.Int): kotlin.Unit
public operator fun Sample.rem(/*0*/ x: kotlin.Int): kotlin.Unit
public final class IntAndUnit {
public constructor IntAndUnit()
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 mod(/*0*/ x: kotlin.Int): kotlin.Int
public final operator fun rem(/*0*/ x: kotlin.Int): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public final class OldAndNew {
public constructor OldAndNew()
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 mod(/*0*/ x: kotlin.Int): kotlin.Unit
public final operator fun rem(/*0*/ x: kotlin.Int): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public final class OnlyNew {
public constructor OnlyNew()
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 rem(/*0*/ x: kotlin.Int): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public final class OnlyOld {
public constructor OnlyOld()
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 mod(/*0*/ x: kotlin.Int): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public final class Sample {
public constructor Sample()
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 open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -0,0 +1,16 @@
// !LANGUAGE: -OperatorRem
// !DIAGNOSTICS: -UNUSED_PARAMETER, -UNUSED_VARIABLE
class Foo {
<!UNSUPPORTED_FEATURE!>operator<!> fun rem(x: Int): Foo = Foo()
}
class Bar {
<!UNSUPPORTED_FEATURE!>operator<!> fun remAssign(x: Int) {}
}
fun baz() {
val f = Foo() % 1
val b = Bar()
b %= 1
}
@@ -0,0 +1,19 @@
package
public fun baz(): kotlin.Unit
public final class Bar {
public constructor Bar()
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 remAssign(/*0*/ x: kotlin.Int): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public final class Foo {
public constructor Foo()
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 rem(/*0*/ x: kotlin.Int): Foo
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -0,0 +1,15 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER, -UNUSED_VARIABLE
class Foo {
operator fun rem(x: Int): Foo = Foo()
}
class Bar {
operator fun remAssign(x: Int) {}
}
fun baz() {
val f = Foo() % 1
val b = Bar()
b %= 1
}
@@ -0,0 +1,19 @@
package
public fun baz(): kotlin.Unit
public final class Bar {
public constructor Bar()
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 remAssign(/*0*/ x: kotlin.Int): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public final class Foo {
public constructor Foo()
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 rem(/*0*/ x: kotlin.Int): Foo
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -0,0 +1,12 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER
class Foo {
}
operator fun Foo.mod(x: Int): Foo = Foo()
operator fun Foo.rem(x: Int): Int = 0
fun foo() {
takeInt(Foo() % 1)
}
fun takeInt(x: Int) {}
@@ -0,0 +1,13 @@
package
public fun foo(): kotlin.Unit
public fun takeInt(/*0*/ x: kotlin.Int): kotlin.Unit
public operator fun Foo.mod(/*0*/ x: kotlin.Int): Foo
public operator fun Foo.rem(/*0*/ x: kotlin.Int): kotlin.Int
public final class Foo {
public constructor Foo()
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 open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -0,0 +1,12 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER
class Foo {
operator fun mod(x: Int): Foo = Foo()
operator fun rem(x: Int): Int = 0
}
fun foo() {
takeInt(Foo() % 1)
}
fun takeInt(x: Int) {}
@@ -0,0 +1,13 @@
package
public fun foo(): kotlin.Unit
public fun takeInt(/*0*/ x: kotlin.Int): kotlin.Unit
public final class Foo {
public constructor Foo()
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 mod(/*0*/ x: kotlin.Int): Foo
public final operator fun rem(/*0*/ x: kotlin.Int): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -0,0 +1,14 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER
class Foo {
operator fun mod(x: Int): Foo = Foo()
}
operator fun Foo.rem(x: Int): Int = 0
fun foo() {
takeInt(Foo() % 1)
}
fun takeInt(x: Int) {}
@@ -0,0 +1,13 @@
package
public fun foo(): kotlin.Unit
public fun takeInt(/*0*/ x: kotlin.Int): kotlin.Unit
public operator fun Foo.rem(/*0*/ x: kotlin.Int): kotlin.Int
public final class Foo {
public constructor Foo()
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 mod(/*0*/ x: kotlin.Int): Foo
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -10454,6 +10454,18 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
doTest(fileName);
}
@TestMetadata("remAssignmentOperation.kt")
public void testRemAssignmentOperation() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/operatorConventions/remAssignmentOperation.kt");
doTest(fileName);
}
@TestMetadata("remOverModOperation.kt")
public void testRemOverModOperation() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/operatorConventions/remOverModOperation.kt");
doTest(fileName);
}
@TestMetadata("compiler/testData/codegen/box/operatorConventions/compareTo")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
@@ -206,6 +206,18 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
doTest(fileName);
}
@TestMetadata("DeprecatedModAssignOperatorConventions.kt")
public void testDeprecatedModAssignOperatorConventions() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/DeprecatedModAssignOperatorConventions.kt");
doTest(fileName);
}
@TestMetadata("DeprecatedModOperatorConventions.kt")
public void testDeprecatedModOperatorConventions() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/DeprecatedModOperatorConventions.kt");
doTest(fileName);
}
@TestMetadata("DeprecatedUnaryOperatorConventions.kt")
public void testDeprecatedUnaryOperatorConventions() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/DeprecatedUnaryOperatorConventions.kt");
@@ -13316,6 +13328,45 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
}
}
@TestMetadata("compiler/testData/diagnostics/tests/operatorRem")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class OperatorRem extends AbstractDiagnosticsTest {
public void testAllFilesPresentInOperatorRem() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/tests/operatorRem"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
}
@TestMetadata("noOperatorRemFeature.kt")
public void testNoOperatorRemFeature() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/operatorRem/noOperatorRemFeature.kt");
doTest(fileName);
}
@TestMetadata("operatorRem.kt")
public void testOperatorRem() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/operatorRem/operatorRem.kt");
doTest(fileName);
}
@TestMetadata("preferRemAsExtentionOverMod.kt")
public void testPreferRemAsExtentionOverMod() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/operatorRem/preferRemAsExtentionOverMod.kt");
doTest(fileName);
}
@TestMetadata("preferRemAsMemberOverMod.kt")
public void testPreferRemAsMemberOverMod() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/operatorRem/preferRemAsMemberOverMod.kt");
doTest(fileName);
}
@TestMetadata("prefereRemAsExtensionOverMemberMod.kt")
public void testPrefereRemAsExtensionOverMemberMod() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/operatorRem/prefereRemAsExtensionOverMemberMod.kt");
doTest(fileName);
}
}
@TestMetadata("compiler/testData/diagnostics/tests/operatorsOverloading")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
@@ -10454,6 +10454,18 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
doTest(fileName);
}
@TestMetadata("remAssignmentOperation.kt")
public void testRemAssignmentOperation() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/operatorConventions/remAssignmentOperation.kt");
doTest(fileName);
}
@TestMetadata("remOverModOperation.kt")
public void testRemOverModOperation() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/operatorConventions/remOverModOperation.kt");
doTest(fileName);
}
@TestMetadata("compiler/testData/codegen/box/operatorConventions/compareTo")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
@@ -10454,6 +10454,18 @@ public class LightAnalysisModeCodegenTestGenerated extends AbstractLightAnalysis
doTest(fileName);
}
@TestMetadata("remAssignmentOperation.kt")
public void testRemAssignmentOperation() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/operatorConventions/remAssignmentOperation.kt");
doTest(fileName);
}
@TestMetadata("remOverModOperation.kt")
public void testRemOverModOperation() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/operatorConventions/remOverModOperation.kt");
doTest(fileName);
}
@TestMetadata("compiler/testData/codegen/box/operatorConventions/compareTo")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
@@ -35,6 +35,7 @@ enum class LanguageFeature(val sinceVersion: LanguageVersion?) {
UnderscoresInNumericLiterals(KOTLIN_1_1),
DivisionByZeroInConstantExpressions(KOTLIN_1_1),
InlineConstVals(KOTLIN_1_1),
OperatorRem(KOTLIN_1_1),
// Experimental features
MultiPlatformProjects(null),
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -49,11 +49,13 @@ object OperatorNameConventions {
@JvmField val TIMES = Name.identifier("times")
@JvmField val DIV = Name.identifier("div")
@JvmField val MOD = Name.identifier("mod")
@JvmField val REM = Name.identifier("rem")
@JvmField val RANGE_TO = Name.identifier("rangeTo")
@JvmField val TIMES_ASSIGN = Name.identifier("timesAssign")
@JvmField val DIV_ASSIGN = Name.identifier("divAssign")
@JvmField val MOD_ASSIGN = Name.identifier("modAssign")
@JvmField val REM_ASSIGN = Name.identifier("remAssign")
@JvmField val PLUS_ASSIGN = Name.identifier("plusAssign")
@JvmField val MINUS_ASSIGN = Name.identifier("minusAssign")
@JvmField val COROUTINE_HANDLE_RESULT = Name.identifier("handleResult")
@@ -72,8 +74,8 @@ object OperatorNameConventions {
internal val SIMPLE_UNARY_OPERATION_NAMES = setOf(UNARY_PLUS, UNARY_MINUS, NOT)
@JvmField
internal val BINARY_OPERATION_NAMES = setOf(TIMES, PLUS, MINUS, DIV, MOD, RANGE_TO)
internal val BINARY_OPERATION_NAMES = setOf(TIMES, PLUS, MINUS, DIV, MOD, REM, RANGE_TO)
@JvmField
internal val ASSIGNMENT_OPERATIONS = setOf(TIMES_ASSIGN, DIV_ASSIGN, MOD_ASSIGN, PLUS_ASSIGN, MINUS_ASSIGN)
internal val ASSIGNMENT_OPERATIONS = setOf(TIMES_ASSIGN, DIV_ASSIGN, MOD_ASSIGN, REM_ASSIGN, PLUS_ASSIGN, MINUS_ASSIGN)
}
@@ -12333,6 +12333,18 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
doTest(fileName);
}
@TestMetadata("remAssignmentOperation.kt")
public void testRemAssignmentOperation() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/operatorConventions/remAssignmentOperation.kt");
doTest(fileName);
}
@TestMetadata("remOverModOperation.kt")
public void testRemOverModOperation() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/operatorConventions/remOverModOperation.kt");
doTest(fileName);
}
@TestMetadata("compiler/testData/codegen/box/operatorConventions/compareTo")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)