KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > gnu > mapping > InheritingEnvironment


1 // Copyright (c) 2004 Per M.A. Bothner.
2
// This is free software; for terms and warranty disclaimer see ./COPYING.
3

4 package gnu.mapping;
5
6 public class InheritingEnvironment extends SimpleEnvironment
7 {
8   int numInherited;
9   Environment[] inherited;
10   Namespace[] namespaceMap;
11   Object JavaDoc[] propertyMap;
12   int baseTimestamp;
13
14   public InheritingEnvironment (String JavaDoc name, Environment parent)
15   {
16     super(name);
17     addParent(parent);
18     if (parent instanceof SimpleEnvironment)
19       {
20         int timestamp = ++((SimpleEnvironment) parent).currentTimestamp;
21         baseTimestamp = timestamp;
22         currentTimestamp = timestamp;
23       }
24   }
25
26   public final int getNumParents () { return numInherited; }
27   public final Environment getParent (int index) { return inherited[index]; }
28
29   public void addParent (Environment env)
30   {
31     if (numInherited == 0)
32       inherited = new Environment[4];
33     else if (numInherited <= inherited.length)
34       {
35      Environment[] newInherited
36        = new Environment[2 * numInherited];
37      System.arraycopy(inherited, 0, newInherited, 0, numInherited);
38      inherited = newInherited;
39       }
40     inherited[numInherited] = env;
41     numInherited++;
42   }
43
44   public NamedLocation lookupInherited (Symbol name, Object JavaDoc property, int hash)
45   {
46     for (int i = 0; i < numInherited; i++)
47       {
48     Symbol sym = name;
49     Object JavaDoc prop = property;
50     if (namespaceMap != null && namespaceMap.length > 2*i)
51       {
52         Object JavaDoc srcNamespace = namespaceMap[2*i];
53         Object JavaDoc dstNamespace = namespaceMap[2*i+1];
54         if (srcNamespace != null || dstNamespace != null)
55           {
56         if (name.getNamespace() != dstNamespace)
57           continue;
58         sym = Symbol.make(srcNamespace, name.getName());
59           }
60       }
61     if (propertyMap != null && propertyMap.length > 2*i)
62       {
63         Object JavaDoc srcProperty = propertyMap[2*i];
64         Object JavaDoc dstProperty = propertyMap[2*i+1];
65         if (srcProperty != null || dstProperty != null)
66           {
67         if (property != dstProperty)
68           continue;
69         prop = srcProperty;
70           }
71       }
72     NamedLocation loc = inherited[i].lookup(sym, prop, hash);
73     if (loc != null && loc.isBound())
74       {
75         if (! (loc instanceof SharedLocation)
76         || ((SharedLocation) loc).timestamp < baseTimestamp)
77           return loc;
78       }
79       }
80     return null;
81   }
82
83   public NamedLocation lookup (Symbol name, Object JavaDoc property, int hash)
84   {
85     NamedLocation loc = super.lookup(name, property, hash);
86     if (loc != null && loc.isBound())
87       return loc;
88     return lookupInherited(name, property, hash);
89   }
90
91   public synchronized NamedLocation
92   getLocation (Symbol name, Object JavaDoc property, int hash, boolean create)
93   {
94     NamedLocation loc = lookupDirect(name, property, hash);
95     if (loc != null && (create || loc.isBound()))
96       return loc;
97     if ((flags & INDIRECT_DEFINES) != 0 && create)
98       loc = inherited[0].getLocation(name, property, hash, true);
99     else
100       loc = lookupInherited(name, property, hash);
101
102     if (loc != null)
103       {
104     if (create /* && loc.getEnvironment() != this*/)
105       {
106         NamedLocation xloc = addUnboundLocation(name, property, hash);
107         if ((flags & CAN_DEFINE) == 0 && loc.isBound())
108           redefineError(name, property, xloc);
109         xloc.base = loc;
110             if (loc.value == IndirectableLocation.INDIRECT_FLUIDS)
111               xloc.value = loc.value;
112         else if ((flags & DIRECT_INHERITED_ON_SET) != 0)
113           xloc.value = IndirectableLocation.DIRECT_ON_SET;
114         else
115           xloc.value = null;
116         if (xloc instanceof SharedLocation)
117           ((SharedLocation) xloc).timestamp = baseTimestamp;
118         return xloc;
119       }
120     else
121       return loc;
122       }
123     return create ? addUnboundLocation(name, property, hash) : null;
124   }
125
126   public LocationEnumeration enumerateAllLocations()
127   {
128     LocationEnumeration it = new LocationEnumeration(table, 1 << log2Size);
129     it.env = this;
130     if (inherited != null && inherited.length > 0)
131       {
132     it.inherited = inherited[0].enumerateAllLocations();
133     it.index = 0;
134       }
135     return it;
136   }
137
138   protected boolean hasMoreElements (LocationEnumeration it)
139   {
140     if (it.inherited != null)
141       {
142     for (;;)
143       {
144         NamedLocation loc = it.curLoc;
145         for (;;)
146           {
147         it.inherited.curLoc = loc;
148         if (! it.inherited.hasMoreElements())
149           {
150             it.curLoc = it.inherited.curLoc;
151             break;
152           }
153         loc = it.inherited.curLoc;
154         if (lookup(loc.name, loc.property) == loc)
155           {
156             it.curLoc = loc;
157             return true;
158           }
159         loc = loc.next;
160           }
161         if (++it.index == numInherited)
162           break;
163         it.inherited = inherited[it.index].enumerateAllLocations();
164       }
165     it.inherited = null;
166     it.bindings = table;
167     it.index = 1 << log2Size;
168       }
169     return super.hasMoreElements(it);
170   }
171
172   protected void toStringBase (StringBuffer JavaDoc sbuf)
173   {
174     sbuf.append(" baseTs:");
175     sbuf.append(baseTimestamp);
176     for (int i = 0; i < numInherited; i++)
177       {
178     sbuf.append(" base:");
179     sbuf.append(inherited[i].toStringVerbose());
180       }
181   }
182 }
183
Popular Tags