001: /*
002: * Bytecode Analysis Framework
003: * Copyright (C) 2003,2004 University of Maryland
004: *
005: * This library is free software; you can redistribute it and/or
006: * modify it under the terms of the GNU Lesser General Public
007: * License as published by the Free Software Foundation; either
008: * version 2.1 of the License, or (at your option) any later version.
009: *
010: * This library is distributed in the hope that it will be useful,
011: * but WITHOUT ANY WARRANTY; without even the implied warranty of
012: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
013: * Lesser General Public License for more details.
014: *
015: * You should have received a copy of the GNU Lesser General Public
016: * License along with this library; if not, write to the Free Software
017: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
018: */
019:
020: package edu.umd.cs.findbugs.ba.bcp;
021:
022: import org.apache.bcel.generic.ConstantPoolGen;
023: import org.apache.bcel.generic.InstructionHandle;
024:
025: import edu.umd.cs.findbugs.annotations.SuppressWarnings;
026: import edu.umd.cs.findbugs.ba.DataflowAnalysisException;
027: import edu.umd.cs.findbugs.ba.Edge;
028: import edu.umd.cs.findbugs.ba.vna.ValueNumberFrame;
029:
030: /**
031: * A "meta" PatternElement that matches any of a list of other child PatternElements.
032: * An example of how this is useful is that you might want to match invocations of any
033: * of a number of different methods. To do this, you can create a MatchAny
034: * with some number of Invoke elements as children.
035: * <p/>
036: * <p> Note that the minOccur() and maxOccur() counts of the child PatternElements
037: * are ignored. A MatchAny element always matches exactly one instruction.
038: *
039: * @author David Hovemeyer
040: * @see PatternElement
041: */
042: public class MatchAny extends PatternElement {
043: private PatternElement[] childList;
044:
045: /**
046: * Constructor.
047: *
048: * @param childList list of child PatternElements
049: */
050: @SuppressWarnings("EI2")
051: public MatchAny(PatternElement[] childList) {
052: this .childList = childList;
053: }
054:
055: @Override
056: public PatternElement label(String label) {
057: for (PatternElement aChildList : childList) {
058: aChildList.label(label);
059: }
060: return this ;
061: }
062:
063: @Override
064: public PatternElement setAllowTrailingEdges(
065: boolean allowTrailingEdges) {
066: // Just forward this on to all children,
067: // since it is the children that the PatternMatcher will ask
068: // about edges.
069: for (PatternElement aChildList : childList)
070: aChildList.setAllowTrailingEdges(allowTrailingEdges);
071:
072: return this ;
073: }
074:
075: @Override
076: public MatchResult match(InstructionHandle handle,
077: ConstantPoolGen cpg, ValueNumberFrame before,
078: ValueNumberFrame after, BindingSet bindingSet)
079: throws DataflowAnalysisException {
080:
081: for (PatternElement child : childList) {
082: MatchResult matchResult = child.match(handle, cpg, before,
083: after, bindingSet);
084: if (matchResult != null)
085: return matchResult;
086: }
087:
088: return null;
089:
090: }
091:
092: @Override
093: public boolean acceptBranch(Edge edge, InstructionHandle source) {
094: // Note: when selecting branch instructions, only the actual
095: // (child) PatternElement should be used.
096: throw new IllegalStateException("shouldn't happen");
097: }
098:
099: @Override
100: public int minOccur() {
101: return 1;
102: }
103:
104: @Override
105: public int maxOccur() {
106: return 1;
107: }
108: }
109:
110: // vim:ts=4
|