Condition -> ConditionalExpression (IDEA-CR-16701)

This commit is contained in:
Tagir Valeev
2016-12-14 12:53:23 +07:00
parent 0c0839a28f
commit c42b7d81cf
3 changed files with 32 additions and 31 deletions
@@ -23,7 +23,7 @@ import com.intellij.psi.util.TypeConversionUtil;
*
* @author Tagir Valeev
*/
interface Condition {
interface ConditionalExpression {
String getType();
String getCondition();
@@ -36,7 +36,7 @@ interface Condition {
return getCondition() + "?" + getTrueBranch() + ":" + getFalseBranch();
}
class Plain implements Condition {
class Plain implements ConditionalExpression {
private final String myType;
private final String myCondition;
private final String myTrueBranch;
@@ -66,7 +66,7 @@ interface Condition {
}
}
class Boolean implements Condition {
class Boolean implements ConditionalExpression {
private String myCondition;
private boolean myInvert;
@@ -110,7 +110,7 @@ interface Condition {
}
}
class Optional implements Condition {
class Optional implements ConditionalExpression {
private final String myType;
private final String myCondition;
private final String myPresentExpression;
@@ -460,27 +460,27 @@ public class StreamToLoopInspection extends BaseJavaBatchLocalInspectionTool {
myFinisher = finisher;
}
public void setFinisher(Condition condition) {
if(condition instanceof Condition.Optional) {
condition = tryUnwrapOptional((Condition.Optional)condition, expr -> true);
public void setFinisher(ConditionalExpression conditionalExpression) {
if(conditionalExpression instanceof ConditionalExpression.Optional) {
conditionalExpression = tryUnwrapOptional((ConditionalExpression.Optional)conditionalExpression, expr -> true);
}
setFinisher(condition.asExpression());
setFinisher(conditionalExpression.asExpression());
}
public String assignAndBreak(Condition condition) {
public String assignAndBreak(ConditionalExpression conditionalExpression) {
Predicate<PsiElement> predicate = expr -> PsiUtil.skipParenthesizedExprUp(expr.getParent()) instanceof PsiReturnStatement;
if(condition instanceof Condition.Optional) {
condition = tryUnwrapOptional((Condition.Optional)condition, predicate);
if(conditionalExpression instanceof ConditionalExpression.Optional) {
conditionalExpression = tryUnwrapOptional((ConditionalExpression.Optional)conditionalExpression, predicate);
}
if(condition instanceof Condition.Boolean) {
condition = tryUnwrapBoolean((Condition.Boolean)condition);
if(conditionalExpression instanceof ConditionalExpression.Boolean) {
conditionalExpression = tryUnwrapBoolean((ConditionalExpression.Boolean)conditionalExpression);
}
if(predicate.test(myPlaceholder)) {
setFinisher(condition.getFalseBranch());
return "return "+condition.getTrueBranch()+";";
setFinisher(conditionalExpression.getFalseBranch());
return "return " + conditionalExpression.getTrueBranch() + ";";
}
PsiElement parent = PsiUtil.skipParenthesizedExprUp(myPlaceholder.getParent());
if(parent instanceof PsiIfStatement && condition.getTrueBranch().equals(String.valueOf(true))) {
if(parent instanceof PsiIfStatement && conditionalExpression.getTrueBranch().equals(String.valueOf(true))) {
PsiIfStatement ifStatement = (PsiIfStatement)parent;
if(ifStatement.getElseBranch() == null) {
PsiStatement thenStatement = ControlFlowUtils.stripBraces(ifStatement.getThenBranch());
@@ -494,25 +494,26 @@ public class StreamToLoopInspection extends BaseJavaBatchLocalInspectionTool {
}
}
}
if(condition instanceof Condition.Optional && myPlaceholder instanceof PsiExpression) {
if(conditionalExpression instanceof ConditionalExpression.Optional && myPlaceholder instanceof PsiExpression) {
PsiMethodCallExpression call = ExpressionUtils.getCallForQualifier((PsiExpression)myPlaceholder);
if(call != null && call.getParent() instanceof PsiExpressionStatement) {
PsiExpression[] args = call.getArgumentList().getExpressions();
if(args.length == 1 && "ifPresent".equals(call.getMethodExpression().getReferenceName())) {
FunctionHelper fn = FunctionHelper.create(args[0], 1);
if(fn != null) {
fn.transform(this, ((Condition.Optional)condition).unwrap("").getTrueBranch());
fn.transform(this, ((ConditionalExpression.Optional)conditionalExpression).unwrap("").getTrueBranch());
myPlaceholder = call.getParent();
return fn.getText() + ";\n" + getBreakStatement();
}
}
}
}
String found = declareResult(condition.getCondition(), condition.getType(), condition.getFalseBranch(), false);
return found + " = " +condition.getTrueBranch()+";\n" + getBreakStatement();
String found =
declareResult(conditionalExpression.getCondition(), conditionalExpression.getType(), conditionalExpression.getFalseBranch(), false);
return found + " = " + conditionalExpression.getTrueBranch() + ";\n" + getBreakStatement();
}
private Condition tryUnwrapBoolean(Condition.Boolean condition) {
private ConditionalExpression tryUnwrapBoolean(ConditionalExpression.Boolean condition) {
if (myPlaceholder instanceof PsiExpression) {
PsiExpression negation = BoolUtils.findNegation((PsiExpression)myPlaceholder);
if (negation != null) {
@@ -537,7 +538,7 @@ public class StreamToLoopInspection extends BaseJavaBatchLocalInspectionTool {
}
@NotNull
private Condition tryUnwrapOptional(Condition.Optional condition, Predicate<PsiElement> predicate) {
private ConditionalExpression tryUnwrapOptional(ConditionalExpression.Optional condition, Predicate<PsiElement> predicate) {
if (myPlaceholder instanceof PsiExpression) {
PsiMethodCallExpression call = ExpressionUtils.getCallForQualifier((PsiExpression)myPlaceholder);
if (call != null && !(call.getParent() instanceof PsiExpressionStatement)) {
@@ -545,7 +546,7 @@ public class StreamToLoopInspection extends BaseJavaBatchLocalInspectionTool {
PsiExpression[] args = call.getArgumentList().getExpressions();
if (args.length == 0 && "isPresent".equals(name)) {
myPlaceholder = call;
return new Condition.Boolean(condition.getCondition(), false);
return new ConditionalExpression.Boolean(condition.getCondition(), false);
}
if (args.length == 1) {
String absentExpression = null;
@@ -333,7 +333,7 @@ abstract class TerminalOperation extends Operation {
String seen = context.declare("seen", "boolean", "false");
String accumulator = context.declareResult("acc", myType, TypeConversionUtil.isPrimitive(myType) ? "0" : "null", false);
myUpdater.transform(context, accumulator, inVar.getName());
context.setFinisher(new Condition.Optional(myType, seen, accumulator));
context.setFinisher(new ConditionalExpression.Optional(myType, seen, accumulator));
String ifClause = "if(!" + seen + ") {\n" +
seen + "=true;\n" +
accumulator + "=" + inVar + ";\n" +
@@ -400,10 +400,10 @@ abstract class TerminalOperation extends Operation {
String count = context.declare("count", "long", "0");
String seenCheck = count + ">0";
String result = (myDoubleAccumulator ? "" : "(double)") + sum + "/" + count;
Condition condition = myUseOptional ?
new Condition.Optional("double", seenCheck, result) :
new Condition.Plain("double", seenCheck, result, "0.0");
context.setFinisher(condition);
ConditionalExpression conditionalExpression = myUseOptional ?
new ConditionalExpression.Optional("double", seenCheck, result) :
new ConditionalExpression.Plain("double", seenCheck, result, "0.0");
context.setFinisher(conditionalExpression);
return sum + "+=" + inVar + ";\n" + count + "++;\n";
}
}
@@ -434,7 +434,7 @@ abstract class TerminalOperation extends Operation {
@Override
String generate(StreamVariable inVar, StreamToLoopReplacementContext context) {
return context.assignAndBreak(new Condition.Optional(myType, "found", inVar.getName()));
return context.assignAndBreak(new ConditionalExpression.Optional(myType, "found", inVar.getName()));
}
}
@@ -484,7 +484,7 @@ abstract class TerminalOperation extends Operation {
expression = myFn.getText();
}
return "if(" + expression + ") {\n" +
context.assignAndBreak(new Condition.Boolean("b", myDefaultValue)) +
context.assignAndBreak(new ConditionalExpression.Boolean("b", myDefaultValue)) +
"}\n";
}
}
@@ -661,7 +661,7 @@ abstract class TerminalOperation extends Operation {
String seen = context.declare("seen", "boolean", "false");
String best = context.declareResult("best", myType, TypeConversionUtil.isPrimitive(myType) ? "0" : "null", false);
String type = myType;
context.setFinisher(new Condition.Optional(type, seen, best));
context.setFinisher(new ConditionalExpression.Optional(type, seen, best));
String comparePredicate = myTemplate.replace("{best}", best).replace("{item}", inVar.getName()).replace("{comparator}", comparator);
return "if(!" + seen + " || " + comparePredicate + ") {\n" +
seen + "=true;\n" +