KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*******************************************************************************
2  * Copyright (c) 2000, 2006 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  * Tim Tromey - update method signature syntax (bug 31507)
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.Field JavaDoc;
20 import java.lang.reflect.Modifier JavaDoc;
21 import java.util.ArrayList JavaDoc;
22 import java.util.Arrays JavaDoc;
23 import java.util.Collections JavaDoc;
24 import java.util.HashMap 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 import java.util.TreeSet JavaDoc;
30
31 import org.eclipse.jdi.internal.jdwp.JdwpCommandPacket;
32 import org.eclipse.jdi.internal.jdwp.JdwpMethodID;
33 import org.eclipse.jdi.internal.jdwp.JdwpReplyPacket;
34
35 import com.ibm.icu.text.MessageFormat;
36 import com.sun.jdi.AbsentInformationException;
37 import com.sun.jdi.ClassLoaderReference;
38 import com.sun.jdi.ClassNotLoadedException;
39 import com.sun.jdi.Locatable;
40 import com.sun.jdi.Location;
41 import com.sun.jdi.Method;
42 import com.sun.jdi.Type;
43
44
45 /**
46  * Implementation of com.sun.jdi.Method.
47  */

48 public class MethodImpl extends TypeComponentImpl implements Method, Locatable {
49     /** InvokeOptions Constants. */
50     public static final int INVOKE_SINGLE_THREADED_JDWP = 0x01;
51     public static final int INVOKE_NONVIRTUAL_JDWP = 0x02;
52     
53     /** Map with Strings for flag bits. */
54     private static String JavaDoc[] fgInvokeOptions = null;
55     
56     /** MethodTypeID that corresponds to this reference. */
57     private JdwpMethodID fMethodID;
58     
59     /** The following are the stored results of JDWP calls. */
60     private List JavaDoc fVariables = null;
61     private long fLowestValidCodeIndex = -1;
62     private long fHighestValidCodeIndex = -1;
63     private Map JavaDoc fCodeIndexToLine = null;
64     private Map JavaDoc fLineToCodeIndexes = null;
65     private Map JavaDoc fStratumAllLineLocations = null;
66     private int fArgumentSlotsCount = -1;
67     private List JavaDoc fArguments = null;
68     private List JavaDoc fArgumentTypes = null;
69     private List JavaDoc fArgumentTypeNames = null;
70     private List JavaDoc fArgumentTypeSignatures = null;
71     private byte[] fByteCodes = null;
72     private long[] fCodeIndexTable;
73     private int[] fJavaStratumLineNumberTable;
74     
75     private String JavaDoc fReturnTypeName= null;
76     
77     /**
78      * Creates new MethodImpl.
79      */

80     public MethodImpl(VirtualMachineImpl vmImpl, ReferenceTypeImpl declaringType, JdwpMethodID methodID, String JavaDoc name, String JavaDoc signature, String JavaDoc genericSignature, int modifierBits) {
81         super("Method", vmImpl, declaringType, name, signature, genericSignature, modifierBits); //$NON-NLS-1$
82
fMethodID = methodID;
83     }
84
85     /**
86      * Flushes all stored Jdwp results.
87      */

88     protected void flushStoredJdwpResults() {
89         fVariables = null;
90         fLowestValidCodeIndex = -1;
91         fHighestValidCodeIndex = -1;
92         fCodeIndexToLine = null;
93         fLineToCodeIndexes = null;
94         fStratumAllLineLocations = null;
95         fCodeIndexTable= null;
96         fJavaStratumLineNumberTable= null;
97         fArgumentSlotsCount = -1;
98         fArguments = null;
99         fArgumentTypes = null;
100         fArgumentTypeNames = null;
101         fArgumentTypeSignatures = null;
102         fByteCodes = null;
103     }
104     
105     /**
106      * @return Returns methodID of method.
107      */

108     protected JdwpMethodID getMethodID() {
109         return fMethodID;
110     }
111     
112     /**
113      * @return Returns map of location to line number.
114      */

115     protected Map JavaDoc javaStratumCodeIndexToLine() throws AbsentInformationException {
116         if (isAbstract()) {
117             return Collections.EMPTY_MAP;
118         }
119         getLineTable();
120         return fCodeIndexToLine;
121     }
122     
123     /**
124      * @return Returns map of line number to locations.
125      */

126     protected List JavaDoc javaStratumLineToCodeIndexes(int line) throws AbsentInformationException {
127         if (isAbstract() || isNative()) {
128             return null;
129         }
130         getLineTable();
131         
132         return (List JavaDoc)fLineToCodeIndexes.get(new Integer JavaDoc(line));
133     }
134     
135     /**
136      * Gets line table from VM.
137      */

138     private void getLineTable() throws AbsentInformationException {
139         if (isObsolete()) {
140             return;
141         }
142         if (fCodeIndexToLine != null) {
143             if (fCodeIndexToLine.isEmpty()) {
144                 throw new AbsentInformationException(JDIMessages.MethodImpl_Got_empty_line_number_table_for_this_method_1);
145             }
146             return;
147         }
148
149         initJdwpRequest();
150         try {
151             ByteArrayOutputStream JavaDoc outBytes = new ByteArrayOutputStream JavaDoc();
152             DataOutputStream JavaDoc outData = new DataOutputStream JavaDoc(outBytes);
153             writeWithReferenceType(this, outData);
154     
155             JdwpReplyPacket replyPacket = requestVM(JdwpCommandPacket.M_LINE_TABLE, outBytes);
156             switch (replyPacket.errorCode()) {
157                 case JdwpReplyPacket.ABSENT_INFORMATION:
158                     throw new AbsentInformationException(JDIMessages.MethodImpl_No_line_number_information_available_2);
159                 case JdwpReplyPacket.NATIVE_METHOD:
160                     throw new AbsentInformationException(JDIMessages.MethodImpl_No_line_number_information_available_2);
161             }
162             defaultReplyErrorHandler(replyPacket.errorCode());
163             
164             DataInputStream JavaDoc replyData = replyPacket.dataInStream();
165             fLowestValidCodeIndex = readLong("lowest index", replyData); //$NON-NLS-1$
166
fHighestValidCodeIndex = readLong("highest index", replyData); //$NON-NLS-1$
167
int nrOfElements = readInt("elements", replyData); //$NON-NLS-1$
168
fCodeIndexToLine = new HashMap JavaDoc();
169             fLineToCodeIndexes = new HashMap JavaDoc();
170             if (nrOfElements == 0) {
171                 throw new AbsentInformationException(JDIMessages.MethodImpl_Got_empty_line_number_table_for_this_method_3);
172             }
173             fCodeIndexTable= new long[nrOfElements];
174             fJavaStratumLineNumberTable= new int[nrOfElements];
175             for (int i = 0; i < nrOfElements; i++) {
176                 long lineCodeIndex = readLong("code index", replyData); //$NON-NLS-1$
177
Long JavaDoc lineCodeIndexLong = new Long JavaDoc(lineCodeIndex);
178                 int lineNr = readInt("line nr", replyData); //$NON-NLS-1$
179
Integer JavaDoc lineNrInt = new Integer JavaDoc(lineNr);
180                 
181                 // Add entry to code-index to line mapping.
182
fCodeIndexToLine.put(lineCodeIndexLong, lineNrInt);
183                 
184                 fCodeIndexTable[i]= lineCodeIndex;
185                 fJavaStratumLineNumberTable[i]= lineNr;
186                 
187                 List JavaDoc lineNrEntry = (List JavaDoc)fLineToCodeIndexes.get(lineNrInt);
188                 if (lineNrEntry == null) {
189                     lineNrEntry= new ArrayList JavaDoc();
190                     fLineToCodeIndexes.put(lineNrInt, lineNrEntry);
191                 }
192                 lineNrEntry.add(lineCodeIndexLong);
193             }
194         } catch (IOException JavaDoc e) {
195             fCodeIndexToLine = null;
196             fLineToCodeIndexes = null;
197             defaultIOExceptionHandler(e);
198         } finally {
199             handledJdwpRequest();
200         }
201     }
202     
203     /**
204      * @return Returns the line number that corresponds to the given lineCodeIndex.
205      */

206     protected int javaStratumLineNumber(long lineCodeIndex) throws AbsentInformationException {
207         if (isAbstract() || isNative() || isObsolete()) {
208             return -1;
209         }
210         getLineTable();
211         if (lineCodeIndex > fHighestValidCodeIndex) {
212             throw new AbsentInformationException(JDIMessages.MethodImpl_Invalid_code_index_of_a_location_given_4);
213         }
214
215         Long JavaDoc lineCodeIndexObj;
216         Integer JavaDoc lineNrObj;
217         long index= lineCodeIndex;
218         // Search for the line where this code index is located.
219
do {
220             lineCodeIndexObj = new Long JavaDoc(index);
221             lineNrObj = (Integer JavaDoc)javaStratumCodeIndexToLine().get(lineCodeIndexObj);
222         } while (lineNrObj == null && --index >= fLowestValidCodeIndex);
223         if (lineNrObj == null) {
224             if (lineCodeIndex >= fLowestValidCodeIndex) {
225                 index= lineCodeIndex;
226                 do {
227                     lineCodeIndexObj = new Long JavaDoc(index);
228                     lineNrObj = (Integer JavaDoc)javaStratumCodeIndexToLine().get(lineCodeIndexObj);
229                 } while (lineNrObj == null && ++index <= fHighestValidCodeIndex);
230                 if (lineNrObj != null) {
231                     return lineNrObj.intValue();
232                 }
233             }
234             throw new AbsentInformationException (JDIMessages.MethodImpl_Invalid_code_index_of_a_location_given_4);
235         }
236         return lineNrObj.intValue();
237     }
238
239     
240     /**
241      * @see com.sun.jdi.Method#allLineLocations()
242      */

243     public List JavaDoc allLineLocations() throws AbsentInformationException {
244         return allLineLocations(virtualMachine().getDefaultStratum(), null);
245     }
246     
247     /**
248      * @see com.sun.jdi.Method#arguments()
249      */

250     public List JavaDoc arguments() throws AbsentInformationException {
251         if (isNative() || isAbstract()) {
252             throw new AbsentInformationException(JDIMessages.MethodImpl_No_local_variable_information_available_9);
253         }
254         if (fArguments != null) {
255             return fArguments;
256         }
257         
258         List JavaDoc result = new ArrayList JavaDoc();
259         Iterator JavaDoc iter = variables().iterator();
260         while (iter.hasNext()) {
261             LocalVariableImpl var = (LocalVariableImpl)iter.next();
262             if (var.isArgument())
263                 result.add(var);
264         }
265         fArguments = result;
266         return fArguments;
267     }
268     
269     /**
270      * @return Returns a text representation of all declared argument types of this method.
271      */

272     public List JavaDoc argumentTypeNames() {
273         if (fArgumentTypeNames != null) {
274             return fArgumentTypeNames;
275         }
276         List JavaDoc argumentTypeSignatures= argumentTypeSignatures();
277         List JavaDoc result= new ArrayList JavaDoc();
278         for (Iterator JavaDoc iter= argumentTypeSignatures.iterator(); iter.hasNext();) {
279             result.add(TypeImpl.signatureToName((String JavaDoc) iter.next()));
280         }
281         
282         fArgumentTypeNames= result;
283         return fArgumentTypeNames;
284     }
285
286
287     /**
288      * @return Returns a signatures of all declared argument types of this method.
289      */

290     private List JavaDoc argumentTypeSignatures() {
291         if (fArgumentTypeSignatures != null) {
292             return fArgumentTypeSignatures;
293         }
294         
295         fArgumentTypeSignatures= GenericSignature.getParameterTypes(signature());
296         return fArgumentTypeSignatures;
297     }
298
299     /**
300      * @return Returns the list containing the type of each argument.
301      */

302     public List JavaDoc argumentTypes() throws ClassNotLoadedException {
303         if (fArgumentTypes != null) {
304             return fArgumentTypes;
305         }
306
307         List JavaDoc result = new ArrayList JavaDoc();
308         Iterator JavaDoc iter = argumentTypeSignatures().iterator();
309         ClassLoaderReference classLoaderRef= declaringType().classLoader();
310         VirtualMachineImpl vm= virtualMachineImpl();
311         while (iter.hasNext()) {
312             String JavaDoc argumentTypeSignature = (String JavaDoc)iter.next();
313             result.add(TypeImpl.create(vm, argumentTypeSignature, classLoaderRef));
314         }
315         fArgumentTypes = result;
316         return fArgumentTypes;
317     }
318
319     /**
320      * @return Returns an array containing the bytecodes for this method.
321      */

322     public byte[] bytecodes() {
323         if (fByteCodes != null) {
324             return fByteCodes;
325         }
326
327         initJdwpRequest();
328         try {
329             ByteArrayOutputStream JavaDoc outBytes = new ByteArrayOutputStream JavaDoc();
330             DataOutputStream JavaDoc outData = new DataOutputStream JavaDoc(outBytes);
331             writeWithReferenceType(this, outData);
332             
333             JdwpReplyPacket replyPacket = requestVM(JdwpCommandPacket.M_BYTECODES, outBytes);
334             defaultReplyErrorHandler(replyPacket.errorCode());
335             
336             DataInputStream JavaDoc replyData = replyPacket.dataInStream();
337             int length = readInt("length", replyData); //$NON-NLS-1$
338
fByteCodes = readByteArray(length, "bytecodes", replyData); //$NON-NLS-1$
339
return fByteCodes;
340         } catch (IOException JavaDoc e) {
341             fByteCodes = null;
342             defaultIOExceptionHandler(e);
343             return null;
344         } finally {
345             handledJdwpRequest();
346         }
347     }
348
349     /**
350      * @return Returns the hash code value.
351      */

352     public int hashCode() {
353         return fMethodID.hashCode();
354     }
355     
356     /**
357      * @return Returns true if two mirrors refer to the same entity in the target VM.
358      * @see java.lang.Object#equals(Object)
359      */

360     public boolean equals(Object JavaDoc object) {
361         return object != null
362             && object.getClass().equals(this.getClass())
363             && fMethodID.equals(((MethodImpl)object).fMethodID)
364             && referenceTypeImpl().equals(((MethodImpl)object).referenceTypeImpl());
365     }
366
367     /**
368      * @return Returns a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object.
369      */

370     public int compareTo(Object JavaDoc object) {
371         if (object == null || !object.getClass().equals(this.getClass()))
372             throw new ClassCastException JavaDoc(JDIMessages.MethodImpl_Can__t_compare_method_to_given_object_6);
373         
374         // See if declaring types are the same, if not return comparison between declaring types.
375
Method type2 = (Method)object;
376         if (!declaringType().equals(type2.declaringType()))
377             return declaringType().compareTo(type2.declaringType());
378         
379         // Return comparison of position within declaring type.
380
int index1 = declaringType().methods().indexOf(this);
381         int index2 = type2.declaringType().methods().indexOf(type2);
382         if (index1 < index2) {
383             return -1;
384         } else if (index1 > index2) {
385             return 1;
386         } else {
387             return 0;
388         }
389     }
390     
391     
392     /**
393      * @see com.sun.jdi.Method#isAbstract()
394      */

395     public boolean isAbstract() {
396         return (fModifierBits & MODIFIER_ACC_ABSTRACT) != 0;
397     }
398     
399     
400     /**
401      * @see com.sun.jdi.Method#isConstructor()
402      */

403     public boolean isConstructor() {
404         return name().equals("<init>"); //$NON-NLS-1$
405
}
406     
407     /**
408      * @see com.sun.jdi.Method#isNative()
409      */

410     public boolean isNative() {
411         return (fModifierBits & MODIFIER_ACC_NATIVE) != 0;
412     }
413         
414     /**
415      * @see com.sun.jdi.Method#isStaticInitializer()
416      */

417     public boolean isStaticInitializer() {
418         return name().equals("<clinit>"); //$NON-NLS-1$
419
}
420     
421     /**
422      * @see com.sun.jdi.Method#isSynchronized()
423      */

424     public boolean isSynchronized() {
425         return (fModifierBits & MODIFIER_ACC_SYNCHRONIZED) != 0;
426     }
427     
428     /**
429      * @see com.sun.jdi.Method#locationOfCodeIndex(long)
430      */

431     public Location locationOfCodeIndex(long index) {
432         if (isAbstract() || isNative()) {
433             return null;
434         }
435         try {
436             Integer JavaDoc lineNrInt = (Integer JavaDoc)javaStratumCodeIndexToLine().get(new Long JavaDoc(index));
437             if (lineNrInt == null) {
438                 throw new AbsentInformationException(MessageFormat.format(JDIMessages.MethodImpl_No_valid_location_at_the_specified_code_index__0__2, new Object JavaDoc[]{Long.toString(index)}));
439             }
440         } catch (AbsentInformationException e ) {
441         }
442         return new LocationImpl(virtualMachineImpl(), this, index);
443     }
444     
445     /**
446      * @see com.sun.jdi.Method#locationsOfLine(int)
447      */

448     public List JavaDoc locationsOfLine(int line) throws AbsentInformationException {
449         return locationsOfLine(virtualMachine().getDefaultStratum(), null, line);
450     }
451     
452     /**
453      * @see com.sun.jdi.Method#returnType()
454      */

455     public Type returnType() throws ClassNotLoadedException {
456         int startIndex = signature().lastIndexOf(')') + 1; // Signature position is just after ending brace.
457
return TypeImpl.create(virtualMachineImpl(), signature().substring(startIndex), declaringType().classLoader());
458     }
459
460     
461     /**
462      * @see com.sun.jdi.Method#returnTypeName()
463      */

464     public String JavaDoc returnTypeName() {
465         if (fReturnTypeName != null) {
466             return fReturnTypeName;
467         }
468         int startIndex = signature().lastIndexOf(')') + 1; // Signature position is just after ending brace.
469
fReturnTypeName= TypeImpl.signatureToName(signature().substring(startIndex));
470         return fReturnTypeName;
471     }
472     
473     
474     /**
475      * @see com.sun.jdi.Method#variables()
476      */

477     public List JavaDoc variables() throws AbsentInformationException {
478         if (isNative() || isAbstract()) {
479             throw new AbsentInformationException(JDIMessages.MethodImpl_No_local_variable_information_available_9);
480         }
481         
482         if (fVariables != null) {
483             return fVariables;
484         }
485
486         initJdwpRequest();
487         try {
488             ByteArrayOutputStream JavaDoc outBytes = new ByteArrayOutputStream JavaDoc();
489             DataOutputStream JavaDoc outData = new DataOutputStream JavaDoc(outBytes);
490             writeWithReferenceType(this, outData);
491             
492             boolean withGenericSignature= virtualMachineImpl().isJdwpVersionGreaterOrEqual(1, 5);
493             int jdwpCommand= withGenericSignature ? JdwpCommandPacket.M_VARIABLE_TABLE_WITH_GENERIC : JdwpCommandPacket.M_VARIABLE_TABLE;
494             JdwpReplyPacket replyPacket = requestVM(jdwpCommand, outBytes);
495             switch (replyPacket.errorCode()) {
496                 case JdwpReplyPacket.ABSENT_INFORMATION:
497                     return inferArguments();
498             }
499             
500             defaultReplyErrorHandler(replyPacket.errorCode());
501             
502             DataInputStream JavaDoc replyData = replyPacket.dataInStream();
503             fArgumentSlotsCount = readInt("arg count", replyData); //$NON-NLS-1$
504
int nrOfElements = readInt("elements", replyData); //$NON-NLS-1$
505
List JavaDoc variables = new ArrayList JavaDoc(nrOfElements);
506             for (int i = 0; i < nrOfElements; i++) {
507                 long codeIndex = readLong("code index", replyData); //$NON-NLS-1$
508
String JavaDoc name = readString("name", replyData); //$NON-NLS-1$
509
String JavaDoc signature = readString("signature", replyData); //$NON-NLS-1$
510
String JavaDoc genericSignature= null;
511                 if (withGenericSignature) {
512                     genericSignature= readString("generic signature", replyData); //$NON-NLS-1$
513
if ("".equals(genericSignature)) { //$NON-NLS-1$
514
genericSignature= null;
515                     }
516                 }
517                 int length = readInt("length", replyData); //$NON-NLS-1$
518
int slot = readInt("slot", replyData); //$NON-NLS-1$
519
boolean isArgument = slot < fArgumentSlotsCount;
520
521                 // Note that for instance methods, the first slot contains the this reference.
522
if (isStatic() || slot > 0) {
523                     LocalVariableImpl localVar = new LocalVariableImpl(virtualMachineImpl(), this, codeIndex, name, signature, genericSignature, length, slot, isArgument);
524                     variables.add(localVar);
525                 }
526             }
527             fVariables= variables;
528             return fVariables;
529         } catch (IOException JavaDoc e) {
530             fArgumentSlotsCount = -1;
531             fVariables = null;
532             defaultIOExceptionHandler(e);
533             return null;
534         } finally {
535             handledJdwpRequest();
536         }
537     }
538     
539     
540     /**
541      * @throws AbsentInformationException
542      */

543     private List JavaDoc inferArguments() throws AbsentInformationException {
544         // infer arguments, if possible
545

546         // try to generate the right generic signature for each argument
547
String JavaDoc genericSignature= genericSignature();
548         String JavaDoc[] signatures= (String JavaDoc[]) argumentTypeSignatures().toArray(new String JavaDoc[0]);
549         String JavaDoc[] genericSignatures;
550         if (genericSignature == null) {
551             genericSignatures= new String JavaDoc[signatures.length];
552         } else {
553             genericSignatures= (String JavaDoc[]) GenericSignature.getParameterTypes(genericSignature).toArray(new String JavaDoc[0]);
554             for (int i= 0; i < genericSignatures.length; i++) {
555                 if (genericSignatures[i].equals(signatures[i])) {
556                     genericSignatures[i]= null;
557                 }
558             }
559         }
560         
561         int slot = 0;
562         if (!isStatic()) {
563             slot++;
564         }
565         if (signatures.length >0) {
566             fArgumentSlotsCount = signatures.length;
567             fVariables = new ArrayList JavaDoc(fArgumentSlotsCount);
568             for (int i = 0; i < signatures.length; i++) {
569                 String JavaDoc name = "arg" + i; //$NON-NLS-1$
570
LocalVariableImpl localVar = new LocalVariableImpl(virtualMachineImpl(), this, 0, name, signatures[i], genericSignatures[i], -1, slot, true);
571                 fVariables.add(localVar);
572                 slot++;
573             }
574             return fVariables;
575         }
576         throw new AbsentInformationException(JDIMessages.MethodImpl_No_local_variable_information_available_9);
577
578     }
579
580     /**
581      * @see com.sun.jdi.Method#variablesByName(String)
582      */

583     public List JavaDoc variablesByName(String JavaDoc name) throws AbsentInformationException {
584         Iterator JavaDoc iter = variables().iterator();
585         List JavaDoc result = new ArrayList JavaDoc();
586         while (iter.hasNext()) {
587             LocalVariableImpl var = (LocalVariableImpl)iter.next();
588             if (var.name().equals(name)) {
589                 result.add(var);
590             }
591         }
592         return result;
593     }
594
595     /**
596      * @see com.sun.jdi.Locatable#location()
597      */

598     public Location location() {
599         if (isAbstract()) {
600             return null;
601         }
602         if (isNative()) {
603             return new LocationImpl(virtualMachineImpl(), this, -1);
604         }
605         // First retrieve line code table.
606
try {
607             getLineTable();
608         } catch (AbsentInformationException e) {
609             return new LocationImpl(virtualMachineImpl(), this, -1);
610         }
611
612         // Return location with Lowest Valid Code Index.
613
return new LocationImpl(virtualMachineImpl(), this, fLowestValidCodeIndex);
614     }
615     
616     /**
617      * Writes JDWP representation.
618      */

619     public void write(MirrorImpl target, DataOutputStream JavaDoc out) throws IOException JavaDoc {
620         fMethodID.write(out);
621         if (target.fVerboseWriter != null) {
622             target.fVerboseWriter.println("method", fMethodID.value()); //$NON-NLS-1$
623
}
624     }
625     
626     /**
627      * Writes JDWP representation, including ReferenceType.
628      */

629     protected void writeWithReferenceType(MirrorImpl target, DataOutputStream JavaDoc out) throws IOException JavaDoc {
630         referenceTypeImpl().write(target, out);
631         write(target, out);
632     }
633
634     /**
635      * Writes JDWP representation, including ReferenceType with Tag.
636      */

637     protected void writeWithReferenceTypeWithTag(MirrorImpl target, DataOutputStream JavaDoc out) throws IOException JavaDoc {
638         referenceTypeImpl().writeWithTag(target, out);
639         write(target, out);
640     }
641
642     /**
643      * @return Reads JDWP representation and returns new instance.
644      */

645     protected static MethodImpl readWithReferenceTypeWithTag(MirrorImpl target, DataInputStream JavaDoc in) throws IOException JavaDoc {
646         VirtualMachineImpl vmImpl = target.virtualMachineImpl();
647         // See Location.
648
ReferenceTypeImpl referenceType = ReferenceTypeImpl.readWithTypeTag(target, in);
649         if (referenceType == null)
650             return null;
651
652         JdwpMethodID ID = new JdwpMethodID(vmImpl);
653         if (target.fVerboseWriter != null) {
654             target.fVerboseWriter.println("method", ID.value()); //$NON-NLS-1$
655
}
656
657         ID.read(in);
658         if (ID.isNull()) {
659             return null;
660         }
661             
662         // The method must be part of a known reference type.
663
MethodImpl method = referenceType.findMethod(ID);
664         if (method == null) {
665             throw new InternalError JavaDoc(JDIMessages.MethodImpl_Got_MethodID_of_ReferenceType_that_is_not_a_member_of_the_ReferenceType_10);
666         }
667         return method;
668     }
669     
670     /**
671      * @return Reads JDWP representation and returns new instance.
672      */

673     protected static MethodImpl readWithNameSignatureModifiers(ReferenceTypeImpl target, ReferenceTypeImpl referenceType, boolean withGenericSignature, DataInputStream JavaDoc in) throws IOException JavaDoc {
674         VirtualMachineImpl vmImpl = target.virtualMachineImpl();
675         JdwpMethodID ID = new JdwpMethodID(vmImpl);
676         ID.read(in);
677         if (target.fVerboseWriter != null) {
678             target.fVerboseWriter.println("method", ID.value()); //$NON-NLS-1$
679
}
680
681         if (ID.isNull()) {
682             return null;
683         }
684         String JavaDoc name = target.readString("name", in); //$NON-NLS-1$
685
String JavaDoc signature = target.readString("signature", in); //$NON-NLS-1$
686
String JavaDoc genericSignature= null;
687         if (withGenericSignature) {
688             genericSignature= target.readString("generic signature", in); //$NON-NLS-1$
689
if ("".equals(genericSignature)) { //$NON-NLS-1$
690
genericSignature= null;
691             }
692         }
693         int modifierBits= target.readInt("modifiers", AccessibleImpl.getModifierStrings(), in); //$NON-NLS-1$
694

695         MethodImpl mirror = new MethodImpl(vmImpl, referenceType, ID, name, signature, genericSignature, modifierBits);
696         return mirror;
697     }
698
699     /**
700      * Retrieves constant mappings.
701      */

702     public static void getConstantMaps() {
703         if (fgInvokeOptions != null) {
704             return;
705         }
706         
707         Field JavaDoc[] fields = MethodImpl.class.getDeclaredFields();
708         fgInvokeOptions = new String JavaDoc[32];
709
710         for (int i = 0; i < fields.length; i++) {
711             Field JavaDoc field = fields[i];
712             if ((field.getModifiers() & Modifier.PUBLIC) == 0 || (field.getModifiers() & java.lang.reflect.Modifier.STATIC) == 0 || (field.getModifiers() & Modifier.FINAL) == 0) {
713                 continue;
714             }
715                 
716             try {
717                 String JavaDoc name = field.getName();
718
719                 if (name.startsWith("INVOKE_")) { //$NON-NLS-1$
720
int value = field.getInt(null);
721                     for (int j = 0; j < fgInvokeOptions.length; j++) {
722                         if ((1 << j & value) != 0) {
723                             fgInvokeOptions[j]= name;
724                             break;
725                         }
726                     }
727                 }
728             } catch (IllegalAccessException JavaDoc e) {
729                 // Will not occur for own class.
730
} catch (IllegalArgumentException JavaDoc e) {
731                 // Should not occur.
732
// We should take care that all public static final constants
733
// in this class are numbers that are convertible to int.
734
}
735         }
736     }
737     
738     /**
739      * @return Returns a map with string representations of tags.
740      */

741      protected static String JavaDoc[] getInvokeOptions() {
742         getConstantMaps();
743         return fgInvokeOptions;
744      }
745     /**
746      * @see Method#isObsolete()
747      *
748      * The JDK 1.4.0 specification states that obsolete methods
749      * are given an ID of zero. It also states that when a method
750      * is redefined, the new method gets the ID of the old method.
751      * Thus, the JDWP query for isObsolete on JDK 1.4 will never return true
752      * for a non-zero method ID. The query is therefore not needed
753      */

754     public boolean isObsolete() {
755         if (virtualMachineImpl().isJdwpVersionGreaterOrEqual(1, 4)) {
756             return fMethodID.value() == 0;
757         }
758         return false;
759     }
760
761     /**
762      * @see Method#allLineLocations(String, String)
763      */

764     public List JavaDoc allLineLocations(String JavaDoc stratum, String JavaDoc sourceName) throws AbsentInformationException {
765         if (isAbstract() || isNative()) {
766             return Collections.EMPTY_LIST;
767         }
768         if (stratum == null) { // if stratum not defined use the default stratum for the declaring type
769
stratum= declaringType().defaultStratum();
770         }
771         List JavaDoc allLineLocations= null;
772         Map JavaDoc sourceNameAllLineLocations= null;
773         if (fStratumAllLineLocations == null) { // the stratum map doesn't exist, create it
774
fStratumAllLineLocations= new HashMap JavaDoc();
775         } else {
776             // get the source name map
777
sourceNameAllLineLocations= (Map JavaDoc)fStratumAllLineLocations.get(stratum);
778         }
779         if (sourceNameAllLineLocations == null) { // the source name map doesn't exist, create it
780
sourceNameAllLineLocations= new HashMap JavaDoc();
781             fStratumAllLineLocations.put(stratum, sourceNameAllLineLocations);
782         } else {
783             // get the line locations
784
allLineLocations= (List JavaDoc)sourceNameAllLineLocations.get(sourceName);
785         }
786         if (allLineLocations == null) { // the line locations are not know, compute and store them
787
getLineTable();
788             allLineLocations= referenceTypeImpl().allLineLocations(stratum, sourceName, this, fCodeIndexTable, fJavaStratumLineNumberTable);
789             sourceNameAllLineLocations.put(sourceName, allLineLocations);
790         }
791         return allLineLocations;
792     }
793
794     /**
795      * @see Method#locationsOfLine(String, String, int)
796      */

797     public List JavaDoc locationsOfLine(String JavaDoc stratum, String JavaDoc sourceName, int lineNumber) throws AbsentInformationException {
798         if (isAbstract() || isNative()) {
799             return Collections.EMPTY_LIST;
800         }
801         return referenceTypeImpl().locationsOfLine(stratum, sourceName, lineNumber, this);
802     }
803
804     /**
805      * Return a list which contains a location for the each disjoin range of code indice
806      * that have bean assigned to the given lines (by the compiler or/and the VM).
807      * Return an empty list if there is not executable code at the specified lines.
808      */

809     protected List JavaDoc javaStratumLocationsOfLines(List JavaDoc javaLines) throws AbsentInformationException {
810         Set JavaDoc tmpLocations= new TreeSet JavaDoc();
811         for (Iterator JavaDoc iter = javaLines.iterator(); iter.hasNext();) {
812             Integer JavaDoc key = (Integer JavaDoc)iter.next();
813             List JavaDoc indexes= javaStratumLineToCodeIndexes(key.intValue());
814             if (indexes != null) {
815                 tmpLocations.addAll(indexes);
816             }
817         }
818         List JavaDoc locations = new ArrayList JavaDoc();
819         for (Iterator JavaDoc iter = tmpLocations.iterator(); iter.hasNext();) {
820             long index = ((Long JavaDoc)iter.next()).longValue();
821             int position= Arrays.binarySearch(fCodeIndexTable, index);
822             if (position == 0 || !tmpLocations.contains(new Long JavaDoc(fCodeIndexTable[position - 1]))) {
823                 locations.add(new LocationImpl(virtualMachineImpl(), this, index));
824             }
825         }
826         return locations;
827     }
828     
829     public boolean isBridge() {
830         return (fModifierBits & MODIFIER_ACC_BRIDGE) != 0;
831     }
832
833     public boolean isVarArgs() {
834         // TODO: remove this test when j9 solve its problem
835
// it returns invalid 1.5 flags for 1.4 classes.
836
// see bug 53870
837
return !virtualMachine().name().equals("j9") && (fModifierBits & MODIFIER_ACC_VARARGS) != 0; //$NON-NLS-1$
838
}
839 }
840
Popular Tags