dfa: check that states to be merged are really complementary (IDEA-136917)
[idea/community.git] / java / java-tests / testSrc / com / intellij / codeInspection / DataFlowInspectionTest.java
1 /*
2  * Copyright 2000-2013 JetBrains s.r.o.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.intellij.codeInspection;
17
18 import com.intellij.JavaTestUtil;
19 import com.intellij.codeInspection.dataFlow.DataFlowInspection;
20 import com.intellij.testFramework.LightProjectDescriptor;
21 import com.intellij.testFramework.fixtures.JavaCodeInsightTestFixture;
22 import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
23 import org.jetbrains.annotations.NotNull;
24
25 /**
26  * @author peter
27  */
28 public class DataFlowInspectionTest extends LightCodeInsightFixtureTestCase {
29
30   @NotNull
31   @Override
32   protected LightProjectDescriptor getProjectDescriptor() {
33     return JAVA_1_7;
34   }
35
36   @Override
37   protected String getTestDataPath() {
38     return JavaTestUtil.getJavaTestDataPath() + "/inspection/dataFlow/fixture/";
39   }
40
41   private void doTest() {
42     final DataFlowInspection inspection = new DataFlowInspection();
43     inspection.SUGGEST_NULLABLE_ANNOTATIONS = true;
44     inspection.REPORT_CONSTANT_REFERENCE_VALUES = false;
45     myFixture.enableInspections(inspection);
46     myFixture.testHighlighting(true, false, true, getTestName(false) + ".java");
47   }
48
49   public void testTryInAnonymous() throws Throwable { doTest(); }
50   public void testNullableAnonymousMethod() throws Throwable { doTest(); }
51   public void testNullableAnonymousParameter() throws Throwable { doTest(); }
52   public void testNullableAnonymousVolatile() throws Throwable { doTest(); }
53   public void testNullableAnonymousVolatileNotNull() throws Throwable { doTest(); }
54   public void testLocalClass() throws Throwable { doTest(); }
55
56   public void testFieldInAnonymous() throws Throwable { doTest(); }
57   public void testFieldInitializerInAnonymous() throws Throwable { doTest(); }
58   public void testNullableField() throws Throwable { doTest(); }
59   public void testCanBeNullDoesntImplyIsNull() throws Throwable { doTest(); }
60   public void testAnnReport() throws Throwable { doTest(); }
61
62   public void testBigMethodNotComplex() throws Throwable { doTest(); }
63   public void testBuildRegexpNotComplex() throws Throwable { doTest(); }
64   public void testTernaryInWhileNotComplex() throws Throwable { doTest(); }
65   public void testTryCatchInForNotComplex() throws Throwable { doTest(); }
66   public void testNestedTryInWhileNotComplex() throws Throwable { doTest(); }
67   public void testExceptionFromFinally() throws Throwable { doTest(); }
68   public void testExceptionFromFinallyNesting() throws Throwable { doTest(); }
69   public void testNestedFinally() { doTest(); }
70   public void testTryFinallyInsideFinally() { doTest(); }
71   public void testFieldChangedBetweenSynchronizedBlocks() throws Throwable { doTest(); }
72
73   public void testGeneratedEquals() throws Throwable { doTest(); }
74
75   public void testIDEA84489() throws Throwable { doTest(); }
76   public void testComparingNullToNotNull() { doTest(); }
77   public void testComparingNullableToNullable() { doTest(); }
78   public void testComparingNullableToUnknown() { doTest(); }
79   public void testComparingToNotNullShouldNotAffectNullity() throws Throwable { doTest(); }
80   public void testComparingToNullableShouldNotAffectNullity() throws Throwable { doTest(); }
81   public void testStringTernaryAlwaysTrue() throws Throwable { doTest(); }
82   public void testStringConcatAlwaysNotNull() throws Throwable { doTest(); }
83
84   public void testNotNullPrimitive() throws Throwable { doTest(); }
85   public void testBoxing128() throws Throwable { doTest(); }
86   public void testFinalFieldsInitializedByAnnotatedParameters() throws Throwable { doTest(); }
87   public void testFinalFieldsInitializedNotNull() throws Throwable { doTest(); }
88   public void testMultiCatch() throws Throwable { doTest(); }
89   public void testContinueFlushesLoopVariable() throws Throwable { doTest(); }
90
91   public void testEqualsNotNull() throws Throwable { doTest(); }
92   public void testVisitFinallyOnce() throws Throwable { doTest(); }
93   public void testNotEqualsDoesntImplyNotNullity() throws Throwable { doTest(); }
94   public void testEqualsEnumConstant() throws Throwable { doTest(); }
95   public void testSwitchEnumConstant() { doTest(); }
96   public void testEnumConstantNotNull() throws Throwable { doTest(); }
97   public void testEqualsConstant() throws Throwable { doTest(); }
98   public void testDontSaveTypeValue() { doTest(); }
99   public void testFinalLoopVariableInstanceof() throws Throwable { doTest(); }
100   public void testGreaterIsNotEquals() throws Throwable { doTest(); }
101   public void testNotGreaterIsNotEquals() throws Throwable { doTest(); }
102
103   public void testChainedFinalFieldsDfa() throws Throwable { doTest(); }
104   public void testFinalFieldsDifferentInstances() throws Throwable { doTest(); }
105   public void testThisFieldGetters() throws Throwable { doTest(); }
106   public void testChainedFinalFieldAccessorsDfa() throws Throwable { doTest(); }
107   public void testAccessorPlusMutator() throws Throwable { doTest(); }
108   public void testClosureVariableField() throws Throwable { doTest(); }
109   public void testOptionalThis() { doTest(); }
110   public void testQualifiedThis() { doTest(); }
111
112   public void testAssigningNullableToNotNull() throws Throwable { doTest(); }
113   public void testAssigningUnknownToNullable() throws Throwable { doTest(); }
114   public void testAssigningClassLiteralToNullable() throws Throwable { doTest(); }
115
116   public void testSynchronizingOnNullable() throws Throwable { doTest(); }
117   public void testSwitchOnNullable() { doTest(); }
118   public void testReturningNullFromVoidMethod() throws Throwable { doTest(); }
119   public void testReturningNullConstant() { doTest(); }
120
121   public void testCatchRuntimeException() throws Throwable { doTest(); }
122   // IDEA-129331
123   //public void testCatchThrowable() throws Throwable { doTest(); }
124   public void testNotNullCatchParameter() { doTest(); }
125
126   public void testAssertFailInCatch() throws Throwable {
127     myFixture.addClass("package org.junit; public class Assert { public static void fail() {}}");
128     doTest();
129   }
130
131   public void testPreserveNullableOnUncheckedCast() throws Throwable { doTest(); }
132   public void testPrimitiveCastMayChangeValue() throws Throwable { doTest(); }
133
134   public void testPassingNullableIntoVararg() throws Throwable { doTest(); }
135   public void testEqualsImpliesNotNull() throws Throwable { doTestReportConstantReferences(); }
136   public void testEffectivelyUnqualified() throws Throwable { doTest(); }
137
138   public void testSkipAssertions() {
139     final DataFlowInspection inspection = new DataFlowInspection();
140     inspection.DONT_REPORT_TRUE_ASSERT_STATEMENTS = true;
141     myFixture.enableInspections(inspection);
142     myFixture.testHighlighting(true, false, true, getTestName(false) + ".java");
143   }
144
145   public void testParanoidMode() {
146     final DataFlowInspection inspection = new DataFlowInspection();
147     inspection.TREAT_UNKNOWN_MEMBERS_AS_NULLABLE = true;
148     myFixture.enableInspections(inspection);
149     myFixture.testHighlighting(true, false, true, getTestName(false) + ".java");
150   }
151
152   public void testReportConstantReferences() {
153     doTestReportConstantReferences();
154     myFixture.launchAction(myFixture.findSingleIntention("Replace with 'null'"));
155     myFixture.checkResultByFile(getTestName(false) + "_after.java");
156   }
157
158   public void testReportConstantReferences_OverloadedCall() {
159     doTestReportConstantReferences();
160     myFixture.launchAction(myFixture.findSingleIntention("Replace with 'null'"));
161     myFixture.checkResultByFile(getTestName(false) + "_after.java");
162   }
163
164   public void testReportConstantReferencesAfterFinalFieldAccess() { doTestReportConstantReferences(); }
165
166   private void doTestReportConstantReferences() {
167     DataFlowInspection inspection = new DataFlowInspection();
168     inspection.SUGGEST_NULLABLE_ANNOTATIONS = true;
169     myFixture.enableInspections(inspection);
170     myFixture.testHighlighting(true, false, true, getTestName(false) + ".java");
171   }
172
173   public void testCheckFieldInitializers() {
174     doTest();
175   }
176
177   public void testConstantDoubleComparisons() { doTest(); }
178   public void testInherentNumberRanges() { doTest(); }
179
180   public void testMutableNullableFieldsTreatment() { doTest(); }
181   public void testMutableVolatileNullableFieldsTreatment() { doTest(); }
182   public void testMutableNotAnnotatedFieldsTreatment() { doTest(); }
183   public void testSuperCallMayChangeFields() { doTest(); }
184   public void testOtherCallMayChangeFields() { doTest(); }
185
186   public void testMethodCallFlushesField() { doTest(); }
187   public void testUnknownFloatMayBeNaN() { doTest(); }
188   public void testFloatEquality() { doTest(); }
189   public void testLastConstantConditionInAnd() { doTest(); }
190   
191   public void testCompileTimeConstant() { doTest(); }
192
193   public void testTransientFinalField() { doTest(); }
194   public void testRememberLocalTransientFieldState() { doTest(); }
195   public void testFinalFieldDuringInitialization() { doTest(); }
196   public void testFinalFieldDuringSuperInitialization() { doTest(); }
197   public void _testSymmetricUncheckedCast() { doTest(); } // https://youtrack.jetbrains.com/issue/IDEABKL-6871
198   public void testNullCheckDoesntAffectUncheckedCast() { doTest(); }
199   public void testThrowNull() { doTest(); }
200
201   public void testExplicitlyNullableLocalVar() { doTest(); }
202
203   public void testTryWithResourcesNullability() { doTest(); }
204   public void testTryWithResourcesInstanceOf() { doTest(); }
205   public void testOmnipresentExceptions() { doTest(); }
206
207   public void testEqualsHasNoSideEffects() { doTest(); }
208
209   public void testHonorGetterAnnotation() { doTest(); }
210
211   public void testIgnoreAssertions() {
212     final DataFlowInspection inspection = new DataFlowInspection();
213     inspection.IGNORE_ASSERT_STATEMENTS = true;
214     myFixture.enableInspections(inspection);
215     myFixture.testHighlighting(true, false, true, getTestName(false) + ".java");
216   }
217
218   public void testContractAnnotation() { doTest(); }
219   public void testContractInapplicableComparison() { doTest(); }
220   public void testContractInLoopNotTooComplex() { doTest(); }
221   public void testContractWithManyParameters() { doTest(); }
222   public void testContractWithNullable() { doTest(); }
223   public void testContractWithNotNull() { doTest(); }
224   public void testContractPreservesUnknownNullability() { doTest(); }
225   public void testContractSeveralClauses() { doTest(); }
226   public void testContractVarargs() { doTest(); }
227
228   public void testBoxingImpliesNotNull() { doTest(); }
229   public void testLargeIntegersAreNotEqualWhenBoxed() { doTest(); }
230   public void testNoGenericCCE() { doTest(); }
231   public void testLongCircuitOperations() { doTest(); }
232   public void testUnconditionalForLoop() { doTest(); }
233   public void testAnonymousMethodIndependence() { doTest(); }
234   public void testAnonymousFieldIndependence() { doTest(); }
235   public void testNoConfusionWithAnonymousConstantInitializer() { doTest(); }
236   public void testForeachOverWildcards() { doTest(); }
237   public void testFinalGetter() { doTest(); }
238   public void testGetterResultsNotSame() { doTest(); }
239
240   public void testByteBufferGetter() {
241     myFixture.addClass("package java.nio; public class MappedByteBuffer { public int getInt() {} }");
242     doTest();
243   }
244
245   public void testManySequentialIfsNotComplex() { doTest(); }
246   public void testManySequentialInstanceofsNotComplex() { doTest(); }
247   public void testLongDisjunctionsNotComplex() { doTest(); }
248   public void testWhileNotComplex() { doTest(); }
249   public void testAssertTrueNotComplex() { doTest(); }
250   public void testManyDisjunctiveFieldAssignmentsInLoopNotComplex() { doTest(); }
251   public void testManyContinuesNotComplex() { doTest(); }
252   public void testFinallyNotComplex() { doTest(); }
253   public void testFlushFurtherUnusedVariables() { doTest(); }
254   public void testDontFlushVariablesUsedInClosures() { doTest(); }
255
256   public void testVariablesDiverge() { doTest(); }
257   public void testMergeByNullability() { doTest(); }
258   public void testCheckComplementarityWhenMerge() { doTest(); }
259   public void testDontForgetInstanceofInfoWhenMerging() { doTest(); }
260   public void testDontForgetEqInfoWhenMergingByType() { doTest(); }
261   public void testDontMakeNullableAfterInstanceof() { doTest(); }
262   public void testDontMakeUnrelatedVariableNotNullWhenMerging() { doTest(); }
263   public void testDontMakeUnrelatedVariableFalseWhenMerging() { doTest(); }
264   public void testDontLoseInequalityInformation() { doTest(); }
265   
266   public void testNotEqualsTypo() { doTest(); }
267   public void testAndEquals() { doTest(); }
268
269   public void testUnusedCallDoesNotMakeUnknown() { doTest(); }
270   public void testEmptyCallDoesNotMakeNullable() { doTest(); }
271   public void testGettersAndPureNoFlushing() { doTest(); }
272   
273   public void testNotNullAfterDereference() { doTest(); }
274
275   public void testNullableBoolean() { doTest(); }
276
277   public void testSameComparisonTwice() { doTest(); }
278   public void testRootThrowableCause() { doTest(); }
279
280   public void testOverridingInferredNotNullMethod() { doTest(); }
281   public void testUseInferredContracts() { doTest(); }
282   public void testContractWithNoArgs() { doTest(); }
283   public void testContractInferenceBewareOverriding() { doTest(); }
284
285   public void testNumberComparisonsWhenValueIsKnown() { doTest(); }
286   public void testFloatComparisons() { doTest(); }
287
288   public void testNullableArray() { doTest(); }
289
290   public void testAccessingSameArrayElements() { doTest(); }
291
292   public void testParametersAreNonnullByDefault() {
293     addJavaxNullabilityAnnotations(myFixture);
294     addJavaxDefaultNullabilityAnnotations(myFixture);
295     
296     myFixture.addClass("package foo; public class AnotherPackageNotNull { public static void foo(String s) {}}");
297     myFixture.addFileToProject("foo/package-info.java", "@javax.annotation.ParametersAreNonnullByDefault package foo;");
298     
299     doTest(); 
300   }
301
302   public static void addJavaxDefaultNullabilityAnnotations(final JavaCodeInsightTestFixture fixture) {
303     fixture.addClass("package javax.annotation;" +
304                      "@javax.annotation.meta.TypeQualifierDefault(java.lang.annotation.ElementType.PARAMETER) @javax.annotation.Nonnull " +
305                      "public @interface ParametersAreNonnullByDefault {}");
306     fixture.addClass("package javax.annotation;" +
307                      "@javax.annotation.meta.TypeQualifierDefault(java.lang.annotation.ElementType.PARAMETER) @javax.annotation.Nullable " +
308                      "public @interface ParametersAreNullableByDefault {}");
309   }
310
311   public static void addJavaxNullabilityAnnotations(final JavaCodeInsightTestFixture fixture) {
312     fixture.addClass("package javax.annotation;" +
313                      "public @interface Nonnull {}");
314     fixture.addClass("package javax.annotation;" +
315                      "public @interface Nullable {}");
316     fixture.addClass("package javax.annotation.meta;" +
317                      "public @interface TypeQualifierDefault { java.lang.annotation.ElementType[] value() default {};}");
318   }
319
320   public void testCustomTypeQualifierDefault() {
321     addJavaxNullabilityAnnotations(myFixture);
322     myFixture.addClass("package bar;" +
323                        "@javax.annotation.meta.TypeQualifierDefault(java.lang.annotation.ElementType.METHOD) @javax.annotation.Nonnull " +
324                        "public @interface MethodsAreNotNullByDefault {}");
325
326     myFixture.addClass("package foo; public class AnotherPackageNotNull { public static native Object foo(String s); }");
327     myFixture.addFileToProject("foo/package-info.java", "@bar.MethodsAreNotNullByDefault package foo;");
328
329     myFixture.enableInspections(new DataFlowInspection());
330     myFixture.testHighlighting(true, false, true, getTestName(false) + ".java");
331   }
332
333   public void testTrueOrEqualsSomething() {
334     doTest();
335     myFixture.launchAction(myFixture.findSingleIntention("Remove redundant assignment"));
336     myFixture.checkResultByFile(getTestName(false) + "_after.java");
337   }
338
339   public void testAssertThat() {
340     myFixture.addClass("package org.hamcrest; public class CoreMatchers { " +
341                        "public static <T> Matcher<T> notNullValue() {}\n" +
342                        "public static <T> Matcher<T> not(Matcher<T> matcher) {}\n" +
343                        "public static <T> Matcher<T> equalTo(T operand) {}\n" +
344                        "}");
345     myFixture.addClass("package org.hamcrest; public interface Matcher<T> {}");
346     myFixture.addClass("package org.junit; public class Assert { " +
347                        "public static <T> void assertThat(T actual, org.hamcrest.Matcher<? super T> matcher) {}\n" +
348                        "public static <T> void assertThat(String msg, T actual, org.hamcrest.Matcher<? super T> matcher) {}\n" +
349                        "}");
350     myFixture.enableInspections(new DataFlowInspection());
351     myFixture.testHighlighting(true, false, true, getTestName(false) + ".java");
352   }
353
354   public void testGuavaCheckNotNull() {
355     myFixture.addClass("package com.google.common.base; public class Preconditions { " +
356                        "public static <T> T checkNotNull(T reference) {}\n" +
357                        "}");
358     myFixture.enableInspections(new DataFlowInspection());
359     myFixture.testHighlighting(true, false, true, getTestName(false) + ".java");
360   }
361
362   public void _testNullCheckBeforeInstanceof() { doTest(); } // https://youtrack.jetbrains.com/issue/IDEA-113220
363 }