public static void main(String[] args) { CommandLineOptions opts = new CommandLineOptions(args); List files; if (opts.containsCommaSeparatedFileList()) { files = collectFromCommaDelimitedString(opts.getInputFileName()); } else { files = collectFilesFromOneName(opts.getInputFileName()); } PMD pmd; if (opts.jdk13()) { pmd = new PMD(new TargetJDK1_3()); } else { pmd = new PMD(); } RuleContext ctx = new RuleContext(); ctx.setReport(new Report()); try { RuleSetFactory ruleSetFactory = new RuleSetFactory(); RuleSet rules = ruleSetFactory.createRuleSet(opts.getRulesets()); for (Iterator i = files.iterator(); i.hasNext(); ) { File file = (File) i.next(); ctx.setSourceCodeFilename( glomName(opts.shortNamesEnabled(), opts.getInputFileName(), file)); try { pmd.processFile(new FileInputStream(file), opts.getEncoding(), rules, ctx); } catch (PMDException pmde) { if (opts.debugEnabled()) { pmde.getReason().printStackTrace(); } ctx.getReport() .addError( new Report.ProcessingError( pmde.getMessage(), glomName(opts.shortNamesEnabled(), opts.getInputFileName(), file))); } } } catch (FileNotFoundException fnfe) { System.out.println(opts.usage()); fnfe.printStackTrace(); } catch (RuleSetNotFoundException rsnfe) { System.out.println(opts.usage()); rsnfe.printStackTrace(); } try { Renderer r = opts.createRenderer(); System.out.println(r.render(ctx.getReport())); } catch (Exception e) { System.out.println(e.getMessage()); System.out.println(opts.usage()); if (opts.debugEnabled()) { e.printStackTrace(); } } }
public void testPluginname() throws Throwable { Rule rule = new XPathRule(); rule.addProperty("xpath", "//VariableDeclaratorId[string-length(@Image) < 3]"); rule.setMessage("{0}"); rule.addProperty("pluginname", "true"); PMD p = new PMD(); RuleContext ctx = new RuleContext(); Report report = new Report(); ctx.setReport(report); ctx.setSourceCodeFilename("n/a"); RuleSet rules = new RuleSet(); rules.addRule(rule); p.processFile(new StringReader(TEST1), rules, ctx); RuleViolation rv = (RuleViolation) report.iterator().next(); assertEquals("a", rv.getDescription()); }
/** * @param reader - a Reader to the Java code to analyse * @param ruleSet - the set of rules to process against the file * @param ctx - the context in which PMD is operating. This contains the Renderer and whatnot */ public void processFile(Reader reader, RuleSet ruleSet, RuleContext ctx) throws PMDException { try { JavaParser parser = targetJDKVersion.createParser(reader); ASTCompilationUnit c = parser.CompilationUnit(); Thread.yield(); SymbolFacade stb = new SymbolFacade(); stb.initializeWith(c); List acus = new ArrayList(); acus.add(c); ruleSet.apply(acus, ctx); reader.close(); } catch (ParseException pe) { throw new PMDException("Error while parsing " + ctx.getSourceCodeFilename(), pe); } catch (Exception e) { throw new PMDException("Error while processing " + ctx.getSourceCodeFilename(), e); } }
/** * @param languageVersion LanguageVersion * @param ruleSet RuleSet * @param dataSources List<DataSource> * @param results Set<RuleDuration> * @param debug boolean * @throws PMDException * @throws IOException */ private static void stress( LanguageVersion languageVersion, RuleSet ruleSet, List<DataSource> dataSources, Set<RuleDuration> results, boolean debug) throws PMDException, IOException { for (Rule rule : ruleSet.getRules()) { if (debug) { System.out.println("Starting " + rule.getName()); } RuleSet working = new RuleSet(); working.addRule(rule); RuleSets ruleSets = new RuleSets(working); PMDConfiguration config = new PMDConfiguration(); config.setDefaultLanguageVersion(languageVersion); RuleContext ctx = new RuleContext(); long start = System.currentTimeMillis(); Reader reader = null; for (DataSource dataSource : dataSources) { reader = new InputStreamReader(dataSource.getInputStream()); ctx.setSourceCodeFilename(dataSource.getNiceFileName(false, null)); new SourceCodeProcessor(config).processSourceCode(reader, ruleSets, ctx); IOUtil.closeQuietly(reader); } long end = System.currentTimeMillis(); long elapsed = end - start; results.add(new RuleDuration(elapsed, rule)); if (debug) { System.out.println("Done timing " + rule.getName() + "; elapsed time was " + elapsed); } } }
/** {@inheritDoc} */ @Override @SuppressWarnings("unchecked") public List<Node> evaluate(Node node, RuleContext data) { List<Node> results = new ArrayList<Node>(); try { initializeXPathExpression( data.getLanguageVersion().getLanguageVersionHandler().getXPathHandler().getNavigator()); List<XPath> xpaths = nodeNameToXPaths.get(node.toString()); if (xpaths == null) { xpaths = nodeNameToXPaths.get(AST_ROOT); } for (XPath xpath : xpaths) { List<Node> nodes = xpath.selectNodes(node); results.addAll(nodes); } } catch (JaxenException ex) { throw new RuntimeException(ex); } return results; }
public Object visit(ASTMethodDeclaration node, Object data) { if (interfaceSkipper == true) { // skip methods in interfaces return super.visit(node, data); } ASTResultType rt = (ASTResultType) node.jjtGetChild(0); if (rt.isVoid() == true) { return super.visit(node, data); } ASTType t = (ASTType) rt.jjtGetChild(0); if (t.jjtGetNumChildren() == 0 || !(t.jjtGetChild(0) instanceof ASTName)) { return super.visit(node, data); } String returnVariableName = null; List finder = new ArrayList(); GET_RETURN_VARIABLE_NAME: { node.findChildrenOfType(ASTReturnStatement.class, finder, true); if (finder.size() != 1) { return super.visit(node, data); } ASTReturnStatement rs = (ASTReturnStatement) finder.get(0); // EXPLODES IF THE CLASS IS AN INTERFACE SINCE NO RETURN finder.clear(); rs.findChildrenOfType(ASTPrimaryExpression.class, finder, true); ASTPrimaryExpression ape = (ASTPrimaryExpression) finder.get(0); Node lastChild = ape.jjtGetChild(ape.jjtGetNumChildren() - 1); if (lastChild instanceof ASTPrimaryPrefix) { returnVariableName = getNameFromPrimaryPrefix((ASTPrimaryPrefix) lastChild); } if (returnVariableName == null) { return super.visit(node, data); } } CHECK_OUTER_IF: { finder.clear(); node.findChildrenOfType(ASTIfStatement.class, finder, true); if (finder.size() == 2) { ASTIfStatement is = (ASTIfStatement) finder.get(0); if (ifVerify(is, returnVariableName)) { // find synchronized finder.clear(); is.findChildrenOfType(ASTSynchronizedStatement.class, finder, true); if (finder.size() == 1) { ASTSynchronizedStatement ss = (ASTSynchronizedStatement) finder.get(0); finder.clear(); ss.findChildrenOfType(ASTIfStatement.class, finder, true); if (finder.size() == 1) { ASTIfStatement is2 = (ASTIfStatement) finder.get(0); if (ifVerify(is2, returnVariableName)) { finder.clear(); is2.findChildrenOfType(ASTStatementExpression.class, finder, true); if (finder.size() == 1) { ASTStatementExpression se = (ASTStatementExpression) finder.get(0); if (se.jjtGetNumChildren() == 3) { // primaryExpression, AssignmentOperator, Expression if (se.jjtGetChild(0) instanceof ASTPrimaryExpression) { ASTPrimaryExpression pe = (ASTPrimaryExpression) se.jjtGetChild(0); if (matchName(pe, returnVariableName)) { if (se.jjtGetChild(1) instanceof ASTAssignmentOperator) { RuleContext ctx = (RuleContext) data; ctx.getReport() .addRuleViolation(createRuleViolation(ctx, node.getBeginLine())); } } } } } } } } } } } return super.visit(node, data); }
/** * Constructor which shares attributes and report listeners with the given RuleContext. * * @param ruleContext the context from which the values are shared */ public RuleContext(RuleContext ruleContext) { this.attributes = ruleContext.attributes; this.report.addSynchronizedListeners(ruleContext.getReport().getSynchronizedListeners()); }
private void updateMarkers(IFile file, RuleContext context, boolean fTask) throws CoreException, PropertiesException { Map<IFile, Set<MarkerInfo2>> accumulator = getAccumulator(); Set<MarkerInfo2> markerSet = new HashSet<MarkerInfo2>(); List<Review> reviewsList = findReviewedViolations(file); Review review = new Review(); Iterator<RuleViolation> iter = context.getReport().iterator(); // final IPreferences preferences = PMDPlugin.getDefault().loadPreferences(); // final int maxViolationsPerFilePerRule = preferences.getMaxViolationsPerFilePerRule(); Map<Rule, Integer> violationsByRule = new HashMap<Rule, Integer>(); Rule rule = null; while (iter.hasNext()) { RuleViolation violation = iter.next(); rule = violation.getRule(); review.ruleName = rule.getName(); review.lineNumber = violation.getBeginLine(); if (reviewsList.contains(review)) { log.debug( "Ignoring violation of rule " + rule.getName() + " at line " + violation.getBeginLine() + " because of a review."); continue; } Integer count = violationsByRule.get(rule); if (count == null) { count = NumericConstants.ZERO; violationsByRule.put(rule, count); } int maxViolations = maxAllowableViolationsFor(rule); if (count.intValue() < maxViolations) { // Ryan Gustafson 02/16/2008 - Always use PMD_MARKER, as people get confused as to why PMD // problems don't always show up on Problems view like they do when you do build. // markerSet.add(getMarkerInfo(violation, fTask ? PMDRuntimeConstants.PMD_TASKMARKER : // PMDRuntimeConstants.PMD_MARKER)); markerSet.add(getMarkerInfo(violation, markerTypeFor(violation))); /* if (isDfaEnabled && violation.getRule().usesDFA()) { markerSet.add(getMarkerInfo(violation, PMDRuntimeConstants.PMD_DFA_MARKER)); } else { markerSet.add(getMarkerInfo(violation, fTask ? PMDRuntimeConstants.PMD_TASKMARKER : PMDRuntimeConstants.PMD_MARKER)); } */ violationsByRule.put(rule, Integer.valueOf(count.intValue() + 1)); log.debug( "Adding a violation for rule " + rule.getName() + " at line " + violation.getBeginLine()); } else { log.debug( "Ignoring violation of rule " + rule.getName() + " at line " + violation.getBeginLine() + " because maximum violations has been reached for file " + file.getName()); } } if (accumulator != null) { log.debug("Adding markerSet to accumulator for file " + file.getName()); accumulator.put(file, markerSet); } }
/** * Run PMD against a resource * * @param resource the resource to process */ protected final void reviewResource(IResource resource) { IFile file = (IFile) resource.getAdapter(IFile.class); if (file == null || file.getFileExtension() == null) return; Reader input = null; try { boolean included = isIncluded(file); log.debug("Derived files included: " + projectProperties.isIncludeDerivedFiles()); log.debug("file " + file.getName() + " is derived: " + file.isDerived()); log.debug("file checked: " + included); prepareMarkerAccumulator(file); LanguageVersionDiscoverer languageDiscoverer = new LanguageVersionDiscoverer(); LanguageVersion languageVersion = languageDiscoverer.getDefaultLanguageVersionForFile(file.getName()); // in case it is java, select the correct java version if (languageVersion != null && languageVersion.getLanguage() == Language.JAVA) { languageVersion = PMDPlugin.javaVersionFor(file.getProject()); } if (languageVersion != null) { configuration().setDefaultLanguageVersion(languageVersion); } log.debug("discovered language: " + languageVersion); final File sourceCodeFile = file.getRawLocation().toFile(); if (included && getRuleSet().applies(sourceCodeFile) && isFileInWorkingSet(file) && languageVersion != null) { subTask("PMD checking: " + file.getName()); Timer timer = new Timer(); RuleContext context = PMD.newRuleContext(file.getName(), sourceCodeFile); context.setLanguageVersion(languageVersion); input = new InputStreamReader(file.getContents(), file.getCharset()); // getPmdEngine().processFile(input, getRuleSet(), context); // getPmdEngine().processFile(sourceCodeFile, getRuleSet(), context); RuleSets rSets = new RuleSets(getRuleSet()); new SourceCodeProcessor(configuration()).processSourceCode(input, rSets, context); timer.stop(); pmdDuration += timer.getDuration(); updateMarkers(file, context, isUseTaskMarker()); worked(1); fileCount++; } else { log.debug("The file " + file.getName() + " is not in the working set"); } } catch (CoreException e) { log.error("Core exception visiting " + file.getName(), e); // TODO: // complete message } catch (PMDException e) { log.error("PMD exception visiting " + file.getName(), e); // TODO: // complete message } catch (IOException e) { log.error("IO exception visiting " + file.getName(), e); // TODO: // complete message } catch (PropertiesException e) { log.error("Properties exception visiting " + file.getName(), e); // TODO: // complete message } finally { IOUtil.closeQuietly(input); } }