From 08507237955fa6531483cabbe9c07bfb580069f2 Mon Sep 17 00:00:00 2001 From: "honfika@gmail.com" Date: Sun, 25 Dec 2016 20:22:24 +0100 Subject: [PATCH] AS3 PCode serach --- .../decompiler/flash/abc/ScriptPack.java | 12 ++++ .../flash/abc/types/traits/Trait.java | 7 +- .../flash/abc/types/traits/TraitClass.java | 18 +++++ .../flash/abc/types/traits/TraitFunction.java | 6 ++ .../types/traits/TraitMethodGetterSetter.java | 6 ++ .../abc/types/traits/TraitSlotConst.java | 4 ++ .../flash/abc/types/traits/Traits.java | 8 +++ .../exporters/modes/ScriptExportMode.java | 8 ++- .../flash/search/ABCSearchResult.java | 20 ++++++ .../flash/search/ActionScriptSearch.java | 65 ++++++++++++++----- .../decompiler/flash/search/MethodId.java | 41 ++++++++++++ .../flash/gui/abc/ASMSourceEditorPane.java | 3 +- .../decompiler/flash/gui/abc/TraitsList.java | 2 +- .../flash/gui/abc/TraitsListItem.java | 11 ++-- .../flash/gui/abc/TraitsListModel.java | 18 +++-- 15 files changed, 194 insertions(+), 35 deletions(-) create mode 100644 libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/search/MethodId.java diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ScriptPack.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ScriptPack.java index 3d56fce27..c3f14fb72 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ScriptPack.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ScriptPack.java @@ -40,6 +40,7 @@ import com.jpexs.decompiler.flash.helpers.GraphTextWriter; import com.jpexs.decompiler.flash.helpers.HighlightedText; import com.jpexs.decompiler.flash.helpers.NulWriter; import com.jpexs.decompiler.flash.helpers.hilight.Highlighting; +import com.jpexs.decompiler.flash.search.MethodId; import com.jpexs.decompiler.flash.tags.Tag; import com.jpexs.decompiler.flash.treeitems.AS3ClassTreeItem; import com.jpexs.decompiler.graph.DottedChain; @@ -616,4 +617,15 @@ public class ScriptPack extends AS3ClassTreeItem { ((Tag) abc.parentTag).setModified(true); } + + public void getMethodInfos(List methodInfos) { + int script_init = abc.script_info.get(scriptIndex).init_index; + methodInfos.add(new MethodId(-1, script_init)); + + List traits = abc.script_info.get(scriptIndex).traits.traits; + for (int t = 0; t < traitIndices.size(); t++) { + Trait trait = traits.get(t); + trait.getMethodInfos(abc, -1, methodInfos); + } + } } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/Trait.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/Trait.java index 93b5d6876..510217e13 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/Trait.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/Trait.java @@ -34,6 +34,7 @@ import com.jpexs.decompiler.flash.exporters.script.DependencyType; import com.jpexs.decompiler.flash.helpers.GraphTextWriter; import com.jpexs.decompiler.flash.helpers.NulWriter; import com.jpexs.decompiler.flash.helpers.hilight.HighlightSpecialType; +import com.jpexs.decompiler.flash.search.MethodId; import com.jpexs.decompiler.flash.tags.ABCContainerTag; import com.jpexs.decompiler.graph.DottedChain; import com.jpexs.helpers.Helper; @@ -110,8 +111,8 @@ public abstract class Trait implements Cloneable, Serializable { } if (Configuration.handleSkinPartsAutomatically.get()) { /* - private static var _skinParts:Object = {"attr":false,"attr2":true}; - => + private static var _skinParts:Object = {"attr":false,"attr2":true}; + => [SkinPart required="false"] public var attr; [SkinPart required="true"] @@ -509,4 +510,6 @@ public abstract class Trait implements Cloneable, Serializable { public boolean isVisible(boolean isStatic, ABC abc) { return true; } + + public abstract void getMethodInfos(ABC abc, int classIndex, List methodInfos); } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/TraitClass.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/TraitClass.java index 5d9afa2bb..03070a2ad 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/TraitClass.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/TraitClass.java @@ -31,6 +31,7 @@ import com.jpexs.decompiler.flash.exporters.script.DependencyType; import com.jpexs.decompiler.flash.helpers.GraphTextWriter; import com.jpexs.decompiler.flash.helpers.NulWriter; import com.jpexs.decompiler.flash.helpers.hilight.HighlightSpecialType; +import com.jpexs.decompiler.flash.search.MethodId; import com.jpexs.decompiler.graph.DottedChain; import com.jpexs.decompiler.graph.ScopeStack; import com.jpexs.decompiler.graph.TypeItem; @@ -275,4 +276,21 @@ public class TraitClass extends Trait implements TraitWithSlot { writer.newLine(); return writer; } + + @Override + public void getMethodInfos(ABC abc, int classIndex, List methodInfos) { + InstanceInfo instanceInfo = abc.instance_info.get(class_info); + ClassInfo classInfo = abc.class_info.get(class_info); + + //class initializer + methodInfos.add(new MethodId(class_info, classInfo.cinit_index)); + + //constructor - instance initializer + methodInfos.add(new MethodId(class_info, instanceInfo.iinit_index)); + + //static variables,constants & methods + classInfo.static_traits.getMethodInfos(abc, class_info, methodInfos); + + instanceInfo.instance_traits.getMethodInfos(abc, class_info, methodInfos); + } } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/TraitFunction.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/TraitFunction.java index dcb80e1e1..d8643fd3d 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/TraitFunction.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/TraitFunction.java @@ -25,6 +25,7 @@ import com.jpexs.decompiler.flash.exporters.script.DependencyParser; import com.jpexs.decompiler.flash.helpers.GraphTextWriter; import com.jpexs.decompiler.flash.helpers.NulWriter; import com.jpexs.decompiler.flash.helpers.hilight.HighlightSpecialType; +import com.jpexs.decompiler.flash.search.MethodId; import com.jpexs.decompiler.graph.DottedChain; import com.jpexs.decompiler.graph.ScopeStack; import com.jpexs.helpers.Helper; @@ -144,4 +145,9 @@ public class TraitFunction extends Trait implements TraitWithSlot { writer.hilightSpecial(Integer.toString(slot_id), HighlightSpecialType.SLOT_ID); return writer; } + + @Override + public void getMethodInfos(ABC abc, int classIndex, List methodInfos) { + methodInfos.add(new MethodId(classIndex, method_info)); + } } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/TraitMethodGetterSetter.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/TraitMethodGetterSetter.java index 64d139ffe..e84aa51de 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/TraitMethodGetterSetter.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/TraitMethodGetterSetter.java @@ -28,6 +28,7 @@ import com.jpexs.decompiler.flash.exporters.script.DependencyParser; import com.jpexs.decompiler.flash.helpers.GraphTextWriter; import com.jpexs.decompiler.flash.helpers.NulWriter; import com.jpexs.decompiler.flash.helpers.hilight.HighlightSpecialType; +import com.jpexs.decompiler.flash.search.MethodId; import com.jpexs.decompiler.graph.DottedChain; import com.jpexs.decompiler.graph.ScopeStack; import com.jpexs.helpers.Helper; @@ -225,4 +226,9 @@ public class TraitMethodGetterSetter extends Trait { writer.newLine(); return writer; } + + @Override + public void getMethodInfos(ABC abc, int classIndex, List methodInfos) { + methodInfos.add(new MethodId(classIndex, method_info)); + } } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/TraitSlotConst.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/TraitSlotConst.java index 6e401f904..4d6607570 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/TraitSlotConst.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/TraitSlotConst.java @@ -32,6 +32,7 @@ import com.jpexs.decompiler.flash.exporters.script.DependencyType; import com.jpexs.decompiler.flash.helpers.GraphTextWriter; import com.jpexs.decompiler.flash.helpers.NulWriter; import com.jpexs.decompiler.flash.helpers.hilight.HighlightSpecialType; +import com.jpexs.decompiler.flash.search.MethodId; import com.jpexs.decompiler.graph.DottedChain; import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.model.LocalData; @@ -245,4 +246,7 @@ public class TraitSlotConst extends Trait implements TraitWithSlot { return writer; } + @Override + public void getMethodInfos(ABC abc, int classIndex, List methodInfos) { + } } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/Traits.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/Traits.java index b863ed879..f8e8b261b 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/Traits.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/Traits.java @@ -23,6 +23,7 @@ import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode; import com.jpexs.decompiler.flash.exporters.script.Dependency; import com.jpexs.decompiler.flash.helpers.GraphTextWriter; import com.jpexs.decompiler.flash.helpers.NulWriter; +import com.jpexs.decompiler.flash.search.MethodId; import com.jpexs.decompiler.graph.DottedChain; import java.io.Serializable; import java.util.ArrayList; @@ -250,4 +251,11 @@ public class Traits implements Cloneable, Serializable { t.getDependencies(customNs, abc, dependencies, uses, ignorePackage, fullyQualifiedNames); } } + + public void getMethodInfos(ABC abc, int classIndex, List methodInfos) { + for (int t = 0; t < traits.size(); t++) { + Trait trait = traits.get(t); + trait.getMethodInfos(abc, classIndex, methodInfos); + } + } } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/modes/ScriptExportMode.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/modes/ScriptExportMode.java index 943310a33..1584c9b4b 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/modes/ScriptExportMode.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/modes/ScriptExportMode.java @@ -21,6 +21,10 @@ package com.jpexs.decompiler.flash.exporters.modes; * @author JPEXS */ public enum ScriptExportMode { - - AS, PCODE, PCODE_HEX, HEX, CONSTANTS, AS_METHOD_STUBS; + AS, + PCODE, + PCODE_HEX, + HEX, + CONSTANTS, // AS1/2 ConstantPool + AS_METHOD_STUBS; } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/search/ABCSearchResult.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/search/ABCSearchResult.java index 5fda2a46f..68ddbff11 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/search/ABCSearchResult.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/search/ABCSearchResult.java @@ -26,14 +26,34 @@ public class ABCSearchResult { private final ScriptPack scriptPack; + private final int classIndex; + + private final int methodIndex; + public ABCSearchResult(ScriptPack scriptPack) { this.scriptPack = scriptPack; + classIndex = 0; + methodIndex = 0; + } + + public ABCSearchResult(ScriptPack scriptPack, int classIndex, int methodIndex) { + this.scriptPack = scriptPack; + this.classIndex = classIndex; + this.methodIndex = methodIndex; } public ScriptPack getScriptPack() { return scriptPack; } + public int getClassIndex() { + return classIndex; + } + + public int getMethodIndex() { + return methodIndex; + } + @Override public String toString() { return scriptPack.getClassPath().toString(); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/search/ActionScriptSearch.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/search/ActionScriptSearch.java index 27ec8f8fa..b12b29ab9 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/search/ActionScriptSearch.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/search/ActionScriptSearch.java @@ -17,7 +17,9 @@ package com.jpexs.decompiler.flash.search; import com.jpexs.decompiler.flash.SWF; +import com.jpexs.decompiler.flash.abc.ABC; import com.jpexs.decompiler.flash.abc.ScriptPack; +import com.jpexs.decompiler.flash.abc.types.MethodBody; import com.jpexs.decompiler.flash.cache.ScriptDecompiledListener; import com.jpexs.decompiler.flash.configuration.Configuration; import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode; @@ -55,7 +57,10 @@ public class ActionScriptSearch { ASMSource asm = item.getValue(); if (pcode) { - //Main.startWork(workText + " \"" + txt + "\" - (" + pos + "/" + asms.size() + ") " + item.getKey() + "... ", worker); + if (listener != null) { + listener.onSearch(pos, asms.size(), item.getKey()); + } + HighlightedTextWriter writer = new HighlightedTextWriter(Configuration.getCodeFormatting(), true); asm.getASMSource(ScriptExportMode.PCODE, writer, null); String text = writer.toString(); @@ -137,29 +142,53 @@ public class ActionScriptSearch { } } - int fpos = pos; - Future text = SWF.getCachedFuture(pack, new ScriptDecompiledListener() { - @Override - public void onStart() { - if (listener != null) { - listener.onDecompile(fpos, allpacks.size(), pack.getClassPath().toString()); - } + if (pcode) { + if (listener != null) { + listener.onSearch(pos, allpacks.size(), pack.getClassPath().toString()); } - @Override - public void onComplete(HighlightedText result) { - if (listener != null) { - listener.onSearch(fpos, allpacks.size(), pack.getClassPath().toString()); - } + List methodInfos = new ArrayList<>(); + pack.getMethodInfos(methodInfos); - if (pat.matcher(result.text).find()) { - ABCSearchResult searchResult = new ABCSearchResult(pack); - found.add(searchResult); + ABC abc = pack.abc; + for (MethodId methodInfo : methodInfos) { + int bodyIndex = abc.findBodyIndex(methodInfo.getMethodIndex()); + if (bodyIndex != -1) { + MethodBody body = abc.bodies.get(bodyIndex); + HighlightedTextWriter writer = new HighlightedTextWriter(Configuration.getCodeFormatting(), true); + abc.bodies.get(bodyIndex).getCode().toASMSource(abc.constants, abc.method_info.get(body.method_info), body, ScriptExportMode.PCODE, writer); + String text = writer.toString(); + if (pat.matcher(text).find()) { + ABCSearchResult searchResult = new ABCSearchResult(pack, methodInfo.getClassIndex(), methodInfo.getMethodIndex()); + found.add(searchResult); + } } } - }); + } else { + int fpos = pos; + Future text = SWF.getCachedFuture(pack, new ScriptDecompiledListener() { + @Override + public void onStart() { + if (listener != null) { + listener.onDecompile(fpos, allpacks.size(), pack.getClassPath().toString()); + } + } - futures.add(text); + @Override + public void onComplete(HighlightedText result) { + if (listener != null) { + listener.onSearch(fpos, allpacks.size(), pack.getClassPath().toString()); + } + + if (pat.matcher(result.text).find()) { + ABCSearchResult searchResult = new ABCSearchResult(pack); + found.add(searchResult); + } + } + }); + + futures.add(text); + } } for (Future future : futures) { diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/search/MethodId.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/search/MethodId.java new file mode 100644 index 000000000..b8f88f347 --- /dev/null +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/search/MethodId.java @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2010-2016 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 . + */ +package com.jpexs.decompiler.flash.search; + +/** + * + * @author JPEXS + */ +public class MethodId { + + private final int classIndex; + + private final int methodIndex; + + public MethodId(int classIndex, int methodIndex) { + this.classIndex = classIndex; + this.methodIndex = methodIndex; + } + + public int getClassIndex() { + return classIndex; + } + + public int getMethodIndex() { + return methodIndex; + } +} diff --git a/src/com/jpexs/decompiler/flash/gui/abc/ASMSourceEditorPane.java b/src/com/jpexs/decompiler/flash/gui/abc/ASMSourceEditorPane.java index ab4982613..760879a7d 100644 --- a/src/com/jpexs/decompiler/flash/gui/abc/ASMSourceEditorPane.java +++ b/src/com/jpexs/decompiler/flash/gui/abc/ASMSourceEditorPane.java @@ -121,7 +121,8 @@ public class ASMSourceEditorPane extends DebuggableEditorPane implements CaretLi if (trait != null && exportMode != ScriptExportMode.AS && exportMode != ScriptExportMode.AS_METHOD_STUBS) { trait.convertTraitHeader(abc, writer); } - abc.bodies.get(bodyIndex).getCode().toASMSource(abc.constants, abc.method_info.get(abc.bodies.get(bodyIndex).method_info), abc.bodies.get(bodyIndex), exportMode, writer); + MethodBody body = abc.bodies.get(bodyIndex); + abc.bodies.get(bodyIndex).getCode().toASMSource(abc.constants, abc.method_info.get(body.method_info), body, exportMode, writer); if (trait != null) { writer.appendNoHilight("end ; trait").newLine(); } diff --git a/src/com/jpexs/decompiler/flash/gui/abc/TraitsList.java b/src/com/jpexs/decompiler/flash/gui/abc/TraitsList.java index 7c63a7498..1e582685f 100644 --- a/src/com/jpexs/decompiler/flash/gui/abc/TraitsList.java +++ b/src/com/jpexs/decompiler/flash/gui/abc/TraitsList.java @@ -74,9 +74,9 @@ public class TraitsList extends JList implements ListSelectionListener { if (classIndex >= abc.instance_info.size()) { return; } + this.classIndex = classIndex; setModel(new TraitsListModel(abc, classIndex, scriptIndex, sorted)); - } private int lastSelected = -1; diff --git a/src/com/jpexs/decompiler/flash/gui/abc/TraitsListItem.java b/src/com/jpexs/decompiler/flash/gui/abc/TraitsListItem.java index ddce8551a..49af65ebc 100644 --- a/src/com/jpexs/decompiler/flash/gui/abc/TraitsListItem.java +++ b/src/com/jpexs/decompiler/flash/gui/abc/TraitsListItem.java @@ -117,15 +117,17 @@ public class TraitsListItem { } } else if (isStatic) { ConvertData convertData = new ConvertData(); - abc.class_info.get(classIndex).static_traits.traits.get(index).convertHeader(null, convertData, "", abc, true, ScriptExportMode.AS, scriptIndex, classIndex, new NulWriter(), new ArrayList<>(), false); + Trait trait = abc.class_info.get(classIndex).static_traits.traits.get(index); + trait.convertHeader(null, convertData, "", abc, true, ScriptExportMode.AS, scriptIndex, classIndex, new NulWriter(), new ArrayList<>(), false); HighlightedTextWriter writer = new HighlightedTextWriter(Configuration.getCodeFormatting(), false); - abc.class_info.get(classIndex).static_traits.traits.get(index).toStringHeader(null, convertData, "", abc, true, ScriptExportMode.AS, scriptIndex, classIndex, writer, new ArrayList<>(), false); + trait.toStringHeader(null, convertData, "", abc, true, ScriptExportMode.AS, scriptIndex, classIndex, writer, new ArrayList<>(), false); s = writer.toString(); } else { ConvertData convertData = new ConvertData(); - abc.instance_info.get(classIndex).instance_traits.traits.get(index).convertHeader(null, convertData, "", abc, false, ScriptExportMode.AS, scriptIndex, classIndex, new NulWriter(), new ArrayList<>(), false); + Trait trait = abc.instance_info.get(classIndex).instance_traits.traits.get(index); + trait.convertHeader(null, convertData, "", abc, false, ScriptExportMode.AS, scriptIndex, classIndex, new NulWriter(), new ArrayList<>(), false); HighlightedTextWriter writer = new HighlightedTextWriter(Configuration.getCodeFormatting(), false); - abc.instance_info.get(classIndex).instance_traits.traits.get(index).toStringHeader(null, convertData, "", abc, false, ScriptExportMode.AS, scriptIndex, classIndex, writer, new ArrayList<>(), false); + trait.toStringHeader(null, convertData, "", abc, false, ScriptExportMode.AS, scriptIndex, classIndex, writer, new ArrayList<>(), false); s = writer.toString(); } } catch (InterruptedException ex) { @@ -144,7 +146,6 @@ public class TraitsListItem { } public enum Type { - METHOD, VAR, CONST, diff --git a/src/com/jpexs/decompiler/flash/gui/abc/TraitsListModel.java b/src/com/jpexs/decompiler/flash/gui/abc/TraitsListModel.java index f5a49cbfa..3780bca55 100644 --- a/src/com/jpexs/decompiler/flash/gui/abc/TraitsListModel.java +++ b/src/com/jpexs/decompiler/flash/gui/abc/TraitsListModel.java @@ -17,6 +17,7 @@ package com.jpexs.decompiler.flash.gui.abc; import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.types.traits.Trait; import com.jpexs.decompiler.flash.configuration.Configuration; import java.util.ArrayList; import java.util.Collections; @@ -55,19 +56,24 @@ public final class TraitsListModel implements ListModel { private void reset() { items = new ArrayList<>(); if (classIndex > -1) { - for (int t = 0; t < abc.class_info.get(classIndex).static_traits.traits.size(); t++) { - if (abc.class_info.get(classIndex).static_traits.traits.get(t).isVisible(true, abc)) { - items.add(new TraitsListItem(TraitsListItem.Type.getTypeForTrait(abc.class_info.get(classIndex).static_traits.traits.get(t)), t, true, abc, classIndex, scriptIndex)); + List traits = abc.class_info.get(classIndex).static_traits.traits; + for (int t = 0; t < traits.size(); t++) { + if (traits.get(t).isVisible(true, abc)) { + items.add(new TraitsListItem(TraitsListItem.Type.getTypeForTrait(traits.get(t)), t, true, abc, classIndex, scriptIndex)); } } - for (int t = 0; t < abc.instance_info.get(classIndex).instance_traits.traits.size(); t++) { - if (abc.instance_info.get(classIndex).instance_traits.traits.get(t).isVisible(false, abc)) { - items.add(new TraitsListItem(TraitsListItem.Type.getTypeForTrait(abc.instance_info.get(classIndex).instance_traits.traits.get(t)), t, false, abc, classIndex, scriptIndex)); + + traits = abc.instance_info.get(classIndex).instance_traits.traits; + for (int t = 0; t < traits.size(); t++) { + if (traits.get(t).isVisible(false, abc)) { + items.add(new TraitsListItem(TraitsListItem.Type.getTypeForTrait(traits.get(t)), t, false, abc, classIndex, scriptIndex)); } } + items.add(new TraitsListItem(TraitsListItem.Type.INITIALIZER, 0, false, abc, classIndex, scriptIndex)); items.add(new TraitsListItem(TraitsListItem.Type.INITIALIZER, 0, true, abc, classIndex, scriptIndex)); } + if (Configuration.enableScriptInitializerDisplay.get()) { items.add(new TraitsListItem(TraitsListItem.Type.SCRIPT_INITIALIZER, 0, true, abc, classIndex, scriptIndex)); }