📄 findbugs2.java
字号:
return trainingInputDir; } /* (non-Javadoc) * @see edu.umd.cs.findbugs.IFindBugsEngine#getTrainingOutputDir() */ public String getTrainingOutputDir() { return trainingOutputDir; } /* (non-Javadoc) * @see edu.umd.cs.findbugs.IFindBugsEngine#useTrainingInput() */ public boolean useTrainingInput() { return trainingInputDir != null; } /* (non-Javadoc) * @see edu.umd.cs.findbugs.IFindBugsEngine#setScanNestedArchives(boolean) */ public void setScanNestedArchives(boolean scanNestedArchives) { this.scanNestedArchives = scanNestedArchives; } /** * Create the analysis cache object. */ private void createAnalysisCache() { analysisCache = ClassFactory.instance().createAnalysisCache(classPath, bugReporter); // TODO: this would be a good place to load "analysis plugins" which could // add additional analysis engines. Or, perhaps when we load // detector plugins we should check for analysis engines. // Either way, allowing plugins to add new analyses would be nice. new edu.umd.cs.findbugs.classfile.engine.EngineRegistrar().registerAnalysisEngines(analysisCache); new edu.umd.cs.findbugs.classfile.engine.asm.EngineRegistrar().registerAnalysisEngines(analysisCache); new edu.umd.cs.findbugs.classfile.engine.bcel.EngineRegistrar().registerAnalysisEngines(analysisCache); Global.setAnalysisCacheForCurrentThread(analysisCache); } /** * Build the classpath from project codebases and system codebases. * * @throws InterruptedException if the analysis thread is interrupted * @throws IOException if an I/O error occurs * @throws ResourceNotFoundException */ private void buildClassPath() throws InterruptedException, IOException, CheckedAnalysisException { IClassPathBuilder builder = classFactory.createClassPathBuilder(bugReporter); for (String path : project.getFileArray()) { builder.addCodeBase(classFactory.createFilesystemCodeBaseLocator(path), true); } for (String path : project.getAuxClasspathEntryList()) { builder.addCodeBase(classFactory.createFilesystemCodeBaseLocator(path), false); } builder.scanNestedArchives(scanNestedArchives); builder.build(classPath, progress); appClassList = builder.getAppClassList(); // If any of the application codebases contain source code, // add them to the source path. // Also, use the last modified time of application codebases // to set the project timestamp. for (Iterator<? extends ICodeBase> i = classPath.appCodeBaseIterator(); i.hasNext(); ){ ICodeBase appCodeBase = i.next(); if (appCodeBase.containsSourceFiles()) { String pathName = appCodeBase.getPathName(); if (pathName != null) { project.addSourceDir(pathName); } } project.addTimestamp(appCodeBase.getLastModifiedTime()); } } private void buildReferencedClassSet() throws CheckedAnalysisException, InterruptedException { // XXX: should drive progress dialog (scanning phase)? referencedClassSet = new TreeSet<ClassDescriptor>(); LinkedList<ClassDescriptor> workList = new LinkedList<ClassDescriptor>(); workList.addAll(appClassList); Set<ClassDescriptor> seen = new HashSet<ClassDescriptor>(); Set<ClassDescriptor> appClassSet = new HashSet<ClassDescriptor>(appClassList); Set<ClassDescriptor> badAppClassSet = new HashSet<ClassDescriptor>(); while (!workList.isEmpty()) { if (Thread.interrupted()) throw new InterruptedException(); ClassDescriptor classDesc = workList.removeFirst(); if (seen.contains(classDesc)) { continue; } seen.add(classDesc); referencedClassSet.add(classDesc); // Get list of referenced classes and add them to set. // Add superclasses and superinterfaces to worklist. try { ClassInfo classInfo = Global.getAnalysisCache().getClassAnalysis(ClassInfo.class, classDesc); referencedClassSet.addAll(Arrays.asList(classInfo.getReferencedClassDescriptorList())); if (classInfo.getSuperclassDescriptor() != null) { workList.addLast(classInfo.getSuperclassDescriptor()); } for (ClassDescriptor ifaceDesc : classInfo.getInterfaceDescriptorList()) { workList.addLast(ifaceDesc); } } catch (MissingClassException e) { // Just log it as a missing class bugReporter.reportMissingClass(e.getClassDescriptor()); if (appClassSet.contains(classDesc)) { badAppClassSet.add(classDesc); } } catch (CheckedAnalysisException e) { // Failed to scan a referenced class --- just log the error and continue bugReporter.logError("Error scanning " + classDesc + " for referenced classes", e); if (appClassSet.contains(classDesc)) { badAppClassSet.add(classDesc); } } } // Delete any application classes that could not be read appClassList.removeAll(badAppClassSet); } public List<ClassDescriptor> sortByCallGraph(Collection<ClassDescriptor> classList) { return edu.umd.cs.findbugs.util.TopologicalSort.sortByCallGraph(classList, new OutEdges<ClassDescriptor>() { public Collection<ClassDescriptor> getOutEdges(ClassDescriptor e) { try { ClassInfo classInfo = Global.getAnalysisCache().getClassAnalysis(ClassInfo.class, e); return Arrays.asList( classInfo.getReferencedClassDescriptorList()); } catch (CheckedAnalysisException e2) { AnalysisContext.logError("error while analyzing " + e.getClassName(), e2); return TigerSubstitutes.emptyList(); } }}); } /** * Create the AnalysisContext that will serve as the BCEL-compatibility * layer over the AnalysisCache. */ private void createAnalysisContext() throws CheckedAnalysisException, IOException { AnalysisCacheToAnalysisContextAdapter analysisContext = new AnalysisCacheToAnalysisContextAdapter(); // Make the AnalysisCache the backing store for // the BCEL Repository analysisContext.clearRepository(); // Specify which classes are application classes analysisContext.setAppClassList(appClassList); // If needed, load SourceInfoMap if (sourceInfoFileName != null) { SourceInfoMap sourceInfoMap = analysisContext.getSourceInfoMap(); sourceInfoMap.read(new FileInputStream(sourceInfoFileName)); } // Make this the current analysis context AnalysisContext.setCurrentAnalysisContext(analysisContext); } /** * Configure analysis feature settings. */ private void configureAnalysisFeatures() { for (AnalysisFeatureSetting setting : analysisFeatureSettingList) { setting.configure(AnalysisContext.currentAnalysisContext()); } } /** * Create an execution plan. * * @throws OrderingConstraintException if the detector ordering constraints are inconsistent */ private void createExecutionPlan() throws OrderingConstraintException { executionPlan = new ExecutionPlan(); // Use user preferences to decide which detectors are enabled. DetectorFactoryChooser detectorFactoryChooser = new DetectorFactoryChooser() { HashSet<DetectorFactory> forcedEnabled = new HashSet<DetectorFactory>(); /* (non-Javadoc) * @see edu.umd.cs.findbugs.DetectorFactoryChooser#choose(edu.umd.cs.findbugs.DetectorFactory) */ public boolean choose(DetectorFactory factory) { return FindBugs.isDetectorEnabled(FindBugs2.this, factory) || forcedEnabled.contains(factory); } public void enable(DetectorFactory factory) { forcedEnabled.add(factory); factory.setEnabledButNonReporting(true); } }; executionPlan.setDetectorFactoryChooser(detectorFactoryChooser); // Add plugins for (Iterator<Plugin> i = detectorFactoryCollection.pluginIterator(); i.hasNext(); ) { Plugin plugin = i.next(); if (DEBUG) { System.out.println("Adding plugin " + plugin.getPluginId() + " to execution plan"); } executionPlan.addPlugin(plugin); } // Build the execution plan executionPlan.build(); if (DEBUG) { System.out.println(executionPlan.getNumPasses() + " passes in execution plan"); } } /** * Analyze the classes in the application codebase. */ private void analyzeApplication() throws InterruptedException { int passCount = 0; boolean multiplePasses = executionPlan.getNumPasses() > 1; int [] classesPerPass = new int[executionPlan.getNumPasses()]; classesPerPass[0] = referencedClassSet .size(); for(int i = 0; i < classesPerPass.length; i++) classesPerPass[i] = i == 0 ? referencedClassSet.size() : appClassList.size(); progress.predictPassCount(classesPerPass); for (Iterator<AnalysisPass> i = executionPlan.passIterator(); i.hasNext(); ) { AnalysisPass pass = i.next(); // Instantiate the detectors Detector2[] detectorList = pass.instantiateDetector2sInPass(bugReporter); // If there are multiple passes, then on the first pass, // we apply detectors to all classes referenced by the application classes. // On subsequent passes, we apply detector only to application classes. Collection<ClassDescriptor> classCollection = (multiplePasses && passCount == 0) ? referencedClassSet : appClassList; if (DEBUG) { System.out.println("Pass " + (passCount) + ": " + classCollection.size() + " classes"); } if (passCount > 0) { List<ClassDescriptor> result = sortByCallGraph(classCollection); classCollection = result; } progress.startAnalysis(classCollection.size()); for (ClassDescriptor classDescriptor : classCollection) { if (DEBUG) { System.out.println("Class " + classDescriptor); } if (!classScreener.matches(classDescriptor.toResourceName())) { if (DEBUG) { System.out.println("*** Excluded by class screener"); } continue; } currentClassName = ClassName.toDottedClassName(classDescriptor.getClassName()); notifyClassObservers(classDescriptor); for (Detector2 detector : detectorList) { if (Thread.interrupted()) throw new InterruptedException(); if (DEBUG) { System.out.println("Applying " + detector.getDetectorClassName() + " to " + classDescriptor); } try { detector.visitClass(classDescriptor); } catch (ClassFormatException e) { logRecoverableException(classDescriptor, detector, e); } catch (MissingClassException e) { Global.getAnalysisCache().getErrorLogger().reportMissingClass(e.getClassDescriptor()); } catch (CheckedAnalysisException e) { logRecoverableException(classDescriptor, detector, e); } catch (AnalysisException e) { logRecoverableException(classDescriptor, detector, e); } catch (ArrayIndexOutOfBoundsException e) { logRecoverableException(classDescriptor, detector, e); } catch (ClassCastException e) { logRecoverableException(classDescriptor, detector, e); } catch (RuntimeException e) { logRecoverableException(classDescriptor, detector, e); } } progress.finishClass(); } // Call finishPass on each detector for (Detector2 detector : detectorList) { detector.finishPass(); } AnalysisContext.currentAnalysisContext().updateDatabases(passCount); progress.finishPerClassAnalysis(); passCount++; } // Flush any queued bug reports bugReporter.finish(); // Flush any queued error reports bugReporter.reportQueuedErrors(); } /** * Notify all IClassObservers that we are visiting given class. * * @param classDescriptor the class being visited */ private void notifyClassObservers(ClassDescriptor classDescriptor) { for (IClassObserver observer : classObserverList) { observer.observeClass(classDescriptor); } } /** * Report an exception that occurred while analyzing a class * with a detector. * * @param classDescriptor class being analyzed * @param detector detector doing the analysis * @param e the exception */ private void logRecoverableException( ClassDescriptor classDescriptor, Detector2 detector, Throwable e) { bugReporter.logError("Exception analyzing " + classDescriptor.toDottedClassName() + " using detector " + detector.getDetectorClassName(), e); } public static void main(String[] args) throws Exception { // Create FindBugs2 engine FindBugs2 findBugs = new FindBugs2(); // Parse command line and configure the engine TextUICommandLine commandLine = new TextUICommandLine(); FindBugs.processCommandLine(commandLine, args, findBugs); // Away we go! FindBugs.runMain(findBugs, commandLine); } /* (non-Javadoc) * @see edu.umd.cs.findbugs.IFindBugsEngine#setAbridgedMessages(boolean) */ public void setAbridgedMessages(boolean xmlWithAbridgedMessages) { abridgedMessages = xmlWithAbridgedMessages; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -