KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > javassist > bytecode > LineNumberAttribute


1 /*
2  * Javassist, a Java-bytecode translator toolkit.
3  * Copyright (C) 1999-2005 Shigeru Chiba. All Rights Reserved.
4  *
5  * The contents of this file are subject to the Mozilla Public License Version
6  * 1.1 (the "License"); you may not use this file except in compliance with
7  * the License. Alternatively, the contents of this file may be used under
8  * the terms of the GNU Lesser General Public License Version 2.1 or later.
9  *
10  * Software distributed under the License is distributed on an "AS IS" basis,
11  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12  * for the specific language governing rights and limitations under the
13  * License.
14  */

15
16 package javassist.bytecode;
17
18 import java.io.DataInputStream JavaDoc;
19 import java.io.IOException JavaDoc;
20 import java.util.Map JavaDoc;
21
22 /**
23  * <code>LineNumberTable_attribute</code>.
24  */

25 public class LineNumberAttribute extends AttributeInfo {
26     /**
27      * The name of this attribute <code>"LineNumberTable"</code>.
28      */

29     public static final String JavaDoc tag = "LineNumberTable";
30
31     LineNumberAttribute(ConstPool cp, int n, DataInputStream JavaDoc in)
32         throws IOException JavaDoc
33     {
34         super(cp, n, in);
35     }
36
37     private LineNumberAttribute(ConstPool cp, byte[] i) {
38         super(cp, tag, i);
39     }
40
41     /**
42      * Returns <code>line_number_table_length</code>.
43      * This represents the number of entries in the table.
44      */

45     public int tableLength() {
46         return ByteArray.readU16bit(info, 0);
47     }
48
49     /**
50      * Returns <code>line_number_table[i].start_pc</code>.
51      * This represents the index into the code array at which the code
52      * for a new line in the original source file begins.
53      *
54      * @param i the i-th entry.
55      */

56     public int startPc(int i) {
57         return ByteArray.readU16bit(info, i * 4 + 2);
58     }
59
60     /**
61      * Returns <code>line_number_table[i].line_number</code>.
62      * This represents the corresponding line number in the original
63      * source file.
64      *
65      * @param i the i-th entry.
66      */

67     public int lineNumber(int i) {
68         return ByteArray.readU16bit(info, i * 4 + 4);
69     }
70
71     /**
72      * Returns the line number corresponding to the specified bytecode.
73      *
74      * @param pc the index into the code array.
75      */

76     public int toLineNumber(int pc) {
77         int n = tableLength();
78         int i = 0;
79         for (; i < n; ++i)
80             if (pc < startPc(i))
81                 if (i == 0)
82                     return lineNumber(0);
83                 else
84                     break;
85
86         return lineNumber(i - 1);
87     }
88
89     /**
90      * Returns the index into the code array at which the code for
91      * the specified line begins.
92      *
93      * @param line the line number.
94      * @return -1 if the specified line is not found.
95      */

96     public int toStartPc(int line) {
97         int n = tableLength();
98         for (int i = 0; i < n; ++i)
99             if (line == lineNumber(i))
100                 return startPc(i);
101
102         return -1;
103     }
104
105     /**
106      * Used as a return type of <code>toNearPc()</code>.
107      */

108     static public class Pc {
109         /**
110          * The index into the code array.
111          */

112         public int index;
113         /**
114          * The line number.
115          */

116         public int line;
117     }
118
119     /**
120      * Returns the index into the code array at which the code for
121      * the specified line (or the nearest line after the specified one)
122      * begins.
123      *
124      * @param line the line number.
125      * @return a pair of the index and the line number of the
126      * bytecode at that index.
127      */

128     public Pc toNearPc(int line) {
129         int n = tableLength();
130         int nearPc = 0;
131         int distance = 0;
132         if (n > 0) {
133             distance = lineNumber(0) - line;
134             nearPc = startPc(0);
135         }
136
137         for (int i = 1; i < n; ++i) {
138             int d = lineNumber(i) - line;
139             if ((d < 0 && d > distance)
140                 || (d >= 0 && (d < distance || distance < 0))) {
141                     distance = d;
142                     nearPc = startPc(i);
143             }
144         }
145
146         Pc res = new Pc();
147         res.index = nearPc;
148         res.line = line + distance;
149         return res;
150     }
151
152     /**
153      * Makes a copy.
154      *
155      * @param newCp the constant pool table used by the new copy.
156      * @param classnames should be null.
157      */

158     public AttributeInfo copy(ConstPool newCp, Map JavaDoc classnames) {
159         byte[] src = info;
160         int num = src.length;
161         byte[] dest = new byte[num];
162         for (int i = 0; i < num; ++i)
163             dest[i] = src[i];
164
165         LineNumberAttribute attr = new LineNumberAttribute(newCp, dest);
166         return attr;
167     }
168
169     /**
170      * Adjusts start_pc if bytecode is inserted in a method body.
171      */

172     void shiftPc(int where, int gapLength, boolean exclusive) {
173         int n = tableLength();
174         for (int i = 0; i < n; ++i) {
175             int pos = i * 4 + 2;
176             int pc = ByteArray.readU16bit(info, pos);
177             if (pc > where || (exclusive && pc == where))
178                 ByteArray.write16bit(pc + gapLength, info, pos);
179         }
180     }
181 }
182
Popular Tags