mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
add nested stream filter recognition
This commit is contained in:
+17
-10
@@ -743,30 +743,33 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo
|
||||
}
|
||||
}
|
||||
|
||||
static class CompoundFilterOp extends FilterOp {
|
||||
private final FlatMapOp myFlatMapOp;
|
||||
static class CompoundFilterOp extends FilterOp {
|
||||
private final PsiExpression myMatchExpression;
|
||||
private final StreamSource mySource;
|
||||
private final PsiVariable myMatchVariable;
|
||||
|
||||
CompoundFilterOp(FilterOp source, FlatMapOp flatMapOp) {
|
||||
super(source.getExpression(), flatMapOp.myVariable, source.myNegated);
|
||||
myMatchVariable = source.myVariable;
|
||||
myFlatMapOp = flatMapOp;
|
||||
protected CompoundFilterOp(StreamSource source, PsiVariable matchVariable, FilterOp sourceFilter) {
|
||||
super(sourceFilter.getExpression(), matchVariable, sourceFilter.isNegated());
|
||||
myMatchExpression = sourceFilter.getExpression();
|
||||
mySource = source;
|
||||
myMatchVariable = sourceFilter.getVariable();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
PsiExpression makeIntermediateExpression(PsiElementFactory factory) {
|
||||
return factory.createExpressionFromText(myFlatMapOp.getStreamExpression() + ".anyMatch(" +
|
||||
LambdaUtil.createLambda(myMatchVariable, myExpression) + ")", myExpression);
|
||||
return factory.createExpressionFromText(mySource.createReplacement() + ".anyMatch(" +
|
||||
LambdaUtil.createLambda(myMatchVariable, myMatchExpression) + ")", myMatchExpression);
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean isWriteAllowed(PsiVariable variable, PsiExpression reference) {
|
||||
return myFlatMapOp.isWriteAllowed(variable, reference);
|
||||
return mySource.isWriteAllowed(variable, reference);
|
||||
}
|
||||
|
||||
@Override
|
||||
StreamEx<PsiExpression> expressions() {
|
||||
return StreamEx.of(myExpression, myFlatMapOp.myExpression);
|
||||
return StreamEx.of(myMatchExpression, mySource.getExpression());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -820,6 +823,10 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo
|
||||
return "." + operation + "(" + lambda + ")";
|
||||
}
|
||||
|
||||
public StreamSource getSource() {
|
||||
return mySource;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
String getStreamExpression() {
|
||||
return mySource.createReplacement();
|
||||
|
||||
@@ -113,8 +113,9 @@ class TerminalBlock {
|
||||
|
||||
@Nullable
|
||||
private TerminalBlock extractFilter() {
|
||||
if(getSingleStatement() instanceof PsiIfStatement) {
|
||||
PsiIfStatement ifStatement = (PsiIfStatement)getSingleStatement();
|
||||
PsiStatement single = getSingleStatement();
|
||||
if (single instanceof PsiIfStatement) {
|
||||
PsiIfStatement ifStatement = (PsiIfStatement)single;
|
||||
if(ifStatement.getElseBranch() == null && ifStatement.getCondition() != null) {
|
||||
PsiStatement thenBranch = ifStatement.getThenBranch();
|
||||
if(thenBranch != null) {
|
||||
@@ -122,6 +123,27 @@ class TerminalBlock {
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (single instanceof PsiLoopStatement) {
|
||||
// Try extract nested filter like this:
|
||||
// for(List subList : list) for(T t : subList) if(condition.test(t)) { ...; break; }
|
||||
// if t is not used in "...", then this could be converted to
|
||||
// list.stream().filter(subList -> subList.stream().anyMatch(condition)).forEach(subList -> ...)
|
||||
PsiLoopStatement loopStatement = (PsiLoopStatement)single;
|
||||
StreamSource source = StreamSource.tryCreate(loopStatement);
|
||||
final PsiStatement body = loopStatement.getBody();
|
||||
if (source == null || body == null) return null;
|
||||
TerminalBlock innerTb = from(source, body);
|
||||
FilterOp innerFilter = innerTb.getLastOperation(FilterOp.class);
|
||||
if (innerFilter == null) return null;
|
||||
if (!VariableAccessUtils.variableIsUsed(myVariable, body)) return null;
|
||||
PsiStatement[] statements = innerTb.getStatements();
|
||||
PsiStatement lastStatement = statements[statements.length - 1];
|
||||
PsiReturnStatement returnStatement = tryCast(lastStatement, PsiReturnStatement.class);
|
||||
if (returnStatement == null) return null;
|
||||
if (!ExpressionUtils.isReferenceTo(returnStatement.getReturnValue(), getVariable())) return null;
|
||||
return new TerminalBlock(this, new CompoundFilterOp(source, myVariable, innerFilter),
|
||||
myVariable, statements);
|
||||
}
|
||||
if(myStatements.length >= 1) {
|
||||
PsiStatement first = myStatements[0];
|
||||
// extract filter with negation
|
||||
@@ -179,7 +201,8 @@ class TerminalBlock {
|
||||
PsiStatement lastStatement = statements[statements.length-1];
|
||||
if (lastStatement instanceof PsiBreakStatement && op.breaksMe((PsiBreakStatement)lastStatement) &&
|
||||
ReferencesSearch.search(withFlatMapFilter.getVariable(), new LocalSearchScope(statements)).findFirst() == null) {
|
||||
return new TerminalBlock(this, new CompoundFilterOp((FilterOp)withFlatMapFilter.getLastOperation(), op),
|
||||
FilterOp filterOp = (FilterOp)withFlatMapFilter.getLastOperation();
|
||||
return new TerminalBlock(this, new CompoundFilterOp(op.getSource(), op.getVariable(), filterOp),
|
||||
myVariable, Arrays.copyOfRange(statements, 0, statements.length-1));
|
||||
}
|
||||
}
|
||||
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
// "Replace with findFirst()" "true"
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class Main {
|
||||
class MappedField{
|
||||
List<MappedField> getLoadNames(){return null;}
|
||||
}
|
||||
|
||||
public MappedField getMappedField(final String storedName) {
|
||||
List<MappedField> persistenceFields = new ArrayList<>();
|
||||
return persistenceFields.stream().filter(mf -> mf.getLoadNames().stream().anyMatch(storedName::equals)).findFirst().orElse(null);
|
||||
}
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
// "Replace with findFirst()" "true"
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class Main {
|
||||
class MappedField{
|
||||
List<MappedField> getLoadNames(){return null;}
|
||||
}
|
||||
|
||||
public MappedField getMappedField(final String storedName) {
|
||||
List<MappedField> persistenceFields = new ArrayList<>();
|
||||
for<caret> (final MappedField mf : persistenceFields) {
|
||||
for (final String n : mf.getLoadNames()) {
|
||||
if (storedName.equals(n)) {
|
||||
return mf;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user