/* * Copyright (C) 2010-2016 JPEXS, All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3.0 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. */ package com.jpexs.decompiler.flash.abc.types.traits; import com.jpexs.decompiler.flash.abc.ABC; import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; import com.jpexs.decompiler.flash.abc.avm2.model.NewFunctionAVM2Item; import com.jpexs.decompiler.flash.abc.types.AssignedValue; import com.jpexs.decompiler.flash.abc.types.ConvertData; 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.configuration.Configuration; import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode; import com.jpexs.decompiler.flash.exporters.script.Dependency; import com.jpexs.decompiler.flash.exporters.script.DependencyParser; 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.graph.DottedChain; import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.model.LocalData; import com.jpexs.helpers.Helper; import java.util.ArrayList; import java.util.HashMap; import java.util.List; /** * * @author JPEXS */ public class TraitSlotConst extends Trait implements TraitWithSlot { public int slot_id; public int type_index; public int value_index; public int value_kind; @Override public void delete(ABC abc, boolean d) { abc.constants.getMultiname(name_index).deleted = d; } @Override public int getSlotIndex() { return slot_id; } @Override public String toString(ABC abc, List<DottedChain> fullyQualifiedNames) { String typeStr = "*"; if (type_index > 0) { typeStr = abc.constants.getMultiname(type_index).toString(abc.constants, fullyQualifiedNames); } return "0x" + Helper.formatAddress(fileOffset) + " " + Helper.byteArrToString(bytes) + " SlotConst " + abc.constants.getMultiname(name_index).toString(abc.constants, fullyQualifiedNames) + " slot=" + slot_id + " type=" + typeStr + " value=" + (new ValueKind(value_index, value_kind)).toString(abc.constants) + " metadata=" + Helper.intArrToString(metadata); } public String getType(AVM2ConstantPool constants, List<DottedChain> fullyQualifiedNames) { String typeStr = "*"; if (type_index > 0) { typeStr = constants.getMultiname(type_index).getName(constants, fullyQualifiedNames, false, true); } return typeStr; } public GraphTextWriter getNameStr(GraphTextWriter writer, ABC abc, List<DottedChain> fullyQualifiedNames) { String typeStr = getType(abc.constants, fullyQualifiedNames); if (typeStr.equals("*")) { typeStr = ""; } else { typeStr = ":" + typeStr; } ValueKind val = null; if (value_kind != 0) { val = new ValueKind(value_index, value_kind); } String slotconst = "var"; if (kindType == TRAIT_CONST) { slotconst = "const"; } if (val != null && val.isNamespace()) { slotconst = "namespace"; } writer.hilightSpecial(slotconst + " ", HighlightSpecialType.TRAIT_TYPE); writer.hilightSpecial(getName(abc).getName(abc.constants, fullyQualifiedNames, false, true), HighlightSpecialType.TRAIT_NAME); writer.hilightSpecial(typeStr, HighlightSpecialType.TRAIT_TYPE_NAME); return writer; } public void getValueStr(ScriptExportMode exportMode, Trait parent, ConvertData convertData, GraphTextWriter writer, ABC abc, List<DottedChain> fullyQualifiedNames) throws InterruptedException { if (convertData.assignedValues.containsKey(this)) { AssignedValue assignment = convertData.assignedValues.get(this); writer.startTrait(assignment.initializer); writer.startMethod(assignment.method); if (Configuration.showMethodBodyId.get()) { writer.appendNoHilight("// method body index: "); writer.appendNoHilight(abc.findBodyIndex(assignment.method)); writer.appendNoHilight(" method index: "); writer.appendNoHilight(assignment.method); writer.newLine(); } if (exportMode != ScriptExportMode.AS_METHOD_STUBS) { assignment.value.toString(writer, LocalData.create(abc.constants, new HashMap<>(), fullyQualifiedNames)); } writer.endMethod(); writer.endTrait(); return; } if (value_kind != 0) { ValueKind val = new ValueKind(value_index, value_kind); writer.hilightSpecial(val.toString(abc.constants), HighlightSpecialType.TRAIT_VALUE); } } public boolean isNamespace() { if (value_kind != 0) { ValueKind val = new ValueKind(value_index, value_kind); return val.isNamespace(); } return false; } @Override public GraphTextWriter toString(Trait parent, ConvertData convertData, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, GraphTextWriter writer, List<DottedChain> fullyQualifiedNames, boolean parallel) throws InterruptedException { getMetaData(parent, convertData, abc, writer); Multiname n = getName(abc); boolean showModifier = true; if ((classIndex == -1) && (n != null)) { Namespace ns = n.getNamespace(abc.constants); if (ns == null) { showModifier = false; } else if ((ns.kind != Namespace.KIND_PACKAGE) && (ns.kind != Namespace.KIND_PACKAGE_INTERNAL)) { showModifier = false; } } if (showModifier) { getModifiers(abc, isStatic, writer); } if (convertData.assignedValues.containsKey(this)) { GraphTargetItem val = convertData.assignedValues.get(this).value; if (val instanceof NewFunctionAVM2Item) { return val.toString(writer, LocalData.create(abc.constants, new HashMap<>(), fullyQualifiedNames)); } } getNameStr(writer, abc, fullyQualifiedNames); if (value_kind != 0 || convertData.assignedValues.containsKey(this)) { writer.appendNoHilight(" = "); getValueStr(exportMode, parent, convertData, writer, abc, fullyQualifiedNames); } return writer.appendNoHilight(";").newLine(); } @Override public void convert(Trait parent, ConvertData convertData, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, NulWriter writer, List<DottedChain> fullyQualifiedNames, boolean parallel) throws InterruptedException { getNameStr(writer, abc, fullyQualifiedNames); if (value_kind != 0 || convertData.assignedValues.containsKey(this)) { getValueStr(exportMode, parent, convertData, writer, abc, fullyQualifiedNames); } } public boolean isConst() { return kindType == TRAIT_CONST; } public boolean isVar() { return kindType == TRAIT_SLOT; } @Override public int removeTraps(int scriptIndex, int classIndex, boolean isStatic, ABC abc, String path) { //do nothing return 0; } @Override public TraitSlotConst clone() { TraitSlotConst ret = (TraitSlotConst) super.clone(); return ret; } @Override public void getDependencies(String customNs, ABC abc, List<Dependency> dependencies, List<String> uses, DottedChain ignorePackage, List<DottedChain> fullyQualifiedNames) { if (ignorePackage == null) { ignorePackage = getPackage(abc); } super.getDependencies(customNs, abc, dependencies, uses, ignorePackage, fullyQualifiedNames); DependencyParser.parseDependenciesFromMultiname(customNs, abc, dependencies, uses, abc.constants.getMultiname(type_index), getPackage(abc), fullyQualifiedNames, DependencyType.SIGNATURE); } @Override public boolean isVisible(boolean isStatic, ABC abc) { if (Configuration.handleSkinPartsAutomatically.get()) { /* Hide: private static var _skinParts (part of [SkinPart] compilations) */ if (isStatic && "_skinParts".equals(getName(abc).getName(abc.constants, new ArrayList<>(), true, true))) { if (kindType == Trait.TRAIT_SLOT) { if ("_skinParts".equals(getName(abc).getName(abc.constants, new ArrayList<>(), true, true))) { if (getName(abc).getNamespace(abc.constants).kind == Namespace.KIND_PRIVATE) { return false; } } } } } return true; } @Override public GraphTextWriter convertTraitHeader(ABC abc, GraphTextWriter writer) { convertCommonHeaderFlags(isConst() ? "const" : "slot", abc, writer); writer.newLine(); writer.appendNoHilight("slotid "); writer.hilightSpecial(Integer.toString(slot_id), HighlightSpecialType.SLOT_ID); writer.newLine(); writer.appendNoHilight("type "); writer.hilightSpecial(abc.constants.multinameToString(type_index), HighlightSpecialType.TRAIT_TYPE_NAME); writer.newLine(); writer.appendNoHilight("value "); writer.hilightSpecial((new ValueKind(value_index, value_kind).toASMString(abc.constants)), HighlightSpecialType.TRAIT_VALUE); writer.newLine(); return writer; } }