KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > jbet > MethodInfo


1 /*
2  * JBET - Java Binary Enhancement Tool
3  * Copyright (c) 2003 Networks Associates Technology, Inc.
4  *
5  * This software was developed under DARPA/SPAWAR contract
6  * N66001-00-C-8602 "SPMA" as part of the
7  * DARPA OASIS research program.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  * notice, this list of conditions and the following disclaimer in the
16  * documentation and/or other materials provided with the distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28  * SUCH DAMAGE.
29  */

30
31 /**
32  * This class represents a method, one method per object. Most of the
33  * actual content, however, is in the Attributes. "Index" values are
34  * indexes into the constant pool.
35  *
36  * $Id: MethodInfo.java,v 1.18 2003/09/09 17:31:54 areisse Exp $
37  *
38  * @author Lee Badger
39  * @author Larry D'Anna
40  * @version 0.1
41  */

42
43 package jbet;
44 import java.io.*;
45 import java.util.*;
46
47 public class MethodInfo extends MethodSignature {
48
49     public static String JavaDoc JbetLogFacility = "method";
50
51     /* IO stuff, may be stale */
52     private int nameIndex;
53     private int descriptorIndex;
54     private Vector codeAttributes;
55     private Vector attributes;
56     private int [] exceptionInts;
57
58     
59     /* method_info */
60     public Vector attrHints;
61
62     /* code */
63     public int maxStack;
64     public int maxLocals;
65     public Snippit code;
66     public Vector codeAttrHints;
67     public boolean invalid_limits = false;
68
69     /* other attributes */
70     public boolean synthetic, deprecated;
71
72     /* which methods this one calls */
73     class CallInfo
74     {
75     InternSet calls;
76
77     public Iterator calls ()
78     {
79         return calls.iterator();
80     }
81     }
82
83     Object JavaDoc block;
84     boolean[] lvused;
85     Object JavaDoc dataflow; // cached data flow results
86
public ClassInfo cr;
87     CallInfo calls;
88
89     void relocate (Hashtable subs) {
90     descriptor = descriptor.relocate_new(subs);
91     for (int i = 0; i < exceptions.size(); i++) {
92         String JavaDoc s = exceptionAt(i);
93         s = Util.relocate(s, subs);
94         exceptions.setElementAt(s, i);
95     }
96     if (code != null)
97         code.relocate(subs);
98     }
99
100     public MethodInfo () {
101     exceptions = new Vector();
102     attrHints = new Vector();
103     codeAttrHints = new Vector();
104     }
105
106     public Object JavaDoc classrep() { return cr; }
107
108     public MethodInfo resolve() throws ClassFileException {
109     return this;
110     }
111
112     String JavaDoc exceptionAt(int i) {
113     return (String JavaDoc) exceptions.elementAt(i); }
114
115
116     public void disassemble(LineWriter out, String JavaDoc prefix) {
117     out.println (prefix + ".method " + Util.flags2str(accessFlags) + " " + name +
118               " " + descriptor + " {");
119     String JavaDoc p = prefix + " ";
120     for (int i = 0; i < exceptions.size(); i++)
121         out.println(p + ".throws " + exceptions.elementAt(i));
122     if (synthetic)
123         out.println(p + ".synthetic");
124     if (deprecated)
125         out.println(p + ".deprecated");
126     if (code != null) {
127         out.println(p + ".maxstack " + maxStack);
128         out.println(p + ".maxlocals " + maxLocals);
129         code.disassemble(out, p);
130     }
131     out.println(prefix + "}");
132     return;
133     }
134
135     public boolean checkAccess (String JavaDoc fromPackage) {
136     if ((accessFlags & ACC_PUBLIC) != 0)
137         return true;
138     if ((accessFlags & ACC_PRIVATE) != 0)
139         return false;
140     if ((accessFlags & ACC_PROTECTED) != 0)
141         return false;
142     return fromPackage.equals (cr.getPackageName());
143     }
144
145     public boolean checkAccess (ClassInfo cr2) throws ClassFileException {
146     if ((accessFlags & ACC_PUBLIC) != 0)
147         return true;
148     if ((accessFlags & ACC_PRIVATE) != 0)
149         return false;
150     if ((accessFlags & ACC_PROTECTED) != 0) {
151         while (true) {
152         if (cr2 == cr)
153             return true;
154         if (cr2.superClass == null)
155             return false;
156         cr2 = Jbet.loader.getClass (cr2.superClass);
157         }
158     }
159     return cr2.getPackageName().equals (cr.getPackageName ());
160     }
161
162     /* assemble a method */
163     public MethodInfo (Lexer lexer) throws ClassFileException {
164     this();
165     invalid_limits = true;
166     maxStack = -1; maxLocals = -1;
167
168     lexer.push(Lexer.ST_ASM);
169     if (!lexer.match(Token.TAG).text.equals(".method"))
170         lexer.unexpected(lexer.justread());
171     accessFlags = lexer.parse_flags(ACC_ALL_MFLAGS);
172     name = lexer.match(Token.TAG).text;
173     descriptor = lexer.parse_descriptor();
174     lexer.match('{');
175     code = new Snippit();
176     code.assemble(lexer, null, 0, this);
177     if (code.empty()) code = null;
178     lexer.match('}');
179     lexer.pop();
180     if (maxStack >= 0 && maxLocals >= 0) {
181         invalid_limits = false;
182     }
183     }
184
185
186     /* create an empty method */
187     public MethodInfo (String JavaDoc n, Descriptor d, int acc) {
188     accessFlags = acc;
189     name = n;
190     descriptor = d;
191     exceptions = new Vector();
192     attrHints = new Vector();
193     maxStack = maxLocals = -1;
194     code = null;
195     synthetic = deprecated = false;
196     codeAttrHints = new Vector();
197     }
198
199     public MethodInfo (String JavaDoc n, Descriptor d) { this (n,d,0); }
200
201     /* copy a method */
202     public MethodInfo (MethodInfo mi) {
203     name = mi.name;
204     accessFlags = mi.accessFlags;
205     descriptor = mi.descriptor;
206     
207     exceptions = new Vector( mi.exceptions.size() );
208     for (int i = 0; i < mi.exceptions.size(); i++)
209         exceptions.addElement( mi.exceptions.elementAt(i) );
210     
211     attrHints = new Vector();
212
213     synthetic = mi.synthetic;
214     deprecated = mi.deprecated;
215
216     if (mi.code != null) {
217         maxStack = mi.maxStack;
218         maxLocals = mi.maxLocals;
219         code = new Snippit( mi.code );
220         codeAttrHints = new Vector();
221     }
222     cr = mi.cr;
223     }
224
225     /* read the code attribute */
226     void readCode (DataInputStream dataIn, ConstantPool constantPool)
227     throws IOException, ClassFileException {
228     
229     maxStack = dataIn.readUnsignedShort();
230     maxLocals = dataIn.readUnsignedShort();
231     
232     int codeLength = dataIn.readInt();
233         
234         
235     byte [] bytes = new byte [ codeLength ] ;
236     dataIn.readFully (bytes, 0, codeLength);
237
238     int exTableLength = dataIn.readUnsignedShort();
239     ExceptionRec [] exTable = new ExceptionRec [ exTableLength ];
240     for (int i = 0; i < exTableLength; i++)
241         exTable[i] = new ExceptionRec (dataIn, constantPool);
242
243     LineNumRec [] lineNums = null;
244     LocalVarRec [] localVars = null;
245
246     code = new Snippit (bytes, exTable, constantPool);
247     
248     int attributesCount = dataIn.readUnsignedShort();
249     codeAttrHints = new Vector (attributesCount);
250     for (int i = 0; i < attributesCount; i++) {
251         int attrNameindex = dataIn.readUnsignedShort();
252         String JavaDoc attrname = constantPool.utf8At(attrNameindex);
253         int length = dataIn.readInt();
254         
255         GenericAttribute item = new GenericAttribute (attrname, attrNameindex);
256                 
257         if (attrname.equals("LineNumberTable")) {
258         int numLines = dataIn.readUnsignedShort();
259         lineNums = new LineNumRec [ numLines ];
260         for (int j = 0; j < numLines; j++)
261             lineNums[j] = new LineNumRec (dataIn);
262         code.addLines( lineNums );
263         item.writer = code.lineNumWriter();
264         } else if (attrname.equals("LocalVariableTable")) {
265         int numLocals = dataIn.readUnsignedShort();
266         localVars = new LocalVarRec [ numLocals ] ;
267         for (int j = 0; j < numLocals; j++)
268             localVars[j] = new LocalVarRec (dataIn, constantPool);
269         code.addLocals(localVars, constantPool);
270         item.writer = code.localsWriter();
271         } else {
272         Jbet.warn.println ("Warning: unrecognised code attribute " + attrname);
273         item.read (length, dataIn);
274         }
275         codeAttrHints.addElement(item);
276     }
277     codeAttributes = codeAttrHints;
278     }
279
280     
281     /* read a method info */
282     public MethodInfo (DataInputStream dataIn, ConstantPool constantPool)
283     throws IOException, ClassFileException {
284     Jbet.debug.print("reading method ... ");
285     exceptions = new Vector();
286     synthetic = deprecated = false;
287     code = null;
288     codeAttributes = null;
289     
290     accessFlags = dataIn.readUnsignedShort();
291     
292     nameIndex = dataIn.readUnsignedShort();
293     name = constantPool.utf8At(nameIndex);
294     Jbet.debug.println(name);
295
296     descriptorIndex = dataIn.readUnsignedShort();
297     String JavaDoc descriptorString = constantPool.utf8At(descriptorIndex);
298     descriptor = new Descriptor (descriptorString);
299     
300     int attributesCount = dataIn.readUnsignedShort();
301     attrHints = new Vector (attributesCount);
302     for (int i = 0; i < attributesCount; i++) {
303         int attrNameindex = dataIn.readUnsignedShort();
304         String JavaDoc attrname = constantPool.utf8At(attrNameindex);
305         int length = dataIn.readInt();
306         
307         GenericAttribute item = new GenericAttribute (attrname, attrNameindex);
308         
309         if (attrname.equals("Code")) {
310         readCode (dataIn, constantPool);
311         item.writer = codeWriter();
312         } else if (attrname.equals("Exceptions")) {
313         int numExceptions = dataIn.readUnsignedShort();
314         exceptionInts = new int [ numExceptions ];
315         exceptions.ensureCapacity(numExceptions + exceptions.size());
316         for (int j = 0; j < numExceptions; j++) {
317             int exclassIndex = dataIn.readUnsignedShort();
318             exceptionInts[j] = exclassIndex;
319             exceptions.addElement( constantPool.cpClassAt(exclassIndex).string() );
320         }
321         item.writer = exceptionsWriter();
322         } else if (attrname.equals("Synthetic")) {
323         synthetic = true;
324         item.nodata();
325         } else if (attrname.equals("Deprecated")) {
326         deprecated = true;
327         item.nodata();
328         } else {
329         Jbet.warn.println ("Warning: unrecognised method attribute " + attrname);
330         item.read (length, dataIn);
331         }
332         attrHints.addElement(item);
333     }
334     attributes = attrHints;
335
336     }
337
338     public void resolveConstants () {
339     resolveConstants(cr.constantPool);
340     }
341
342     void resolveConstants (ConstantPool constantPool) {
343     if (invalid_limits) {
344         int ms = maxStack;
345         int ml = maxLocals;
346         try {
347         maxStack = maxLocals = -1;
348         DataFlow df = new DataFlow (this);
349         df.out = Jbet.debug;
350         df.run(true);
351         maxStack = df.maxStackDetected;
352         maxLocals = df.maxLocalsDetected;
353         invalid_limits = false;
354         } catch (Throwable JavaDoc e) {
355         maxStack = ms;
356         maxLocals = ml;
357         Jbet.warn.println ("Warning: caught a exception in resolve constants: " + e);
358         e.printStackTrace(Jbet.warn);
359         }
360     }
361
362     
363     nameIndex = constantPool.internUtf8 (name);
364     descriptorIndex = constantPool.internUtf8( descriptor.toString() );
365
366     Vector outAttrs = new Vector();
367
368     if (synthetic)
369         outAttrs.addElement(new GenericAttribute("Synthetic", constantPool).nodata());
370
371     if (deprecated)
372         outAttrs.addElement(new GenericAttribute("Deprecated", constantPool).nodata());
373
374     if (exceptions.size() != 0) {
375         exceptionInts = new int [ exceptions.size() ];
376         for (int i = 0; i < exceptions.size(); i++)
377         exceptionInts[i] = constantPool.internClass(exceptionAt(i));
378
379         GenericAttribute attr = new GenericAttribute("Exceptions", constantPool);
380         attr.writer = exceptionsWriter();
381         outAttrs.addElement( attr );
382     }
383
384     if (code != null)
385         outAttrs.addElement( genCodeAttribute(constantPool) );
386     
387     attributes = new Vector( outAttrs.size() );
388
389     GenericAttribute.permute(attrHints, outAttrs, attributes);
390     }
391
392
393     AttributeWriter exceptionsWriter() {
394     return new AttributeWriter() {
395         public void write(DataOutputStream dataOut)
396             throws IOException {
397             
398             dataOut.writeShort(exceptionInts.length);
399             for (int i = 0; i < exceptionInts.length; i++)
400             dataOut.writeShort( exceptionInts[i] );
401         }
402         public int size() { return 2 + exceptionInts.length*2; };
403         };
404     }
405
406
407     AttributeWriter codeWriter() {
408     return new AttributeWriter() {
409         public void write (DataOutputStream dataOut)
410             throws IOException, RuntimeException JavaDoc {
411
412             dataOut.writeShort (maxStack);
413             dataOut.writeShort (maxLocals);
414             code.writeCodeAndExceptions (dataOut);
415
416             dataOut.writeShort ( codeAttributes.size() );
417             for (int i = 0; i < codeAttributes.size(); i++)
418             ((GenericAttribute)codeAttributes.elementAt(i)).writeAll(dataOut);
419         }
420
421         public int size() {
422             int ret = 2 + 2 + code.codeSize() + code.exceptionsSize() + 2;
423             for (int i = 0; i < codeAttributes.size(); i++)
424             ret += ((GenericAttribute)codeAttributes.elementAt(i))
425                 .writer.size() + 6;
426             return ret;
427         }
428         };
429     }
430
431     GenericAttribute genCodeAttribute(ConstantPool constantPool) {
432     code.resolveConstants (constantPool);
433     Vector outAttrs = new Vector ();
434     
435     GenericAttribute attr;
436
437     if ( (attr = code.genLineNumAttr(constantPool)) != null )
438         outAttrs.addElement(attr);
439     if ( (attr = code.genLocalsAttr(constantPool)) != null )
440         outAttrs.addElement(attr);
441
442     codeAttributes = new Vector ( outAttrs.size() );
443     GenericAttribute.permute(codeAttrHints, outAttrs, codeAttributes);
444
445     attr = new GenericAttribute ("Code", constantPool);
446     attr.writer = codeWriter();
447
448     return attr;
449     }
450
451     
452     void writeFile (DataOutputStream dataOut) throws IOException {
453
454     dataOut.writeShort (accessFlags);
455     dataOut.writeShort (nameIndex);
456     dataOut.writeShort (descriptorIndex);
457     
458     dataOut.writeShort( attributes.size() );
459     for (int i = 0; i < attributes.size(); i++)
460         ((GenericAttribute)attributes.elementAt(i)).writeAll(dataOut);
461     }
462
463     public void removeDataFlow ()
464     {
465     dataflow = null;
466     for (Instruction instr = code.head; instr != null; instr = instr.next)
467         instr._procState = null;
468
469     System.gc();
470     }
471         
472     public void printout(LineWriter out, boolean summarize) {
473     printout (out, summarize, false, false, false);
474     }
475
476     public void printout(LineWriter out, boolean summarize, boolean printlines, boolean printlocals, boolean printcounts) {
477     String JavaDoc f = flags2str(accessFlags);
478     if (!f.equals(""))
479         out.print( f + " " );
480
481     if (synthetic)
482         out.print( "synthetic " );
483     if (deprecated)
484         out.print( "deprecated " );
485
486     out.print (name + " " + descriptor.toString() + (summarize ? "" : "\n"));
487
488     if (exceptions.size() != 0) {
489         out.print ( summarize ? " throws " : "\tThrows: ");
490         for (int i = 0; i < exceptions.size(); i++)
491         out.print ( exceptionAt(i) + " " );
492         out.print( summarize ? "" : "\n" );
493     }
494
495     if (summarize) {
496         out.println();
497         return;
498     }
499
500     if (attributes == null || attributes.size() == 0)
501         return;
502  
503     out.print( "\tAttributes:" );
504     for (int i = 0; i < attributes.size(); i++)
505         out.print (" " + ((GenericAttribute)attributes.elementAt(i)).name );
506     out.println();
507      
508     if (code == null)
509         return;
510
511     out.print( "\tCode Attributes:" );
512     for (int i = 0; i < codeAttributes.size(); i++)
513         out.print (" " + ((GenericAttribute)codeAttributes.elementAt(i)).name);
514     out.println();
515         
516
517     out.println("\tCode Length: " + code.codelength);
518     out.println("\tMaxStack/MaxLocals: " + maxStack + "/" + maxLocals);
519
520     code.printExceptions(out);
521     if (printlocals) code.printLocals(out);
522     if (printlines) code.printLines(out);
523     code.printCode(out, true, printcounts);
524
525     }
526
527     static String JavaDoc flags2str (int accessFlags) {
528     return Util.flags2str(accessFlags);
529     }
530     
531     public boolean isStatic() {
532     return (accessFlags & ACC_STATIC) != 0;
533     }
534
535     public boolean isVirtual() {
536     return (accessFlags & ACC_STATIC) == 0;
537     }
538         
539     public boolean isNative() {
540     return (accessFlags & ACC_NATIVE) != 0;
541     }
542
543     void addDummyLocals () throws ClassFileException, DataFlowException {
544     code.resolveConstants (cr.constantPool);
545     DataFlow tr = new DataFlow (this);
546     tr.run();
547     code.lvVector = new Vector();
548
549     for (Instruction ins = code.head; ins != null; ins = ins.next) {
550         DataFlow.ProcState ps = (DataFlow.ProcState) ins.procState();
551
552         if (ps == null)
553         continue;
554         for (int i = 0; i < ps.locals.length; i++)
555         if (ps.locals[i] != null &&
556             ps.locals[i].base != 'l') {
557             LocalVarRec lv = new LocalVarRec();
558             lv.name = "v" + i;
559             lv.descriptor = ps.locals[i];
560             lv.index = i;
561             lv.start = new BranchTarget (ins);
562             lv.start.offset = ins.pc();
563             lv.end = new BranchTarget (ins);
564             lv.length = 1;
565             code.lvVector.addElement (lv);
566         }
567     }
568     resolveConstants ();
569     }
570
571     public void addLinesAsPCs ()
572     {
573     code.addLinesAsPCs (cr.constantPool);
574     }
575
576     public static final int ACC_PUBLIC = Util.ACC_PUBLIC;
577     public static final int ACC_PRIVATE = Util.ACC_PRIVATE;
578     public static final int ACC_PROTECTED = Util.ACC_PROTECTED;
579     public static final int ACC_STATIC = Util.ACC_STATIC;
580     public static final int ACC_FINAL = Util.ACC_FINAL;
581     public static final int ACC_SYNCHRONIZED = Util.ACC_SYNCHRONIZED;
582     public static final int ACC_NATIVE = Util.ACC_NATIVE;
583     public static final int ACC_ABSTRACT = Util.ACC_ABSTRACT;
584     public static final int ACC_STRICT = Util.ACC_STRICT;
585
586     public static final int ACC_ALL_MFLAGS = ACC_PUBLIC | ACC_PRIVATE |
587     ACC_PROTECTED | ACC_STATIC | ACC_FINAL | ACC_SYNCHRONIZED |
588     ACC_NATIVE | ACC_ABSTRACT | ACC_STRICT;
589
590     public boolean equals(Object JavaDoc o) {
591     return this == o;
592     }
593
594     public String JavaDoc qualifiedName() {
595     return cr.name() + "." + name + " : " + descriptor;
596     }
597
598     /* Does this call other directly? */
599     public boolean calls (MethodInfo other) {
600     if (calls == null)
601         findCalls ();
602
603     return calls.calls.contains (other);
604     }
605
606     /* Does this call other indirectly (or directly)? */
607     public boolean icalls (MethodInfo other) {
608     return icalls1 (other, new InternSet ());
609     }
610
611     /* Is this method recursive? */
612     public boolean recursive () {
613     return icalls1 (this, new InternSet ());
614     }
615
616     private boolean icalls1 (MethodInfo other, InternSet done) {
617     if (calls == null)
618         findCalls ();
619
620     for (Iterator i = calls.calls(); i.hasNext(); ) {
621         MethodInfo mi = (MethodInfo) i.next();
622
623         if (mi == other)
624         return true;
625
626         if (!done.contains (mi)) {
627         done.add (mi);
628         if (icalls1 (mi, done))
629             return true;
630         }
631     }
632
633     return false;
634     }
635
636     public InternSet allCalls () {
637     return allCalls1 (new InternSet(), new InternSet ());
638     }
639
640     InternSet allCalls1 (final InternSet out, final InternSet done) {
641     if (calls == null)
642         findCalls ();
643
644     for (Iterator i = calls.calls(); i.hasNext(); ) {
645         MethodInfo mi = (MethodInfo) i.next();
646
647         if (!done.contains (mi)) {
648         done.add (mi);
649         mi.allCalls1 (out, done);
650         }
651     }
652
653     return out;
654     }
655
656     public void printCalls (LineWriter out) {
657     printCalls1 (out, new InternSet(), "");
658     }
659
660     void printCalls1 (LineWriter out, InternSet done, String JavaDoc indent0) {
661     out.println (indent0 + cr.name() + '.' + name + descriptor);
662     String JavaDoc indent1 = indent0 + " ";
663
664     if (calls == null)
665         findCalls ();
666
667     for (Iterator i = calls.calls(); i.hasNext(); ) {
668         MethodSignature ms = (MethodSignature) i.next();
669         try {
670         MethodInfo mi = ms.resolve();
671
672         if (!done.contains (mi)) {
673             done.add (mi);
674             mi.printCalls1 (out, done, indent1);
675         }
676         else
677             out.println (indent1 + mi.cr.name() + '.' + mi.name + mi.descriptor);
678         } catch (Exception JavaDoc e) {
679         out.println (indent1 + ms.classrep() + '.' + ms.name + ms.descriptor + " E");
680         }
681     }
682     }
683
684     /* Generate a list of the direct method calls */
685     void findCalls () {
686     calls = new CallInfo();
687     calls.calls = new InternSet();
688
689     if (code == null)
690         return;
691
692     for (Instruction ins = code.head; ins != null; ins = ins.next) {
693         if (ins.usesMethod ()) {
694         try {
695             MethodInfo mi = Jbet.loader.getMethod (ins.classRef(), ins.elemName(), ins.descriptor());
696             calls.calls.add (mi);
697         } catch (ClassFileException e) {
698             calls.calls.add (new MethodSignature (ins.classRef(), ins.elemName(), ins.descriptor()));
699         } catch (ElementNotFoundException e) {
700             calls.calls.add (new MethodSignature (ins.classRef(), ins.elemName(), ins.descriptor()));
701         }
702         }
703     }
704     }
705
706     private boolean isOverridden (ClassInfo base) throws ClassFileException
707     {
708     if (base.superClass != null) {
709         ClassInfo suc = Jbet.loader.getClass (base.superClass);
710         if (suc.findMethod (name, descriptor) != null)
711         return true;
712         if (isOverridden (suc))
713         return true;
714     }
715
716     for (int i = 0; i < base.interfaces.size(); i++) {
717         ClassInfo ic = Jbet.loader.getClass (base.interfaceAt (i));
718         if (ic.findMethod (name, descriptor) != null)
719         return true;
720         if (isOverridden (ic))
721         return true;
722     }
723
724     return false;
725     }
726
727     public boolean isOverridden () throws ClassFileException
728     {
729     return isOverridden (cr);
730     }
731 }
732
Popular Tags