| 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 |