mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
FunctionHelper: fix renaming in lambdas if autogenerated name conflicts with the existing one
This commit is contained in:
@@ -34,7 +34,10 @@ import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
@@ -183,6 +186,14 @@ abstract class FunctionHelper {
|
||||
};
|
||||
}
|
||||
|
||||
static boolean hasVarReference(PsiExpression expression, String name, StreamToLoopReplacementContext context) {
|
||||
PsiLambdaExpression lambda = (PsiLambdaExpression)context.createExpression(name+"->"+expression.getText());
|
||||
PsiParameter var = lambda.getParameterList().getParameters()[0];
|
||||
PsiElement body = lambda.getBody();
|
||||
LOG.assertTrue(body != null);
|
||||
return ReferencesSearch.search(var, new LocalSearchScope(body)).findFirst() != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces all the references to the variable {@code name} in given expression with {@code replacement}.
|
||||
*
|
||||
@@ -480,22 +491,15 @@ abstract class FunctionHelper {
|
||||
}
|
||||
|
||||
void rename(String oldName, String newName, StreamToLoopReplacementContext context) {
|
||||
OptionalLong idx = StreamEx.of(myParameters).indexOf(newName);
|
||||
if(idx.isPresent()) {
|
||||
int idx = ArrayUtil.indexOf(myParameters, newName);
|
||||
if(idx >= 0) {
|
||||
// If new name collides with existing parameter, rename it
|
||||
for(int i = 1;; i++) {
|
||||
String paramName = newName+'$'+i;
|
||||
if (!paramName.equals(oldName) &&
|
||||
!StreamEx.of(myParameters).has(paramName)) {
|
||||
try {
|
||||
myBody = replaceVarReference(myBody, newName, paramName, context);
|
||||
myParameters[(int)idx.getAsLong()] = paramName;
|
||||
break;
|
||||
}
|
||||
catch(IllegalStateException ise) {
|
||||
// something is really wrong if we already have references to all newName$1, newName$2, ... newName$50
|
||||
// or probably IllegalStateException was thrown by something else: at least we don't stuck in endless loop
|
||||
if(i > 50) throw ise;
|
||||
}
|
||||
if (!paramName.equals(oldName) && !StreamEx.of(myParameters).has(paramName) && !hasVarReference(myBody, paramName, context)) {
|
||||
myBody = replaceVarReference(myBody, newName, paramName, context);
|
||||
myParameters[idx] = paramName;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
// "Replace Stream API chain with loop" "true"
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class Main {
|
||||
public List<? extends CharSequence> getList() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
private void collect() {
|
||||
List<CharSequence> list = new ArrayList<>();
|
||||
for (CharSequence charSequence : getList()) {
|
||||
if (Objects.nonNull(charSequence)) {
|
||||
list.add(charSequence);
|
||||
}
|
||||
}
|
||||
List<? extends CharSequence> res = list;
|
||||
System.out.println(res);
|
||||
}
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
// "Replace Stream API chain with loop" "true"
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class Main {
|
||||
public List<? extends CharSequence> getList() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
private void collect() {
|
||||
List<? extends CharSequence> res = getList().stream().filter(Objects::nonNull).col<caret>lect(Collectors.toList());
|
||||
System.out.println(res);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user