001: /*
002: * @(#)MarkedInstruction.java
003: *
004: * Copyright (C) 2002,2003 Matt Albrecht
005: * groboclown@users.sourceforge.net
006: * http://groboutils.sourceforge.net
007: *
008: * Permission is hereby granted, free of charge, to any person obtaining a
009: * copy of this software and associated documentation files (the "Software"),
010: * to deal in the Software without restriction, including without limitation
011: * the rights to use, copy, modify, merge, publish, distribute, sublicense,
012: * and/or sell copies of the Software, and to permit persons to whom the
013: * Software is furnished to do so, subject to the following conditions:
014: *
015: * The above copyright notice and this permission notice shall be included in
016: * all copies or substantial portions of the Software.
017: *
018: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
019: * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
020: * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
021: * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
022: * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
023: * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
024: * DEALINGS IN THE SOFTWARE.
025: */
026:
027: package net.sourceforge.groboutils.codecoverage.v2.compiler;
028:
029: import java.util.Iterator;
030: import java.util.LinkedList;
031: import java.util.List;
032:
033: import org.apache.bcel.generic.Instruction;
034: import org.apache.bcel.generic.InstructionHandle;
035: import org.apache.bcel.generic.InstructionList;
036:
037: /**
038: * Contains one original method instruction, along with all the analysis
039: * module marks for this instruction.
040: *
041: * @author Matt Albrecht <a href="mailto:groboclown@users.sourceforge.net">groboclown@users.sourceforge.net</a>
042: * @version $Date: 2004/04/15 05:48:25 $
043: * @since December 17, 2002
044: */
045: public class MarkedInstruction {
046: private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger
047: .getLogger(MarkedInstruction.class);
048: private final InstructionHandle origInstr;
049: private final List marks = new LinkedList();
050: private boolean closed = false;
051:
052: /**
053: * constant pool index for the name of the class's signature.
054: */
055: private final int classSigPoolIndex;
056:
057: /**
058: * constant pool index for the method-ref for invoking the logger.
059: */
060: private final int staticMethodPoolIndex;
061:
062: /**
063: * Reference to the owning method's index
064: */
065: private final short methodIndex;
066:
067: /**
068: * @throws IllegalStateException if the class file has already been
069: * modified (identified by a class name field).
070: */
071: MarkedInstruction(short methodIndex, int classSigPoolIndex,
072: int staticMethodPoolIndex, InstructionHandle instr) {
073: if (instr == null) {
074: throw new IllegalArgumentException("no null args");
075: }
076: this .origInstr = instr;
077: this .methodIndex = methodIndex;
078: this .classSigPoolIndex = classSigPoolIndex;
079: this .staticMethodPoolIndex = staticMethodPoolIndex;
080: }
081:
082: /**
083: * Retrieve the list of all the marks (if there are any active ones),
084: * but does not add the original instruction (that is for the owner to
085: * know where it goes - before or after). If there are no active
086: * marks, then <tt>null</tt> will be returned. After this has been
087: * called, all the active marks will be removed (assuming that they
088: * have been added to the modified method instruction list).
089: */
090: InstructionList getMarkedList() {
091: InstructionList markedList = null;
092: if (!this .marks.isEmpty()) {
093: markedList = new InstructionList();
094: // mark the instruction first, then add the instruction
095: Iterator iter = this .marks.iterator();
096: while (iter.hasNext()) {
097: LOG.debug("Adding mark to list.");
098: ((MeasureMark) iter.next())
099: .addToInstructionList(markedList);
100: }
101: markedList.setPositions(true);
102: // since we just added the marks, we shouldn't add them
103: // again, so remove all current marks.
104: this .marks.clear();
105: }
106: return markedList;
107: }
108:
109: public int getInstructionPosition() {
110: return this .origInstr.getPosition();
111: }
112:
113: /**
114: * Retrieve the instruction represented by this mark.
115: */
116: public Instruction getInstruction() {
117: return this .origInstr.getInstruction();
118: }
119:
120: /**
121: * Mark this instruction with the given measure and mark indicies; the
122: * method index is pre-defined by the particular method this instruction
123: * resides in.
124: */
125: public void addMark(short measureIndex, short markIndex) {
126: MeasureMark mm = new MeasureMark(this .classSigPoolIndex,
127: this .staticMethodPoolIndex, this .methodIndex,
128: measureIndex, markIndex);
129: this .marks.add(mm);
130: }
131:
132: /**
133: * Retrieve the handle this instruction represents.
134: */
135: InstructionHandle getHandle() {
136: return this.origInstr;
137: }
138: }
|