LineNumberGen.java

  1. /*
  2.  * Licensed to the Apache Software Foundation (ASF) under one or more
  3.  * contributor license agreements.  See the NOTICE file distributed with
  4.  * this work for additional information regarding copyright ownership.
  5.  * The ASF licenses this file to You under the Apache License, Version 2.0
  6.  * (the "License"); you may not use this file except in compliance with
  7.  * the License.  You may obtain a copy of the License at
  8.  *
  9.  *      http://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  *  Unless required by applicable law or agreed to in writing, software
  12.  *  distributed under the License is distributed on an "AS IS" BASIS,
  13.  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  *  See the License for the specific language governing permissions and
  15.  *  limitations under the License.
  16.  */
  17. package org.apache.bcel.generic;

  18. import java.util.Objects;

  19. import org.apache.bcel.classfile.LineNumber;

  20. /**
  21.  * This class represents a line number within a method, i.e., give an instruction a line number corresponding to the
  22.  * source code line.
  23.  *
  24.  * @see LineNumber
  25.  * @see MethodGen
  26.  */
  27. public class LineNumberGen implements InstructionTargeter, Cloneable {

  28.     static final LineNumberGen[] EMPTY_ARRAY = {};

  29.     private InstructionHandle ih;
  30.     private int srcLine;

  31.     /**
  32.      * Create a line number.
  33.      *
  34.      * @param ih instruction handle to reference
  35.      */
  36.     public LineNumberGen(final InstructionHandle ih, final int srcLine) {
  37.         setInstruction(ih);
  38.         setSourceLine(srcLine);
  39.     }

  40.     @Override
  41.     public Object clone() {
  42.         try {
  43.             return super.clone();
  44.         } catch (final CloneNotSupportedException e) {
  45.             throw new UnsupportedOperationException("Clone Not Supported", e); // never happens
  46.         }
  47.     }

  48.     /**
  49.      * @return true, if ih is target of this line number
  50.      */
  51.     @Override
  52.     public boolean containsTarget(final InstructionHandle ih) {
  53.         return this.ih == ih;
  54.     }

  55.     public InstructionHandle getInstruction() {
  56.         return ih;
  57.     }

  58.     /**
  59.      * Gets LineNumber attribute.
  60.      *
  61.      * This relies on that the instruction list has already been dumped to byte code or that the 'setPositions' methods
  62.      * has been called for the instruction list.
  63.      */
  64.     public LineNumber getLineNumber() {
  65.         return new LineNumber(ih.getPosition(), srcLine);
  66.     }

  67.     public int getSourceLine() {
  68.         return srcLine;
  69.     }

  70.     public void setInstruction(final InstructionHandle instructionHandle) { // TODO could be package-protected?
  71.         Objects.requireNonNull(instructionHandle, "instructionHandle");
  72.         BranchInstruction.notifyTarget(this.ih, instructionHandle, this);
  73.         this.ih = instructionHandle;
  74.     }

  75.     public void setSourceLine(final int srcLine) { // TODO could be package-protected?
  76.         this.srcLine = srcLine;
  77.     }

  78.     /**
  79.      * @param oldIh old target
  80.      * @param newIh new target
  81.      */
  82.     @Override
  83.     public void updateTarget(final InstructionHandle oldIh, final InstructionHandle newIh) {
  84.         if (oldIh != ih) {
  85.             throw new ClassGenException("Not targeting " + oldIh + ", but " + ih + "}");
  86.         }
  87.         setInstruction(newIh);
  88.     }
  89. }