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 441 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
452 | 452 |
453 bool shouldBuildNode(SourceNode n) { | 453 bool shouldBuildNode(SourceNode n) { |
454 if (n.needsRebuild) return true; | 454 if (n.needsRebuild) return true; |
455 if (n is HtmlSourceNode) return htmlNeedsRebuild; | 455 if (n is HtmlSourceNode) return htmlNeedsRebuild; |
456 if (n is ResourceSourceNode) return false; | 456 if (n is ResourceSourceNode) return false; |
457 return (n as DartSourceNode) | 457 return (n as DartSourceNode) |
458 .imports | 458 .imports |
459 .any((i) => apiChangeDetected.contains(i)); | 459 .any((i) => apiChangeDetected.contains(i)); |
460 } | 460 } |
461 | 461 |
462 visitInPostOrder( | 462 visitInPostOrder(start, (n) { |
463 start, | 463 if (n.structureChanged) htmlNeedsRebuild = true; |
464 (n) { | 464 if (shouldBuildNode(n)) { |
465 if (n.structureChanged) htmlNeedsRebuild = true; | 465 var oldHash = n.cachingHash; |
466 if (shouldBuildNode(n)) { | 466 if (build(n)) apiChangeDetected.add(n); |
467 var oldHash = n.cachingHash; | 467 if (oldHash != n.cachingHash) htmlNeedsRebuild = true; |
468 if (build(n)) apiChangeDetected.add(n); | 468 } else if (n is DartSourceNode && |
469 if (oldHash != n.cachingHash) htmlNeedsRebuild = true; | 469 n.exports.any((e) => apiChangeDetected.contains(e))) { |
470 } else if (n is DartSourceNode && | 470 apiChangeDetected.add(n); |
471 n.exports.any((e) => apiChangeDetected.contains(e))) { | 471 } |
472 apiChangeDetected.add(n); | 472 n.needsRebuild = false; |
473 } | 473 n.structureChanged = false; |
474 n.needsRebuild = false; | 474 if (n is DartSourceNode) { |
475 n.structureChanged = false; | 475 // Note: clearing out flags in the parts could be a problem if someone |
476 if (n is DartSourceNode) { | 476 // tries to use a file both as a part and a library at the same time. |
477 // Note: clearing out flags in the parts could be a problem if someone | 477 // In that case, we might not correctly propagate changes in the |
478 // tries to use a file both as a part and a library at the same time. | 478 // places where it is used as a library. |
479 // In that case, we might not correctly propagate changes in the | 479 // Technically it's not allowed to have a file as a part and a library |
480 // places where it is used as a library. | 480 // at once, and the analyzer should report an error in that case. |
481 // Technically it's not allowed to have a file as a part and a library | 481 n.parts.forEach((p) => p.needsRebuild = p.structureChanged = false); |
482 // at once, and the analyzer should report an error in that case. | 482 } |
483 n.parts.forEach((p) => p.needsRebuild = p.structureChanged = false); | 483 }, includeParts: false); |
484 } | |
485 }, | |
486 includeParts: false); | |
487 } | 484 } |
488 | 485 |
489 /// Helper that runs [action] on nodes reachable from [start] in pre-order. | 486 /// Helper that runs [action] on nodes reachable from [start] in pre-order. |
490 visitInPreOrder(SourceNode start, void action(SourceNode node), | 487 visitInPreOrder(SourceNode start, void action(SourceNode node), |
491 {bool includeParts: false}) { | 488 {bool includeParts: false}) { |
492 var seen = new HashSet<SourceNode>(); | 489 var seen = new HashSet<SourceNode>(); |
493 helper(SourceNode node) { | 490 helper(SourceNode node) { |
494 if (!seen.add(node)) return; | 491 if (!seen.add(node)) return; |
495 action(node); | 492 action(node); |
496 var deps = includeParts ? node.allDeps : node.depsWithoutParts; | 493 var deps = includeParts ? node.allDeps : node.depsWithoutParts; |
(...skipping 11 matching lines...) Expand all Loading... |
508 var deps = includeParts ? node.allDeps : node.depsWithoutParts; | 505 var deps = includeParts ? node.allDeps : node.depsWithoutParts; |
509 deps.forEach(helper); | 506 deps.forEach(helper); |
510 action(node); | 507 action(node); |
511 } | 508 } |
512 helper(start); | 509 helper(start); |
513 } | 510 } |
514 | 511 |
515 bool _same(Set a, Set b) => a.length == b.length && a.containsAll(b); | 512 bool _same(Set a, Set b) => a.length == b.length && a.containsAll(b); |
516 | 513 |
517 final _log = new Logger('dev_compiler.dependency_graph'); | 514 final _log = new Logger('dev_compiler.dependency_graph'); |
OLD | NEW |