KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdi > internal > ReferenceTypeImpl


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  * Yavor Boyadzhiev <yavor.vasilev.boyadzhiev@sap.com> - Bug 162399
11  *******************************************************************************/

12 package org.eclipse.jdi.internal;
13
14
15 import java.io.ByteArrayOutputStream JavaDoc;
16 import java.io.DataInputStream JavaDoc;
17 import java.io.DataOutputStream JavaDoc;
18 import java.io.IOException JavaDoc;
19 import java.lang.reflect.Modifier JavaDoc;
20 import java.util.ArrayList JavaDoc;
21 import java.util.Collections JavaDoc;
22 import java.util.HashMap JavaDoc;
23 import java.util.HashSet JavaDoc;
24 import java.util.Hashtable JavaDoc;
25 import java.util.Iterator JavaDoc;
26 import java.util.List JavaDoc;
27 import java.util.Map JavaDoc;
28 import java.util.Set JavaDoc;
29
30 import org.eclipse.jdi.internal.jdwp.JdwpCommandPacket;
31 import org.eclipse.jdi.internal.jdwp.JdwpFieldID;
32 import org.eclipse.jdi.internal.jdwp.JdwpID;
33 import org.eclipse.jdi.internal.jdwp.JdwpMethodID;
34 import org.eclipse.jdi.internal.jdwp.JdwpReferenceTypeID;
35 import org.eclipse.jdi.internal.jdwp.JdwpReplyPacket;
36
37 import com.ibm.icu.text.MessageFormat;
38 import com.sun.jdi.AbsentInformationException;
39 import com.sun.jdi.ClassLoaderReference;
40 import com.sun.jdi.ClassNotLoadedException;
41 import com.sun.jdi.ClassNotPreparedException;
42 import com.sun.jdi.ClassObjectReference;
43 import com.sun.jdi.ClassType;
44 import com.sun.jdi.Field;
45 import com.sun.jdi.InternalException;
46 import com.sun.jdi.NativeMethodException;
47 import com.sun.jdi.ObjectCollectedException;
48 import com.sun.jdi.ReferenceType;
49 import com.sun.jdi.VMDisconnectedException;
50 import com.sun.jdi.Value;
51
52 /**
53  * this class implements the corresponding interfaces
54  * declared by the JDI specification. See the com.sun.jdi package
55  * for more information.
56  *
57  */

