/* * 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.avm2.model; import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; import com.jpexs.decompiler.flash.abc.types.Namespace; import com.jpexs.decompiler.flash.helpers.GraphTextWriter; import com.jpexs.decompiler.graph.DottedChain; import com.jpexs.decompiler.graph.GraphSourceItem; import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.TypeItem; import com.jpexs.decompiler.graph.model.LocalData; import java.util.ArrayList; import java.util.HashMap; import java.util.List; /** * * @author JPEXS */ public class FullMultinameAVM2Item extends AVM2Item { public int multinameIndex; public GraphTargetItem name; public GraphTargetItem namespace; public boolean property; public String resolvedMultinameName; public FullMultinameAVM2Item(boolean property, GraphSourceItem instruction, GraphSourceItem lineStartIns, int multinameIndex, String resolvedMultinameName, GraphTargetItem name) { super(instruction, lineStartIns, PRECEDENCE_PRIMARY); this.multinameIndex = multinameIndex; this.name = name; this.namespace = null; this.property = property; this.resolvedMultinameName = resolvedMultinameName; } public FullMultinameAVM2Item(boolean property, GraphSourceItem instruction, GraphSourceItem lineStartIns, int multinameIndex, String resolvedMultinameName) { super(instruction, lineStartIns, PRECEDENCE_PRIMARY); this.multinameIndex = multinameIndex; this.resolvedMultinameName = resolvedMultinameName; this.name = null; this.namespace = null; this.property = property; } public FullMultinameAVM2Item(boolean property, GraphSourceItem instruction, GraphSourceItem lineStartIns, int multinameIndex, String resolvedMultinameName, GraphTargetItem name, GraphTargetItem namespace) { super(instruction, lineStartIns, PRECEDENCE_PRIMARY); this.multinameIndex = multinameIndex; this.name = name; this.namespace = namespace; this.property = property; this.resolvedMultinameName = resolvedMultinameName; } public boolean isRuntime() { return (name != null) || (namespace != null); } public boolean isTopLevel(String tname, AVM2ConstantPool constants, HashMap<Integer, String> localRegNames, List<DottedChain> fullyQualifiedNames) throws InterruptedException { String cname; if (name != null) { cname = name.toString(LocalData.create(constants, localRegNames, fullyQualifiedNames)); } else { cname = (constants.getMultiname(multinameIndex).getName(constants, fullyQualifiedNames, true, true)); } String cns = ""; if (namespace != null) { cns = namespace.toString(LocalData.create(constants, localRegNames, fullyQualifiedNames)); } else { Namespace ns = constants.getMultiname(multinameIndex).getNamespace(constants); if ((ns != null) && (ns.name_index != 0)) { cns = ns.getName(constants).toPrintableString(true); } } return cname.equals(tname) && cns.isEmpty(); } public boolean isXML(AVM2ConstantPool constants, HashMap<Integer, String> localRegNames, List<DottedChain> fullyQualifiedNames) throws InterruptedException { return isTopLevel("XML", constants, localRegNames, fullyQualifiedNames); } @Override public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) throws InterruptedException { if (namespace != null) { namespace.toString(writer, localData); writer.append("::"); } else { /*Namespace ns = constants.getMultiname(multinameIndex).getNamespace(constants); if ((ns != null)&&(ns.name_index!=0)) { ret = hilight(ns.getName(constants) + "::")+ret; }*/ } if (name != null) { writer.append("["); if (name instanceof IntegerValueAVM2Item) { name.toString(writer, localData); } else { name.toStringString(writer, localData); } writer.append("]"); } else { AVM2ConstantPool constants = localData.constantsAvm2; List<DottedChain> fullyQualifiedNames = property ? new ArrayList<>() : localData.fullyQualifiedNames; if (multinameIndex > 0 && multinameIndex < constants.getMultinameCount()) { writer.append(constants.getMultiname(multinameIndex).getName(constants, fullyQualifiedNames, false, true)); } else { writer.append("§§multiname(").append(multinameIndex).append(")"); } } return writer; } public boolean compareSame(FullMultinameAVM2Item other) { if (multinameIndex != other.multinameIndex) { return false; } GraphTargetItem tiName = name; if (name != null) { name = name.getThroughDuplicate(); } while (tiName instanceof LocalRegAVM2Item) { if (((LocalRegAVM2Item) tiName).computedValue != null) { tiName = ((LocalRegAVM2Item) tiName).computedValue.getThroughNotCompilable().getThroughDuplicate(); } else { break; } } GraphTargetItem tiName2 = other.name; if (tiName2 != null) { tiName2 = tiName2.getThroughDuplicate(); } while (tiName2 instanceof LocalRegAVM2Item) { if (((LocalRegAVM2Item) tiName2).computedValue != null) { tiName2 = ((LocalRegAVM2Item) tiName2).computedValue.getThroughNotCompilable().getThroughDuplicate(); } else { break; } } if (tiName != tiName2) { return false; } GraphTargetItem tiNameSpace = namespace; if (tiNameSpace != null) { tiNameSpace = tiNameSpace.getThroughDuplicate(); } while (tiNameSpace instanceof LocalRegAVM2Item) { if (((LocalRegAVM2Item) tiNameSpace).computedValue != null) { tiNameSpace = ((LocalRegAVM2Item) tiNameSpace).computedValue.getThroughNotCompilable().getThroughDuplicate(); } } GraphTargetItem tiNameSpace2 = other.namespace; if (tiNameSpace2 != null) { tiNameSpace2 = tiNameSpace2.getThroughDuplicate(); } while (tiNameSpace2 instanceof LocalRegAVM2Item) { if (((LocalRegAVM2Item) tiNameSpace2).computedValue != null) { tiNameSpace2 = ((LocalRegAVM2Item) tiNameSpace2).computedValue.getThroughNotCompilable().getThroughDuplicate(); } } return (tiNameSpace == tiNameSpace2); } @Override public GraphTargetItem returnType() { return TypeItem.UNBOUNDED; } @Override public boolean hasReturnValue() { return true; } }