SourceCodeProcessor xref

View Javadoc
1 /**
2  * BSD-style license; for more info see http://pmd.sourceforge.net/license.html 
3  */
4 package net.sourceforge.pmd;
5 
6 import java.io.InputStream;
7 import java.io.InputStreamReader;
8 import java.io.Reader;
9 import java.io.UnsupportedEncodingException;
10 import java.util.ArrayList;
11 import java.util.List;
12 
13 import net.sourceforge.pmd.benchmark.Benchmark;
14 import net.sourceforge.pmd.benchmark.Benchmarker;
15 import net.sourceforge.pmd.lang.Language;
16 import net.sourceforge.pmd.lang.LanguageVersion;
17 import net.sourceforge.pmd.lang.LanguageVersionHandler;
18 import net.sourceforge.pmd.lang.Parser;
19 import net.sourceforge.pmd.lang.VisitorStarter;
20 import net.sourceforge.pmd.lang.ast.Node;
21 import net.sourceforge.pmd.lang.ast.ParseException;
22 import net.sourceforge.pmd.lang.xpath.Initializer;
23 
24 import org.apache.commons.io.IOUtils;
25 
26 public class SourceCodeProcessor {
27 
28 private final PMDConfiguration configuration;
29 
30 public SourceCodeProcessor(PMDConfiguration configuration) {
31 	this.configuration = configuration;
32 }
33 
34 
35 /**
36  * Processes the input stream against a rule set using the given input encoding.
37  *
38  * @param sourceCode The InputStream to analyze.
39  * @param ruleSets The collection of rules to process against the file.
40  * @param ctx The context in which PMD is operating.
41  * @throws PMDException if the input encoding is unsupported, the input stream could
42  * not be parsed, or other error is encountered.
43  * @see #processSourceCode(Reader, RuleSets, RuleContext)
44  */
45 public void processSourceCode(InputStream sourceCode, RuleSets ruleSets, RuleContext ctx) throws PMDException {
46 		try {
47 		 processSourceCode(new InputStreamReader(sourceCode, configuration.getSourceEncoding()), ruleSets, ctx);
48 		} catch (UnsupportedEncodingException uee) {
49 		 throw new PMDException("Unsupported encoding exception: " + uee.getMessage());
50 		}
51 }
52 
53 
54 /**
55  * Processes the input stream against a rule set using the given input encoding.
56  * If the LanguageVersion is <code>null</code> on the RuleContext, it will
57  * be automatically determined. Any code which wishes to process files for
58  * different Languages, will need to be sure to either properly set the
59  * Language on the RuleContext, or set it to <code>null</code> first.
60  *
61  * @see RuleContext#setLanguageVersion(LanguageVersion)
62  * @see PMDConfiguration#getLanguageVersionOfFile(String)
63  *
64  * @param sourceCode The Reader to analyze.
65  * @param ruleSets The collection of rules to process against the file.
66  * @param ctx The context in which PMD is operating.
67  * @throws PMDException if the input encoding is unsupported, the input stream could
68  * not be parsed, or other error is encountered.
69  */
70 public void processSourceCode(Reader sourceCode, RuleSets ruleSets, RuleContext ctx) throws PMDException {
71 	determineLanguage(ctx);
72 
73 		// make sure custom XPath functions are initialized
74 		Initializer.initialize();
75 
76 	 // Coarse check to see if any RuleSet applies to file, will need to do a finer RuleSet specific check later
77 		 if (ruleSets.applies(ctx.getSourceCodeFile())) {
78 
79 		try {
80 			processSource(sourceCode, ruleSets,ctx);
81 
82 		} catch (ParseException pe) {
83 		 throw new PMDException("Error while parsing " + ctx.getSourceCodeFilename(), pe);
84 		} catch (Exception e) {
85 		 throw new PMDException("Error while processing " + ctx.getSourceCodeFilename(), e);
86 		} finally {
87 		 IOUtils.closeQuietly(sourceCode);
88 		}
89 		}
90 }
91 
92 
93 private Node parse(RuleContext ctx, Reader sourceCode, Parser parser) {
94 		long start = System.nanoTime();
95 		Node rootNode = parser.parse(ctx.getSourceCodeFilename(), sourceCode);
96 		ctx.getReport().suppress(parser.getSuppressMap());
97 		long end = System.nanoTime(); 	
98 		Benchmarker.mark(Benchmark.Parser, end - start, 0);
99 		return rootNode;
100 }
101 
102 private void symbolFacade(Node rootNode, LanguageVersionHandler languageVersionHandler) {
103 	long start = System.nanoTime();
104 		languageVersionHandler.getSymbolFacade().start(rootNode);
105 		long end = System.nanoTime();
106 		Benchmarker.mark(Benchmark.SymbolTable, end - start, 0);
107 }
108 
109 // private ParserOptions getParserOptions(final LanguageVersionHandler languageVersionHandler) {
110 //		// TODO Handle Rules having different parser options.
111 //		ParserOptions parserOptions = languageVersionHandler.getDefaultParserOptions();
112 //		parserOptions.setSuppressMarker(configuration.getSuppressMarker());
113 //		return parserOptions;
114 // }
115 
116 private void usesDFA(LanguageVersion languageVersion, Node rootNode, RuleSets ruleSets, Language language ) {
117 
118 		if (ruleSets.usesDFA(language)) {
119 		 long start = System.nanoTime();
120 		 VisitorStarter dataFlowFacade = languageVersion.getLanguageVersionHandler().getDataFlowFacade();
121 		 dataFlowFacade.start(rootNode);
122 		 long end = System.nanoTime();
123 		 Benchmarker.mark(Benchmark.DFA, end - start, 0);
124 		}
125 }
126 
127 private void usesTypeResolution(LanguageVersion languageVersion, Node rootNode, RuleSets ruleSets, Language language) {
128 	
129 		if (ruleSets.usesTypeResolution(language)) {
130 		 long start = System.nanoTime();
131 		 languageVersion.getLanguageVersionHandler().getTypeResolutionFacade(configuration.getClassLoader()).start(rootNode);
132 		 long end = System.nanoTime();
133 		 Benchmarker.mark(Benchmark.TypeResolution, end - start, 0);
134 		}
135 }
136 
137 private void processSource(Reader sourceCode, RuleSets ruleSets, RuleContext ctx) {
138 		LanguageVersion languageVersion = ctx.getLanguageVersion();
139 		LanguageVersionHandler languageVersionHandler = languageVersion.getLanguageVersionHandler();		
140 		Parser parser = PMD.parserFor(languageVersion, configuration);
141 		
142 		Node rootNode = parse(ctx, sourceCode, parser);
143 		symbolFacade(rootNode, languageVersionHandler);
144 		Language language = languageVersion.getLanguage();
145 		usesDFA(languageVersion, rootNode, ruleSets, language);
146 		usesTypeResolution(languageVersion, rootNode, ruleSets,language);
147 		
148 		List<Node> acus = new ArrayList<Node>();
149 		acus.add(rootNode);
150 		ruleSets.apply(acus, ctx, language);		
151 	}
152 
153 
154 
155 	private void determineLanguage(RuleContext ctx) {
156 		// If LanguageVersion of the source file is not known, make a determination
157 		if (ctx.getLanguageVersion() == null) {
158 		 LanguageVersion languageVersion = configuration.getLanguageVersionOfFile(ctx.getSourceCodeFilename());
159 		 ctx.setLanguageVersion(languageVersion);
160 		}
161 }
162 }

AltStyle によって変換されたページ (->オリジナル) /