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

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: Remove withCurrentElementAsync 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 {
ahe 2013/08/06 16:29:17 Can you remove this task?
Johnni Winther 2013/08/27 11:05:00 Done.
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,
94 [ConstantSystem constantSystem = DART_CONSTANT_SYSTEM]) 105 [ConstantSystem constantSystem = DART_CONSTANT_SYSTEM])
(...skipping 566 matching lines...) Expand 10 before | Expand all | Expand 10 after
661 return spanFromTokens(annotation.beginToken, annotation.endToken); 672 return spanFromTokens(annotation.beginToken, annotation.endToken);
662 } else { 673 } else {
663 throw 'No error location.'; 674 throw 'No error location.';
664 } 675 }
665 } 676 }
666 677
667 void log(message) { 678 void log(message) {
668 reportDiagnostic(null, message, api.Diagnostic.VERBOSE_INFO); 679 reportDiagnostic(null, message, api.Diagnostic.VERBOSE_INFO);
669 } 680 }
670 681
671 bool run(Uri uri) { 682 Future<bool> run(Uri uri) {
672 totalCompileTime.start(); 683 totalCompileTime.start();
673 try { 684
674 runCompiler(uri); 685 return runCompiler(uri).then((_) {
675 } on CompilerCancelledException catch (exception) { 686 return true;
ahe 2013/08/06 16:29:17 Can't you eliminate this call to then?
Johnni Winther 2013/08/27 11:05:00 Done.
676 log('Error: $exception'); 687 }).catchError((error) {
677 return false; 688 if (error is CompilerCancelledException) {
678 } catch (exception) { 689 log('Error: $error');
690 return false;
691 }
692
679 try { 693 try {
680 if (!hasCrashed) { 694 if (!hasCrashed) {
681 hasCrashed = true; 695 hasCrashed = true;
682 reportDiagnostic(new SourceSpan(uri, 0, 0), 696 reportDiagnostic(new SourceSpan(uri, 0, 0),
683 MessageKind.COMPILER_CRASHED.error().toString(), 697 MessageKind.COMPILER_CRASHED.error().toString(),
684 api.Diagnostic.CRASH); 698 api.Diagnostic.CRASH);
685 pleaseReportCrash(); 699 pleaseReportCrash();
686 } 700 }
687 } catch (doubleFault) { 701 } catch (doubleFault) {
688 // Ignoring exceptions in exception handling. 702 // Ignoring exceptions in exception handling.
689 } 703 }
690 rethrow; 704 throw error;
691 } finally { 705 }).whenComplete(() {
692 tracer.close(); 706 tracer.close();
693 totalCompileTime.stop(); 707 totalCompileTime.stop();
694 } 708 }).then((_) {
695 return !compilationFailed; 709 return !compilationFailed;
ahe 2013/08/06 16:29:17 As it should be handled by this.
710 });
696 } 711 }
697 712
698 bool hasIsolateSupport() => isolateLibrary != null; 713 bool hasIsolateSupport() => isolateLibrary != null;
699 714
700 /** 715 /**
701 * This method is called before [library] import and export scopes have been 716 * This method is called before [library] import and export scopes have been
702 * set up. 717 * set up.
703 */ 718 */
704 void onLibraryScanned(LibraryElement library, Uri uri) { 719 void onLibraryScanned(LibraryElement library, Uri uri) {
705 if (dynamicClass != null) { 720 if (dynamicClass != null) {
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
742 mirrorSystemGetNameFunction = 757 mirrorSystemGetNameFunction =
743 cls.lookupLocalMember(const SourceString('getName')); 758 cls.lookupLocalMember(const SourceString('getName'));
744 } else if (symbolClass == cls) { 759 } else if (symbolClass == cls) {
745 symbolConstructor = cls.constructors.head; 760 symbolConstructor = cls.constructors.head;
746 } else if (symbolImplementationClass == cls) { 761 } else if (symbolImplementationClass == cls) {
747 symbolValidatedConstructor = symbolImplementationClass.lookupConstructor( 762 symbolValidatedConstructor = symbolImplementationClass.lookupConstructor(
748 symbolValidatedConstructorSelector); 763 symbolValidatedConstructorSelector);
749 } 764 }
750 } 765 }
751 766
752 LibraryElement scanBuiltinLibrary(String filename); 767 Future<LibraryElement> scanBuiltinLibrary(String filename);
753 768
754 void initializeSpecialClasses() { 769 void initializeSpecialClasses() {
755 final List missingCoreClasses = []; 770 final List missingCoreClasses = [];
756 ClassElement lookupCoreClass(String name) { 771 ClassElement lookupCoreClass(String name) {
757 ClassElement result = coreLibrary.find(new SourceString(name)); 772 ClassElement result = coreLibrary.find(new SourceString(name));
758 if (result == null) { 773 if (result == null) {
759 missingCoreClasses.add(name); 774 missingCoreClasses.add(name);
760 } 775 }
761 return result; 776 return result;
762 } 777 }
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
818 833
819 Element _filledListConstructor; 834 Element _filledListConstructor;
820 Element get filledListConstructor { 835 Element get filledListConstructor {
821 if (_filledListConstructor != null) return _filledListConstructor; 836 if (_filledListConstructor != null) return _filledListConstructor;
822 Selector callConstructor = new Selector.callConstructor( 837 Selector callConstructor = new Selector.callConstructor(
823 const SourceString("filled"), listClass.getLibrary()); 838 const SourceString("filled"), listClass.getLibrary());
824 return _filledListConstructor = 839 return _filledListConstructor =
825 listClass.lookupConstructor(callConstructor); 840 listClass.lookupConstructor(callConstructor);
826 } 841 }
827 842
828 void scanBuiltinLibraries() { 843 Future scanBuiltinLibraries() {
829 jsHelperLibrary = scanBuiltinLibrary('_js_helper'); 844 return scanBuiltinLibrary('_js_helper').then((LibraryElement library) {
830 interceptorsLibrary = scanBuiltinLibrary('_interceptors'); 845 jsHelperLibrary = library;
831 foreignLibrary = scanBuiltinLibrary('_foreign_helper'); 846 return scanBuiltinLibrary('_interceptors');
832 isolateHelperLibrary = scanBuiltinLibrary('_isolate_helper'); 847 }).then((LibraryElement library) {
848 interceptorsLibrary = library;
849 return scanBuiltinLibrary('_foreign_helper');
850 }).then((LibraryElement library) {
851 foreignLibrary = library;
852 return scanBuiltinLibrary('_isolate_helper');
853 }).then((LibraryElement library) {
854 isolateHelperLibrary = library;
833 855
834 assertMethod = jsHelperLibrary.find(const SourceString('assertHelper')); 856 assertMethod = jsHelperLibrary.find(const SourceString('assertHelper'));
835 identicalFunction = coreLibrary.find(const SourceString('identical')); 857 identicalFunction = coreLibrary.find(const SourceString('identical'));
836 858
837 initializeSpecialClasses(); 859 initializeSpecialClasses();
838 860
839 functionClass.ensureResolved(this); 861 functionClass.ensureResolved(this);
840 functionApplyMethod = 862 functionApplyMethod =
841 functionClass.lookupLocalMember(const SourceString('apply')); 863 functionClass.lookupLocalMember(const SourceString('apply'));
842 jsInvocationMirrorClass.ensureResolved(this); 864 jsInvocationMirrorClass.ensureResolved(this);
843 invokeOnMethod = jsInvocationMirrorClass.lookupLocalMember(INVOKE_ON); 865 invokeOnMethod = jsInvocationMirrorClass.lookupLocalMember(INVOKE_ON);
844 866
845 if (preserveComments) { 867 if (preserveComments) {
846 var uri = new Uri(scheme: 'dart', path: 'mirrors'); 868 var uri = new Uri(scheme: 'dart', path: 'mirrors');
847 LibraryElement libraryElement = 869 return libraryLoader.loadLibrary(uri, null, uri).then(
848 libraryLoader.loadLibrary(uri, null, uri); 870 (LibraryElement libraryElement) {
849 documentClass = libraryElement.find(const SourceString('Comment')); 871 documentClass = libraryElement.find(const SourceString('Comment'));
850 } 872 });
873 }
874 });
851 } 875 }
852 876
853 void importHelperLibrary(LibraryElement library) { 877 void importHelperLibrary(LibraryElement library) {
854 if (jsHelperLibrary != null) { 878 if (jsHelperLibrary != null) {
855 libraryLoader.importLibrary(library, jsHelperLibrary, null); 879 libraryLoader.importLibrary(library, jsHelperLibrary, null);
856 } 880 }
857 } 881 }
858 882
859 /** 883 /**
860 * Get an [Uri] pointing to a patch for the dart: library with 884 * Get an [Uri] pointing to a patch for the dart: library with
861 * the given path. Returns null if there is no patch. 885 * the given path. Returns null if there is no patch.
862 */ 886 */
863 Uri resolvePatchUri(String dartLibraryPath); 887 Uri resolvePatchUri(String dartLibraryPath);
864 888
865 void runCompiler(Uri uri) { 889 Future runCompiler(Uri uri) {
866 // TODO(ahe): This prevents memory leaks when invoking the compiler 890 // TODO(ahe): This prevents memory leaks when invoking the compiler
867 // multiple times. Implement a better mechanism where StringWrapper 891 // multiple times. Implement a better mechanism where StringWrapper
868 // instances are shared on a per library basis. 892 // instances are shared on a per library basis.
869 SourceString.canonicalizedValues.clear(); 893 SourceString.canonicalizedValues.clear();
870 894
871 assert(uri != null || analyzeOnly); 895 assert(uri != null || analyzeOnly);
872 scanBuiltinLibraries(); 896 return scanBuiltinLibraries().then((_) {
873 if (librariesToAnalyzeWhenRun != null) { 897 if (librariesToAnalyzeWhenRun != null) {
874 for (Uri libraryUri in librariesToAnalyzeWhenRun) { 898 return Future.forEach(librariesToAnalyzeWhenRun, (libraryUri) {
875 log('analyzing $libraryUri ($buildId)'); 899 log('analyzing $libraryUri ($buildId)');
876 libraryLoader.loadLibrary(libraryUri, null, libraryUri); 900 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 }); 901 });
921 } 902 }
903 }).then((_) {
904 if (uri != null) {
905 if (analyzeOnly) {
906 log('analyzing $uri ($buildId)');
907 } else {
908 log('compiling $uri ($buildId)');
909 }
910 return libraryLoader.loadLibrary(uri, null, uri)
911 .then((LibraryElement library) {
912 mainApp = library;
913 });
914 }
915 }).then((_) {
916 Element main = null;
ahe 2013/08/06 16:29:17 I think it would make sense to move the rest of th
Johnni Winther 2013/08/27 11:05:00 Done.
917 if (mainApp != null) {
918 main = mainApp.find(MAIN);
919 if (main == null) {
920 if (!analyzeOnly) {
921 // Allow analyze only of libraries with no main.
922 reportFatalError(
923 mainApp,
924 MessageKind.GENERIC,
925 {'text': 'Error: Could not find "${MAIN.slowToString()}".'});
926 } else if (!analyzeAll) {
927 reportFatalError(
928 mainApp,
929 MessageKind.GENERIC,
930 {'text': 'Error: Could not find "${MAIN.slowToString()}". '
931 'No source will be analyzed. '
932 'Use "--analyze-all" to analyze all code in the library.'});
933 }
934 } else {
935 if (!main.isFunction()) {
936 reportFatalError(
937 main,
938 MessageKind.GENERIC,
939 {'text': 'Error: "${MAIN.slowToString()}" is not a function.'});
940 }
941 FunctionElement mainMethod = main;
942 FunctionSignature parameters = mainMethod.computeSignature(this);
943 parameters.forEachParameter((Element parameter) {
944 reportError(
945 parameter,
946 MessageKind.GENERIC,
947 {'text':
948 'Error: "${MAIN.slowToString()}" cannot have parameters.'});
949 });
950 }
922 951
923 mirrorUsageAnalyzerTask.analyzeUsage(mainApp); 952 mirrorUsageAnalyzerTask.analyzeUsage(mainApp);
924 953
925 // In order to see if a library is deferred, we must compute the 954 // In order to see if a library is deferred, we must compute the
926 // compile-time constants that are metadata. This means adding 955 // compile-time constants that are metadata. This means adding
927 // something to the resolution queue. So we cannot wait with 956 // something to the resolution queue. So we cannot wait with
928 // this until after the resolution queue is processed. 957 // this until after the resolution queue is processed.
929 // TODO(ahe): Clean this up, for example, by not enqueueing 958 // TODO(ahe): Clean this up, for example, by not enqueueing
930 // classes only used for metadata. 959 // classes only used for metadata.
931 deferredLoadTask.findDeferredLibraries(mainApp); 960 deferredLoadTask.findDeferredLibraries(mainApp);
932 } 961 }
933 962
934 log('Resolving...'); 963 log('Resolving...');
935 phase = PHASE_RESOLVING; 964 phase = PHASE_RESOLVING;
936 if (analyzeAll) { 965 if (analyzeAll) {
937 libraries.forEach( 966 libraries.forEach(
938 (_, lib) => fullyEnqueueLibrary(lib, enqueuer.resolution)); 967 (_, lib) => fullyEnqueueLibrary(lib, enqueuer.resolution));
939 } 968 }
940 // Elements required by enqueueHelpers are global dependencies 969 // Elements required by enqueueHelpers are global dependencies
941 // that are not pulled in by a particular element. 970 // that are not pulled in by a particular element.
942 backend.enqueueHelpers(enqueuer.resolution, globalDependencies); 971 backend.enqueueHelpers(enqueuer.resolution, globalDependencies);
943 processQueue(enqueuer.resolution, main); 972 processQueue(enqueuer.resolution, main);
944 enqueuer.resolution.logSummary(log); 973 enqueuer.resolution.logSummary(log);
945 974
946 if (compilationFailed) return; 975 if (compilationFailed) return;
947 if (analyzeOnly) return; 976 if (analyzeOnly) return;
948 assert(main != null); 977 assert(main != null);
949 phase = PHASE_DONE_RESOLVING; 978 phase = PHASE_DONE_RESOLVING;
950 979
951 // TODO(ahe): Remove this line. Eventually, enqueuer.resolution 980 // TODO(ahe): Remove this line. Eventually, enqueuer.resolution
952 // should know this. 981 // should know this.
953 world.populate(); 982 world.populate();
954 // Compute whole-program-knowledge that the backend needs. (This might 983 // Compute whole-program-knowledge that the backend needs. (This might
955 // require the information computed in [world.populate].) 984 // require the information computed in [world.populate].)
956 backend.onResolutionComplete(); 985 backend.onResolutionComplete();
957 986
958 deferredLoadTask.onResolutionComplete(main); 987 deferredLoadTask.onResolutionComplete(main);
959 988
960 log('Inferring types...'); 989 log('Inferring types...');
961 typesTask.onResolutionComplete(main); 990 typesTask.onResolutionComplete(main);
962 991
963 log('Compiling...'); 992 log('Compiling...');
964 phase = PHASE_COMPILING; 993 phase = PHASE_COMPILING;
965 // TODO(johnniwinther): Move these to [CodegenEnqueuer]. 994 // TODO(johnniwinther): Move these to [CodegenEnqueuer].
966 if (hasIsolateSupport()) { 995 if (hasIsolateSupport()) {
967 enqueuer.codegen.addToWorkList( 996 enqueuer.codegen.addToWorkList(
968 isolateHelperLibrary.find(Compiler.START_ROOT_ISOLATE)); 997 isolateHelperLibrary.find(Compiler.START_ROOT_ISOLATE));
969 enqueuer.codegen.registerGetOfStaticFunction(mainApp.find(MAIN)); 998 enqueuer.codegen.registerGetOfStaticFunction(mainApp.find(MAIN));
970 } 999 }
971 if (enabledNoSuchMethod) { 1000 if (enabledNoSuchMethod) {
972 enqueuer.codegen.registerInvocation(noSuchMethodSelector); 1001 enqueuer.codegen.registerInvocation(noSuchMethodSelector);
973 enqueuer.codegen.addToWorkList(createInvocationMirrorElement); 1002 enqueuer.codegen.addToWorkList(createInvocationMirrorElement);
974 } 1003 }
975 if (compileAll) { 1004 if (compileAll) {
976 libraries.forEach((_, lib) => fullyEnqueueLibrary(lib, enqueuer.codegen)); 1005 libraries.forEach((_, lib) => fullyEnqueueLibrary(lib,
977 } 1006 enqueuer.codegen));
978 processQueue(enqueuer.codegen, main); 1007 }
979 enqueuer.codegen.logSummary(log); 1008 processQueue(enqueuer.codegen, main);
1009 enqueuer.codegen.logSummary(log);
980 1010
981 if (compilationFailed) return; 1011 if (compilationFailed) return;
982 1012
983 backend.assembleProgram(); 1013 backend.assembleProgram();
984 1014
985 checkQueues(); 1015 checkQueues();
986 1016
987 if (compilationFailed) { 1017 if (compilationFailed) {
988 assembledCode = null; // Signals failure. 1018 assembledCode = null; // Signals failure.
989 } 1019 }
1020 });
990 } 1021 }
991 1022
992 void fullyEnqueueLibrary(LibraryElement library, Enqueuer world) { 1023 void fullyEnqueueLibrary(LibraryElement library, Enqueuer world) {
993 void enqueueAll(Element element) { 1024 void enqueueAll(Element element) {
994 fullyEnqueueTopLevelElement(element, world); 1025 fullyEnqueueTopLevelElement(element, world);
995 } 1026 }
996 library.implementation.forEachLocalMember(enqueueAll); 1027 library.implementation.forEachLocalMember(enqueueAll);
997 } 1028 }
998 1029
999 void fullyEnqueueTopLevelElement(Element element, Enqueuer world) { 1030 void fullyEnqueueTopLevelElement(Element element, Enqueuer world) {
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after
1311 Uri translateResolvedUri(LibraryElement importingLibrary, 1342 Uri translateResolvedUri(LibraryElement importingLibrary,
1312 Uri resolvedUri, Node node) { 1343 Uri resolvedUri, Node node) {
1313 unimplemented('Compiler.translateResolvedUri'); 1344 unimplemented('Compiler.translateResolvedUri');
1314 } 1345 }
1315 1346
1316 /** 1347 /**
1317 * Reads the script specified by the [readableUri]. 1348 * Reads the script specified by the [readableUri].
1318 * 1349 *
1319 * See [LibraryLoader] for terminology on URIs. 1350 * See [LibraryLoader] for terminology on URIs.
1320 */ 1351 */
1321 Script readScript(Uri readableUri, [Node node]) { 1352 Future<Script> readScript(Uri readableUri, [Element element, Node node]) {
1322 unimplemented('Compiler.readScript'); 1353 unimplemented('Compiler.readScript');
1323 } 1354 }
1324 1355
1325 String get legDirectory { 1356 String get legDirectory {
1326 unimplemented('Compiler.legDirectory'); 1357 unimplemented('Compiler.legDirectory');
1327 } 1358 }
1328 1359
1329 // TODO(karlklose): split into findHelperFunction and findHelperClass and 1360 // TODO(karlklose): split into findHelperFunction and findHelperClass and
1330 // add a check that the element has the expected kind. 1361 // add a check that the element has the expected kind.
1331 Element findHelper(SourceString name) 1362 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: 1486 * [invariant] as the argument to an [:assert:] statement:
1456 * 1487 *
1457 * assert(invariant(position, isValid)); 1488 * assert(invariant(position, isValid));
1458 * 1489 *
1459 * [spannable] must be non-null and will be used to provide positional 1490 * [spannable] must be non-null and will be used to provide positional
1460 * information in the generated error message. 1491 * information in the generated error message.
1461 */ 1492 */
1462 bool invariant(Spannable spannable, var condition, {var message: null}) { 1493 bool invariant(Spannable spannable, var condition, {var message: null}) {
1463 // TODO(johnniwinther): Use [spannable] and [message] to provide better 1494 // TODO(johnniwinther): Use [spannable] and [message] to provide better
1464 // information on assertion errors. 1495 // information on assertion errors.
1496 if (spannable == null) {
1497 throw new SpannableAssertionFailure(CURRENT_ELEMENT_SPANNABLE,
1498 "Spannable was null for invariant. Use CURRENT_ELEMENT_SPANNABLE.");
1499 }
1465 if (condition is Function){ 1500 if (condition is Function){
1466 condition = condition(); 1501 condition = condition();
1467 } 1502 }
1468 if (spannable == null || !condition) { 1503 if (!condition) {
1469 if (message is Function) { 1504 if (message is Function) {
1470 message = message(); 1505 message = message();
1471 } 1506 }
1472 throw new SpannableAssertionFailure(spannable, message); 1507 throw new SpannableAssertionFailure(spannable, message);
1473 } 1508 }
1474 return true; 1509 return true;
1475 } 1510 }
1476 1511
1477 /// A sink that drains into /dev/null. 1512 /// A sink that drains into /dev/null.
1478 class NullSink implements EventSink<String> { 1513 class NullSink implements EventSink<String> {
1479 final String name; 1514 final String name;
1480 1515
1481 NullSink(this.name); 1516 NullSink(this.name);
1482 1517
1483 add(String value) {} 1518 add(String value) {}
1484 1519
1485 void addError(Object error) {} 1520 void addError(Object error) {}
1486 1521
1487 void close() {} 1522 void close() {}
1488 1523
1489 toString() => name; 1524 toString() => name;
1490 1525
1491 /// Convenience method for getting an [api.CompilerOutputProvider]. 1526 /// Convenience method for getting an [api.CompilerOutputProvider].
1492 static NullSink outputProvider(String name, String extension) { 1527 static NullSink outputProvider(String name, String extension) {
1493 return new NullSink('$name.$extension'); 1528 return new NullSink('$name.$extension');
1494 } 1529 }
1495 } 1530 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698