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

Side by Side Diff: sdk/lib/_internal/compiler/implementation/compiler.dart

Issue 17759007: First pass at asynchronous input loading in dart2js. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Change to unix line endings. Created 7 years, 4 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 part of dart2js; 5 part of dart2js;
6 6
7 /** 7 /**
8 * If true, print a warning for each method that was resolved, but not 8 * If true, print a warning for each method that was resolved, but not
9 * compiled. 9 * compiled.
10 */ 10 */
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
74 74
75 typedef void PostProcessAction(); 75 typedef void PostProcessAction();
76 76
77 class PostProcessTask { 77 class PostProcessTask {
78 final Element element; 78 final Element element;
79 final PostProcessAction action; 79 final PostProcessAction action;
80 80
81 PostProcessTask(this.element, this.action); 81 PostProcessTask(this.element, this.action);
82 } 82 }
83 83
84 // TODO(rnystrom): Now that file reading is asynchronous, this task is no longer
85 // used and the time spent reading files isn't easily measurable (or even that
86 // well-defined). As Peter says:
87 //
88 // As far as I can tell, we can only count how much time is being spent reading
89 // files by having a global counter that covers the time from the beginning of
90 // the compiler until it reaches a point when all libraries are scanned, and
91 // subtract the time spent in other tasks.
92 //
93 // I think you should drop measureAsync. I think we can measure the time spent
94 // reading files in dart2js.dart (you can just add a TODO).
84 class ReadingFilesTask extends CompilerTask { 95 class ReadingFilesTask extends CompilerTask {
85 ReadingFilesTask(Compiler compiler) : super(compiler); 96 ReadingFilesTask(Compiler compiler) : super(compiler);
86 String get name => 'Reading input files'; 97 String get name => 'Reading input files';
87 } 98 }
88 99
89 abstract class Backend { 100 abstract class Backend {
90 final Compiler compiler; 101 final Compiler compiler;
91 final ConstantSystem constantSystem; 102 final ConstantSystem constantSystem;
92 103
93 Backend(this.compiler, 104 Backend(this.compiler,
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after
393 ClassElement jsInvocationMirrorClass; 404 ClassElement jsInvocationMirrorClass;
394 /// Document class from dart:mirrors. 405 /// Document class from dart:mirrors.
395 ClassElement documentClass; 406 ClassElement documentClass;
396 Element assertMethod; 407 Element assertMethod;
397 Element identicalFunction; 408 Element identicalFunction;
398 Element functionApplyMethod; 409 Element functionApplyMethod;
399 Element invokeOnMethod; 410 Element invokeOnMethod;
400 Element createInvocationMirrorElement; 411 Element createInvocationMirrorElement;
401 412
402 Element get currentElement => _currentElement; 413 Element get currentElement => _currentElement;
414
415 void _setCurrentElement(Element newElement, Element oldElement) {
416 assert(invariant(
417 newElement == null ? CURRENT_ELEMENT_SPANNABLE : newElement,
418 _currentElement == oldElement,
419 message: "Current element mismatch. "
420 "Expected $oldElement but found $_currentElement."));
421 _currentElement = newElement;
422 }
403 423
404 /** 424 /**
405 * Perform an operation, [f], returning the return value from [f]. If an 425 * Perform an operation, [f], returning the return value from [f]. If an
406 * error occurs then report it as having occurred during compilation of 426 * error occurs then report it as having occurred during compilation of
407 * [element]. Can be nested. 427 * [element]. Can be nested.
408 */ 428 */
409 withCurrentElement(Element element, f()) { 429 withCurrentElement(Element element, f()) {
410 Element old = currentElement; 430 Element old = currentElement;
411 _currentElement = element; 431 _setCurrentElement(element, old);
412 try { 432 try {
413 return f(); 433 var result = f();
434 assert(invariant(element, result is! Future,
435 message: '"withCurrentElement" called with asynchronous function. '
436 'Use "withCurrentElementAsync" instead.'));
437 return result;
414 } on SpannableAssertionFailure catch (ex) { 438 } on SpannableAssertionFailure catch (ex) {
415 if (!hasCrashed) { 439 onSpannableAssertionFailure(ex);
416 SourceSpan span = spanFromSpannable(ex.node);
417 reportError(ex.node, MessageKind.GENERIC, {'text': ex.message});
418 pleaseReportCrash();
419 }
420 hasCrashed = true;
421 rethrow; 440 rethrow;
422 } on CompilerCancelledException catch (ex) { 441 } on CompilerCancelledException catch (ex) {
423 rethrow; 442 rethrow;
424 } on StackOverflowError catch (ex) { 443 } on StackOverflowError catch (ex) {
425 // We cannot report anything useful in this case, because we 444 // We cannot report anything useful in this case, because we
426 // do not have enough stack space. 445 // do not have enough stack space.
427 rethrow; 446 rethrow;
428 } catch (ex) { 447 } catch (ex) {
429 try { 448 onUnhandledException(element);
430 unhandledExceptionOnElement(element);
431 } catch (doubleFault) {
432 // Ignoring exceptions in exception handling.
433 }
434 rethrow; 449 rethrow;
435 } finally { 450 } finally {
436 _currentElement = old; 451 _setCurrentElement(old, element);
452 }
453 }
454
455 Future withCurrentElementAsync(Element element, Future f()) {
456 Element old = currentElement;
457 _setCurrentElement(element, old);
458 try {
459 return f().catchError((ex) {
ahe 2013/08/02 11:50:19 I don't think this will work. I'l talk to you in p
Johnni Winther 2013/08/02 13:47:47 Removed.
460 if (ex is SpannableAssertionFailure) {
461 onSpannableAssertionFailure(ex);
462 } else if (ex is CompilerCancelledException ||
463 ex is StackOverflowError) {
464 // Do nothing.
ahe 2013/08/02 11:50:19 Why is that?
465 } else {
466 onUnhandledException(element);
467 }
468 return new Future.error(ex);
469 })
470 .whenComplete(() {
471 _setCurrentElement(old, element);
472 });
473 } catch (ex) {
474 _setCurrentElement(old, element);
475 return new Future.error(ex);
476 }
477 }
478
479 void onSpannableAssertionFailure(SpannableAssertionFailure ex) {
480 if (!hasCrashed) {
481 SourceSpan span = spanFromSpannable(ex.node);
482 reportError(ex.node, MessageKind.GENERIC, {'text': ex.message});
483 pleaseReportCrash();
484 }
485 hasCrashed = true;
486 }
487
488 void onUnhandledException(Element element) {
489 try {
490 unhandledExceptionOnElement(element);
491 } catch (doubleFault) {
492 // Ignoring exceptions in exception handling.
437 } 493 }
438 } 494 }
439 495
440 List<CompilerTask> tasks; 496 List<CompilerTask> tasks;
441 ScannerTask scanner; 497 ScannerTask scanner;
442 DietParserTask dietParser; 498 DietParserTask dietParser;
443 ParserTask parser; 499 ParserTask parser;
444 PatchParserTask patchParser; 500 PatchParserTask patchParser;
445 LibraryLoader libraryLoader; 501 LibraryLoader libraryLoader;
446 TreeValidatorTask validator; 502 TreeValidatorTask validator;
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after
661 return spanFromTokens(annotation.beginToken, annotation.endToken); 717 return spanFromTokens(annotation.beginToken, annotation.endToken);
662 } else { 718 } else {
663 throw 'No error location.'; 719 throw 'No error location.';
664 } 720 }
665 } 721 }
666 722
667 void log(message) { 723 void log(message) {
668 reportDiagnostic(null, message, api.Diagnostic.VERBOSE_INFO); 724 reportDiagnostic(null, message, api.Diagnostic.VERBOSE_INFO);
669 } 725 }
670 726
671 bool run(Uri uri) { 727 Future<bool> run(Uri uri) {
672 totalCompileTime.start(); 728 totalCompileTime.start();
673 try { 729
674 runCompiler(uri); 730 return runCompiler(uri).then((_) {
675 } on CompilerCancelledException catch (exception) { 731 return true;
676 log('Error: $exception'); 732 }).catchError((error) {
677 return false; 733 if (error is CompilerCancelledException) {
678 } catch (exception) { 734 log('Error: $error');
735 return false;
736 }
737
679 try { 738 try {
680 if (!hasCrashed) { 739 if (!hasCrashed) {
681 hasCrashed = true; 740 hasCrashed = true;
682 reportDiagnostic(new SourceSpan(uri, 0, 0), 741 reportDiagnostic(new SourceSpan(uri, 0, 0),
683 MessageKind.COMPILER_CRASHED.error().toString(), 742 MessageKind.COMPILER_CRASHED.error().toString(),
684 api.Diagnostic.CRASH); 743 api.Diagnostic.CRASH);
685 pleaseReportCrash(); 744 pleaseReportCrash();
686 } 745 }
687 } catch (doubleFault) { 746 } catch (doubleFault) {
688 // Ignoring exceptions in exception handling. 747 // Ignoring exceptions in exception handling.
689 } 748 }
690 rethrow; 749 throw error;
691 } finally { 750 }).whenComplete(() {
692 tracer.close(); 751 tracer.close();
693 totalCompileTime.stop(); 752 totalCompileTime.stop();
694 } 753 }).then((_) {
695 return !compilationFailed; 754 return !compilationFailed;
755 });
696 } 756 }
697 757
698 bool hasIsolateSupport() => isolateLibrary != null; 758 bool hasIsolateSupport() => isolateLibrary != null;
699 759
700 /** 760 /**
701 * This method is called before [library] import and export scopes have been 761 * This method is called before [library] import and export scopes have been
702 * set up. 762 * set up.
703 */ 763 */
704 void onLibraryScanned(LibraryElement library, Uri uri) { 764 void onLibraryScanned(LibraryElement library, Uri uri) {
705 if (dynamicClass != null) { 765 if (dynamicClass != null) {
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
742 mirrorSystemGetNameFunction = 802 mirrorSystemGetNameFunction =
743 cls.lookupLocalMember(const SourceString('getName')); 803 cls.lookupLocalMember(const SourceString('getName'));
744 } else if (symbolClass == cls) { 804 } else if (symbolClass == cls) {
745 symbolConstructor = cls.constructors.head; 805 symbolConstructor = cls.constructors.head;
746 } else if (symbolImplementationClass == cls) { 806 } else if (symbolImplementationClass == cls) {
747 symbolValidatedConstructor = symbolImplementationClass.lookupConstructor( 807 symbolValidatedConstructor = symbolImplementationClass.lookupConstructor(
748 symbolValidatedConstructorSelector); 808 symbolValidatedConstructorSelector);
749 } 809 }
750 } 810 }
751 811
752 LibraryElement scanBuiltinLibrary(String filename); 812 Future<LibraryElement> scanBuiltinLibrary(String filename);
753 813
754 void initializeSpecialClasses() { 814 void initializeSpecialClasses() {
755 final List missingCoreClasses = []; 815 final List missingCoreClasses = [];
756 ClassElement lookupCoreClass(String name) { 816 ClassElement lookupCoreClass(String name) {
757 ClassElement result = coreLibrary.find(new SourceString(name)); 817 ClassElement result = coreLibrary.find(new SourceString(name));
758 if (result == null) { 818 if (result == null) {
759 missingCoreClasses.add(name); 819 missingCoreClasses.add(name);
760 } 820 }
761 return result; 821 return result;
762 } 822 }
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
818 878
819 Element _filledListConstructor; 879 Element _filledListConstructor;
820 Element get filledListConstructor { 880 Element get filledListConstructor {
821 if (_filledListConstructor != null) return _filledListConstructor; 881 if (_filledListConstructor != null) return _filledListConstructor;
822 Selector callConstructor = new Selector.callConstructor( 882 Selector callConstructor = new Selector.callConstructor(
823 const SourceString("filled"), listClass.getLibrary()); 883 const SourceString("filled"), listClass.getLibrary());
824 return _filledListConstructor = 884 return _filledListConstructor =
825 listClass.lookupConstructor(callConstructor); 885 listClass.lookupConstructor(callConstructor);
826 } 886 }
827 887
828 void scanBuiltinLibraries() { 888 Future scanBuiltinLibraries() {
829 jsHelperLibrary = scanBuiltinLibrary('_js_helper'); 889 return scanBuiltinLibrary('_js_helper').then((LibraryElement library) {
830 interceptorsLibrary = scanBuiltinLibrary('_interceptors'); 890 jsHelperLibrary = library;
831 foreignLibrary = scanBuiltinLibrary('_foreign_helper'); 891 return scanBuiltinLibrary('_interceptors');
832 isolateHelperLibrary = scanBuiltinLibrary('_isolate_helper'); 892 }).then((LibraryElement library) {
893 interceptorsLibrary = library;
894 return scanBuiltinLibrary('_foreign_helper');
895 }).then((LibraryElement library) {
896 foreignLibrary = library;
897 return scanBuiltinLibrary('_isolate_helper');
898 }).then((LibraryElement library) {
899 isolateHelperLibrary = library;
833 900
834 assertMethod = jsHelperLibrary.find(const SourceString('assertHelper')); 901 assertMethod = jsHelperLibrary.find(const SourceString('assertHelper'));
835 identicalFunction = coreLibrary.find(const SourceString('identical')); 902 identicalFunction = coreLibrary.find(const SourceString('identical'));
836 903
837 initializeSpecialClasses(); 904 initializeSpecialClasses();
838 905
839 functionClass.ensureResolved(this); 906 functionClass.ensureResolved(this);
840 functionApplyMethod = 907 functionApplyMethod =
841 functionClass.lookupLocalMember(const SourceString('apply')); 908 functionClass.lookupLocalMember(const SourceString('apply'));
842 jsInvocationMirrorClass.ensureResolved(this); 909 jsInvocationMirrorClass.ensureResolved(this);
843 invokeOnMethod = jsInvocationMirrorClass.lookupLocalMember(INVOKE_ON); 910 invokeOnMethod = jsInvocationMirrorClass.lookupLocalMember(INVOKE_ON);
844 911
845 if (preserveComments) { 912 if (preserveComments) {
846 var uri = new Uri(scheme: 'dart', path: 'mirrors'); 913 var uri = new Uri(scheme: 'dart', path: 'mirrors');
847 LibraryElement libraryElement = 914 return libraryLoader.loadLibrary(uri, null, uri).then(
848 libraryLoader.loadLibrary(uri, null, uri); 915 (LibraryElement libraryElement) {
849 documentClass = libraryElement.find(const SourceString('Comment')); 916 documentClass = libraryElement.find(const SourceString('Comment'));
850 } 917 });
918 }
919 });
851 } 920 }
852 921
853 void importHelperLibrary(LibraryElement library) { 922 void importHelperLibrary(LibraryElement library) {
854 if (jsHelperLibrary != null) { 923 if (jsHelperLibrary != null) {
855 libraryLoader.importLibrary(library, jsHelperLibrary, null); 924 libraryLoader.importLibrary(library, jsHelperLibrary, null);
856 } 925 }
857 } 926 }
858 927
859 /** 928 /**
860 * Get an [Uri] pointing to a patch for the dart: library with 929 * Get an [Uri] pointing to a patch for the dart: library with
861 * the given path. Returns null if there is no patch. 930 * the given path. Returns null if there is no patch.
862 */ 931 */
863 Uri resolvePatchUri(String dartLibraryPath); 932 Uri resolvePatchUri(String dartLibraryPath);
864 933
865 void runCompiler(Uri uri) { 934 Future runCompiler(Uri uri) {
866 // TODO(ahe): This prevents memory leaks when invoking the compiler 935 // TODO(ahe): This prevents memory leaks when invoking the compiler
867 // multiple times. Implement a better mechanism where StringWrapper 936 // multiple times. Implement a better mechanism where StringWrapper
868 // instances are shared on a per library basis. 937 // instances are shared on a per library basis.
869 SourceString.canonicalizedValues.clear(); 938 SourceString.canonicalizedValues.clear();
870 939
871 assert(uri != null || analyzeOnly); 940 assert(uri != null || analyzeOnly);
872 scanBuiltinLibraries(); 941 return scanBuiltinLibraries().then((_) {
873 if (librariesToAnalyzeWhenRun != null) { 942 if (librariesToAnalyzeWhenRun != null) {
874 for (Uri libraryUri in librariesToAnalyzeWhenRun) { 943 return Future.forEach(librariesToAnalyzeWhenRun, (libraryUri) {
875 log('analyzing $libraryUri ($buildId)'); 944 log('analyzing $libraryUri ($buildId)');
876 libraryLoader.loadLibrary(libraryUri, null, libraryUri); 945 return libraryLoader.loadLibrary(libraryUri, null, libraryUri);
877 }
878 }
879 if (uri != null) {
880 if (analyzeOnly) {
881 log('analyzing $uri ($buildId)');
882 } else {
883 log('compiling $uri ($buildId)');
884 }
885 mainApp = libraryLoader.loadLibrary(uri, null, uri);
886 }
887 Element main = null;
888 if (mainApp != null) {
889 main = mainApp.find(MAIN);
890 if (main == null) {
891 if (!analyzeOnly) {
892 // Allow analyze only of libraries with no main.
893 reportFatalError(
894 mainApp,
895 MessageKind.GENERIC,
896 {'text': 'Error: Could not find "${MAIN.slowToString()}".'});
897 } else if (!analyzeAll) {
898 reportFatalError(
899 mainApp,
900 MessageKind.GENERIC,
901 {'text': 'Error: Could not find "${MAIN.slowToString()}". '
902 'No source will be analyzed. '
903 'Use "--analyze-all" to analyze all code in the library.'});
904 }
905 } else {
906 if (!main.isFunction()) {
907 reportFatalError(
908 main,
909 MessageKind.GENERIC,
910 {'text': 'Error: "${MAIN.slowToString()}" is not a function.'});
911 }
912 FunctionElement mainMethod = main;
913 FunctionSignature parameters = mainMethod.computeSignature(this);
914 parameters.forEachParameter((Element parameter) {
915 reportError(
916 parameter,
917 MessageKind.GENERIC,
918 {'text':
919 'Error: "${MAIN.slowToString()}" cannot have parameters.'});
920 }); 946 });
921 } 947 }
948 }).then((_) {
949 if (uri != null) {
950 if (analyzeOnly) {
951 log('analyzing $uri ($buildId)');
952 } else {
953 log('compiling $uri ($buildId)');
954 }
955 return libraryLoader.loadLibrary(uri, null, uri)
956 .then((LibraryElement library) {
957 mainApp = library;
958 });
959 }
960 }).then((_) {
961 Element main = null;
962 if (mainApp != null) {
963 main = mainApp.find(MAIN);
964 if (main == null) {
965 if (!analyzeOnly) {
966 // Allow analyze only of libraries with no main.
967 reportFatalError(
968 mainApp,
969 MessageKind.GENERIC,
970 {'text': 'Error: Could not find "${MAIN.slowToString()}".'});
971 } else if (!analyzeAll) {
972 reportFatalError(
973 mainApp,
974 MessageKind.GENERIC,
975 {'text': 'Error: Could not find "${MAIN.slowToString()}". '
976 'No source will be analyzed. '
977 'Use "--analyze-all" to analyze all code in the library.'});
978 }
979 } else {
980 if (!main.isFunction()) {
981 reportFatalError(
982 main,
983 MessageKind.GENERIC,
984 {'text': 'Error: "${MAIN.slowToString()}" is not a function.'});
985 }
986 FunctionElement mainMethod = main;
987 FunctionSignature parameters = mainMethod.computeSignature(this);
988 parameters.forEachParameter((Element parameter) {
989 reportError(
990 parameter,
991 MessageKind.GENERIC,
992 {'text':
993 'Error: "${MAIN.slowToString()}" cannot have parameters.'});
994 });
995 }
922 996
923 mirrorUsageAnalyzerTask.analyzeUsage(mainApp); 997 mirrorUsageAnalyzerTask.analyzeUsage(mainApp);
924 998
925 // In order to see if a library is deferred, we must compute the 999 // In order to see if a library is deferred, we must compute the
926 // compile-time constants that are metadata. This means adding 1000 // compile-time constants that are metadata. This means adding
927 // something to the resolution queue. So we cannot wait with 1001 // something to the resolution queue. So we cannot wait with
928 // this until after the resolution queue is processed. 1002 // this until after the resolution queue is processed.
929 // TODO(ahe): Clean this up, for example, by not enqueueing 1003 // TODO(ahe): Clean this up, for example, by not enqueueing
930 // classes only used for metadata. 1004 // classes only used for metadata.
931 deferredLoadTask.findDeferredLibraries(mainApp); 1005 deferredLoadTask.findDeferredLibraries(mainApp);
932 } 1006 }
933 1007
934 log('Resolving...'); 1008 log('Resolving...');
935 phase = PHASE_RESOLVING; 1009 phase = PHASE_RESOLVING;
936 if (analyzeAll) { 1010 if (analyzeAll) {
937 libraries.forEach( 1011 libraries.forEach(
938 (_, lib) => fullyEnqueueLibrary(lib, enqueuer.resolution)); 1012 (_, lib) => fullyEnqueueLibrary(lib, enqueuer.resolution));
939 } 1013 }
940 // Elements required by enqueueHelpers are global dependencies 1014 // Elements required by enqueueHelpers are global dependencies
941 // that are not pulled in by a particular element. 1015 // that are not pulled in by a particular element.
942 backend.enqueueHelpers(enqueuer.resolution, globalDependencies); 1016 backend.enqueueHelpers(enqueuer.resolution, globalDependencies);
943 processQueue(enqueuer.resolution, main); 1017 processQueue(enqueuer.resolution, main);
944 enqueuer.resolution.logSummary(log); 1018 enqueuer.resolution.logSummary(log);
945 1019
946 if (compilationFailed) return; 1020 if (compilationFailed) return;
947 if (analyzeOnly) return; 1021 if (analyzeOnly) return;
948 assert(main != null); 1022 assert(main != null);
949 phase = PHASE_DONE_RESOLVING; 1023 phase = PHASE_DONE_RESOLVING;
950 1024
951 // TODO(ahe): Remove this line. Eventually, enqueuer.resolution 1025 // TODO(ahe): Remove this line. Eventually, enqueuer.resolution
952 // should know this. 1026 // should know this.
953 world.populate(); 1027 world.populate();
954 // Compute whole-program-knowledge that the backend needs. (This might 1028 // Compute whole-program-knowledge that the backend needs. (This might
955 // require the information computed in [world.populate].) 1029 // require the information computed in [world.populate].)
956 backend.onResolutionComplete(); 1030 backend.onResolutionComplete();
957 1031
958 deferredLoadTask.onResolutionComplete(main); 1032 deferredLoadTask.onResolutionComplete(main);
959 1033
960 log('Inferring types...'); 1034 log('Inferring types...');
961 typesTask.onResolutionComplete(main); 1035 typesTask.onResolutionComplete(main);
962 1036
963 log('Compiling...'); 1037 log('Compiling...');
964 phase = PHASE_COMPILING; 1038 phase = PHASE_COMPILING;
965 // TODO(johnniwinther): Move these to [CodegenEnqueuer]. 1039 // TODO(johnniwinther): Move these to [CodegenEnqueuer].
966 if (hasIsolateSupport()) { 1040 if (hasIsolateSupport()) {
967 enqueuer.codegen.addToWorkList( 1041 enqueuer.codegen.addToWorkList(
968 isolateHelperLibrary.find(Compiler.START_ROOT_ISOLATE)); 1042 isolateHelperLibrary.find(Compiler.START_ROOT_ISOLATE));
969 enqueuer.codegen.registerGetOfStaticFunction(mainApp.find(MAIN)); 1043 enqueuer.codegen.registerGetOfStaticFunction(mainApp.find(MAIN));
970 } 1044 }
971 if (enabledNoSuchMethod) { 1045 if (enabledNoSuchMethod) {
972 enqueuer.codegen.registerInvocation(noSuchMethodSelector); 1046 enqueuer.codegen.registerInvocation(noSuchMethodSelector);
973 enqueuer.codegen.addToWorkList(createInvocationMirrorElement); 1047 enqueuer.codegen.addToWorkList(createInvocationMirrorElement);
974 } 1048 }
975 if (compileAll) { 1049 if (compileAll) {
976 libraries.forEach((_, lib) => fullyEnqueueLibrary(lib, enqueuer.codegen)); 1050 libraries.forEach((_, lib) => fullyEnqueueLibrary(lib,
977 } 1051 enqueuer.codegen));
978 processQueue(enqueuer.codegen, main); 1052 }
979 enqueuer.codegen.logSummary(log); 1053 processQueue(enqueuer.codegen, main);
1054 enqueuer.codegen.logSummary(log);
980 1055
981 if (compilationFailed) return; 1056 if (compilationFailed) return;
982 1057
983 backend.assembleProgram(); 1058 backend.assembleProgram();
984 1059
985 checkQueues(); 1060 checkQueues();
986 1061
987 if (compilationFailed) { 1062 if (compilationFailed) {
988 assembledCode = null; // Signals failure. 1063 assembledCode = null; // Signals failure.
989 } 1064 }
1065 });
990 } 1066 }
991 1067
992 void fullyEnqueueLibrary(LibraryElement library, Enqueuer world) { 1068 void fullyEnqueueLibrary(LibraryElement library, Enqueuer world) {
993 void enqueueAll(Element element) { 1069 void enqueueAll(Element element) {
994 fullyEnqueueTopLevelElement(element, world); 1070 fullyEnqueueTopLevelElement(element, world);
995 } 1071 }
996 library.implementation.forEachLocalMember(enqueueAll); 1072 library.implementation.forEachLocalMember(enqueueAll);
997 } 1073 }
998 1074
999 void fullyEnqueueTopLevelElement(Element element, Enqueuer world) { 1075 void fullyEnqueueTopLevelElement(Element element, Enqueuer world) {
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after
1311 Uri translateResolvedUri(LibraryElement importingLibrary, 1387 Uri translateResolvedUri(LibraryElement importingLibrary,
1312 Uri resolvedUri, Node node) { 1388 Uri resolvedUri, Node node) {
1313 unimplemented('Compiler.translateResolvedUri'); 1389 unimplemented('Compiler.translateResolvedUri');
1314 } 1390 }
1315 1391
1316 /** 1392 /**
1317 * Reads the script specified by the [readableUri]. 1393 * Reads the script specified by the [readableUri].
1318 * 1394 *
1319 * See [LibraryLoader] for terminology on URIs. 1395 * See [LibraryLoader] for terminology on URIs.
1320 */ 1396 */
1321 Script readScript(Uri readableUri, [Node node]) { 1397 Future<Script> readScript(Uri readableUri, [Node node]) {
1322 unimplemented('Compiler.readScript'); 1398 unimplemented('Compiler.readScript');
1323 } 1399 }
1324 1400
1325 String get legDirectory { 1401 String get legDirectory {
1326 unimplemented('Compiler.legDirectory'); 1402 unimplemented('Compiler.legDirectory');
1327 } 1403 }
1328 1404
1329 // TODO(karlklose): split into findHelperFunction and findHelperClass and 1405 // TODO(karlklose): split into findHelperFunction and findHelperClass and
1330 // add a check that the element has the expected kind. 1406 // add a check that the element has the expected kind.
1331 Element findHelper(SourceString name) 1407 Element findHelper(SourceString name)
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
1455 * [invariant] as the argument to an [:assert:] statement: 1531 * [invariant] as the argument to an [:assert:] statement:
1456 * 1532 *
1457 * assert(invariant(position, isValid)); 1533 * assert(invariant(position, isValid));
1458 * 1534 *
1459 * [spannable] must be non-null and will be used to provide positional 1535 * [spannable] must be non-null and will be used to provide positional
1460 * information in the generated error message. 1536 * information in the generated error message.
1461 */ 1537 */
1462 bool invariant(Spannable spannable, var condition, {var message: null}) { 1538 bool invariant(Spannable spannable, var condition, {var message: null}) {
1463 // TODO(johnniwinther): Use [spannable] and [message] to provide better 1539 // TODO(johnniwinther): Use [spannable] and [message] to provide better
1464 // information on assertion errors. 1540 // information on assertion errors.
1541 if (spannable == null) {
1542 throw new SpannableAssertionFailure(CURRENT_ELEMENT_SPANNABLE,
1543 "Spannable was null for invariant. Use CURRENT_ELEMENT_SPANNABLE.");
1544 }
1465 if (condition is Function){ 1545 if (condition is Function){
1466 condition = condition(); 1546 condition = condition();
1467 } 1547 }
1468 if (spannable == null || !condition) { 1548 if (!condition) {
1469 if (message is Function) { 1549 if (message is Function) {
1470 message = message(); 1550 message = message();
1471 } 1551 }
1472 throw new SpannableAssertionFailure(spannable, message); 1552 throw new SpannableAssertionFailure(spannable, message);
1473 } 1553 }
1474 return true; 1554 return true;
1475 } 1555 }
1476 1556
1477 /// A sink that drains into /dev/null. 1557 /// A sink that drains into /dev/null.
1478 class NullSink implements EventSink<String> { 1558 class NullSink implements EventSink<String> {
1479 final String name; 1559 final String name;
1480 1560
1481 NullSink(this.name); 1561 NullSink(this.name);
1482 1562
1483 add(String value) {} 1563 add(String value) {}
1484 1564
1485 void addError(Object error) {} 1565 void addError(Object error) {}
1486 1566
1487 void close() {} 1567 void close() {}
1488 1568
1489 toString() => name; 1569 toString() => name;
1490 1570
1491 /// Convenience method for getting an [api.CompilerOutputProvider]. 1571 /// Convenience method for getting an [api.CompilerOutputProvider].
1492 static NullSink outputProvider(String name, String extension) { 1572 static NullSink outputProvider(String name, String extension) {
1493 return new NullSink('$name.$extension'); 1573 return new NullSink('$name.$extension');
1494 } 1574 }
1495 } 1575 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698