1b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato/*
2b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * ProGuard -- shrinking, optimization, obfuscation, and preverification
3b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato *             of Java bytecode.
4b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato *
5b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu)
6b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato *
7b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * This program is free software; you can redistribute it and/or modify it
8b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * under the terms of the GNU General Public License as published by the Free
9b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * Software Foundation; either version 2 of the License, or (at your option)
10b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * any later version.
11b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato *
12b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * This program is distributed in the hope that it will be useful, but WITHOUT
13b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * more details.
16b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato *
17b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * You should have received a copy of the GNU General Public License along
18b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * with this program; if not, write to the Free Software Foundation, Inc.,
19b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */
21b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratopackage proguard.classfile.attribute;
22b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
23b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.classfile.*;
24b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.classfile.attribute.visitor.*;
25b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
26b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato/**
27b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * This Attribute represents a line number table attribute.
28b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato *
29b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * @author Eric Lafortune
30b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */
31b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratopublic class LineNumberTableAttribute extends Attribute
32b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato{
33b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public int              u2lineNumberTableLength;
34b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public LineNumberInfo[] lineNumberTable;
35b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
36b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
37b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
38b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Creates an uninitialized LineNumberTableAttribute.
39b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
40b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public LineNumberTableAttribute()
41b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
42b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
43b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
44b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
45b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
46b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Creates an initialized LineNumberTableAttribute.
47b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
48b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public LineNumberTableAttribute(int              u2attributeNameIndex,
49b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                    int              u2lineNumberTableLength,
50b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                    LineNumberInfo[] lineNumberTable)
51b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
52b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        super(u2attributeNameIndex);
53b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
54b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        this.u2lineNumberTableLength = u2lineNumberTableLength;
55b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        this.lineNumberTable         = lineNumberTable;
56b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
57b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
58b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
59b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
60b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Returns the line number corresponding to the given byte code program
61b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * counter.
62b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
63b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public int getLineNumber(int pc)
64b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
65b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        for (int index = u2lineNumberTableLength-1 ; index >= 0 ; index--)
66b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
67b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            LineNumberInfo info = lineNumberTable[index];
68b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            if (pc >= info.u2startPC)
69b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            {
70b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                return info.u2lineNumber;
71b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            }
72b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
73b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
74b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        return u2lineNumberTableLength > 0 ?
75b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            lineNumberTable[0].u2lineNumber :
76b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            0;
77b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
78b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
79b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
80b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang    /**
81b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang     * Returns the lowest line number, or 0 if there aren't any line numbers.
82b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang     */
83b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang    public int getLowestLineNumber()
84b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang    {
85b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang        if (u2lineNumberTableLength == 0)
86b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang        {
87b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang            return 0;
88b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang        }
89b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang
90b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang        int lowestLineNumber = Integer.MAX_VALUE;
91b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang
92b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang        for (int index = 0; index < u2lineNumberTableLength; index++)
93b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang        {
94b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang            int lineNumber = lineNumberTable[index].u2lineNumber;
95b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang            if (lineNumber < lowestLineNumber)
96b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang            {
97b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang                lowestLineNumber = lineNumber;
98b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang            }
99b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang        }
100b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang
101b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang        return lowestLineNumber;
102b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang    }
103b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang
104b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang
105b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang    /**
106b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang     * Returns the highest line number, or 0 if there aren't any line numbers.
107b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang     */
108b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang    public int getHighestLineNumber()
109b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang    {
110b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang        if (u2lineNumberTableLength == 0)
111b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang        {
112b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang            return 0;
113b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang        }
114b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang
115b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang        int highestLineNumber = Integer.MIN_VALUE;
116b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang
117b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang        for (int index = 0; index < u2lineNumberTableLength; index++)
118b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang        {
119b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang            int lineNumber = lineNumberTable[index].u2lineNumber;
120b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang            if (lineNumber > highestLineNumber)
121b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang            {
122b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang                highestLineNumber = lineNumber;
123b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang            }
124b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang        }
125b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang
126b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang        return highestLineNumber;
127b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang    }
128b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang
129b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang
130b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    // Implementations for Attribute.
131b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
132b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void accept(Clazz clazz, Method method, CodeAttribute codeAttribute, AttributeVisitor attributeVisitor)
133b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
134b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        attributeVisitor.visitLineNumberTableAttribute(clazz, method, codeAttribute, this);
135b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
136b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
137b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
138b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
139b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Applies the given visitor to all line numbers.
140b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
141b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void lineNumbersAccept(Clazz clazz, Method method, CodeAttribute codeAttribute, LineNumberInfoVisitor lineNumberInfoVisitor)
142b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
143b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        for (int index = 0; index < u2lineNumberTableLength; index++)
144b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
145b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            // We don't need double dispatching here, since there is only one
146b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            // type of LineNumberInfo.
147b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            lineNumberInfoVisitor.visitLineNumberInfo(clazz, method, codeAttribute, lineNumberTable[index]);
148b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
149b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
150b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato}
151