Chromium Code Reviews| Index: sdk/lib/_internal/compiler/implementation/compiler.dart |
| diff --git a/sdk/lib/_internal/compiler/implementation/compiler.dart b/sdk/lib/_internal/compiler/implementation/compiler.dart |
| index 91ee72a610f4ca239c2f7af099de85bd360d2392..ef0d1e7b370a86da19b2020f6818a1ebdb522869 100644 |
| --- a/sdk/lib/_internal/compiler/implementation/compiler.dart |
| +++ b/sdk/lib/_internal/compiler/implementation/compiler.dart |
| @@ -36,7 +36,6 @@ abstract class WorkItem { |
| assert(invariant(element, element.isDeclaration)); |
| } |
| - |
| void run(Compiler compiler, Enqueuer world); |
| } |
| @@ -81,11 +80,6 @@ class PostProcessTask { |
| PostProcessTask(this.element, this.action); |
| } |
| -class ReadingFilesTask extends CompilerTask { |
| - ReadingFilesTask(Compiler compiler) : super(compiler); |
| - String get name => 'Reading input files'; |
| -} |
| - |
| abstract class Backend { |
| final Compiler compiler; |
| final ConstantSystem constantSystem; |
| @@ -245,7 +239,9 @@ abstract class Backend { |
| void registerStaticUse(Element element, Enqueuer enqueuer) {} |
| - void onLibraryLoaded(LibraryElement library, Uri uri) {} |
| + Future onLibraryLoaded(LibraryElement library, Uri uri) { |
| + return new Future.value(); |
| + } |
| void registerMetadataInstantiatedType(DartType type, TreeElements elements) {} |
| void registerMetadataStaticUse(Element element) {} |
| @@ -501,7 +497,6 @@ abstract class Compiler implements DiagnosticListener { |
| ConstantHandler constantHandler; |
| ConstantHandler metadataHandler; |
| EnqueueTask enqueuer; |
| - CompilerTask fileReadingTask; |
| DeferredLoadTask deferredLoadTask; |
| MirrorUsageAnalyzerTask mirrorUsageAnalyzerTask; |
| ContainerTracer containerTracer; |
| @@ -603,7 +598,6 @@ abstract class Compiler implements DiagnosticListener { |
| validator = new TreeValidatorTask(this); |
| tasks = [ |
| - fileReadingTask = new ReadingFilesTask(this), |
| libraryLoader = new LibraryLoaderTask(this), |
| scanner = new ScannerTask(this), |
| dietParser = new DietParserTask(this), |
| @@ -721,14 +715,15 @@ abstract class Compiler implements DiagnosticListener { |
| reportDiagnostic(null, message, api.Diagnostic.VERBOSE_INFO); |
| } |
| - bool run(Uri uri) { |
| + Future<bool> run(Uri uri) { |
| totalCompileTime.start(); |
| - try { |
| - runCompiler(uri); |
| - } on CompilerCancelledException catch (exception) { |
| - log('Error: $exception'); |
| - return false; |
| - } catch (exception) { |
| + |
| + return runCompiler(uri).catchError((error) { |
|
ahe
2013/09/02 13:43:24
I think runCompiler needs to be wrapped in try-cat
Johnni Winther
2013/09/03 07:51:39
Done.
|
| + if (error is CompilerCancelledException) { |
| + log('Error: $error'); |
| + return false; |
| + } |
| + |
| try { |
| if (!hasCrashed) { |
| hasCrashed = true; |
| @@ -740,12 +735,13 @@ abstract class Compiler implements DiagnosticListener { |
| } catch (doubleFault) { |
| // Ignoring exceptions in exception handling. |
| } |
| - rethrow; |
| - } finally { |
| + throw error; |
| + }).whenComplete(() { |
| tracer.close(); |
| totalCompileTime.stop(); |
| - } |
| - return !compilationFailed; |
| + }).then((_) { |
| + return !compilationFailed; |
| + }); |
| } |
| bool hasIsolateSupport() => isolateLibrary != null; |
| @@ -754,7 +750,7 @@ abstract class Compiler implements DiagnosticListener { |
| * This method is called before [library] import and export scopes have been |
| * set up. |
| */ |
| - void onLibraryLoaded(LibraryElement library, Uri uri) { |
| + Future onLibraryLoaded(LibraryElement library, Uri uri) { |
| if (dynamicClass != null) { |
| // When loading the built-in libraries, dynamicClass is null. We |
| // take advantage of this as core imports js_helper and sees [dynamic] |
| @@ -777,12 +773,12 @@ abstract class Compiler implements DiagnosticListener { |
| findRequiredElement(library, const SourceString('DeferredLibrary')); |
| } else if (isolateHelperLibrary == null |
| && (uri == new Uri(scheme: 'dart', path: '_isolate_helper'))) { |
| - isolateHelperLibrary = scanBuiltinLibrary('_isolate_helper'); |
| + isolateHelperLibrary = library; |
| } else if (foreignLibrary == null |
| && (uri == new Uri(scheme: 'dart', path: '_foreign_helper'))) { |
| - foreignLibrary = scanBuiltinLibrary('_foreign_helper'); |
| + foreignLibrary = library; |
| } |
| - backend.onLibraryLoaded(library, uri); |
| + return backend.onLibraryLoaded(library, uri); |
| } |
| Element findRequiredElement(LibraryElement library, SourceString name) { |
| @@ -810,7 +806,7 @@ abstract class Compiler implements DiagnosticListener { |
| } |
| } |
| - LibraryElement scanBuiltinLibrary(String filename); |
| + Future<LibraryElement> scanBuiltinLibrary(String filename); |
| void initializeSpecialClasses() { |
| final List missingCoreClasses = []; |
| @@ -888,26 +884,32 @@ abstract class Compiler implements DiagnosticListener { |
| listClass.lookupConstructor(callConstructor); |
| } |
| - void scanBuiltinLibraries() { |
| - jsHelperLibrary = scanBuiltinLibrary('_js_helper'); |
| - interceptorsLibrary = scanBuiltinLibrary('_interceptors'); |
| - assertMethod = jsHelperLibrary.find(const SourceString('assertHelper')); |
| - identicalFunction = coreLibrary.find(const SourceString('identical')); |
| + Future scanBuiltinLibraries() { |
| + return scanBuiltinLibrary('_js_helper').then((LibraryElement library) { |
| + jsHelperLibrary = library; |
| + return scanBuiltinLibrary('_interceptors'); |
| + }).then((LibraryElement library) { |
| + interceptorsLibrary = library; |
| - initializeSpecialClasses(); |
| + assertMethod = jsHelperLibrary.find(const SourceString('assertHelper')); |
| + identicalFunction = coreLibrary.find(const SourceString('identical')); |
| - functionClass.ensureResolved(this); |
| - functionApplyMethod = |
| - functionClass.lookupLocalMember(const SourceString('apply')); |
| - jsInvocationMirrorClass.ensureResolved(this); |
| - invokeOnMethod = jsInvocationMirrorClass.lookupLocalMember(INVOKE_ON); |
| + initializeSpecialClasses(); |
| - if (preserveComments) { |
| - var uri = new Uri(scheme: 'dart', path: 'mirrors'); |
| - LibraryElement libraryElement = |
| - libraryLoader.loadLibrary(uri, null, uri); |
| - documentClass = libraryElement.find(const SourceString('Comment')); |
| - } |
| + functionClass.ensureResolved(this); |
| + functionApplyMethod = |
| + functionClass.lookupLocalMember(const SourceString('apply')); |
| + jsInvocationMirrorClass.ensureResolved(this); |
| + invokeOnMethod = jsInvocationMirrorClass.lookupLocalMember(INVOKE_ON); |
| + |
| + if (preserveComments) { |
| + var uri = new Uri(scheme: 'dart', path: 'mirrors'); |
| + return libraryLoader.loadLibrary(uri, null, uri).then( |
| + (LibraryElement libraryElement) { |
| + documentClass = libraryElement.find(const SourceString('Comment')); |
| + }); |
| + } |
| + }); |
| } |
| void importHelperLibrary(LibraryElement library) { |
| @@ -922,28 +924,39 @@ abstract class Compiler implements DiagnosticListener { |
| */ |
| Uri resolvePatchUri(String dartLibraryPath); |
| - void runCompiler(Uri uri) { |
| + Future runCompiler(Uri uri) { |
| // TODO(ahe): This prevents memory leaks when invoking the compiler |
| // multiple times. Implement a better mechanism where StringWrapper |
| // instances are shared on a per library basis. |
| SourceString.canonicalizedValues.clear(); |
| assert(uri != null || analyzeOnly); |
| - scanBuiltinLibraries(); |
| - if (librariesToAnalyzeWhenRun != null) { |
| - for (Uri libraryUri in librariesToAnalyzeWhenRun) { |
| - log('analyzing $libraryUri ($buildId)'); |
| - libraryLoader.loadLibrary(libraryUri, null, libraryUri); |
| + return scanBuiltinLibraries().then((_) { |
| + if (librariesToAnalyzeWhenRun != null) { |
| + return Future.forEach(librariesToAnalyzeWhenRun, (libraryUri) { |
| + log('analyzing $libraryUri ($buildId)'); |
| + return libraryLoader.loadLibrary(libraryUri, null, libraryUri); |
| + }); |
| } |
| - } |
| - if (uri != null) { |
| - if (analyzeOnly) { |
| - log('analyzing $uri ($buildId)'); |
| - } else { |
| - log('compiling $uri ($buildId)'); |
| + }).then((_) { |
| + if (uri != null) { |
| + if (analyzeOnly) { |
| + log('analyzing $uri ($buildId)'); |
| + } else { |
| + log('compiling $uri ($buildId)'); |
| + } |
| + return libraryLoader.loadLibrary(uri, null, uri) |
| + .then((LibraryElement library) { |
| + mainApp = library; |
| + }); |
| } |
| - mainApp = libraryLoader.loadLibrary(uri, null, uri); |
| - } |
| + }).then((_) { |
| + compileLoadedLibraries(); |
| + }); |
| + } |
| + |
| + /// Performs the compilation when all libraries have been loaded. |
| + void compileLoadedLibraries() { |
| Element main = null; |
| if (mainApp != null) { |
| main = mainApp.find(MAIN); |
| @@ -959,8 +972,8 @@ abstract class Compiler implements DiagnosticListener { |
| mainApp, |
| MessageKind.GENERIC, |
| {'text': 'Error: Could not find "${MAIN.slowToString()}". ' |
| - 'No source will be analyzed. ' |
| - 'Use "--analyze-all" to analyze all code in the library.'}); |
| + 'No source will be analyzed. ' |
| + 'Use "--analyze-all" to analyze all code in the library.'}); |
| } |
| } else { |
| if (!main.isFunction()) { |
| @@ -976,7 +989,7 @@ abstract class Compiler implements DiagnosticListener { |
| parameter, |
| MessageKind.GENERIC, |
| {'text': |
| - 'Error: "${MAIN.slowToString()}" cannot have parameters.'}); |
| + 'Error: "${MAIN.slowToString()}" cannot have parameters.'}); |
| }); |
| } |
| @@ -1033,7 +1046,8 @@ abstract class Compiler implements DiagnosticListener { |
| enqueuer.codegen.addToWorkList(createInvocationMirrorElement); |
| } |
| if (compileAll) { |
| - libraries.forEach((_, lib) => fullyEnqueueLibrary(lib, enqueuer.codegen)); |
| + libraries.forEach((_, lib) => fullyEnqueueLibrary(lib, |
| + enqueuer.codegen)); |
| } |
| processQueue(enqueuer.codegen, main); |
| enqueuer.codegen.logSummary(log); |
| @@ -1360,7 +1374,7 @@ abstract class Compiler implements DiagnosticListener { |
| * |
| * See [LibraryLoader] for terminology on URIs. |
| */ |
| - Script readScript(Uri readableUri, [Node node]) { |
| + Future<Script> readScript(Uri readableUri, [Element element, Node node]) { |
| unimplemented('Compiler.readScript'); |
| } |
| @@ -1504,10 +1518,14 @@ class SourceSpan { |
| bool invariant(Spannable spannable, var condition, {var message: null}) { |
| // TODO(johnniwinther): Use [spannable] and [message] to provide better |
| // information on assertion errors. |
| + if (spannable == null) { |
| + throw new SpannableAssertionFailure(CURRENT_ELEMENT_SPANNABLE, |
| + "Spannable was null for invariant. Use CURRENT_ELEMENT_SPANNABLE."); |
| + } |
| if (condition is Function){ |
| condition = condition(); |
| } |
| - if (spannable == null || !condition) { |
| + if (!condition) { |
| if (message is Function) { |
| message = message(); |
| } |