Create system to declare processing stages in an extensible fashion
This commit is contained in:
@ -6,7 +6,7 @@ package net.sourceforge.pmd.lang.apex;
|
||||
|
||||
import java.io.Writer;
|
||||
|
||||
import net.sourceforge.pmd.lang.AbstractLanguageVersionHandler;
|
||||
import net.sourceforge.pmd.lang.AbstractPmdLanguageVersionHandler;
|
||||
import net.sourceforge.pmd.lang.Parser;
|
||||
import net.sourceforge.pmd.lang.ParserOptions;
|
||||
import net.sourceforge.pmd.lang.VisitorStarter;
|
||||
@ -18,7 +18,7 @@ import net.sourceforge.pmd.lang.apex.rule.ApexRuleViolationFactory;
|
||||
import net.sourceforge.pmd.lang.ast.xpath.DefaultASTXPathHandler;
|
||||
import net.sourceforge.pmd.lang.rule.RuleViolationFactory;
|
||||
|
||||
public class ApexHandler extends AbstractLanguageVersionHandler {
|
||||
public class ApexHandler extends AbstractPmdLanguageVersionHandler {
|
||||
|
||||
@Override
|
||||
public VisitorStarter getMultifileFacade() {
|
||||
|
@ -266,6 +266,7 @@ public interface Rule extends PropertySource {
|
||||
/**
|
||||
* Sets whether this Rule uses Data Flow Analysis.
|
||||
*/
|
||||
@Deprecated
|
||||
void setDfa(boolean isDfa);
|
||||
|
||||
/**
|
||||
@ -282,6 +283,7 @@ public interface Rule extends PropertySource {
|
||||
*
|
||||
* @return <code>true</code> if Data Flow Analysis is used.
|
||||
*/
|
||||
@Deprecated
|
||||
boolean isDfa();
|
||||
|
||||
/**
|
||||
@ -294,6 +296,7 @@ public interface Rule extends PropertySource {
|
||||
/**
|
||||
* Sets whether this Rule uses Type Resolution.
|
||||
*/
|
||||
@Deprecated
|
||||
void setTypeResolution(boolean usingTypeResolution);
|
||||
|
||||
/**
|
||||
@ -311,6 +314,7 @@ public interface Rule extends PropertySource {
|
||||
*
|
||||
* @return <code>true</code> if Type Resolution is used.
|
||||
*/
|
||||
@Deprecated
|
||||
boolean isTypeResolution();
|
||||
|
||||
/**
|
||||
@ -323,6 +327,7 @@ public interface Rule extends PropertySource {
|
||||
/**
|
||||
* Sets whether this Rule uses multi-file analysis.
|
||||
*/
|
||||
@Deprecated
|
||||
void setMultifile(boolean multifile);
|
||||
|
||||
/**
|
||||
@ -340,6 +345,7 @@ public interface Rule extends PropertySource {
|
||||
*
|
||||
* @return <code>true</code> if the multi file analysis is used.
|
||||
*/
|
||||
@Deprecated
|
||||
boolean isMultifile();
|
||||
|
||||
/**
|
||||
|
@ -596,6 +596,8 @@ public class RuleSet implements ChecksumAware {
|
||||
return includePatterns;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Does any Rule for the given Language use the DFA layer?
|
||||
*
|
||||
@ -604,6 +606,7 @@ public class RuleSet implements ChecksumAware {
|
||||
* @return <code>true</code> if a Rule for the Language uses the DFA layer,
|
||||
* <code>false</code> otherwise.
|
||||
*/
|
||||
@Deprecated
|
||||
public boolean usesDFA(Language language) {
|
||||
for (Rule r : rules) {
|
||||
if (r.getLanguage().equals(language) && r.isDfa()) {
|
||||
@ -621,6 +624,7 @@ public class RuleSet implements ChecksumAware {
|
||||
* @return <code>true</code> if a Rule for the Language uses Type
|
||||
* Resolution, <code>false</code> otherwise.
|
||||
*/
|
||||
@Deprecated
|
||||
public boolean usesTypeResolution(Language language) {
|
||||
for (Rule r : rules) {
|
||||
if (r.getLanguage().equals(language) && r.isTypeResolution()) {
|
||||
@ -640,6 +644,7 @@ public class RuleSet implements ChecksumAware {
|
||||
* @return {@code true} if a Rule for the Language uses multi file analysis,
|
||||
* {@code false} otherwise.
|
||||
*/
|
||||
@Deprecated
|
||||
public boolean usesMultifile(Language language) {
|
||||
for (Rule r : rules) {
|
||||
if (r.getLanguage().equals(language) && r.isMultifile()) {
|
||||
|
@ -161,6 +161,7 @@ public class RuleSets {
|
||||
* the language of a source
|
||||
* @return true if any rule in the RuleSet needs the DFA layer
|
||||
*/
|
||||
@Deprecated
|
||||
public boolean usesDFA(Language language) {
|
||||
for (RuleSet ruleSet : ruleSets) {
|
||||
if (ruleSet.usesDFA(language)) {
|
||||
@ -210,6 +211,7 @@ public class RuleSets {
|
||||
* @return <code>true</code> if a Rule for the Language uses Type
|
||||
* Resolution, <code>false</code> otherwise.
|
||||
*/
|
||||
@Deprecated
|
||||
public boolean usesTypeResolution(Language language) {
|
||||
for (RuleSet ruleSet : ruleSets) {
|
||||
if (ruleSet.usesTypeResolution(language)) {
|
||||
@ -228,6 +230,7 @@ public class RuleSets {
|
||||
* @return {@code true} if a Rule for the Language uses multi file analysis,
|
||||
* {@code false} otherwise.
|
||||
*/
|
||||
@Deprecated
|
||||
public boolean usesMultifile(Language language) {
|
||||
for (RuleSet ruleSet : ruleSets) {
|
||||
if (ruleSet.usesMultifile(language)) {
|
||||
|
@ -173,6 +173,34 @@ public class SourceCodeProcessor {
|
||||
Parser parser = PMD.parserFor(languageVersion, configuration);
|
||||
|
||||
Node rootNode = parse(ctx, sourceCode, parser);
|
||||
// basically:
|
||||
// 1. make the union of all stage dependencies of each rule, by language, for the Rulesets
|
||||
// 2. order them by dependency
|
||||
// 3. run them and time them if needed
|
||||
|
||||
// The problem is the first two steps need only be done once.
|
||||
// They're probably costly and if we do this here without changing anything,
|
||||
// they'll be done on each file! Btw currently the "usesDfa" and such are nested loops testing
|
||||
// all rules of all rulesets, but they're run on each file too!
|
||||
|
||||
// Also, the benchmarking framework needs a small refactor. TimedOperationCategory needs to be
|
||||
// made extensible -> probably should be turned to a class with static constants + factory methods
|
||||
// and not an enum.
|
||||
|
||||
// With mutable RuleSets, caching of the value can't be guaranteed to be accurate...
|
||||
// The approach I'd like to take is either
|
||||
// * to create a new RunnableRulesets class which is immutable, and performs all these preliminary
|
||||
// computations upon construction.
|
||||
// * or to modify Ruleset and Rulesets to be immutable. This IMO is a better option because it makes
|
||||
// these objects easier to reason about and pass around from thread to thread. It also avoid creating
|
||||
// a new class, and breaking SourceCodeProcessor's API too much.
|
||||
//
|
||||
// The "preliminary computations" also include:
|
||||
// * removing dysfunctional rules
|
||||
// * separating rulechain rules from normal rules
|
||||
// * grouping rules by language/ file extension
|
||||
// * etc.
|
||||
|
||||
resolveQualifiedNames(rootNode, languageVersionHandler);
|
||||
symbolFacade(rootNode, languageVersionHandler);
|
||||
Language language = languageVersion.getLanguage();
|
||||
|
@ -0,0 +1,34 @@
|
||||
/**
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.lang;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import net.sourceforge.pmd.lang.ast.AstProcessingStage;
|
||||
import net.sourceforge.pmd.lang.rule.RuleViolationFactory;
|
||||
|
||||
|
||||
/**
|
||||
* Base language version handler for languages that only support CPD.
|
||||
*
|
||||
* @author Clément Fournier
|
||||
* @since 6.10.0
|
||||
*/
|
||||
public abstract class AbstractCpdLanguageVersionHandler extends AbstractLanguageVersionHandler {
|
||||
@Override
|
||||
public List<? extends AstProcessingStage<?>> getProcessingStages() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
|
||||
protected abstract String getLanguageName();
|
||||
|
||||
|
||||
@Override
|
||||
public RuleViolationFactory getRuleViolationFactory() {
|
||||
throw new UnsupportedOperationException("getRuleViolationFactory() is not supported for " + getLanguageName());
|
||||
}
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
/**
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.lang;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.lang3.EnumUtils;
|
||||
|
||||
import net.sourceforge.pmd.lang.ast.AstProcessingStage;
|
||||
|
||||
|
||||
/**
|
||||
* Base language version handler for languages that support PMD, i.e. can build an AST
|
||||
* and support AST processing stages.
|
||||
*
|
||||
* @author Clément Fournier
|
||||
* @since 6.10.0
|
||||
*/
|
||||
public abstract class AbstractPmdLanguageVersionHandler extends AbstractLanguageVersionHandler {
|
||||
|
||||
|
||||
private final List<? extends AstProcessingStage<?>> processingStages;
|
||||
|
||||
|
||||
/**
|
||||
* Declare processing stages within an enum. An enum is the best way
|
||||
* to declare them since the illegality of forward references naturally
|
||||
* prevents circular dependencies to be declared. The natural ordering
|
||||
* on enums is also a sound and stable ordering for processing stages.
|
||||
*
|
||||
* @param processingStagesEnum Enum class
|
||||
* @param <T> Type of the enum class
|
||||
*/
|
||||
protected <T extends Enum<T> & AstProcessingStage<T>> AbstractPmdLanguageVersionHandler(Class<T> processingStagesEnum) {
|
||||
this.processingStages = EnumUtils.getEnumList(processingStagesEnum);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Declare no optional processing stages as of yet.
|
||||
*/
|
||||
protected AbstractPmdLanguageVersionHandler() {
|
||||
this.processingStages = Collections.emptyList();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public final List<? extends AstProcessingStage<?>> getProcessingStages() {
|
||||
return processingStages;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -5,10 +5,14 @@
|
||||
package net.sourceforge.pmd.lang;
|
||||
|
||||
import java.io.Writer;
|
||||
import java.util.List;
|
||||
|
||||
import net.sourceforge.pmd.annotation.Experimental;
|
||||
import net.sourceforge.pmd.lang.dfa.DFAGraphRule;
|
||||
import net.sourceforge.pmd.lang.ast.AstProcessingStage;
|
||||
import net.sourceforge.pmd.lang.rule.RuleViolationFactory;
|
||||
|
||||
|
||||
/**
|
||||
* Interface for obtaining the classes necessary for checking source files of a
|
||||
* specific language.
|
||||
@ -17,20 +21,21 @@ import net.sourceforge.pmd.lang.rule.RuleViolationFactory;
|
||||
*/
|
||||
public interface LanguageVersionHandler {
|
||||
|
||||
/**
|
||||
* Get the DataFlowHandler.
|
||||
*/
|
||||
DataFlowHandler getDataFlowHandler();
|
||||
|
||||
/**
|
||||
* Get the XPathHandler.
|
||||
*/
|
||||
XPathHandler getXPathHandler();
|
||||
|
||||
|
||||
/**
|
||||
* Get the RuleViolationFactory.
|
||||
* Returns the list of all supported optional processing stages.
|
||||
*
|
||||
* @return A list of all optional processing stages.
|
||||
*/
|
||||
RuleViolationFactory getRuleViolationFactory();
|
||||
@Experimental
|
||||
List<? extends AstProcessingStage<?>> getProcessingStages();
|
||||
|
||||
|
||||
/**
|
||||
* Get the default ParserOptions.
|
||||
@ -39,6 +44,7 @@ public interface LanguageVersionHandler {
|
||||
*/
|
||||
ParserOptions getDefaultParserOptions();
|
||||
|
||||
|
||||
/**
|
||||
* Get the Parser.
|
||||
*
|
||||
@ -46,46 +52,70 @@ public interface LanguageVersionHandler {
|
||||
*/
|
||||
Parser getParser(ParserOptions parserOptions);
|
||||
|
||||
|
||||
/**
|
||||
* Get the RuleViolationFactory.
|
||||
*/
|
||||
RuleViolationFactory getRuleViolationFactory();
|
||||
|
||||
|
||||
/**
|
||||
* Get the DumpFacade.
|
||||
*
|
||||
* @param writer The writer to dump to.
|
||||
*
|
||||
* @return VisitorStarter
|
||||
*/
|
||||
// TODO should we deprecate? Not much use to it.
|
||||
// Plus if it's not implemented, then it does nothing to the writer which is unexpected.
|
||||
VisitorStarter getDumpFacade(Writer writer, String prefix, boolean recurse);
|
||||
|
||||
|
||||
/**
|
||||
* Get the DataFlowHandler.
|
||||
*/
|
||||
@Deprecated
|
||||
DataFlowHandler getDataFlowHandler();
|
||||
|
||||
|
||||
/**
|
||||
* Get the DataFlowFacade.
|
||||
*
|
||||
* @return VisitorStarter
|
||||
*/
|
||||
@Deprecated
|
||||
VisitorStarter getDataFlowFacade();
|
||||
|
||||
/**
|
||||
* Get the SymbolFacade.
|
||||
*
|
||||
* @return VisitorStarter
|
||||
*/
|
||||
VisitorStarter getSymbolFacade();
|
||||
|
||||
/**
|
||||
* Get the SymbolFacade.
|
||||
*
|
||||
* @param classLoader
|
||||
* A ClassLoader to use for resolving Types.
|
||||
* @return VisitorStarter
|
||||
*/
|
||||
@Deprecated
|
||||
VisitorStarter getSymbolFacade();
|
||||
|
||||
|
||||
/**
|
||||
* Get the SymbolFacade.
|
||||
*
|
||||
* @param classLoader A ClassLoader to use for resolving Types.
|
||||
*
|
||||
* @return VisitorStarter
|
||||
*/
|
||||
@Deprecated
|
||||
VisitorStarter getSymbolFacade(ClassLoader classLoader);
|
||||
|
||||
|
||||
/**
|
||||
* Get the TypeResolutionFacade.
|
||||
*
|
||||
* @param classLoader
|
||||
* A ClassLoader to use for resolving Types.
|
||||
* @return VisitorStarter
|
||||
*/
|
||||
VisitorStarter getTypeResolutionFacade(ClassLoader classLoader);
|
||||
|
||||
/**
|
||||
* Get the DumpFacade.
|
||||
* @param classLoader A ClassLoader to use for resolving Types.
|
||||
*
|
||||
* @param writer
|
||||
* The writer to dump to.
|
||||
* @return VisitorStarter
|
||||
*/
|
||||
VisitorStarter getDumpFacade(Writer writer, String prefix, boolean recurse);
|
||||
@Deprecated
|
||||
VisitorStarter getTypeResolutionFacade(ClassLoader classLoader);
|
||||
|
||||
|
||||
/**
|
||||
@ -93,6 +123,7 @@ public interface LanguageVersionHandler {
|
||||
*
|
||||
* @return The visitor starter
|
||||
*/
|
||||
@Deprecated
|
||||
VisitorStarter getMultifileFacade();
|
||||
|
||||
|
||||
@ -104,8 +135,10 @@ public interface LanguageVersionHandler {
|
||||
*
|
||||
* @return The visitor starter
|
||||
*/
|
||||
@Deprecated
|
||||
VisitorStarter getQualifiedNameResolutionFacade(ClassLoader classLoader);
|
||||
|
||||
|
||||
@Deprecated
|
||||
DFAGraphRule getDFAGraphRule();
|
||||
}
|
||||
|
@ -48,6 +48,9 @@ public interface XPathHandler {
|
||||
/**
|
||||
* Get a Jaxen Navigator for this Language. May return <code>null</code> if
|
||||
* there is no Jaxen Navigation for this language.
|
||||
*
|
||||
* @deprecated PMD 7.0.0 will remove support for Jaxen
|
||||
*/
|
||||
@Deprecated
|
||||
Navigator getNavigator();
|
||||
}
|
||||
|
@ -0,0 +1,34 @@
|
||||
/**
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.lang.ast;
|
||||
|
||||
import net.sourceforge.pmd.annotation.Experimental;
|
||||
import net.sourceforge.pmd.lang.LanguageVersion;
|
||||
|
||||
|
||||
/**
|
||||
* Configuration relevant to e.g. an {@link AstProcessingStage}.
|
||||
*
|
||||
* @author Clément Fournier
|
||||
* @since 6.10.0
|
||||
*/
|
||||
@Experimental
|
||||
public interface AstAnalysisConfiguration {
|
||||
|
||||
|
||||
/**
|
||||
* Gets the classloader used for type resolution.
|
||||
*
|
||||
* @return The classloader.
|
||||
*/
|
||||
ClassLoader getTypeResolutionClassLoader();
|
||||
|
||||
|
||||
/**
|
||||
* Returns the language version used for this analysis.
|
||||
*/
|
||||
LanguageVersion getLanguageVersion();
|
||||
|
||||
}
|
@ -0,0 +1,110 @@
|
||||
/**
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.lang.ast;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import net.sourceforge.pmd.Rule;
|
||||
import net.sourceforge.pmd.RuleSets;
|
||||
import net.sourceforge.pmd.annotation.Experimental;
|
||||
import net.sourceforge.pmd.lang.LanguageVersionHandler;
|
||||
|
||||
// @formatter:off
|
||||
/**
|
||||
* Represents one of the stages applying on the AST
|
||||
* after parsing is done. Each of these stages implicitly
|
||||
* depends on the parser stage.
|
||||
*
|
||||
* <p>An analysis on a file goes through the following stages:
|
||||
* <ul>
|
||||
* <li> Parsing stage: taking the source and configuration, and returning an AST
|
||||
* <li> Language-specific AST visits: sequence of stages specific to each language.
|
||||
* Each stage performs side effects on the AST, e.g. to resolve such things as comments,
|
||||
* types, DFA graph, etc.
|
||||
* <li> Rulechain application: all rulechain rules are run on the final AST
|
||||
* <li> Rule application: other rules are run
|
||||
* </ul>
|
||||
*
|
||||
* <p>These steps are run on each file during the analysis, unless the cache entry of the file is up-to-date.
|
||||
* They're all run sequentially by the same thread. Rule application performs side-effects on the Report,
|
||||
* which is rendered after all files have been processed.
|
||||
*
|
||||
* <p>Parsing and rule[chain] application stages are considered special and are handled differently for now.
|
||||
* A {@link LanguageVersionHandler} is responsible for listing all available {@link AstProcessingStage}s
|
||||
* (see {@link LanguageVersionHandler#getProcessingStages()}). The actual set of stages that will get executed
|
||||
* for a run is the union of the dependencies of the rules in the run {@link RuleSets}.
|
||||
*
|
||||
* <p>Additional doc, to be moved elsewhere probably:
|
||||
* <p>PMD's execution goes through other more global stages (not sure about the exact order):
|
||||
* <ul>
|
||||
* <li> Rule loading: creates a {@link RuleSets} from the ruleset files
|
||||
* <li> Cache loading: loads the cache file for incremental analysis if any, creates the new cache
|
||||
* <li> Report creation: creates a report object for the rules to act on
|
||||
* <li> File collection: collects the files to analyse and dispatches them to worker threads.
|
||||
* Each file undergoes the steps described above.
|
||||
* <li> Report rendering
|
||||
* <li> Cache persisting
|
||||
* </ul>
|
||||
*
|
||||
*
|
||||
* @author Clément Fournier
|
||||
* @since 6.10.0
|
||||
*/
|
||||
// @formatter:on
|
||||
@Experimental
|
||||
public interface AstProcessingStage<T extends AstProcessingStage<T>> extends Comparable<T> {
|
||||
|
||||
|
||||
/**
|
||||
* Gets the stages on which this stage depends.
|
||||
* E.g. the type resolution stage may depend on the
|
||||
* qualified name resolution stage.
|
||||
*
|
||||
* <p>Returns an empty list if this stage only depends
|
||||
* on the parser stage.
|
||||
*/
|
||||
List<T> getDependencies();
|
||||
|
||||
|
||||
/**
|
||||
* Returns the name of this stage, used e.g. to display in a
|
||||
* benchmark report.
|
||||
*
|
||||
* @return The name of the stage.
|
||||
*/
|
||||
String getDisplayName();
|
||||
|
||||
|
||||
/**
|
||||
* Performs some side effects on the AST, e.g. to resolve something.
|
||||
*
|
||||
* @param rootNode Root of the tree
|
||||
* @param configuration Configuration
|
||||
*/
|
||||
void processAST(RootNode rootNode, AstAnalysisConfiguration configuration);
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if the given rule depends on this stage,
|
||||
* in which case, any ruleset containing that rule depends
|
||||
* on this stage too.
|
||||
*
|
||||
* @param rule Rule to test
|
||||
*
|
||||
* @return true if the given rule depends on this stage.
|
||||
*/
|
||||
// This can be customized for each step.
|
||||
// For now we use the Rule.isDfa() / Rule.isTypeRes()
|
||||
// In the future we can check an annotation.
|
||||
// If the rule is an XPath rule, then additional work
|
||||
// performed by the XPath analyser will be taken into account.
|
||||
|
||||
// This separation based on the type of rule means that the
|
||||
// method for dependency determination should probably be on the
|
||||
// Rule interface, but I don't know for now.
|
||||
@Experimental
|
||||
boolean ruleDependsOnThisStage(Rule rule);
|
||||
|
||||
}
|
@ -318,6 +318,7 @@ public abstract class AbstractRule extends AbstractPropertySource implements Rul
|
||||
@Override
|
||||
public void addRuleChainVisit(Class<? extends Node> nodeClass) {
|
||||
if (!nodeClass.getSimpleName().startsWith("AST")) {
|
||||
// Classes under the Comment hierarchy and stuff need to be refactored in the Java AST
|
||||
throw new IllegalArgumentException("Node class does not start with 'AST' prefix: " + nodeClass);
|
||||
}
|
||||
addRuleChainVisit(nodeClass.getSimpleName().substring("AST".length()));
|
||||
|
@ -61,7 +61,7 @@ public class DummyLanguageModule extends BaseLanguageModule {
|
||||
}
|
||||
}
|
||||
|
||||
public static class Handler extends AbstractLanguageVersionHandler {
|
||||
public static class Handler extends AbstractPmdLanguageVersionHandler {
|
||||
@Override
|
||||
public RuleViolationFactory getRuleViolationFactory() {
|
||||
return new RuleViolationFactory();
|
||||
|
@ -4,21 +4,21 @@
|
||||
|
||||
package net.sourceforge.pmd.lang.cpp;
|
||||
|
||||
import net.sourceforge.pmd.lang.AbstractLanguageVersionHandler;
|
||||
import net.sourceforge.pmd.lang.AbstractCpdLanguageVersionHandler;
|
||||
import net.sourceforge.pmd.lang.Parser;
|
||||
import net.sourceforge.pmd.lang.ParserOptions;
|
||||
import net.sourceforge.pmd.lang.rule.RuleViolationFactory;
|
||||
|
||||
/**
|
||||
* Implementation of LanguageVersionHandler for the C++ Language.
|
||||
*/
|
||||
public class CppHandler extends AbstractLanguageVersionHandler {
|
||||
public class CppHandler extends AbstractCpdLanguageVersionHandler {
|
||||
|
||||
@Override
|
||||
public RuleViolationFactory getRuleViolationFactory() {
|
||||
throw new UnsupportedOperationException("getRuleViolationFactory() is not supported for C++");
|
||||
protected String getLanguageName() {
|
||||
return "C++";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Parser getParser(ParserOptions parserOptions) {
|
||||
return new CppParser(parserOptions);
|
||||
|
@ -6,7 +6,7 @@ package net.sourceforge.pmd.lang.java;
|
||||
|
||||
import java.io.Writer;
|
||||
|
||||
import net.sourceforge.pmd.lang.AbstractLanguageVersionHandler;
|
||||
import net.sourceforge.pmd.lang.AbstractPmdLanguageVersionHandler;
|
||||
import net.sourceforge.pmd.lang.DataFlowHandler;
|
||||
import net.sourceforge.pmd.lang.LanguageRegistry;
|
||||
import net.sourceforge.pmd.lang.VisitorStarter;
|
||||
@ -40,7 +40,12 @@ import net.sf.saxon.sxpath.IndependentContext;
|
||||
*
|
||||
* @author pieter_van_raemdonck - Application Engineers NV/SA - www.ae.be
|
||||
*/
|
||||
public abstract class AbstractJavaHandler extends AbstractLanguageVersionHandler {
|
||||
public abstract class AbstractJavaHandler extends AbstractPmdLanguageVersionHandler {
|
||||
|
||||
protected AbstractJavaHandler() {
|
||||
super(JavaProcessingStage.class);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public DataFlowHandler getDataFlowHandler() {
|
||||
|
@ -0,0 +1,103 @@
|
||||
/**
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.lang.java;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import net.sourceforge.pmd.Rule;
|
||||
import net.sourceforge.pmd.lang.ast.RootNode;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit;
|
||||
import net.sourceforge.pmd.lang.java.dfa.DataFlowFacade;
|
||||
import net.sourceforge.pmd.lang.java.qname.QualifiedNameResolver;
|
||||
import net.sourceforge.pmd.lang.java.symboltable.SymbolFacade;
|
||||
import net.sourceforge.pmd.lang.java.typeresolution.TypeResolutionFacade;
|
||||
import net.sourceforge.pmd.lang.ast.AstAnalysisConfiguration;
|
||||
import net.sourceforge.pmd.lang.ast.AstProcessingStage;
|
||||
|
||||
|
||||
/**
|
||||
* Java processing stages.
|
||||
*
|
||||
* @author Clément Fournier
|
||||
* @since 6.10.0
|
||||
*/
|
||||
public enum JavaProcessingStage implements AstProcessingStage<JavaProcessingStage> {
|
||||
|
||||
/**
|
||||
* Qualified name resolution.
|
||||
*/
|
||||
QNAME_RESOLUTION("Qualified name resolution") {
|
||||
@Override
|
||||
public void processAST(RootNode rootNode, AstAnalysisConfiguration configuration) {
|
||||
new QualifiedNameResolver().initializeWith(configuration.getTypeResolutionClassLoader(), (ASTCompilationUnit) rootNode);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Symbol table analysis.
|
||||
*/
|
||||
SYMBOL_RESOLUTION("Symbol table") {
|
||||
@Override
|
||||
public void processAST(RootNode rootNode, AstAnalysisConfiguration configuration) {
|
||||
new SymbolFacade().initializeWith(configuration.getTypeResolutionClassLoader(), (ASTCompilationUnit) rootNode);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Type resolution, depends on QName resolution.
|
||||
*/
|
||||
TYPE_RESOLUTION("Type resolution", QNAME_RESOLUTION) {
|
||||
@Override
|
||||
public void processAST(RootNode rootNode, AstAnalysisConfiguration configuration) {
|
||||
new TypeResolutionFacade().initializeWith(configuration.getTypeResolutionClassLoader(), (ASTCompilationUnit) rootNode);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Data flow analysis.
|
||||
*/
|
||||
DFA("Data flow analysis") {
|
||||
@Override
|
||||
public void processAST(RootNode rootNode, AstAnalysisConfiguration configuration) {
|
||||
new DataFlowFacade().initializeWith(new JavaDataFlowHandler(), (ASTCompilationUnit) rootNode);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean ruleDependsOnThisStage(Rule rule) {
|
||||
return rule.isDfa();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
private final String displayName;
|
||||
private final List<JavaProcessingStage> dependencies;
|
||||
|
||||
|
||||
JavaProcessingStage(String displayName, JavaProcessingStage... dependencies) {
|
||||
this.displayName = displayName;
|
||||
this.dependencies = Collections.unmodifiableList(Arrays.asList(dependencies));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<JavaProcessingStage> getDependencies() {
|
||||
return dependencies;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getDisplayName() {
|
||||
return displayName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean ruleDependsOnThisStage(Rule rule) {
|
||||
// most stages are enabled by default in java
|
||||
return true;
|
||||
}
|
||||
}
|
@ -6,7 +6,7 @@ package net.sourceforge.pmd.lang.ecmascript;
|
||||
|
||||
import java.io.Writer;
|
||||
|
||||
import net.sourceforge.pmd.lang.AbstractLanguageVersionHandler;
|
||||
import net.sourceforge.pmd.lang.AbstractPmdLanguageVersionHandler;
|
||||
import net.sourceforge.pmd.lang.Parser;
|
||||
import net.sourceforge.pmd.lang.ParserOptions;
|
||||
import net.sourceforge.pmd.lang.VisitorStarter;
|
||||
@ -21,7 +21,7 @@ import net.sourceforge.pmd.lang.rule.RuleViolationFactory;
|
||||
/**
|
||||
* Implementation of LanguageVersionHandler for the ECMAScript Version 3.
|
||||
*/
|
||||
public class Ecmascript3Handler extends AbstractLanguageVersionHandler {
|
||||
public class Ecmascript3Handler extends AbstractPmdLanguageVersionHandler {
|
||||
|
||||
@Override
|
||||
public XPathHandler getXPathHandler() {
|
||||
|
@ -7,6 +7,7 @@ package net.sourceforge.pmd.lang.jsp;
|
||||
import java.io.Writer;
|
||||
|
||||
import net.sourceforge.pmd.lang.AbstractLanguageVersionHandler;
|
||||
import net.sourceforge.pmd.lang.AbstractPmdLanguageVersionHandler;
|
||||
import net.sourceforge.pmd.lang.Parser;
|
||||
import net.sourceforge.pmd.lang.ParserOptions;
|
||||
import net.sourceforge.pmd.lang.VisitorStarter;
|
||||
@ -23,7 +24,7 @@ import net.sourceforge.pmd.lang.rule.RuleViolationFactory;
|
||||
*
|
||||
* @author pieter_van_raemdonck - Application Engineers NV/SA - www.ae.be
|
||||
*/
|
||||
public class JspHandler extends AbstractLanguageVersionHandler {
|
||||
public class JspHandler extends AbstractPmdLanguageVersionHandler {
|
||||
|
||||
@Override
|
||||
public XPathHandler getXPathHandler() {
|
||||
|
@ -4,21 +4,22 @@
|
||||
|
||||
package net.sourceforge.pmd.lang.matlab;
|
||||
|
||||
import net.sourceforge.pmd.lang.AbstractLanguageVersionHandler;
|
||||
import net.sourceforge.pmd.lang.AbstractCpdLanguageVersionHandler;
|
||||
import net.sourceforge.pmd.lang.Parser;
|
||||
import net.sourceforge.pmd.lang.ParserOptions;
|
||||
import net.sourceforge.pmd.lang.rule.RuleViolationFactory;
|
||||
|
||||
|
||||
/**
|
||||
* Implementation of LanguageVersionHandler for the Matlab Language.
|
||||
*/
|
||||
public class MatlabHandler extends AbstractLanguageVersionHandler {
|
||||
public class MatlabHandler extends AbstractCpdLanguageVersionHandler {
|
||||
|
||||
@Override
|
||||
public RuleViolationFactory getRuleViolationFactory() {
|
||||
throw new UnsupportedOperationException("getRuleViolationFactory() is not supported for Matlab");
|
||||
protected String getLanguageName() {
|
||||
return "Matlab";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Parser getParser(ParserOptions parserOptions) {
|
||||
return new MatlabParser(parserOptions);
|
||||
|
@ -4,21 +4,22 @@
|
||||
|
||||
package net.sourceforge.pmd.lang.objectivec;
|
||||
|
||||
import net.sourceforge.pmd.lang.AbstractLanguageVersionHandler;
|
||||
import net.sourceforge.pmd.lang.AbstractCpdLanguageVersionHandler;
|
||||
import net.sourceforge.pmd.lang.Parser;
|
||||
import net.sourceforge.pmd.lang.ParserOptions;
|
||||
import net.sourceforge.pmd.lang.rule.RuleViolationFactory;
|
||||
|
||||
|
||||
/**
|
||||
* Implementation of LanguageVersionHandler for the Objective-C Language.
|
||||
*/
|
||||
public class ObjectiveCHandler extends AbstractLanguageVersionHandler {
|
||||
public class ObjectiveCHandler extends AbstractCpdLanguageVersionHandler {
|
||||
|
||||
@Override
|
||||
public RuleViolationFactory getRuleViolationFactory() {
|
||||
throw new UnsupportedOperationException("getRuleViolationFactory() is not supported for Objective-C");
|
||||
protected String getLanguageName() {
|
||||
return "Objective-C";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Parser getParser(ParserOptions parserOptions) {
|
||||
return new ObjectiveCParser(parserOptions);
|
||||
|
@ -6,7 +6,7 @@ package net.sourceforge.pmd.lang.plsql;
|
||||
|
||||
import java.io.Writer;
|
||||
|
||||
import net.sourceforge.pmd.lang.AbstractLanguageVersionHandler;
|
||||
import net.sourceforge.pmd.lang.AbstractPmdLanguageVersionHandler;
|
||||
import net.sourceforge.pmd.lang.DataFlowHandler;
|
||||
import net.sourceforge.pmd.lang.Parser;
|
||||
import net.sourceforge.pmd.lang.ParserOptions;
|
||||
@ -30,7 +30,12 @@ import net.sourceforge.pmd.lang.rule.RuleViolationFactory;
|
||||
*
|
||||
* @author sturton - PLDoc - pldoc.sourceforge.net
|
||||
*/
|
||||
public class PLSQLHandler extends AbstractLanguageVersionHandler {
|
||||
public class PLSQLHandler extends AbstractPmdLanguageVersionHandler {
|
||||
|
||||
|
||||
public PLSQLHandler() {
|
||||
super(PlsqlProcessingStage.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Parser getParser(ParserOptions parserOptions) {
|
||||
|
@ -0,0 +1,84 @@
|
||||
/**
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.lang.plsql;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import net.sourceforge.pmd.Rule;
|
||||
import net.sourceforge.pmd.lang.ast.RootNode;
|
||||
import net.sourceforge.pmd.lang.plsql.ast.ASTInput;
|
||||
import net.sourceforge.pmd.lang.plsql.dfa.DataFlowFacade;
|
||||
import net.sourceforge.pmd.lang.plsql.symboltable.SymbolFacade;
|
||||
import net.sourceforge.pmd.lang.ast.AstAnalysisConfiguration;
|
||||
import net.sourceforge.pmd.lang.ast.AstProcessingStage;
|
||||
|
||||
|
||||
/**
|
||||
* PL-SQL AST processing stages.
|
||||
*
|
||||
* @author Clément Fournier
|
||||
* @since 6.10.0
|
||||
*/
|
||||
public enum PlsqlProcessingStage implements AstProcessingStage<PlsqlProcessingStage> {
|
||||
|
||||
/**
|
||||
* Symbol table analysis.
|
||||
*/
|
||||
SYMBOL_RESOLUTION("Symbol table") {
|
||||
@Override
|
||||
public void processAST(RootNode rootNode, AstAnalysisConfiguration configuration) {
|
||||
new SymbolFacade().initializeWith((ASTInput) rootNode);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean ruleDependsOnThisStage(Rule rule) {
|
||||
return true;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Data flow analysis.
|
||||
*/
|
||||
DFA("Data flow analysis") {
|
||||
@Override
|
||||
public void processAST(RootNode rootNode, AstAnalysisConfiguration configuration) {
|
||||
new DataFlowFacade().initializeWith(new PLSQLDataFlowHandler(), (ASTInput) rootNode);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean ruleDependsOnThisStage(Rule rule) {
|
||||
return rule.isDfa();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
private final String displayName;
|
||||
private final List<PlsqlProcessingStage> dependencies;
|
||||
|
||||
|
||||
PlsqlProcessingStage(String displayName, PlsqlProcessingStage... dependencies) {
|
||||
this.displayName = displayName;
|
||||
this.dependencies = Collections.unmodifiableList(Arrays.asList(dependencies));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<PlsqlProcessingStage> getDependencies() {
|
||||
return dependencies;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getDisplayName() {
|
||||
return displayName;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -4,21 +4,23 @@
|
||||
|
||||
package net.sourceforge.pmd.lang.python;
|
||||
|
||||
import net.sourceforge.pmd.lang.AbstractLanguageVersionHandler;
|
||||
import net.sourceforge.pmd.lang.AbstractCpdLanguageVersionHandler;
|
||||
import net.sourceforge.pmd.lang.Parser;
|
||||
import net.sourceforge.pmd.lang.ParserOptions;
|
||||
import net.sourceforge.pmd.lang.rule.RuleViolationFactory;
|
||||
|
||||
|
||||
/**
|
||||
* Implementation of LanguageVersionHandler for the Python Language.
|
||||
*/
|
||||
public class PythonHandler extends AbstractLanguageVersionHandler {
|
||||
public class PythonHandler extends AbstractCpdLanguageVersionHandler {
|
||||
|
||||
|
||||
@Override
|
||||
public RuleViolationFactory getRuleViolationFactory() {
|
||||
throw new UnsupportedOperationException("getRuleViolationFactory() is not supported for Python");
|
||||
protected String getLanguageName() {
|
||||
return "Python";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Parser getParser(ParserOptions parserOptions) {
|
||||
return new PythonParser(parserOptions);
|
||||
|
@ -14,8 +14,8 @@ import java.util.Map;
|
||||
import net.sourceforge.pmd.Rule;
|
||||
import net.sourceforge.pmd.RuleContext;
|
||||
import net.sourceforge.pmd.RuleViolation;
|
||||
import net.sourceforge.pmd.lang.AbstractLanguageVersionHandler;
|
||||
import net.sourceforge.pmd.lang.AbstractParser;
|
||||
import net.sourceforge.pmd.lang.AbstractPmdLanguageVersionHandler;
|
||||
import net.sourceforge.pmd.lang.BaseLanguageModule;
|
||||
import net.sourceforge.pmd.lang.Parser;
|
||||
import net.sourceforge.pmd.lang.ParserOptions;
|
||||
@ -67,7 +67,7 @@ public class DummyLanguageModule extends BaseLanguageModule {
|
||||
}
|
||||
}
|
||||
|
||||
public static class Handler extends AbstractLanguageVersionHandler {
|
||||
public static class Handler extends AbstractPmdLanguageVersionHandler {
|
||||
@Override
|
||||
public RuleViolationFactory getRuleViolationFactory() {
|
||||
return new RuleViolationFactory();
|
||||
|
@ -6,7 +6,7 @@ package net.sourceforge.pmd.lang.vf;
|
||||
|
||||
import java.io.Writer;
|
||||
|
||||
import net.sourceforge.pmd.lang.AbstractLanguageVersionHandler;
|
||||
import net.sourceforge.pmd.lang.AbstractPmdLanguageVersionHandler;
|
||||
import net.sourceforge.pmd.lang.Parser;
|
||||
import net.sourceforge.pmd.lang.ParserOptions;
|
||||
import net.sourceforge.pmd.lang.VisitorStarter;
|
||||
@ -18,7 +18,7 @@ import net.sourceforge.pmd.lang.vf.ast.DumpFacade;
|
||||
import net.sourceforge.pmd.lang.vf.ast.VfNode;
|
||||
import net.sourceforge.pmd.lang.vf.rule.VfRuleViolationFactory;
|
||||
|
||||
public class VfHandler extends AbstractLanguageVersionHandler {
|
||||
public class VfHandler extends AbstractPmdLanguageVersionHandler {
|
||||
|
||||
@Override
|
||||
public XPathHandler getXPathHandler() {
|
||||
|
@ -6,7 +6,7 @@ package net.sourceforge.pmd.lang.vm;
|
||||
|
||||
import java.io.Writer;
|
||||
|
||||
import net.sourceforge.pmd.lang.AbstractLanguageVersionHandler;
|
||||
import net.sourceforge.pmd.lang.AbstractPmdLanguageVersionHandler;
|
||||
import net.sourceforge.pmd.lang.Parser;
|
||||
import net.sourceforge.pmd.lang.ParserOptions;
|
||||
import net.sourceforge.pmd.lang.VisitorStarter;
|
||||
@ -21,7 +21,7 @@ import net.sourceforge.pmd.lang.vm.rule.VmRuleViolationFactory;
|
||||
* Implementation of LanguageVersionHandler for the VM parser.
|
||||
*
|
||||
*/
|
||||
public class VmHandler extends AbstractLanguageVersionHandler {
|
||||
public class VmHandler extends AbstractPmdLanguageVersionHandler {
|
||||
|
||||
@Override
|
||||
public XPathHandler getXPathHandler() {
|
||||
|
@ -6,7 +6,7 @@ package net.sourceforge.pmd.lang.xml;
|
||||
|
||||
import java.io.Writer;
|
||||
|
||||
import net.sourceforge.pmd.lang.AbstractLanguageVersionHandler;
|
||||
import net.sourceforge.pmd.lang.AbstractPmdLanguageVersionHandler;
|
||||
import net.sourceforge.pmd.lang.Parser;
|
||||
import net.sourceforge.pmd.lang.ParserOptions;
|
||||
import net.sourceforge.pmd.lang.VisitorStarter;
|
||||
@ -21,7 +21,7 @@ import net.sourceforge.pmd.lang.xml.rule.XmlRuleViolationFactory;
|
||||
/**
|
||||
* Implementation of LanguageVersionHandler for the XML.
|
||||
*/
|
||||
public class XmlHandler extends AbstractLanguageVersionHandler {
|
||||
public class XmlHandler extends AbstractPmdLanguageVersionHandler {
|
||||
|
||||
@Override
|
||||
public XPathHandler getXPathHandler() {
|
||||
|
Reference in New Issue
Block a user