diff --git a/compiler/frontend/src/org/jetbrains/jet/lexer/JetKeywordToken.java b/compiler/frontend/src/org/jetbrains/jet/lexer/JetKeywordToken.java index c7771a11e60..6f54557d9b7 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lexer/JetKeywordToken.java +++ b/compiler/frontend/src/org/jetbrains/jet/lexer/JetKeywordToken.java @@ -19,36 +19,33 @@ package org.jetbrains.jet.lexer; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; -public class JetKeywordToken extends JetToken { +public class JetKeywordToken extends JetSingleValueToken { /** * Generate keyword (identifier that has a keyword meaning in all possible contexts) */ public static JetKeywordToken keyword(String value) { - return new JetKeywordToken(value, false); + return keyword(value, value); + } + + public static JetKeywordToken keyword(String debugName, String value) { + return new JetKeywordToken(debugName, value, false); } /** * Generate soft keyword (identifier that has a keyword meaning only in some contexts) */ public static JetKeywordToken softKeyword(String value) { - return new JetKeywordToken(value, true); + return new JetKeywordToken(value, value, true); } - private final String myValue; private final boolean myIsSoft; - private JetKeywordToken(@NotNull @NonNls String value, boolean isSoft) { - super(value); - myValue = value; + private JetKeywordToken(@NotNull @NonNls String debugName, @NotNull @NonNls String value, boolean isSoft) { + super(debugName, value); myIsSoft = isSoft; } - public String getValue() { - return myValue; - } - - public boolean isSoft() { return myIsSoft; } diff --git a/compiler/frontend/src/org/jetbrains/jet/lexer/JetSingleValueToken.java b/compiler/frontend/src/org/jetbrains/jet/lexer/JetSingleValueToken.java new file mode 100644 index 00000000000..4597dd91058 --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/lexer/JetSingleValueToken.java @@ -0,0 +1,36 @@ +/* + * Copyright 2010-2014 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.jet.lexer; + +import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; + +public class JetSingleValueToken extends JetToken { + + private final String myValue; + + public JetSingleValueToken(@NotNull @NonNls String debugName, @NotNull @NonNls String value) { + super(debugName); + myValue = value; + } + + @NotNull @NonNls + public String getValue() { + return myValue; + } + +} diff --git a/compiler/frontend/src/org/jetbrains/jet/lexer/JetTokens.java b/compiler/frontend/src/org/jetbrains/jet/lexer/JetTokens.java index 873f1ecbce2..561c6e81ed3 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lexer/JetTokens.java +++ b/compiler/frontend/src/org/jetbrains/jet/lexer/JetTokens.java @@ -83,58 +83,56 @@ public interface JetTokens { JetToken LABEL_IDENTIFIER = new JetToken("LABEL_IDENTIFIER"); JetToken FIELD_IDENTIFIER = new JetToken("FIELD_IDENTIFIER"); - JetToken LBRACKET = new JetToken("LBRACKET"); - JetToken RBRACKET = new JetToken("RBRACKET"); - JetToken LBRACE = new JetToken("LBRACE"); - JetToken RBRACE = new JetToken("RBRACE"); - JetToken LPAR = new JetToken("LPAR"); - JetToken RPAR = new JetToken("RPAR"); - JetToken DOT = new JetToken("DOT"); - JetToken PLUSPLUS = new JetToken("PLUSPLUS"); - JetToken MINUSMINUS = new JetToken("MINUSMINUS"); - JetToken MUL = new JetToken("MUL"); - JetToken PLUS = new JetToken("PLUS"); - JetToken MINUS = new JetToken("MINUS"); - JetToken EXCL = new JetToken("EXCL"); - JetToken DIV = new JetToken("DIV"); - JetToken PERC = new JetToken("PERC"); - JetToken LT = new JetToken("LT"); - JetToken GT = new JetToken("GT"); - JetToken LTEQ = new JetToken("LTEQ"); - JetToken GTEQ = new JetToken("GTEQ"); - JetToken EQEQEQ = new JetToken("EQEQEQ"); - JetToken ARROW = new JetToken("ARROW"); - JetToken DOUBLE_ARROW = new JetToken("DOUBLE_ARROW"); - JetToken EXCLEQEQEQ = new JetToken("EXCLEQEQEQ"); - JetToken EQEQ = new JetToken("EQEQ"); - JetToken EXCLEQ = new JetToken("EXCLEQ"); - JetToken EXCLEXCL = new JetToken("EXCLEXCL"); - JetToken ANDAND = new JetToken("ANDAND"); - JetToken OROR = new JetToken("OROR"); - JetToken SAFE_ACCESS = new JetToken("SAFE_ACCESS"); - JetToken ELVIS = new JetToken("ELVIS"); - // JetToken MAP = new JetToken("MAP"); - // JetToken FILTER = new JetToken("FILTER"); - JetToken QUEST = new JetToken("QUEST"); - JetToken COLONCOLON = new JetToken("COLONCOLON"); - JetToken COLON = new JetToken("COLON"); - JetToken SEMICOLON = new JetToken("SEMICOLON"); - JetToken RANGE = new JetToken("RANGE"); - JetToken EQ = new JetToken("EQ"); - JetToken MULTEQ = new JetToken("MULTEQ"); - JetToken DIVEQ = new JetToken("DIVEQ"); - JetToken PERCEQ = new JetToken("PERCEQ"); - JetToken PLUSEQ = new JetToken("PLUSEQ"); - JetToken MINUSEQ = new JetToken("MINUSEQ"); - JetToken NOT_IN = JetKeywordToken.keyword("NOT_IN"); - JetToken NOT_IS = JetKeywordToken.keyword("NOT_IS"); - JetToken HASH = new JetToken("HASH"); - JetToken AT = new JetToken("AT"); - JetToken ATAT = new JetToken("ATAT"); + JetSingleValueToken LBRACKET = new JetSingleValueToken("LBRACKET", "["); + JetSingleValueToken RBRACKET = new JetSingleValueToken("RBRACKET", "]"); + JetSingleValueToken LBRACE = new JetSingleValueToken("LBRACE", "{"); + JetSingleValueToken RBRACE = new JetSingleValueToken("RBRACE", "}"); + JetSingleValueToken LPAR = new JetSingleValueToken("LPAR", "("); + JetSingleValueToken RPAR = new JetSingleValueToken("RPAR", ")"); + JetSingleValueToken DOT = new JetSingleValueToken("DOT", "."); + JetSingleValueToken PLUSPLUS = new JetSingleValueToken("PLUSPLUS", "++"); + JetSingleValueToken MINUSMINUS = new JetSingleValueToken("MINUSMINUS", "--"); + JetSingleValueToken MUL = new JetSingleValueToken("MUL", "*"); + JetSingleValueToken PLUS = new JetSingleValueToken("PLUS", "+"); + JetSingleValueToken MINUS = new JetSingleValueToken("MINUS", "-"); + JetSingleValueToken EXCL = new JetSingleValueToken("EXCL", "!"); + JetSingleValueToken DIV = new JetSingleValueToken("DIV", "/"); + JetSingleValueToken PERC = new JetSingleValueToken("PERC", "%"); + JetSingleValueToken LT = new JetSingleValueToken("LT", "<"); + JetSingleValueToken GT = new JetSingleValueToken("GT", ">"); + JetSingleValueToken LTEQ = new JetSingleValueToken("LTEQ", "<="); + JetSingleValueToken GTEQ = new JetSingleValueToken("GTEQ", ">="); + JetSingleValueToken EQEQEQ = new JetSingleValueToken("EQEQEQ", "=="); + JetSingleValueToken ARROW = new JetSingleValueToken("ARROW", "->"); + JetSingleValueToken DOUBLE_ARROW = new JetSingleValueToken("DOUBLE_ARROW", "=>"); + JetSingleValueToken EXCLEQEQEQ = new JetSingleValueToken("EXCLEQEQEQ", "!=="); + JetSingleValueToken EQEQ = new JetSingleValueToken("EQEQ", "=="); + JetSingleValueToken EXCLEQ = new JetSingleValueToken("EXCLEQ", "!="); + JetSingleValueToken EXCLEXCL = new JetSingleValueToken("EXCLEXCL", "!!"); + JetSingleValueToken ANDAND = new JetSingleValueToken("ANDAND", "&&"); + JetSingleValueToken OROR = new JetSingleValueToken("OROR", "||"); + JetSingleValueToken SAFE_ACCESS = new JetSingleValueToken("SAFE_ACCESS", "?."); + JetSingleValueToken ELVIS = new JetSingleValueToken("ELVIS", "?:"); + JetSingleValueToken QUEST = new JetSingleValueToken("QUEST", "?"); + JetSingleValueToken COLONCOLON = new JetSingleValueToken("COLONCOLON", "::"); + JetSingleValueToken COLON = new JetSingleValueToken("COLON", ":"); + JetSingleValueToken SEMICOLON = new JetSingleValueToken("SEMICOLON", ";"); + JetSingleValueToken RANGE = new JetSingleValueToken("RANGE", ".."); + JetSingleValueToken EQ = new JetSingleValueToken("EQ", "="); + JetSingleValueToken MULTEQ = new JetSingleValueToken("MULTEQ", "*="); + JetSingleValueToken DIVEQ = new JetSingleValueToken("DIVEQ", "/="); + JetSingleValueToken PERCEQ = new JetSingleValueToken("PERCEQ", "%="); + JetSingleValueToken PLUSEQ = new JetSingleValueToken("PLUSEQ", "+="); + JetSingleValueToken MINUSEQ = new JetSingleValueToken("MINUSEQ", "-="); + JetKeywordToken NOT_IN = JetKeywordToken.keyword("NOT_IN", "!in"); + JetKeywordToken NOT_IS = JetKeywordToken.keyword("NOT_IS", "!is"); + JetSingleValueToken HASH = new JetSingleValueToken("HASH", "#"); + JetSingleValueToken AT = new JetSingleValueToken("AT", "@"); + JetSingleValueToken ATAT = new JetSingleValueToken("ATAT", "@@"); TokenSet LABELS = TokenSet.create(AT, ATAT, LABEL_IDENTIFIER); - JetToken COMMA = new JetToken("COMMA"); + JetSingleValueToken COMMA = new JetSingleValueToken("COMMA", ","); JetToken EOL_OR_SEMICOLON = new JetToken("EOL_OR_SEMICOLON"); JetKeywordToken IMPORT_KEYWORD = JetKeywordToken.softKeyword("import"); diff --git a/generators/src/org/jetbrains/jet/generators/tests/GenerateTests.kt b/generators/src/org/jetbrains/jet/generators/tests/GenerateTests.kt index 1e2ed58fb78..c25e47f8fff 100644 --- a/generators/src/org/jetbrains/jet/generators/tests/GenerateTests.kt +++ b/generators/src/org/jetbrains/jet/generators/tests/GenerateTests.kt @@ -376,6 +376,7 @@ fun main(args: Array) { model("intentions/attributeCallReplacements/replaceBinaryInfixIntention", testMethod = "doTestReplaceBinaryInfixIntention") model("intentions/attributeCallReplacements/replaceUnaryPrefixIntention", testMethod = "doTestReplaceUnaryPrefixIntention") model("intentions/attributeCallReplacements/replaceInvokeIntention", testMethod = "doTestReplaceInvokeIntention") + model("intentions/simplifyNegatedBinaryExpressionIntention", testMethod = "doTestSimplifyNegatedBinaryExpressionIntention") } testClass(javaClass()) { diff --git a/idea/resources/intentionDescriptions/SimplifyNegatedBinaryExpressionIntention/after.kt.template b/idea/resources/intentionDescriptions/SimplifyNegatedBinaryExpressionIntention/after.kt.template new file mode 100644 index 00000000000..771d5f518f9 --- /dev/null +++ b/idea/resources/intentionDescriptions/SimplifyNegatedBinaryExpressionIntention/after.kt.template @@ -0,0 +1,3 @@ +if (a != b) { + println("Not Equal") +} diff --git a/idea/resources/intentionDescriptions/SimplifyNegatedBinaryExpressionIntention/before.kt.template b/idea/resources/intentionDescriptions/SimplifyNegatedBinaryExpressionIntention/before.kt.template new file mode 100644 index 00000000000..b55588746f2 --- /dev/null +++ b/idea/resources/intentionDescriptions/SimplifyNegatedBinaryExpressionIntention/before.kt.template @@ -0,0 +1,3 @@ +if (!(a == b)) { + println("Not Equal") +} diff --git a/idea/resources/intentionDescriptions/SimplifyNegatedBinaryExpressionIntention/description.html b/idea/resources/intentionDescriptions/SimplifyNegatedBinaryExpressionIntention/description.html new file mode 100644 index 00000000000..db74677e7ff --- /dev/null +++ b/idea/resources/intentionDescriptions/SimplifyNegatedBinaryExpressionIntention/description.html @@ -0,0 +1,7 @@ + + +This intention simplifies negated binary expressions by replacing expressions such as +!(a op b) with a negop b +(where op and negop are inverse comparison operators like == and != or in and !in). + + \ No newline at end of file diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml index 1b7b4d3732b..459b79600ba 100644 --- a/idea/src/META-INF/plugin.xml +++ b/idea/src/META-INF/plugin.xml @@ -535,6 +535,11 @@ Kotlin + + org.jetbrains.jet.plugin.intentions.SimplifyNegatedBinaryExpressionIntention + Kotlin + + org.jetbrains.jet.plugin.intentions.RemoveUnnecessaryParenthesesIntention Kotlin diff --git a/idea/src/org/jetbrains/jet/plugin/JetBundle.properties b/idea/src/org/jetbrains/jet/plugin/JetBundle.properties index c4dd0f5643c..cabd02412f0 100644 --- a/idea/src/org/jetbrains/jet/plugin/JetBundle.properties +++ b/idea/src/org/jetbrains/jet/plugin/JetBundle.properties @@ -81,6 +81,8 @@ remove.parameter=Remove parameter ''{0}'' change.signature.family=Change signature of function/constructor cast.expression.to.type=Cast expression ''{0}'' to ''{1}'' cast.expression.family=Cast Expression +simplify.negated.binary.expression=Simplify negated ''{0}'' expression to ''{1}'' +simplify.negated.binary.expression.family=Simplify Negated Binary Expression replace.call.error.skipped.defaults=Cannot skip default arguments. replace.call.error.undefined.returntype=Unable to determine the return type. diff --git a/idea/src/org/jetbrains/jet/plugin/intentions/SimplifyNegatedBinaryExpressionIntention.kt b/idea/src/org/jetbrains/jet/plugin/intentions/SimplifyNegatedBinaryExpressionIntention.kt new file mode 100644 index 00000000000..4e0fb6ea4ff --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/intentions/SimplifyNegatedBinaryExpressionIntention.kt @@ -0,0 +1,95 @@ +/* + * Copyright 2010-2014 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.jet.plugin.intentions + +import org.jetbrains.jet.lang.psi.JetPrefixExpression +import org.jetbrains.jet.lang.psi.JetParenthesizedExpression +import org.jetbrains.jet.lexer.JetTokens +import org.jetbrains.jet.lang.psi.JetBinaryExpression +import org.jetbrains.jet.lang.psi.JetPsiFactory +import com.intellij.openapi.editor.Editor +import org.jetbrains.jet.lang.psi.JetOperationExpression +import org.jetbrains.jet.lang.psi.JetIsExpression +import org.jetbrains.jet.lexer.JetToken +import org.jetbrains.jet.lang.psi.JetExpression +import org.jetbrains.jet.lang.psi.JetPsiUtil +import org.jetbrains.jet.lexer.JetSingleValueToken +import org.jetbrains.jet.plugin.JetBundle + + +public class SimplifyNegatedBinaryExpressionIntention : JetSelfTargetingIntention("simplify.negated.binary.expression", javaClass()) { + + private fun JetPrefixExpression.unparenthesize(): JetExpression? { + return (this.getBaseExpression() as? JetParenthesizedExpression)?.getExpression() + } + + public fun JetToken.negate(): JetSingleValueToken? = when (this) { + JetTokens.IN_KEYWORD -> JetTokens.NOT_IN + JetTokens.NOT_IN -> JetTokens.IN_KEYWORD + + JetTokens.IS_KEYWORD -> JetTokens.NOT_IS + JetTokens.NOT_IS -> JetTokens.IS_KEYWORD + + JetTokens.EQEQ -> JetTokens.EXCLEQ + JetTokens.EXCLEQ -> JetTokens.EQEQ + + JetTokens.LT -> JetTokens.GTEQ + JetTokens.GTEQ -> JetTokens.LT + + JetTokens.GT -> JetTokens.LTEQ + JetTokens.LTEQ -> JetTokens.GT + + else -> null + } + + override fun isApplicableTo(element: JetPrefixExpression): Boolean { + if (element.getOperationReference().getReferencedNameElementType() != JetTokens.EXCL) return false + + val expression = element.unparenthesize() as? JetOperationExpression + if (!(expression is JetIsExpression || expression is JetBinaryExpression)) return false + + val operation = (JetPsiUtil.getOperationToken(expression) as? JetSingleValueToken) ?: return false + val negOperation = operation.negate() ?: return false + + setText(JetBundle.message(key, operation.getValue(), negOperation.getValue())) + return true + } + + override fun applyTo(element: JetPrefixExpression, editor: Editor) { + // Guaranteed to succeed (by isApplicableTo) + val expression = element.unparenthesize()!! + val invertedOperation = JetPsiUtil.getOperationToken(expression as JetOperationExpression)!!.negate()!! + + element.replace( + when (expression) { + is JetIsExpression -> JetPsiFactory.createExpression( + expression.getProject(), + "${expression.getLeftHandSide().getText() ?: ""} ${invertedOperation.getValue()} ${expression.getTypeRef()?.getText() ?: ""}" + ) + is JetBinaryExpression -> JetPsiFactory.createBinaryExpression( + expression.getProject(), + expression.getLeft(), + invertedOperation.getValue(), + expression.getRight() + ) + else -> throw IllegalStateException( + "Expression is neither a JetIsExpression or JetBinaryExpression (checked by isApplicableTo): ${expression.getText()}" + ) + } + ) + } +} diff --git a/idea/testData/intentions/simplifyNegatedBinaryExpressionIntention/equals.kt b/idea/testData/intentions/simplifyNegatedBinaryExpressionIntention/equals.kt new file mode 100644 index 00000000000..d2fc1545eab --- /dev/null +++ b/idea/testData/intentions/simplifyNegatedBinaryExpressionIntention/equals.kt @@ -0,0 +1,4 @@ +// INTENTION_TEXT: Simplify negated '==' expression to '!=' +fun test(n: Int) { + !(0 == 1) +} \ No newline at end of file diff --git a/idea/testData/intentions/simplifyNegatedBinaryExpressionIntention/equals.kt.after b/idea/testData/intentions/simplifyNegatedBinaryExpressionIntention/equals.kt.after new file mode 100644 index 00000000000..433463d6976 --- /dev/null +++ b/idea/testData/intentions/simplifyNegatedBinaryExpressionIntention/equals.kt.after @@ -0,0 +1,4 @@ +// INTENTION_TEXT: Simplify negated '==' expression to '!=' +fun test(n: Int) { + 0 != 1 +} \ No newline at end of file diff --git a/idea/testData/intentions/simplifyNegatedBinaryExpressionIntention/greaterThan.kt b/idea/testData/intentions/simplifyNegatedBinaryExpressionIntention/greaterThan.kt new file mode 100644 index 00000000000..fcd6fb4cb20 --- /dev/null +++ b/idea/testData/intentions/simplifyNegatedBinaryExpressionIntention/greaterThan.kt @@ -0,0 +1,4 @@ +// INTENTION_TEXT: Simplify negated '>' expression to '<=' +fun test(n: Int) { + !(0 > 1) +} \ No newline at end of file diff --git a/idea/testData/intentions/simplifyNegatedBinaryExpressionIntention/greaterThan.kt.after b/idea/testData/intentions/simplifyNegatedBinaryExpressionIntention/greaterThan.kt.after new file mode 100644 index 00000000000..0cc456fb2e9 --- /dev/null +++ b/idea/testData/intentions/simplifyNegatedBinaryExpressionIntention/greaterThan.kt.after @@ -0,0 +1,4 @@ +// INTENTION_TEXT: Simplify negated '>' expression to '<=' +fun test(n: Int) { + 0 <= 1 +} \ No newline at end of file diff --git a/idea/testData/intentions/simplifyNegatedBinaryExpressionIntention/greaterThanOrEquals.kt b/idea/testData/intentions/simplifyNegatedBinaryExpressionIntention/greaterThanOrEquals.kt new file mode 100644 index 00000000000..759b2aa16b7 --- /dev/null +++ b/idea/testData/intentions/simplifyNegatedBinaryExpressionIntention/greaterThanOrEquals.kt @@ -0,0 +1,4 @@ +// INTENTION_TEXT: Simplify negated '>=' expression to '<' +fun test(n: Int) { + !(0 >= 1) +} \ No newline at end of file diff --git a/idea/testData/intentions/simplifyNegatedBinaryExpressionIntention/greaterThanOrEquals.kt.after b/idea/testData/intentions/simplifyNegatedBinaryExpressionIntention/greaterThanOrEquals.kt.after new file mode 100644 index 00000000000..03f1a925600 --- /dev/null +++ b/idea/testData/intentions/simplifyNegatedBinaryExpressionIntention/greaterThanOrEquals.kt.after @@ -0,0 +1,4 @@ +// INTENTION_TEXT: Simplify negated '>=' expression to '<' +fun test(n: Int) { + 0 < 1 +} \ No newline at end of file diff --git a/idea/testData/intentions/simplifyNegatedBinaryExpressionIntention/in.kt b/idea/testData/intentions/simplifyNegatedBinaryExpressionIntention/in.kt new file mode 100644 index 00000000000..d2011413bb7 --- /dev/null +++ b/idea/testData/intentions/simplifyNegatedBinaryExpressionIntention/in.kt @@ -0,0 +1,5 @@ +// INTENTION_TEXT: Simplify negated 'in' expression to '!in' +fun test(n: Int) { + val arr = ArrayList(1) + !(0 in arr) +} \ No newline at end of file diff --git a/idea/testData/intentions/simplifyNegatedBinaryExpressionIntention/in.kt.after b/idea/testData/intentions/simplifyNegatedBinaryExpressionIntention/in.kt.after new file mode 100644 index 00000000000..69a092757e1 --- /dev/null +++ b/idea/testData/intentions/simplifyNegatedBinaryExpressionIntention/in.kt.after @@ -0,0 +1,5 @@ +// INTENTION_TEXT: Simplify negated 'in' expression to '!in' +fun test(n: Int) { + val arr = ArrayList(1) + 0 !in arr +} \ No newline at end of file diff --git a/idea/testData/intentions/simplifyNegatedBinaryExpressionIntention/inapplicableBinaryOperation.kt b/idea/testData/intentions/simplifyNegatedBinaryExpressionIntention/inapplicableBinaryOperation.kt new file mode 100644 index 00000000000..cdd82422591 --- /dev/null +++ b/idea/testData/intentions/simplifyNegatedBinaryExpressionIntention/inapplicableBinaryOperation.kt @@ -0,0 +1,5 @@ +// IS_APPLICABLE: false +fun lt(a: Int, b: Int): Boolean = a < b +fun test(n: Int) { + !(1 lt 2) +} \ No newline at end of file diff --git a/idea/testData/intentions/simplifyNegatedBinaryExpressionIntention/is.kt b/idea/testData/intentions/simplifyNegatedBinaryExpressionIntention/is.kt new file mode 100644 index 00000000000..b4c827f5a2d --- /dev/null +++ b/idea/testData/intentions/simplifyNegatedBinaryExpressionIntention/is.kt @@ -0,0 +1,4 @@ +// INTENTION_TEXT: Simplify negated 'is' expression to '!is' +fun test(n: Int) { + !(0 is Int) +} \ No newline at end of file diff --git a/idea/testData/intentions/simplifyNegatedBinaryExpressionIntention/is.kt.after b/idea/testData/intentions/simplifyNegatedBinaryExpressionIntention/is.kt.after new file mode 100644 index 00000000000..0e23ca8f264 --- /dev/null +++ b/idea/testData/intentions/simplifyNegatedBinaryExpressionIntention/is.kt.after @@ -0,0 +1,4 @@ +// INTENTION_TEXT: Simplify negated 'is' expression to '!is' +fun test(n: Int) { + 0 !is Int +} \ No newline at end of file diff --git a/idea/testData/intentions/simplifyNegatedBinaryExpressionIntention/lessThan.kt b/idea/testData/intentions/simplifyNegatedBinaryExpressionIntention/lessThan.kt new file mode 100644 index 00000000000..078bc09821a --- /dev/null +++ b/idea/testData/intentions/simplifyNegatedBinaryExpressionIntention/lessThan.kt @@ -0,0 +1,4 @@ +// INTENTION_TEXT: Simplify negated '<' expression to '>=' +fun test(n: Int) { + !(0 < 1) +} \ No newline at end of file diff --git a/idea/testData/intentions/simplifyNegatedBinaryExpressionIntention/lessThan.kt.after b/idea/testData/intentions/simplifyNegatedBinaryExpressionIntention/lessThan.kt.after new file mode 100644 index 00000000000..2181eba637d --- /dev/null +++ b/idea/testData/intentions/simplifyNegatedBinaryExpressionIntention/lessThan.kt.after @@ -0,0 +1,4 @@ +// INTENTION_TEXT: Simplify negated '<' expression to '>=' +fun test(n: Int) { + 0 >= 1 +} \ No newline at end of file diff --git a/idea/testData/intentions/simplifyNegatedBinaryExpressionIntention/lessThanOrEquals.kt b/idea/testData/intentions/simplifyNegatedBinaryExpressionIntention/lessThanOrEquals.kt new file mode 100644 index 00000000000..53f2fc2a80e --- /dev/null +++ b/idea/testData/intentions/simplifyNegatedBinaryExpressionIntention/lessThanOrEquals.kt @@ -0,0 +1,4 @@ +// INTENTION_TEXT: Simplify negated '<=' expression to '>' +fun test(n: Int) { + !(0 <= 1) +} \ No newline at end of file diff --git a/idea/testData/intentions/simplifyNegatedBinaryExpressionIntention/lessThanOrEquals.kt.after b/idea/testData/intentions/simplifyNegatedBinaryExpressionIntention/lessThanOrEquals.kt.after new file mode 100644 index 00000000000..6d0d246accb --- /dev/null +++ b/idea/testData/intentions/simplifyNegatedBinaryExpressionIntention/lessThanOrEquals.kt.after @@ -0,0 +1,4 @@ +// INTENTION_TEXT: Simplify negated '<=' expression to '>' +fun test(n: Int) { + 0 > 1 +} \ No newline at end of file diff --git a/idea/testData/intentions/simplifyNegatedBinaryExpressionIntention/notEquals.kt b/idea/testData/intentions/simplifyNegatedBinaryExpressionIntention/notEquals.kt new file mode 100644 index 00000000000..517b4d64e0a --- /dev/null +++ b/idea/testData/intentions/simplifyNegatedBinaryExpressionIntention/notEquals.kt @@ -0,0 +1,4 @@ +// INTENTION_TEXT: Simplify negated '!=' expression to '==' +fun test(n: Int) { + !(0 != 1) +} \ No newline at end of file diff --git a/idea/testData/intentions/simplifyNegatedBinaryExpressionIntention/notEquals.kt.after b/idea/testData/intentions/simplifyNegatedBinaryExpressionIntention/notEquals.kt.after new file mode 100644 index 00000000000..9e49cb44877 --- /dev/null +++ b/idea/testData/intentions/simplifyNegatedBinaryExpressionIntention/notEquals.kt.after @@ -0,0 +1,4 @@ +// INTENTION_TEXT: Simplify negated '!=' expression to '==' +fun test(n: Int) { + 0 == 1 +} \ No newline at end of file diff --git a/idea/testData/intentions/simplifyNegatedBinaryExpressionIntention/notIn.kt b/idea/testData/intentions/simplifyNegatedBinaryExpressionIntention/notIn.kt new file mode 100644 index 00000000000..36806908ed7 --- /dev/null +++ b/idea/testData/intentions/simplifyNegatedBinaryExpressionIntention/notIn.kt @@ -0,0 +1,5 @@ +// INTENTION_TEXT: Simplify negated '!in' expression to 'in' +fun test(n: Int) { + val arr = ArrayList(1) + !(0 !in arr) +} \ No newline at end of file diff --git a/idea/testData/intentions/simplifyNegatedBinaryExpressionIntention/notIn.kt.after b/idea/testData/intentions/simplifyNegatedBinaryExpressionIntention/notIn.kt.after new file mode 100644 index 00000000000..37f4a0a679b --- /dev/null +++ b/idea/testData/intentions/simplifyNegatedBinaryExpressionIntention/notIn.kt.after @@ -0,0 +1,5 @@ +// INTENTION_TEXT: Simplify negated '!in' expression to 'in' +fun test(n: Int) { + val arr = ArrayList(1) + 0 in arr +} \ No newline at end of file diff --git a/idea/testData/intentions/simplifyNegatedBinaryExpressionIntention/notIs.kt b/idea/testData/intentions/simplifyNegatedBinaryExpressionIntention/notIs.kt new file mode 100644 index 00000000000..d527dc16812 --- /dev/null +++ b/idea/testData/intentions/simplifyNegatedBinaryExpressionIntention/notIs.kt @@ -0,0 +1,4 @@ +// INTENTION_TEXT: Simplify negated '!is' expression to 'is' +fun test(n: Int) { + !(0 !is Int) +} \ No newline at end of file diff --git a/idea/testData/intentions/simplifyNegatedBinaryExpressionIntention/notIs.kt.after b/idea/testData/intentions/simplifyNegatedBinaryExpressionIntention/notIs.kt.after new file mode 100644 index 00000000000..361e7a30ec5 --- /dev/null +++ b/idea/testData/intentions/simplifyNegatedBinaryExpressionIntention/notIs.kt.after @@ -0,0 +1,4 @@ +// INTENTION_TEXT: Simplify negated '!is' expression to 'is' +fun test(n: Int) { + 0 is Int +} \ No newline at end of file diff --git a/idea/testData/intentions/simplifyNegatedBinaryExpressionIntention/simpleInvert.kt b/idea/testData/intentions/simplifyNegatedBinaryExpressionIntention/simpleInvert.kt new file mode 100644 index 00000000000..46f0c504048 --- /dev/null +++ b/idea/testData/intentions/simplifyNegatedBinaryExpressionIntention/simpleInvert.kt @@ -0,0 +1,4 @@ +// IS_APPLICABLE: false +fun test(n: Int) { + !true +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/plugin/intentions/AbstractCodeTransformationTest.java b/idea/tests/org/jetbrains/jet/plugin/intentions/AbstractCodeTransformationTest.java index 85bfacfac16..4d452ad72f8 100644 --- a/idea/tests/org/jetbrains/jet/plugin/intentions/AbstractCodeTransformationTest.java +++ b/idea/tests/org/jetbrains/jet/plugin/intentions/AbstractCodeTransformationTest.java @@ -195,6 +195,10 @@ public abstract class AbstractCodeTransformationTest extends LightCodeInsightTes doTestIntention(path, new TestableReplaceInvokeIntention()); } + public void doTestSimplifyNegatedBinaryExpressionIntention(@NotNull String path) throws Exception { + doTestIntention(path, new SimplifyNegatedBinaryExpressionIntention()); + } + private void doTestIntention(@NotNull String path, @NotNull IntentionAction intentionAction) throws Exception { configureByFile(path); diff --git a/idea/tests/org/jetbrains/jet/plugin/intentions/CodeTransformationTestGenerated.java b/idea/tests/org/jetbrains/jet/plugin/intentions/CodeTransformationTestGenerated.java index 9337414d11f..eedd02d0748 100644 --- a/idea/tests/org/jetbrains/jet/plugin/intentions/CodeTransformationTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/plugin/intentions/CodeTransformationTestGenerated.java @@ -30,7 +30,7 @@ import org.jetbrains.jet.plugin.intentions.AbstractCodeTransformationTest; /** This class is generated by {@link org.jetbrains.jet.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */ @SuppressWarnings("all") -@InnerTestClasses({CodeTransformationTestGenerated.ElvisToIfThen.class, CodeTransformationTestGenerated.IfThenToElvis.class, CodeTransformationTestGenerated.SafeAccessToIfThen.class, CodeTransformationTestGenerated.IfThenToSafeAccess.class, CodeTransformationTestGenerated.IfToAssignment.class, CodeTransformationTestGenerated.IfToReturn.class, CodeTransformationTestGenerated.IfToReturnAsymmetrically.class, CodeTransformationTestGenerated.WhenToAssignment.class, CodeTransformationTestGenerated.WhenToReturn.class, CodeTransformationTestGenerated.AssignmentToIf.class, CodeTransformationTestGenerated.AssignmentToWhen.class, CodeTransformationTestGenerated.PropertyToIf.class, CodeTransformationTestGenerated.PropertyToWhen.class, CodeTransformationTestGenerated.ReturnToIf.class, CodeTransformationTestGenerated.ReturnToWhen.class, CodeTransformationTestGenerated.IfToWhen.class, CodeTransformationTestGenerated.WhenToIf.class, CodeTransformationTestGenerated.Flatten.class, CodeTransformationTestGenerated.Merge.class, CodeTransformationTestGenerated.IntroduceSubject.class, CodeTransformationTestGenerated.EliminateSubject.class, CodeTransformationTestGenerated.Split.class, CodeTransformationTestGenerated.Join.class, CodeTransformationTestGenerated.ConvertMemberToExtension.class, CodeTransformationTestGenerated.ReconstructedType.class, CodeTransformationTestGenerated.RemoveUnnecessaryParentheses.class, CodeTransformationTestGenerated.ReplaceWithDotQualifiedMethodCall.class, CodeTransformationTestGenerated.ReplaceWithInfixFunctionCall.class, CodeTransformationTestGenerated.RemoveCurlyBracesFromTemplate.class, CodeTransformationTestGenerated.MoveLambdaInsideParentheses.class, CodeTransformationTestGenerated.MoveLambdaOutsideParentheses.class, CodeTransformationTestGenerated.ReplaceExplicitFunctionLiteralParamWithIt.class, CodeTransformationTestGenerated.ReplaceItWithExplicitFunctionLiteralParam.class, CodeTransformationTestGenerated.RemoveBraces.class, CodeTransformationTestGenerated.AddBraces.class, CodeTransformationTestGenerated.ReplaceGetIntention.class, CodeTransformationTestGenerated.ReplaceContainsIntention.class, CodeTransformationTestGenerated.ReplaceBinaryInfixIntention.class, CodeTransformationTestGenerated.ReplaceUnaryPrefixIntention.class, CodeTransformationTestGenerated.ReplaceInvokeIntention.class}) +@InnerTestClasses({CodeTransformationTestGenerated.ElvisToIfThen.class, CodeTransformationTestGenerated.IfThenToElvis.class, CodeTransformationTestGenerated.SafeAccessToIfThen.class, CodeTransformationTestGenerated.IfThenToSafeAccess.class, CodeTransformationTestGenerated.IfToAssignment.class, CodeTransformationTestGenerated.IfToReturn.class, CodeTransformationTestGenerated.IfToReturnAsymmetrically.class, CodeTransformationTestGenerated.WhenToAssignment.class, CodeTransformationTestGenerated.WhenToReturn.class, CodeTransformationTestGenerated.AssignmentToIf.class, CodeTransformationTestGenerated.AssignmentToWhen.class, CodeTransformationTestGenerated.PropertyToIf.class, CodeTransformationTestGenerated.PropertyToWhen.class, CodeTransformationTestGenerated.ReturnToIf.class, CodeTransformationTestGenerated.ReturnToWhen.class, CodeTransformationTestGenerated.IfToWhen.class, CodeTransformationTestGenerated.WhenToIf.class, CodeTransformationTestGenerated.Flatten.class, CodeTransformationTestGenerated.Merge.class, CodeTransformationTestGenerated.IntroduceSubject.class, CodeTransformationTestGenerated.EliminateSubject.class, CodeTransformationTestGenerated.Split.class, CodeTransformationTestGenerated.Join.class, CodeTransformationTestGenerated.ConvertMemberToExtension.class, CodeTransformationTestGenerated.ReconstructedType.class, CodeTransformationTestGenerated.RemoveUnnecessaryParentheses.class, CodeTransformationTestGenerated.ReplaceWithDotQualifiedMethodCall.class, CodeTransformationTestGenerated.ReplaceWithInfixFunctionCall.class, CodeTransformationTestGenerated.RemoveCurlyBracesFromTemplate.class, CodeTransformationTestGenerated.MoveLambdaInsideParentheses.class, CodeTransformationTestGenerated.MoveLambdaOutsideParentheses.class, CodeTransformationTestGenerated.ReplaceExplicitFunctionLiteralParamWithIt.class, CodeTransformationTestGenerated.ReplaceItWithExplicitFunctionLiteralParam.class, CodeTransformationTestGenerated.RemoveBraces.class, CodeTransformationTestGenerated.AddBraces.class, CodeTransformationTestGenerated.ReplaceGetIntention.class, CodeTransformationTestGenerated.ReplaceContainsIntention.class, CodeTransformationTestGenerated.ReplaceBinaryInfixIntention.class, CodeTransformationTestGenerated.ReplaceUnaryPrefixIntention.class, CodeTransformationTestGenerated.ReplaceInvokeIntention.class, CodeTransformationTestGenerated.SimplifyNegatedBinaryExpressionIntention.class}) public class CodeTransformationTestGenerated extends AbstractCodeTransformationTest { @TestMetadata("idea/testData/intentions/branched/elvisToIfThen") public static class ElvisToIfThen extends AbstractCodeTransformationTest { @@ -2602,6 +2602,74 @@ public class CodeTransformationTestGenerated extends AbstractCodeTransformationT } + @TestMetadata("idea/testData/intentions/simplifyNegatedBinaryExpressionIntention") + public static class SimplifyNegatedBinaryExpressionIntention extends AbstractCodeTransformationTest { + public void testAllFilesPresentInSimplifyNegatedBinaryExpressionIntention() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("idea/testData/intentions/simplifyNegatedBinaryExpressionIntention"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("equals.kt") + public void testEquals() throws Exception { + doTestSimplifyNegatedBinaryExpressionIntention("idea/testData/intentions/simplifyNegatedBinaryExpressionIntention/equals.kt"); + } + + @TestMetadata("greaterThan.kt") + public void testGreaterThan() throws Exception { + doTestSimplifyNegatedBinaryExpressionIntention("idea/testData/intentions/simplifyNegatedBinaryExpressionIntention/greaterThan.kt"); + } + + @TestMetadata("greaterThanOrEquals.kt") + public void testGreaterThanOrEquals() throws Exception { + doTestSimplifyNegatedBinaryExpressionIntention("idea/testData/intentions/simplifyNegatedBinaryExpressionIntention/greaterThanOrEquals.kt"); + } + + @TestMetadata("in.kt") + public void testIn() throws Exception { + doTestSimplifyNegatedBinaryExpressionIntention("idea/testData/intentions/simplifyNegatedBinaryExpressionIntention/in.kt"); + } + + @TestMetadata("inapplicableBinaryOperation.kt") + public void testInapplicableBinaryOperation() throws Exception { + doTestSimplifyNegatedBinaryExpressionIntention("idea/testData/intentions/simplifyNegatedBinaryExpressionIntention/inapplicableBinaryOperation.kt"); + } + + @TestMetadata("is.kt") + public void testIs() throws Exception { + doTestSimplifyNegatedBinaryExpressionIntention("idea/testData/intentions/simplifyNegatedBinaryExpressionIntention/is.kt"); + } + + @TestMetadata("lessThan.kt") + public void testLessThan() throws Exception { + doTestSimplifyNegatedBinaryExpressionIntention("idea/testData/intentions/simplifyNegatedBinaryExpressionIntention/lessThan.kt"); + } + + @TestMetadata("lessThanOrEquals.kt") + public void testLessThanOrEquals() throws Exception { + doTestSimplifyNegatedBinaryExpressionIntention("idea/testData/intentions/simplifyNegatedBinaryExpressionIntention/lessThanOrEquals.kt"); + } + + @TestMetadata("notEquals.kt") + public void testNotEquals() throws Exception { + doTestSimplifyNegatedBinaryExpressionIntention("idea/testData/intentions/simplifyNegatedBinaryExpressionIntention/notEquals.kt"); + } + + @TestMetadata("notIn.kt") + public void testNotIn() throws Exception { + doTestSimplifyNegatedBinaryExpressionIntention("idea/testData/intentions/simplifyNegatedBinaryExpressionIntention/notIn.kt"); + } + + @TestMetadata("notIs.kt") + public void testNotIs() throws Exception { + doTestSimplifyNegatedBinaryExpressionIntention("idea/testData/intentions/simplifyNegatedBinaryExpressionIntention/notIs.kt"); + } + + @TestMetadata("simpleInvert.kt") + public void testSimpleInvert() throws Exception { + doTestSimplifyNegatedBinaryExpressionIntention("idea/testData/intentions/simplifyNegatedBinaryExpressionIntention/simpleInvert.kt"); + } + + } + public static Test suite() { TestSuite suite = new TestSuite("CodeTransformationTestGenerated"); suite.addTestSuite(ElvisToIfThen.class); @@ -2644,6 +2712,7 @@ public class CodeTransformationTestGenerated extends AbstractCodeTransformationT suite.addTestSuite(ReplaceBinaryInfixIntention.class); suite.addTestSuite(ReplaceUnaryPrefixIntention.class); suite.addTestSuite(ReplaceInvokeIntention.class); + suite.addTestSuite(SimplifyNegatedBinaryExpressionIntention.class); return suite; } }