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, that is, 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 Thrown 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       * Constructs a LineNumber.
55       *
56       * @param startPc Program Counter (PC) corresponds to.
57       * @param lineNumber line number in source file.
58       */
59      public LineNumber(final int startPc, final int lineNumber) {
60          this.startPc = Args.requireU2(startPc, "startPc");
61          this.lineNumber = Args.requireU2(lineNumber, "lineNumber");
62      }
63  
64      /**
65       * Initialize from another object.
66       *
67       * @param c The object to copy.
68       */
69      public LineNumber(final LineNumber c) {
70          this(c.getStartPC(), c.getLineNumber());
71      }
72  
73      /**
74       * Called by objects that are traversing the nodes of the tree implicitly defined by the contents of a Java class.
75       * I.e., the hierarchy of methods, fields, attributes, etc. spawns a tree of objects.
76       *
77       * @param v Visitor object.
78       */
79      @Override
80      public void accept(final Visitor v) {
81          v.visitLineNumber(this);
82      }
83  
84      /**
85       * Creates a deep copy of this object.
86       *
87       * @return deep copy of this object.
88       */
89      public LineNumber copy() {
90          try {
91              return (LineNumber) clone();
92          } catch (final CloneNotSupportedException e) {
93              // TODO should this throw?
94          }
95          return null;
96      }
97  
98      /**
99       * Dumps line number/pc pair to file stream in binary format.
100      *
101      * @param file Output file stream.
102      * @throws IOException Thrown if an I/O Exception occurs in writeShort.
103      */
104     public void dump(final DataOutputStream file) throws IOException {
105         file.writeShort(startPc);
106         file.writeShort(lineNumber);
107     }
108 
109     /**
110      * Gets the line number.
111      *
112      * @return Corresponding source line.
113      */
114     public int getLineNumber() {
115         return lineNumber & 0xffff;
116     }
117 
118     /**
119      * Gets the program counter.
120      *
121      * @return PC in code.
122      */
123     public int getStartPC() {
124         return startPc & 0xffff;
125     }
126 
127     /**
128      * Sets the line number.
129      *
130      * @param lineNumber The source line number.
131      */
132     public void setLineNumber(final int lineNumber) {
133         this.lineNumber = (short) lineNumber;
134     }
135 
136     /**
137      * Sets the program counter.
138      *
139      * @param startPc The pc for this line number.
140      */
141     public void setStartPC(final int startPc) {
142         this.startPc = (short) startPc;
143     }
144 
145     /**
146      * @return String representation.
147      */
148     @Override
149     public String toString() {
150         return "LineNumber(" + getStartPC() + ", " + getLineNumber() + ")";
151     }
152 }