IDEA-166888 Report useless Stream or Optional intermediate operations

This commit is contained in:
Tagir Valeev
2017-01-20 11:32:48 +07:00
parent 7784656aeb
commit bf1f12619f
9 changed files with 432 additions and 4 deletions
@@ -0,0 +1,42 @@
import java.util.*;
import java.util.stream.*;
public class RedundantStreamOptionalCall {
public void test() {
List<Integer> list = Stream.of(1, 2, 3).<warning descr="Redundant 'sorted' call: subsequent 'sorted' call makes sorting useless">sorted(Comparator.reverseOrder())</warning>
.filter(x -> x > 0).sorted().collect(Collectors.toList());
if(Stream.of(1, 2, 3).<warning descr="Redundant 'sorted' call: subsequent 'allMatch' call makes sorting useless">sorted()</warning>.filter(x -> x > 0).allMatch(x -> x < 10)) {
return;
}
if(Stream.of("foo", "bar", "baz").<warning descr="Redundant 'sorted' call: subsequent 'count' call makes sorting useless">sorted(String.CASE_INSENSITIVE_ORDER)</warning>.count() > 0) {
return;
}
long first = Stream.of(1, 2, 3).distinct().sorted().skip(1).limit(2).<warning descr="Redundant 'distinct' call: there already was a 'distinct' call in the chain">distinct()</warning>
.findFirst().orElse(0);
Object[] objects = Stream.of(1, 2, 3).distinct().map(x -> x*2).distinct().toArray();
Object[] objects2 = Stream.of(1, 2, 3).distinct().<warning descr="Redundant 'filter' call: predicate is always true">filter(x -> true)</warning>.
<warning descr="Redundant 'distinct' call: there already was a 'distinct' call in the chain">distinct()</warning>.toArray();
Object xyz = Optional.of(123).<warning descr="Redundant 'map' call">map(integer -> Integer.valueOf(integer))</warning>.orElse(null);
Object xyz2 = Optional.of(123).<warning descr="Redundant 'map' call">map(Integer::valueOf)</warning>.orElse(null);
Object xyz3 = Optional.of(123).<warning descr="Redundant 'map' call">map(Integer::intValue)</warning>.orElse(null);
Object xyz4 = Optional.of(123).map(Integer::longValue).orElse(null);
Object xyz5 = IntStream.of(123).<warning descr="Redundant 'map' call">map(i -> Integer.valueOf(i))</warning>.count();
Object xyz6 = Stream.of(123).<warning descr="Redundant 'map' call">map(i -> Integer.valueOf(i))</warning>.count();
Optional.of(123).<warning descr="Redundant 'filter' call: predicate is always true">filter(x -> true)</warning>.ifPresent(System.out::println);
double avg = IntStream.range(0, 100).distinct()
.asLongStream().<warning descr="Redundant 'distinct' call: there already was a 'distinct' call in the chain">distinct()</warning>.average().orElse(0);
LongStream.range(0, 100).<warning descr="Redundant 'parallel' call: there's subsequent 'sequential' call which overrides this call">parallel()</warning>
.boxed().map(x -> x*2).sorted().sequential().forEach(System.out::println);
Stream.of(0, 100).map(x -> x*2).<warning descr="Redundant 'parallel' call: there's subsequent 'parallel' call which overrides this call">parallel()</warning>
.filter(x -> x > 0).sorted().parallel().forEach(System.out::println);
IntStream.of(0, 100).map(x -> x*2).<warning descr="Redundant 'sequential' call: there's subsequent 'sequential' call which overrides this call">sequential()</warning>
.filter(x -> x > 0).distinct().sequential().forEach(System.out::println);
Stream.of(0, 100).map(x -> x*2).<warning descr="Redundant 'sequential' call: there's subsequent 'parallel' call which overrides this call">sequential()</warning>
.filter(x -> x > 0).limit(10).parallel().forEach(System.out::println);
IntStream.range(0, 100).unordered().filter(x -> x > 50).<warning descr="Redundant 'unordered' call: there already was an 'unordered' call in the chain">unordered()</warning>.forEach(System.out::println);
IntStream.range(0, 100).unordered().filter(x -> x > 50).sorted().unordered().forEach(System.out::println);
}
}
@@ -0,0 +1,9 @@
// "Remove 'map' call" "true"
import java.util.stream.Stream;
public class Test {
public void test() {
/*redundant*/
System.out.println(Stream.of(/*just one number*/123).count());
}
}
@@ -0,0 +1,8 @@
// "Remove 'map' call" "true"
import java.util.stream.Stream;
public class Test {
public void test() {
System.out.println(Stream.of(/*just one number*/123).m<caret>ap((i) -> /*redundant*/ (i)).count());
}
}
@@ -0,0 +1,66 @@
/*
* Copyright 2000-2017 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 com.intellij.codeInspection;
import com.intellij.JavaTestUtil;
import com.intellij.codeInsight.daemon.quickFix.LightQuickFixParameterizedTestCase;
import com.intellij.testFramework.LightProjectDescriptor;
import com.siyeh.ig.LightInspectionTestCase;
import org.jetbrains.annotations.NotNull;
/**
* @author Tagir Valeev
*/
public class RedundantStreamOptionalCallInspectionTest extends LightInspectionTestCase {
public static final String TEST_DATA_DIR = "/inspection/redundantStreamOptionalCall/";
public void testRedundantStreamOptionalCall() {
doTest();
}
@Override
protected InspectionProfileEntry getInspection() {
return new RedundantStreamOptionalCallInspection();
}
@Override
protected String getBasePath() {
return JavaTestUtil.getRelativeJavaTestDataPath() + TEST_DATA_DIR;
}
@NotNull
@Override
protected LightProjectDescriptor getProjectDescriptor() {
return JAVA_8;
}
public static class RedundantStreamOptionalCallFixTest extends LightQuickFixParameterizedTestCase {
@NotNull
@Override
protected LocalInspectionTool[] configureLocalInspectionTools() {
return new LocalInspectionTool[]{new RedundantStreamOptionalCallInspection()};
}
public void test() throws Exception {
doAllTests();
}
@Override
protected String getBasePath() {
return TEST_DATA_DIR;
}
}
}