0
|
1 /*
|
|
2 * Copyright 2002-2007 Sun Microsystems, Inc. All Rights Reserved.
|
|
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
4 *
|
|
5 * This code is free software; you can redistribute it and/or modify it
|
|
6 * under the terms of the GNU General Public License version 2 only, as
|
|
7 * published by the Free Software Foundation.
|
|
8 *
|
|
9 * This code is distributed in the hope that it will be useful, but WITHOUT
|
|
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
12 * version 2 for more details (a copy is included in the LICENSE file that
|
|
13 * accompanied this code).
|
|
14 *
|
|
15 * You should have received a copy of the GNU General Public License version
|
|
16 * 2 along with this work; if not, write to the Free Software Foundation,
|
|
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
18 *
|
|
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
|
20 * CA 95054 USA or visit www.sun.com if you need additional information or
|
|
21 * have any questions.
|
|
22 *
|
|
23 */
|
|
24
|
|
25 package sun.jvm.hotspot.jdi;
|
|
26
|
|
27 import com.sun.jdi.*;
|
|
28 import sun.jvm.hotspot.oops.Klass;
|
|
29 import sun.jvm.hotspot.oops.InstanceKlass;
|
|
30
|
|
31 import java.util.*;
|
|
32 import java.lang.ref.SoftReference;
|
|
33
|
|
34 public class ClassTypeImpl extends ReferenceTypeImpl
|
|
35 implements ClassType
|
|
36 {
|
|
37 private SoftReference interfacesCache = null;
|
|
38 private SoftReference allInterfacesCache = null;
|
|
39 private SoftReference subclassesCache = null;
|
|
40
|
|
41 protected ClassTypeImpl(VirtualMachine aVm, InstanceKlass aRef) {
|
|
42 super(aVm, aRef);
|
|
43 }
|
|
44
|
|
45 public ClassType superclass() {
|
|
46 InstanceKlass kk = (InstanceKlass)ref().getSuper();
|
|
47 if (kk == null) {
|
|
48 return null;
|
|
49 }
|
|
50 return (ClassType) vm.referenceType(kk);
|
|
51 }
|
|
52
|
|
53 public List interfaces() {
|
|
54 List interfaces = (interfacesCache != null)? (List) interfacesCache.get() : null;
|
|
55 if (interfaces == null) {
|
|
56 checkPrepared();
|
|
57 interfaces = Collections.unmodifiableList(getInterfaces());
|
|
58 interfacesCache = new SoftReference(interfaces);
|
|
59 }
|
|
60 return interfaces;
|
|
61 }
|
|
62
|
|
63 void addInterfaces(List list) {
|
|
64 List immediate = interfaces();
|
|
65
|
|
66 HashSet hashList = new HashSet(list);
|
|
67 hashList.addAll(immediate);
|
|
68 list.clear();
|
|
69 list.addAll(hashList);
|
|
70
|
|
71 Iterator iter = immediate.iterator();
|
|
72 while (iter.hasNext()) {
|
|
73 InterfaceTypeImpl interfaze = (InterfaceTypeImpl)iter.next();
|
|
74 interfaze.addSuperinterfaces(list);
|
|
75 }
|
|
76
|
|
77 ClassTypeImpl superclass = (ClassTypeImpl)superclass();
|
|
78 if (superclass != null) {
|
|
79 superclass.addInterfaces(list);
|
|
80 }
|
|
81 }
|
|
82
|
|
83 public List allInterfaces() {
|
|
84 List allinterfaces = (allInterfacesCache != null)? (List) allInterfacesCache.get() : null;
|
|
85 if (allinterfaces == null) {
|
|
86 checkPrepared();
|
|
87 allinterfaces = new ArrayList();
|
|
88 addInterfaces(allinterfaces);
|
|
89 allinterfaces = Collections.unmodifiableList(allinterfaces);
|
|
90 allInterfacesCache = new SoftReference(allinterfaces);
|
|
91 }
|
|
92 return allinterfaces;
|
|
93 }
|
|
94
|
|
95 public List subclasses() {
|
|
96 List subclasses = (subclassesCache != null)? (List) subclassesCache.get() : null;
|
|
97 if (subclasses == null) {
|
|
98 List all = vm.allClasses();
|
|
99 subclasses = new ArrayList(0);
|
|
100 Iterator iter = all.iterator();
|
|
101 while (iter.hasNext()) {
|
|
102 ReferenceType refType = (ReferenceType)iter.next();
|
|
103 if (refType instanceof ClassType) {
|
|
104 ClassType clazz = (ClassType)refType;
|
|
105 ClassType superclass = clazz.superclass();
|
|
106 if ((superclass != null) && superclass.equals(this)) {
|
|
107 subclasses.add(refType);
|
|
108 }
|
|
109 }
|
|
110 }
|
|
111 subclasses = Collections.unmodifiableList(subclasses);
|
|
112 subclassesCache = new SoftReference(subclasses);
|
|
113 }
|
|
114 return subclasses;
|
|
115 }
|
|
116
|
|
117 public Method concreteMethodByName(String name, String signature) {
|
|
118 checkPrepared();
|
|
119 List methods = visibleMethods();
|
|
120 Method method = null;
|
|
121 Iterator iter = methods.iterator();
|
|
122 while (iter.hasNext()) {
|
|
123 Method candidate = (Method)iter.next();
|
|
124 if (candidate.name().equals(name) &&
|
|
125 candidate.signature().equals(signature) &&
|
|
126 !candidate.isAbstract()) {
|
|
127
|
|
128 method = candidate;
|
|
129 break;
|
|
130 }
|
|
131 }
|
|
132 return method;
|
|
133 }
|
|
134
|
|
135 List getAllMethods() {
|
|
136 ArrayList list = new ArrayList(methods());
|
|
137 ClassType clazz = superclass();
|
|
138 while (clazz != null) {
|
|
139 list.addAll(clazz.methods());
|
|
140 clazz = clazz.superclass();
|
|
141 }
|
|
142 /*
|
|
143 * Avoid duplicate checking on each method by iterating through
|
|
144 * duplicate-free allInterfaces() rather than recursing
|
|
145 */
|
|
146 Iterator iter = allInterfaces().iterator();
|
|
147 while (iter.hasNext()) {
|
|
148 InterfaceType interfaze = (InterfaceType)iter.next();
|
|
149 list.addAll(interfaze.methods());
|
|
150 }
|
|
151 return list;
|
|
152 }
|
|
153
|
|
154 List inheritedTypes() {
|
|
155 List inherited = new ArrayList(interfaces());
|
|
156 if (superclass() != null) {
|
|
157 inherited.add(0, superclass()); /* insert at front */
|
|
158 }
|
|
159 return inherited;
|
|
160 }
|
|
161
|
|
162 public boolean isEnum() {
|
|
163 ClassTypeImpl superclass = (ClassTypeImpl) superclass();
|
|
164 if (superclass != null) {
|
|
165 return superclass.typeNameAsSymbol().equals(vm.javaLangEnum());
|
|
166 } else {
|
|
167 return false;
|
|
168 }
|
|
169 }
|
|
170
|
|
171 public void setValue(Field field, Value value)
|
|
172 throws InvalidTypeException, ClassNotLoadedException {
|
|
173 vm.throwNotReadOnlyException("ClassType.setValue(...)");
|
|
174 }
|
|
175
|
|
176
|
|
177 public Value invokeMethod(ThreadReference threadIntf, Method methodIntf,
|
|
178 List arguments, int options)
|
|
179 throws InvalidTypeException,
|
|
180 ClassNotLoadedException,
|
|
181 IncompatibleThreadStateException,
|
|
182 InvocationException {
|
|
183 vm.throwNotReadOnlyException("ClassType.invokeMethod(...)");
|
|
184 return null;
|
|
185 }
|
|
186
|
|
187 public ObjectReference newInstance(ThreadReference threadIntf,
|
|
188 Method methodIntf,
|
|
189 List arguments, int options)
|
|
190 throws InvalidTypeException,
|
|
191 ClassNotLoadedException,
|
|
192 IncompatibleThreadStateException,
|
|
193 InvocationException {
|
|
194 vm.throwNotReadOnlyException("ClassType.newInstance(...)");
|
|
195 return null;
|
|
196 }
|
|
197
|
|
198 void addVisibleMethods(Map methodMap) {
|
|
199 /*
|
|
200 * Add methods from
|
|
201 * parent types first, so that the methods in this class will
|
|
202 * overwrite them in the hash table
|
|
203 */
|
|
204
|
|
205 Iterator iter = interfaces().iterator();
|
|
206 while (iter.hasNext()) {
|
|
207 InterfaceTypeImpl interfaze = (InterfaceTypeImpl)iter.next();
|
|
208 interfaze.addVisibleMethods(methodMap);
|
|
209 }
|
|
210
|
|
211 ClassTypeImpl clazz = (ClassTypeImpl)superclass();
|
|
212 if (clazz != null) {
|
|
213 clazz.addVisibleMethods(methodMap);
|
|
214 }
|
|
215
|
|
216 addToMethodMap(methodMap, methods());
|
|
217 }
|
|
218
|
|
219 boolean isAssignableTo(ReferenceType type) {
|
|
220 ClassTypeImpl superclazz = (ClassTypeImpl)superclass();
|
|
221 if (this.equals(type)) {
|
|
222 return true;
|
|
223 } else if ((superclazz != null) && superclazz.isAssignableTo(type)) {
|
|
224 return true;
|
|
225 } else {
|
|
226 List interfaces = interfaces();
|
|
227 Iterator iter = interfaces.iterator();
|
|
228 while (iter.hasNext()) {
|
|
229 InterfaceTypeImpl interfaze = (InterfaceTypeImpl)iter.next();
|
|
230 if (interfaze.isAssignableTo(type)) {
|
|
231 return true;
|
|
232 }
|
|
233 }
|
|
234 return false;
|
|
235 }
|
|
236 }
|
|
237
|
|
238 public String toString() {
|
|
239 return "class " + name() + "(" + loaderString() + ")";
|
|
240 }
|
|
241 }
|