View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   https://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.bcel.classfile;
20  
21  import java.io.DataInput;
22  import java.io.DataOutputStream;
23  import java.io.IOException;
24  
25  import org.apache.bcel.util.Args;
26  
27  /**
28   * This class represents a (PC offset, line number) pair, i.e., a line number in the source that corresponds to a
29   * relative address in the byte code. This is used for debugging purposes.
30   *
31   * @see LineNumberTable
32   */
33  public final class LineNumber implements Cloneable, Node {
34  
35      static final LineNumber[] EMPTY_ARRAY = {};
36  
37      /** Program Counter (PC) corresponds to line */
38      private int startPc;
39  
40      /** Number in source file */
41      private int lineNumber;
42  
43      /**
44       * Constructs object from file stream.
45       *
46       * @param file Input stream
47       * @throws IOException if an I/O Exception occurs in readUnsignedShort
48       */
49      LineNumber(final DataInput file) throws IOException {
50          this(file.readUnsignedShort(), file.readUnsignedShort());
51      }
52  
53      /**
54       * @param startPc Program Counter (PC) corresponds to
55       * @param lineNumber line number in source file
56       */
57      public LineNumber(final int startPc, final int lineNumber) {
58          this.startPc = Args.requireU2(startPc, "startPc");
59          this.lineNumber = Args.requireU2(lineNumber, "lineNumber");
60      }
61  
62      /**
63       * Initialize from another object.
64       *
65       * @param c the object to copy
66       */
67      public LineNumber(final LineNumber c) {
68          this(c.getStartPC(), c.getLineNumber());
69      }
70  
71      /**
72       * Called by objects that are traversing the nodes of the tree implicitly defined by the contents of a Java class.
73       * I.e., the hierarchy of methods, fields, attributes, etc. spawns a tree of objects.
74       *
75       * @param v Visitor object
76       */
77      @Override
78      public void accept(final Visitor v) {
79          v.visitLineNumber(this);
80      }
81  
82      /**
83       * @return deep copy of this object
84       */
85      public LineNumber copy() {
86          try {
87              return (LineNumber) clone();
88          } catch (final CloneNotSupportedException e) {
89              // TODO should this throw?
90          }
91          return null;
92      }
93  
94      /**
95       * Dump line number/pc pair to file stream in binary format.
96       *
97       * @param file Output file stream
98       * @throws IOException if an I/O Exception occurs in writeShort
99       */
100     public void dump(final DataOutputStream file) throws IOException {
101         file.writeShort(startPc);
102         file.writeShort(lineNumber);
103     }
104 
105     /**
106      * @return Corresponding source line
107      */
108     public int getLineNumber() {
109         return lineNumber & 0xffff;
110     }
111 
112     /**
113      * @return PC in code
114      */
115     public int getStartPC() {
116         return startPc & 0xffff;
117     }
118 
119     /**
120      * @param lineNumber the source line number
121      */
122     public void setLineNumber(final int lineNumber) {
123         this.lineNumber = (short) lineNumber;
124     }
125 
126     /**
127      * @param startPc the pc for this line number
128      */
129     public void setStartPC(final int startPc) {
130         this.startPc = (short) startPc;
131     }
132 
133     /**
134      * @return String representation
135      */
136     @Override
137     public String toString() {
138         return "LineNumber(" + getStartPC() + ", " + getLineNumber() + ")";
139     }
140 }