1 cananian 1.1.4.1 // HMemberProxy.java, created Wed Jan 12 19:15:03 2000 by cananian
 2 cananian 1.1.4.2 // Copyright (C) 2000 C. Scott Ananian <cananian@alumni.princeton.edu>
 3 cananian 1.1.4.1 // Licensed under the terms of the GNU GPL; see COPYING for details.
 4 cananian 1.1.4.1 package harpoon.ClassFile;
 5 cananian 1.1.4.1 
 6 cananian 1.1.4.5 import harpoon.Util.Util;
 7 cananian 1.1.4.1 /**
 8 cananian 1.1.4.1  * <code>HMemberProxy</code> is a relinkable proxy for an
 9 cananian 1.1.4.1  * <code>HMember</code>.
10 cananian 1.1.4.1  * 
11 cananian 1.1.4.1  * @author  C. Scott Ananian <cananian@alumni.princeton.edu>
12 cananian 1.4      * @version $Id: HMemberProxy.java,v 1.4 2002/04/10 03:04:15 cananian Exp $
13 cananian 1.1.4.1  * @see HFieldProxy
14 cananian 1.1.4.1  * @see HMethodProxy
15 cananian 1.1.4.1  */
16 cananian 1.1.4.5 abstract class HMemberProxy implements HMember {
17 cananian 1.1.4.1     Relinker relinker;
18 cananian 1.1.4.1     boolean sameLinker;
19 cananian 1.1.4.1     private HMember proxy;
20 cananian 1.1.4.6     private final int hashcode;
21 cananian 1.1.4.1 
22 cananian 1.1.4.1     /** Creates a <code>HMemberProxy</code>. */
23 cananian 1.1.4.8     HMemberProxy(Relinker relinker, HMember proxy, int hashcode) {
24 cananian 1.1.4.1         this.relinker = relinker;
25 cananian 1.1.4.6         // one hash code forever.
26 cananian 1.1.4.8         this.hashcode = hashcode;
27 cananian 1.1.4.1     }
28 cananian 1.1.4.1     protected void relink(HMember proxy) {
29 cananian 1.3.2.1         assert !(proxy instanceof HMemberProxy &&
30 cananian 1.3.2.1                       ((HMemberProxy)proxy).relinker==relinker) : "should never proxy to a proxy of this same relinker.";
31 cananian 1.1.4.1         this.proxy = proxy;
32 cananian 1.1.4.1         this.sameLinker = (proxy==null || // keep us safe if the proxy==null
33 cananian 1.1.4.1                            relinker == proxy.getDeclaringClass().getLinker());
34 cananian 1.1.4.1     }
35 cananian 1.1.4.1     // HMember interface
36 cananian 1.1.4.1     public HClass getDeclaringClass() {return wrap(proxy.getDeclaringClass());}
37 cananian 1.1.4.1     public String getDescriptor() { return proxy.getDescriptor(); }
38 cananian 1.1.4.1     public String getName() { return proxy.getName(); }
39 cananian 1.1.4.1     public int getModifiers() { return proxy.getModifiers(); }
40 cananian 1.1.4.1     public boolean isSynthetic() { return proxy.isSynthetic(); }
41 cananian 1.1.4.8     public final int hashCode() { return hashcode; }
42 cananian 1.1.4.7     public abstract String toString();
43 cananian 1.1.4.7     public abstract boolean equals(Object obj);
44 cananian 1.1.4.7 
45 cananian 1.1.4.3     // Comparable interface
46 cananian 1.1.4.3     /** Compares two <code>HMember</code>s lexicographically; first by
47 cananian 1.1.4.3      *  declaring class, then by name, and lastly by descriptor. */
48 cananian 1.3.2.2     public int compareTo(HMember o) {
49 cananian 1.1.4.3         return memberComparator.compare(this, o);
50 cananian 1.1.4.1     }
51 cananian 1.1.4.1 
52 cananian 1.1.4.1     // keep member map up-to-date when hashcode changes.
53 cananian 1.1.4.1     protected void flushMemberMap() { relinker.memberMap.remove(proxy); }
54 cananian 1.1.4.1     protected void updateMemberMap() { relinker.memberMap.put(proxy, this); }
55 cananian 1.1.4.1 
56 cananian 1.1.4.1     // wrap/unwrap
57 cananian 1.1.4.1     protected HClass wrap(HClass hc) {
58 cananian 1.1.4.1         if (sameLinker && hc != proxy.getDeclaringClass()) return hc;
59 cananian 1.1.4.1         return relinker.wrap(hc);
60 cananian 1.1.4.1     }
61 cananian 1.1.4.1     protected HClass unwrap(HClass hc){
62 cananian 1.1.4.1         if (sameLinker && hc != getDeclaringClass()) return hc;
63 cananian 1.1.4.1         return relinker.unwrap(hc);
64 cananian 1.1.4.1     }
65 cananian 1.1.4.1     // array wrap/unwrap.
66 cananian 1.1.4.1     protected HClass[] wrap(HClass[] hc) {
67 cananian 1.1.4.1         HClass[] result = new HClass[hc.length];
68 cananian 1.1.4.1         for (int i=0; i<result.length; i++)
69 cananian 1.1.4.1             result[i] = wrap(hc[i]);
70 cananian 1.1.4.1         return result;
71 cananian 1.1.4.1     }
72 cananian 1.1.4.1     protected HClass[] unwrap(HClass[] hc) {
73 cananian 1.1.4.1         HClass[] result = new HClass[hc.length];
74 cananian 1.1.4.1         for (int i=0; i<result.length; i++)
75 cananian 1.1.4.1             result[i] = unwrap(hc[i]);
76 cananian 1.1.4.1         return result;
77 cananian 1.1.4.1     }
78 cananian 1.2     }