diff --git a/idea/resources/intentionDescriptions/ReplaceMathMaxWithCoerceAtLeastIntention/after.kt.template b/idea/resources/intentionDescriptions/ReplaceMathMaxWithCoerceAtLeastIntention/after.kt.template
new file mode 100644
index 00000000000..517ba05ebe5
--- /dev/null
+++ b/idea/resources/intentionDescriptions/ReplaceMathMaxWithCoerceAtLeastIntention/after.kt.template
@@ -0,0 +1 @@
+1.coerceAtLeast(2)
\ No newline at end of file
diff --git a/idea/resources/intentionDescriptions/ReplaceMathMaxWithCoerceAtLeastIntention/before.kt.template b/idea/resources/intentionDescriptions/ReplaceMathMaxWithCoerceAtLeastIntention/before.kt.template
new file mode 100644
index 00000000000..12524d65bb3
--- /dev/null
+++ b/idea/resources/intentionDescriptions/ReplaceMathMaxWithCoerceAtLeastIntention/before.kt.template
@@ -0,0 +1 @@
+Math.max(1, 2)
diff --git a/idea/resources/intentionDescriptions/ReplaceMathMaxWithCoerceAtLeastIntention/description.html b/idea/resources/intentionDescriptions/ReplaceMathMaxWithCoerceAtLeastIntention/description.html
new file mode 100644
index 00000000000..516a29dafd4
--- /dev/null
+++ b/idea/resources/intentionDescriptions/ReplaceMathMaxWithCoerceAtLeastIntention/description.html
@@ -0,0 +1,5 @@
+
+
+ This intention replaces 'Math.max' calls with 'coerceAtLeast'
+
+
diff --git a/idea/resources/intentionDescriptions/ReplaceMathMinWithCoerceAtMostIntention/after.kt.template b/idea/resources/intentionDescriptions/ReplaceMathMinWithCoerceAtMostIntention/after.kt.template
new file mode 100644
index 00000000000..f8fde5d7fc0
--- /dev/null
+++ b/idea/resources/intentionDescriptions/ReplaceMathMinWithCoerceAtMostIntention/after.kt.template
@@ -0,0 +1 @@
+1.coerceAtMost(2)
\ No newline at end of file
diff --git a/idea/resources/intentionDescriptions/ReplaceMathMinWithCoerceAtMostIntention/before.kt.template b/idea/resources/intentionDescriptions/ReplaceMathMinWithCoerceAtMostIntention/before.kt.template
new file mode 100644
index 00000000000..cdc5686ecf9
--- /dev/null
+++ b/idea/resources/intentionDescriptions/ReplaceMathMinWithCoerceAtMostIntention/before.kt.template
@@ -0,0 +1 @@
+Math.min(1, 2)
diff --git a/idea/resources/intentionDescriptions/ReplaceMathMinWithCoerceAtMostIntention/description.html b/idea/resources/intentionDescriptions/ReplaceMathMinWithCoerceAtMostIntention/description.html
new file mode 100644
index 00000000000..ca8649230c7
--- /dev/null
+++ b/idea/resources/intentionDescriptions/ReplaceMathMinWithCoerceAtMostIntention/description.html
@@ -0,0 +1,5 @@
+
+
+ This intention replaces 'Math.min' calls with 'coerceAtMost'
+
+
diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml
index 0feb8f069ee..5a3edac338d 100644
--- a/idea/src/META-INF/plugin.xml
+++ b/idea/src/META-INF/plugin.xml
@@ -1354,6 +1354,16 @@
Kotlin
+
+ org.jetbrains.kotlin.idea.intentions.ReplaceMathMaxWithCoerceAtLeastIntention
+ Kotlin
+
+
+
+ org.jetbrains.kotlin.idea.intentions.ReplaceMathMinWithCoerceAtMostIntention
+ Kotlin
+
+
(KtCallExpression::class.java, text) {
+
+ override fun applyTo(element: KtCallExpression, editor: Editor?) {
+ val target = element.getStrictParentOfType() ?: element
+ val valueArguments = element.valueArguments
+ val methodName = replacedMethodName
+ val newExpression = KtPsiFactory(element).createExpressionByPattern("$0.$methodName($1)",
+ valueArguments[0].text, valueArguments[1].text)
+ target.replaced(newExpression)
+ }
+
+ override fun isApplicableTo(element: KtCallExpression) =
+ element.calleeExpression?.text == mathMethodName &&
+ element.valueArguments.size == 2 &&
+ element.isMethodCall("java.lang.Math.${mathMethodName}")
+}
\ No newline at end of file
diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/ReplaceMathMinWithCoerceAtMostIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/ReplaceMathMinWithCoerceAtMostIntention.kt
new file mode 100644
index 00000000000..5f466e71e71
--- /dev/null
+++ b/idea/src/org/jetbrains/kotlin/idea/intentions/ReplaceMathMinWithCoerceAtMostIntention.kt
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ * 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.
+ */
+
+package org.jetbrains.kotlin.idea.intentions
+
+class ReplaceMathMinWithCoerceAtMostIntention :
+ ReplaceMathMethodsWithKotlinNativeMethodsIntention("Replace Math.min with coerceAtMost", "coerceAtMost", "min")
\ No newline at end of file
diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/ReplaceSingleLineLetIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/ReplaceSingleLineLetIntention.kt
index 44566d6103f..35a8713b779 100644
--- a/idea/src/org/jetbrains/kotlin/idea/intentions/ReplaceSingleLineLetIntention.kt
+++ b/idea/src/org/jetbrains/kotlin/idea/intentions/ReplaceSingleLineLetIntention.kt
@@ -90,12 +90,7 @@ class ReplaceSingleLineLetIntention : SelfTargetingOffsetIndependentIntention
+}
+
+object Math {
+ fun max(a: Int, b: Int) = 0
+}
diff --git a/idea/testData/intentions/replaceMathMaxWithCoerceAtLeast/doubles.kt b/idea/testData/intentions/replaceMathMaxWithCoerceAtLeast/doubles.kt
new file mode 100644
index 00000000000..988be24442e
--- /dev/null
+++ b/idea/testData/intentions/replaceMathMaxWithCoerceAtLeast/doubles.kt
@@ -0,0 +1,7 @@
+// WITH_RUNTIME
+
+import java.lang.Math.max
+
+fun foo() {
+ max(1.1, 1.2)
+}
\ No newline at end of file
diff --git a/idea/testData/intentions/replaceMathMaxWithCoerceAtLeast/doubles.kt.after b/idea/testData/intentions/replaceMathMaxWithCoerceAtLeast/doubles.kt.after
new file mode 100644
index 00000000000..f5df5c26201
--- /dev/null
+++ b/idea/testData/intentions/replaceMathMaxWithCoerceAtLeast/doubles.kt.after
@@ -0,0 +1,7 @@
+// WITH_RUNTIME
+
+import java.lang.Math.max
+
+fun foo() {
+ 1.1.coerceAtLeast(1.2)
+}
\ No newline at end of file
diff --git a/idea/testData/intentions/replaceMathMaxWithCoerceAtLeast/moreThan2ValueArg.kt b/idea/testData/intentions/replaceMathMaxWithCoerceAtLeast/moreThan2ValueArg.kt
new file mode 100644
index 00000000000..4cd0e0efa6b
--- /dev/null
+++ b/idea/testData/intentions/replaceMathMaxWithCoerceAtLeast/moreThan2ValueArg.kt
@@ -0,0 +1,9 @@
+// WITH_RUNTIME
+// IS_APPLICABLE: false
+// ERROR: None of the following functions can be called with the arguments supplied:
public open fun max(p0: Double, p1: Double): Double defined in java.lang.Math
public open fun max(p0: Float, p1: Float): Float defined in java.lang.Math
public open fun max(p0: Int, p1: Int): Int defined in java.lang.Math
public open fun max(p0: Long, p1: Long): Long defined in java.lang.Math
+
+import java.lang.Math.max
+
+fun foo() {
+ max(1.1, 1.2, 1.3)
+}
\ No newline at end of file
diff --git a/idea/testData/intentions/replaceMathMaxWithCoerceAtLeast/noImport.kt b/idea/testData/intentions/replaceMathMaxWithCoerceAtLeast/noImport.kt
new file mode 100644
index 00000000000..68a05d49418
--- /dev/null
+++ b/idea/testData/intentions/replaceMathMaxWithCoerceAtLeast/noImport.kt
@@ -0,0 +1,5 @@
+// WITH_RUNTIME
+
+fun foo() {
+ Math.max(2, 1)
+}
\ No newline at end of file
diff --git a/idea/testData/intentions/replaceMathMaxWithCoerceAtLeast/noImport.kt.after b/idea/testData/intentions/replaceMathMaxWithCoerceAtLeast/noImport.kt.after
new file mode 100644
index 00000000000..55c5baa66b1
--- /dev/null
+++ b/idea/testData/intentions/replaceMathMaxWithCoerceAtLeast/noImport.kt.after
@@ -0,0 +1,5 @@
+// WITH_RUNTIME
+
+fun foo() {
+ 2.coerceAtLeast(1)
+}
\ No newline at end of file
diff --git a/idea/testData/intentions/replaceMathMaxWithCoerceAtLeast/oneValueArg.kt b/idea/testData/intentions/replaceMathMaxWithCoerceAtLeast/oneValueArg.kt
new file mode 100644
index 00000000000..0ce5d335cf5
--- /dev/null
+++ b/idea/testData/intentions/replaceMathMaxWithCoerceAtLeast/oneValueArg.kt
@@ -0,0 +1,9 @@
+// WITH_RUNTIME
+// IS_APPLICABLE: false
+// ERROR: None of the following functions can be called with the arguments supplied:
public open fun max(p0: Double, p1: Double): Double defined in java.lang.Math
public open fun max(p0: Float, p1: Float): Float defined in java.lang.Math
public open fun max(p0: Int, p1: Int): Int defined in java.lang.Math
public open fun max(p0: Long, p1: Long): Long defined in java.lang.Math
+
+import java.lang.Math.max
+
+fun foo() {
+ max(1.1)
+}
\ No newline at end of file
diff --git a/idea/testData/intentions/replaceMathMaxWithCoerceAtLeast/simple.kt b/idea/testData/intentions/replaceMathMaxWithCoerceAtLeast/simple.kt
new file mode 100644
index 00000000000..86540ae647f
--- /dev/null
+++ b/idea/testData/intentions/replaceMathMaxWithCoerceAtLeast/simple.kt
@@ -0,0 +1,7 @@
+// WITH_RUNTIME
+
+import java.lang.Math.max
+
+fun foo() {
+ max(1, 2)
+}
\ No newline at end of file
diff --git a/idea/testData/intentions/replaceMathMaxWithCoerceAtLeast/simple.kt.after b/idea/testData/intentions/replaceMathMaxWithCoerceAtLeast/simple.kt.after
new file mode 100644
index 00000000000..f8631458189
--- /dev/null
+++ b/idea/testData/intentions/replaceMathMaxWithCoerceAtLeast/simple.kt.after
@@ -0,0 +1,7 @@
+// WITH_RUNTIME
+
+import java.lang.Math.max
+
+fun foo() {
+ 1.coerceAtLeast(2)
+}
\ No newline at end of file
diff --git a/idea/testData/intentions/replaceMathMinWithCoerceAtMost/.intention b/idea/testData/intentions/replaceMathMinWithCoerceAtMost/.intention
new file mode 100644
index 00000000000..fcc06d057f4
--- /dev/null
+++ b/idea/testData/intentions/replaceMathMinWithCoerceAtMost/.intention
@@ -0,0 +1 @@
+org.jetbrains.kotlin.idea.intentions.ReplaceMathMinWithCoerceAtMostIntention
\ No newline at end of file
diff --git a/idea/testData/intentions/replaceMathMinWithCoerceAtMost/customMinMethod.kt b/idea/testData/intentions/replaceMathMinWithCoerceAtMost/customMinMethod.kt
new file mode 100644
index 00000000000..fe831ae9cb6
--- /dev/null
+++ b/idea/testData/intentions/replaceMathMinWithCoerceAtMost/customMinMethod.kt
@@ -0,0 +1,10 @@
+// WITH_RUNTIME
+// IS_APPLICABLE: false
+
+fun foo() {
+ Math.min(1, 2)
+}
+
+object Math {
+ fun min(a: Int, b: Int) = 0
+}
diff --git a/idea/testData/intentions/replaceMathMinWithCoerceAtMost/doubles.kt b/idea/testData/intentions/replaceMathMinWithCoerceAtMost/doubles.kt
new file mode 100644
index 00000000000..45f308c0b4e
--- /dev/null
+++ b/idea/testData/intentions/replaceMathMinWithCoerceAtMost/doubles.kt
@@ -0,0 +1,7 @@
+// WITH_RUNTIME
+
+import java.lang.Math.min
+
+fun foo() {
+ min(1.1, 1.2)
+}
\ No newline at end of file
diff --git a/idea/testData/intentions/replaceMathMinWithCoerceAtMost/doubles.kt.after b/idea/testData/intentions/replaceMathMinWithCoerceAtMost/doubles.kt.after
new file mode 100644
index 00000000000..279c32e840e
--- /dev/null
+++ b/idea/testData/intentions/replaceMathMinWithCoerceAtMost/doubles.kt.after
@@ -0,0 +1,7 @@
+// WITH_RUNTIME
+
+import java.lang.Math.min
+
+fun foo() {
+ 1.1.coerceAtMost(1.2)
+}
\ No newline at end of file
diff --git a/idea/testData/intentions/replaceMathMinWithCoerceAtMost/moreThan2ValueArg.kt b/idea/testData/intentions/replaceMathMinWithCoerceAtMost/moreThan2ValueArg.kt
new file mode 100644
index 00000000000..d3d74881b48
--- /dev/null
+++ b/idea/testData/intentions/replaceMathMinWithCoerceAtMost/moreThan2ValueArg.kt
@@ -0,0 +1,9 @@
+// WITH_RUNTIME
+// IS_APPLICABLE: false
+// ERROR: None of the following functions can be called with the arguments supplied:
public open fun min(p0: Double, p1: Double): Double defined in java.lang.Math
public open fun min(p0: Float, p1: Float): Float defined in java.lang.Math
public open fun min(p0: Int, p1: Int): Int defined in java.lang.Math
public open fun min(p0: Long, p1: Long): Long defined in java.lang.Math
+
+import java.lang.Math.min
+
+fun foo() {
+ min(1.1, 1.2, 1.3)
+}
\ No newline at end of file
diff --git a/idea/testData/intentions/replaceMathMinWithCoerceAtMost/noImport.kt b/idea/testData/intentions/replaceMathMinWithCoerceAtMost/noImport.kt
new file mode 100644
index 00000000000..5f520414b7b
--- /dev/null
+++ b/idea/testData/intentions/replaceMathMinWithCoerceAtMost/noImport.kt
@@ -0,0 +1,5 @@
+// WITH_RUNTIME
+
+fun foo() {
+ Math.min(2, 1)
+}
\ No newline at end of file
diff --git a/idea/testData/intentions/replaceMathMinWithCoerceAtMost/noImport.kt.after b/idea/testData/intentions/replaceMathMinWithCoerceAtMost/noImport.kt.after
new file mode 100644
index 00000000000..10f915aadec
--- /dev/null
+++ b/idea/testData/intentions/replaceMathMinWithCoerceAtMost/noImport.kt.after
@@ -0,0 +1,5 @@
+// WITH_RUNTIME
+
+fun foo() {
+ 2.coerceAtMost(1)
+}
\ No newline at end of file
diff --git a/idea/testData/intentions/replaceMathMinWithCoerceAtMost/oneValueArg.kt b/idea/testData/intentions/replaceMathMinWithCoerceAtMost/oneValueArg.kt
new file mode 100644
index 00000000000..bfad8b0344a
--- /dev/null
+++ b/idea/testData/intentions/replaceMathMinWithCoerceAtMost/oneValueArg.kt
@@ -0,0 +1,9 @@
+// WITH_RUNTIME
+// IS_APPLICABLE: false
+// ERROR: None of the following functions can be called with the arguments supplied:
public open fun min(p0: Double, p1: Double): Double defined in java.lang.Math
public open fun min(p0: Float, p1: Float): Float defined in java.lang.Math
public open fun min(p0: Int, p1: Int): Int defined in java.lang.Math
public open fun min(p0: Long, p1: Long): Long defined in java.lang.Math
+
+import java.lang.Math.min
+
+fun foo() {
+ min(1.1)
+}
\ No newline at end of file
diff --git a/idea/testData/intentions/replaceMathMinWithCoerceAtMost/simple.kt b/idea/testData/intentions/replaceMathMinWithCoerceAtMost/simple.kt
new file mode 100644
index 00000000000..b4a3649f7fb
--- /dev/null
+++ b/idea/testData/intentions/replaceMathMinWithCoerceAtMost/simple.kt
@@ -0,0 +1,7 @@
+// WITH_RUNTIME
+
+import java.lang.Math.min
+
+fun foo() {
+ min(1, 2)
+}
\ No newline at end of file
diff --git a/idea/testData/intentions/replaceMathMinWithCoerceAtMost/simple.kt.after b/idea/testData/intentions/replaceMathMinWithCoerceAtMost/simple.kt.after
new file mode 100644
index 00000000000..79ee55d839a
--- /dev/null
+++ b/idea/testData/intentions/replaceMathMinWithCoerceAtMost/simple.kt.after
@@ -0,0 +1,7 @@
+// WITH_RUNTIME
+
+import java.lang.Math.min
+
+fun foo() {
+ 1.coerceAtMost(2)
+}
\ No newline at end of file
diff --git a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java
index 70572bb0625..f668d9ddb7c 100644
--- a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java
+++ b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java
@@ -10526,6 +10526,96 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
}
}
+ @TestMetadata("idea/testData/intentions/replaceMathMaxWithCoerceAtLeast")
+ @TestDataPath("$PROJECT_ROOT")
+ @RunWith(JUnit3RunnerWithInners.class)
+ public static class ReplaceMathMaxWithCoerceAtLeast extends AbstractIntentionTest {
+ public void testAllFilesPresentInReplaceMathMaxWithCoerceAtLeast() throws Exception {
+ KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/intentions/replaceMathMaxWithCoerceAtLeast"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), true);
+ }
+
+ @TestMetadata("customMaxMethod.kt")
+ public void testCustomMaxMethod() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/replaceMathMaxWithCoerceAtLeast/customMaxMethod.kt");
+ doTest(fileName);
+ }
+
+ @TestMetadata("doubles.kt")
+ public void testDoubles() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/replaceMathMaxWithCoerceAtLeast/doubles.kt");
+ doTest(fileName);
+ }
+
+ @TestMetadata("moreThan2ValueArg.kt")
+ public void testMoreThan2ValueArg() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/replaceMathMaxWithCoerceAtLeast/moreThan2ValueArg.kt");
+ doTest(fileName);
+ }
+
+ @TestMetadata("noImport.kt")
+ public void testNoImport() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/replaceMathMaxWithCoerceAtLeast/noImport.kt");
+ doTest(fileName);
+ }
+
+ @TestMetadata("oneValueArg.kt")
+ public void testOneValueArg() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/replaceMathMaxWithCoerceAtLeast/oneValueArg.kt");
+ doTest(fileName);
+ }
+
+ @TestMetadata("simple.kt")
+ public void testSimple() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/replaceMathMaxWithCoerceAtLeast/simple.kt");
+ doTest(fileName);
+ }
+ }
+
+ @TestMetadata("idea/testData/intentions/replaceMathMinWithCoerceAtMost")
+ @TestDataPath("$PROJECT_ROOT")
+ @RunWith(JUnit3RunnerWithInners.class)
+ public static class ReplaceMathMinWithCoerceAtMost extends AbstractIntentionTest {
+ public void testAllFilesPresentInReplaceMathMinWithCoerceAtMost() throws Exception {
+ KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/intentions/replaceMathMinWithCoerceAtMost"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), true);
+ }
+
+ @TestMetadata("customMinMethod.kt")
+ public void testCustomMinMethod() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/replaceMathMinWithCoerceAtMost/customMinMethod.kt");
+ doTest(fileName);
+ }
+
+ @TestMetadata("doubles.kt")
+ public void testDoubles() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/replaceMathMinWithCoerceAtMost/doubles.kt");
+ doTest(fileName);
+ }
+
+ @TestMetadata("moreThan2ValueArg.kt")
+ public void testMoreThan2ValueArg() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/replaceMathMinWithCoerceAtMost/moreThan2ValueArg.kt");
+ doTest(fileName);
+ }
+
+ @TestMetadata("noImport.kt")
+ public void testNoImport() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/replaceMathMinWithCoerceAtMost/noImport.kt");
+ doTest(fileName);
+ }
+
+ @TestMetadata("oneValueArg.kt")
+ public void testOneValueArg() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/replaceMathMinWithCoerceAtMost/oneValueArg.kt");
+ doTest(fileName);
+ }
+
+ @TestMetadata("simple.kt")
+ public void testSimple() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/replaceMathMinWithCoerceAtMost/simple.kt");
+ doTest(fileName);
+ }
+ }
+
@TestMetadata("idea/testData/intentions/replaceRangeToWithUntil")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)