1
2
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
37
38
39
40
41
42
43
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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70 public void processSourceCode(Reader sourceCode, RuleSets ruleSets, RuleContext ctx) throws PMDException {
71 determineLanguage(ctx);
72
73
74 Initializer.initialize();
75
76
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(configuration.getClassLoader()).start(rootNode);
105 long end = System.nanoTime();
106 Benchmarker.mark(Benchmark.SymbolTable, end - start, 0);
107 }
108
109
110
111
112
113
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
157 if (ctx.getLanguageVersion() == null) {
158 LanguageVersion languageVersion = configuration.getLanguageVersionOfFile(ctx.getSourceCodeFilename());
159 ctx.setLanguageVersion(languageVersion);
160 }
161 }
162 }