History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/com/sun/tools/jdi/ClassTypeImpl.java (1 of 18352 files). Show all

Unified · Split

java/pkg/com/sun/tools/jdi/ClassTypeImpl.java+428−0
@@ -0,0 +1,428 @@
1/*
2 * Copyright (c) 1998, 2008, Oracle and/or its affiliates. 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. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package com.sun.tools.jdi;
27
28import com.sun.jdi.*;
29
30import java.util.*;
31
32public class ClassTypeImpl extends ReferenceTypeImpl
33 implements ClassType
34{
35 private boolean cachedSuperclass = false;
36 private ClassType superclass = null;
37 private int lastLine = -1;
38 private List<InterfaceType> interfaces = null;
39
40 protected ClassTypeImpl(VirtualMachine aVm,long aRef) {
41 super(aVm, aRef);
42 }
43
44 public ClassType superclass() {
45 if(!cachedSuperclass) {
46 ClassTypeImpl sup = null;
47 try {
48 sup = JDWP.ClassType.Superclass.
49 process(vm, this).superclass;
50 } catch (JDWPException exc) {
51 throw exc.toJDIException();
52 }
53
54 /*
55 * If there is a superclass, cache its
56 * ClassType here. Otherwise,
57 * leave the cache reference null.
58 */
59 if (sup != null) {
60 superclass = sup;
61 }
62 cachedSuperclass = true;
63 }
64
65 return superclass;
66 }
67
68 public List<InterfaceType> interfaces() {
69 if (interfaces == null) {
70 interfaces = getInterfaces();
71 }
72 return interfaces;
73 }
74
75 void addInterfaces(List<InterfaceType> list) {
76 List<InterfaceType> immediate = interfaces();
77 list.addAll(interfaces());
78
79 Iterator iter = immediate.iterator();
80 while (iter.hasNext()) {
81 InterfaceTypeImpl interfaze = (InterfaceTypeImpl)iter.next();
82 interfaze.addSuperinterfaces(list);
83 }
84
85 ClassTypeImpl superclass = (ClassTypeImpl)superclass();
86 if (superclass != null) {
87 superclass.addInterfaces(list);
88 }
89 }
90
91 public List<InterfaceType> allInterfaces() {
92 List<InterfaceType> all = new ArrayList<InterfaceType>();
93 addInterfaces(all);
94 return all;
95 }
96
97 public List<ClassType> subclasses() {
98 List<ClassType> subs = new ArrayList<ClassType>();
99 for (ReferenceType refType : vm.allClasses()) {
100 if (refType instanceof ClassType) {
101 ClassType clazz = (ClassType)refType;
102 ClassType superclass = clazz.superclass();
103 if ((superclass != null) && superclass.equals(this)) {
104 subs.add((ClassType)refType);
105 }
106 }
107 }
108
109 return subs;
110 }
111
112 public boolean isEnum() {
113 ClassType superclass = superclass();
114 if (superclass != null &&
115 superclass.name().equals("java.lang.Enum")) {
116 return true;
117 }
118 return false;
119 }
120
121 public void setValue(Field field, Value value)
122 throws InvalidTypeException, ClassNotLoadedException {
123
124 validateMirror(field);
125 validateMirrorOrNull(value);
126 validateFieldSet(field);
127
128 // More validation specific to setting from a ClassType
129 if(!field.isStatic()) {
130 throw new IllegalArgumentException(
131 "Must set non-static field through an instance");
132 }
133
134 try {
135 JDWP.ClassType.SetValues.FieldValue[] values =
136 new JDWP.ClassType.SetValues.FieldValue[1];
137 values[0] = new JDWP.ClassType.SetValues.FieldValue(
138 ((FieldImpl)field).ref(),
139 // validate and convert if necessary
140 ValueImpl.prepareForAssignment(value, (FieldImpl)field));
141
142 try {
143 JDWP.ClassType.SetValues.process(vm, this, values);
144 } catch (JDWPException exc) {
145 throw exc.toJDIException();
146 }
147 } catch (ClassNotLoadedException e) {
148 /*
149 * Since we got this exception,
150 * the field type must be a reference type. The value
151 * we're trying to set is null, but if the field's
152 * class has not yet been loaded through the enclosing
153 * class loader, then setting to null is essentially a
154 * no-op, and we should allow it without an exception.
155 */
156 if (value != null) {
157 throw e;
158 }
159 }
160 }
161
162 PacketStream sendInvokeCommand(final ThreadReferenceImpl thread,
163 final MethodImpl method,
164 final ValueImpl[] args,
165 final int options) {
166 CommandSender sender =
167 new CommandSender() {
168 public PacketStream send() {
169 return JDWP.ClassType.InvokeMethod.enqueueCommand(
170 vm, ClassTypeImpl.this, thread,
171 method.ref(), args, options);
172 }
173 };
174
175 PacketStream stream;
176 if ((options & INVOKE_SINGLE_THREADED) != 0) {
177 stream = thread.sendResumingCommand(sender);
178 } else {
179 stream = vm.sendResumingCommand(sender);
180 }
181 return stream;
182 }
183
184 PacketStream sendNewInstanceCommand(final ThreadReferenceImpl thread,
185 final MethodImpl method,
186 final ValueImpl[] args,
187 final int options) {
188 CommandSender sender =
189 new CommandSender() {
190 public PacketStream send() {
191 return JDWP.ClassType.NewInstance.enqueueCommand(
192 vm, ClassTypeImpl.this, thread,
193 method.ref(), args, options);
194 }
195 };
196
197 PacketStream stream;
198 if ((options & INVOKE_SINGLE_THREADED) != 0) {
199 stream = thread.sendResumingCommand(sender);
200 } else {
201 stream = vm.sendResumingCommand(sender);
202 }
203 return stream;
204 }
205
206 public Value invokeMethod(ThreadReference threadIntf, Method methodIntf,
207 List<? extends Value> origArguments, int options)
208 throws InvalidTypeException,
209 ClassNotLoadedException,
210 IncompatibleThreadStateException,
211 InvocationException {
212 validateMirror(threadIntf);
213 validateMirror(methodIntf);
214 validateMirrorsOrNulls(origArguments);
215
216 MethodImpl method = (MethodImpl)methodIntf;
217 ThreadReferenceImpl thread = (ThreadReferenceImpl)threadIntf;
218
219 validateMethodInvocation(method);
220
221 List<? extends Value> arguments = method.validateAndPrepareArgumentsForInvoke(origArguments);
222
223 ValueImpl[] args = arguments.toArray(new ValueImpl[0]);
224 JDWP.ClassType.InvokeMethod ret;
225 try {
226 PacketStream stream =
227 sendInvokeCommand(thread, method, args, options);
228 ret = JDWP.ClassType.InvokeMethod.waitForReply(vm, stream);
229 } catch (JDWPException exc) {
230 if (exc.errorCode() == JDWP.Error.INVALID_THREAD) {
231 throw new IncompatibleThreadStateException();
232 } else {
233 throw exc.toJDIException();
234 }
235 }
236
237 /*
238 * There is an implict VM-wide suspend at the conclusion
239 * of a normal (non-single-threaded) method invoke
240 */
241 if ((options & INVOKE_SINGLE_THREADED) == 0) {
242 vm.notifySuspend();
243 }
244
245 if (ret.exception != null) {
246 throw new InvocationException(ret.exception);
247 } else {
248 return ret.returnValue;
249 }
250 }
251
252 public ObjectReference newInstance(ThreadReference threadIntf,
253 Method methodIntf,
254 List<? extends Value> origArguments,
255 int options)
256 throws InvalidTypeException,
257 ClassNotLoadedException,
258 IncompatibleThreadStateException,
259 InvocationException {
260 validateMirror(threadIntf);
261 validateMirror(methodIntf);
262 validateMirrorsOrNulls(origArguments);
263
264 MethodImpl method = (MethodImpl)methodIntf;
265 ThreadReferenceImpl thread = (ThreadReferenceImpl)threadIntf;
266
267 validateConstructorInvocation(method);
268
269 List<Value> arguments = method.validateAndPrepareArgumentsForInvoke(
270 origArguments);
271 ValueImpl[] args = arguments.toArray(new ValueImpl[0]);
272 JDWP.ClassType.NewInstance ret = null;
273 try {
274 PacketStream stream =
275 sendNewInstanceCommand(thread, method, args, options);
276 ret = JDWP.ClassType.NewInstance.waitForReply(vm, stream);
277 } catch (JDWPException exc) {
278 if (exc.errorCode() == JDWP.Error.INVALID_THREAD) {
279 throw new IncompatibleThreadStateException();
280 } else {
281 throw exc.toJDIException();
282 }
283 }
284
285 /*
286 * There is an implict VM-wide suspend at the conclusion
287 * of a normal (non-single-threaded) method invoke
288 */
289 if ((options & INVOKE_SINGLE_THREADED) == 0) {
290 vm.notifySuspend();
291 }
292
293 if (ret.exception != null) {
294 throw new InvocationException(ret.exception);
295 } else {
296 return ret.newObject;
297 }
298 }
299
300 public Method concreteMethodByName(String name, String signature) {
301 Method method = null;
302 for (Method candidate : visibleMethods()) {
303 if (candidate.name().equals(name) &&
304 candidate.signature().equals(signature) &&
305 !candidate.isAbstract()) {
306
307 method = candidate;
308 break;
309 }
310 }
311 return method;
312 }
313
314 public List<Method> allMethods() {
315 ArrayList<Method> list = new ArrayList<Method>(methods());
316
317 ClassType clazz = superclass();
318 while (clazz != null) {
319 list.addAll(clazz.methods());
320 clazz = clazz.superclass();
321 }
322
323 /*
324 * Avoid duplicate checking on each method by iterating through
325 * duplicate-free allInterfaces() rather than recursing
326 */
327 for (InterfaceType interfaze : allInterfaces()) {
328 list.addAll(interfaze.methods());
329 }
330
331 return list;
332 }
333
334 List<ReferenceType> inheritedTypes() {
335 List<ReferenceType> inherited = new ArrayList<ReferenceType>();
336 if (superclass() != null) {
337 inherited.add(0, (ReferenceType)superclass()); /* insert at front */
338 }
339 for (ReferenceType rt : interfaces()) {
340 inherited.add(rt);
341 }
342 return inherited;
343 }
344
345 void validateMethodInvocation(Method method)
346 throws InvalidTypeException,
347 InvocationException {
348 /*
349 * Method must be in this class or a superclass.
350 */
351 ReferenceTypeImpl declType = (ReferenceTypeImpl)method.declaringType();
352 if (!declType.isAssignableFrom(this)) {
353 throw new IllegalArgumentException("Invalid method");
354 }
355
356 /*
357 * Method must be a static and not a static initializer
358 */
359 if (!method.isStatic()) {
360 throw new IllegalArgumentException("Cannot invoke instance method on a class type");
361 } else if (method.isStaticInitializer()) {
362 throw new IllegalArgumentException("Cannot invoke static initializer");
363 }
364 }
365
366 void validateConstructorInvocation(Method method)
367 throws InvalidTypeException,
368 InvocationException {
369 /*
370 * Method must be in this class.
371 */
372 ReferenceTypeImpl declType = (ReferenceTypeImpl)method.declaringType();
373 if (!declType.equals(this)) {
374 throw new IllegalArgumentException("Invalid constructor");
375 }
376
377 /*
378 * Method must be a constructor
379 */
380 if (!method.isConstructor()) {
381 throw new IllegalArgumentException("Cannot create instance with non-constructor");
382 }
383 }
384
385 void addVisibleMethods(Map<String, Method> methodMap) {
386 /*
387 * Add methods from
388 * parent types first, so that the methods in this class will
389 * overwrite them in the hash table
390 */
391
392 Iterator iter = interfaces().iterator();
393 while (iter.hasNext()) {
394 InterfaceTypeImpl interfaze = (InterfaceTypeImpl)iter.next();
395 interfaze.addVisibleMethods(methodMap);
396 }
397
398 ClassTypeImpl clazz = (ClassTypeImpl)superclass();
399 if (clazz != null) {
400 clazz.addVisibleMethods(methodMap);
401 }
402
403 addToMethodMap(methodMap, methods());
404 }
405
406 boolean isAssignableTo(ReferenceType type) {
407 ClassTypeImpl superclazz = (ClassTypeImpl)superclass();
408 if (this.equals(type)) {
409 return true;
410 } else if ((superclazz != null) && superclazz.isAssignableTo(type)) {
411 return true;
412 } else {
413 List<InterfaceType> interfaces = interfaces();
414 Iterator iter = interfaces.iterator();
415 while (iter.hasNext()) {
416 InterfaceTypeImpl interfaze = (InterfaceTypeImpl)iter.next();
417 if (interfaze.isAssignableTo(type)) {
418 return true;
419 }
420 }
421 return false;
422 }
423 }
424
425 public String toString() {
426 return "class " + name() + " (" + loaderString() + ")";
427 }
428}