OLD | NEW |
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 /// Command line tool to run the checker on a Dart program. | 5 /// Command line tool to run the checker on a Dart program. |
6 library dev_compiler.devc; | 6 library dev_compiler.devc; |
7 | 7 |
8 import 'dart:async'; | 8 import 'dart:async'; |
9 import 'dart:convert'; | 9 import 'dart:convert'; |
10 import 'dart:io'; | 10 import 'dart:io'; |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
58 resolver = options.useMockSdk | 58 resolver = options.useMockSdk |
59 ? new TypeResolver.fromMock(mockSdkSources, options) | 59 ? new TypeResolver.fromMock(mockSdkSources, options) |
60 : new TypeResolver.fromDir(options.dartSdkPath, options); | 60 : new TypeResolver.fromDir(options.dartSdkPath, options); |
61 } | 61 } |
62 | 62 |
63 if (reporter == null) { | 63 if (reporter == null) { |
64 reporter = options.dumpInfo | 64 reporter = options.dumpInfo |
65 ? new SummaryReporter() | 65 ? new SummaryReporter() |
66 : new LogReporter(options.useColors); | 66 : new LogReporter(options.useColors); |
67 } | 67 } |
68 var graph = new SourceGraph(resolver.context, options); | 68 var graph = new SourceGraph(resolver.context, reporter); |
69 var rules = new RestrictedRules(resolver.context.typeProvider, reporter, | 69 var rules = new RestrictedRules(resolver.context.typeProvider, reporter, |
70 options: options); | 70 options: options); |
71 var checker = new CodeChecker(rules, reporter, options); | 71 var checker = new CodeChecker(rules, reporter, options); |
72 var inputFile = options.entryPointFile; | 72 var inputFile = options.entryPointFile; |
73 var uri = inputFile.startsWith('dart:') || inputFile.startsWith('package:') | 73 var uri = inputFile.startsWith('dart:') || inputFile.startsWith('package:') |
74 ? Uri.parse(inputFile) | 74 ? Uri.parse(inputFile) |
75 : new Uri.file(path.absolute(inputFile)); | 75 : new Uri.file(path.absolute(inputFile)); |
76 var entryNode = graph.nodeFromUri(uri); | 76 var entryNode = graph.nodeFromUri(uri); |
77 | 77 |
78 var outputDir = options.outputDir; | 78 var outputDir = options.outputDir; |
(...skipping 12 matching lines...) Expand all Loading... |
91 } | 91 } |
92 | 92 |
93 Compiler._(this._options, this._resolver, this._reporter, this._rules, | 93 Compiler._(this._options, this._resolver, this._reporter, this._rules, |
94 this._checker, this._graph, this._entryNode, this._generators); | 94 this._checker, this._graph, this._entryNode, this._generators); |
95 | 95 |
96 bool _buildSource(SourceNode node) { | 96 bool _buildSource(SourceNode node) { |
97 if (node is HtmlSourceNode) { | 97 if (node is HtmlSourceNode) { |
98 _buildHtmlFile(node); | 98 _buildHtmlFile(node); |
99 } else if (node is DartSourceNode) { | 99 } else if (node is DartSourceNode) { |
100 _buildDartLibrary(node); | 100 _buildDartLibrary(node); |
101 } else if (node is JavaScriptSourceNode) { | 101 } else if (node is ResourceSourceNode) { |
102 _buildJavaScriptFile(node); | 102 _buildResourceFile(node); |
103 } else { | 103 } else { |
104 assert(false); // should not get a build request on PartSourceNode | 104 assert(false); // should not get a build request on PartSourceNode |
105 } | 105 } |
106 | 106 |
107 // TODO(sigmund): don't always return true. Use summarization to better | 107 // TODO(sigmund): don't always return true. Use summarization to better |
108 // determine when rebuilding is needed. | 108 // determine when rebuilding is needed. |
109 return true; | 109 return true; |
110 } | 110 } |
111 | 111 |
112 void _buildHtmlFile(HtmlSourceNode node) { | 112 void _buildHtmlFile(HtmlSourceNode node) { |
113 if (_options.outputDir == null) return; | 113 if (_options.outputDir == null) return; |
| 114 var uri = node.source.uri; |
| 115 _reporter.enterHtml(uri); |
114 var output = generateEntryHtml(node, _options); | 116 var output = generateEntryHtml(node, _options); |
115 if (output == null) { | 117 if (output == null) { |
116 _failure = true; | 118 _failure = true; |
117 return; | 119 return; |
118 } | 120 } |
| 121 _reporter.leaveHtml(); |
119 var filename = path.basename(node.uri.path); | 122 var filename = path.basename(node.uri.path); |
120 String outputFile = path.join(_options.outputDir, filename); | 123 String outputFile = path.join(_options.outputDir, filename); |
121 new File(outputFile).writeAsStringSync(output); | 124 new File(outputFile).writeAsStringSync(output); |
122 | 125 |
123 if (_options.outputDart) return; | 126 if (_options.outputDart) return; |
124 } | 127 } |
125 | 128 |
126 void _buildJavaScriptFile(JavaScriptSourceNode node) { | 129 void _buildResourceFile(ResourceSourceNode node) { |
127 // JavaScriptSourceNodes are pieces of the dev_compiler runtime which are | 130 // ResourceSourceNodes are pieces of the dev_compiler runtime which are |
128 // dependencies added for js codegen. | 131 // dependencies added for js codegen. |
129 if (_options.outputDir == null || _options.outputDart) return; | 132 if (_options.outputDir == null || _options.outputDart) return; |
130 assert(node.uri.scheme == 'package'); | 133 assert(node.uri.scheme == 'package'); |
131 var filepath = path.join(_options.outputDir, node.uri.path); | 134 var filepath = path.join(_options.outputDir, node.uri.path); |
132 var dir = path.dirname(filepath); | 135 var dir = path.dirname(filepath); |
133 new Directory(dir).createSync(recursive: true); | 136 new Directory(dir).createSync(recursive: true); |
134 new File(filepath).writeAsStringSync(node.source.contents.data); | 137 new File(filepath).writeAsStringSync(node.source.contents.data); |
135 } | 138 } |
136 | 139 |
137 bool _isEntry(DartSourceNode node) { | 140 bool _isEntry(DartSourceNode node) { |
138 if (_entryNode is DartSourceNode) return _entryNode == node; | 141 if (_entryNode is DartSourceNode) return _entryNode == node; |
139 return (_entryNode as HtmlSourceNode).scripts.contains(node); | 142 return (_entryNode as HtmlSourceNode).scripts.contains(node); |
140 } | 143 } |
141 | 144 |
142 void _buildDartLibrary(DartSourceNode node) { | 145 void _buildDartLibrary(DartSourceNode node) { |
143 var source = node.source; | 146 var source = node.source; |
144 // TODO(sigmund): find out from analyzer team if there is a better way | 147 // TODO(sigmund): find out from analyzer team if there is a better way |
145 _resolver.context.applyChanges(new ChangeSet()..changedSource(source)); | 148 _resolver.context.applyChanges(new ChangeSet()..changedSource(source)); |
146 var entryUnit = _resolver.context.resolveCompilationUnit2(source, source); | 149 var entryUnit = _resolver.context.resolveCompilationUnit2(source, source); |
147 var lib = entryUnit.element.enclosingElement; | 150 var lib = entryUnit.element.enclosingElement; |
148 if (!_options.checkSdk && lib.isInSdk) return; | 151 if (!_options.checkSdk && lib.isInSdk) return; |
149 var current = node.info; | 152 var current = node.info; |
150 if (current != null) { | 153 if (current != null) { |
151 assert(current.library == lib); | 154 assert(current.library == lib); |
152 } else { | 155 } else { |
153 node.info = current = new LibraryInfo(lib, _isEntry(node)); | 156 node.info = current = new LibraryInfo(lib, _isEntry(node)); |
154 } | 157 } |
155 _reporter.enterLibrary(current); | 158 _reporter.enterLibrary(source.uri); |
156 _libraries.add(current); | 159 _libraries.add(current); |
157 _rules.currentLibraryInfo = current; | 160 _rules.currentLibraryInfo = current; |
158 | 161 |
159 var units = [entryUnit] | 162 var units = [entryUnit] |
160 ..addAll(node.parts.map( | 163 ..addAll(node.parts.map( |
161 (p) => _resolver.context.resolveCompilationUnit2(p.source, source))); | 164 (p) => _resolver.context.resolveCompilationUnit2(p.source, source))); |
162 bool failureInLib = false; | 165 bool failureInLib = false; |
163 for (var unit in units) { | 166 for (var unit in units) { |
164 var unitSource = unit.element.source; | 167 var unitSource = unit.element.source; |
165 _reporter.enterSource(unitSource); | 168 _reporter.enterSource(unitSource); |
(...skipping 15 matching lines...) Expand all Loading... |
181 | 184 |
182 CheckerResults run() { | 185 CheckerResults run() { |
183 var clock = new Stopwatch()..start(); | 186 var clock = new Stopwatch()..start(); |
184 | 187 |
185 // TODO(sigmund): we are missing a couple failures here. The | 188 // TODO(sigmund): we are missing a couple failures here. The |
186 // dependendency_graph now detects broken imports or unsupported features | 189 // dependendency_graph now detects broken imports or unsupported features |
187 // like more than one script tag (see .severe messages in | 190 // like more than one script tag (see .severe messages in |
188 // dependency_graph.dart). Such failures should be reported back | 191 // dependency_graph.dart). Such failures should be reported back |
189 // here so we can mark failure=true in the CheckerResutls. | 192 // here so we can mark failure=true in the CheckerResutls. |
190 rebuild(_entryNode, _graph, _buildSource); | 193 rebuild(_entryNode, _graph, _buildSource); |
191 if (_options.dumpInfo && _reporter is SummaryReporter) { | 194 _dumpInfoIfRequested(); |
192 var result = (_reporter as SummaryReporter).result; | |
193 print(summaryToString(result)); | |
194 if (_options.dumpInfoFile != null) { | |
195 new File(_options.dumpInfoFile) | |
196 .writeAsStringSync(JSON.encode(result.toJsonMap())); | |
197 } | |
198 } | |
199 clock.stop(); | 195 clock.stop(); |
200 if (_options.serverMode) { | 196 if (_options.serverMode) { |
201 var time = (clock.elapsedMilliseconds / 1000).toStringAsFixed(2); | 197 var time = (clock.elapsedMilliseconds / 1000).toStringAsFixed(2); |
202 print('Compiled ${_libraries.length} libraries in ${time} s\n'); | 198 print('Compiled ${_libraries.length} libraries in ${time} s\n'); |
203 } | 199 } |
204 return new CheckerResults( | 200 return new CheckerResults( |
205 _libraries, _rules, _failure || _options.forceCompile); | 201 _libraries, _rules, _failure || _options.forceCompile); |
206 } | 202 } |
207 | 203 |
208 void _runAgain() { | 204 void _runAgain() { |
209 var clock = new Stopwatch()..start(); | 205 var clock = new Stopwatch()..start(); |
210 if (_reporter is SummaryReporter) (_reporter as SummaryReporter).clear(); | |
211 _libraries = <LibraryInfo>[]; | 206 _libraries = <LibraryInfo>[]; |
212 int changed = 0; | 207 int changed = 0; |
213 | 208 |
214 // TODO(sigmund): propagate failures here (see TODO in run). | 209 // TODO(sigmund): propagate failures here (see TODO in run). |
215 rebuild(_entryNode, _graph, (n) { | 210 rebuild(_entryNode, _graph, (n) { |
216 changed++; | 211 changed++; |
217 return _buildSource(n); | 212 return _buildSource(n); |
218 }); | 213 }); |
219 if (_reporter is SummaryReporter) { | |
220 print(summaryToString((_reporter as SummaryReporter).result)); | |
221 } | |
222 clock.stop(); | 214 clock.stop(); |
| 215 if (changed > 0) _dumpInfoIfRequested(); |
223 var time = (clock.elapsedMilliseconds / 1000).toStringAsFixed(2); | 216 var time = (clock.elapsedMilliseconds / 1000).toStringAsFixed(2); |
224 print("Compiled ${changed} libraries in ${time} s\n"); | 217 print("Compiled ${changed} libraries in ${time} s\n"); |
225 } | 218 } |
| 219 |
| 220 _dumpInfoIfRequested() { |
| 221 if (!_options.dumpInfo || _reporter is! SummaryReporter) return; |
| 222 var result = (_reporter as SummaryReporter).result; |
| 223 if (!_options.serverMode) print(summaryToString(result)); |
| 224 var filepath = _options.serverMode |
| 225 ? path.join(_options.outputDir, 'messages.json') |
| 226 : _options.dumpInfoFile; |
| 227 if (filepath == null) return; |
| 228 new File(filepath).writeAsStringSync(JSON.encode(result.toJsonMap())); |
| 229 } |
226 } | 230 } |
227 | 231 |
228 class CompilerServer { | 232 class CompilerServer { |
229 final Compiler compiler; | 233 final Compiler compiler; |
230 final String outDir; | 234 final String outDir; |
231 final int port; | 235 final int port; |
232 final String _entryPath; | 236 final String _entryPath; |
233 | 237 |
234 factory CompilerServer(CompilerOptions options) { | 238 factory CompilerServer(CompilerOptions options) { |
235 var entryPath = path.basename(options.entryPointFile); | 239 var entryPath = path.basename(options.entryPointFile); |
(...skipping 27 matching lines...) Expand all Loading... |
263 } | 267 } |
264 | 268 |
265 rebuildIfNeeded(shelf.Request request) { | 269 rebuildIfNeeded(shelf.Request request) { |
266 var filepath = request.url.path; | 270 var filepath = request.url.path; |
267 if (filepath == '/$_entryPath' || filepath == '/') compiler._runAgain(); | 271 if (filepath == '/$_entryPath' || filepath == '/') compiler._runAgain(); |
268 } | 272 } |
269 } | 273 } |
270 | 274 |
271 final _log = new Logger('dev_compiler'); | 275 final _log = new Logger('dev_compiler'); |
272 final _earlyErrorResult = new CheckerResults(const [], null, true); | 276 final _earlyErrorResult = new CheckerResults(const [], null, true); |
OLD | NEW |