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

Unified Diff: lib/src/compiler.dart

Issue 1376123004: Batch the batch compiler for tests (Closed) Base URL: https://github.com/dart-lang/dev_compiler.git@master
Patch Set: Address comments Created 5 years, 2 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 | « lib/src/checker/checker.dart ('k') | test/codegen/expect/DeltaBlue.txt » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: lib/src/compiler.dart
diff --git a/lib/src/compiler.dart b/lib/src/compiler.dart
index fb18179abfca52a1632dab0d1b54d062b5b96479..bdf56716942f894862021511dd82e744dd4b77ab 100644
--- a/lib/src/compiler.dart
+++ b/lib/src/compiler.dart
@@ -71,18 +71,23 @@ bool compile(CompilerOptions options) {
return new BatchCompiler(context, options, reporter: reporter).run();
}
+// Callback on each individual compiled library
+typedef void CompilationNotifier(String path);
+
class BatchCompiler extends AbstractCompiler {
JSGenerator _jsGen;
LibraryElement _dartCore;
String _runtimeOutputDir;
- /// Already compiled sources, so we don't compile them again.
- final _compiled = new HashSet<LibraryElement>();
+ /// Already compiled sources, so we don't check or compile them again.
+ final _compilationRecord = <LibraryElement, bool>{};
bool _sdkCopied = false;
bool _failure = false;
bool get failure => _failure;
+ final _pendingLibraries = <LibraryUnit>[];
+
BatchCompiler(AnalysisContext context, CompilerOptions options,
{AnalysisErrorListener reporter})
: super(
@@ -100,11 +105,6 @@ class BatchCompiler extends AbstractCompiler {
ErrorCollector get reporter => checker.reporter;
- void reset() {
- _compiled.clear();
- _sdkCopied = false;
- }
-
/// Compiles every file in [options.inputs].
/// Returns true on successful compile.
bool run() {
@@ -112,16 +112,17 @@ class BatchCompiler extends AbstractCompiler {
options.inputs.forEach(compileFromUriString);
clock.stop();
var time = (clock.elapsedMilliseconds / 1000).toStringAsFixed(2);
- _log.fine('Compiled ${_compiled.length} libraries in ${time} s\n');
+ _log.fine('Compiled ${_compilationRecord.length} libraries in ${time} s\n');
return !_failure;
}
- void compileFromUriString(String uriString) {
- _compileFromUri(stringToUri(uriString));
+ void compileFromUriString(String uriString, [CompilationNotifier notifier]) {
+ _compileFromUri(stringToUri(uriString), notifier);
}
- void _compileFromUri(Uri uri) {
+ void _compileFromUri(Uri uri, CompilationNotifier notifier) {
+ _failure = false;
if (!uri.isAbsolute) {
throw new ArgumentError.value('$uri', 'uri', 'must be absolute');
}
@@ -129,32 +130,82 @@ class BatchCompiler extends AbstractCompiler {
if (source == null) {
throw new ArgumentError.value('$uri', 'uri', 'could not find source for');
}
- compileSource(source);
+ _compileSource(source, notifier);
}
- void compileSource(Source source) {
+ void _compileSource(Source source, CompilationNotifier notifier) {
if (AnalysisEngine.isHtmlFileName(source.uri.path)) {
- _compileHtml(source);
+ _compileHtml(source, notifier);
} else {
- _compileLibrary(context.computeLibraryElement(source));
+ _compileLibrary(context.computeLibraryElement(source), notifier);
}
+ _processPending();
reporter.flush();
}
- void _compileLibrary(LibraryElement library) {
- if (!_compiled.add(library)) return;
+ void _processPending() {
+ // _pendingLibraries was recorded in post-order. Process from the end
+ // to ensure reverse post-order. This will ensure that we handle back
+ // edges from the original depth-first search correctly.
+
+ while (_pendingLibraries.isNotEmpty) {
+ var unit = _pendingLibraries.removeLast();
+ var library = unit.library.element.enclosingElement;
+ assert(_compilationRecord[library] == true);
+
+ // Process dependences one more time to propagate failure from cycles
+ for (var import in library.imports) {
+ if (!_compilationRecord[import.importedLibrary]) {
+ _compilationRecord[library] = false;
+ }
+ }
+ for (var export in library.exports) {
+ if (!_compilationRecord[export.exportedLibrary]) {
+ _compilationRecord[library] = false;
+ }
+ }
+
+ // Generate code if still valid
+ if (_jsGen != null &&
+ (_compilationRecord[library] ||
+ options.codegenOptions.forceCompile)) {
+ _jsGen.generateLibrary(unit);
+ }
+ }
+ }
+
+ bool _compileLibrary(LibraryElement library, CompilationNotifier notifier) {
+ var success = _compilationRecord[library];
+ if (success != null) {
+ if (!success) _failure = true;
+ return success;
+ }
+
+ // Optimistically mark a library valid until proven otherwise
+ _compilationRecord[library] = true;
if (!options.checkSdk && library.source.uri.scheme == 'dart') {
+ // We assume the Dart SDK is always valid
if (_jsGen != null) _copyDartRuntime();
- return;
+ return true;
}
+ // Check dependences to determine if this library type checks
// TODO(jmesserly): in incremental mode, we can skip the transitive
// compile of imports/exports.
- _compileLibrary(_dartCore); // implicit dart:core dependency
- for (var import in library.imports) _compileLibrary(import.importedLibrary);
- for (var export in library.exports) _compileLibrary(export.exportedLibrary);
+ _compileLibrary(_dartCore, notifier); // implicit dart:core dependency
+ for (var import in library.imports) {
+ if (!_compileLibrary(import.importedLibrary, notifier)) {
+ _compilationRecord[library] = false;
+ }
+ }
+ for (var export in library.exports) {
+ if (!_compileLibrary(export.exportedLibrary, notifier)) {
+ _compilationRecord[library] = false;
+ }
+ }
+ // Check this library's own code
var unitElements = [library.definingCompilationUnit]..addAll(library.parts);
var units = <CompilationUnit>[];
@@ -163,20 +214,35 @@ class BatchCompiler extends AbstractCompiler {
var unit = context.resolveCompilationUnit(element.source, library);
units.add(unit);
failureInLib = logErrors(element.source) || failureInLib;
+ checker.reset();
checker.visitCompilationUnit(unit);
if (checker.failure) failureInLib = true;
}
+ if (failureInLib) _compilationRecord[library] = false;
- if (failureInLib) {
- _failure = true;
- if (!options.codegenOptions.forceCompile) return;
+ // Notifier framework if requested
+ if (notifier != null) {
+ reporter.flush();
+ notifier(getOutputPath(library.source.uri));
}
- if (_jsGen != null) {
+ // Record valid libraries for further dependence checking (cycles) and
+ // codegen.
+
+ // TODO(vsm): Restructure this to not delay code generation more than
+ // necessary. We'd like to process the AST before there is any chance
+ // it's cached out. We should refactor common logic in
+ // server/dependency_graph and perhaps the analyzer itself.
+ success = _compilationRecord[library];
+ if (success || options.codegenOptions.forceCompile) {
var unit = units.first;
var parts = units.skip(1).toList();
- _jsGen.generateLibrary(new LibraryUnit(unit, parts));
+ _pendingLibraries.add(new LibraryUnit(unit, parts));
}
+
+ // Return tentative success status.
+ if (!success) _failure = true;
+ return success;
}
void _copyDartRuntime() {
@@ -194,7 +260,7 @@ class BatchCompiler extends AbstractCompiler {
}
}
- void _compileHtml(Source source) {
+ void _compileHtml(Source source, CompilationNotifier notifier) {
// TODO(jmesserly): reuse DartScriptsTask instead of copy/paste.
var contents = context.getContents(source);
var document = html.parse(contents.data, generateSpans: true);
@@ -224,7 +290,7 @@ class BatchCompiler extends AbstractCompiler {
if (scriptSource != null) {
var lib = context.computeLibraryElement(scriptSource);
- _compileLibrary(lib);
+ _compileLibrary(lib, notifier);
script.replaceWith(_linkLibraries(lib, loadedLibs, from: htmlOutDir));
}
}
« no previous file with comments | « lib/src/checker/checker.dart ('k') | test/codegen/expect/DeltaBlue.txt » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698