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 10 matching lines...) Expand all Loading... |
21 UriBasedDirective; | 21 UriBasedDirective; |
22 import 'package:analyzer/src/generated/engine.dart' | 22 import 'package:analyzer/src/generated/engine.dart' |
23 show ParseDartTask, AnalysisContext; | 23 show ParseDartTask, AnalysisContext; |
24 import 'package:analyzer/src/generated/error.dart'; | 24 import 'package:analyzer/src/generated/error.dart'; |
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 'info.dart'; | 31 import 'package:dev_compiler/src/compiler.dart' show defaultRuntimeFiles; |
32 import 'options.dart'; | 32 import 'package:dev_compiler/src/info.dart'; |
33 import 'report.dart'; | 33 import 'package:dev_compiler/src/options.dart'; |
| 34 import 'package:dev_compiler/src/report.dart'; |
34 | 35 |
35 /// Holds references to all source nodes in the import graph. This is mainly | 36 /// Holds references to all source nodes in the import graph. This is mainly |
36 /// used as a level of indirection to ensure that each source has a canonical | 37 /// used as a level of indirection to ensure that each source has a canonical |
37 /// representation. | 38 /// representation. |
38 class SourceGraph { | 39 class SourceGraph { |
39 /// All nodes in the source graph. Used to get a canonical representation for | 40 /// All nodes in the source graph. Used to get a canonical representation for |
40 /// any node. | 41 /// any node. |
41 final Map<Uri, SourceNode> nodes = {}; | 42 final Map<Uri, SourceNode> nodes = {}; |
42 | 43 |
43 /// Resources included by default on any application. | 44 /// Resources included by default on any application. |
44 final runtimeDeps = new Set<ResourceSourceNode>(); | 45 final runtimeDeps = new Set<ResourceSourceNode>(); |
45 | 46 |
46 /// Analyzer used to resolve source files. | 47 /// Analyzer used to resolve source files. |
47 final AnalysisContext _context; | 48 final AnalysisContext _context; |
48 final AnalysisErrorListener _reporter; | 49 final AnalysisErrorListener _reporter; |
49 final CompilerOptions _options; | 50 final CompilerOptions _options; |
50 | 51 |
51 SourceGraph(this._context, this._reporter, this._options) { | 52 SourceGraph(this._context, this._reporter, this._options) { |
52 var dir = _options.runtimeDir; | 53 var dir = _options.runtimeDir; |
53 if (dir == null) { | 54 if (dir == null) { |
54 _log.severe('Runtime dir could not be determined automatically, ' | 55 _log.severe('Runtime dir could not be determined automatically, ' |
55 'please specify the --runtime-dir flag on the command line.'); | 56 'please specify the --runtime-dir flag on the command line.'); |
56 return; | 57 return; |
57 } | 58 } |
58 var prefix = path.absolute(dir); | 59 var prefix = path.absolute(dir); |
59 var files = _options.serverMode | 60 var files = _options.serverMode && _options.widget |
60 ? runtimeFilesForServerMode(_options.widget) | 61 ? runtimeFilesForServerMode |
61 : defaultRuntimeFiles; | 62 : defaultRuntimeFiles; |
62 for (var file in files) { | 63 for (var file in files) { |
63 runtimeDeps.add(nodeFromUri(path.toUri(path.join(prefix, file)))); | 64 runtimeDeps.add(nodeFromUri(path.toUri(path.join(prefix, file)))); |
64 } | 65 } |
65 } | 66 } |
66 | 67 |
67 /// Node associated with a resolved [uri]. | 68 /// Node associated with a resolved [uri]. |
68 SourceNode nodeFromUri(Uri uri) { | 69 SourceNode nodeFromUri(Uri uri) { |
69 var uriString = Uri.encodeFull('$uri'); | 70 var uriString = Uri.encodeFull('$uri'); |
70 return nodes.putIfAbsent(uri, () { | 71 return nodes.putIfAbsent(uri, () { |
71 var source = _context.sourceFactory.forUri(uriString); | 72 var source = _context.sourceFactory.forUri(uriString); |
72 var extension = path.extension(uriString); | 73 var extension = path.extension(uriString); |
73 if (extension == '.html') { | 74 if (extension == '.html') { |
74 return new HtmlSourceNode(this, uri, source); | 75 return new HtmlSourceNode(this, uri, source); |
75 } else if (extension == '.dart' || uriString.startsWith('dart:')) { | 76 } else if (extension == '.dart' || uriString.startsWith('dart:')) { |
76 return new DartSourceNode(this, uri, source); | 77 return new DartSourceNode(this, uri, source); |
77 } else { | 78 } else { |
78 return new ResourceSourceNode(this, uri, source); | 79 return new ResourceSourceNode(this, uri, source); |
79 } | 80 } |
80 }); | 81 }); |
81 } | 82 } |
82 | 83 |
83 List<String> get resources => _options.sourceOptions.resources; | 84 List<String> get resources => _options.sourceOptions.resources; |
84 } | 85 } |
85 | 86 |
| 87 final runtimeFilesForServerMode = new List<String>.from(defaultRuntimeFiles) |
| 88 ..add('messages_widget.js') |
| 89 ..add('messages.css'); |
| 90 |
86 /// A node in the import graph representing a source file. | 91 /// A node in the import graph representing a source file. |
87 abstract class SourceNode { | 92 abstract class SourceNode { |
88 final SourceGraph graph; | 93 final SourceGraph graph; |
89 | 94 |
90 /// Resolved URI for this node. | 95 /// Resolved URI for this node. |
91 final Uri uri; | 96 final Uri uri; |
92 | 97 |
93 /// Resolved source from the analyzer. We let the analyzer internally track | 98 /// Resolved source from the analyzer. We let the analyzer internally track |
94 /// for modifications to the source files. | 99 /// for modifications to the source files. |
95 Source _source; | 100 Source _source; |
(...skipping 398 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
494 if (!seen.add(node)) return; | 499 if (!seen.add(node)) return; |
495 var deps = includeParts ? node.allDeps : node.depsWithoutParts; | 500 var deps = includeParts ? node.allDeps : node.depsWithoutParts; |
496 deps.forEach(helper); | 501 deps.forEach(helper); |
497 action(node); | 502 action(node); |
498 } | 503 } |
499 helper(start); | 504 helper(start); |
500 } | 505 } |
501 | 506 |
502 bool _same(Set a, Set b) => a.length == b.length && a.containsAll(b); | 507 bool _same(Set a, Set b) => a.length == b.length && a.containsAll(b); |
503 | 508 |
504 /// Runtime files added to all applications when running the compiler in the | |
505 /// command line. | |
506 final defaultRuntimeFiles = () { | |
507 var files = [ | |
508 'harmony_feature_check.js', | |
509 'dart_utils.js', | |
510 'dart_library.js', | |
511 '_errors.js', | |
512 '_types.js', | |
513 '_rtti.js', | |
514 '_classes.js', | |
515 '_operations.js', | |
516 'dart_runtime.js', | |
517 ]; | |
518 files.addAll(corelibOrder.map((l) => l.replaceAll('.', '/') + '.js')); | |
519 return files; | |
520 }(); | |
521 | |
522 /// Curated order to minimize lazy classes needed by dart:core and its | |
523 /// transitive SDK imports. | |
524 const corelibOrder = const [ | |
525 'dart.core', | |
526 'dart.collection', | |
527 'dart._internal', | |
528 'dart.math', | |
529 'dart._interceptors', | |
530 'dart.async', | |
531 'dart._foreign_helper', | |
532 'dart._js_embedded_names', | |
533 'dart._js_helper', | |
534 'dart.isolate', | |
535 'dart.typed_data', | |
536 'dart._native_typed_data', | |
537 'dart._isolate_helper', | |
538 'dart._js_primitives', | |
539 'dart.convert', | |
540 'dart.mirrors', | |
541 'dart._js_mirrors', | |
542 'dart.js' | |
543 // _foreign_helper is not included, as it only defines the JS builtin that | |
544 // the compiler handles at compile time. | |
545 ]; | |
546 | |
547 /// Runtime files added to applications when running in server mode. | |
548 List<String> runtimeFilesForServerMode([bool includeWidget = true]) => | |
549 new List<String>.from(defaultRuntimeFiles) | |
550 ..addAll(includeWidget ? const ['messages_widget.js', 'messages.css'] : []); | |
551 | |
552 final _log = new Logger('dev_compiler.dependency_graph'); | 509 final _log = new Logger('dev_compiler.dependency_graph'); |
OLD | NEW |