diff --git a/src/main/java/com/caoccao/javet/buddy/ts2java/ast/expr/Ts2JavaAstBinExprLogical.java b/src/main/java/com/caoccao/javet/buddy/ts2java/ast/expr/Ts2JavaAstBinExprLogical.java index 84c8760..cf44e58 100644 --- a/src/main/java/com/caoccao/javet/buddy/ts2java/ast/expr/Ts2JavaAstBinExprLogical.java +++ b/src/main/java/com/caoccao/javet/buddy/ts2java/ast/expr/Ts2JavaAstBinExprLogical.java @@ -30,6 +30,7 @@ public abstract class Ts2JavaAstBinExprLogical extends Ts2JavaAstBinExpr implements ITs2JavaBangFlippable { protected boolean bangFlipped; protected Label labelFalse; + protected boolean labelSwitched; protected Label labelTrue; protected Ts2JavaAstBinExprLogical( @@ -40,20 +41,13 @@ protected Ts2JavaAstBinExprLogical( bangFlipped = false; labelFalse = new Label(); labelTrue = new Label(); + labelSwitched = false; type = TypeDescription.ForLoadedType.of(boolean.class); } @Override public void flipBang() { - if (isBangFlippable()) { - bangFlipped = !bangFlipped; - if (left instanceof ITs2JavaBangFlippable) { - left.as(ITs2JavaBangFlippable.class).flipBang(); - } - if (right instanceof ITs2JavaBangFlippable) { - right.as(ITs2JavaBangFlippable.class).flipBang(); - } - } + bangFlipped = !bangFlipped; } public Label getLabelFalse() { @@ -73,6 +67,10 @@ public boolean isBangFlipped() { return bangFlipped; } + public boolean isLabelSwitched() { + return labelSwitched; + } + public abstract boolean isLabelTrueRequired(); protected Size logicalClose(MethodVisitor methodVisitor) { @@ -103,4 +101,8 @@ public Ts2JavaAstBinExprLogical setLabelTrue(Label labelTrue) { this.labelTrue = labelTrue; return this; } + + public void switchLabel() { + labelSwitched = !labelSwitched; + } } diff --git a/src/main/java/com/caoccao/javet/buddy/ts2java/ast/expr/Ts2JavaAstBinExprLogicalCompare.java b/src/main/java/com/caoccao/javet/buddy/ts2java/ast/expr/Ts2JavaAstBinExprLogicalCompare.java index 03f94fe..0e55f3e 100644 --- a/src/main/java/com/caoccao/javet/buddy/ts2java/ast/expr/Ts2JavaAstBinExprLogicalCompare.java +++ b/src/main/java/com/caoccao/javet/buddy/ts2java/ast/expr/Ts2JavaAstBinExprLogicalCompare.java @@ -18,6 +18,7 @@ import com.caoccao.javet.buddy.ts2java.ast.enums.Ts2JavaAstBinaryOp; import com.caoccao.javet.buddy.ts2java.ast.interfaces.ITs2JavaAst; +import com.caoccao.javet.buddy.ts2java.ast.interfaces.abilities.ITs2JavaBangFlippable; import com.caoccao.javet.buddy.ts2java.ast.memo.Ts2JavaMemoFunction; import com.caoccao.javet.buddy.ts2java.compiler.JavaClassCast; import com.caoccao.javet.swc4j.ast.enums.Swc4jAstBinaryOp; @@ -25,6 +26,7 @@ import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.implementation.Implementation; import net.bytebuddy.implementation.bytecode.StackManipulation; +import net.bytebuddy.jar.asm.Label; import net.bytebuddy.jar.asm.MethodVisitor; import java.util.ArrayList; @@ -58,12 +60,24 @@ public Size apply(MethodVisitor methodVisitor, Implementation.Context context) { .map(s -> s.apply(methodVisitor, context)) .orElse(Size.ZERO)); final Swc4jAstBinaryOp finalOp = bangFlipped ? op.getOppositeOperator() : op; - sizes.add(Ts2JavaAstBinaryOp.getLogicalCompareStackManipulation(ast, finalOp, upCastType, labelFalse) + final Label label = labelSwitched ? labelTrue : labelFalse; + sizes.add(Ts2JavaAstBinaryOp.getLogicalCompareStackManipulation(ast, finalOp, upCastType, label) .apply(methodVisitor, context)); sizes.add(logicalClose(methodVisitor)); return aggregateSize(sizes); } + @Override + public void flipBang() { + super.flipBang(); + if (left instanceof ITs2JavaBangFlippable) { + left.as(ITs2JavaBangFlippable.class).flipBang(); + } + if (right instanceof ITs2JavaBangFlippable) { + right.as(ITs2JavaBangFlippable.class).flipBang(); + } + } + @Override public boolean isLabelTrueRequired() { return false; diff --git a/src/main/java/com/caoccao/javet/buddy/ts2java/ast/expr/Ts2JavaAstBinExprLogicalCondition.java b/src/main/java/com/caoccao/javet/buddy/ts2java/ast/expr/Ts2JavaAstBinExprLogicalCondition.java index ca232d7..7bce6bd 100644 --- a/src/main/java/com/caoccao/javet/buddy/ts2java/ast/expr/Ts2JavaAstBinExprLogicalCondition.java +++ b/src/main/java/com/caoccao/javet/buddy/ts2java/ast/expr/Ts2JavaAstBinExprLogicalCondition.java @@ -17,6 +17,7 @@ package com.caoccao.javet.buddy.ts2java.ast.expr; import com.caoccao.javet.buddy.ts2java.ast.interfaces.ITs2JavaAst; +import com.caoccao.javet.buddy.ts2java.ast.interfaces.abilities.ITs2JavaBangFlippable; import com.caoccao.javet.buddy.ts2java.ast.memo.Ts2JavaMemoFunction; import com.caoccao.javet.buddy.ts2java.exceptions.Ts2JavaAstException; import com.caoccao.javet.swc4j.ast.enums.Swc4jAstBinaryOp; @@ -46,19 +47,19 @@ public Size apply(MethodVisitor methodVisitor, Implementation.Context context) { final Swc4jAstBinaryOp finalOp = bangFlipped ? op.getOppositeOperator() : op; final boolean isLeftLogical = left instanceof Ts2JavaAstBinExprLogical; final boolean isRightLogical = right instanceof Ts2JavaAstBinExprLogical; + if (isLeftLogical) { + left.as(Ts2JavaAstBinExprLogical.class) + .setLabelTrue(labelSwitched ? labelFalse : labelTrue) + .setLabelFalse(labelSwitched ? labelTrue : labelFalse); + } if (isRightLogical) { right.as(Ts2JavaAstBinExprLogical.class) - .setLabelTrue(labelTrue) - .setLabelFalse(labelFalse); + .setLabelTrue(labelSwitched ? labelFalse : labelTrue) + .setLabelFalse(labelSwitched ? labelTrue : labelFalse); } final int opcodeCompareFalse = bangFlipped ? Opcodes.IFNE : Opcodes.IFEQ; switch (finalOp) { case LogicalAnd: { - if (isLeftLogical) { - left.as(Ts2JavaAstBinExprLogical.class) - .setLabelTrue(labelTrue) - .setLabelFalse(labelFalse); - } sizes.add(left.apply(methodVisitor, context)); if (!isLeftLogical) { methodVisitor.visitJumpInsn(opcodeCompareFalse, labelFalse); @@ -71,9 +72,7 @@ public Size apply(MethodVisitor methodVisitor, Implementation.Context context) { } case LogicalOr: { if (isLeftLogical) { - left.as(Ts2JavaAstBinExprLogical.class) - .setLabelTrue(labelFalse) - .setLabelFalse(labelTrue); + left.as(Ts2JavaAstBinExprLogical.class).switchLabel(); } final int opcodeCompareTrue = bangFlipped ? Opcodes.IFEQ : Opcodes.IFNE; sizes.add(left.apply(methodVisitor, context)); @@ -125,10 +124,8 @@ public void compile() { @Override public void flipBang() { super.flipBang(); - if (isBangFlippable()) { - if (left instanceof Ts2JavaAstBinExprLogical) { - left.as(Ts2JavaAstBinExprLogical.class).flipBang(); - } + if (right instanceof ITs2JavaBangFlippable) { + right.as(ITs2JavaBangFlippable.class).flipBang(); } }