58 public abstract class ReferenceTypeImpl extends TypeImpl implements ReferenceType, org.eclipse.jdi.hcr.ReferenceType {
59
60     /** ClassStatus Constants. */
61     public static final int JDWP_CLASS_STATUS_VERIFIED = 1;
62     public static final int JDWP_CLASS_STATUS_PREPARED = 2;
63     public static final int JDWP_CLASS_STATUS_INITIALIZED = 4;
64     public static final int JDWP_CLASS_STATUS_ERROR = 8;
65
66     /** Mapping of command codes to strings. */
67     private static String JavaDoc[] fgClassStatusStrings = null;
68
69     /**
70      * Represent the data about one file info contained in one stratum in the SMAP.
71      */

72     protected static class FileInfo {
73         
74         /**
75          * The id.
76          */

77         protected int fFileId;
78
79         /**
80          * The name of the source file.
81          */

82         protected String JavaDoc fFileName;
83
84         /**
85          * The path of the source file.
86          */

87         protected String JavaDoc fAbsoluteFileName;
88         
89         /**
90          * Map line number in the input source file
91          * -> list of [start line in the output source file, range in the output source file].
92          * (Integer -> List of int[2]).
93          */

94         private HashMap JavaDoc fLineInfo;
95
96         /**
97          * FileInfo constructor.
98          *
99          * @param fileId the id.
100          * @param fileName the name of the source file.
101          * @param absoluteFileName the path of the source file (can be <code>null</code>).
102          */

103         public FileInfo(int fileId, String JavaDoc fileName, String JavaDoc absoluteFileName) {
104             fFileId= fileId;
105             fFileName= fileName;
106             fAbsoluteFileName= absoluteFileName;
107             fLineInfo= new HashMap JavaDoc();
108         }
109         
110         /**
111          * Add information about the mapping of one line.
112          * Associate a line in the input source file to a snippet of code
113          * in the output source file.
114          *
115          * @param inputLine the line number in the input source file.
116          * @param outputStartLine the number of the first line of the corresponding snippet in the output source file.
117          * @param outputLineRange the size of the corresponding snippet in the output source file.
118          */

119         public void addLineInfo(int inputLine, int outputStartLine, int outputLineRange) {
120             Integer JavaDoc key= new Integer JavaDoc(inputLine);
121             List JavaDoc outputLines= (List JavaDoc)fLineInfo.get(key);
122             if (outputLines == null) {
123                 outputLines= new ArrayList JavaDoc();
124                 fLineInfo.put(key, outputLines);
125             }
126             outputLines.add(new int[] {outputStartLine, outputLineRange});
127         }
128
129         /**
130          * Return a list of line information about the code in the output source file
131          * associated to the given line in the input source file.
132          *
133          * @param lineNumber the line number in the input source file.
134          * @return a List of int[2].
135          */

136         public List JavaDoc getOutputLinesForLine(int lineNumber) {
137             List JavaDoc list= new ArrayList JavaDoc();
138             List JavaDoc outputLines= (List JavaDoc)fLineInfo.get(new Integer JavaDoc(lineNumber));
139             if (outputLines != null) {
140                 for (Iterator JavaDoc iter = outputLines.iterator(); iter.hasNext();) {
141                     int[] info = (int[])iter.next();
142                     int outputLineNumber= info[0];
143                     int length = info[1];
144                     if (length == 0){
145                         length = length + 1;
146                     }
147                     for (int i= 0; i < length; i++) {
148                         list.add(new Integer JavaDoc(outputLineNumber++));
149                     }
150                 }
151             }
152             return list;
153         }
154
155         /**
156          * @see java.lang.Object#equals(java.lang.Object)
157          */

158         public boolean equals(Object JavaDoc object) {
159             if (!(object instanceof FileInfo)) {
160                 return false;
161             }
162             return fFileId == ((FileInfo)object).fFileId;
163         }
164
165     }
166     
167     /**
168      * Represent the information contained in the SMAP about one stratum.
169      */

170     protected static class Stratum {
171
172         /**
173          * The id of this stratum.
174          */

175         private String JavaDoc fId;
176         
177         /**
178          * The file info data associated to this stratum.
179          */

180         private List JavaDoc fFileInfos;
181     
182         /**
183          * Id of the primary file for this stratum.
184          */

185         private int fPrimaryFileId;
186         
187         /**
188          * Map line number in the output source file -> list of line numbers in the input source file.
189          * (Integer -> List of Integer)
190          */

191         private HashMap JavaDoc fOutputLineToInputLine;
192         
193         /**
194          * Stratum constructor.
195          * @param id The id of this stratum.
196          */

197         public Stratum(String JavaDoc id) {
198             fId= id;
199             fFileInfos= new ArrayList JavaDoc();
200             fOutputLineToInputLine= new HashMap JavaDoc();
201             fPrimaryFileId= -1;
202         }
203         
204         /**
205          * Add a file info to this stratum.
206          *
207          * @param fileId the id.
208          * @param fileName the name of the source file.
209          */

210         public void addFileInfo(int fileId, String JavaDoc fileName) throws AbsentInformationException {
211             addFileInfo(fileId, fileName, null);
212         }
213         
214         /**
215          * Add a file info to this stratum.
216          *
217          * @param fileId the id.
218          * @param fileName the name of the source file.
219          * @param absoluteFileName the path of the source file.
220          */

221         public void addFileInfo(int fileId, String JavaDoc fileName, String JavaDoc absoluteFileName) throws AbsentInformationException {
222             if (fPrimaryFileId == -1) {
223                 fPrimaryFileId= fileId;
224             }
225             FileInfo fileInfo= new FileInfo(fileId, fileName, absoluteFileName);
226             if (fFileInfos.contains(fileInfo)) {
227                 throw new AbsentInformationException(MessageFormat.format(JDIMessages.ReferenceTypeImpl_28, new String JavaDoc[] {Integer.toString(fileId), fId}));
228             }
229             fFileInfos.add(fileInfo);
230         }
231
232         /**
233          * Add line mapping information.
234          *
235          * @param inputStartLine number of the first line in the input source file.
236          * @param lineFileId id of the input source file.
237          * @param repeatCount number of iterations.
238          * @param outputStartLine number of the first line in the output source file.
239          * @param outputLineIncrement number of line to increment at each iteration.
240          * @throws AbsentInformationException
241          */

242         public void addLineInfo(int inputStartLine, int lineFileId, int repeatCount, int outputStartLine, int outputLineIncrement) throws AbsentInformationException {
243             FileInfo fileInfo= null;
244             // get the FileInfo object
245
for (Iterator JavaDoc iter = fFileInfos.iterator(); iter.hasNext();) {
246                 FileInfo element = (FileInfo)iter.next();
247                 if (element.fFileId == lineFileId) {
248                     fileInfo= element;
249                 }
250             }
251             if (fileInfo == null) {
252                 throw new AbsentInformationException(MessageFormat.format(JDIMessages.ReferenceTypeImpl_29, new String JavaDoc[] {Integer.toString(lineFileId)}));
253             }
254             // add the data to the different hash maps.
255
for (int i= 0; i < repeatCount; i++, inputStartLine++) {
256                 fileInfo.addLineInfo(inputStartLine, outputStartLine, outputLineIncrement);
257                 if (outputLineIncrement == 0) {
258                     // see bug 40022
259
addLineInfoToMap(inputStartLine, lineFileId, outputStartLine);
260                 } else {
261                     for (int j= 0; j < outputLineIncrement; j++, outputStartLine++) {
262                         addLineInfoToMap(inputStartLine, lineFileId, outputStartLine);
263                     }
264                 }
265             }
266         }
267
268         /**
269          * Add the data to the map.
270          */

271         private void addLineInfoToMap(int inputStartLine, int lineFileId, int outputStartLine) {
272             Integer JavaDoc key= new Integer JavaDoc(outputStartLine);
273             List JavaDoc inputLines= (List JavaDoc)fOutputLineToInputLine.get(key);
274             if (inputLines == null) {
275                 inputLines= new ArrayList JavaDoc();
276                 fOutputLineToInputLine.put(key, inputLines);
277             }
278             inputLines.add(new int[] {lineFileId, inputStartLine});
279         }
280
281         /**
282          * Return the FileInfo object for the specified source name.
283          * Return <code>null</code> if the specified name is the source name of no file info.
284          * @param sourceName the source name to search.
285          */

286         public FileInfo getFileInfo(String JavaDoc sourceName) {
287             for (Iterator JavaDoc iter = fFileInfos.iterator(); iter.hasNext();) {
288                 FileInfo fileInfo = (FileInfo)iter.next();
289                 if (fileInfo.fFileName.equals(sourceName)) {
290                     return fileInfo;
291                 }
292             }
293             return null;
294         }
295
296         /**
297          * @param outputLineNumber
298          * @return
299          */

300         public List JavaDoc getInputLineInfos(int outputLineNumber) {
301             return (List JavaDoc)fOutputLineToInputLine.get(new Integer JavaDoc(outputLineNumber));
302         }
303
304     }
305     
306
307
308     /** ReferenceTypeID that corresponds to this reference. */
309     private JdwpReferenceTypeID fReferenceTypeID;
310
311     /** The following are the stored results of JDWP calls. */
312     protected List JavaDoc fInterfaces = null;
313     private List JavaDoc fMethods = null;
314     private Hashtable JavaDoc fMethodTable= null;
315     private List JavaDoc fFields = null;
316     private List JavaDoc fAllMethods = null;
317     private List JavaDoc fVisibleMethods = null;
318     private List JavaDoc fAllFields = null;
319     private List JavaDoc fVisibleFields = null;
320     private List JavaDoc fAllInterfaces = null;
321     private Map JavaDoc fStratumAllLineLocations = null;
322     private String JavaDoc fSourceName = null;
323     private int fModifierBits = -1;
324     private ClassLoaderReferenceImpl fClassLoader = null;
325     private ClassObjectReferenceImpl fClassObject = null;
326     
327     private String JavaDoc fGenericSignature; // 1.5 addition
328
private boolean fGenericSignatureKnown; // 1.5 addition
329

330     private boolean fGotClassFileVersion = false; // HCR addition.
331
private int fClassFileVersion; // HCR addition.
332
private boolean fIsHCREligible; // HCR addition.
333
private boolean fIsVersionKnown; // HCR addition.
334

335     private boolean fSourceDebugExtensionAvailable= true; // JSR-045 addition
336

337     /**
338      * The default stratum id.
339      */

340     private String JavaDoc fDefaultStratumId; // JSR-045 addition
341

342     /**
343      * A map of the defined strata.
344      * Map stratum id -> Stratum object.
345      * (String -> Stratum).
346      */

347     private Map JavaDoc fStrata; // JSR-045 addition
348

349     /**
350      * The source map string returned by the VM.
351      */

352     private String JavaDoc fSmap; // JSR-045 addition
353

354     /**
355      * Creates new instance.
356      */

357     protected ReferenceTypeImpl(String JavaDoc description, VirtualMachineImpl vmImpl, JdwpReferenceTypeID referenceTypeID) {
358         super(description, vmImpl);
359         fReferenceTypeID = referenceTypeID;
360     }
361     
362     /**
363      * Creates new instance.
364      */

365     protected ReferenceTypeImpl(String JavaDoc description, VirtualMachineImpl vmImpl, JdwpReferenceTypeID referenceTypeID, String JavaDoc signature, String JavaDoc genericSignature) {
366         super(description, vmImpl);
367         fReferenceTypeID = referenceTypeID;
368         setSignature(signature);
369         setGenericSignature(genericSignature);
370     }
371     
372     /**
373      * @return Returns type tag.
374      */

375     public abstract byte typeTag();
376     
377     /**
378      * Flushes all stored Jdwp results.
379      */

380     public void flushStoredJdwpResults() {
381         Iterator JavaDoc iter;
382     
383         // Flush Methods.
384
if (fMethods != null) {
385             iter = fMethods.iterator();
386             while (iter.hasNext()) {
387                 MethodImpl method = (MethodImpl)iter.next();
388                 method.flushStoredJdwpResults();
389             }
390             fMethods = null;
391             fMethodTable= null;
392         }
393
394         // Flush Fields.
395
if (fFields != null) {
396             iter = fFields.iterator();
397             while (iter.hasNext()) {
398                 FieldImpl field = (FieldImpl)iter.next();
399                 field.flushStoredJdwpResults();
400             }
401             fFields = null;
402         }
403
404         fInterfaces = null;
405         fAllMethods = null;
406         fVisibleMethods = null;
407         fAllFields = null;
408         fVisibleFields = null;
409         fAllInterfaces = null;
410         fStratumAllLineLocations = null;
411         fSourceName = null;
412         fModifierBits = -1;
413         fClassLoader = null;
414         fClassObject = null;
415         fGotClassFileVersion = false;
416         // java 1.5
417
fGenericSignature= null;
418         fGenericSignatureKnown= false;
419         
420         // JSR-045
421
fSourceDebugExtensionAvailable= true;
422         fDefaultStratumId= null;
423         fStrata= null;
424         fSmap= null;
425         
426         // The following cached results are stored higher up in the class hierarchy.
427
fSignature = null;
428         fSourceName = null;
429     }
430     
431     /**
432      * @return Returns the interfaces declared as implemented by this class. Interfaces indirectly implemented (extended by the implemented interface or implemented by a superclass) are not included.
433      */

434     public List JavaDoc allInterfaces() {
435         if (fAllInterfaces != null) {
436             return fAllInterfaces;
437         }
438     
439         /* Recursion:
440          * The interfaces that it directly implements;
441          * All interfaces that are implemented by its interfaces;
442          * If it is a class, all interfaces that are implemented by its superclass.
443          */

444         // The interfaces are maintained in a set, to avoid duplicates.
445
// The interfaces of its own (own interfaces() command) are first inserted.
446
HashSet JavaDoc allInterfacesSet = new HashSet JavaDoc(interfaces());
447         
448         // All interfaces of the interfaces it implements.
449
Iterator JavaDoc interfaces = interfaces().iterator();
450         InterfaceTypeImpl inter;
451         while (interfaces.hasNext()) {
452             inter = (InterfaceTypeImpl)interfaces.next();
453             allInterfacesSet.addAll(inter.allInterfaces());
454         }
455         
456         // If it is a class, all interfaces of it's superclass.
457
if (this instanceof ClassType) {
458             ClassType superclass = ((ClassType)this).superclass();
459             if (superclass != null) {
460                 allInterfacesSet.addAll(superclass.allInterfaces());
461             }
462         }
463                 
464         fAllInterfaces = new ArrayList JavaDoc(allInterfacesSet);
465         return fAllInterfaces;
466     }
467     
468     /**
469      * @return Returns Jdwp Reference ID.
470      */

471     public JdwpReferenceTypeID getRefTypeID() {
472         return fReferenceTypeID;
473     }
474     
475     /**
476      * @return Returns modifier bits.
477      */

478     public int modifiers() {
479         if (fModifierBits != -1)
480             return fModifierBits;
481             
482         initJdwpRequest();
483         try {
484             JdwpReplyPacket replyPacket = requestVM(JdwpCommandPacket.RT_MODIFIERS, this);
485             defaultReplyErrorHandler(replyPacket.errorCode());
486             DataInputStream JavaDoc replyData = replyPacket.dataInStream();
487             fModifierBits = readInt("modifiers", AccessibleImpl.getModifierStrings(), replyData); //$NON-NLS-1$
488
return fModifierBits;
489         } catch (IOException JavaDoc e) {
490             defaultIOExceptionHandler(e);
491             return 0;
492         } finally {
493             handledJdwpRequest();
494         }
495     }
496     
497     /**
498      * Add methods to a set of methods if they are not overridden, add new names+signature combinations to set of names+signature combinations.
499      */

500     private void addVisibleMethods(List JavaDoc inheritedMethods, Set JavaDoc nameAndSignatures, List JavaDoc resultMethods) {
501         Iterator JavaDoc iter = inheritedMethods.iterator();
502         MethodImpl inheritedMethod;
503         while (iter.hasNext()) {
504             inheritedMethod = (MethodImpl)iter.next();
505             if (!nameAndSignatures.contains(inheritedMethod.name() + inheritedMethod.signature())) {
506                 resultMethods.add(inheritedMethod);
507             }
508         }
509     }
510     
511     /**
512      * @return Returns a list containing each visible and unambiguous Method in this type.
513      */

514     public List JavaDoc visibleMethods() {
515         if (fVisibleMethods != null)
516             return fVisibleMethods;
517
518         /* Recursion:
519          * The methods of its own (own methods() command);
520          * All methods of the interfaces it implements;
521          * If it is a class, all methods of it's superclass.
522          */

523         // The name+signature combinations of methods are maintained in a set, to avoid including methods that have been overridden.
524
Set JavaDoc namesAndSignatures = new HashSet JavaDoc();
525         List JavaDoc visibleMethods= new ArrayList JavaDoc();
526         
527         // The methods of its own (own methods() command).
528
for (Iterator JavaDoc iter= methods().iterator(); iter.hasNext();) {
529             MethodImpl method= (MethodImpl) iter.next();
530             namesAndSignatures.add(method.name() + method.signature());
531             visibleMethods.add(method);
532         }
533
534         // All methods of the interfaces it implements.
535
Iterator JavaDoc interfaces = interfaces().iterator();
536         InterfaceTypeImpl inter;
537         while (interfaces.hasNext()) {
538             inter = (InterfaceTypeImpl)interfaces.next();
539             addVisibleMethods(inter.visibleMethods(), namesAndSignatures, visibleMethods);
540         }
541         
542         // If it is a class, all methods of it's superclass.
543
if (this instanceof ClassType) {
544             ClassType superclass = ((ClassType)this).superclass();
545             if (superclass != null)
546                 addVisibleMethods(superclass.visibleMethods(), namesAndSignatures, visibleMethods);
547         }
548         
549         fVisibleMethods= visibleMethods;
550         return fVisibleMethods;
551     }
552
553     /**
554      * @return Returns a list containing each Method declared in this type, and its super-classes, implemented interfaces, and/or super-interfaces.
555      */

556     public List JavaDoc allMethods() {
557         if (fAllMethods != null)
558             return fAllMethods;
559
560         /* Recursion:
561          * The methods of its own (own methods() command);
562          * All methods of the interfaces it implements;
563          * If it is a class, all methods of it's superclass.
564          */

565         // The name+signature combinations of methods are maintained in a set.
566
HashSet JavaDoc resultSet = new HashSet JavaDoc();
567         
568         // The methods of its own (own methods() command).
569
resultSet.addAll(methods());
570         
571         // All methods of the interfaces it implements.
572
Iterator JavaDoc interfaces = interfaces().iterator();
573         InterfaceTypeImpl inter;
574         while (interfaces.hasNext()) {
575             inter = (InterfaceTypeImpl)interfaces.next();
576             resultSet.addAll(inter.allMethods());
577         }
578         
579         // If it is a class, all methods of it's superclass.
580
if (this instanceof ClassType) {
581             ClassType superclass = ((ClassType)this).superclass();
582             if (superclass != null)
583                 resultSet.addAll(superclass.allMethods());
584         }
585         
586         fAllMethods = new ArrayList JavaDoc(resultSet);
587         return fAllMethods;
588     }
589
590     /**
591      * @return Returns the interfaces declared as implemented by this class. Interfaces indirectly implemented (extended by the implemented interface or implemented by a superclass) are not included.
592      */

593     public List JavaDoc interfaces() {
594         if (fInterfaces != null) {
595             return fInterfaces;
596         }
597             
598         initJdwpRequest();
599         try {
600             JdwpReplyPacket replyPacket = requestVM(JdwpCommandPacket.RT_INTERFACES, this);
601             switch (replyPacket.errorCode()) {
602                 case JdwpReplyPacket.NOT_FOUND:
603                     // Workaround for problem in J2ME WTK (wireless toolkit)
604
// @see Bug 12966
605
return Collections.EMPTY_LIST;
606                 default:
607                     defaultReplyErrorHandler(replyPacket.errorCode());
608             }
609             DataInputStream JavaDoc replyData = replyPacket.dataInStream();
610             List JavaDoc elements = new ArrayList JavaDoc();
611             int nrOfElements = readInt("elements", replyData); //$NON-NLS-1$
612
for (int i = 0; i < nrOfElements; i++) {
613                 InterfaceTypeImpl ref = InterfaceTypeImpl.read(this, replyData);
614                 if (ref == null) {
615                     continue;
616                 }
617                 elements.add(ref);
618             }
619             fInterfaces = elements;
620             return elements;
621         } catch (IOException JavaDoc e) {
622             defaultIOExceptionHandler(e);
623             return null;
624         } finally {
625             handledJdwpRequest();
626         }
627     }
628             
629     /**
630      * Add fields to a set of fields if they are not overridden, add new field names to set of field names.
631      */

632     private void addVisibleFields(List JavaDoc newFields, Set JavaDoc names, List JavaDoc resultFields) {
633         Iterator JavaDoc iter = newFields.iterator();
634         FieldImpl field;
635         while (iter.hasNext()) {
636             field = (FieldImpl)iter.next();
637             String JavaDoc name = field.name();
638             if (!names.contains(name)) {
639                 resultFields.add(field);
640                 names.add(name);
641             }
642         }
643     }
644     
645     /**
646      * @return Returns a list containing each visible and unambiguous Field in this type.
647      */

648     public List JavaDoc visibleFields() {
649         if (fVisibleFields != null)
650             return fVisibleFields;
651
652         /* Recursion:
653          * The fields of its own (own fields() command);
654          * All fields of the interfaces it implements;
655          * If it is a class, all fields of it's superclass.
656          */

657         // The names of fields are maintained in a set, to avoid including fields that have been overridden.
658
HashSet JavaDoc fieldNames = new HashSet JavaDoc();
659         
660         // The fields of its own (own fields() command).
661
List JavaDoc visibleFields = new ArrayList JavaDoc();
662         addVisibleFields(fields(), fieldNames, visibleFields);
663         
664         // All fields of the interfaces it implements.
665
Iterator JavaDoc interfaces = interfaces().iterator();
666         InterfaceTypeImpl inter;
667         while (interfaces.hasNext()) {
668             inter = (InterfaceTypeImpl)interfaces.next();
669             addVisibleFields(inter.visibleFields(), fieldNames, visibleFields);
670         }
671         
672         // If it is a class, all fields of it's superclass.
673
if (this instanceof ClassType) {
674             ClassType superclass = ((ClassType)this).superclass();
675             if (superclass != null)
676                 addVisibleFields(superclass.visibleFields(), fieldNames, visibleFields);
677         }
678                 
679         fVisibleFields = visibleFields;
680         return fVisibleFields;
681     }
682
683     /**
684      * @return Returns a list containing each Field declared in this type, and its super-classes, implemented interfaces, and/or super-interfaces.
685      */

686     public List JavaDoc allFields() {
687         if (fAllFields != null)
688             return fAllFields;
689
690         /* Recursion:
691          * The fields of its own (own fields() command);
692          * All fields of the interfaces it implements;
693          * If it is a class, all fields of it's superclass.
694          */

695         // The names of fields are maintained in a set, to avoid including fields that have been inherited double.
696
HashSet JavaDoc resultSet = new HashSet JavaDoc();
697         
698         // The fields of its own (own fields() command).
699
resultSet.addAll(fields());
700         
701         // All fields of the interfaces it implements.
702
Iterator JavaDoc interfaces = interfaces().iterator();
703         InterfaceTypeImpl inter;
704         while (interfaces.hasNext()) {
705             inter = (InterfaceTypeImpl)interfaces.next();
706             resultSet.addAll(inter.allFields());
707         }
708         
709         // If it is a class, all fields of it's superclass.
710
if (this instanceof ClassType) {
711             ClassType superclass = ((ClassType)this).superclass();
712             if (superclass != null)
713                 resultSet.addAll(superclass.allFields());
714         }
715                 
716         fAllFields = new ArrayList JavaDoc(resultSet);
717         return fAllFields;
718     }
719     
720     /**
721      * @return Returns the class loader object which loaded the class corresponding to this type.
722      */

723     public ClassLoaderReference classLoader() {
724         if (fClassLoader != null)
725             return fClassLoader;
726
727         initJdwpRequest();
728         try {
729             JdwpReplyPacket replyPacket = requestVM(JdwpCommandPacket.RT_CLASS_LOADER, this);
730             defaultReplyErrorHandler(replyPacket.errorCode());
731             DataInputStream JavaDoc replyData = replyPacket.dataInStream();
732             fClassLoader = ClassLoaderReferenceImpl.read(this, replyData);
733             return fClassLoader;
734         } catch (IOException JavaDoc e) {
735             defaultIOExceptionHandler(e);
736             return null;
737         } finally {
738             handledJdwpRequest();
739         }
740     }
741         
742     /**
743      * @return Returns the class object that corresponds to this type in the target VM.
744      */

745     public ClassObjectReference classObject() {
746         if (fClassObject != null)
747             return fClassObject;
748
749         initJdwpRequest();
750   &n