Issue #382 AS3: Adding new trait

This commit is contained in:
Jindra Petk
2013-09-16 22:51:56 +02:00
parent 4a712230ab
commit dd27bfafe1
18 changed files with 531 additions and 83 deletions

View File

@@ -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;
}
}

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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;

View File

@@ -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

View File

@@ -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) {

View File

@@ -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;
}
}
}

View File

@@ -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;

View File

@@ -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>()));
}
}

View 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;
}
}
}

View File

@@ -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() {

Binary file not shown.

After

Width:  |  Height:  |  Size: 671 B

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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