mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-06-22 03:15:41 +00:00
Issue #382 AS3: Adding new trait
This commit is contained in:
@@ -35,6 +35,7 @@ import com.jpexs.decompiler.flash.helpers.collections.MyEntry;
|
||||
import com.jpexs.decompiler.graph.Graph;
|
||||
import java.io.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
@@ -63,6 +64,20 @@ public class ABC {
|
||||
protected HashSet<EventListener> listeners = new HashSet<>();
|
||||
private static final Logger logger = Logger.getLogger(ABC.class.getName());
|
||||
|
||||
public int addMethodBody(MethodBody body) {
|
||||
bodies = Arrays.copyOf(bodies, bodies.length + 1);
|
||||
bodies[bodies.length - 1] = body;
|
||||
bodyIdxFromMethodIdx = Arrays.copyOf(bodyIdxFromMethodIdx, bodyIdxFromMethodIdx.length + 1);
|
||||
bodyIdxFromMethodIdx[bodyIdxFromMethodIdx.length - 1] = body.method_info;
|
||||
return bodies.length - 1;
|
||||
}
|
||||
|
||||
public int addMethodInfo(MethodInfo mi) {
|
||||
method_info = Arrays.copyOf(method_info, method_info.length + 1);
|
||||
method_info[method_info.length - 1] = mi;
|
||||
return method_info.length - 1;
|
||||
}
|
||||
|
||||
public void addEventListener(EventListener listener) {
|
||||
listeners.add(listener);
|
||||
}
|
||||
@@ -196,7 +211,7 @@ public class ABC {
|
||||
Set<Integer> namespaceUsages = getNsStringUsages();
|
||||
int strIndex = constants.constant_multiname[multinameIndex].name_index;
|
||||
if (stringUsages.contains(strIndex) || namespaceUsages.contains(strIndex)) { //name is used elsewhere as string literal
|
||||
strIndex = constants.forceGetStringId(newname);
|
||||
strIndex = constants.getStringId(newname, true);
|
||||
constants.constant_multiname[multinameIndex].name_index = strIndex;
|
||||
} else {
|
||||
constants.constant_string[strIndex] = newname;
|
||||
@@ -256,11 +271,11 @@ public class ABC {
|
||||
name = fullname.substring(fullname.lastIndexOf(".") + 1);
|
||||
}
|
||||
if (!pkg.equals("")) {
|
||||
int pkgStrIndex = constants.forceGetStringId(pkg);
|
||||
int pkgStrIndex = constants.getStringId(pkg, true);
|
||||
pkgStrIndex = deobfuscatePackageName(stringUsageTypes, stringUsages, namesMap, pkgStrIndex, renameType);
|
||||
pkg = constants.constant_string[pkgStrIndex];
|
||||
}
|
||||
int nameStrIndex = constants.forceGetStringId(name);
|
||||
int nameStrIndex = constants.getStringId(name, true);
|
||||
nameStrIndex = deobfuscateName(stringUsageTypes, stringUsages, namespaceUsages, namesMap, nameStrIndex, true, renameType);
|
||||
name = constants.constant_string[nameStrIndex];
|
||||
String fullChanged = "";
|
||||
@@ -268,7 +283,7 @@ public class ABC {
|
||||
fullChanged = pkg + ".";
|
||||
}
|
||||
fullChanged += name;
|
||||
strIndex = constants.forceGetStringId(fullChanged);
|
||||
strIndex = constants.getStringId(fullChanged, true);
|
||||
body.code.code.get(ip - 1).operands[0] = strIndex;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1069,6 +1069,9 @@ public class AVM2Code implements Serializable {
|
||||
}
|
||||
|
||||
public int fixIPAfterDebugLine(int ip) {
|
||||
if (code.isEmpty()) {
|
||||
return ip;
|
||||
}
|
||||
if (ip >= code.size()) {
|
||||
return code.size() - 1;
|
||||
}
|
||||
|
||||
@@ -82,6 +82,19 @@ public class ConstantPool {
|
||||
return constant_string.length - 1;
|
||||
}
|
||||
|
||||
public int getNamespaceId(Namespace val, int index) {
|
||||
for (int n = 1; n < constant_namespace.length; n++) {
|
||||
Namespace ns = constant_namespace[n];
|
||||
if (ns.name_index == val.name_index && (ns.kind == val.kind)) {
|
||||
if (index == 0) {
|
||||
return n;
|
||||
}
|
||||
index--;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int getIntId(long value) {
|
||||
for (int i = 1; i < constant_int.length; i++) {
|
||||
if (constant_int[i] == value) {
|
||||
@@ -109,42 +122,82 @@ public class ConstantPool {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int getStringId(String s) {
|
||||
public int getStringId(String val) {
|
||||
for (int i = 1; i < constant_string.length; i++) {
|
||||
if (constant_string[i].equals(s)) {
|
||||
if (constant_string[i].equals(val)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int forceGetStringId(String val) {
|
||||
public int getMultinameId(Multiname val) {
|
||||
loopm:
|
||||
for (int m = 1; m < constant_multiname.length; m++) {
|
||||
Multiname mul = constant_multiname[m];
|
||||
if (mul.kind == val.kind && mul.name_index == val.name_index && mul.namespace_index == val.namespace_index && mul.namespace_set_index == val.namespace_set_index && mul.qname_index == val.qname_index && mul.params.size() == val.params.size()) {
|
||||
for (int p = 0; p < mul.params.size(); p++) {
|
||||
if (mul.params.get(p) != val.params.get(p)) {
|
||||
continue loopm;
|
||||
}
|
||||
}
|
||||
return m;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int getQnameId(String name, int namespaceKind, String namespaceName, boolean add) {
|
||||
return getMultinameId(new Multiname(Multiname.QNAME, getStringId(name, add), getNamespaceId(new Namespace(namespaceKind, getStringId(namespaceName, add)), 0, add), -1, -1, new ArrayList<Integer>()), add);
|
||||
}
|
||||
|
||||
public int getPublicQnameId(String name, boolean add) {
|
||||
return getQnameId(name, Namespace.KIND_PACKAGE, "", add);
|
||||
}
|
||||
|
||||
public int getMultinameId(Multiname val, boolean add) {
|
||||
int id = getMultinameId(val);
|
||||
if (add && id == 0) {
|
||||
id = addMultiname(val);
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
public int getStringId(String val, boolean add) {
|
||||
int id = getStringId(val);
|
||||
if (id == 0) {
|
||||
if (add && id == 0) {
|
||||
id = addString(val);
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
public int forceGetIntId(long val) {
|
||||
public int getIntId(long val, boolean add) {
|
||||
int id = getIntId(val);
|
||||
if (id == 0) {
|
||||
if (add && id == 0) {
|
||||
id = addInt(val);
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
public int forceGetUIntId(long val) {
|
||||
public int getNamespaceId(Namespace val, int index, boolean add) {
|
||||
int id = getNamespaceId(val, index);
|
||||
if (add && id == 0) {
|
||||
id = addNamespace(val);
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
public int getUIntId(long val, boolean add) {
|
||||
int id = getUIntId(val);
|
||||
if (id == 0) {
|
||||
if (add && id == 0) {
|
||||
id = addUInt(val);
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
public int forceGetDoubleId(double val) {
|
||||
public int getDoubleId(double val, boolean add) {
|
||||
int id = getDoubleId(val);
|
||||
if (id == 0) {
|
||||
if (add && id == 0) {
|
||||
id = addDouble(val);
|
||||
}
|
||||
return id;
|
||||
|
||||
@@ -251,16 +251,7 @@ public class ASM3Parser {
|
||||
}
|
||||
expected(ParsedSymbol.TYPE_PARENT_CLOSE, ")", lexer);
|
||||
|
||||
for (int n = 1; n < constants.constant_namespace.length; n++) {
|
||||
Namespace ns = constants.constant_namespace[n];
|
||||
if (ns.getName(constants).equals(name.value) && (ns.kind == kind)) {
|
||||
if (index == 0) {
|
||||
return n;
|
||||
}
|
||||
index--;
|
||||
}
|
||||
}
|
||||
return constants.addNamespace(new Namespace(kind, constants.forceGetStringId((String) name.value)));
|
||||
return constants.getNamespaceId(new Namespace(kind, constants.getStringId((String) name.value, true)), index, true);
|
||||
}
|
||||
|
||||
private static int parseMultiName(ConstantPool constants, Flasm3Lexer lexer) throws ParseException, IOException {
|
||||
@@ -320,7 +311,7 @@ public class ASM3Parser {
|
||||
expected(ParsedSymbol.TYPE_COMMA, ",", lexer);
|
||||
ParsedSymbol name = lexer.lex();
|
||||
expected(name, ParsedSymbol.TYPE_STRING, "String");
|
||||
name_index = constants.forceGetStringId((String) name.value);
|
||||
name_index = constants.getStringId((String) name.value, true);
|
||||
expected(ParsedSymbol.TYPE_PARENT_CLOSE, ")", lexer);
|
||||
break;
|
||||
case ParsedSymbol.TYPE_KEYWORD_RTQNAME:
|
||||
@@ -328,7 +319,7 @@ public class ASM3Parser {
|
||||
expected(ParsedSymbol.TYPE_PARENT_OPEN, "(", lexer);
|
||||
ParsedSymbol rtqName = lexer.lex();
|
||||
expected(rtqName, ParsedSymbol.TYPE_STRING, "String");
|
||||
name_index = constants.forceGetStringId((String) rtqName.value);
|
||||
name_index = constants.getStringId((String) rtqName.value, true);
|
||||
expected(ParsedSymbol.TYPE_PARENT_CLOSE, ")", lexer);
|
||||
break;
|
||||
case ParsedSymbol.TYPE_KEYWORD_RTQNAMEL:
|
||||
@@ -341,7 +332,7 @@ public class ASM3Parser {
|
||||
expected(ParsedSymbol.TYPE_PARENT_OPEN, "(", lexer);
|
||||
ParsedSymbol mName = lexer.lex();
|
||||
expected(mName, ParsedSymbol.TYPE_STRING, "String");
|
||||
name_index = constants.forceGetStringId((String) mName.value);
|
||||
name_index = constants.getStringId((String) mName.value, true);
|
||||
expected(ParsedSymbol.TYPE_COMMA, ",", lexer);
|
||||
namespace_set_index = parseNamespaceSet(constants, lexer);
|
||||
expected(ParsedSymbol.TYPE_PARENT_CLOSE, ")", lexer);
|
||||
@@ -366,20 +357,8 @@ public class ASM3Parser {
|
||||
expected(ParsedSymbol.TYPE_PARENT_CLOSE, ")", lexer);
|
||||
break;
|
||||
}
|
||||
loopm:
|
||||
for (int m = 1; m < constants.constant_multiname.length; m++) {
|
||||
Multiname mul = constants.constant_multiname[m];
|
||||
if (mul.kind == kind && mul.name_index == name_index && mul.namespace_index == namespace_index && mul.namespace_set_index == namespace_set_index && mul.qname_index == qname_index && mul.params.size() == params.size()) {
|
||||
for (int p = 0; p < mul.params.size(); p++) {
|
||||
if (mul.params.get(p) != params.get(p)) {
|
||||
continue loopm;
|
||||
}
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
}
|
||||
return constants.addMultiname(new Multiname(kind, name_index, namespace_index, namespace_set_index, qname_index, params));
|
||||
return constants.getMultinameId(new Multiname(kind, name_index, namespace_index, namespace_set_index, qname_index, params), true);
|
||||
}
|
||||
|
||||
public static ValueKind parseValue(ConstantPool constants, Flasm3Lexer lexer) throws IOException, ParseException {
|
||||
@@ -394,7 +373,7 @@ public class ASM3Parser {
|
||||
value = lexer.lex();
|
||||
expected(value, ParsedSymbol.TYPE_INTEGER, "Integer");
|
||||
expected(ParsedSymbol.TYPE_PARENT_CLOSE, ")", lexer);
|
||||
value_index = constants.forceGetIntId((Long) value.value);
|
||||
value_index = constants.getIntId((Long) value.value, true);
|
||||
break;
|
||||
case ParsedSymbol.TYPE_KEYWORD_UINTEGER:
|
||||
value_kind = ValueKind.CONSTANT_UInt;
|
||||
@@ -402,7 +381,7 @@ public class ASM3Parser {
|
||||
value = lexer.lex();
|
||||
expected(value, ParsedSymbol.TYPE_INTEGER, "UInteger");
|
||||
expected(ParsedSymbol.TYPE_PARENT_CLOSE, ")", lexer);
|
||||
value_index = constants.forceGetUIntId((Long) value.value);
|
||||
value_index = constants.getUIntId((Long) value.value, true);
|
||||
break;
|
||||
case ParsedSymbol.TYPE_KEYWORD_DOUBLE:
|
||||
value_kind = ValueKind.CONSTANT_Double;
|
||||
@@ -410,7 +389,7 @@ public class ASM3Parser {
|
||||
value = lexer.lex();
|
||||
expected(value, ParsedSymbol.TYPE_FLOAT, "Double");
|
||||
expected(ParsedSymbol.TYPE_PARENT_CLOSE, ")", lexer);
|
||||
value_index = constants.forceGetDoubleId((Double) value.value);
|
||||
value_index = constants.getDoubleId((Double) value.value, true);
|
||||
break;
|
||||
/*case ParsedSymbol.TYPE_KEYWORD_DECIMAL:
|
||||
value_kind = ValueKind.CONSTANT_Decimal;
|
||||
@@ -421,7 +400,7 @@ public class ASM3Parser {
|
||||
value = lexer.lex();
|
||||
expected(value, ParsedSymbol.TYPE_STRING, "String");
|
||||
expected(ParsedSymbol.TYPE_PARENT_CLOSE, ")", lexer);
|
||||
value_index = constants.forceGetStringId((String) value.value);
|
||||
value_index = constants.getStringId((String) value.value, true);
|
||||
break;
|
||||
case ParsedSymbol.TYPE_KEYWORD_TRUE:
|
||||
value_kind = ValueKind.CONSTANT_True;
|
||||
@@ -540,7 +519,7 @@ public class ASM3Parser {
|
||||
if (symb.type == ParsedSymbol.TYPE_KEYWORD_NAME) {
|
||||
symb = lexer.lex();
|
||||
expected(symb, ParsedSymbol.TYPE_STRING, "String");
|
||||
info.name_index = constants.forceGetStringId((String) symb.value);
|
||||
info.name_index = constants.getStringId((String) symb.value, true);
|
||||
continue;
|
||||
}
|
||||
if (symb.type == ParsedSymbol.TYPE_KEYWORD_PARAM) {
|
||||
@@ -550,7 +529,7 @@ public class ASM3Parser {
|
||||
if (symb.type == ParsedSymbol.TYPE_KEYWORD_PARAMNAME) {
|
||||
symb = lexer.lex();
|
||||
expected(symb, ParsedSymbol.TYPE_STRING, "String");
|
||||
paramNames.add(constants.forceGetStringId((String) symb.value));
|
||||
paramNames.add(constants.getStringId((String) symb.value, true));
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -62,13 +62,13 @@ public class MethodInfoParser {
|
||||
int id = 0;
|
||||
switch (symbValue.type) {
|
||||
case ParsedSymbol.TYPE_INTEGER:
|
||||
value = new ValueKind(abc.constants.forceGetIntId((Long) symbValue.value), ValueKind.CONSTANT_Int);
|
||||
value = new ValueKind(abc.constants.getIntId((Long) symbValue.value, true), ValueKind.CONSTANT_Int);
|
||||
break;
|
||||
case ParsedSymbol.TYPE_FLOAT:
|
||||
value = new ValueKind(abc.constants.forceGetDoubleId((Double) symbValue.value), ValueKind.CONSTANT_Double);
|
||||
value = new ValueKind(abc.constants.getDoubleId((Double) symbValue.value, true), ValueKind.CONSTANT_Double);
|
||||
break;
|
||||
case ParsedSymbol.TYPE_STRING:
|
||||
value = new ValueKind(abc.constants.forceGetStringId((String) symbValue.value), ValueKind.CONSTANT_Utf8);
|
||||
value = new ValueKind(abc.constants.getStringId((String) symbValue.value, true), ValueKind.CONSTANT_Utf8);
|
||||
break;
|
||||
case ParsedSymbol.TYPE_TRUE:
|
||||
value = new ValueKind(0, ValueKind.CONSTANT_True);
|
||||
@@ -200,13 +200,13 @@ public class MethodInfoParser {
|
||||
int id = 0;
|
||||
switch (symbValue.type) {
|
||||
case ParsedSymbol.TYPE_INTEGER:
|
||||
optionalValues.add(new ValueKind(abc.constants.forceGetIntId((Long) symbValue.value), ValueKind.CONSTANT_Int));
|
||||
optionalValues.add(new ValueKind(abc.constants.getIntId((Long) symbValue.value, true), ValueKind.CONSTANT_Int));
|
||||
break;
|
||||
case ParsedSymbol.TYPE_FLOAT:
|
||||
optionalValues.add(new ValueKind(abc.constants.forceGetDoubleId((Double) symbValue.value), ValueKind.CONSTANT_Double));
|
||||
optionalValues.add(new ValueKind(abc.constants.getDoubleId((Double) symbValue.value, true), ValueKind.CONSTANT_Double));
|
||||
break;
|
||||
case ParsedSymbol.TYPE_STRING:
|
||||
optionalValues.add(new ValueKind(abc.constants.forceGetStringId((String) symbValue.value), ValueKind.CONSTANT_Utf8));
|
||||
optionalValues.add(new ValueKind(abc.constants.getStringId((String) symbValue.value, true), ValueKind.CONSTANT_Utf8));
|
||||
break;
|
||||
case ParsedSymbol.TYPE_TRUE:
|
||||
optionalValues.add(new ValueKind(0, ValueKind.CONSTANT_True));
|
||||
@@ -304,7 +304,7 @@ public class MethodInfoParser {
|
||||
update.setFlagHas_paramnames();
|
||||
update.paramNames = new int[paramNames.size()];
|
||||
for (int p = 0; p < paramNames.size(); p++) {
|
||||
update.paramNames[p] = abc.constants.forceGetStringId(paramNames.get(p));
|
||||
update.paramNames[p] = abc.constants.getStringId(paramNames.get(p), true);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -34,6 +34,24 @@ public class Namespace {
|
||||
public int kind;
|
||||
public int name_index;
|
||||
|
||||
public static String kindToStr(int kind) {
|
||||
for (int i = 0; i < nameSpaceKinds.length; i++) {
|
||||
if (nameSpaceKinds[i] == kind) {
|
||||
return nameSpaceKindNames[i];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String kindToPrefix(int kind) {
|
||||
for (int i = 0; i < nameSpaceKinds.length; i++) {
|
||||
if (nameSpaceKinds[i] == kind) {
|
||||
return namePrefixes[i];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Namespace(int kind, int name_index) {
|
||||
this.kind = kind;
|
||||
this.name_index = name_index;
|
||||
|
||||
@@ -92,7 +92,7 @@ public class TraitSlotConst extends Trait implements TraitWithSlot {
|
||||
}
|
||||
|
||||
if (assignedValue != null) {
|
||||
valueStr = Highlighting.trim(assignedValue.toString(true, abc.constants, new HashMap<Integer, String>(), fullyQualifiedNames));
|
||||
valueStr = Highlighting.trim(assignedValue.toString(highlight, abc.constants, new HashMap<Integer, String>(), fullyQualifiedNames));
|
||||
if (highlight && (parent instanceof TraitClass)) {
|
||||
TraitClass tc = (TraitClass) parent;
|
||||
int traitInitId = abc.class_info[tc.class_info].static_traits.traits.length
|
||||
|
||||
@@ -21,6 +21,7 @@ import com.jpexs.decompiler.flash.helpers.hilight.Highlighting;
|
||||
import com.jpexs.decompiler.flash.tags.ABCContainerTag;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
@@ -34,6 +35,12 @@ public class Traits implements Serializable {
|
||||
|
||||
public Trait[] traits = new Trait[0];
|
||||
|
||||
public int addTrait(Trait t) {
|
||||
traits = Arrays.copyOf(traits, traits.length + 1);
|
||||
traits[traits.length - 1] = t;
|
||||
return traits.length - 1;
|
||||
}
|
||||
|
||||
public int removeTraps(int scriptIndex, int classIndex, boolean isStatic, ABC abc, String path) {
|
||||
int ret = 0;
|
||||
for (Trait t : traits) {
|
||||
|
||||
@@ -21,6 +21,17 @@ import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.ClassPath;
|
||||
import com.jpexs.decompiler.flash.abc.ScriptPack;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
|
||||
import com.jpexs.decompiler.flash.abc.types.ABCException;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodBody;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
|
||||
import com.jpexs.decompiler.flash.abc.types.Multiname;
|
||||
import com.jpexs.decompiler.flash.abc.types.Namespace;
|
||||
import com.jpexs.decompiler.flash.abc.types.ValueKind;
|
||||
import com.jpexs.decompiler.flash.abc.types.traits.Trait;
|
||||
import com.jpexs.decompiler.flash.abc.types.traits.TraitMethodGetterSetter;
|
||||
import com.jpexs.decompiler.flash.abc.types.traits.TraitSlotConst;
|
||||
import com.jpexs.decompiler.flash.abc.types.traits.Traits;
|
||||
import static com.jpexs.decompiler.flash.gui.AppStrings.translate;
|
||||
import com.jpexs.decompiler.flash.gui.Freed;
|
||||
import com.jpexs.decompiler.flash.gui.HeaderLabel;
|
||||
@@ -90,6 +101,8 @@ public class ABCPanel extends JPanel implements ItemListener, ActionListener, Fr
|
||||
private String searchFor;
|
||||
private boolean searchIgnoreCase;
|
||||
private boolean searchRegexp;
|
||||
private NewTraitDialog newTraitDialog;
|
||||
public JLabel scriptNameLabel;
|
||||
|
||||
public boolean search(String txt, boolean ignoreCase, boolean regexp) {
|
||||
if ((txt != null) && (!txt.equals(""))) {
|
||||
@@ -283,9 +296,31 @@ public class ABCPanel extends JPanel implements ItemListener, ActionListener, Fr
|
||||
|
||||
decompiledScrollPane = new JScrollPane(decompiledTextArea);
|
||||
|
||||
|
||||
JPanel iconDecPanel = new JPanel();
|
||||
iconDecPanel.setLayout(new BoxLayout(iconDecPanel, BoxLayout.Y_AXIS));
|
||||
JPanel iconsPanel = new JPanel();
|
||||
iconsPanel.setLayout(new BoxLayout(iconsPanel, BoxLayout.X_AXIS));
|
||||
|
||||
JButton newTraitButton = new JButton(View.getIcon("traitadd16"));
|
||||
newTraitButton.setMargin(new Insets(5, 5, 5, 5));
|
||||
newTraitButton.addActionListener(this);
|
||||
newTraitButton.setActionCommand("ADDTRAIT");
|
||||
newTraitButton.setToolTipText(translate("button.addtrait"));
|
||||
iconsPanel.add(newTraitButton);
|
||||
|
||||
|
||||
scriptNameLabel = new JLabel("-");
|
||||
scriptNameLabel.setAlignmentX(0);
|
||||
iconsPanel.setAlignmentX(0);
|
||||
decompiledScrollPane.setAlignmentX(0);
|
||||
iconDecPanel.add(scriptNameLabel);
|
||||
iconDecPanel.add(iconsPanel);
|
||||
iconDecPanel.add(decompiledScrollPane);
|
||||
|
||||
JPanel decPanel = new JPanel(new BorderLayout());
|
||||
decPanel.add(searchPanel, BorderLayout.NORTH);
|
||||
decPanel.add(decompiledScrollPane, BorderLayout.CENTER);
|
||||
decPanel.add(iconDecPanel, BorderLayout.CENTER);
|
||||
detailPanel = new DetailPanel(this);
|
||||
JPanel panB = new JPanel();
|
||||
panB.setLayout(new BorderLayout());
|
||||
@@ -535,25 +570,124 @@ public class ABCPanel extends JPanel implements ItemListener, ActionListener, Fr
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (e.getActionCommand().equals("FILTERSCRIPT")) {
|
||||
doFilter();
|
||||
}
|
||||
if (e.getActionCommand().equals("SEARCHCANCEL")) {
|
||||
foundPos = 0;
|
||||
searchPanel.setVisible(false);
|
||||
found = new ArrayList<>();
|
||||
searchFor = null;
|
||||
}
|
||||
if (e.getActionCommand().equals("SEARCHPREV")) {
|
||||
foundPos--;
|
||||
if (foundPos < 0) {
|
||||
foundPos += found.size();
|
||||
}
|
||||
updateSearchPos();
|
||||
}
|
||||
if (e.getActionCommand().equals("SEARCHNEXT")) {
|
||||
foundPos = (foundPos + 1) % found.size();
|
||||
updateSearchPos();
|
||||
switch (e.getActionCommand()) {
|
||||
case "ADDTRAIT":
|
||||
int class_index = decompiledTextArea.getClassIndex();
|
||||
if (class_index < 0) {
|
||||
return;
|
||||
}
|
||||
if (newTraitDialog == null) {
|
||||
newTraitDialog = new NewTraitDialog();
|
||||
}
|
||||
int void_type = abc.constants.getPublicQnameId("void", true);//abc.constants.forceGetMultinameId(new Multiname(Multiname.QNAME, abc.constants.forceGetStringId("void"), abc.constants.forceGetNamespaceId(new Namespace(Namespace.KIND_PACKAGE, abc.constants.forceGetStringId("")), 0), -1, -1, new ArrayList<Integer>()));
|
||||
int int_type = abc.constants.getPublicQnameId("int", true); //abc.constants.forceGetMultinameId(new Multiname(Multiname.QNAME, abc.constants.forceGetStringId("int"), abc.constants.forceGetNamespaceId(new Namespace(Namespace.KIND_PACKAGE, abc.constants.forceGetStringId("")), 0), -1, -1, new ArrayList<Integer>()));
|
||||
|
||||
Trait t = null;
|
||||
int kind;
|
||||
int nskind;
|
||||
String name = null;
|
||||
boolean isStatic;
|
||||
Multiname m;
|
||||
|
||||
boolean again = false;
|
||||
loopm:
|
||||
do {
|
||||
if (again) {
|
||||
View.showMessageDialog(null, translate("error.trait.exists").replace("%name%", name), translate("error"), JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
again = false;
|
||||
if (!newTraitDialog.display()) {
|
||||
return;
|
||||
}
|
||||
kind = newTraitDialog.getTraitType();
|
||||
nskind = newTraitDialog.getNamespaceKind();
|
||||
name = newTraitDialog.getTraitName();
|
||||
isStatic = newTraitDialog.getStatic();
|
||||
m = new Multiname(Multiname.QNAME, abc.constants.getStringId(name, true), abc.constants.getNamespaceId(new Namespace(nskind, abc.constants.getStringId("", true)), 0, true), -1, -1, new ArrayList<Integer>());
|
||||
int mid = abc.constants.getMultinameId(m);
|
||||
if (mid == 0) {
|
||||
break;
|
||||
}
|
||||
for (Trait tr : abc.class_info[class_index].static_traits.traits) {
|
||||
if (tr.name_index == mid) {
|
||||
again = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (Trait tr : abc.instance_info[class_index].instance_traits.traits) {
|
||||
if (tr.name_index == mid) {
|
||||
again = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while (again);
|
||||
switch (kind) {
|
||||
case Trait.TRAIT_GETTER:
|
||||
case Trait.TRAIT_SETTER:
|
||||
case Trait.TRAIT_METHOD:
|
||||
TraitMethodGetterSetter tm = new TraitMethodGetterSetter();
|
||||
MethodInfo mi = new MethodInfo(new int[0], void_type, abc.constants.getStringId(name, true), 0, new ValueKind[0], new int[0]);
|
||||
int method_info = abc.addMethodInfo(mi);
|
||||
tm.method_info = method_info;
|
||||
MethodBody body = new MethodBody();
|
||||
body.method_info = method_info;
|
||||
body.init_scope_depth = 1;
|
||||
body.max_regs = 1;
|
||||
body.max_scope_depth = 1;
|
||||
body.max_stack = 1;
|
||||
body.exceptions = new ABCException[0];
|
||||
AVM2Code code = new AVM2Code();
|
||||
body.code = code;
|
||||
Traits traits = new Traits();
|
||||
traits.traits = new Trait[0];
|
||||
body.traits = traits;
|
||||
abc.addMethodBody(body);
|
||||
t = tm;
|
||||
break;
|
||||
case Trait.TRAIT_SLOT:
|
||||
case Trait.TRAIT_CONST:
|
||||
TraitSlotConst ts = new TraitSlotConst();
|
||||
ts.type_index = int_type;
|
||||
ts.value_kind = ValueKind.CONSTANT_Int;
|
||||
ts.value_index = abc.constants.getIntId(0, true);
|
||||
t = ts;
|
||||
break;
|
||||
}
|
||||
if (t != null) {
|
||||
t.kindType = kind;
|
||||
t.name_index = abc.constants.getMultinameId(m, true);
|
||||
int traitId;
|
||||
if (isStatic) {
|
||||
traitId = abc.class_info[class_index].static_traits.addTrait(t);
|
||||
} else {
|
||||
traitId = abc.class_info[class_index].static_traits.traits.length + abc.instance_info[class_index].instance_traits.addTrait(t);
|
||||
}
|
||||
reload();
|
||||
decompiledTextArea.gotoTrait(traitId);
|
||||
}
|
||||
|
||||
break;
|
||||
case "FILTERSCRIPT":
|
||||
doFilter();
|
||||
break;
|
||||
case "SEARCHCANCEL":
|
||||
foundPos = 0;
|
||||
searchPanel.setVisible(false);
|
||||
found = new ArrayList<>();
|
||||
searchFor = null;
|
||||
break;
|
||||
case "SEARCHPREV":
|
||||
foundPos--;
|
||||
if (foundPos < 0) {
|
||||
foundPos += found.size();
|
||||
}
|
||||
updateSearchPos();
|
||||
break;
|
||||
case "SEARCHNEXT":
|
||||
foundPos = (foundPos + 1) % found.size();
|
||||
updateSearchPos();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -460,6 +460,7 @@ public class DecompiledEditorPane extends LineMarkedEditorPane implements CaretL
|
||||
}
|
||||
|
||||
public void setScript(ScriptPack scriptLeaf, List<ABCContainerTag> abcList) {
|
||||
abcPanel.scriptNameLabel.setText(scriptLeaf.getPath().toString());
|
||||
int scriptIndex = scriptLeaf.scriptIndex;
|
||||
ScriptInfo script = null;
|
||||
ABC abc = scriptLeaf.abc;
|
||||
|
||||
@@ -53,7 +53,7 @@ public class DetailPanel extends JPanel implements ActionListener {
|
||||
private boolean editMode = false;
|
||||
private JPanel buttonsPanel;
|
||||
private ABCPanel abcPanel;
|
||||
private JTextArea traitNameLabel;
|
||||
private JLabel traitNameLabel;
|
||||
|
||||
public DetailPanel(ABCPanel abcPanel) {
|
||||
this.abcPanel = abcPanel;
|
||||
@@ -105,10 +105,10 @@ public class DetailPanel extends JPanel implements ActionListener {
|
||||
selectedLabel.setHorizontalAlignment(SwingConstants.CENTER);
|
||||
JPanel topPanel = new JPanel(new BorderLayout());
|
||||
topPanel.add(selectedLabel, BorderLayout.NORTH);
|
||||
traitNameLabel = new JTextArea("");
|
||||
traitNameLabel = new JLabel("");
|
||||
JPanel traitInfoPanel = new JPanel();
|
||||
traitInfoPanel.setLayout(new BoxLayout(traitInfoPanel, BoxLayout.LINE_AXIS));
|
||||
traitInfoPanel.add(new JLabel(" " + translate("abc.detail.traitname")));
|
||||
//traitInfoPanel.add(new JLabel(" " + translate("abc.detail.traitname")));
|
||||
traitInfoPanel.add(traitNameLabel);
|
||||
topPanel.add(traitInfoPanel, BorderLayout.CENTER);
|
||||
add(topPanel, BorderLayout.NORTH);
|
||||
@@ -155,7 +155,7 @@ public class DetailPanel extends JPanel implements ActionListener {
|
||||
if (trait == null) {
|
||||
traitNameLabel.setText("-");
|
||||
} else {
|
||||
traitNameLabel.setText(" " + trait.getName(abcPanel.abc).getName(abcPanel.abc.constants, new ArrayList<String>()) + " Index: " + trait.name_index);
|
||||
traitNameLabel.setText(trait.getName(abcPanel.abc).getName(abcPanel.abc.constants, new ArrayList<String>()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
179
trunk/src/com/jpexs/decompiler/flash/gui/abc/NewTraitDialog.java
Normal file
179
trunk/src/com/jpexs/decompiler/flash/gui/abc/NewTraitDialog.java
Normal file
@@ -0,0 +1,179 @@
|
||||
/*
|
||||
* Copyright (C) 2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.gui.abc;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.types.Namespace;
|
||||
import com.jpexs.decompiler.flash.abc.types.traits.Trait;
|
||||
import com.jpexs.decompiler.flash.gui.AppDialog;
|
||||
import com.jpexs.decompiler.flash.gui.AppStrings;
|
||||
import com.jpexs.decompiler.flash.gui.View;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Container;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JCheckBox;
|
||||
import javax.swing.JComboBox;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.event.AncestorEvent;
|
||||
import javax.swing.event.AncestorListener;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class NewTraitDialog extends AppDialog implements ActionListener {
|
||||
|
||||
private static int modifiers[] = new int[]{
|
||||
Namespace.KIND_PACKAGE,
|
||||
Namespace.KIND_PRIVATE,
|
||||
Namespace.KIND_PROTECTED,
|
||||
Namespace.KIND_NAMESPACE,
|
||||
Namespace.KIND_PACKAGE_INTERNAL,
|
||||
Namespace.KIND_EXPLICIT,
|
||||
Namespace.KIND_STATIC_PROTECTED
|
||||
};
|
||||
private static int types[] = new int[]{
|
||||
Trait.TRAIT_METHOD,
|
||||
Trait.TRAIT_GETTER,
|
||||
Trait.TRAIT_SETTER,
|
||||
Trait.TRAIT_CONST,
|
||||
Trait.TRAIT_SLOT
|
||||
};
|
||||
private JComboBox<String> accessComboBox;
|
||||
private JComboBox<String> typeComboBox;
|
||||
private JCheckBox staticCheckbox;
|
||||
private JTextField nameField;
|
||||
|
||||
public boolean getStatic() {
|
||||
return staticCheckbox.isSelected();
|
||||
}
|
||||
|
||||
public int getNamespaceKind() {
|
||||
return modifiers[accessComboBox.getSelectedIndex()];
|
||||
}
|
||||
|
||||
public int getTraitType() {
|
||||
return types[typeComboBox.getSelectedIndex()];
|
||||
}
|
||||
|
||||
public String getTraitName() {
|
||||
return nameField.getText();
|
||||
}
|
||||
|
||||
public NewTraitDialog() {
|
||||
setSize(500, 300);
|
||||
setTitle(translate("dialog.title"));
|
||||
View.centerScreen(this);
|
||||
View.setWindowIcon(this);
|
||||
Container cnt = getContentPane();
|
||||
cnt.setLayout(new BorderLayout());
|
||||
JPanel optionsPanel = new JPanel(new FlowLayout());
|
||||
//optionsPanel.add(new JLabel(translate("label.type")));
|
||||
typeComboBox = new JComboBox<>(new String[]{
|
||||
translate("type.method"),
|
||||
translate("type.getter"),
|
||||
translate("type.setter"),
|
||||
translate("type.const"),
|
||||
translate("type.slot"),});
|
||||
staticCheckbox = new JCheckBox(translate("checkbox.static"));
|
||||
optionsPanel.add(staticCheckbox);
|
||||
String accessStrings[] = new String[modifiers.length];
|
||||
for (int i = 0; i < accessStrings.length; i++) {
|
||||
String pref = Namespace.kindToPrefix(modifiers[i]);
|
||||
String name = Namespace.kindToStr(modifiers[i]);
|
||||
accessStrings[i] = (pref.equals("") ? "" : pref + " ") + "(" + name + ")";
|
||||
}
|
||||
|
||||
|
||||
//optionsPanel.add(new JLabel(translate("label.access")));
|
||||
accessComboBox = new JComboBox<>(accessStrings);
|
||||
optionsPanel.add(accessComboBox);
|
||||
|
||||
optionsPanel.add(typeComboBox);
|
||||
|
||||
|
||||
//optionsPanel.add(new JLabel(translate("label.name")));
|
||||
|
||||
nameField = new JTextField();
|
||||
nameField.setPreferredSize(new Dimension(300, nameField.getPreferredSize().height));
|
||||
optionsPanel.add(nameField);
|
||||
|
||||
cnt.add(optionsPanel, BorderLayout.CENTER);
|
||||
JPanel buttonsPanel = new JPanel(new FlowLayout());
|
||||
JButton buttonOk = new JButton(AppStrings.translate("button.ok"));
|
||||
buttonOk.setActionCommand("OK");
|
||||
buttonOk.addActionListener(this);
|
||||
JButton buttonCancel = new JButton(AppStrings.translate("button.cancel"));
|
||||
buttonCancel.setActionCommand("CANCEL");
|
||||
buttonCancel.addActionListener(this);
|
||||
buttonsPanel.add(buttonOk);
|
||||
buttonsPanel.add(buttonCancel);
|
||||
cnt.add(buttonsPanel, BorderLayout.SOUTH);
|
||||
pack();
|
||||
setDefaultCloseOperation(HIDE_ON_CLOSE);
|
||||
setModalityType(ModalityType.APPLICATION_MODAL);
|
||||
|
||||
nameField.addAncestorListener(new AncestorListener() {
|
||||
@Override
|
||||
public void ancestorAdded(AncestorEvent event) {
|
||||
JComponent component = event.getComponent();
|
||||
component.requestFocusInWindow();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ancestorRemoved(AncestorEvent event) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ancestorMoved(AncestorEvent event) {
|
||||
}
|
||||
});
|
||||
getRootPane().setDefaultButton(buttonOk);
|
||||
}
|
||||
|
||||
public boolean display() {
|
||||
nameField.setText("");
|
||||
setVisible(true);
|
||||
return result;
|
||||
}
|
||||
private boolean result = false;
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
switch (e.getActionCommand()) {
|
||||
case "OK":
|
||||
if (nameField.getText().trim().equals("")) {
|
||||
View.showMessageDialog(null, translate("error.name"), AppStrings.translate("error"), JOptionPane.ERROR_MESSAGE);
|
||||
return;
|
||||
}
|
||||
result = true;
|
||||
setVisible(false);
|
||||
break;
|
||||
case "CANCEL":
|
||||
result = false;
|
||||
setVisible(false);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -64,15 +64,18 @@ public class TraitsListItem {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String s = "";
|
||||
if ((type != Type.INITIALIZER) && isStatic) {
|
||||
return abc.class_info[classIndex].static_traits.traits[index].convertHeader(null, "", abcTags, abc, true, false, scriptIndex, classIndex, false, new ArrayList<String>(), false);
|
||||
s = abc.class_info[classIndex].static_traits.traits[index].convertHeader(null, "", abcTags, abc, true, false, scriptIndex, classIndex, false, new ArrayList<String>(), false);
|
||||
} else if ((type != Type.INITIALIZER) && (!isStatic)) {
|
||||
return abc.instance_info[classIndex].instance_traits.traits[index].convertHeader(null, "", abcTags, abc, false, false, scriptIndex, classIndex, false, new ArrayList<String>(), false);
|
||||
s = abc.instance_info[classIndex].instance_traits.traits[index].convertHeader(null, "", abcTags, abc, false, false, scriptIndex, classIndex, false, new ArrayList<String>(), false);
|
||||
} else if (!isStatic) {
|
||||
return STR_INSTANCE_INITIALIZER;
|
||||
s = STR_INSTANCE_INITIALIZER;
|
||||
} else {
|
||||
return STR_CLASS_INITIALIZER;
|
||||
s = STR_CLASS_INITIALIZER;
|
||||
}
|
||||
s = s.replaceAll("[ \r\n]+", " ");
|
||||
return s;
|
||||
}
|
||||
|
||||
public Type getType() {
|
||||
|
||||
BIN
trunk/src/com/jpexs/decompiler/flash/gui/graphics/traitadd16.png
Normal file
BIN
trunk/src/com/jpexs/decompiler/flash/gui/graphics/traitadd16.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 671 B |
@@ -355,3 +355,7 @@ preview.stop = Stop
|
||||
message.confirm.removemultiple = Are you sure you want to remove %count% items\n and all objects which depend on it?
|
||||
|
||||
menu.tools.searchcache = Search browsers cache
|
||||
|
||||
#after version 1.7.2u2
|
||||
error.trait.exists = Trait with name "%name%" already exists.
|
||||
button.addtrait = Add trait
|
||||
@@ -359,4 +359,8 @@ preview.stop = Zastavit
|
||||
|
||||
message.confirm.removemultiple = Opravdu chcete odebrat %count% polo\u017eek\n a v\u0161echny objekty kter\u00e9 na nich z\u00e1vis\u00ed?
|
||||
|
||||
menu.tools.searchcache = Prohledat cache prohl\u00ed\u017ee\u010d\u016f
|
||||
menu.tools.searchcache = Prohledat cache prohl\u00ed\u017ee\u010d\u016f
|
||||
|
||||
#after version 1.7.2u2
|
||||
error.trait.exists = Vlastnost s n\u00e1zvem "%name%" ji\u017e existuje.
|
||||
button.addtrait = P\u0159idat vlastnost
|
||||
@@ -0,0 +1,24 @@
|
||||
# Copyright (C) 2013 JPEXS
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
type.method = Method
|
||||
type.getter = Getter
|
||||
type.setter = Setter
|
||||
type.const = Const
|
||||
type.slot = Slot (var)
|
||||
checkbox.static = Static
|
||||
dialog.title = New trait
|
||||
|
||||
error.name = You must specify trait name
|
||||
@@ -0,0 +1,24 @@
|
||||
# Copyright (C) 2013 JPEXS
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
type.method = Metoda
|
||||
type.getter = Getter
|
||||
type.setter = Setter
|
||||
type.const = Konstanta
|
||||
type.slot = Slot (var)
|
||||
checkbox.static = Static
|
||||
dialog.title = Nov\u00e1 vlastnost
|
||||
|
||||
error.name = Mus\u00edte uv\u00e9st n\u00e1zev vlastnosti
|
||||
Reference in New Issue
Block a user