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 /// Tracks the shape of the import/export graph and dependencies between files. | 5 /// Tracks the shape of the import/export graph and dependencies between files. |
6 library dev_compiler.src.dependency_graph; | 6 library dev_compiler.src.dependency_graph; |
7 | 7 |
8 import 'dart:collection' show HashSet, HashMap; | 8 import 'dart:collection' show HashSet, HashMap; |
9 | 9 |
10 import 'package:analyzer/analyzer.dart' show parseDirectives; | 10 import 'package:analyzer/analyzer.dart' show parseDirectives; |
(...skipping 14 matching lines...) Expand all Loading... |
25 import 'package:analyzer/src/generated/source.dart' show Source, SourceKind; | 25 import 'package:analyzer/src/generated/source.dart' show Source, SourceKind; |
26 import 'package:html/dom.dart' show Document, Node, Element; | 26 import 'package:html/dom.dart' show Document, Node, Element; |
27 import 'package:html/parser.dart' as html; | 27 import 'package:html/parser.dart' as html; |
28 import 'package:logging/logging.dart' show Logger, Level; | 28 import 'package:logging/logging.dart' show Logger, Level; |
29 import 'package:path/path.dart' as path; | 29 import 'package:path/path.dart' as path; |
30 | 30 |
31 import '../compiler.dart' show defaultRuntimeFiles; | 31 import '../compiler.dart' show defaultRuntimeFiles; |
32 import '../info.dart'; | 32 import '../info.dart'; |
33 import '../options.dart'; | 33 import '../options.dart'; |
34 import '../report.dart'; | 34 import '../report.dart'; |
| 35 import '../report/html_reporter.dart'; |
35 | 36 |
36 /// Holds references to all source nodes in the import graph. This is mainly | 37 /// Holds references to all source nodes in the import graph. This is mainly |
37 /// used as a level of indirection to ensure that each source has a canonical | 38 /// used as a level of indirection to ensure that each source has a canonical |
38 /// representation. | 39 /// representation. |
39 class SourceGraph { | 40 class SourceGraph { |
40 /// All nodes in the source graph. Used to get a canonical representation for | 41 /// All nodes in the source graph. Used to get a canonical representation for |
41 /// any node. | 42 /// any node. |
42 final Map<Uri, SourceNode> nodes = {}; | 43 final Map<Uri, SourceNode> nodes = {}; |
43 | 44 |
44 /// Resources included by default on any application. | 45 /// Resources included by default on any application. |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
139 int newStamp = _source.exists() ? _source.modificationStamp : -1; | 140 int newStamp = _source.exists() ? _source.modificationStamp : -1; |
140 if (newStamp > _lastStamp || newStamp == -1 && _lastStamp != -1) { | 141 if (newStamp > _lastStamp || newStamp == -1 && _lastStamp != -1) { |
141 // If the timestamp changed, read the file from disk and cache it. | 142 // If the timestamp changed, read the file from disk and cache it. |
142 // We don't want the source text to change during compilation. | 143 // We don't want the source text to change during compilation. |
143 saveUpdatedContents(); | 144 saveUpdatedContents(); |
144 _lastStamp = newStamp; | 145 _lastStamp = newStamp; |
145 needsRebuild = true; | 146 needsRebuild = true; |
146 } | 147 } |
147 } | 148 } |
148 | 149 |
| 150 void clearSummary() {} |
| 151 |
149 void saveUpdatedContents() {} | 152 void saveUpdatedContents() {} |
150 | 153 |
151 String toString() { | 154 String toString() { |
152 var simpleUri = uri.scheme == 'file' ? path.relative(uri.path) : "$uri"; | 155 var simpleUri = uri.scheme == 'file' ? path.relative(uri.path) : "$uri"; |
153 return '[$runtimeType: $simpleUri]'; | 156 return '[$runtimeType: $simpleUri]'; |
154 } | 157 } |
155 } | 158 } |
156 | 159 |
157 /// A node representing an entry HTML source file. | 160 /// A node representing an entry HTML source file. |
158 class HtmlSourceNode extends SourceNode { | 161 class HtmlSourceNode extends SourceNode { |
(...skipping 18 matching lines...) Expand all Loading... |
177 | 180 |
178 /// Tracks resource files referenced from HTML nodes, e.g. | 181 /// Tracks resource files referenced from HTML nodes, e.g. |
179 /// `<link rel=stylesheet href=...>` and `<img src=...>` | 182 /// `<link rel=stylesheet href=...>` and `<img src=...>` |
180 final htmlResourceNodes = new HashMap<Element, ResourceSourceNode>(); | 183 final htmlResourceNodes = new HashMap<Element, ResourceSourceNode>(); |
181 | 184 |
182 HtmlSourceNode(SourceGraph graph, Uri uri, Source source) | 185 HtmlSourceNode(SourceGraph graph, Uri uri, Source source) |
183 : runtimeDeps = graph.runtimeDeps, | 186 : runtimeDeps = graph.runtimeDeps, |
184 super(graph, uri, source); | 187 super(graph, uri, source); |
185 | 188 |
186 @override | 189 @override |
| 190 void clearSummary() { |
| 191 var reporter = graph._reporter; |
| 192 if (reporter is HtmlReporter) { |
| 193 reporter.reporter.clearHtml(uri); |
| 194 } else if (reporter is SummaryReporter) { |
| 195 reporter.clearHtml(uri); |
| 196 } |
| 197 } |
| 198 |
| 199 @override |
187 void update() { | 200 void update() { |
188 super.update(); | 201 super.update(); |
189 if (needsRebuild) { | 202 if (needsRebuild) { |
190 var reporter = graph._reporter; | |
191 if (reporter is SummaryReporter) { | |
192 reporter.clearHtml(uri); | |
193 } | |
194 document = html.parse(contents, generateSpans: true); | 203 document = html.parse(contents, generateSpans: true); |
195 var newScripts = new Set<DartSourceNode>(); | 204 var newScripts = new Set<DartSourceNode>(); |
196 var tags = document.querySelectorAll('script[type="application/dart"]'); | 205 var tags = document.querySelectorAll('script[type="application/dart"]'); |
197 for (var script in tags) { | 206 for (var script in tags) { |
198 var src = script.attributes['src']; | 207 var src = script.attributes['src']; |
199 if (src == null) { | 208 if (src == null) { |
200 _reportError( | 209 _reportError( |
201 graph, | 210 graph, |
202 'inlined script tags not supported at this time ' | 211 'inlined script tags not supported at this time ' |
203 '(see https://github.com/dart-lang/dart-dev-compiler/issues/54).', | 212 '(see https://github.com/dart-lang/dart-dev-compiler/issues/54).', |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
284 // once, but how else can we ensure a consistent view across a given | 293 // once, but how else can we ensure a consistent view across a given |
285 // compile? One different from dev_compiler vs analyzer is that our | 294 // compile? One different from dev_compiler vs analyzer is that our |
286 // messages later in the compiler need the original source text to print | 295 // messages later in the compiler need the original source text to print |
287 // spans. We also read source text ourselves to parse directives. | 296 // spans. We also read source text ourselves to parse directives. |
288 // But we could discard it after that point. | 297 // But we could discard it after that point. |
289 void saveUpdatedContents() { | 298 void saveUpdatedContents() { |
290 graph._context.setContents(_source, _source.contents.data); | 299 graph._context.setContents(_source, _source.contents.data); |
291 } | 300 } |
292 | 301 |
293 @override | 302 @override |
| 303 void clearSummary() { |
| 304 var reporter = graph._reporter; |
| 305 if (reporter is HtmlReporter) { |
| 306 reporter.reporter.clearLibrary(uri); |
| 307 } else if (reporter is SummaryReporter) { |
| 308 reporter.clearLibrary(uri); |
| 309 } |
| 310 } |
| 311 |
| 312 @override |
294 void update() { | 313 void update() { |
295 super.update(); | 314 super.update(); |
296 | 315 |
297 if (needsRebuild) { | 316 if (needsRebuild) { |
298 var reporter = graph._reporter; | |
299 if (reporter is SummaryReporter) { | |
300 reporter.clearLibrary(uri); | |
301 } | |
302 | |
303 // If the defining compilation-unit changed, the structure might have | 317 // If the defining compilation-unit changed, the structure might have |
304 // changed. | 318 // changed. |
305 var unit = parseDirectives(contents, name: _source.fullName); | 319 var unit = parseDirectives(contents, name: _source.fullName); |
306 var newImports = new Set<DartSourceNode>(); | 320 var newImports = new Set<DartSourceNode>(); |
307 var newExports = new Set<DartSourceNode>(); | 321 var newExports = new Set<DartSourceNode>(); |
308 var newParts = new Set<DartSourceNode>(); | 322 var newParts = new Set<DartSourceNode>(); |
309 for (var d in unit.directives) { | 323 for (var d in unit.directives) { |
310 // Nothing to do for parts. | 324 // Nothing to do for parts. |
311 if (d is PartOfDirective) return; | 325 if (d is PartOfDirective) return; |
312 if (d is LibraryDirective) continue; | 326 if (d is LibraryDirective) continue; |
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
505 var deps = includeParts ? node.allDeps : node.depsWithoutParts; | 519 var deps = includeParts ? node.allDeps : node.depsWithoutParts; |
506 deps.forEach(helper); | 520 deps.forEach(helper); |
507 action(node); | 521 action(node); |
508 } | 522 } |
509 helper(start); | 523 helper(start); |
510 } | 524 } |
511 | 525 |
512 bool _same(Set a, Set b) => a.length == b.length && a.containsAll(b); | 526 bool _same(Set a, Set b) => a.length == b.length && a.containsAll(b); |
513 | 527 |
514 final _log = new Logger('dev_compiler.dependency_graph'); | 528 final _log = new Logger('dev_compiler.dependency_graph'); |
OLD | NEW |