001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * https://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 */ 019package org.apache.bcel.classfile; 020 021import java.io.DataInput; 022import java.io.DataOutputStream; 023import java.io.IOException; 024 025import org.apache.bcel.util.Args; 026 027/** 028 * This class represents a (PC offset, line number) pair, that is, a line number in the source that corresponds to a 029 * relative address in the byte code. This is used for debugging purposes. 030 * 031 * @see LineNumberTable 032 */ 033public final class LineNumber implements Cloneable, Node { 034 035 static final LineNumber[] EMPTY_ARRAY = {}; 036 037 /** Program Counter (PC) corresponds to line. */ 038 private int startPc; 039 040 /** Number in source file. */ 041 private int lineNumber; 042 043 /** 044 * Constructs object from file stream. 045 * 046 * @param file Input stream. 047 * @throws IOException Thrown if an I/O Exception occurs in readUnsignedShort. 048 */ 049 LineNumber(final DataInput file) throws IOException { 050 this(file.readUnsignedShort(), file.readUnsignedShort()); 051 } 052 053 /** 054 * Constructs a LineNumber. 055 * 056 * @param startPc Program Counter (PC) corresponds to. 057 * @param lineNumber line number in source file. 058 */ 059 public LineNumber(final int startPc, final int lineNumber) { 060 this.startPc = Args.requireU2(startPc, "startPc"); 061 this.lineNumber = Args.requireU2(lineNumber, "lineNumber"); 062 } 063 064 /** 065 * Initialize from another object. 066 * 067 * @param c The object to copy. 068 */ 069 public LineNumber(final LineNumber c) { 070 this(c.getStartPC(), c.getLineNumber()); 071 } 072 073 /** 074 * Called by objects that are traversing the nodes of the tree implicitly defined by the contents of a Java class. 075 * I.e., the hierarchy of methods, fields, attributes, etc. spawns a tree of objects. 076 * 077 * @param v Visitor object. 078 */ 079 @Override 080 public void accept(final Visitor v) { 081 v.visitLineNumber(this); 082 } 083 084 /** 085 * Creates a deep copy of this object. 086 * 087 * @return deep copy of this object. 088 */ 089 public LineNumber copy() { 090 try { 091 return (LineNumber) clone(); 092 } catch (final CloneNotSupportedException e) { 093 // TODO should this throw? 094 } 095 return null; 096 } 097 098 /** 099 * 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}