From 098155927a6736291c156cb73703e25551e6d13b Mon Sep 17 00:00:00 2001 From: sschr15 Date: Thu, 29 Aug 2024 16:13:22 -0500 Subject: [PATCH] Subclass statement types instead of a custom one in its entirety --- .../vineflower/kotlin/stat/KDoStatement.java | 106 +++-- .../kotlin/stat/KSequenceStatement.java | 30 +- .../vineflower/kotlin/stat/KStatement.java | 362 ------------------ .../results/pkg/TestTailrecFunctions.dec | 2 +- .../results/pkg/TestTryFinallyExpressions.dec | 6 +- 5 files changed, 100 insertions(+), 406 deletions(-) delete mode 100644 plugins/kotlin/src/main/java/org/vineflower/kotlin/stat/KStatement.java diff --git a/plugins/kotlin/src/main/java/org/vineflower/kotlin/stat/KDoStatement.java b/plugins/kotlin/src/main/java/org/vineflower/kotlin/stat/KDoStatement.java index 37e695a02..ae4fe04d4 100644 --- a/plugins/kotlin/src/main/java/org/vineflower/kotlin/stat/KDoStatement.java +++ b/plugins/kotlin/src/main/java/org/vineflower/kotlin/stat/KDoStatement.java @@ -9,11 +9,31 @@ import org.vineflower.kotlin.expr.KVarExprent; import org.vineflower.kotlin.util.KUtils; -public class KDoStatement extends KStatement { +public class KDoStatement extends DoStatement { public KDoStatement(DoStatement statement) { - super(statement); + super(); + setLooptype(statement.getLooptype()); + setInitExprent(statement.getInitExprent()); + setConditionExprent(statement.getConditionExprent()); + setIncExprent(statement.getIncExprent()); + + setFirst(statement.getFirst()); + stats.addAllWithKey(statement.getStats(), statement.getStats().getLstKeys()); + parent = statement.getParent(); + first = statement.getFirst(); + exprents = statement.getExprents(); + labelEdges.addAll(statement.getLabelEdges()); + varDefinitions.addAll(statement.getVarDefinitions()); + post = statement.getPost(); + lastBasicType = statement.getLastBasicType(); + + isMonitorEnter = statement.isMonitorEnter(); + containsMonitorExit = statement.containsMonitorExit(); + isLastAthrow = statement.containsMonitorExitOrAthrow() && !containsMonitorExit; + + continueSet = statement.getContinueSet(); } - + private static boolean isIntegerType(VarType type) { return VarType.VARTYPE_INT.equals(type) || VarType.VARTYPE_BYTE.equals(type) || @@ -25,30 +45,34 @@ private static boolean isIntegerType(VarType type) { @Override public TextBuffer toJava(int indent) { TextBuffer buf = new TextBuffer(); - boolean labeled = statement.isLabeled(); + boolean labeled = isLabeled(); + + if (getLooptype() != Type.FOR) { + buf.append(ExprProcessor.listToJava(varDefinitions, indent)); - buf.appendIndent(indent); + buf.appendIndent(indent); - if (labeled) { - buf.append("label") - .append(this.id) - .append("@ "); + if (labeled) { + buf.append("label") + .append(this.id) + .append("@ "); + } } - switch (statement.getLooptype()) { + switch (getLooptype()) { case INFINITE -> { buf.append("while (true) {").appendLineSeparator(); - buf.append(ExprProcessor.jmpWrapper(statement.getFirst(), indent + 1, false)); + buf.append(ExprProcessor.jmpWrapper(first, indent + 1, false)); buf.appendIndent(indent).append("}").appendLineSeparator(); } case DO_WHILE -> { - Exprent expr = KUtils.replaceExprent(statement.getConditionExprent()); + Exprent expr = KUtils.replaceExprent(getConditionExprent()); if (expr == null) { - expr = statement.getConditionExprent(); + expr = getConditionExprent(); } buf.append("do {").appendLineSeparator(); - buf.append(ExprProcessor.jmpWrapper(statement.getFirst(), indent + 1, false)); + buf.append(ExprProcessor.jmpWrapper(first, indent + 1, false)); buf.appendIndent(indent).append("} while ("); buf.pushNewlineGroup(indent, 1); buf.appendPossibleNewline(); @@ -58,9 +82,9 @@ public TextBuffer toJava(int indent) { buf.append(")").appendLineSeparator(); } case WHILE -> { - Exprent expr = KUtils.replaceExprent(statement.getConditionExprent()); + Exprent expr = KUtils.replaceExprent(getConditionExprent()); if (expr == null) { - expr = statement.getConditionExprent(); + expr = getConditionExprent(); } buf.append("while ("); @@ -70,36 +94,38 @@ public TextBuffer toJava(int indent) { buf.appendPossibleNewline("", true); buf.popNewlineGroup(); buf.append(") {").appendLineSeparator(); - buf.append(ExprProcessor.jmpWrapper(statement.getFirst(), indent + 1, false)); + buf.append(ExprProcessor.jmpWrapper(first, indent + 1, false)); buf.appendIndent(indent).append("}").appendLineSeparator(); } case FOR_EACH -> { - KVarExprent init = new KVarExprent((VarExprent) statement.getInitExprent()); + KVarExprent init = new KVarExprent((VarExprent) getInitExprent()); init.setExcludeVarVal(true); - Exprent inc = KUtils.replaceExprent(statement.getIncExprent()); + Exprent inc = KUtils.replaceExprent(getIncExprent()); if (inc == null) { - inc = statement.getIncExprent(); + inc = getIncExprent(); } buf.append("for (").append(init.toJava(indent)); inc.getInferredExprType(null); //TODO: see DoStatement buf.append(" in ").append(inc.toJava(indent)).append(") {").appendLineSeparator(); - buf.append(ExprProcessor.jmpWrapper(statement.getFirst(), indent + 1, false)); + buf.append(ExprProcessor.jmpWrapper(first, indent + 1, false)); buf.appendIndent(indent).append("}").appendLineSeparator(); } case FOR -> { + buf.appendIndent(indent); + // This is a hard one as Kotlin has no one-to-one equivalent to Java's for loop resugar: if ( - statement.getInitExprent() instanceof AssignmentExprent init && + getInitExprent() instanceof AssignmentExprent init && init.getLeft() instanceof VarExprent varExpr && isIntegerType(varExpr.getExprType()) && init.getRight() instanceof ConstExprent constExpr && - statement.getIncExprent() instanceof FunctionExprent inc && + getIncExprent() instanceof FunctionExprent inc && inc.getFuncType().isPPMM() && - statement.getConditionExprent() instanceof FunctionExprent condition && + getConditionExprent() instanceof FunctionExprent condition && condition.getFuncType() == FunctionExprent.FunctionType.LT ) { // Turn for loop into range @@ -136,7 +162,15 @@ public TextBuffer toJava(int indent) { if (constExpr.getValue() instanceof Integer i && i == 0) { buf.append("repeat(") .append(conditionExpr.toJava()) - .append(") {"); + .append(") "); + + if (labeled) { + buf.append("label") + .append(id) + .append("@"); + } + + buf.append("{"); if (!"it".equals(varExpr.getName())) { buf.append(" ") @@ -145,6 +179,12 @@ public TextBuffer toJava(int indent) { } buf.appendLineSeparator(); } else { + if (labeled) { + buf.append("label") + .append(id) + .append("@ "); + } + buf.append("for (") .append(varExpr.toJava(indent)) .append(" in ") @@ -155,23 +195,23 @@ public TextBuffer toJava(int indent) { .appendLineSeparator(); } - buf.append(ExprProcessor.jmpWrapper(statement.getFirst(), indent + 1, false)); + buf.append(ExprProcessor.jmpWrapper(first, indent + 1, false)); buf.appendIndent(indent).append("}").appendLineSeparator(); } else { //TODO other cases - Exprent init = KUtils.replaceExprent(statement.getInitExprent()); + Exprent init = KUtils.replaceExprent(getInitExprent()); if (init == null) { - init = statement.getInitExprent(); + init = getInitExprent(); } - Exprent condition = KUtils.replaceExprent(statement.getConditionExprent()); + Exprent condition = KUtils.replaceExprent(getConditionExprent()); if (condition == null) { - condition = statement.getConditionExprent(); + condition = getConditionExprent(); } - Exprent inc = KUtils.replaceExprent(statement.getIncExprent()); + Exprent inc = KUtils.replaceExprent(getIncExprent()); if (inc == null) { - inc = statement.getIncExprent(); + inc = getIncExprent(); } if (labeled) { @@ -200,7 +240,7 @@ public TextBuffer toJava(int indent) { buf.append("if ("); buf.append(condition.toJava(indent + 1)); buf.append(") break").appendLineSeparator(); - buf.append(ExprProcessor.jmpWrapper(statement.getFirst(), indent + 1, false)); + buf.append(ExprProcessor.jmpWrapper(first, indent + 1, false)); buf.appendLineSeparator(); buf.appendIndent(indent + 1).append(inc.toJava(indent + 1)).appendLineSeparator(); buf.appendIndent(indent).append("}").appendLineSeparator(); diff --git a/plugins/kotlin/src/main/java/org/vineflower/kotlin/stat/KSequenceStatement.java b/plugins/kotlin/src/main/java/org/vineflower/kotlin/stat/KSequenceStatement.java index bad169ef1..74e2e6d89 100644 --- a/plugins/kotlin/src/main/java/org/vineflower/kotlin/stat/KSequenceStatement.java +++ b/plugins/kotlin/src/main/java/org/vineflower/kotlin/stat/KSequenceStatement.java @@ -5,29 +5,45 @@ import org.jetbrains.java.decompiler.modules.decompiler.stats.Statement; import org.jetbrains.java.decompiler.util.TextBuffer; -public class KSequenceStatement extends KStatement { +public class KSequenceStatement extends SequenceStatement { public KSequenceStatement(SequenceStatement statement) { - super(statement); + super(); + + setFirst(statement.getFirst()); + stats.addAllWithKey(statement.getStats(), statement.getStats().getLstKeys()); + parent = statement.getParent(); + first = statement.getFirst(); + exprents = statement.getExprents(); + labelEdges.addAll(statement.getLabelEdges()); + varDefinitions.addAll(statement.getVarDefinitions()); + post = statement.getPost(); + lastBasicType = statement.getLastBasicType(); + + isMonitorEnter = statement.isMonitorEnter(); + containsMonitorExit = statement.containsMonitorExit(); + isLastAthrow = statement.containsMonitorExitOrAthrow() && !containsMonitorExit; + + continueSet = statement.getContinueSet(); } @Override public TextBuffer toJava(int indent) { TextBuffer buf = new TextBuffer(); - boolean labeled = statement.isLabeled(); + boolean labeled = isLabeled(); - buf.append(ExprProcessor.listToJava(statement.getVarDefinitions(), indent)); + buf.append(ExprProcessor.listToJava(varDefinitions, indent)); if (labeled) { buf.appendIndent(indent++) .append("run label") - .append(statement.id) + .append(id) .append("@{") .appendLineSeparator(); } boolean notEmpty = false; - for (int i = 0; i < statement.getStats().size(); i++) { - Statement st = statement.getStats().get(i); + for (int i = 0; i < stats.size(); i++) { + Statement st = stats.get(i); TextBuffer str = ExprProcessor.jmpWrapper(st, indent, false); if (i > 0 && !str.containsOnlyWhitespaces() && notEmpty) { diff --git a/plugins/kotlin/src/main/java/org/vineflower/kotlin/stat/KStatement.java b/plugins/kotlin/src/main/java/org/vineflower/kotlin/stat/KStatement.java deleted file mode 100644 index 078f0771c..000000000 --- a/plugins/kotlin/src/main/java/org/vineflower/kotlin/stat/KStatement.java +++ /dev/null @@ -1,362 +0,0 @@ -package org.vineflower.kotlin.stat; - -import org.jetbrains.java.decompiler.modules.decompiler.StatEdge; -import org.jetbrains.java.decompiler.modules.decompiler.exps.Exprent; -import org.jetbrains.java.decompiler.modules.decompiler.exps.VarExprent; -import org.jetbrains.java.decompiler.modules.decompiler.stats.BasicBlockStatement; -import org.jetbrains.java.decompiler.modules.decompiler.stats.RootStatement; -import org.jetbrains.java.decompiler.modules.decompiler.stats.Statement; -import org.jetbrains.java.decompiler.struct.match.IMatchable; -import org.jetbrains.java.decompiler.struct.match.MatchEngine; -import org.jetbrains.java.decompiler.struct.match.MatchNode; -import org.jetbrains.java.decompiler.util.StartEndPair; -import org.jetbrains.java.decompiler.util.TextBuffer; -import org.jetbrains.java.decompiler.util.collections.VBStyleCollection; - -import java.util.BitSet; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -public abstract class KStatement extends Statement { - protected final T statement; - - public KStatement(T statement) { - super(statement.type); - this.statement = statement; - } - - public abstract TextBuffer toJava(int indent); - - @Override - public void clearTempInformation() { - statement.clearTempInformation(); - } - - @Override - public void collapseNodesToStatement(Statement stat) { - statement.collapseNodesToStatement(stat); - } - - @Override - public void addLabeledEdge(StatEdge edge) { - statement.addLabeledEdge(edge); - } - - @SuppressWarnings("deprecation") - @Override - public void addEdgeInternal(EdgeDirection direction, StatEdge edge) { - statement.addEdgeInternal(direction, edge); - } - - @SuppressWarnings("deprecation") - @Override - public void removeEdgeInternal(EdgeDirection direction, StatEdge edge) { - statement.removeEdgeInternal(direction, edge); - } - - @Override - public void addPredecessor(StatEdge edge) { - statement.addPredecessor(edge); - } - - @Override - public void removePredecessor(StatEdge edge) { - statement.removePredecessor(edge); - } - - @Override - public void addSuccessor(StatEdge edge) { - statement.addSuccessor(edge); - } - - @Override - public void removeSuccessor(StatEdge edge) { - statement.removeSuccessor(edge); - } - - @Override - public void removeAllSuccessors(Statement stat) { - statement.removeAllSuccessors(stat); - } - - @Override - public HashSet buildContinueSet() { - return statement.buildContinueSet(); - } - - @Override - public void buildMonitorFlags() { - statement.buildMonitorFlags(); - } - - @Override - public void markMonitorexitDead() { - statement.markMonitorexitDead(); - } - - @Override - public List getReversePostOrderList(Statement root) { - return statement.getReversePostOrderList(root); - } - - @Override - public List getPostReversePostOrderList(List lstexits) { - return statement.getPostReversePostOrderList(lstexits); - } - - @Override - public boolean containsStatement(Statement stat) { - return statement.containsStatement(stat); - } - - @Override - public boolean containsStatementStrict(Statement stat) { - return statement.containsStatementStrict(stat); - } - - @Override - public List getSequentialObjects() { - return statement.getSequentialObjects(); - } - - @Override - public void initExprents() { - statement.initExprents(); - } - - @Override - public void replaceExprent(Exprent oldexpr, Exprent newexpr) { - statement.replaceExprent(oldexpr, newexpr); - } - - @Override - public Statement getSimpleCopy() { - return statement.getSimpleCopy(); - } - - @Override - public void initSimpleCopy() { - statement.initSimpleCopy(); - } - - @Override - public void replaceStatement(Statement oldstat, Statement newstat) { - statement.replaceStatement(oldstat, newstat); - } - - @Override - public List getImplicitlyDefinedVars() { - return statement.getImplicitlyDefinedVars(); - } - - @Override - public void changeEdgeNode(EdgeDirection direction, StatEdge edge, Statement value) { - statement.changeEdgeNode(direction, edge, value); - } - - @Override - public void changeEdgeType(EdgeDirection direction, StatEdge edge, int newtype) { - statement.changeEdgeType(direction, edge, newtype); - } - - @Override - public List getNeighbours(int type, EdgeDirection direction) { - return statement.getNeighbours(type, direction); - } - - @Override - public Set getNeighboursSet(int type, EdgeDirection direction) { - return statement.getNeighboursSet(type, direction); - } - - @Override - public List getSuccessorEdges(int type) { - return statement.getSuccessorEdges(type); - } - - @Override - public List getSuccessorEdgeView(int type) { - return statement.getSuccessorEdgeView(type); - } - - @Override - public List getPredecessorEdges(int type) { - return statement.getPredecessorEdges(type); - } - - @Override - public List getAllSuccessorEdges() { - return statement.getAllSuccessorEdges(); - } - - @Override - public List getAllDirectSuccessorEdges() { - return statement.getAllDirectSuccessorEdges(); - } - - @Override - public boolean hasAnySuccessor() { - return statement.hasAnySuccessor(); - } - - @Override - public boolean hasAnyDirectSuccessor() { - return statement.hasAnyDirectSuccessor(); - } - - @Override - public boolean hasSuccessor(int type) { - return statement.hasSuccessor(type); - } - - @Override - public StatEdge getFirstSuccessor() { - return statement.getFirstSuccessor(); - } - - @Override - public StatEdge getFirstDirectSuccessor() { - return statement.getFirstDirectSuccessor(); - } - - @Override - public List getAllPredecessorEdges() { - return statement.getAllPredecessorEdges(); - } - - @Override - public Statement getFirst() { - return statement.getFirst(); - } - - @Override - public void setFirst(Statement first) { - statement.setFirst(first); - } - - @Override - public Statement getPost() { - return statement.getPost(); - } - - @Override - public VBStyleCollection getStats() { - return statement.getStats(); - } - - @Override - public LastBasicType getLastBasicType() { - return statement.getLastBasicType(); - } - - @Override - public HashSet getContinueSet() { - return statement.getContinueSet(); - } - - @Override - public boolean containsMonitorExit() { - return statement.containsMonitorExit(); - } - - @Override - public boolean containsMonitorExitOrAthrow() { - return statement.containsMonitorExitOrAthrow(); - } - - @Override - public boolean isMonitorEnter() { - return statement.isMonitorEnter(); - } - - @Override - public BasicBlockStatement getBasichead() { - return statement.getBasichead(); - } - - @Override - public boolean isLabeled() { - return statement.isLabeled(); - } - - @Override - public boolean hasBasicSuccEdge() { - return statement.hasBasicSuccEdge(); - } - - @Override - public Statement getParent() { - return statement.getParent(); - } - - @Override - public void setParent(Statement parent) { - statement.setParent(parent); - } - - @Override - public RootStatement getTopParent() { - return statement.getTopParent(); - } - - @Override - public HashSet getLabelEdges() { - return statement.getLabelEdges(); - } - - @Override - public List getVarDefinitions() { - return statement.getVarDefinitions(); - } - - @Override - public List getExprents() { - return statement.getExprents(); - } - - @Override - public boolean isCopied() { - return statement.isCopied(); - } - - @Override - public void setCopied(boolean copied) { - statement.setCopied(copied); - } - - @Override - public boolean isPhantom() { - return statement.isPhantom(); - } - - @Override - public void setPhantom(boolean phantom) { - statement.setPhantom(phantom); - } - - @Override - public String toString() { - return statement.toString(); - } - - @Override - public void getOffset(BitSet values) { - statement.getOffset(values); - } - - @Override - public StartEndPair getStartEndRange() { - return statement.getStartEndRange(); - } - - @Override - public IMatchable findObject(MatchNode matchNode, int index) { - return statement.findObject(matchNode, index); - } - - @Override - public boolean match(MatchNode matchNode, MatchEngine engine) { - return statement.match(matchNode, engine); - } -} diff --git a/plugins/kotlin/testData/results/pkg/TestTailrecFunctions.dec b/plugins/kotlin/testData/results/pkg/TestTailrecFunctions.dec index 3fb041428..5365f43d6 100644 --- a/plugins/kotlin/testData/results/pkg/TestTailrecFunctions.dec +++ b/plugins/kotlin/testData/results/pkg/TestTailrecFunctions.dec @@ -46,7 +46,7 @@ public class TestTailrecFunctions { public tailrec fun testTryCatchFinally() { label31: { - label32: { + run label33@{ try { try { this.testTryCatchFinally();// 35 diff --git a/plugins/kotlin/testData/results/pkg/TestTryFinallyExpressions.dec b/plugins/kotlin/testData/results/pkg/TestTryFinallyExpressions.dec index 05c8835e9..4e278e3fd 100644 --- a/plugins/kotlin/testData/results/pkg/TestTryFinallyExpressions.dec +++ b/plugins/kotlin/testData/results/pkg/TestTryFinallyExpressions.dec @@ -43,9 +43,9 @@ public class TestTryFinallyExpressions { label68: { var var19: java.lang.String = a;// 28 - run label69@{ - run label70@{ - run label71@{ + run label138@{ + run label137@{ + run label136@{ try { try { if (a == b) {// 30