Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(150)

Unified Diff: pkg/front_end/lib/src/incremental/file_state.dart

Issue 2879783002: Compute topologically sorted library cycles. (Closed)
Patch Set: Fixes for review comments. Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | pkg/front_end/lib/src/incremental_kernel_generator_impl.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/front_end/lib/src/incremental/file_state.dart
diff --git a/pkg/front_end/lib/src/incremental/file_state.dart b/pkg/front_end/lib/src/incremental/file_state.dart
index c1bcfeb17b0ff2dc245f361a5f7f13aff77f5ead..3012f6db3a807085b248cad0ad6e1c2216a0a84a 100644
--- a/pkg/front_end/lib/src/incremental/file_state.dart
+++ b/pkg/front_end/lib/src/incremental/file_state.dart
@@ -6,6 +6,7 @@ import 'dart:async';
import 'dart:typed_data';
import 'package:front_end/file_system.dart';
+import 'package:front_end/src/dependency_walker.dart' as graph;
import 'package:front_end/src/fasta/parser/top_level_parser.dart';
import 'package:front_end/src/fasta/scanner.dart';
import 'package:front_end/src/fasta/source/directive_listener.dart';
@@ -27,37 +28,40 @@ class FileState {
bool _exists;
List<int> _content;
- List<FileState> _importedFiles;
- List<FileState> _exportedFiles;
+ List<FileState> _importedLibraries;
+ List<FileState> _exportedLibraries;
List<FileState> _partFiles;
- Set<FileState> _directReferencedFiles = new Set<FileState>();
+ List<FileState> _directReferencedLibraries = <FileState>[];
FileState._(this._fsState, this.fileUri);
/// The content of the file.
List<int> get content => _content;
+ /// Libraries that this library file directly imports or exports.
+ List<FileState> get directReferencedLibraries => _directReferencedLibraries;
+
/// Whether the file exists.
bool get exists => _exists;
+ /// The list of the libraries exported by this library.
+ List<FileState> get exportedLibraries => _exportedLibraries;
+
@override
int get hashCode => fileUri.hashCode;
- /// Return the set of transitive files - the file itself and all of the
- /// directly or indirectly referenced files.
- Set<FileState> get transitiveFiles {
- // TODO(scheglov) add caching.
- var transitiveFiles = new Set<FileState>();
+ /// The list of the libraries imported by this library.
+ List<FileState> get importedLibraries => _importedLibraries;
- void appendReferenced(FileState file) {
- if (transitiveFiles.add(file)) {
- file._directReferencedFiles.forEach(appendReferenced);
- }
- }
+ /// The list of files this library file references as parts.
+ List<FileState> get partFiles => _partFiles;
- appendReferenced(this);
- return transitiveFiles;
+ /// Return topologically sorted cycles of dependencies for this library.
+ List<LibraryCycle> get topologicalOrder {
+ var libraryWalker = new _LibraryWalker();
+ libraryWalker.walk(libraryWalker.getNode(this));
+ return libraryWalker.topologicallySortedCycles;
}
@override
@@ -84,25 +88,31 @@ class FileState {
new TopLevelParser(listener).parseUnit(scannerResults.tokens);
// Build the graph.
- _importedFiles = <FileState>[];
- _exportedFiles = <FileState>[];
+ _importedLibraries = <FileState>[];
+ _exportedLibraries = <FileState>[];
_partFiles = <FileState>[];
- await _addFileForRelativeUri(_importedFiles, 'dart:core');
+ await _addFileForRelativeUri(_importedLibraries, 'dart:core');
for (String uri in listener.imports) {
- await _addFileForRelativeUri(_importedFiles, uri);
+ await _addFileForRelativeUri(_importedLibraries, uri);
}
for (String uri in listener.exports) {
- await _addFileForRelativeUri(_exportedFiles, uri);
+ await _addFileForRelativeUri(_exportedLibraries, uri);
}
for (String uri in listener.parts) {
await _addFileForRelativeUri(_partFiles, uri);
}
- // Compute referenced files.
- _directReferencedFiles = new Set<FileState>()
- ..addAll(_importedFiles)
- ..addAll(_exportedFiles)
- ..addAll(_partFiles);
+ // Compute referenced libraries.
+ _directReferencedLibraries = (new Set<FileState>()
+ ..addAll(_importedLibraries)
+ ..addAll(_exportedLibraries))
+ .toList();
+ }
+
+ @override
+ String toString() {
+ if (fileUri.scheme == 'file') return fileUri.path;
+ return fileUri.toString();
}
/// Add the [FileState] for the given [relativeUri] to the [files].
@@ -178,6 +188,14 @@ class FileSystemState {
}
}
+/// List of libraries that reference each other, so form a cycle.
+class LibraryCycle {
+ final List<FileState> libraries = <FileState>[];
+
+ @override
+ String toString() => '[' + libraries.join(', ') + ']';
+}
+
/// [FileSystemState] based implementation of [FileSystem].
/// It provides a consistent view on the known file system state.
class _FileSystemView implements FileSystem {
@@ -226,3 +244,45 @@ class _FileSystemViewEntry implements FileSystemEntity {
throw new StateError('The method should not be invoked.');
}
}
+
+/// Node in [_LibraryWalker].
+class _LibraryNode extends graph.Node<_LibraryNode> {
+ final _LibraryWalker walker;
+ final FileState file;
+
+ @override
+ bool isEvaluated = false;
+
+ _LibraryNode(this.walker, this.file);
+
+ @override
+ List<_LibraryNode> computeDependencies() {
+ return file.directReferencedLibraries.map(walker.getNode).toList();
+ }
+}
+
+/// Helper that organizes dependencies of a library into topologically
+/// sorted [LibraryCycle]s.
+class _LibraryWalker extends graph.DependencyWalker<_LibraryNode> {
+ final nodesOfFiles = <FileState, _LibraryNode>{};
+ final topologicallySortedCycles = <LibraryCycle>[];
+
+ @override
+ void evaluate(_LibraryNode v) {
+ evaluateScc([v]);
+ }
+
+ @override
+ void evaluateScc(List<_LibraryNode> scc) {
+ var cycle = new LibraryCycle();
+ for (var node in scc) {
+ node.isEvaluated = true;
+ cycle.libraries.add(node.file);
+ }
+ topologicallySortedCycles.add(cycle);
+ }
+
+ _LibraryNode getNode(FileState file) {
+ return nodesOfFiles.putIfAbsent(file, () => new _LibraryNode(this, file));
+ }
+}
« no previous file with comments | « no previous file | pkg/front_end/lib/src/incremental_kernel_generator_impl.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698