1 cananian 1.1.2.3 // LocalVariableNamer, created Wed Jun  6 15:14:26 2001 by bdemsky
  2 cananian 1.1.2.3 // Copyright (C) 2000 Brian Demsky <bdemsky@mit.edu>
  3 bdemsky  1.1.2.1 // Licensed under the terms of the GNU GPL; see COPYING for details.
  4 bdemsky  1.1.2.1 package harpoon.Analysis.RoleInference;
  5 bdemsky  1.1.2.1 import harpoon.IR.RawClass.AttributeCode;
  6 bdemsky  1.1.2.1 import harpoon.IR.RawClass.AttributeLineNumberTable;
  7 bdemsky  1.1.2.1 import harpoon.IR.RawClass.AttributeLocalVariableTable;
  8 bdemsky  1.1.2.1 import harpoon.ClassFile.HMethod;
  9 bdemsky  1.1.2.1 import harpoon.ClassFile.HClass;
 10 bdemsky  1.1.2.1 import harpoon.ClassFile.Loader;
 11 bdemsky  1.1.2.1 import harpoon.Util.Util;
 12 bdemsky  1.1.2.1 
 13 bdemsky  1.1.2.1 import java.io.InputStream;
 14 bdemsky  1.1.2.1 
 15 bdemsky  1.1.2.1 /**
 16 bdemsky  1.1.2.1  * <code>LocalVariableNamer</code>
 17 bdemsky  1.1.2.1  * 
 18 cananian 1.1.2.3  * @author  Brian Demsky <bdemsky@mit.edu>
 19 cananian 1.4      * @version $Id: LocalVariableNamer.java,v 1.4 2002/04/10 03:01:26 cananian Exp $
 20 bdemsky  1.1.2.1  */
 21 bdemsky  1.1.2.1 public class LocalVariableNamer {
 22 bdemsky  1.1.2.1 
 23 bdemsky  1.1.2.1     AttributeCode ac = null;
 24 bdemsky  1.1.2.1     AttributeLineNumberTable alnt = null;
 25 bdemsky  1.1.2.1     AttributeLocalVariableTable alvt = null;    
 26 bdemsky  1.1.2.1 
 27 bdemsky  1.1.2.1     /** Creates a <code>LocalVariableNamer</code>. */
 28 bdemsky  1.1.2.1     public LocalVariableNamer(HMethod hm) {
 29 bdemsky  1.1.2.1         /* create a RawClass for the declaring class of HMethod hm */
 30 bdemsky  1.1.2.1         HClass hc=hm.getDeclaringClass();
 31 bdemsky  1.1.2.1         String methodname=hm.getName();
 32 bdemsky  1.1.2.1         if (methodname.endsWith("$$initcheck"))
 33 bdemsky  1.1.2.1             methodname=methodname.substring(0,methodname.length()-11);
 34 bdemsky  1.1.2.1         String className = hc.getName();
 35 bdemsky  1.1.2.1         //System.out.println(className+" "+hm.getName()+" "+methodname);
 36 bdemsky  1.1.2.1         InputStream is =
 37 bdemsky  1.1.2.1             Loader.getResourceAsStream(Loader.classToResource(className));
 38 bdemsky  1.1.2.1         harpoon.IR.RawClass.ClassFile raw =
 39 bdemsky  1.1.2.1             new harpoon.IR.RawClass.ClassFile(is);
 40 bdemsky  1.1.2.1         /* now find the appropriate MethodInfo */
 41 bdemsky  1.1.2.1         harpoon.IR.RawClass.MethodInfo mi = null;
 42 bdemsky  1.1.2.1         for (int i=0; i<raw.methods.length; i++)
 43 bdemsky  1.1.2.1             if (raw.methods[i].name().equals(methodname) &&
 44 bdemsky  1.1.2.1                 raw.methods[i].descriptor().equals(hm.getDescriptor()))
 45 bdemsky  1.1.2.1                 mi = raw.methods[i];
 46 cananian 1.3.2.1         assert mi!=null;
 47 bdemsky  1.1.2.1         /* find the Code attribute of the MethodInfo */
 48 bdemsky  1.1.2.1 
 49 bdemsky  1.1.2.1         for (int i=0; i<mi.attributes.length; i++)
 50 bdemsky  1.1.2.1             if (mi.attributes[i] instanceof AttributeCode)
 51 bdemsky  1.1.2.1                 ac = (AttributeCode) mi.attributes[i];
 52 cananian 1.3.2.1         assert ac!=null; /* or else this is an abstract method */       
 53 bdemsky  1.1.2.1 
 54 bdemsky  1.1.2.1         for (int i=0; i<ac.attributes.length; i++)
 55 bdemsky  1.1.2.1             if (ac.attributes[i] instanceof AttributeLineNumberTable)
 56 bdemsky  1.1.2.1                 alnt = (AttributeLineNumberTable) ac.attributes[i];
 57 bdemsky  1.1.2.1             else if (ac.attributes[i] instanceof AttributeLocalVariableTable)
 58 bdemsky  1.1.2.1                 alvt = (AttributeLocalVariableTable) ac.attributes[i];
 59 bdemsky  1.1.2.1 
 60 bdemsky  1.1.2.1         //      if (alnt!=null)
 61 bdemsky  1.1.2.1         //alnt.print(new java.io.PrintWriter(System.out,true),3);
 62 bdemsky  1.1.2.1         //if (alvt!=null)
 63 bdemsky  1.1.2.1         //alvt.print(new java.io.PrintWriter(System.out,true),3);
 64 bdemsky  1.1.2.1 
 65 bdemsky  1.1.2.1     }
 66 bdemsky  1.1.2.1     
 67 bdemsky  1.1.2.1     public String lv_name(int lv_index, int line_number) {
 68 bdemsky  1.1.2.1         /* if we don't have both alnt and avnt we don't know the name */
 69 bdemsky  1.1.2.1         if (alnt==null || alvt==null) return null;
 70 cananian 1.3.2.1         assert lv_index < ac.max_locals; /* or invalid lv_index */
 71 bdemsky  1.1.2.1         /* now find the local variable and line number table attributes */
 72 bdemsky  1.1.2.1         /* otherwise, return the first appropriate name */
 73 bdemsky  1.1.2.1         for (int i=0; i<alnt.line_number_table.length; i++) {
 74 bdemsky  1.1.2.1             if (alnt.line_number_table[i].line_number==line_number) {
 75 bdemsky  1.1.2.1                 int start_pc = alnt.line_number_table[i].start_pc;
 76 bdemsky  1.1.2.1                 int end_pc = ac.code.length;
 77 bdemsky  1.1.2.1                 if (i+1<alnt.line_number_table.length)
 78 bdemsky  1.1.2.1                     end_pc = alnt.line_number_table[i+1].start_pc;
 79 bdemsky  1.1.2.1                 // xxx: the javadoc for AttributeLocalVariableTable
 80 bdemsky  1.1.2.1                 // indicates that we should probably not depend on the
 81 bdemsky  1.1.2.1                 // table being sorted, but every instance i've seen has
 82 bdemsky  1.1.2.1                 // been sorted.
 83 bdemsky  1.1.2.2                 for (int pc=start_pc; pc<end_pc; pc++) {
 84 bdemsky  1.1.2.1                     // check for lv entry at this pc
 85 bdemsky  1.1.2.1                     String ln = alvt.localName(pc, lv_index);
 86 bdemsky  1.1.2.1                     if (ln!=null) return ln;
 87 bdemsky  1.1.2.1                 }
 88 bdemsky  1.1.2.2             }
 89 bdemsky  1.1.2.2         }
 90 bdemsky  1.1.2.2 
 91 bdemsky  1.1.2.2         for (int i=0; i<alnt.line_number_table.length; i++) {
 92 bdemsky  1.1.2.2             if (alnt.line_number_table[i].line_number==line_number) {
 93 bdemsky  1.1.2.2                 int start_pc = alnt.line_number_table[i].start_pc;
 94 bdemsky  1.1.2.2                 int end_pc = ac.code.length;
 95 bdemsky  1.1.2.2                 if (i+1<alnt.line_number_table.length)
 96 bdemsky  1.1.2.2                     end_pc = alnt.line_number_table[i+1].start_pc;
 97 bdemsky  1.1.2.2                 // xxx: the javadoc for AttributeLocalVariableTable
 98 bdemsky  1.1.2.2                 // indicates that we should probably not depend on the
 99 bdemsky  1.1.2.2                 // table being sorted, but every instance i've seen has
100 bdemsky  1.1.2.2                 // been sorted.
101 bdemsky  1.1.2.2                 int pc=end_pc;
102 bdemsky  1.1.2.2                 // check for lv entry at this pc
103 bdemsky  1.1.2.2                 String ln = alvt.localName(pc, lv_index);
104 bdemsky  1.1.2.2                 if (ln!=null) return ln;
105 bdemsky  1.1.2.1             }
106 bdemsky  1.1.2.1         }
107 bdemsky  1.1.2.1         /* no relevant entries found. */
108 bdemsky  1.1.2.1         return null;
109 bdemsky  1.1.2.1     }
110 bdemsky  1.1.2.1 
111 bdemsky  1.1.2.1     
112 cananian 1.2     }