📄 findbugs.java
字号:
public int getMissingClassCount() { return bugReporter.getMissingClassCount(); } /* (non-Javadoc) * @see edu.umd.cs.findbugs.IFindBugsEngine#emitTrainingOutput() */ public boolean emitTrainingOutput() { return emitTrainingOutput; } /* (non-Javadoc) * @see edu.umd.cs.findbugs.IFindBugsEngine#getUserPreferences() */ public UserPreferences getUserPreferences() { if (userPreferences == null) userPreferences = UserPreferences.createDefaultUserPreferences(); return userPreferences; } /* (non-Javadoc) * @see edu.umd.cs.findbugs.IFindBugsEngine#getTrainingInputDir() */ public String getTrainingInputDir() { 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 useTrainingInput; } /* (non-Javadoc) * @see edu.umd.cs.findbugs.IFindBugsEngine#setScanNestedArchives(boolean) */ public void setScanNestedArchives(boolean scanNestedArchives) { // Ignore this - we're not really going to try to do this } /** * Set the FindBugs home directory. */ public static void setHome(String home) { FindBugs.home = home; } /** * Get the FindBugs home directory. */ public static String getHome() { if (home == null) { home = SystemProperties.getProperty("findbugs.home"); if (home == null) { System.err.println("Error: The findbugs.home property is not set!"); } } return home; } /* ---------------------------------------------------------------------- * Private methods * ---------------------------------------------------------------------- */ /** * Configure analysis features. */ private void configureAnalysisFeatures() { for (AnalysisFeatureSetting setting : settingList) { setting.configure(analysisContext); } } /** * Configure training databases. * * @throws IOException */ public static void configureTrainingDatabases(IFindBugsEngine findBugs) throws IOException { if (findBugs.emitTrainingOutput()) { String trainingOutputDir = findBugs.getTrainingOutputDir(); if (!new File(trainingOutputDir).isDirectory()) throw new IOException("Training output directory " + trainingOutputDir + " does not exist"); AnalysisContext.currentAnalysisContext().setDatabaseOutputDir(trainingOutputDir); // XXX: hack System.setProperty("findbugs.checkreturn.savetraining", new File(trainingOutputDir, "checkReturn.db").getPath()); } if (findBugs.useTrainingInput()) { String trainingInputDir = findBugs.getTrainingInputDir(); if (!new File(trainingInputDir).isDirectory()) throw new IOException("Training input directory " + trainingInputDir + " does not exist"); AnalysisContext.currentAnalysisContext().setDatabaseInputDir(trainingInputDir); AnalysisContext.currentAnalysisContext().loadInterproceduralDatabases(); // XXX: hack System.setProperty("findbugs.checkreturn.loadtraining", new File(trainingInputDir, "checkReturn.db").getPath()); } else { AnalysisContext.currentAnalysisContext().loadDefaultInterproceduralDatabases(); } } /** * Create the ExecutionPlan. * * @throws OrderingConstraintException */ private void createExecutionPlan() throws OrderingConstraintException { executionPlan = new ExecutionPlan(); // Only enabled detectors should be part of the execution plan executionPlan.setDetectorFactoryChooser(new DetectorFactoryChooser() { HashSet<DetectorFactory> forcedEnabled = new HashSet<DetectorFactory>(); public boolean choose(DetectorFactory factory) { return FindBugs.isDetectorEnabled(FindBugs.this, factory) || forcedEnabled.contains(factory); } public void enable(DetectorFactory factory) { forcedEnabled.add(factory); factory.setEnabledButNonReporting(true); } }); // Add plugins for (Iterator<Plugin> i = detectorFactoryCollection.pluginIterator(); i.hasNext();) { Plugin plugin = i.next(); executionPlan.addPlugin(plugin); } // Build the plan executionPlan.build(); } /** * Determing whether or not given DetectorFactory should be enabled. * * @param findBugs the IFindBugsEngine * @param factory the DetectorFactory * @return true if the DetectorFactory should be enabled, false otherwise */ public static boolean isDetectorEnabled(IFindBugsEngine findBugs, DetectorFactory factory) { if (!factory.getPlugin().isEnabled()) return false; if (!findBugs.getUserPreferences().isDetectorEnabled(factory)) return false; if (!factory.isEnabledForCurrentJRE()) return false; // Slow first pass detectors are usually disabled, but may be explicitly enabled if (!AnalysisContext.currentAnalysisContext().getBoolProperty(FindBugsAnalysisFeatures.INTERPROCEDURAL_ANALYSIS) && factory.isDetectorClassSubtypeOf(InterproceduralFirstPassDetector.class)) return false; // Training detectors are enabled if, and only if, we are emitting training output boolean isTrainingDetector = factory.isDetectorClassSubtypeOf(TrainingDetector.class); boolean isNonReportingDetector = factory.isDetectorClassSubtypeOf(NonReportingDetector.class); if (findBugs.emitTrainingOutput()) { return isTrainingDetector || isNonReportingDetector; } if (isTrainingDetector) return false; return true; } /** * Based on Project settings, set the classpath to be used * by the Repository when looking up classes. */ private void setRepositoryClassPath() { // Set aux classpath entries addCollectionToClasspath(project.getAuxClasspathEntryList()); // Set implicit classpath entries addCollectionToClasspath(project.getImplicitClasspathEntryList()); // Add system classpath entries String systemClassPath = ClassPath.getClassPath(); StringTokenizer tok = new StringTokenizer(systemClassPath, File.pathSeparator); while (tok.hasMoreTokens()) { String entry = tok.nextToken(); try { analysisContext.addClasspathEntry(entry); } catch (IOException e) { bugReporter.logError("Warning: could not add URL " + entry + " to classpath", e); } } } /** * Add all classpath entries in given Collection to the given * URLClassPathRepository. Missing entries are not fatal: * we'll log them as analysis errors, but the analysis can * continue. * * @param collection classpath entries to add */ private void addCollectionToClasspath(Collection<String> collection) { for (String entry : collection) { try { //repository.addURL(entry); analysisContext.addClasspathEntry(entry); } catch (IOException e) { bugReporter.logError("Warning: could not add URL " + entry + " to classpath", e); } } } /** * Add all classes contained in given file or directory to the BCEL Repository. * * @param item work list item representing the file, which may be a jar/zip * archive, a single class file, or a directory to be recursively * searched for class files * @param archiveWorkList work list of archives to analyze: this method * may add to the work list if it finds nested archives * @param repositoryClassList a List to which all classes found in * the archive or directory are added, so we later know * which files to analyze */ private void scanArchiveOrDirectory(ArchiveWorkListItem item, LinkedList<ArchiveWorkListItem> archiveWorkList, List<String> repositoryClassList, List<String> additionalAuxClasspathEntryList) throws IOException, InterruptedException { String fileName = item.getFileName(); ClassProducer classProducer = null; try { // Create a URL for the filename. // The protocol defaults to "file" if not explicitly // specified in the filename. String protocol = URLClassPath.getURLProtocol(fileName); if (protocol == null) { protocol = "file"; fileName = "file:" + fileName; } URL url = new URL(fileName); // Figure out the file extension String fileExtension = null; int lastDot = fileName.lastIndexOf('.'); if (lastDot >= 0) { fileExtension = fileName.substring(lastDot); } // Create the ClassProducer if (fileExtension != null && URLClassPath.isArchiveExtension(fileExtension)) classProducer = new ZipClassProducer(url, archiveWorkList, additionalAuxClasspathEntryList); else if (fileExtension != null && fileExtension.equals(".class")) classProducer = new SingleClassProducer(url); else if (protocol.equals("file")) { // Assume it's a directory fileName = fileName.substring("file:".length()); File dir = new File(fileName); if (!dir.isDirectory()) throw new IOException("Path " + fileName + " is not an archive, class file, or directory"); classProducer = new DirectoryClassProducer(fileName, additionalAuxClasspathEntryList); } else throw new IOException("URL " + fileName + " is not an archive, class file, or directory"); if (DEBUG || URLClassPathRepository.DEBUG) { System.out.println("Scanning " + url + " for classes"); } // Load all referenced classes into the Repository for (; ;) { if (Thread.interrupted()) throw new InterruptedException(); try { JavaClass jclass = classProducer.getNextClass(); if (jclass == null) break; if (DEBUG) System.out.println("Scanned " + jclass.getClassName()); analysisContext.addApplicationClassToRepository(jclass); repositoryClassList.add(jclass.getClassName()); } catch (ClassFormatException e) { if (DEBUG) e.printStackTrace(); bugReporter.logError("Invalid classfile format", e); } } if (item.isExplicit()) progressCallback.finishArchive(); // If the archive or directory scanned contained source files, // add it to the end of the source path. if (classProducer.containsSourceFiles()) project.addSourceDir(fileName); project.addTimestamp(classProducer.getLastModificationTime()); } catch (IOException e) { // You'd think that the message for a FileNotFoundException would include // the filename, but you'd be wrong. So, we'll add it explicitly. IOException ioe = new IOException("Could not analyze " + fileName); ioe.initCause(e); throw ioe; } finally { if (classProducer != null) { classProducer.close(); } } } /** * Execute a single AnalysisPass. * * @param analysisPass the AnalysisPass * @param repositoryClassList list of application classes in the repository * @throws InterruptedException */ private void executeAnalysisPass(AnalysisPass analysisPass, List<String> repositoryClassList) throws InterruptedException { // Callback for progress dialog: analysis is starting progressCallback.startAnalysis(repositoryClassList.size()); int thisPass = passCount++; if (ExecutionPlan.DEBUG) { System.out.println("************* Analysis pass " + thisPass + " *************"); for (Iterator<DetectorFactory> i = analysisPass.iterator(); i.hasNext();) { DetectorFactory factory = i.next(); System.out.println("\t" + factory.getFullName()); } } // Create detectors // XXX: we can only support BCEL-based detectors. Detector[] detectors = analysisPass.instantiateDetectorsInPass(bugReporter); // Examine each class in the application Set<String> examinedClassSet = new HashSet<String>(); for (String className : repositoryClassList) { if (examinedClassSet.add(className)) examineClass(detectors, className); } if (DEBUG) { long total = 0; for (Long aLong : detectorTimings.values()) { total += aLong.longValue(); } System.out.println(); System.out.println("Detector Timings"); for (Map.Entry<String, Long> entry : detectorTimings.entrySet()) { String detectorName = entry.getKey(); long detectorTime = entry.getValue().longValue(); System.out.println(detectorName + ": " + detectorTime + " ms -> (" + (detectorTime * 100.0f / (float) total) + ") %"); } System.out.println(); detectorTimings = new HashMap<String,Long>(); } // Callback for progress dialog: analysis finished progressCallback.finishPerClassAnalysis(); // Force any detectors which defer work until all classes have // been seen to do that work. this.reportFinal(detectors); AnalysisContext.currentAnalysisContext().updateDatabases(thisPass); } /** * Examine a single class by invoking all of the Detectors on it. * * @param detectors the Detectors to execute on the class * @param className the fully qualified name of the class to examine */ private void examineClass(Detector[] detectors, String className) throws InterruptedException { if (DEBUG) System.out.println("Examining class " + className); long entireClassAnalysisStart = 0; if (TIMEDEBUG || DEBUG) { entireClassAnalysisStart = System.currentTimeMillis(); } this.currentClass = className; try { JavaClass javaClass = Repository.lookupClass(className); // Notify ClassObservers for (IClassObserver aClassObserver : classObserverList) { ClassDescriptor classDescriptor = new ClassDescriptor(ClassName.toSlashedClassName(javaClass.getClassName())); aClassObserver.observeClass(classDescriptor); } // Create a ClassContext for the class ClassContext classContext = analysisContext.getClassContext(javaClass); // Run the Detectors for (Detector detector1 : detectors) { if (Thread.interrupted()) throw new InterruptedException(); Detector detector = detector1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -