StreamToLoopInspection: simplify getEffectiveQualifier usage; support unqualified Iterable.forEach, Map.forEach

Review ID: IDEA-CR-46452

GitOrigin-RevId: 7622f0f1274d9f23bfaef88096b3eedd2b4d18a6
This commit is contained in:
Tagir Valeev
2019-04-24 12:36:57 +07:00
committed by intellij-monorepo-bot
parent 356b90a3ce
commit 9af3284048
6 changed files with 48 additions and 15 deletions

View File

@@ -83,9 +83,11 @@ abstract class SourceOperation extends Operation {
return fn == null ? null : new IterateSource(args[0], fn);
}
if (name.equals("stream") && args.length == 0 &&
InheritanceUtil.isInheritor(aClass, CommonClassNames.JAVA_UTIL_COLLECTION) &&
ExpressionUtils.getEffectiveQualifier(call.getMethodExpression()) != null) {
return new ForEachSource(call.getMethodExpression().getQualifierExpression());
InheritanceUtil.isInheritor(aClass, CommonClassNames.JAVA_UTIL_COLLECTION)) {
PsiExpression qualifier = ExpressionUtils.getEffectiveQualifier(call.getMethodExpression());
if (qualifier != null) {
return new ForEachSource(qualifier);
}
}
if (name.equals("stream") && args.length == 1 &&
CommonClassNames.JAVA_UTIL_ARRAYS.equals(className)) {
@@ -110,22 +112,20 @@ abstract class SourceOperation extends Operation {
static class ForEachSource extends SourceOperation {
private final boolean myEntrySet;
private @Nullable PsiExpression myQualifier;
private @NotNull PsiExpression myQualifier;
ForEachSource(@Nullable PsiExpression qualifier) {
ForEachSource(@NotNull PsiExpression qualifier) {
this(qualifier, false);
}
ForEachSource(@Nullable PsiExpression qualifier, boolean entrySet) {
ForEachSource(@NotNull PsiExpression qualifier, boolean entrySet) {
myQualifier = qualifier;
myEntrySet = entrySet;
}
@Override
void rename(String oldName, String newName, StreamToLoopReplacementContext context) {
if(myQualifier != null) {
myQualifier = replaceVarReference(myQualifier, oldName, newName, context);
}
myQualifier = replaceVarReference(myQualifier, oldName, newName, context);
}
@Override
@@ -148,10 +148,7 @@ abstract class SourceOperation extends Operation {
@Override
public String wrap(StreamVariable outVar, String code, StreamToLoopReplacementContext context) {
PsiExpression iterationParameter = myQualifier == null ? ExpressionUtils
.getEffectiveQualifier(((PsiMethodCallExpression)context.createExpression("stream()")).getMethodExpression()) : myQualifier;
assert iterationParameter != null; // Checked at construction site that effective qualifier is available
String iterationParameterText = iterationParameter.getText() + (myEntrySet ? ".entrySet()" : "");
String iterationParameterText = myQualifier.getText() + (myEntrySet ? ".entrySet()" : "");
return context.getLoopLabel() + "for(" + outVar.getDeclaration() + ": " + iterationParameterText + ") {" + code + "}\n";
}
}

View File

@@ -142,7 +142,7 @@ public class StreamToLoopInspection extends AbstractBaseJavaLocalInspectionTool
@Nullable
static List<OperationRecord> extractIterableForEach(PsiMethodCallExpression terminalCall) {
if (!ITERABLE_FOREACH.test(terminalCall) || !ExpressionUtils.isVoidContext(terminalCall)) return null;
PsiExpression qualifier = terminalCall.getMethodExpression().getQualifierExpression();
PsiExpression qualifier = ExpressionUtils.getEffectiveQualifier(terminalCall.getMethodExpression());
if (qualifier == null) return null;
// Do not visit this path if some class implements both Iterable and Stream
PsiType type = qualifier.getType();
@@ -167,7 +167,7 @@ public class StreamToLoopInspection extends AbstractBaseJavaLocalInspectionTool
@Nullable
static List<OperationRecord> extractMapForEach(PsiMethodCallExpression terminalCall) {
if (!MAP_FOREACH.test(terminalCall) || !ExpressionUtils.isVoidContext(terminalCall)) return null;
PsiExpression qualifier = terminalCall.getMethodExpression().getQualifierExpression();
PsiExpression qualifier = ExpressionUtils.getEffectiveQualifier(terminalCall.getMethodExpression());
if (qualifier == null) return null;
// Do not visit this path if some class implements both Map and Stream
PsiType type = qualifier.getType();

View File

@@ -43,4 +43,14 @@ public class Main {
interface Visitor { }
}
class X implements Iterable<String> {
class Y {
void test() {
for (String s : X.this) {
System.out.println(s);
}
}
}
}
}

View File

@@ -31,4 +31,15 @@ public class Main {
}
}
class X implements Map<String, String> {
class Y {
void test() {
for (Entry<String, String> entry : X.this.entrySet()) {
String k = entry.getKey();
String v = entry.getValue();
System.out.println(k + "-" + v);
}
}
}
}
}

View File

@@ -33,4 +33,12 @@ public class Main {
interface Visitor { }
}
class X implements Iterable<String> {
class Y {
void test() {
forEach(System.out::println);
}
}
}
}

View File

@@ -21,4 +21,11 @@ public class Main {
map.forEach(otherMap::putIfAbsent);
}
class X implements Map<String, String> {
class Y {
void test() {
forEach((k, v) -> System.out.println(k + "-" + v));
}
}
}
}