From d58038d3effbb5d4558617d05a2af9fbf9b2e89b Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Fri, 19 Oct 2012 19:05:29 +0400 Subject: [PATCH] Deparenthesize 'null' before checking the constant expression --- .../jetbrains/jet/lang/psi/JetPsiUtil.java | 6 ++++ .../BasicExpressionTypingVisitor.java | 4 +-- .../senselessComparison/parenthesized.kt | 31 +++++++++++++++++++ .../checkers/JetDiagnosticsTestGenerated.java | 21 +++++++++++-- 4 files changed, 58 insertions(+), 4 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/senselessComparison/parenthesized.kt diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java index 07d555b5daa..5b7b8e7e650 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java @@ -25,6 +25,7 @@ import com.intellij.psi.tree.IElementType; import com.intellij.psi.util.PsiTreeUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.JetNodeTypes; import org.jetbrains.jet.lang.resolve.ImportPath; import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.name.Name; @@ -412,4 +413,9 @@ public class JetPsiUtil { return result; } + + public static boolean isNullConstant(@NotNull JetExpression expression) { + JetExpression deparenthesized = deparenthesize(expression); + return deparenthesized instanceof JetConstantExpression && deparenthesized.getNode().getElementType() == JetNodeTypes.NULL; + } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java index 7ef94bd40b8..6cfe36ad6b4 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java @@ -1101,10 +1101,10 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { private void checkSenselessComparisonWithNull(@NotNull JetBinaryExpression expression, @NotNull JetExpression left, @NotNull JetExpression right, @NotNull ExpressionTypingContext context) { JetExpression expr; - if (left instanceof JetConstantExpression && left.getNode().getElementType() == JetNodeTypes.NULL) { + if (JetPsiUtil.isNullConstant(left)) { expr = right; } - else if (right instanceof JetConstantExpression && right.getNode().getElementType() == JetNodeTypes.NULL) { + else if (JetPsiUtil.isNullConstant(right)) { expr = left; } else return; diff --git a/compiler/testData/diagnostics/tests/senselessComparison/parenthesized.kt b/compiler/testData/diagnostics/tests/senselessComparison/parenthesized.kt new file mode 100644 index 00000000000..a72c19c358a --- /dev/null +++ b/compiler/testData/diagnostics/tests/senselessComparison/parenthesized.kt @@ -0,0 +1,31 @@ +fun testEquals(x: Int) { + if (x == null) {} + if (x == (null)) {} + if (x == null: Nothing?) {} + if (x == null: Nothing?) {} + if (x == @foo null) {} +} + +fun testEqualsFlipped(x: Int) { + if (null == x) {} + if ((null) == x) {} + if (null: Nothing? == x) {} + if (null: Nothing? == x) {} + if (@foo null == x) {} +} + +fun testNotEquals(x: Int) { + if (x != null) {} + if (x != (null)) {} + if (x != null: Nothing?) {} + if (x != null: Nothing?) {} + if (x != @foo null) {} +} + +fun testNotEqualsFlipped(x: Int) { + if (null != x) {} + if ((null) != x) {} + if (null: Nothing? != x) {} + if (null: Nothing? != x) {} + if (@foo null != x) {} +} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java index c2544192bb2..2712ffdb6de 100644 --- a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java @@ -15,19 +15,22 @@ */ package org.jetbrains.jet.checkers; +import junit.framework.Assert; import junit.framework.Test; import junit.framework.TestSuite; + +import java.io.File; import org.jetbrains.jet.JetTestUtils; import org.jetbrains.jet.test.InnerTestClasses; import org.jetbrains.jet.test.TestMetadata; -import java.io.File; +import org.jetbrains.jet.checkers.AbstractDiagnosticsTestWithEagerResolve; /** This class is generated by {@link org.jetbrains.jet.checkers.AbstractDiagnosticsTestWithEagerResolve}. DO NOT MODIFY MANUALLY */ @InnerTestClasses({JetDiagnosticsTestGenerated.Tests.class, JetDiagnosticsTestGenerated.Script.class}) public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEagerResolve { @TestMetadata("compiler/testData/diagnostics/tests") - @InnerTestClasses({Tests.Annotations.class, Tests.BackingField.class, Tests.Cast.class, Tests.CheckArguments.class, Tests.ControlFlowAnalysis.class, Tests.ControlStructures.class, Tests.DataClasses.class, Tests.DataFlow.class, Tests.DataFlowInfoTraversal.class, Tests.DeclarationChecks.class, Tests.Enum.class, Tests.Extensions.class, Tests.FunctionLiterals.class, Tests.Generics.class, Tests.IncompleteCode.class, Tests.Inference.class, Tests.Infos.class, Tests.J_k.class, Tests.Jdk_annotations.class, Tests.Library.class, Tests.NullabilityAndAutoCasts.class, Tests.NullableTypes.class, Tests.Objects.class, Tests.OperatorsOverloading.class, Tests.Overload.class, Tests.Override.class, Tests.Redeclarations.class, Tests.Regressions.class, Tests.Scopes.class, Tests.Shadowing.class, Tests.Substitutions.class, Tests.Subtyping.class, Tests.Tuples.class, Tests.Varargs.class}) + @InnerTestClasses({Tests.Annotations.class, Tests.BackingField.class, Tests.Cast.class, Tests.CheckArguments.class, Tests.ControlFlowAnalysis.class, Tests.ControlStructures.class, Tests.DataClasses.class, Tests.DataFlow.class, Tests.DataFlowInfoTraversal.class, Tests.DeclarationChecks.class, Tests.Enum.class, Tests.Extensions.class, Tests.FunctionLiterals.class, Tests.Generics.class, Tests.IncompleteCode.class, Tests.Inference.class, Tests.Infos.class, Tests.J_k.class, Tests.Jdk_annotations.class, Tests.Library.class, Tests.NullabilityAndAutoCasts.class, Tests.NullableTypes.class, Tests.Objects.class, Tests.OperatorsOverloading.class, Tests.Overload.class, Tests.Override.class, Tests.Redeclarations.class, Tests.Regressions.class, Tests.Scopes.class, Tests.SenselessComparison.class, Tests.Shadowing.class, Tests.Substitutions.class, Tests.Subtyping.class, Tests.Tuples.class, Tests.Varargs.class}) public static class Tests extends AbstractDiagnosticsTestWithEagerResolve { @TestMetadata("Abstract.kt") public void testAbstract() throws Exception { @@ -3349,6 +3352,19 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage } + @TestMetadata("compiler/testData/diagnostics/tests/senselessComparison") + public static class SenselessComparison extends AbstractDiagnosticsTestWithEagerResolve { + public void testAllFilesPresentInSenselessComparison() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.checkers.AbstractDiagnosticsTestWithEagerResolve", new File("compiler/testData/diagnostics/tests/senselessComparison"), "kt", true); + } + + @TestMetadata("parenthesized.kt") + public void testParenthesized() throws Exception { + doTest("compiler/testData/diagnostics/tests/senselessComparison/parenthesized.kt"); + } + + } + @TestMetadata("compiler/testData/diagnostics/tests/shadowing") public static class Shadowing extends AbstractDiagnosticsTestWithEagerResolve { public void testAllFilesPresentInShadowing() throws Exception { @@ -3551,6 +3567,7 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage suite.addTestSuite(Redeclarations.class); suite.addTestSuite(Regressions.class); suite.addTestSuite(Scopes.class); + suite.addTestSuite(SenselessComparison.class); suite.addTestSuite(Shadowing.class); suite.addTestSuite(Substitutions.class); suite.addTestSuite(Subtyping.class);