15867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com/*
25867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * [The "BSD licence"]
300fc68adf2e39aeb9fed35293f2576bbe729ec4bJesusFreke@JesusFreke.com * Copyright (c) 2010 Ben Gruver (JesusFreke)
45867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * All rights reserved.
55867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com *
65867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * Redistribution and use in source and binary forms, with or without
75867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * modification, are permitted provided that the following conditions
85867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * are met:
95867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * 1. Redistributions of source code must retain the above copyright
105867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com *    notice, this list of conditions and the following disclaimer.
115867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * 2. Redistributions in binary form must reproduce the above copyright
125867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com *    notice, this list of conditions and the following disclaimer in the
135867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com *    documentation and/or other materials provided with the distribution.
145867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * 3. The name of the author may not be used to endorse or promote products
155867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com *    derived from this software without specific prior written permission.
165867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com *
175867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
185867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
195867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
205867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
215867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
225867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
235867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
245867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
255867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
265867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
275867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com */
285867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com
295867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.compackage org.jf.dexlib;
305867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com
315867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.comimport org.jf.dexlib.Util.AnnotatedOutput;
32b3abca4c90929e31e6a8c52bc0178c44e3e53c6bJesusFreke@JesusFreke.comimport org.jf.dexlib.Util.Input;
335867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com
34e5466fee2396e262fe2823f5f5d90ff7e39dd3a7Ben Gruverpublic class MethodIdItem extends Item<MethodIdItem> implements Convertible<MethodIdItem> {
355867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com    private int hashCode = 0;
365867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com
375867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com    private TypeIdItem classType;
385867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com    private ProtoIdItem methodPrototype;
395867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com    private StringIdItem methodName;
405867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com
415867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com    /**
425867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com     * Creates a new uninitialized <code>MethodIdItem</code>
435867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com     * @param dexFile The <code>DexFile</code> that this item belongs to
445867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com     */
455867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com    protected MethodIdItem(DexFile dexFile) {
465867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com        super(dexFile);
475867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com    }
485867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com
495867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com    /**
505867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com     * Creates a new <code>MethodIdItem</code> for the given class, type and name
515867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com     * @param dexFile The <code>DexFile</code> that this item belongs to
525867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com     * @param classType the class that the method is a member of
535867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com     * @param methodPrototype the type of the method
545867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com     * @param methodName the name of the method
555867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com     */
565867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com    private MethodIdItem(DexFile dexFile, TypeIdItem classType, ProtoIdItem methodPrototype, StringIdItem methodName) {
575867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com        this(dexFile);
585867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com        this.classType = classType;
595867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com        this.methodPrototype = methodPrototype;
605867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com        this.methodName = methodName;
615867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com    }
625867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com
635867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com    /**
645867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com     * Returns a <code>MethodIdItem</code> for the given values, and that has been interned into
655867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com     * the given <code>DexFile</code>
665867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com     * @param dexFile The <code>DexFile</code> that this item belongs to
675867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com     * @param classType the class that the method is a member of
685867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com     * @param methodPrototype the type of the method
695867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com     * @param methodName the name of the method
705867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com     * @return a <code>MethodIdItem</code> for the given values, and that has been interned into
715867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com     * the given <code>DexFile</code>
725867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com     */
73928790f2939e0eec7ab2e4653a19c6c27a113634JesusFreke@JesusFreke.com    public static MethodIdItem internMethodIdItem(DexFile dexFile, TypeIdItem classType,
745867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com                                                       ProtoIdItem methodPrototype, StringIdItem methodName) {
755867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com        MethodIdItem methodIdItem = new MethodIdItem(dexFile, classType, methodPrototype, methodName);
765867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com        return dexFile.MethodIdsSection.intern(methodIdItem);
775867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com    }
785867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com
79928790f2939e0eec7ab2e4653a19c6c27a113634JesusFreke@JesusFreke.com    /**
80928790f2939e0eec7ab2e4653a19c6c27a113634JesusFreke@JesusFreke.com     * Looks up a <code>MethodIdItem</code> from the given <code>DexFile</code> for the given
81928790f2939e0eec7ab2e4653a19c6c27a113634JesusFreke@JesusFreke.com     * values
82928790f2939e0eec7ab2e4653a19c6c27a113634JesusFreke@JesusFreke.com     * @param dexFile The <code>DexFile</code> that this item belongs to
83928790f2939e0eec7ab2e4653a19c6c27a113634JesusFreke@JesusFreke.com     * @param classType the class that the method is a member of
84928790f2939e0eec7ab2e4653a19c6c27a113634JesusFreke@JesusFreke.com     * @param methodPrototype the type of the method
85928790f2939e0eec7ab2e4653a19c6c27a113634JesusFreke@JesusFreke.com     * @param methodName the name of the method
86928790f2939e0eec7ab2e4653a19c6c27a113634JesusFreke@JesusFreke.com     * @return a <code>MethodIdItem</code> from the given <code>DexFile</code> for the given
87928790f2939e0eec7ab2e4653a19c6c27a113634JesusFreke@JesusFreke.com     * values, or null if it doesn't exist
88928790f2939e0eec7ab2e4653a19c6c27a113634JesusFreke@JesusFreke.com     */
89928790f2939e0eec7ab2e4653a19c6c27a113634JesusFreke@JesusFreke.com    public static MethodIdItem lookupMethodIdItem(DexFile dexFile, TypeIdItem classType,
90928790f2939e0eec7ab2e4653a19c6c27a113634JesusFreke@JesusFreke.com                                                       ProtoIdItem methodPrototype, StringIdItem methodName) {
91928790f2939e0eec7ab2e4653a19c6c27a113634JesusFreke@JesusFreke.com        MethodIdItem methodIdItem = new MethodIdItem(dexFile, classType, methodPrototype, methodName);
92928790f2939e0eec7ab2e4653a19c6c27a113634JesusFreke@JesusFreke.com        return dexFile.MethodIdsSection.getInternedItem(methodIdItem);
93928790f2939e0eec7ab2e4653a19c6c27a113634JesusFreke@JesusFreke.com    }
94928790f2939e0eec7ab2e4653a19c6c27a113634JesusFreke@JesusFreke.com
955867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com    /** {@inheritDoc} */
965867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com    protected void readItem(Input in, ReadContext readContext) {
975867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com        classType = dexFile.TypeIdsSection.getItemByIndex(in.readShort());
985867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com        methodPrototype = dexFile.ProtoIdsSection.getItemByIndex(in.readShort());
995867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com        methodName = dexFile.StringIdsSection.getItemByIndex(in.readInt());
1005867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com    }
1015867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com
1025867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com    /** {@inheritDoc} */
1035867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com    protected int placeItem(int offset) {
1045867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com        return offset + 8;
1055867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com    }
1065867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com
1075867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com    /** {@inheritDoc} */
1085867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com    protected void writeItem(AnnotatedOutput out) {
1095867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com        if (out.annotates()) {
1105867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com            out.annotate(2, "class_type: " + classType.getTypeDescriptor());
1115867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com            out.annotate(2, "method_prototype: " + methodPrototype.getPrototypeString());
1125867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com            out.annotate(4, "method_name: " + methodName.getStringValue());
1135867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com        }
1145867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com
1158b3b577f00fb3ee76954267e33195ad8312129cdBen Gruver        int classIndex = classType.getIndex();
1168b3b577f00fb3ee76954267e33195ad8312129cdBen Gruver        if (classIndex > 0xffff) {
1178b3b577f00fb3ee76954267e33195ad8312129cdBen Gruver            throw new RuntimeException(String.format("Error writing method_id_item for %s. The type index of " +
1188b3b577f00fb3ee76954267e33195ad8312129cdBen Gruver                    "defining class %s is too large", getMethodString(), classType.getTypeDescriptor()));
1198b3b577f00fb3ee76954267e33195ad8312129cdBen Gruver        }
1208b3b577f00fb3ee76954267e33195ad8312129cdBen Gruver        out.writeShort(classIndex);
1218b3b577f00fb3ee76954267e33195ad8312129cdBen Gruver
1228b3b577f00fb3ee76954267e33195ad8312129cdBen Gruver        int prototypeIndex = methodPrototype.getIndex();
1238b3b577f00fb3ee76954267e33195ad8312129cdBen Gruver        if (prototypeIndex > 0xffff) {
1248b3b577f00fb3ee76954267e33195ad8312129cdBen Gruver            throw new RuntimeException(String.format("Error writing method_id_item for %0. The prototype index of " +
1258b3b577f00fb3ee76954267e33195ad8312129cdBen Gruver                    "method prototype %s is too large", getMethodString(), methodPrototype.getPrototypeString()));
1268b3b577f00fb3ee76954267e33195ad8312129cdBen Gruver        }
1278b3b577f00fb3ee76954267e33195ad8312129cdBen Gruver        out.writeShort(prototypeIndex);
1288b3b577f00fb3ee76954267e33195ad8312129cdBen Gruver
1295867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com        out.writeInt(methodName.getIndex());
1305867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com    }
1315867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com
1325867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com    /** {@inheritDoc} */
1335867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com    public ItemType getItemType() {
1345867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com        return ItemType.TYPE_METHOD_ID_ITEM;
1355867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com    }
1365867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com
1375867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com    /** {@inheritDoc} */
1385867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com    public String getConciseIdentity() {
1395867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com        return "method_id_item: " + getMethodString();
1405867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com    }
1415867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com
1425867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com    /** {@inheritDoc} */
1435867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com    public int compareTo(MethodIdItem o) {
1445867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com        int result = classType.compareTo(o.classType);
1455867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com        if (result != 0) {
1465867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com            return result;
1475867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com        }
1485867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com
1495867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com        result = methodName.compareTo(o.methodName);
1505867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com        if (result != 0) {
1515867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com            return result;
1525867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com        }
1535867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com
1545867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com        return methodPrototype.compareTo(o.methodPrototype);
1555867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com    }
1565867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com
1575867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com    private String cachedMethodString = null;
1585867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com    /**
1595867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com     * @return a string formatted like LclassName;->methodName(TTTT..)R
1605867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com     */
1615867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com    public String getMethodString() {
1625867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com        if (cachedMethodString == null) {
1635867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com            String classType = this.classType.getTypeDescriptor();
1645867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com            String methodName = this.methodName.getStringValue();
1655867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com            String prototypeString = methodPrototype.getPrototypeString();
1665867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com
1675867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com            StringBuilder sb = new StringBuilder(classType.length() + methodName.length() + prototypeString.length() +
1685867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com                    2);
1695867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com            sb.append(classType);
1705867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com            sb.append("->");
1715867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com            sb.append(methodName);
1725867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com            sb.append(prototypeString);
1735867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com            cachedMethodString = sb.toString();
1745867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com        }
1755867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com        return cachedMethodString;
1765867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com    }
1775867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com
178662e42515071ef596745ffe80c461881541bc447Ben Gruver    private String cachedShortMethodString = null;
179c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com    /**
180c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com     * @return a string formatted like methodName(TTTT..)R
181c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com     */
182662e42515071ef596745ffe80c461881541bc447Ben Gruver    public String getShortMethodString() {
183662e42515071ef596745ffe80c461881541bc447Ben Gruver        if (cachedShortMethodString == null) {
184c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com            String methodName = this.methodName.getStringValue();
185c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com            String prototypeString = methodPrototype.getPrototypeString();
186c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com
187c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com            StringBuilder sb = new StringBuilder(methodName.length() + prototypeString.length());
188c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com            sb.append(methodName);
189c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com            sb.append(prototypeString);
190662e42515071ef596745ffe80c461881541bc447Ben Gruver            cachedShortMethodString = sb.toString();
191c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com        }
192662e42515071ef596745ffe80c461881541bc447Ben Gruver        return cachedShortMethodString;
193c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com    }
194c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com
1955867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com    /**
1965867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com     * @return the method prototype
1975867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com     */
1985867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com    public ProtoIdItem getPrototype() {
1995867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com        return methodPrototype;
2005867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com    }
2015867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com
2025867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com    /**
2035867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com     * @return the name of the method
2045867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com     */
2055867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com    public StringIdItem getMethodName() {
2065867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com        return methodName;
2075867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com    }
2085867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com
2095867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com    /**
2105867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com     * @return the class this method is a member of
2115867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com     */
2125867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com    public TypeIdItem getContainingClass() {
2135867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com        return classType;
2145867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com    }
2155867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com
2165867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com    /**
2175867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com     * calculate and cache the hashcode
2185867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com     */
2195867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com    private void calcHashCode() {
2205867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com        hashCode = classType.hashCode();
2215867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com        hashCode = 31 * hashCode + methodPrototype.hashCode();
2225867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com        hashCode = 31 * hashCode + methodName.hashCode();
2235867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com    }
2245867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com
2255867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com    @Override
2265867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com    public int hashCode() {
2275867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com        //there's a small possibility that the actual hash code will be 0. If so, we'll
2285867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com        //just end up recalculating it each time
2295867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com        if (hashCode == 0)
2305867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com            calcHashCode();
2315867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com        return hashCode;
2325867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com    }
2335867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com
2345867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com    @Override
2355867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com    public boolean equals(Object o) {
2365867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com        if (this==o) {
2375867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com            return true;
2385867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com        }
2395867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com        if (o==null || !this.getClass().equals(o.getClass())) {
2405867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com            return false;
2415867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com        }
2425867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com
2435867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com        //This assumes that the referenced items have been interned in both objects.
2445867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com        //This is a valid assumption because all outside code must use the static
2455867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com        //"getInterned..." style methods to make new items, and any item created
2465867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com        //internally is guaranteed to be interned
2475867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com        MethodIdItem other = (MethodIdItem)o;
2485867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com        return (classType == other.classType &&
2495867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com                methodPrototype == other.methodPrototype &&
2505867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com                methodName == other.methodName);
2515867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com    }
252e5466fee2396e262fe2823f5f5d90ff7e39dd3a7Ben Gruver
253e5466fee2396e262fe2823f5f5d90ff7e39dd3a7Ben Gruver    public MethodIdItem convert() {
254e5466fee2396e262fe2823f5f5d90ff7e39dd3a7Ben Gruver        return this;
255e5466fee2396e262fe2823f5f5d90ff7e39dd3a7Ben Gruver    }
2565867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com}
257