📄 findbugs.java
字号:
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 = 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 && 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"); // 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()); Repository.addClass(jclass); repositoryClassList.add(jclass.getClassName()); } catch (ClassFormatException e) { e.printStackTrace(); bugReporter.logError(e.getMessage()); } } 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); } 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. throw new IOException("Could not analyze " + fileName + ": " + e.getMessage()); } finally { if (classProducer != null) { classProducer.close(); } } } /** * Examine a single class by invoking all of the Detectors on it. * * @param className the fully qualified name of the class to examine */ private void examineClass(String className) throws InterruptedException { if (DEBUG) System.out.println("Examining class " + className); this.currentClass = className; try { JavaClass javaClass = Repository.lookupClass(className); // Notify ClassObservers for (Iterator<ClassObserver> i = classObserverList.iterator(); i.hasNext();) { i.next().observeClass(javaClass); } // Create a ClassContext for the class ClassContext classContext = analysisContext.getClassContext(javaClass); // Run the Detectors for (int i = 0; i < detectors.length; ++i) { if (Thread.interrupted()) throw new InterruptedException(); Detector detector = detectors[i]; try { if (DEBUG) System.out.println(" running " + detector.getClass().getName()); detector.visitClassContext(classContext); } catch (AnalysisException e) { reportRecoverableDetectorException(className, detector, e); } catch (ArrayIndexOutOfBoundsException e) { reportRecoverableDetectorException(className, detector, e); } catch (ClassCastException e) { reportRecoverableDetectorException(className, detector, e); } } } catch (ClassNotFoundException e) { // This should never happen unless there are bugs in BCEL. bugReporter.reportMissingClass(e); reportRecoverableException(className, e); } catch (ClassFormatException e) { reportRecoverableException(className, e); } progressCallback.finishClass(); } private void reportRecoverableException(String className, Exception e) { if (DEBUG) { e.printStackTrace(); } bugReporter.logError("Exception analyzing " + className + ": " + e.toString()); } private void reportRecoverableDetectorException(String className, Detector detector, Exception e) { if (DEBUG) { e.printStackTrace(); } bugReporter.logError("Exception analyzing " + className + " using detector " + detector.getClass().getName() + ": " + e.toString()); } /** * Call report() on all detectors, to give them a chance to * report any accumulated bug reports. */ private void reportFinal() throws InterruptedException { for (int i = 0; i < detectors.length; ++i) { if (Thread.interrupted()) throw new InterruptedException(); detectors[i].report(); } } /** * Get the file extension of given fileName. * @return the file extension, or null if there is no file extension */ static String getFileExtension(String fileName) { int lastDot = fileName.lastIndexOf('.'); return (lastDot >= 0) ? fileName.substring(lastDot) : null; } /** * Get the URL protocol of given URL string. * @param urlString the URL string * @return the protocol name ("http", "file", etc.), or null if there is no protocol */ static String getURLProtocol(String urlString) { String protocol = null; int firstColon = urlString.indexOf(':'); if (firstColon >= 0) { String specifiedProtocol = urlString.substring(0, firstColon); if (knownURLProtocolSet.contains(specifiedProtocol)) protocol = specifiedProtocol; } return protocol; } /** * Determine if given file extension indicates an archive file. * * @param fileExtension the file extension (e.g., ".jar") * @return true if the file extension indicates an archive, * false otherwise */ static boolean isArchiveExtension(String fileExtension) { return archiveExtensionSet.contains(fileExtension); } /** * Parse the data for a class to create a JavaClass object. */ private static JavaClass parseClass(String archiveName, InputStream in, String fileName) throws IOException { if (DEBUG) System.out.println("About to parse " + fileName + " in " + archiveName); return parseFromStream(in, fileName); } /** * Parse the data for a class to create a JavaClass object. */ private static JavaClass parseClass(URL url) throws IOException { if (DEBUG) System.out.println("About to parse " + url.toString()); InputStream in = url.openStream(); return parseFromStream(in, url.toString()); } /** * Parse an input stream to produce a JavaClass object. * Makes sure that the input stream is closed no * matter what. */ private static JavaClass parseFromStream(InputStream in, String fileName) throws IOException { boolean parsed = false; try { JavaClass jclass = new ClassParser(in, fileName).parse(); parsed = true; return jclass; } finally { if (!parsed) { // BCEL does not close the input stream unless // parsing was successful. try { in.close(); } catch (IOException ignore) { // Ignore } } } } /** * Process -bugCategories option. * @param categories comma-separated list of bug categories * @return Set of categories to be used */ private static Set<String> handleBugCategories(String categories) { // Parse list of bug categories HashSet<String> categorySet = new HashSet<String>(); StringTokenizer tok = new StringTokenizer(categories, ","); while (tok.hasMoreTokens()) { categorySet.add(tok.nextToken()); } // Enable only those detectors that can emit those categories // (and the ones that produce unknown bug patterns, just to be safe). // Skip disabled detectors, though. for (Iterator<DetectorFactory> i = DetectorFactoryCollection.instance().factoryIterator(); i.hasNext();) { DetectorFactory factory = i.next(); if (!factory.isEnabled()) continue; Collection<BugPattern> reported = factory.getReportedBugPatterns(); boolean enable = false; if (reported.isEmpty()) { // Don't know what bug patterns are produced by this detector if (DEBUG) System.out.println("Unknown bug patterns for " + factory.getShortName()); enable = true; } else { for (Iterator<BugPattern> j = reported.iterator(); j.hasNext();) { BugPattern bugPattern = j.next(); if (categorySet.contains(bugPattern.getCategory())) { if (DEBUG) System.out.println("MATCH ==> " + categorySet + " -- " + bugPattern.getCategory()); enable = true; break; } } } if (DEBUG && enable) { System.out.println("Enabling " + factory.getShortName()); } factory.setEnabled(enable); } return categorySet; } /* ---------------------------------------------------------------------- * main() method * ---------------------------------------------------------------------- */ public static void main(String[] argv) { try { FindBugsCommandLine commandLine = new FindBugsCommandLine(); FindBugs findBugs = createEngine(commandLine, argv); try { runMain(findBugs, commandLine); } catch (RuntimeException e) { System.err.println("Fatal exception: " + e.toString()); String currentClass = findBugs.getCurrentClass(); if (currentClass != null) { System.err.println("\tWhile analyzing " + currentClass); } e.printStackTrace(); System.err.println("Please report the failure to " + Version.SUPPORT_EMAIL); System.exit(1); } } catch (java.io.IOException e) { // Probably a missing file if (DEBUG) { e.printStackTrace(); } System.err.println("IO Error: " + e.getMessage()); System.exit(1); } catch (FilterException e) { System.err.println("Filter exception: " + e.getMessage()); } catch (IllegalArgumentException e) { // Probably an illegal command line argument System.err.println("Illegal argument: " + e.getMessage()); System.exit(1); } } private static FindBugs createEngine(FindBugsCommandLine commandLine, String[] argv) throws java.io.IOException, FilterException { // Expand option files in command line. // An argument beginning with "@" is treated as specifying // the name of an option file. // Each line of option files are treated as a single argument. // Blank lines and comment lines (beginning with "#") // are ignored. argv = CommandLine.expandOptionFiles(argv, true, true); int argCount = commandLine.parse(argv); Project project = commandLine.getProject(); for (int i = argCount; i < argv.length; ++i) project.addFile(argv[i]); if (project.getFileCount() == 0) { System.out.println("FindBugs version " + Version.RELEASE + ", " + Version.WEBSITE); System.out.println("Usage: findbugs -textui [options...] [jar/zip/class files, directories...]"); System.out.println("Options:"); commandLine.printUsage(System.out); System.exit(0); } return commandLine.createEngine(); } private static void runMain(FindBugs findBugs, FindBugsCommandLine commandLine) throws java.io.IOException, RuntimeException, FilterException { try { findBugs.execute(); } catch (InterruptedException e) { // Not possible when running from the command line } int bugCount = findBugs.getBugCount(); int missingClassCount = findBugs.getMissingClassCount(); int errorCount = findBugs.getErrorCount(); if (!commandLine.quiet() || commandLine.setExitCode()) { if (bugCount > 0) System.err.println("Warnings generated: " + bugCount); if (missingClassCount > 0) System.err.println("Missing classes: " + missingClassCount); if (errorCount > 0) System.err.println("Analysis errors: " + errorCount); } if (commandLine.setExitCode()) { int exitCode = 0; if (errorCount > 0) exitCode |= ERROR_FLAG; if (missingClassCount > 0) exitCode |= MISSING_CLASS_FLAG; if (bugCount > 0) exitCode |= BUGS_FOUND_FLAG; System.exit(exitCode); } }}// vim:ts=4
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -