/* * Bytecode Analysis Framework * Copyright (C) 2003,2004 University of Maryland * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package edu.umd.cs.findbugs.ba.bcp; /** * A ByteCodePattern is a pattern matching a sequence of bytecode instructions. * * @author David Hovemeyer * @see PatternElement * @see PatternMatcher */ public class ByteCodePattern { private PatternElement first, last; private int interElementWild; private int numElements; private int dummyVariableCount; /** * Add a PatternElement to the end of the pattern. * * @param element * the PatternElement * @return this object */ public ByteCodePattern add(PatternElement element) { if (first != null) addInterElementWild(); addElement(element); return this; } /** * Add a wildcard to match between 0 and given number of instructions. If * there is already a wildcard at the end of the current pattern, resets its * max value to that given. * * @param numWild * maximum number of instructions to be matched by the wildcard */ public ByteCodePattern addWild(int numWild) { Wild wild = isLastWild(); if (wild != null) wild.setMinAndMax(0, numWild); else addElement(new Wild(numWild)); return this; } /** * Set number of inter-element wildcards to create between explicit * PatternElements. By default, no implicit wildcards are created. * * @param numWild * the number of wildcard instructions which may be matched * between explicit PatternElements * @return this object */ public ByteCodePattern setInterElementWild(int numWild) { this.interElementWild = numWild; return this; } /** * Get the first PatternElement in the pattern. */ public PatternElement getFirst() { return first; } /** * Get a dummy variable name. The name returned will begin with the * <code>'$'</code> character, and will be different than any previous dummy * variable name allocated by this object. Dummy variable names are useful * for creating PatternElements where you don't care whether the value it * uses is the same as one used by another PatternElement. */ public String dummyVariable() { StringBuilder buf = new StringBuilder(); buf.append("$_"); buf.append(dummyVariableCount++); return buf.toString(); } private void addInterElementWild() { if (interElementWild > 0 && isLastWild() == null) addElement(new Wild(interElementWild)); } private void addElement(PatternElement element) { element.setIndex(numElements++); if (first == null) { first = last = element; } else { last.setNext(element); last = element; } } private Wild isLastWild() { if (last != null && last instanceof Wild) return (Wild) last; else return null; } } // vim:ts=4