AS3: Better semicolon insertion

This commit is contained in:
Jindra Pet��k
2012-12-20 21:02:11 +01:00
parent 3d775b283b
commit d7843ea832
31 changed files with 104 additions and 39 deletions
+4 -4
View File
@@ -533,20 +533,20 @@ public class ABC {
return null; return null;
} }
private String addTabs(String s, int tabs) { private String addTabs(String s, int tabs) {
String parts[] = s.split("\r\n"); String parts[] = s.split("\r\n");
if (!s.contains("\r\n")) { if (!s.contains("\r\n")) {
parts = s.split("\n"); parts = s.split("\n");
} }
String ret = ""; String ret = "";
for (int i = 0; i < parts.length; i++) { for (int i = 0; i < parts.length; i++) {
for (int t = 0; t < tabs; t++) { for (int t = 0; t < tabs; t++) {
ret += IDENT_STRING; ret += IDENT_STRING;
} }
ret += parts[i]; ret += parts[i];
if (i < parts.length - 1) { if (i < parts.length - 1) {
ret += "\r\n"; ret += "\r\n";
} }
} }
return ret; return ret;
} }
@@ -833,7 +833,7 @@ public class AVM2Code {
String ret = ""; String ret = "";
for (int d = 0; d < stack.size(); d++) { for (int d = 0; d < stack.size(); d++) {
TreeItem o = stack.get(d); TreeItem o = stack.get(d);
ret += o.toString(constants) + "\r\n"; ret += o.toStringSemicoloned(constants) + "\r\n";
} }
return ret; return ret;
} }
@@ -1172,7 +1172,7 @@ public HashMap<Integer,String> getLocalRegNamesFromDebug(ABC abc){
throw new UnknownJumpException(stack, ip, output); throw new UnknownJumpException(stack, ip, output);
} }
AVM2Instruction ins = code.get(ip); AVM2Instruction ins = code.get(ip);
//Ify s vice podminkama //Ifs with multiple conditions
if (ins.definition instanceof JumpIns) { if (ins.definition instanceof JumpIns) {
if (ins.operands[0] == 0) { if (ins.operands[0] == 0) {
ip++; ip++;
@@ -1468,6 +1468,12 @@ public HashMap<Integer,String> getLocalRegNamesFromDebug(ABC abc){
if (ip - 1 >= start) { if (ip - 1 >= start) {
insBefore = code.get(ip - 1); insBefore = code.get(ip - 1);
} }
if (insAfter.definition instanceof ConvertBIns) { //SWF compiled with debug contain convert_b
ip++;
addr=pos2adr(ip);
insAfter = code.get(ip + 1);
}
boolean isAnd = false; boolean isAnd = false;
if (insAfter.definition instanceof IfFalseIns) { if (insAfter.definition instanceof IfFalseIns) {
//stack.add("(" + stack.pop() + ")&&"); //stack.add("(" + stack.pop() + ")&&");
@@ -1847,6 +1853,12 @@ public HashMap<Integer,String> getLocalRegNamesFromDebug(ABC abc){
} catch (Exception ex) { } catch (Exception ex) {
} }
for (int p = 0; p < parts.length; p++) { for (int p = 0; p < parts.length; p++) {
if(p==parts.length-1){
if(parts[p].equals(""))
{
continue;
}
}
String strippedP = Highlighting.stripHilights(parts[p]); String strippedP = Highlighting.stripHilights(parts[p]);
if (strippedP.endsWith(":") && (!strippedP.startsWith("case ")) && (!strippedP.equals("default:"))) { if (strippedP.endsWith(":") && (!strippedP.startsWith("case ")) && (!strippedP.equals("default:"))) {
String loopname = strippedP.substring(0, strippedP.length() - 1); String loopname = strippedP.substring(0, strippedP.length() - 1);
@@ -1880,7 +1892,7 @@ public HashMap<Integer,String> getLocalRegNamesFromDebug(ABC abc){
level++; level++;
sub += tabString(level) + parts[p] + "\r\n"; sub += tabString(level) + parts[p] + "\r\n";
level++; level++;
} else if (strippedP.equals("}")) { } else if (strippedP.equals("}")||strippedP.equals("};")) {
level--; level--;
sub += tabString(level) + parts[p] + "\r\n"; sub += tabString(level) + parts[p] + "\r\n";
level--; level--;
@@ -37,7 +37,7 @@ public class BreakTreeItem extends TreeItem {
@Override @Override
public String toString(ConstantPool constants) { public String toString(ConstantPool constants) {
return hilight("break") + " loop" + loopPos + ";"; return hilight("break") + " loop" + loopPos;
} }
} }
@@ -46,7 +46,7 @@ public class CallPropertyTreeItem extends TreeItem {
} }
args = args + arguments.get(a).toString(constants); args = args + arguments.get(a).toString(constants);
} }
return formatProperty(constants, receiver, propertyName) + hilight("(") + args + hilight(")") + (isVoid ? ";" : ""); return formatProperty(constants, receiver, propertyName) + hilight("(") + args + hilight(")");
} }
@@ -49,7 +49,7 @@ public class CallSuperTreeItem extends TreeItem {
} }
String calee = receiver.toString(constants) + "."; String calee = receiver.toString(constants) + ".";
if (Highlighting.stripHilights(calee).equals("this.")) calee = ""; if (Highlighting.stripHilights(calee).equals("this.")) calee = "";
return calee + hilight("super.") + multiname.toString(constants) + hilight("(") + args + hilight(")") + (isVoid ? ";" : ""); return calee + hilight("super.") + multiname.toString(constants) + hilight("(") + args + hilight(")");
} }
@@ -45,7 +45,7 @@ public class ConstructSuperTreeItem extends TreeItem {
} }
String calee = object.toString(constants) + "."; String calee = object.toString(constants) + ".";
if (Highlighting.stripHilights(calee).equals("this.")) calee = ""; if (Highlighting.stripHilights(calee).equals("this.")) calee = "";
return calee + hilight("super(") + argStr + hilight(");"); return calee + hilight("super(") + argStr + hilight(")");
} }
@@ -37,7 +37,7 @@ public class ContinueTreeItem extends TreeItem {
@Override @Override
public String toString(ConstantPool constants) { public String toString(ConstantPool constants) {
return hilight("continue") + " " + (isKnown ? "loop" : "unk") + loopPos + ";"; return hilight("continue") + " " + (isKnown ? "loop" : "unk") + loopPos;
} }
} }
@@ -32,7 +32,7 @@ public class DecLocalTreeItem extends TreeItem {
@Override @Override
public String toString(ConstantPool constants) { public String toString(ConstantPool constants) {
return InstructionDefinition.localRegName(regIndex) + hilight("--") + ";"; return InstructionDefinition.localRegName(regIndex) + hilight("--");
} }
@@ -32,7 +32,7 @@ public class IncLocalTreeItem extends TreeItem {
@Override @Override
public String toString(ConstantPool constants) { public String toString(ConstantPool constants) {
return InstructionDefinition.localRegName(regIndex) + hilight("++") + ";"; return InstructionDefinition.localRegName(regIndex) + hilight("++");
} }
@@ -35,7 +35,7 @@ public class InitPropertyTreeItem extends TreeItem implements SetTypeTreeItem{
@Override @Override
public String toString(ConstantPool constants) { public String toString(ConstantPool constants) {
return formatProperty(constants, object, propertyName) + hilight("=") + value.toString(constants) + ";"; return formatProperty(constants, object, propertyName) + hilight("=") + value.toString(constants);
} }
public TreeItem getObject() { public TreeItem getObject() {
@@ -35,7 +35,7 @@ public class NewFunctionTreeItem extends TreeItem {
@Override @Override
public String toString(ConstantPool constants) { public String toString(ConstantPool constants) {
return hilight("new function(" + paramStr + "):" + returnStr + "\r\n{\r\n") + functionBody + hilight("}\r\n"); return hilight("new function(" + paramStr + "):" + returnStr + "\r\n{\r\n") + functionBody +"\r\n"+ hilight("}");
} }
@@ -31,7 +31,7 @@ public class ReturnValueTreeItem extends TreeItem {
@Override @Override
public String toString(ConstantPool constants) { public String toString(ConstantPool constants) {
return hilight("return ") + value.toString(constants) + ";"; return hilight("return ") + value.toString(constants);
} }
@@ -29,7 +29,7 @@ public class ReturnVoidTreeItem extends TreeItem {
@Override @Override
public String toString(ConstantPool constants) { public String toString(ConstantPool constants) {
return hilight("return") + ";"; return hilight("return");
} }
@@ -33,7 +33,7 @@ public class SetGlobalSlotTreeItem extends TreeItem {
@Override @Override
public String toString(ConstantPool constants) { public String toString(ConstantPool constants) {
return hilight("setglobalslot(" + slotId + ",") + value.toString(constants) + hilight(")") + ";"; return hilight("setglobalslot(" + slotId + ",") + value.toString(constants) + hilight(")");
} }
@@ -34,7 +34,7 @@ public class SetLocalTreeItem extends TreeItem implements SetTypeTreeItem {
@Override @Override
public String toString(ConstantPool constants) { public String toString(ConstantPool constants) {
return hilight(InstructionDefinition.localRegName(regIndex) + "=") + value.toString(constants) + ";"; return hilight(InstructionDefinition.localRegName(regIndex) + "=") + value.toString(constants);
} }
public TreeItem getObject() { public TreeItem getObject() {
@@ -35,7 +35,7 @@ public class SetPropertyTreeItem extends TreeItem implements SetTypeTreeItem{
@Override @Override
public String toString(ConstantPool constants) { public String toString(ConstantPool constants) {
return formatProperty(constants, object, propertyName) + hilight("=") + value.toString(constants) + ";"; return formatProperty(constants, object, propertyName) + hilight("=") + value.toString(constants);
} }
public TreeItem getObject() { public TreeItem getObject() {
@@ -48,7 +48,7 @@ public class SetSlotTreeItem extends TreeItem implements SetTypeTreeItem {
} }
} }
} }
return ret + hilight(slotName.getName(constants)) + hilight("=") + value.toString(constants) + ";"; return ret + hilight(slotName.getName(constants)) + hilight("=") + value.toString(constants);
} }
public TreeItem getObject() { public TreeItem getObject() {
@@ -39,7 +39,7 @@ public class SetSuperTreeItem extends TreeItem {
public String toString(ConstantPool constants) { public String toString(ConstantPool constants) {
String calee = object.toString(constants) + "."; String calee = object.toString(constants) + ".";
if (Highlighting.stripHilights(calee).equals("this.")) calee = ""; if (Highlighting.stripHilights(calee).equals("this.")) calee = "";
return calee + hilight("super.") + propertyName.toString(constants) + hilight("=") + value.toString(constants) + ";"; return calee + hilight("super.") + propertyName.toString(constants) + hilight("=") + value.toString(constants);
} }
@@ -41,7 +41,7 @@ public abstract class TreeItem {
public static final int PRECEDENCE_ASSIGMENT = 14; public static final int PRECEDENCE_ASSIGMENT = 14;
public static final int PRECEDENCE_COMMA = 15; public static final int PRECEDENCE_COMMA = 15;
public static final int NOPRECEDENCE = 16; public static final int NOPRECEDENCE = 16;
public int precedence = NOPRECEDENCE; public int precedence = NOPRECEDENCE;
public AVM2Instruction instruction; public AVM2Instruction instruction;
@@ -53,7 +53,18 @@ public abstract class TreeItem {
public abstract String toString(ConstantPool constants); public abstract String toString(ConstantPool constants);
public String toStringSemicoloned(ConstantPool constants)
{
return toString(constants)+(needsSemicolon()?";":"");
}
public boolean needsSemicolon()
{
return true;
}
protected String hilight(String str) { protected String hilight(String str) {
if (instruction == null) if (instruction == null)
@@ -31,6 +31,13 @@ public class DoWhileTreeItem extends LoopTreeItem implements Block {
public List<TreeItem> commands; public List<TreeItem> commands;
public TreeItem expression; public TreeItem expression;
@Override
public boolean needsSemicolon() {
return false;
}
public DoWhileTreeItem(AVM2Instruction instruction, int loopBreak, int loopContinue, List<TreeItem> commands, TreeItem expression) { public DoWhileTreeItem(AVM2Instruction instruction, int loopBreak, int loopContinue, List<TreeItem> commands, TreeItem expression) {
super(instruction, loopBreak, loopContinue); super(instruction, loopBreak, loopContinue);
this.expression = expression; this.expression = expression;
@@ -43,7 +50,7 @@ public class DoWhileTreeItem extends LoopTreeItem implements Block {
ret += "loop" + loopBreak + ":\r\n"; ret += "loop" + loopBreak + ":\r\n";
ret += hilight("do\r\n{") + "\r\n"; ret += hilight("do\r\n{") + "\r\n";
for (TreeItem ti : commands) { for (TreeItem ti : commands) {
ret += ti.toString(constants) + "\r\n"; ret += ti.toStringSemicoloned(constants) + "\r\n";
} }
ret += hilight("}\r\nwhile(") + expression.toString(constants) + hilight(");") + "\r\n"; ret += hilight("}\r\nwhile(") + expression.toString(constants) + hilight(");") + "\r\n";
ret += ":loop" + loopBreak; ret += ":loop" + loopBreak;
@@ -54,6 +54,11 @@ public class ForEachTreeItem extends LoopTreeItem implements Block {
this.expression = expression; this.expression = expression;
this.commands = commands; this.commands = commands;
} }
@Override
public boolean needsSemicolon() {
return false;
}
@Override @Override
public String toString(ConstantPool constants) { public String toString(ConstantPool constants) {
@@ -61,7 +66,7 @@ public class ForEachTreeItem extends LoopTreeItem implements Block {
ret += "loop" + loopBreak + ":\r\n"; ret += "loop" + loopBreak + ":\r\n";
ret += hilight("for ") + expression.toString(constants) + "\r\n{\r\n"; ret += hilight("for ") + expression.toString(constants) + "\r\n{\r\n";
for (TreeItem ti : commands) { for (TreeItem ti : commands) {
ret += ti.toString(constants) + "\r\n"; ret += ti.toStringSemicoloned(constants) + "\r\n";
} }
ret += hilight("}") + "\r\n"; ret += hilight("}") + "\r\n";
ret += ":loop" + loopBreak; ret += ":loop" + loopBreak;
@@ -70,13 +70,18 @@ public class ForTreeItem extends LoopTreeItem implements Block {
} }
ret += hilight(")") + "\r\n{\r\n"; ret += hilight(")") + "\r\n{\r\n";
for (TreeItem ti : commands) { for (TreeItem ti : commands) {
ret += ti.toString(constants) + "\r\n"; ret += ti.toStringSemicoloned(constants) + "\r\n";
} }
ret += hilight("}") + "\r\n"; ret += hilight("}") + "\r\n";
ret += ":loop" + loopBreak; ret += ":loop" + loopBreak;
return ret; return ret;
} }
@Override
public boolean needsSemicolon() {
return false;
}
public List<ContinueTreeItem> getContinues() { public List<ContinueTreeItem> getContinues() {
List<ContinueTreeItem> ret = new ArrayList<ContinueTreeItem>(); List<ContinueTreeItem> ret = new ArrayList<ContinueTreeItem>();
for (TreeItem ti : commands) { for (TreeItem ti : commands) {
@@ -43,19 +43,24 @@ public class IfTreeItem extends TreeItem implements Block {
String ret = ""; String ret = "";
ret = hilight("if(") + expression.toString(constants) + hilight(")\r\n{\r\n"); ret = hilight("if(") + expression.toString(constants) + hilight(")\r\n{\r\n");
for (TreeItem ti : onTrue) { for (TreeItem ti : onTrue) {
ret += ti.toString(constants) + "\r\n"; ret += ti.toStringSemicoloned(constants) + "\r\n";
} }
ret += hilight("}"); ret += hilight("}");
if (onFalse.size() > 0) { if (onFalse.size() > 0) {
ret += hilight("\r\nelse\r\n{\r\n"); ret += hilight("\r\nelse\r\n{\r\n");
for (TreeItem ti : onFalse) { for (TreeItem ti : onFalse) {
ret += ti.toString(constants) + "\r\n"; ret += ti.toStringSemicoloned(constants) + "\r\n";
} }
ret += hilight("}"); ret += hilight("}");
} }
return ret; return ret;
} }
@Override
public boolean needsSemicolon() {
return false;
}
public List<ContinueTreeItem> getContinues() { public List<ContinueTreeItem> getContinues() {
List<ContinueTreeItem> ret = new ArrayList<ContinueTreeItem>(); List<ContinueTreeItem> ret = new ArrayList<ContinueTreeItem>();
for (TreeItem ti : onTrue) { for (TreeItem ti : onTrue) {
@@ -30,4 +30,8 @@ public abstract class LoopTreeItem extends TreeItem {
this.loopBreak = loopBreak; this.loopBreak = loopBreak;
this.loopContinue = loopContinue; this.loopContinue = loopContinue;
} }
@Override
public boolean needsSemicolon() {
return false;
}
} }
@@ -51,7 +51,7 @@ public class SwitchTreeItem extends LoopTreeItem implements Block {
ret += "case " + caseValues.get(i).toString(constants) + ":\r\n"; ret += "case " + caseValues.get(i).toString(constants) + ":\r\n";
ret += AVM2Code.IDENTOPEN + "\r\n"; ret += AVM2Code.IDENTOPEN + "\r\n";
for (int j = 0; j < caseCommands.get(i).size(); j++) { for (int j = 0; j < caseCommands.get(i).size(); j++) {
ret += caseCommands.get(i).get(j).toString(constants) + "\r\n"; ret += caseCommands.get(i).get(j).toStringSemicoloned(constants) + "\r\n";
} }
ret += AVM2Code.IDENTCLOSE + "\r\n"; ret += AVM2Code.IDENTCLOSE + "\r\n";
} }
@@ -59,7 +59,7 @@ public class SwitchTreeItem extends LoopTreeItem implements Block {
ret += hilight("default") + ":\r\n"; ret += hilight("default") + ":\r\n";
ret += AVM2Code.IDENTOPEN + "\r\n"; ret += AVM2Code.IDENTOPEN + "\r\n";
for (int j = 0; j < defaultCommands.size(); j++) { for (int j = 0; j < defaultCommands.size(); j++) {
ret += defaultCommands.get(j).toString(constants) + "\r\n"; ret += defaultCommands.get(j).toStringSemicoloned(constants) + "\r\n";
} }
ret += AVM2Code.IDENTCLOSE + "\r\n"; ret += AVM2Code.IDENTCLOSE + "\r\n";
} }
@@ -68,6 +68,11 @@ public class SwitchTreeItem extends LoopTreeItem implements Block {
return ret; return ret;
} }
@Override
public boolean needsSemicolon() {
return false;
}
public List<ContinueTreeItem> getContinues() { public List<ContinueTreeItem> getContinues() {
List<ContinueTreeItem> ret = new ArrayList<ContinueTreeItem>(); List<ContinueTreeItem> ret = new ArrayList<ContinueTreeItem>();
@@ -46,21 +46,21 @@ public class TryTreeItem extends TreeItem implements Block {
String ret = ""; String ret = "";
ret += "try\r\n{\r\n"; ret += "try\r\n{\r\n";
for (TreeItem ti : tryCommands) { for (TreeItem ti : tryCommands) {
ret += ti.toString(constants) + "\r\n"; ret += ti.toStringSemicoloned(constants) + "\r\n";
} }
ret += "}"; ret += "}";
for (int e = 0; e < catchExceptions.size(); e++) { for (int e = 0; e < catchExceptions.size(); e++) {
ret += "\r\ncatch(" + catchExceptions.get(e).getVarName(constants) + ":" + catchExceptions.get(e).getTypeName(constants) + ")\r\n{\r\n"; ret += "\r\ncatch(" + catchExceptions.get(e).getVarName(constants) + ":" + catchExceptions.get(e).getTypeName(constants) + ")\r\n{\r\n";
List<TreeItem> commands = catchCommands.get(e); List<TreeItem> commands = catchCommands.get(e);
for (TreeItem ti : commands) { for (TreeItem ti : commands) {
ret += ti.toString(constants) + "\r\n"; ret += ti.toStringSemicoloned(constants) + "\r\n";
} }
ret += "}"; ret += "}";
} }
if (finallyCommands.size() > 0) { if (finallyCommands.size() > 0) {
ret += "\r\nfinally\r\n{\r\n"; ret += "\r\nfinally\r\n{\r\n";
for (TreeItem ti : finallyCommands) { for (TreeItem ti : finallyCommands) {
ret += ti.toString(constants) + "\r\n"; ret += ti.toStringSemicoloned(constants) + "\r\n";
} }
ret += "}"; ret += "}";
} }
@@ -99,4 +99,9 @@ public class TryTreeItem extends TreeItem implements Block {
} }
return ret; return ret;
} }
@Override
public boolean needsSemicolon() {
return false;
}
} }
@@ -43,7 +43,7 @@ public class WhileTreeItem extends LoopTreeItem implements Block {
ret += "loop" + loopBreak + ":\r\n"; ret += "loop" + loopBreak + ":\r\n";
ret += hilight("while(") + expression.toString(constants) + hilight(")") + "\r\n{\r\n"; ret += hilight("while(") + expression.toString(constants) + hilight(")") + "\r\n{\r\n";
for (TreeItem ti : commands) { for (TreeItem ti : commands) {
ret += ti.toString(constants) + "\r\n"; ret += ti.toStringSemicoloned(constants) + "\r\n";
} }
ret += hilight("}") + "\r\n"; ret += hilight("}") + "\r\n";
ret += ":loop" + loopBreak; ret += ":loop" + loopBreak;
@@ -62,4 +62,9 @@ public class WhileTreeItem extends LoopTreeItem implements Block {
} }
return ret; return ret;
} }
@Override
public boolean needsSemicolon() {
return false;
}
} }
@@ -86,6 +86,7 @@ public class MethodBody implements Cloneable {
try { try {
HashMap<Integer,String> localRegNames=code.getLocalRegNamesFromDebug(abc); HashMap<Integer,String> localRegNames=code.getLocalRegNamesFromDebug(abc);
s += code.toSource(isStatic, classIndex, abc, constants, method_info, this, hilight); s += code.toSource(isStatic, classIndex, abc, constants, method_info, this, hilight);
s=s.trim();
if(hilight) if(hilight)
{ {
s=Highlighting.hilighMethod(s, this.method_info); s=Highlighting.hilighMethod(s, this.method_info);
@@ -36,7 +36,7 @@ public class BreakTreeItem extends TreeItem {
@Override @Override
public String toString(ConstantPool constants) { public String toString(ConstantPool constants) {
return hilight("break") + " loop" + loopPos + ";"; return hilight("break") + " loop" + loopPos;
} }
} }
@@ -37,7 +37,7 @@ public class ContinueTreeItem extends TreeItem {
@Override @Override
public String toString(ConstantPool constants) { public String toString(ConstantPool constants) {
return hilight(isBreak ? "break" : "continue") + " " + (isKnown ? "loop" : "unk") + loopPos + ";"; return hilight(isBreak ? "break" : "continue") + " " + (isKnown ? "loop" : "unk") + loopPos;
} }
} }
@@ -31,7 +31,7 @@ public class DefineLocalTreeItem extends TreeItem {
@Override @Override
public String toString(ConstantPool constants) { public String toString(ConstantPool constants) {
if (value == null) return "var " + stripQuotes(name) + ";"; if (value == null) return "var " + stripQuotes(name);
return "var " + stripQuotes(name) + "=" + value.toString(constants) + ";"; return "var " + stripQuotes(name) + "=" + value.toString(constants);
} }
} }