/* * FindBugs - Find Bugs in Java programs * Copyright (C) 2003-2007 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.jsr305; import edu.umd.cs.findbugs.ba.BasicBlock; import org.apache.bcel.generic.ConstantPoolGen; import edu.umd.cs.findbugs.ba.CFG; import edu.umd.cs.findbugs.ba.DepthFirstSearch; import edu.umd.cs.findbugs.ba.ReverseDepthFirstSearch; import edu.umd.cs.findbugs.ba.XMethod; import edu.umd.cs.findbugs.ba.vna.ValueNumber; import edu.umd.cs.findbugs.ba.vna.ValueNumberDataflow; import edu.umd.cs.findbugs.classfile.CheckedAnalysisException; import edu.umd.cs.findbugs.classfile.Global; import edu.umd.cs.findbugs.classfile.IAnalysisCache; import edu.umd.cs.findbugs.classfile.MethodDescriptor; import javax.annotation.meta.When; /** * Factory for BackwardTypeQualifierDataflow objects * for given type qualifier values. * * @author David Hovemeyer */ public class BackwardTypeQualifierDataflowFactory extends TypeQualifierDataflowFactory < BackwardTypeQualifierDataflowAnalysis, BackwardTypeQualifierDataflow > { /** * Constructor. * * @param methodDescriptor MethodDescriptor of the method for which we * want to create BackwardTypeQualifierDataflow objects */ public BackwardTypeQualifierDataflowFactory(MethodDescriptor methodDescriptor) { super(methodDescriptor); } /* (non-Javadoc) * @see edu.umd.cs.findbugs.ba.jsr305.TypeQualifierDataflowFactory#getDataflow(edu.umd.cs.findbugs.ba.DepthFirstSearch, edu.umd.cs.findbugs.ba.XMethod, edu.umd.cs.findbugs.ba.CFG, edu.umd.cs.findbugs.ba.vna.ValueNumberDataflow, org.apache.bcel.generic.ConstantPoolGen, edu.umd.cs.findbugs.classfile.IAnalysisCache, edu.umd.cs.findbugs.classfile.MethodDescriptor, edu.umd.cs.findbugs.ba.jsr305.TypeQualifierValue) */ @Override protected BackwardTypeQualifierDataflow getDataflow(DepthFirstSearch dfs, XMethod xmethod, CFG cfg, ValueNumberDataflow vnaDataflow, ConstantPoolGen cpg, IAnalysisCache analysisCache, MethodDescriptor methodDescriptor, TypeQualifierValue typeQualifierValue) throws CheckedAnalysisException { ReverseDepthFirstSearch rdfs = analysisCache.getMethodAnalysis(ReverseDepthFirstSearch.class, methodDescriptor); BackwardTypeQualifierDataflowAnalysis analysis = new BackwardTypeQualifierDataflowAnalysis( dfs, rdfs, xmethod, cfg, vnaDataflow, cpg, typeQualifierValue ); // Get the corresponding forward dataflow. // We use it to halt tracking of backwards values once we know // that they encounter a conflicting forward value. ForwardTypeQualifierDataflowFactory forwardFactory = analysisCache.getMethodAnalysis(ForwardTypeQualifierDataflowFactory.class, methodDescriptor); ForwardTypeQualifierDataflow forwardDataflow = forwardFactory.getDataflow(typeQualifierValue); analysis.setForwardTypeQualifierDataflow(forwardDataflow); analysis.registerSourceSinkLocations(); BackwardTypeQualifierDataflow dataflow = new BackwardTypeQualifierDataflow(cfg, analysis); dataflow.execute(); return dataflow; } @Override protected void populateDatabase(BackwardTypeQualifierDataflow dataflow, ValueNumberDataflow vnaDataflow, XMethod xmethod, TypeQualifierValue tqv) throws CheckedAnalysisException { assert TypeQualifierDatabase.USE_DATABASE; // Get the dataflow fact that propagated // back to the entry of the method. // This will contain the effective type qualifier // annotations on the method parameters. BasicBlock entry = dataflow.getCFG().getEntry(); TypeQualifierValueSet entryFact = dataflow.getAnalysis().getResultFact(entry); for (int i = 0; i < xmethod.getNumParams(); i++) { if (TypeQualifierApplications.getEffectiveTypeQualifierAnnotation(xmethod, i, tqv) != null) { // this parameter already has an explicit annotation continue; } // Get the value number for this parameter ValueNumber paramVN = vnaDataflow.getAnalysis().getEntryValueForParameter(i); FlowValue paramFlowValue = entryFact.getValue(paramVN); if (paramFlowValue == FlowValue.ALWAYS || paramFlowValue == FlowValue.NEVER) { TypeQualifierDatabase tqdb = Global.getAnalysisCache().getDatabase(TypeQualifierDatabase.class); TypeQualifierAnnotation tqa = TypeQualifierAnnotation.getValue( tqv, paramFlowValue == FlowValue.ALWAYS ? When.ALWAYS : When.NEVER); tqdb.setParameter(xmethod.getMethodDescriptor(), i, tqv, tqa); } } } }