Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 } |
| OLD | NEW |