mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-04-19 13:02:30 +07:00
IDEA-168967 Intention to extract local variable created in stream operation lambda to separate stream step.
This commit is contained in:
@@ -0,0 +1,172 @@
|
||||
/*
|
||||
* 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.codeInsight.intention.impl;
|
||||
|
||||
import com.intellij.codeInsight.intention.PsiElementBaseIntentionAction;
|
||||
import com.intellij.codeInspection.LambdaCanBeMethodReferenceInspection;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.searches.ReferencesSearch;
|
||||
import com.intellij.psi.util.InheritanceUtil;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.refactoring.util.LambdaRefactoringUtil;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.Processor;
|
||||
import com.siyeh.ig.psiutils.ExpressionUtils;
|
||||
import com.siyeh.ig.psiutils.StreamApiUtil;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import static com.intellij.util.ObjectUtils.tryCast;
|
||||
|
||||
/**
|
||||
* @author Tagir Valeev
|
||||
*/
|
||||
public class ExtractStreamMapAction extends PsiElementBaseIntentionAction {
|
||||
@Override
|
||||
public boolean isAvailable(@NotNull Project project, Editor editor, @NotNull PsiElement element) {
|
||||
PsiLocalVariable variable =
|
||||
PsiTreeUtil.getParentOfType(element, PsiLocalVariable.class, false, PsiStatement.class, PsiLambdaExpression.class);
|
||||
if (!isApplicable(variable)) return false;
|
||||
setText("Extract variable '" + Objects.requireNonNull(variable.getName()) + "' to separate stream step");
|
||||
return true;
|
||||
}
|
||||
|
||||
@Contract("null -> false")
|
||||
private static boolean isApplicable(PsiLocalVariable variable) {
|
||||
if (variable == null || variable.getName() == null) return false;
|
||||
if (!StreamApiUtil.isSupportedStreamElement(variable.getType())) return false;
|
||||
PsiExpression initializer = variable.getInitializer();
|
||||
if (initializer == null) return false;
|
||||
PsiDeclarationStatement declaration = tryCast(variable.getParent(), PsiDeclarationStatement.class);
|
||||
if (declaration == null || declaration.getDeclaredElements().length != 1) return false;
|
||||
PsiCodeBlock block = tryCast(declaration.getParent(), PsiCodeBlock.class);
|
||||
if (block == null) return false;
|
||||
PsiLambdaExpression lambda = tryCast(block.getParent(), PsiLambdaExpression.class);
|
||||
if (lambda == null) return false;
|
||||
PsiParameterList parameters = lambda.getParameterList();
|
||||
if (parameters.getParametersCount() != 1) return false;
|
||||
PsiExpressionList args = tryCast(lambda.getParent(), PsiExpressionList.class);
|
||||
if (args == null || args.getExpressions().length != 1) return false;
|
||||
PsiMethodCallExpression call = tryCast(args.getParent(), PsiMethodCallExpression.class);
|
||||
if (call == null ||
|
||||
!InlineStreamMapAction.NEXT_METHODS.contains(call.getMethodExpression().getReferenceName()) ||
|
||||
call.getMethodExpression().getQualifierExpression() == null) {
|
||||
return false;
|
||||
}
|
||||
PsiMethod method = call.resolveMethod();
|
||||
if (method == null ||
|
||||
method.getParameterList().getParametersCount() != 1 ||
|
||||
!InheritanceUtil.isInheritor(method.getContainingClass(), CommonClassNames.JAVA_UTIL_STREAM_BASE_STREAM)) {
|
||||
return false;
|
||||
}
|
||||
PsiParameter parameter = parameters.getParameters()[0];
|
||||
if (ExpressionUtils.isReferenceTo(initializer, parameter) && parameter.getType().equals(variable.getType())) {
|
||||
// If conversion is applied in this case, then extracted previous step will be silently removed.
|
||||
// While this is correct, it may confuse the user. Having "Local variable is redundant" warning with "inline" fix is enough here.
|
||||
return false;
|
||||
}
|
||||
if (method.getName().startsWith("flatMap")) {
|
||||
PsiType outType = StreamApiUtil.getStreamElementType(call.getType());
|
||||
// flatMap from primitive type works only if the stream element type matches
|
||||
if (variable.getType() instanceof PsiPrimitiveType && !variable.getType().equals(outType)) return false;
|
||||
}
|
||||
return ReferencesSearch.search(parameter).forEach(
|
||||
(Processor<PsiReference>)ref -> PsiTreeUtil.isAncestor(initializer, ref.getElement(), false));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invoke(@NotNull Project project, Editor editor, @NotNull PsiElement element) throws IncorrectOperationException {
|
||||
PsiLocalVariable variable =
|
||||
PsiTreeUtil.getParentOfType(element, PsiLocalVariable.class, false, PsiStatement.class, PsiLambdaExpression.class);
|
||||
if (variable == null) return;
|
||||
String name = variable.getName();
|
||||
if (name == null) return;
|
||||
PsiExpression initializer = variable.getInitializer();
|
||||
if (initializer == null) return;
|
||||
PsiLambdaExpression lambda = PsiTreeUtil.getParentOfType(variable, PsiLambdaExpression.class);
|
||||
if (lambda == null) return;
|
||||
PsiMethodCallExpression call = PsiTreeUtil.getParentOfType(lambda, PsiMethodCallExpression.class);
|
||||
if (call == null) return;
|
||||
PsiExpression qualifier = call.getMethodExpression().getQualifierExpression();
|
||||
if (qualifier == null) return;
|
||||
String methodName = call.getMethodExpression().getReferenceName();
|
||||
if (methodName == null) return;
|
||||
PsiParameter parameter = ArrayUtil.getFirstElement(lambda.getParameterList().getParameters());
|
||||
if (parameter == null) return;
|
||||
PsiType outType = StreamApiUtil.getStreamElementType(call.getType(), false);
|
||||
|
||||
String mapOperation = StreamApiUtil.generateMapOperation(parameter, variable.getType(), initializer);
|
||||
PsiElementFactory factory = JavaPsiFacade.getElementFactory(project);
|
||||
if (!mapOperation.isEmpty()) {
|
||||
qualifier = (PsiExpression)qualifier.replace(factory.createExpressionFromText(qualifier.getText() + mapOperation, qualifier));
|
||||
}
|
||||
parameter = (PsiParameter)parameter.replace(factory.createParameter(variable.getName(), variable.getType(), parameter));
|
||||
variable.delete();
|
||||
LambdaRefactoringUtil.simplifyToExpressionLambda(lambda);
|
||||
if (methodName.startsWith("map")) {
|
||||
String replacement = StreamApiUtil.generateMapOperation(parameter, outType, lambda.getBody());
|
||||
if (!replacement.isEmpty()) {
|
||||
call = (PsiMethodCallExpression)call.replace(factory.createExpressionFromText(qualifier.getText() + replacement, call));
|
||||
qualifier = call.getMethodExpression().getQualifierExpression();
|
||||
}
|
||||
else {
|
||||
qualifier = (PsiExpression)call.replace(qualifier);
|
||||
}
|
||||
}
|
||||
else {
|
||||
PsiTypeElement typeElement = parameter.getTypeElement();
|
||||
if (typeElement != null) {
|
||||
if (methodName.startsWith("flatMap")) {
|
||||
String targetName = "flatMap";
|
||||
if (!(typeElement.getType() instanceof PsiPrimitiveType)) {
|
||||
if (PsiType.INT.equals(outType)) {
|
||||
targetName = "flatMapToInt";
|
||||
}
|
||||
else if (PsiType.LONG.equals(outType)) {
|
||||
targetName = "flatMapToLong";
|
||||
}
|
||||
else if (PsiType.DOUBLE.equals(outType)) {
|
||||
targetName = "flatMapToDouble";
|
||||
}
|
||||
}
|
||||
ExpressionUtils.bindCallTo(call, targetName);
|
||||
}
|
||||
typeElement.delete();
|
||||
}
|
||||
}
|
||||
if (qualifier instanceof PsiMethodCallExpression) {
|
||||
PsiLambdaExpression newLambda =
|
||||
tryCast(ArrayUtil.getFirstElement(((PsiMethodCallExpression)qualifier).getArgumentList().getExpressions()),
|
||||
PsiLambdaExpression.class);
|
||||
if (newLambda != null) {
|
||||
LambdaCanBeMethodReferenceInspection.replaceLambdaWithMethodReference(newLambda);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nls
|
||||
@NotNull
|
||||
@Override
|
||||
public String getFamilyName() {
|
||||
return "Extract to separate stream step";
|
||||
}
|
||||
}
|
||||
@@ -45,7 +45,7 @@ public class InlineStreamMapAction extends PsiElementBaseIntentionAction {
|
||||
private static final Set<String> MAP_METHODS =
|
||||
StreamEx.of("map", "mapToInt", "mapToLong", "mapToDouble", "mapToObj", "boxed", "asLongStream", "asDoubleStream").toSet();
|
||||
|
||||
private static final Set<String> NEXT_METHODS = StreamEx
|
||||
static final Set<String> NEXT_METHODS = StreamEx
|
||||
.of("flatMap", "flatMapToInt", "flatMapToLong", "flatMapToDouble", "forEach", "forEachOrdered", "anyMatch", "noneMatch", "allMatch")
|
||||
.append(MAP_METHODS).toSet();
|
||||
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
// "Extract variable 'lowerCase' to separate stream step" "true"
|
||||
import java.util.*;
|
||||
import java.util.stream.*;
|
||||
|
||||
public class Test {
|
||||
boolean test(List<String> list) {
|
||||
return list.stream().map(String::toLowerCase)
|
||||
.anyMatch(lowerCase -> "test".equals(lowerCase));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
// "Extract variable 'arr' to separate stream step" "true"
|
||||
import java.util.*;
|
||||
import java.util.stream.*;
|
||||
|
||||
public class Test {
|
||||
String testArrayInitializer() {
|
||||
return LongStream.of(1, 2, 3).mapToObj(x -> new long[]{x}).map(arr -> Arrays.toString(arr)).collect(Collectors.joining(","));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
// "Extract variable 'l' to separate stream step" "true"
|
||||
import java.util.*;
|
||||
import java.util.stream.*;
|
||||
|
||||
public class Test {
|
||||
long[] testAsLongStream(int[] x) {
|
||||
return Arrays.stream(x).map(i -> i * 2).asLongStream().toArray();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
// "Extract variable 'l' to separate stream step" "true"
|
||||
import java.util.*;
|
||||
import java.util.stream.*;
|
||||
|
||||
public class Test {
|
||||
Object[] testBoxed(int[] x) {
|
||||
return Arrays.stream(x).asLongStream().boxed().toArray();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
// "Extract variable 'y' to separate stream step" "true"
|
||||
import java.util.*;
|
||||
import java.util.stream.*;
|
||||
|
||||
public class Test {
|
||||
void testFlatMap() {
|
||||
Stream.of("xyz").mapToInt(String::length).flatMap(y -> IntStream.range(0, y)).forEach(System.out::println);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
// "Extract variable 'y' to separate stream step" "true"
|
||||
import java.util.*;
|
||||
import java.util.stream.*;
|
||||
|
||||
public class Test {
|
||||
void testFlatMap() {
|
||||
Stream.of("xyz").map(String::length).flatMapToInt(y -> IntStream.range(0, y)).forEach(System.out::println);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
// "Extract variable 's' to separate stream step" "true"
|
||||
import java.util.*;
|
||||
import java.util.stream.*;
|
||||
|
||||
public class Test {
|
||||
void testFlatMap() {
|
||||
IntStream.of(1, 2, 3).mapToObj(String::valueOf).flatMapToInt(s -> IntStream.range(0, s.length())).forEach(System.out::println);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
// "Extract variable 'i' to separate stream step" "true"
|
||||
import java.util.*;
|
||||
import java.util.stream.*;
|
||||
|
||||
public class Test {
|
||||
void test2(List<String> list) {
|
||||
list.stream().mapToInt(String::length).forEach(i -> System.out.println(i));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
// "Extract variable 'fn' to separate stream step" "true"
|
||||
import java.util.*;
|
||||
import java.util.function.*;
|
||||
import java.util.stream.*;
|
||||
|
||||
public class Test {
|
||||
void testFunction() {
|
||||
Stream.of("a", "b", "c").<Supplier<String>>map(x -> x::trim).map(fn -> fn.get()).forEach(System.out::println);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
// "Extract variable 'set' to separate stream step" "true"
|
||||
import java.util.*;
|
||||
import java.util.stream.*;
|
||||
|
||||
public class Test {
|
||||
void testMap(List<Map<String, String>> list) {
|
||||
list.stream().map(Map::keySet).flatMap(set -> set.stream()).forEach(System.out::println);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
// "Extract variable 'y' to separate stream step" "true"
|
||||
import java.util.*;
|
||||
import java.util.stream.*;
|
||||
|
||||
public class Test {
|
||||
void testRemoveMap() {
|
||||
Stream.of("xyz").map(x -> x + x).forEach(System.out::println);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
// "Extract variable 'l' to separate stream step" "true"
|
||||
import java.util.*;
|
||||
import java.util.stream.*;
|
||||
|
||||
public class Test {
|
||||
long[] testMapRename(int[] x) {
|
||||
return Arrays.stream(x).asLongStream().map(l -> l * l).toArray();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
// "Extract variable 'lowerCase' to separate stream step" "true"
|
||||
import java.util.*;
|
||||
import java.util.stream.*;
|
||||
|
||||
public class Test {
|
||||
boolean test(List<String> list) {
|
||||
return list.stream()
|
||||
.anyMatch(s -> {
|
||||
String <caret>lowerCase = s.toLowerCase();
|
||||
return "test".equals(lowerCase);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
// "Extract variable 'lowerCase' to separate stream step" "false"
|
||||
import java.util.*;
|
||||
import java.util.stream.*;
|
||||
|
||||
public class Test {
|
||||
boolean testWrong(List<String> list) {
|
||||
return list.stream()
|
||||
.anyMatch(s -> {
|
||||
String <caret>lowerCase = s.toLowerCase();
|
||||
return lowerCase.equals(s);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
// "Extract variable 'arr' to separate stream step" "true"
|
||||
import java.util.*;
|
||||
import java.util.stream.*;
|
||||
|
||||
public class Test {
|
||||
String testArrayInitializer() {
|
||||
return LongStream.of(1,2,3).mapToObj(x -> {
|
||||
long[] <caret>arr = {x};
|
||||
return Arrays.toString(arr);
|
||||
}).collect(Collectors.joining(","));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
// "Extract variable 'l' to separate stream step" "true"
|
||||
import java.util.*;
|
||||
import java.util.stream.*;
|
||||
|
||||
public class Test {
|
||||
long[] testAsLongStream(int[] x) {
|
||||
return Arrays.stream(x).mapToLong(i -> {
|
||||
int <caret>l = i * 2;
|
||||
return l;
|
||||
}).toArray();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
// "Extract variable 'l' to separate stream step" "true"
|
||||
import java.util.*;
|
||||
import java.util.stream.*;
|
||||
|
||||
public class Test {
|
||||
Object[] testBoxed(int[] x) {
|
||||
return Arrays.stream(x).mapToObj(i -> {
|
||||
long <caret>l = i;
|
||||
return l;
|
||||
}).toArray();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
// "Extract variable 'y' to separate stream step" "true"
|
||||
import java.util.*;
|
||||
import java.util.stream.*;
|
||||
|
||||
public class Test {
|
||||
void testFlatMap() {
|
||||
Stream.of("xyz").flatMapToInt(x -> {
|
||||
int <caret>y = x.length();
|
||||
return IntStream.range(0, y);
|
||||
}).forEach(System.out::println);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
// "Extract variable 'y' to separate stream step" "false"
|
||||
import java.util.*;
|
||||
import java.util.stream.*;
|
||||
|
||||
public class Test {
|
||||
void testFlatMap() {
|
||||
// no direct method which would flatMap from long to int type, so intention is disabled here
|
||||
Stream.of("xyz").flatMapToInt(x -> {
|
||||
long <caret>y = x.length();
|
||||
return IntStream.range(0, (int) y);
|
||||
}).forEach(System.out::println);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
// "Extract variable 'y' to separate stream step" "true"
|
||||
import java.util.*;
|
||||
import java.util.stream.*;
|
||||
|
||||
public class Test {
|
||||
void testFlatMap() {
|
||||
Stream.of("xyz").flatMapToInt(x -> {
|
||||
Integer <caret>y = x.length();
|
||||
return IntStream.range(0, y);
|
||||
}).forEach(System.out::println);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
// "Extract variable 's' to separate stream step" "true"
|
||||
import java.util.*;
|
||||
import java.util.stream.*;
|
||||
|
||||
public class Test {
|
||||
void testFlatMap() {
|
||||
IntStream.of(1, 2, 3).flatMap(x -> {
|
||||
String <caret>s = String.valueOf(x);
|
||||
return IntStream.range(0, s.length());
|
||||
}).forEach(System.out::println);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
// "Extract variable 'i' to separate stream step" "true"
|
||||
import java.util.*;
|
||||
import java.util.stream.*;
|
||||
|
||||
public class Test {
|
||||
void test2(List<String> list) {
|
||||
list.stream().forEach(s -> {
|
||||
int <caret>i = s.length();
|
||||
System.out.println(i);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
// "Extract variable 'i' to separate stream step" "false"
|
||||
import java.util.*;
|
||||
import java.util.stream.*;
|
||||
|
||||
public class Test {
|
||||
void test2(List<String> list) {
|
||||
list.stream().forEach(s -> {
|
||||
float <caret>i = s.length();
|
||||
System.out.println(i);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
// "Extract variable 'fn' to separate stream step" "true"
|
||||
import java.util.*;
|
||||
import java.util.function.*;
|
||||
import java.util.stream.*;
|
||||
|
||||
public class Test {
|
||||
void testFunction() {
|
||||
Stream.of("a", "b", "c").map(x -> {
|
||||
Supplier<String> <caret>fn = x::trim;
|
||||
return fn.get();
|
||||
}).forEach(System.out::println);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
// "Extract variable 'set' to separate stream step" "true"
|
||||
import java.util.*;
|
||||
import java.util.stream.*;
|
||||
|
||||
public class Test {
|
||||
void testMap(List<Map<String, String>> list) {
|
||||
list.stream().flatMap(map -> {
|
||||
Set<String> <caret>set = map.keySet();
|
||||
return set.stream();
|
||||
}).forEach(System.out::println);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
// "Extract variable 'y' to separate stream step" "true"
|
||||
import java.util.*;
|
||||
import java.util.stream.*;
|
||||
|
||||
public class Test {
|
||||
void testRemoveMap() {
|
||||
Stream.of("xyz").map(x -> {
|
||||
String <caret>y = x+x;
|
||||
return y;
|
||||
}).forEach(System.out::println);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
// "Extract variable 'l' to separate stream step" "true"
|
||||
import java.util.*;
|
||||
import java.util.stream.*;
|
||||
|
||||
public class Test {
|
||||
long[] testMapRename(int[] x) {
|
||||
return Arrays.stream(x).mapToLong(i -> {
|
||||
long <caret>l = i;
|
||||
return l * l;
|
||||
}).toArray();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* 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.codeInsight.intention;
|
||||
|
||||
import com.intellij.codeInsight.daemon.LightIntentionActionTestCase;
|
||||
|
||||
public class ExtractStreamMapActionTest extends LightIntentionActionTestCase {
|
||||
|
||||
public void test() throws Exception { doAllTests(); }
|
||||
|
||||
@Override
|
||||
protected String getBasePath() {
|
||||
return "/codeInsight/daemonCodeAnalyzer/quickFix/extractStreamMap";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
import java.util.List;
|
||||
|
||||
public class X {
|
||||
boolean test(List<String> list) {
|
||||
return list.stream()<spot>.map(String::toLowerCase)</spot>.anyMatch(lower -> lower.equals("test"));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
import java.util.List;
|
||||
|
||||
public class X {
|
||||
boolean test(List<String> list) {
|
||||
return list.stream().anyMatch(s -> {
|
||||
<spot>String lower = s.toLowerCase();</spot>
|
||||
return lower.equals("test");
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
<html>
|
||||
<body>
|
||||
This intention extracts the variable declared inside lambda operation to the separate mapping step using Stream.map() or similar operation.
|
||||
</body>
|
||||
</html>
|
||||
@@ -938,6 +938,10 @@
|
||||
<className>com.intellij.codeInsight.intention.impl.InlineStreamMapAction</className>
|
||||
<category>Java/Streams</category>
|
||||
</intentionAction>
|
||||
<intentionAction>
|
||||
<className>com.intellij.codeInsight.intention.impl.ExtractStreamMapAction</className>
|
||||
<category>Java/Streams</category>
|
||||
</intentionAction>
|
||||
<intentionAction>
|
||||
<className>com.intellij.codeInsight.intention.impl.ComposeFunctionChainAction</className>
|
||||
<category>Java/Refactorings</category>
|
||||
|
||||
Reference in New Issue
Block a user