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.*;
16 import net.sourceforge.pmd.lang.ast.Node;
17 import net.sourceforge.pmd.lang.ast.ParseException;
18 import net.sourceforge.pmd.lang.xpath.Initializer;
19
20 import org.apache.commons.io.IOUtils;
21
22 public class SourceCodeProcessor {
23
24 private final PMDConfiguration configuration;
25
26 public SourceCodeProcessor(PMDConfiguration configuration) {
27 this.configuration = configuration;
28 }
29
30
31
32
33
34
35
36
37
38
39
40
41 public void processSourceCode(InputStream sourceCode, RuleSets ruleSets, RuleContext ctx) throws PMDException {
42 try {
43 processSourceCode(new InputStreamReader(sourceCode, configuration.getSourceEncoding()), ruleSets, ctx);
44 } catch (UnsupportedEncodingException uee) {
45 throw new PMDException("Unsupported encoding exception: " + uee.getMessage());
46 }
47 }
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66 public void processSourceCode(Reader sourceCode, RuleSets ruleSets, RuleContext ctx) throws PMDException {
67 determineLanguage(ctx);
68
69
70 Initializer.initialize();
71
72
73 if (ruleSets.applies(ctx.getSourceCodeFile())) {
74
75 try {
76 processSource(sourceCode, ruleSets,ctx);
77
78 } catch (ParseException pe) {
79 throw new PMDException("Error while parsing " + ctx.getSourceCodeFilename(), pe);
80 } catch (Exception e) {
81 throw new PMDException("Error while processing " + ctx.getSourceCodeFilename(), e);
82 } finally {
83 IOUtils.closeQuietly(sourceCode);
84 }
85 }
86 }
87
88
89 private Node parse(RuleContext ctx, Reader sourceCode, Parser parser) {
90 long start = System.nanoTime();
91 Node rootNode = parser.parse(ctx.getSourceCodeFilename(), sourceCode);
92 ctx.getReport().suppress(parser.getSuppressMap());
93 long end = System.nanoTime();
94 Benchmarker.mark(Benchmark.Parser, end - start, 0);
95 return rootNode;
96 }
97
98 private void symbolFacade(Node rootNode, LanguageVersionHandler languageVersionHandler) {
99 long start = System.nanoTime();
100 languageVersionHandler.getSymbolFacade(configuration.getClassLoader()).start(rootNode);
101 long end = System.nanoTime();
102 Benchmarker.mark(Benchmark.SymbolTable, end - start, 0);
103 }
104
105
106
107
108
109
110
111
112 private void usesDFA(LanguageVersion languageVersion, Node rootNode, RuleSets ruleSets, Language language ) {
113
114 if (ruleSets.usesDFA(language)) {
115 long start = System.nanoTime();
116 VisitorStarter dataFlowFacade = languageVersion.getLanguageVersionHandler().getDataFlowFacade();
117 dataFlowFacade.start(rootNode);
118 long end = System.nanoTime();
119 Benchmarker.mark(Benchmark.DFA, end - start, 0);
120 }
121 }
122
123 private void usesTypeResolution(LanguageVersion languageVersion, Node rootNode, RuleSets ruleSets, Language language) {
124
125 if (ruleSets.usesTypeResolution(language)) {
126 long start = System.nanoTime();
127 languageVersion.getLanguageVersionHandler().getTypeResolutionFacade(configuration.getClassLoader()).start(rootNode);
128 long end = System.nanoTime();
129 Benchmarker.mark(Benchmark.TypeResolution, end - start, 0);
130 }
131 }
132
133 private void processSource(Reader sourceCode, RuleSets ruleSets, RuleContext ctx) {
134 LanguageVersion languageVersion = ctx.getLanguageVersion();
135 LanguageVersionHandler languageVersionHandler = languageVersion.getLanguageVersionHandler();
136 Parser parser = PMD.parserFor(languageVersion, configuration);
137
138 Node rootNode = parse(ctx, sourceCode, parser);
139 symbolFacade(rootNode, languageVersionHandler);
140 Language language = languageVersion.getLanguage();
141 usesDFA(languageVersion, rootNode, ruleSets, language);
142 usesTypeResolution(languageVersion, rootNode, ruleSets,language);
143
144 List<Node> acus = new ArrayList<Node>();
145 acus.add(rootNode);
146 ruleSets.apply(acus, ctx, language);
147 }
148
149
150
151 private void determineLanguage(RuleContext ctx) {
152
153 if (ctx.getLanguageVersion() == null) {
154 LanguageVersion languageVersion = configuration.getLanguageVersionOfFile(ctx.getSourceCodeFilename());
155 ctx.setLanguageVersion(languageVersion);
156 }
157 }
158 }