Fixed: Direct editation.

Fixed: Imports in script initializer
This commit is contained in:
Jindra Petřík
2024-08-17 10:35:57 +02:00
parent d99bb058ec
commit c8a8ce8b6d
17 changed files with 228 additions and 91 deletions

View File

@@ -16,6 +16,7 @@
*/
package com.jpexs.decompiler.flash;
import com.jpexs.decompiler.flash.abc.avm2.parser.script.NamespaceItem;
import com.jpexs.decompiler.flash.abc.types.ABCException;
import com.jpexs.decompiler.flash.abc.types.MethodBody;
import com.jpexs.decompiler.flash.abc.types.ScriptInfo;
@@ -179,6 +180,16 @@ public class SourceGeneratorLocalData implements Serializable {
* Number context
*/
public Integer numberContext = null;
/**
* Imported classes
*/
public List<DottedChain> importedClasses = new ArrayList<>();
/**
* Opened namespaces
*/
public List<NamespaceItem> openedNamespaces = new ArrayList<>();
/**
* Gets full class name.

View File

@@ -322,16 +322,44 @@ public class ScriptPack extends AS3ClassTreeItem {
Trait trait = traits.get(t);
if ((trait instanceof TraitSlotConst) && convertData.assignedValues.containsKey((TraitSlotConst) trait)) {
if (trait instanceof TraitSlotConst) {
continue;
}
if (!first) {
writer.newLine();
}
writer.startTrait(t);
Multiname name = trait.getName(abc);
int nskind = name.getSimpleNamespaceKind(abc.constants);
if ((nskind == Namespace.KIND_PACKAGE) || (nskind == Namespace.KIND_PACKAGE_INTERNAL)) {
trait.toStringPackaged(abcIndex, null, convertData, "", abc, false, exportMode, scriptIndex, -1, writer, new ArrayList<>(), parallel, false);
} else {
trait.toString(abcIndex, null, convertData, "", abc, false, exportMode, scriptIndex, -1, writer, new ArrayList<>(), parallel, false);
}
if (!(trait instanceof TraitClass)) {
writer.endTrait();
}
first = false;
}
//Slot const last
for (int t : traitIndices) {
Trait trait = traits.get(t);
if (!(trait instanceof TraitSlotConst)) {
continue;
}
if (convertData.assignedValues.containsKey((TraitSlotConst) trait)) {
continue;
}
if (!first) {
writer.newLine();
}
//if (!(trait instanceof TraitClass)) {
writer.startTrait(t);
//}
Multiname name = trait.getName(abc);
int nskind = name.getSimpleNamespaceKind(abc.constants);
if ((nskind == Namespace.KIND_PACKAGE) || (nskind == Namespace.KIND_PACKAGE_INTERNAL)) {
@@ -351,11 +379,16 @@ public class ScriptPack extends AS3ClassTreeItem {
writer.startMethod(script_init, null);
if (exportMode != ScriptExportMode.AS_METHOD_STUBS) {
if (!scriptInitializerIsEmpty) {
//writer.startBlock();
DottedChain ignorePackage = null;
if (isSimple) {
ignorePackage = getPathPackage();
}
List<DottedChain> fullyQualifiedNames = new ArrayList<>();
writer.newLine();
Trait.writeImports(null, script_init, abcIndex, scriptIndex, -1, true, abc, writer, ignorePackage, fullyQualifiedNames);
List<MethodBody> callStack = new ArrayList<>();
callStack.add(abc.bodies.get(bodyIndex));
abc.bodies.get(bodyIndex).toString(callStack, abcIndex, path + "/.scriptinitializer", exportMode, abc, null, writer, new ArrayList<>(), new HashSet<>());
//writer.endBlock();
abc.bodies.get(bodyIndex).toString(callStack, abcIndex, path + "/.scriptinitializer", exportMode, abc, null, writer, fullyQualifiedNames, new HashSet<>());
} else {
writer.append("");
}

View File

@@ -16,15 +16,21 @@
*/
package com.jpexs.decompiler.flash.abc.avm2.model;
import com.jpexs.decompiler.flash.SourceGeneratorLocalData;
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instructions;
import com.jpexs.decompiler.flash.abc.avm2.parser.script.AVM2SourceGenerator;
import com.jpexs.decompiler.flash.abc.types.AssignedValue;
import com.jpexs.decompiler.flash.abc.types.ConvertData;
import com.jpexs.decompiler.flash.abc.types.traits.TraitSlotConst;
import com.jpexs.decompiler.flash.abc.types.traits.TraitType;
import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode;
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
import com.jpexs.decompiler.graph.CompilationException;
import com.jpexs.decompiler.graph.GraphSourceItem;
import com.jpexs.decompiler.graph.GraphTargetItem;
import com.jpexs.decompiler.graph.SourceGenerator;
import com.jpexs.decompiler.graph.model.LocalData;
import java.util.ArrayList;
import java.util.List;
/**
*
@@ -142,5 +148,5 @@ public class TraitSlotConstAVM2Item extends AVM2Item {
public TraitSlotConst getTrait() {
return trait;
}
}
}

View File

@@ -783,7 +783,7 @@ public class AVM2SourceGenerator implements SourceGenerator {
}
//Class initializer
int cinit_index = method(true, str(""), false, false, false, new ArrayList<>(), pkg, cinitNeedsActivation, cinitVariables, initScope + (implementsStr.isEmpty() ? 0 : 1), false, 0, isInterface ? null : baseClassName, superName, false, localData, new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), cinit, TypeItem.UNBOUNDED);
int cinit_index = method(true, str(""), false, false, false, new ArrayList<>(), pkg, cinitNeedsActivation, cinitVariables, initScope + (implementsStr.isEmpty() ? 0 : 1), false, 0, isInterface ? null : baseClassName, superName, false, localData, new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), commands, TypeItem.UNBOUNDED);
MethodBody cinitBody = abcIndex.getSelectedAbc().findBody(cinit_index);
@@ -806,9 +806,9 @@ public class AVM2SourceGenerator implements SourceGenerator {
}
}
List<AVM2Instruction> cinitcode = new ArrayList<>();
//List<AVM2Instruction> cinitcode = new ArrayList<>();
List<AVM2Instruction> initcode = new ArrayList<>();
for (GraphTargetItem ti : commands) {
/*for (GraphTargetItem ti : commands) {
if ((ti instanceof SlotAVM2Item) || (ti instanceof ConstAVM2Item)) {
GraphTargetItem val = null;
boolean isStatic = false;
@@ -855,15 +855,15 @@ public class AVM2SourceGenerator implements SourceGenerator {
cinitcode.add((AVM2Instruction)src);
}
}
}
}*/
MethodBody initBody = null;
if (!isInterface) {
initBody = abcIndex.getSelectedAbc().findBody(init);
initBody.getCode().code.addAll(iinit == null ? 0 : 2, initcode); //after getlocal0,pushscope
if (cinitBody.getCode().code.get(cinitBody.getCode().code.size() - 1).definition instanceof ReturnVoidIns) {
/*if (cinitBody.getCode().code.get(cinitBody.getCode().code.size() - 1).definition instanceof ReturnVoidIns) {
cinitBody.getCode().code.addAll(2, cinitcode); //after getlocal0,pushscope
}
}*/
}
cinitBody.markOffsets();
cinitBody.autoFillStats(abcIndex.getSelectedAbc(), initScope + (implementsStr.isEmpty() ? 0 : 1), true);
@@ -1626,7 +1626,7 @@ public class AVM2SourceGenerator implements SourceGenerator {
return null;
}
private int genNs(List<DottedChain> importedClasses, DottedChain pkg, NamespaceItem ns, List<NamespaceItem> openedNamespaces, SourceGeneratorLocalData localData, int line) throws CompilationException {
public int genNs(List<DottedChain> importedClasses, DottedChain pkg, NamespaceItem ns, List<NamespaceItem> openedNamespaces, SourceGeneratorLocalData localData, int line) throws CompilationException {
ns.resolveCustomNs(abcIndex, importedClasses, pkg, openedNamespaces, localData);
return ns.getCpoolIndex(abcIndex);
}
@@ -2180,13 +2180,21 @@ public class AVM2SourceGenerator implements SourceGenerator {
ABC abc = abcIndex.getSelectedAbc();
AVM2ConstantPool constants = abc.constants;
MethodInfo mi = new MethodInfo(new int[0], 0, constants.getStringId("", true), 0, new ValueKind[0], new int[0]);
MethodBody mb = new MethodBody(abc, new Traits(), new byte[0], new ABCException[0]);
mb.method_info = abc.addMethodInfo(mi);
mb.setCode(new AVM2Code());
List<AVM2Instruction> mbCode = mb.getCode().code;
mbCode.add(ins(AVM2Instructions.GetLocal0));
mbCode.add(ins(AVM2Instructions.PushScope));
MethodBody mb;
//= new MethodBody(abc, new Traits(), new byte[0], new ABCException[0]);
//mb.method_info = abc.addMethodInfo(mi);
// mb.setCode(new AVM2Code());
localData.importedClasses = importedClasses;
localData.openedNamespaces = openedNamespaces;
int sinit_index = method(true, str(""), false, false, false, new ArrayList<>(), null, sinitNeedsActivation, sinitVariables, 0, false, 0, null, null, false, localData, new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), commands, TypeItem.UNBOUNDED);
mb = abcIndex.getSelectedAbc().findBody(sinit_index);
List<AVM2Instruction> mbCode = mb.getCode().code;
/*mbCode.add(ins(AVM2Instructions.GetLocal0));
mbCode.add(ins(AVM2Instructions.PushScope));
*/
int traitScope = 1;
String documentClassStr = localData.documentClass;
@@ -2197,6 +2205,7 @@ public class AVM2SourceGenerator implements SourceGenerator {
Map<Trait, Integer> initScopes = new HashMap<>();
List<AVM2Instruction> sinitcode = new ArrayList<>();
for (Trait t : scriptInfo.traits.traits) {
if (t instanceof TraitClass) {
TraitClass tc = (TraitClass) t;
@@ -2204,14 +2213,14 @@ public class AVM2SourceGenerator implements SourceGenerator {
List<Integer> parents = new ArrayList<>();
if (documentClass != null && documentClass.equals(className)) {
mbCode.add(ins(AVM2Instructions.GetScopeObject, 0));
sinitcode.add(ins(AVM2Instructions.GetScopeObject, 0));
} else {
int[] nsset = new int[]{constants.getMultiname(tc.name_index).namespace_index};
mbCode.add(ins(AVM2Instructions.FindPropertyStrict, constants.getMultinameId(Multiname.createMultiname(false, constants.getMultiname(tc.name_index).name_index, constants.getNamespaceSetId(nsset, true)), true)));
sinitcode.add(ins(AVM2Instructions.FindPropertyStrict, constants.getMultinameId(Multiname.createMultiname(false, constants.getMultiname(tc.name_index).name_index, constants.getNamespaceSetId(nsset, true)), true)));
}
traitScope++;
if (abc.instance_info.get(tc.class_info).isInterface()) {
mbCode.add(ins(AVM2Instructions.PushNull));
sinitcode.add(ins(AVM2Instructions.PushNull));
} else {
AbcIndexing.ClassIndex ci = abcIndex.findClass(AbcIndexing.multinameToType(abc.instance_info.get(tc.class_info).name_index, constants), null, null/*FIXME?*/);
@@ -2230,52 +2239,36 @@ public class AVM2SourceGenerator implements SourceGenerator {
//add all parent objects to scopestack
for (int i = parents.size() - 1; i >= 0; i--) {
mbCode.add(ins(AVM2Instructions.GetLex, parents.get(i)));
mbCode.add(ins(AVM2Instructions.PushScope));
sinitcode.add(ins(AVM2Instructions.GetLex, parents.get(i)));
sinitcode.add(ins(AVM2Instructions.PushScope));
traitScope++;
}
//direct parent class to new_class instruction
if (!parents.isEmpty()) { //NON EXISTING PARENT CLASS - TODO: handle as error!
mbCode.add(ins(AVM2Instructions.GetLex, parents.get(0)));
sinitcode.add(ins(AVM2Instructions.GetLex, parents.get(0)));
}
}
mbCode.add(ins(AVM2Instructions.NewClass, tc.class_info));
sinitcode.add(ins(AVM2Instructions.NewClass, tc.class_info));
for (int i = 0; i < parents.size(); i++) {
mbCode.add(ins(AVM2Instructions.PopScope));
sinitcode.add(ins(AVM2Instructions.PopScope));
}
mbCode.add(ins(AVM2Instructions.InitProperty, tc.name_index));
sinitcode.add(ins(AVM2Instructions.InitProperty, tc.name_index));
initScopes.put(t, traitScope);
traitScope = 1;
}
}
abc.addMethodBody(mb);
mbCode.addAll(2, sinitcode); //after getlocal0 pushscope
//abc.addMethodBody(mb);
scriptInfo.init_index = mb.method_info;
localData.pkg = DottedChain.EMPTY;
localData.registerVars.put("this", 0);
//localData.registerVars.put("this", 0);
generateTraitsPhase4(new ArrayList<>(), new ArrayList<>(), 1/*??*/, false, null, null, true, localData, traitsList, scriptInfo.traits, traitArr, initScopes, class_index, true);
List<AVM2Instruction> sinitcode = new ArrayList<>();
for (int i = 0; i < sinitVariables.size(); i++) {
AssignableAVM2Item an = sinitVariables.get(i);
if (an instanceof UnresolvedAVM2Item) {
UnresolvedAVM2Item n = (UnresolvedAVM2Item) an;
if (n.resolved == null) {
String fullClass = localData.getFullClass();
List<MethodBody> callStack = new ArrayList<>();
callStack.add(mb);
GraphTargetItem res = n.resolve(localData, fullClass, new TypeItem(fullClass), new ArrayList<>(), new ArrayList<>(), abcIndex, callStack, sinitVariables);
if (res instanceof AssignableAVM2Item) {
sinitVariables.set(i, (AssignableAVM2Item) res);
} else {
sinitVariables.remove(i);
i--;
}
}
}
}
for (GraphTargetItem ti : commands) {
/*for (GraphTargetItem ti : commands) {
if ((ti instanceof SlotAVM2Item) || (ti instanceof ConstAVM2Item)) {
GraphTargetItem val = null;
int ns = -1;
@@ -2310,8 +2303,8 @@ public class AVM2SourceGenerator implements SourceGenerator {
sinitcode.add((AVM2Instruction)src);
}
}
}
mbCode.addAll(sinitcode);
}*/
//mbCode.addAll(sinitcode);
/*int maxSlotId = 0;
for (int k = 0; k < scriptInfo.traits.traits.size(); k++) {

View File

@@ -16,10 +16,16 @@
*/
package com.jpexs.decompiler.flash.abc.avm2.parser.script;
import com.jpexs.decompiler.flash.SourceGeneratorLocalData;
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instructions;
import com.jpexs.decompiler.flash.abc.avm2.model.AVM2Item;
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
import com.jpexs.decompiler.graph.CompilationException;
import com.jpexs.decompiler.graph.GraphSourceItem;
import com.jpexs.decompiler.graph.GraphTargetItem;
import com.jpexs.decompiler.graph.SourceGenerator;
import com.jpexs.decompiler.graph.model.LocalData;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -72,6 +78,7 @@ public class ConstAVM2Item extends AVM2Item {
/**
* Check if is static
*
* @return Is static
*/
public boolean isStatic() {
@@ -80,6 +87,7 @@ public class ConstAVM2Item extends AVM2Item {
/**
* Constructor.
*
* @param metadata Metadata
* @param pkg Package
* @param customNamespace Custom namespace
@@ -110,11 +118,29 @@ public class ConstAVM2Item extends AVM2Item {
@Override
public GraphTargetItem returnType() {
return type;
return null;
}
@Override
public boolean hasReturnValue() {
return true;
return false;
}
@Override
public List<GraphSourceItem> toSource(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException {
AVM2SourceGenerator agen = (AVM2SourceGenerator) generator;
int ns = agen.genNs(localData.importedClasses, pkg.name, pkg, localData.openedNamespaces, localData, line);
if (type.toString().equals("Namespace")) {
return new ArrayList<>();
}
List<GraphSourceItem> ret = new ArrayList<>();
if (value != null) {
ret.add(ins(AVM2Instructions.FindProperty, agen.traitName(ns, var)));
localData.isStatic = true;
ret.addAll(agen.toInsList(value.toSource(localData, agen)));
ret.add(ins(AVM2Instructions.InitProperty, agen.traitName(ns, var)));
}
return ret;
}
}

View File

@@ -16,10 +16,16 @@
*/
package com.jpexs.decompiler.flash.abc.avm2.parser.script;
import com.jpexs.decompiler.flash.SourceGeneratorLocalData;
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instructions;
import com.jpexs.decompiler.flash.abc.avm2.model.AVM2Item;
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
import com.jpexs.decompiler.graph.CompilationException;
import com.jpexs.decompiler.graph.GraphSourceItem;
import com.jpexs.decompiler.graph.GraphTargetItem;
import com.jpexs.decompiler.graph.SourceGenerator;
import com.jpexs.decompiler.graph.model.LocalData;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -67,6 +73,7 @@ public class SlotAVM2Item extends AVM2Item {
/**
* Is static.
*
* @return Is static
*/
public boolean isStatic() {
@@ -75,6 +82,7 @@ public class SlotAVM2Item extends AVM2Item {
/**
* Constructor.
*
* @param metadata Metadata
* @param pkg Package
* @param customNamespace Custom namespace
@@ -102,11 +110,27 @@ public class SlotAVM2Item extends AVM2Item {
@Override
public GraphTargetItem returnType() {
return type;
return null;
}
@Override
public boolean hasReturnValue() {
return true;
return false;
}
@Override
public List<GraphSourceItem> toSource(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException {
AVM2SourceGenerator agen = (AVM2SourceGenerator) generator;
int ns = agen.genNs(localData.importedClasses, pkg.name, pkg, localData.openedNamespaces, localData, line);
List<GraphSourceItem> ret = new ArrayList<>();
if (value != null) {
ret.add(ins(AVM2Instructions.FindProperty, agen.traitName(ns, var)));
localData.isStatic = true;
ret.addAll(agen.toInsList(value.toSource(localData, agen)));
ret.add(ins(AVM2Instructions.SetProperty, agen.traitName(ns, var)));
}
return ret;
}
}

View File

@@ -322,7 +322,7 @@ public abstract class Trait implements Cloneable, Serializable {
* @param scriptIndex Script index
* @param isParent Is parent
*/
private void getAllClassTraitNames(List<String> traitNamesInThisScript, AbcIndexing abcIndex, ABC abc, int classIndex, Integer scriptIndex, boolean isParent) {
private static void getAllClassTraitNames(List<String> traitNamesInThisScript, AbcIndexing abcIndex, ABC abc, int classIndex, Integer scriptIndex, boolean isParent) {
boolean publicProtectedOnly = isParent;
for (Trait it : abc.instance_info.get(classIndex).instance_traits.traits) {
if (publicProtectedOnly) {
@@ -355,6 +355,8 @@ public abstract class Trait implements Cloneable, Serializable {
/**
* Writes imports.
*
* @param trait Trait
* @param methodIndex Method index
* @param abcIndex ABC indexing
* @param scriptIndex Script index
* @param classIndex Class index
@@ -363,9 +365,10 @@ public abstract class Trait implements Cloneable, Serializable {
* @param writer Writer
* @param ignorePackage Ignore package
* @param fullyQualifiedNames Fully qualified names
* @return True if its not empty
* @throws InterruptedException On interrupt
*/
public void writeImports(AbcIndexing abcIndex, int scriptIndex, int classIndex, boolean isStatic, ABC abc, GraphTextWriter writer, DottedChain ignorePackage, List<DottedChain> fullyQualifiedNames) throws InterruptedException {
public static boolean writeImports(Trait trait, int methodIndex, AbcIndexing abcIndex, int scriptIndex, int classIndex, boolean isStatic, ABC abc, GraphTextWriter writer, DottedChain ignorePackage, List<DottedChain> fullyQualifiedNames) throws InterruptedException {
List<String> namesInThisPackage = new ArrayList<>();
for (ABCContainerTag tag : abc.getAbcTags()) {
@@ -391,15 +394,21 @@ public abstract class Trait implements Cloneable, Serializable {
//imports
List<Dependency> dependencies = new ArrayList<>();
String customNs = null;
Multiname multiname = getName(abc);
int nskind = multiname.getSimpleNamespaceKind(abc.constants);
if (nskind == Namespace.KIND_NAMESPACE) {
customNs = multiname.getSimpleNamespaceName(abc.constants).toRawString();
}
List<String> uses = new ArrayList<>();
Reference<Integer> numberContextRef = new Reference<>(null);
getDependencies(abcIndex, scriptIndex, classIndex, isStatic, customNs, abc, dependencies, ignorePackage, new ArrayList<>(), uses, numberContextRef);
if (trait != null) {
Multiname multiname = trait.getName(abc);
int nskind = multiname.getSimpleNamespaceKind(abc.constants);
if (nskind == Namespace.KIND_NAMESPACE) {
customNs = multiname.getSimpleNamespaceName(abc.constants).toRawString();
}
trait.getDependencies(abcIndex, scriptIndex, classIndex, isStatic, customNs, abc, dependencies, ignorePackage, new ArrayList<>(), uses, numberContextRef);
}
if (methodIndex != -1) {
DependencyParser.parseDependenciesFromMethodInfo(abcIndex, trait, scriptIndex, classIndex, isStatic, customNs, abc, methodIndex, dependencies, ignorePackage, fullyQualifiedNames, new ArrayList<>(), uses, numberContextRef);
}
List<DottedChain> imports = new ArrayList<>();
for (Dependency d : dependencies) {
if (!imports.contains(d.getId())) {
@@ -481,11 +490,14 @@ public abstract class Trait implements Cloneable, Serializable {
hasImport = true;
}
}
if (hasImport) {
writer.newLine();
}
boolean hasUse = false;
if (!uses.isEmpty()) {
hasUse = true;
if (hasImport) {
writer.newLine();
}
for (String u : uses) {
writer.appendNoHilight("use namespace " + u + ";").newLine();
}
@@ -505,7 +517,12 @@ public abstract class Trait implements Cloneable, Serializable {
}
writer.appendNoHilight(";");
writer.newLine();
hasUse = true;
}
if (hasImport || hasUse) {
writer.newLine();
}
return hasImport || hasUse;
}
/**

View File

@@ -230,7 +230,10 @@ public class TraitClass extends Trait implements TraitWithSlot {
DottedChain packageName = instanceInfoMultiname.getNamespace(abc.constants).getName(abc.constants); //assume not null name
fullyQualifiedNames = new ArrayList<>();
writeImports(abcIndex, scriptIndex, classIndex, false, abc, writer, packageName, fullyQualifiedNames);
if (getName(abc).getNamespace(abc.constants).kind != Namespace.KIND_PACKAGE_INTERNAL) {
writeImports(this, -1, abcIndex, scriptIndex, classIndex, false, abc, writer, packageName, fullyQualifiedNames);
}
String instanceInfoName = instanceInfoMultiname.getName(abc.constants, fullyQualifiedNames, false, true);
@@ -273,9 +276,11 @@ public class TraitClass extends Trait implements TraitWithSlot {
writer.startBlock();
writer.startClass(class_info);
Reference<Boolean> first = new Reference<>(true);
//static variables & constants
ClassInfo classInfo = abc.class_info.get(class_info);
classInfo.static_traits.toString(abcIndex, new Class[]{TraitSlotConst.class}, this, convertData, path + "/" + instanceInfoName, abc, true, exportMode, false, scriptIndex, class_info, writer, fullyQualifiedNames, parallel, new ArrayList<>(), isInterface);
classInfo.static_traits.toString(first, abcIndex, new Class[]{TraitSlotConst.class}, this, convertData, path + "/" + instanceInfoName, abc, true, exportMode, false, scriptIndex, class_info, writer, fullyQualifiedNames, parallel, new ArrayList<>(), isInterface);
//static initializer
int bodyIndex = abc.findBodyIndex(classInfo.cinit_index);
@@ -285,6 +290,9 @@ public class TraitClass extends Trait implements TraitWithSlot {
if (exportMode != ScriptExportMode.AS_METHOD_STUBS) {
if (!classInitializerIsEmpty) {
//writer.startBlock();
if (!first.getVal()) {
writer.newLine();
}
List<MethodBody> callStack = new ArrayList<>();
callStack.add(abc.bodies.get(bodyIndex));
abc.bodies.get(bodyIndex).toString(callStack, abcIndex, path + "/" + instanceInfoName + ".staticinitializer", exportMode, abc, this, writer, fullyQualifiedNames, new HashSet<>());
@@ -292,7 +300,7 @@ public class TraitClass extends Trait implements TraitWithSlot {
} else {
//Note: There must be trait/method highlight even if the initializer is empty to TraitList in GUI to work correctly
//TODO: handle this better in GUI(?)
writer.append(" ").newLine();
writer.append("");
}
}
writer.endMethod();
@@ -305,14 +313,17 @@ public class TraitClass extends Trait implements TraitWithSlot {
}
//instance variables
instanceInfo.instance_traits.toString(abcIndex, new Class[]{TraitSlotConst.class}, this, convertData, path + "/" + instanceInfoName, abc, false, exportMode, false, scriptIndex, class_info, writer, fullyQualifiedNames, parallel, new ArrayList<>(), isInterface);
instanceInfo.instance_traits.toString(first, abcIndex, new Class[]{TraitSlotConst.class}, this, convertData, path + "/" + instanceInfoName, abc, false, exportMode, false, scriptIndex, class_info, writer, fullyQualifiedNames, parallel, new ArrayList<>(), isInterface);
//instance initializer - constructor
if (!instanceInfo.isInterface()) {
String modifier = "public ";
Multiname m = abc.constants.getMultiname(instanceInfo.name_index);
writer.newLine();
if (!first.getVal()) {
writer.newLine();
}
first.setVal(false);
writer.startTrait(GraphTextWriter.TRAIT_INSTANCE_INITIALIZER);
writer.startMethod(instanceInfo.iinit_index, "iinit");
writer.appendNoHilight(modifier);
@@ -337,10 +348,10 @@ public class TraitClass extends Trait implements TraitWithSlot {
}
//static methods
classInfo.static_traits.toString(abcIndex, new Class[]{TraitClass.class, TraitFunction.class, TraitMethodGetterSetter.class}, this, convertData, path + "/" + instanceInfoName, abc, true, exportMode, false, scriptIndex, class_info, writer, fullyQualifiedNames, parallel, new ArrayList<>(), isInterface);
classInfo.static_traits.toString(first, abcIndex, new Class[]{TraitClass.class, TraitFunction.class, TraitMethodGetterSetter.class}, this, convertData, path + "/" + instanceInfoName, abc, true, exportMode, false, scriptIndex, class_info, writer, fullyQualifiedNames, parallel, new ArrayList<>(), isInterface);
//instance methods
instanceInfo.instance_traits.toString(abcIndex, new Class[]{TraitClass.class, TraitFunction.class, TraitMethodGetterSetter.class}, this, convertData, path + "/" + instanceInfoName, abc, false, exportMode, false, scriptIndex, class_info, writer, fullyQualifiedNames, parallel, convertData.ignoreFrameScripts ? frameTraitNames : new ArrayList<>(), isInterface);
instanceInfo.instance_traits.toString(first, abcIndex, new Class[]{TraitClass.class, TraitFunction.class, TraitMethodGetterSetter.class}, this, convertData, path + "/" + instanceInfoName, abc, false, exportMode, false, scriptIndex, class_info, writer, fullyQualifiedNames, parallel, convertData.ignoreFrameScripts ? frameTraitNames : new ArrayList<>(), isInterface);
writer.endClass();
writer.endBlock(); // class

View File

@@ -161,7 +161,7 @@ public class TraitFunction extends Trait implements TraitWithSlot {
*/
@Override
public GraphTextWriter toString(AbcIndexing abcIndex, Trait parent, ConvertData convertData, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, GraphTextWriter writer, List<DottedChain> fullyQualifiedNames, boolean parallel, boolean insideInterface) throws InterruptedException {
writeImports(abcIndex, scriptIndex, classIndex, false, abc, writer, getPackage(abc), fullyQualifiedNames);
writeImports(this, -1, abcIndex, scriptIndex, classIndex, false, abc, writer, getPackage(abc), fullyQualifiedNames);
getMetaData(this, convertData, abc, writer);
writer.startMethod(method_info, getName(abc).getName(abc.constants, new ArrayList<>(), true, false));
toStringHeader(parent, convertData, path, abc, isStatic, exportMode, scriptIndex, classIndex, writer, fullyQualifiedNames, parallel, insideInterface);
@@ -202,7 +202,7 @@ public class TraitFunction extends Trait implements TraitWithSlot {
@Override
public void convert(AbcIndexing abcIndex, Trait parent, ConvertData convertData, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, NulWriter writer, List<DottedChain> fullyQualifiedNames, boolean parallel, ScopeStack scopeStack) throws InterruptedException {
fullyQualifiedNames = new ArrayList<>();
writeImports(abcIndex, scriptIndex, classIndex, false, abc, writer, getPackage(abc), fullyQualifiedNames);
writeImports(this, -1, abcIndex, scriptIndex, classIndex, false, abc, writer, getPackage(abc), fullyQualifiedNames);
writer.startMethod(method_info, getName(abc).getName(abc.constants, new ArrayList<>(), true, false));
convertHeader(parent, convertData, path, abc, isStatic, exportMode, scriptIndex, classIndex, writer, fullyQualifiedNames, parallel);
int bodyIndex = abc.findBodyIndex(method_info);

View File

@@ -185,7 +185,7 @@ public class TraitMethodGetterSetter extends Trait {
@Override
public void convert(AbcIndexing abcIndex, Trait parent, ConvertData convertData, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, NulWriter writer, List<DottedChain> fullyQualifiedNames, boolean parallel, ScopeStack scopeStack) throws InterruptedException {
if (classIndex < 0) {
writeImports(abcIndex, scriptIndex, classIndex, isStatic, abc, writer, getPackage(abc), fullyQualifiedNames);
writeImports(this, -1, abcIndex, scriptIndex, classIndex, isStatic, abc, writer, getPackage(abc), fullyQualifiedNames);
}
writer.startMethod(method_info, getName(abc).getName(abc.constants, new ArrayList<>(), true, false));
path = path + "." + getName(abc).getName(abc.constants, fullyQualifiedNames, false, true);
@@ -238,7 +238,7 @@ public class TraitMethodGetterSetter extends Trait {
public GraphTextWriter toString(AbcIndexing abcIndex, Trait parent, ConvertData convertData, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, GraphTextWriter writer, List<DottedChain> fullyQualifiedNames, boolean parallel, boolean insideInterface) throws InterruptedException {
if (classIndex < 0) {
writeImports(abcIndex, scriptIndex, classIndex, isStatic, abc, writer, getPackage(abc), fullyQualifiedNames);
//writeImports(this, -1, abcIndex, scriptIndex, classIndex, isStatic, abc, writer, getPackage(abc), fullyQualifiedNames);
}
getMetaData(this, convertData, abc, writer);
writer.startMethod(method_info, getName(abc).getName(abc.constants, new ArrayList<>(), true, false));

View File

@@ -295,6 +295,7 @@ public class Traits implements Cloneable, Serializable {
/**
* To string.
*
* @param first Whether to add newline
* @param abcIndex ABC indexing
* @param traitTypes Trait types
* @param parent Parent trait
@@ -314,7 +315,7 @@ public class Traits implements Cloneable, Serializable {
* @return Writer
* @throws InterruptedException On interrupt
*/
public GraphTextWriter toString(AbcIndexing abcIndex, Class[] traitTypes, Trait parent, ConvertData convertData, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, boolean makePackages, int scriptIndex, int classIndex, GraphTextWriter writer, List<DottedChain> fullyQualifiedNames, boolean parallel, List<String> ignoredTraitNames, boolean insideInterface) throws InterruptedException {
public GraphTextWriter toString(Reference<Boolean> first, AbcIndexing abcIndex, Class[] traitTypes, Trait parent, ConvertData convertData, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, boolean makePackages, int scriptIndex, int classIndex, GraphTextWriter writer, List<DottedChain> fullyQualifiedNames, boolean parallel, List<String> ignoredTraitNames, boolean insideInterface) throws InterruptedException {
/*List<Trait> ordered = new ArrayList<>(traits);
loopi:
@@ -384,7 +385,10 @@ public class Traits implements Cloneable, Serializable {
continue;
}
writer.newLine();
if (!first.getVal()) {
writer.newLine();
}
first.setVal(false);
int h = abc.getGlobalTraitId(TraitType.METHOD , isStatic, classIndex, t);
writer.startTrait(h);
if (makePackages) {
@@ -392,7 +396,7 @@ public class Traits implements Cloneable, Serializable {
} else {
trait.toString(abcIndex, parent, convertData, path, abc, isStatic, exportMode, scriptIndex, classIndex, writer, fullyQualifiedNames, parallel, insideInterface);
}
writer.endTrait();
writer.endTrait();
}
return writer;
}

View File

@@ -3872,7 +3872,7 @@ public class Graph {
* @throws InterruptedException On interrupt
*/
public static GraphTextWriter graphToString(List<GraphTargetItem> tree, GraphTextWriter writer, LocalData localData) throws InterruptedException {
boolean lastNewLine = false;
boolean lastNewLine = true;
for (GraphTargetItem ti : tree) {
if (!ti.isEmpty()) {
if (ti.hasSingleNewLineAround() && !lastNewLine) {