📄 analysiscontext.java
字号:
/* * Bytecode Analysis Framework * Copyright (C) 2003-2006 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;import java.io.File;import java.io.IOException;import java.io.InputStream;import java.util.BitSet;import java.util.Collections;import java.util.HashMap;import java.util.List;import java.util.Map;import net.jcip.annotations.NotThreadSafe;import org.apache.bcel.Repository;import org.apache.bcel.classfile.JavaClass;import edu.umd.cs.findbugs.AbstractBugReporter;import edu.umd.cs.findbugs.SourceLineAnnotation;import edu.umd.cs.findbugs.SystemProperties;import edu.umd.cs.findbugs.annotations.NonNull;import edu.umd.cs.findbugs.ba.ch.Subtypes;import edu.umd.cs.findbugs.ba.interproc.PropertyDatabase;import edu.umd.cs.findbugs.ba.interproc.PropertyDatabaseFormatException;import edu.umd.cs.findbugs.ba.npe.ParameterNullnessPropertyDatabase;import edu.umd.cs.findbugs.ba.npe.ReturnValueNullnessPropertyDatabase;import edu.umd.cs.findbugs.ba.type.FieldStoreTypeDatabase;import edu.umd.cs.findbugs.classfile.ClassDescriptor;import edu.umd.cs.findbugs.classfile.IAnalysisCache;import edu.umd.cs.findbugs.detect.NoteAnnotationRetention;import edu.umd.cs.findbugs.detect.UnreadFields;import edu.umd.cs.findbugs.util.ClassName;import edu.umd.cs.findbugs.util.MapCache;/** * A context for analysis of a complete project. * This serves as the repository for whole-program information * and data structures. * * <p> * <b>NOTE</b>: this class is slated to become obsolete. * New code should use the IAnalysisCache object * returned by Global.getAnalysisCache() to access all analysis * information (global databases, class and method analyses, etc.) * </p> * * @author David Hovemeyer * @see IAnalysisCache * @see edu.umd.cs.findbugs.classfile.Global */@NotThreadSafepublic abstract class AnalysisContext { public static final boolean DEBUG = SystemProperties.getBoolean("findbugs.analysiscontext.debug"); public static final boolean IGNORE_BUILTIN_MODELS = SystemProperties.getBoolean("findbugs.ignoreBuiltinModels"); public static final String DEFAULT_NONNULL_PARAM_DATABASE_FILENAME = "nonnullParam.db"; public static final String DEFAULT_CHECK_FOR_NULL_PARAM_DATABASE_FILENAME = "checkForNullParam.db"; public static final String DEFAULT_NULL_RETURN_VALUE_ANNOTATION_DATABASE = "nullReturn.db"; public static final String UNCONDITIONAL_DEREF_DB_FILENAME = "unconditionalDeref.db"; public static final String NONNULL_RETURN_DB_FILENAME = "nonnullReturn.db"; public static final String UNCONDITIONAL_DEREF_DB_RESOURCE = "jdkBaseUnconditionalDeref.db"; public static final String NONNULL_RETURN_DB_RESOURCE = "jdkBaseNonnullReturn.db"; public static final String DEFAULT_NULL_RETURN_VALUE_DB_FILENAME = "mayReturnNull.db"; private static InheritableThreadLocal<AnalysisContext> currentAnalysisContext = new InheritableThreadLocal<AnalysisContext>(); private static InheritableThreadLocal<XFactory> currentXFactory = new InheritableThreadLocal<XFactory>() { @Override public XFactory initialValue() { return new XFactory(); } }; public abstract NullnessAnnotationDatabase getNullnessAnnotationDatabase(); public abstract CheckReturnAnnotationDatabase getCheckReturnAnnotationDatabase(); public abstract AnnotationRetentionDatabase getAnnotationRetentionDatabase(); public abstract JCIPAnnotationDatabase getJCIPAnnotationDatabase(); /** save the original SyntheticRepository so we may * obtain JavaClass objects which we can reuse. * (A URLClassPathRepository gets closed after analysis.) */ private static final org.apache.bcel.util.Repository originalRepository = Repository.getRepository(); // BCEL SyntheticRepository /** * Default maximum number of ClassContext objects to cache. * FIXME: need to evaluate this parameter. Need to keep stats about accesses. */ private static final int DEFAULT_CACHE_SIZE = 3; // Instance fields private BitSet boolPropertySet; private Map<Object,Object> analysisLocals; private String databaseInputDir; private String databaseOutputDir; protected AnalysisContext() { this.boolPropertySet = new BitSet(); this.analysisLocals = Collections.synchronizedMap(new HashMap<Object,Object>()); } /** * Create a new AnalysisContext. * * @param lookupFailureCallback the RepositoryLookupFailureCallback that * the AnalysisContext should use to report errors * @return a new AnalysisContext */ public static AnalysisContext create(RepositoryLookupFailureCallback lookupFailureCallback) { AnalysisContext analysisContext = new LegacyAnalysisContext(lookupFailureCallback); setCurrentAnalysisContext(analysisContext); return analysisContext; } /** Instantiate the CheckReturnAnnotationDatabase. * Do this after the repository has been set up. */ public abstract void initDatabases(); /** * After a pass has been completed, allow the analysis context to update information. * @param pass -- the first pass is pass 0 */ public abstract void updateDatabases(int pass); /** * Get the AnalysisContext associated with this thread */ static public AnalysisContext currentAnalysisContext() { return currentAnalysisContext.get(); } static public XFactory currentXFactory() { return currentXFactory.get(); } UnreadFields unreadFields; public UnreadFields getUnreadFields() { if (unreadFields == null) throw new IllegalStateException("UnreadFields detector not set"); return unreadFields; } public void setUnreadFields(@NonNull UnreadFields unreadFields) { if (this.unreadFields != null) throw new IllegalStateException("UnreadFields detector already set"); this.unreadFields = unreadFields; } /** * file a ClassNotFoundException with the lookupFailureCallback * @see #getLookupFailureCallback() */ static public void reportMissingClass(ClassNotFoundException e) { String missing = AbstractBugReporter.getMissingClassName(e); if (missing.charAt(0) == '[') return; if (e == null) throw new NullPointerException("argument is null"); AnalysisContext currentAnalysisContext2 = currentAnalysisContext(); if (currentAnalysisContext2 == null) return; if (currentAnalysisContext2.missingClassWarningsSuppressed) return; RepositoryLookupFailureCallback lookupFailureCallback = currentAnalysisContext2.getLookupFailureCallback(); if (lookupFailureCallback != null) lookupFailureCallback.reportMissingClass(e); } /** * Report an error */ static public void logError(String msg, Exception e) { AnalysisContext currentAnalysisContext2 = currentAnalysisContext(); if (currentAnalysisContext2 == null) return; RepositoryLookupFailureCallback lookupFailureCallback = currentAnalysisContext2.getLookupFailureCallback(); if (lookupFailureCallback != null) lookupFailureCallback.logError(msg, e); } /** * Report an error */ static public void logError(String msg) { AnalysisContext currentAnalysisContext2 = currentAnalysisContext(); if (currentAnalysisContext2 == null) return; RepositoryLookupFailureCallback lookupFailureCallback = currentAnalysisContext2.getLookupFailureCallback(); if (lookupFailureCallback != null) lookupFailureCallback.logError(msg); } boolean missingClassWarningsSuppressed = false; public boolean setMissingClassWarningsSuppressed(boolean value) { boolean oldValue = missingClassWarningsSuppressed; missingClassWarningsSuppressed = value; return oldValue; } /** * Get the lookup failure callback. */ public abstract RepositoryLookupFailureCallback getLookupFailureCallback(); /** * Set the source path. */ public final void setSourcePath(List<String> sourcePath) { getSourceFinder().setSourceBaseList(sourcePath); } /** * Get the SourceFinder, for finding source files. */ public abstract SourceFinder getSourceFinder(); /** * Get the Subtypes database. * * @return the Subtypes database */ public abstract Subtypes getSubtypes(); /** * Clear the BCEL Repository in preparation for analysis. */ public abstract void clearRepository(); /** * Clear the ClassContext cache. * This should be done between analysis passes. */ public abstract void clearClassContextCache(); /** * Add an entry to the Repository's classpath. * * @param url the classpath entry URL * @throws IOException */ public abstract void addClasspathEntry(String url) throws IOException; /** * Add an application class to the repository. * * @param appClass the application class */ public abstract void addApplicationClassToRepository(JavaClass appClass); /** * Return whether or not the given class is an application class. * * @param cls the class to lookup * @return true if the class is an application class, false if not * an application class or if the class cannot be located */ public boolean isApplicationClass(JavaClass cls) { return getSubtypes().isApplicationClass(cls); } /** * Return whether or not the given class is an application class. * * @param className name of a class * @return true if the class is an application class, false if not * an application class or if the class cannot be located */ public boolean isApplicationClass(String className) { try { JavaClass javaClass = lookupClass(className); return isApplicationClass(javaClass); } catch (ClassNotFoundException e) { AnalysisContext.reportMissingClass(e); return false; } } /** * Lookup a class. * <em>Use this method instead of Repository.lookupClass().</em> * * @param className the name of the class * @return the JavaClass representing the class * @throws ClassNotFoundException (but not really) */ public abstract JavaClass lookupClass(@NonNull String className) throws ClassNotFoundException; /** * Lookup a class. * <em>Use this method instead of Repository.lookupClass().</em> * * @param classDescriptor descriptor specifying the class to look up
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -