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 js_backend; | 5 part of js_backend; |
| 6 | 6 |
| 7 const VERBOSE_OPTIMIZER_HINTS = false; | 7 const VERBOSE_OPTIMIZER_HINTS = false; |
| 8 | 8 |
| 9 class JavaScriptItemCompilationContext extends ItemCompilationContext { | 9 class JavaScriptItemCompilationContext extends ItemCompilationContext { |
| 10 final Set<HInstruction> boundsChecked = new Set<HInstruction>(); | 10 final Set<HInstruction> boundsChecked = new Set<HInstruction>(); |
| (...skipping 486 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 497 JavaScriptConstantTask constantCompilerTask; | 497 JavaScriptConstantTask constantCompilerTask; |
| 498 | 498 |
| 499 JavaScriptImpactTransformer impactTransformer; | 499 JavaScriptImpactTransformer impactTransformer; |
| 500 | 500 |
| 501 PatchResolverTask patchResolverTask; | 501 PatchResolverTask patchResolverTask; |
| 502 | 502 |
| 503 bool enabledNoSuchMethod = false; | 503 bool enabledNoSuchMethod = false; |
| 504 | 504 |
| 505 SourceInformationStrategy sourceInformationStrategy; | 505 SourceInformationStrategy sourceInformationStrategy; |
| 506 | 506 |
| 507 JavaScriptBackendSerialization serialization; | |
| 508 | |
| 509 final NativeData nativeData = new NativeData(); | |
| 510 | |
| 507 final BackendHelpers helpers; | 511 final BackendHelpers helpers; |
| 508 final BackendImpacts impacts; | 512 final BackendImpacts impacts; |
| 509 | 513 |
| 510 JavaScriptBackend(Compiler compiler, | 514 JavaScriptBackend(Compiler compiler, |
| 511 {bool generateSourceMap: true, | 515 {bool generateSourceMap: true, |
| 512 bool useStartupEmitter: false, | 516 bool useStartupEmitter: false, |
| 513 bool useNewSourceInfo: false}) | 517 bool useNewSourceInfo: false}) |
| 514 : namer = determineNamer(compiler), | 518 : namer = determineNamer(compiler), |
| 515 oneShotInterceptors = new Map<jsAst.Name, Selector>(), | 519 oneShotInterceptors = new Map<jsAst.Name, Selector>(), |
| 516 interceptedElements = new Map<String, Set<Element>>(), | 520 interceptedElements = new Map<String, Set<Element>>(), |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 535 jsInteropAnalysis = new JsInteropAnalysis(this); | 539 jsInteropAnalysis = new JsInteropAnalysis(this); |
| 536 | 540 |
| 537 noSuchMethodRegistry = new NoSuchMethodRegistry(this); | 541 noSuchMethodRegistry = new NoSuchMethodRegistry(this); |
| 538 constantCompilerTask = new JavaScriptConstantTask(compiler); | 542 constantCompilerTask = new JavaScriptConstantTask(compiler); |
| 539 impactTransformer = new JavaScriptImpactTransformer(this); | 543 impactTransformer = new JavaScriptImpactTransformer(this); |
| 540 patchResolverTask = new PatchResolverTask(compiler); | 544 patchResolverTask = new PatchResolverTask(compiler); |
| 541 functionCompiler = compiler.useCpsIr | 545 functionCompiler = compiler.useCpsIr |
| 542 ? new CpsFunctionCompiler( | 546 ? new CpsFunctionCompiler( |
| 543 compiler, this, sourceInformationStrategy) | 547 compiler, this, sourceInformationStrategy) |
| 544 : new SsaFunctionCompiler(this, sourceInformationStrategy); | 548 : new SsaFunctionCompiler(this, sourceInformationStrategy); |
| 549 serialization = new JavaScriptBackendSerialization(this); | |
| 545 } | 550 } |
| 546 | 551 |
| 547 ConstantSystem get constantSystem => constants.constantSystem; | 552 ConstantSystem get constantSystem => constants.constantSystem; |
| 548 | 553 |
| 549 DiagnosticReporter get reporter => compiler.reporter; | 554 DiagnosticReporter get reporter => compiler.reporter; |
| 550 | 555 |
| 551 CoreClasses get coreClasses => compiler.coreClasses; | 556 CoreClasses get coreClasses => compiler.coreClasses; |
| 552 | 557 |
| 553 CoreTypes get coreTypes => compiler.coreTypes; | 558 CoreTypes get coreTypes => compiler.coreTypes; |
| 554 | 559 |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 604 bool registerUse = false; | 609 bool registerUse = false; |
| 605 if (element == helpers.streamIteratorConstructor || | 610 if (element == helpers.streamIteratorConstructor || |
| 606 element == helpers.compiler.symbolConstructor || | 611 element == helpers.compiler.symbolConstructor || |
| 607 element == helpers.compiler.symbolValidatedConstructor || | 612 element == helpers.compiler.symbolValidatedConstructor || |
| 608 element == helpers.syncCompleterConstructor || | 613 element == helpers.syncCompleterConstructor || |
| 609 element == coreClasses.symbolClass || | 614 element == coreClasses.symbolClass || |
| 610 element == helpers.objectNoSuchMethod) { | 615 element == helpers.objectNoSuchMethod) { |
| 611 // TODO(johnniwinther): These are valid but we could be more precise. | 616 // TODO(johnniwinther): These are valid but we could be more precise. |
| 612 registerUse = true; | 617 registerUse = true; |
| 613 } else if (element.implementationLibrary.isPatch || | 618 } else if (element.implementationLibrary.isPatch || |
| 619 // Needed to detect deserialized patch elements. | |
| 620 (element.library.isPlatformLibrary && | |
| 621 element.sourcePosition.uri.path.contains('_internal/js_runtime /lib/')) || | |
|
Siggi Cherem (dart-lang)
2016/03/16 23:40:14
nit: 80 (same below)
Siggi Cherem (dart-lang)
2016/03/16 23:40:14
do we have guarantees that the uri will contain th
Johnni Winther
2016/03/17 10:49:37
Done.
Johnni Winther
2016/03/17 10:49:37
This is not for patch elements (we must register t
| |
| 614 element.library == helpers.jsHelperLibrary || | 622 element.library == helpers.jsHelperLibrary || |
| 615 element.library == helpers.interceptorsLibrary || | 623 element.library == helpers.interceptorsLibrary || |
| 616 element.library == helpers.isolateHelperLibrary) { | 624 element.library == helpers.isolateHelperLibrary) { |
| 617 // TODO(johnniwinther): We should be more precise about these. | 625 // TODO(johnniwinther): We should be more precise about these. |
| 618 registerUse = true; | 626 registerUse = true; |
| 619 } else if (element == coreClasses.listClass || | 627 } else if (element == coreClasses.listClass || |
| 620 element == helpers.mapLiteralClass || | 628 element == helpers.mapLiteralClass || |
| 621 element == coreClasses.functionClass || | 629 element == coreClasses.functionClass || |
| 622 element == coreClasses.stringClass) { | 630 element == coreClasses.stringClass) { |
| 623 // TODO(johnniwinther): Avoid these. | 631 // TODO(johnniwinther): Avoid these. |
| 624 registerUse = true; | 632 registerUse = true; |
| 625 } | 633 } |
| 626 if (!registerUse) { | 634 if (!registerUse) { |
| 627 assert(invariant(element, false, | 635 assert(invariant(element, false, |
|
Siggi Cherem (dart-lang)
2016/03/16 23:40:14
Seems like the `registerUse` logic is mainly for t
Johnni Winther
2016/03/17 10:49:37
Good point. Done.
| |
| 628 message: "Backend use of $element is not allowed.")); | 636 message: "Backend use of $element is not allowed ${element.sourcePos ition}.")); |
| 629 return element; | 637 return element; |
| 630 } | 638 } |
| 631 helpersUsed.add(element.declaration); | 639 helpersUsed.add(element.declaration); |
| 632 if (element.isClass && element.isPatched) { | 640 if (element.isClass && element.isPatched) { |
| 633 // Both declaration and implementation may declare fields, so we | 641 // Both declaration and implementation may declare fields, so we |
| 634 // add both to the list of helpers. | 642 // add both to the list of helpers. |
| 635 helpersUsed.add(element.implementation); | 643 helpersUsed.add(element.implementation); |
| 636 } | 644 } |
| 637 } | 645 } |
| 638 return element; | 646 return element; |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 705 return !selector.isGetter && !compiler.hasIncrementalSupport; | 713 return !selector.isGetter && !compiler.hasIncrementalSupport; |
| 706 } | 714 } |
| 707 | 715 |
| 708 /** | 716 /** |
| 709 * Returns `true` if [member] is called from a subclass via `super`. | 717 * Returns `true` if [member] is called from a subclass via `super`. |
| 710 */ | 718 */ |
| 711 bool isAliasedSuperMember(FunctionElement member) { | 719 bool isAliasedSuperMember(FunctionElement member) { |
| 712 return aliasedSuperMembers.contains(member); | 720 return aliasedSuperMembers.contains(member); |
| 713 } | 721 } |
| 714 | 722 |
| 715 /// The JavaScript names for elements implemented via typed JavaScript | |
| 716 /// interop. | |
| 717 Map<Element, String> jsInteropNames = <Element, String>{}; | |
| 718 | |
| 719 /// The JavaScript names for native JavaScript elements implemented. | |
| 720 Map<Element, String> nativeMemberName = <Element, String>{}; | |
| 721 | |
| 722 /// Tag info for native JavaScript classes names. See | |
| 723 /// [setNativeClassTagInfo]. | |
| 724 Map<ClassElement, String> nativeClassTagInfo = <ClassElement, String>{}; | |
| 725 | |
| 726 /// Returns `true` if [element] is explicitly marked as part of JsInterop. | |
| 727 bool _isJsInterop(Element element) { | |
| 728 return jsInteropNames.containsKey(element.declaration); | |
| 729 } | |
| 730 | |
| 731 /// Returns [element] as an explicit part of JsInterop. The js interop name is | |
| 732 /// expected to be computed later. | |
| 733 void markAsJsInterop(Element element) { | |
| 734 jsInteropNames[element.declaration] = null; | |
| 735 } | |
| 736 | |
| 737 /// Sets the explicit js interop [name] for [element]. | |
| 738 void setJsInteropName(Element element, String name) { | |
| 739 assert(invariant(element, | |
| 740 isJsInterop(element), | |
| 741 message: | |
| 742 'Element $element is not js interop but given a js interop name.')); | |
| 743 jsInteropNames[element.declaration] = name; | |
| 744 } | |
| 745 | |
| 746 /// Returns the explicit js interop name for [element]. | |
| 747 String getJsInteropName(Element element) { | |
| 748 return jsInteropNames[element.declaration]; | |
| 749 } | |
| 750 | |
| 751 /// Returns `true` if [element] is part of JsInterop. | 723 /// Returns `true` if [element] is part of JsInterop. |
| 752 @override | 724 @override |
| 753 bool isJsInterop(Element element) { | 725 bool isJsInterop(Element element) => nativeData.isJsInterop(element); |
| 754 // An function is part of JsInterop in the following cases: | |
| 755 // * It has a jsInteropName annotation | |
| 756 // * It is external member of a class or library tagged as JsInterop. | |
| 757 if (element.isFunction || element.isConstructor || element.isAccessor) { | |
| 758 FunctionElement function = element; | |
| 759 if (!function.isExternal) return false; | |
| 760 | |
| 761 if (_isJsInterop(function)) return true; | |
| 762 if (function.isClassMember) return isJsInterop(function.contextClass); | |
| 763 if (function.isTopLevel) return isJsInterop(function.library); | |
| 764 return false; | |
| 765 } else { | |
| 766 return _isJsInterop(element); | |
| 767 } | |
| 768 } | |
| 769 | |
| 770 /// Returns `true` if the name of [element] is fixed for the generated | |
| 771 /// JavaScript. | |
| 772 bool hasFixedBackendName(Element element) { | |
| 773 return isJsInterop(element) || | |
| 774 nativeMemberName.containsKey(element.declaration); | |
| 775 } | |
| 776 | |
| 777 String _jsNameHelper(Element element) { | |
| 778 String jsInteropName = jsInteropNames[element.declaration]; | |
| 779 assert(invariant(element, | |
| 780 !(_isJsInterop(element) && jsInteropName == null), | |
| 781 message: | |
| 782 'Element $element is js interop but js interop name has not yet ' | |
| 783 'been computed.')); | |
| 784 if (jsInteropName != null && jsInteropName.isNotEmpty) { | |
| 785 return jsInteropName; | |
| 786 } | |
| 787 return element.isLibrary ? 'self' : element.name; | |
| 788 } | |
| 789 | |
| 790 /// Computes the name for [element] to use in the generated JavaScript. This | |
| 791 /// is either given through a native annotation or a js interop annotation. | |
| 792 String getFixedBackendName(Element element) { | |
| 793 String name = nativeMemberName[element.declaration]; | |
| 794 if (name == null && isJsInterop(element)) { | |
| 795 // If an element isJsInterop but _isJsInterop is false that means it is | |
| 796 // considered interop as the parent class is interop. | |
| 797 name = _jsNameHelper( | |
| 798 element.isConstructor ? element.enclosingClass : element); | |
| 799 nativeMemberName[element.declaration] = name; | |
| 800 } | |
| 801 return name; | |
| 802 } | |
| 803 | 726 |
| 804 /// Whether [element] corresponds to a native JavaScript construct either | 727 /// Whether [element] corresponds to a native JavaScript construct either |
| 805 /// through the native mechanism (`@Native(...)` or the `native` pseudo | 728 /// through the native mechanism (`@Native(...)` or the `native` pseudo |
| 806 /// keyword) which is only allowed for internal libraries or via the typed | 729 /// keyword) which is only allowed for internal libraries or via the typed |
| 807 /// JavaScriptInterop mechanism which is allowed for user libraries. | 730 /// JavaScriptInterop mechanism which is allowed for user libraries. |
| 808 @override | 731 @override |
| 809 bool isNative(Element element) { | 732 bool isNative(Element element) => nativeData.isNative(element); |
| 810 if (isJsInterop(element)) return true; | |
| 811 if (element.isClass) { | |
| 812 return nativeClassTagInfo.containsKey(element.declaration); | |
| 813 } else { | |
| 814 return nativeMemberName.containsKey(element.declaration); | |
| 815 } | |
| 816 } | |
| 817 | |
| 818 /// Sets the native [name] for the member [element]. This name is used for | |
| 819 /// [element] in the generated JavaScript. | |
| 820 void setNativeMemberName(MemberElement element, String name) { | |
| 821 // TODO(johnniwinther): Avoid setting this more than once. The enqueuer | |
| 822 // might enqueue [element] several times (before processing it) and computes | |
| 823 // name on each call to `internalAddToWorkList`. | |
| 824 assert(invariant(element, | |
| 825 nativeMemberName[element.declaration] == null || | |
| 826 nativeMemberName[element.declaration] == name, | |
| 827 message: | |
| 828 "Native member name set inconsistently on $element: " | |
| 829 "Existing name '${nativeMemberName[element.declaration]}', " | |
| 830 "new name '$name'.")); | |
| 831 nativeMemberName[element.declaration] = name; | |
| 832 } | |
| 833 | |
| 834 /// Sets the native tag info for [cls]. | |
| 835 /// | |
| 836 /// The tag info string contains comma-separated 'words' which are either | |
| 837 /// dispatch tags (having JavaScript identifier syntax) and directives that | |
| 838 /// begin with `!`. | |
| 839 void setNativeClassTagInfo(ClassElement cls, String tagInfo) { | |
| 840 // TODO(johnniwinther): Assert that this is only called once. The memory | |
| 841 // compiler copies pre-processed elements into a new compiler through | |
| 842 // [Compiler.onLibraryScanned] and thereby causes multiple calls to this | |
| 843 // method. | |
| 844 assert(invariant(cls, | |
| 845 nativeClassTagInfo[cls.declaration] == null || | |
| 846 nativeClassTagInfo[cls.declaration] == tagInfo, | |
| 847 message: | |
| 848 "Native tag info set inconsistently on $cls: " | |
| 849 "Existing tag info '${nativeClassTagInfo[cls.declaration]}', " | |
| 850 "new tag info '$tagInfo'.")); | |
| 851 nativeClassTagInfo[cls.declaration] = tagInfo; | |
| 852 } | |
| 853 | |
| 854 /// Returns the list of native tag words for [cls]. | |
| 855 List<String> getNativeTagsOfClassRaw(ClassElement cls) { | |
| 856 String quotedName = nativeClassTagInfo[cls.declaration]; | |
| 857 return quotedName.substring(1, quotedName.length - 1).split(','); | |
| 858 } | |
| 859 | |
| 860 /// Returns the list of non-directive native tag words for [cls]. | |
| 861 List<String> getNativeTagsOfClass(ClassElement cls) { | |
| 862 return getNativeTagsOfClassRaw(cls).where( | |
| 863 (s) => !s.startsWith('!')).toList(); | |
| 864 } | |
| 865 | |
| 866 /// Returns `true` if [cls] has a `!nonleaf` tag word. | |
| 867 bool hasNativeTagsForcedNonLeaf(ClassElement cls) { | |
| 868 return getNativeTagsOfClassRaw(cls).contains('!nonleaf'); | |
| 869 } | |
| 870 | 733 |
| 871 bool isNativeOrExtendsNative(ClassElement element) { | 734 bool isNativeOrExtendsNative(ClassElement element) { |
| 872 if (element == null) return false; | 735 if (element == null) return false; |
| 873 if (isNative(element) || isJsInterop(element)) { | 736 if (isNative(element) || isJsInterop(element)) { |
| 874 return true; | 737 return true; |
| 875 } | 738 } |
| 876 assert(element.isResolved); | 739 assert(element.isResolved); |
| 877 return isNativeOrExtendsNative(element.superclass); | 740 return isNativeOrExtendsNative(element.superclass); |
| 878 } | 741 } |
| 879 | 742 |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1002 | 865 |
| 1003 void validateInterceptorImplementsAllObjectMethods( | 866 void validateInterceptorImplementsAllObjectMethods( |
| 1004 ClassElement interceptorClass) { | 867 ClassElement interceptorClass) { |
| 1005 if (interceptorClass == null) return; | 868 if (interceptorClass == null) return; |
| 1006 interceptorClass.ensureResolved(resolution); | 869 interceptorClass.ensureResolved(resolution); |
| 1007 coreClasses.objectClass.forEachMember((_, Element member) { | 870 coreClasses.objectClass.forEachMember((_, Element member) { |
| 1008 if (member.isGenerativeConstructor) return; | 871 if (member.isGenerativeConstructor) return; |
| 1009 Element interceptorMember = interceptorClass.lookupMember(member.name); | 872 Element interceptorMember = interceptorClass.lookupMember(member.name); |
| 1010 // Interceptors must override all Object methods due to calling convention | 873 // Interceptors must override all Object methods due to calling convention |
| 1011 // differences. | 874 // differences. |
| 1012 assert(interceptorMember.enclosingClass == interceptorClass); | 875 assert(invariant( |
| 876 interceptorMember, | |
| 877 interceptorMember.enclosingClass == interceptorClass, | |
| 878 message: | |
| 879 "Member ${member.name} not overridden in ${interceptorClass}. " | |
| 880 "Found $interceptorMember from " | |
| 881 "${interceptorMember.enclosingClass}.")); | |
| 1013 }); | 882 }); |
| 1014 } | 883 } |
| 1015 | 884 |
| 1016 void addInterceptorsForNativeClassMembers( | 885 void addInterceptorsForNativeClassMembers( |
| 1017 ClassElement cls, Enqueuer enqueuer) { | 886 ClassElement cls, Enqueuer enqueuer) { |
| 1018 if (enqueuer.isResolutionQueue) { | 887 if (enqueuer.isResolutionQueue) { |
| 1019 cls.ensureResolved(resolution); | 888 cls.ensureResolved(resolution); |
| 1020 cls.forEachMember((ClassElement classElement, Element member) { | 889 cls.forEachMember((ClassElement classElement, Element member) { |
| 1021 if (member.name == Identifiers.call) { | 890 if (member.name == Identifiers.call) { |
| 1022 reporter.reportErrorMessage( | 891 reporter.reportErrorMessage( |
| (...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1202 compiler.globalDependencies); | 1071 compiler.globalDependencies); |
| 1203 enqueueClass(enqueuer, helpers.jsJavaScriptObjectClass, registry); | 1072 enqueueClass(enqueuer, helpers.jsJavaScriptObjectClass, registry); |
| 1204 enqueueClass(enqueuer, helpers.jsPlainJavaScriptObjectClass, registry); | 1073 enqueueClass(enqueuer, helpers.jsPlainJavaScriptObjectClass, registry); |
| 1205 enqueueClass(enqueuer, helpers.jsJavaScriptFunctionClass, registry); | 1074 enqueueClass(enqueuer, helpers.jsJavaScriptFunctionClass, registry); |
| 1206 } else if (cls == helpers.mapLiteralClass) { | 1075 } else if (cls == helpers.mapLiteralClass) { |
| 1207 // For map literals, the dependency between the implementation class | 1076 // For map literals, the dependency between the implementation class |
| 1208 // and [Map] is not visible, so we have to add it manually. | 1077 // and [Map] is not visible, so we have to add it manually. |
| 1209 Element getFactory(String name, int arity) { | 1078 Element getFactory(String name, int arity) { |
| 1210 // The constructor is on the patch class, but dart2js unit tests don't | 1079 // The constructor is on the patch class, but dart2js unit tests don't |
| 1211 // have a patch class. | 1080 // have a patch class. |
| 1212 ClassElement implementation = cls.patch != null ? cls.patch : cls; | 1081 ClassElement implementation = cls.implementation; |
| 1213 ConstructorElement ctor = implementation.lookupConstructor(name); | 1082 ConstructorElement ctor = implementation.lookupConstructor(name); |
| 1214 if (ctor == null || | 1083 if (ctor == null || |
| 1215 (Name.isPrivateName(name) && | 1084 (Name.isPrivateName(name) && |
| 1216 ctor.library != helpers.mapLiteralClass.library)) { | 1085 ctor.library != helpers.mapLiteralClass.library)) { |
| 1217 reporter.internalError( | 1086 reporter.internalError( |
| 1218 helpers.mapLiteralClass, | 1087 helpers.mapLiteralClass, |
| 1219 "Map literal class ${helpers.mapLiteralClass} missing " | 1088 "Map literal class ${helpers.mapLiteralClass} missing " |
| 1220 "'$name' constructor" | 1089 "'$name' constructor" |
| 1221 " ${helpers.mapLiteralClass.constructors}"); | 1090 " ${helpers.mapLiteralClass.constructors}"); |
| 1222 } | 1091 } |
| 1223 return ctor; | 1092 return ctor; |
| 1224 } | 1093 } |
| 1225 Element getMember(String name) { | 1094 Element getMember(String name) { |
| 1226 // The constructor is on the patch class, but dart2js unit tests don't | 1095 // The constructor is on the patch class, but dart2js unit tests don't |
| 1227 // have a patch class. | 1096 // have a patch class. |
| 1228 ClassElement implementation = cls.patch != null ? cls.patch : cls; | 1097 ClassElement implementation = cls.implementation; |
| 1229 Element element = implementation.lookupLocalMember(name); | 1098 Element element = implementation.lookupLocalMember(name); |
| 1230 if (element == null || !element.isFunction || !element.isStatic) { | 1099 if (element == null || !element.isFunction || !element.isStatic) { |
| 1231 reporter.internalError(helpers.mapLiteralClass, | 1100 reporter.internalError(helpers.mapLiteralClass, |
| 1232 "Map literal class ${helpers.mapLiteralClass} missing " | 1101 "Map literal class ${helpers.mapLiteralClass} missing " |
| 1233 "'$name' static member function"); | 1102 "'$name' static member function"); |
| 1234 } | 1103 } |
| 1235 return element; | 1104 return element; |
| 1236 } | 1105 } |
| 1237 helpers.mapLiteralConstructor = getFactory('_literal', 1); | 1106 helpers.mapLiteralConstructor = getFactory('_literal', 1); |
| 1238 helpers.mapLiteralConstructorEmpty = getFactory('_empty', 0); | 1107 helpers.mapLiteralConstructorEmpty = getFactory('_empty', 0); |
| (...skipping 1427 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2666 @override | 2535 @override |
| 2667 Uri resolvePatchUri(String libraryName, Uri platformConfigUri) { | 2536 Uri resolvePatchUri(String libraryName, Uri platformConfigUri) { |
| 2668 String patchLocation = _patchLocations[libraryName]; | 2537 String patchLocation = _patchLocations[libraryName]; |
| 2669 if (patchLocation == null) return null; | 2538 if (patchLocation == null) return null; |
| 2670 return platformConfigUri.resolve(patchLocation); | 2539 return platformConfigUri.resolve(patchLocation); |
| 2671 } | 2540 } |
| 2672 | 2541 |
| 2673 @override | 2542 @override |
| 2674 ImpactStrategy createImpactStrategy( | 2543 ImpactStrategy createImpactStrategy( |
| 2675 {bool supportDeferredLoad: true, | 2544 {bool supportDeferredLoad: true, |
| 2676 bool supportDumpInfo: true}) { | 2545 bool supportDumpInfo: true, |
| 2546 bool supportSerialization: true}) { | |
| 2677 return new JavaScriptImpactStrategy( | 2547 return new JavaScriptImpactStrategy( |
| 2678 resolution, | 2548 resolution, |
| 2679 compiler.dumpInfoTask, | 2549 compiler.dumpInfoTask, |
| 2680 supportDeferredLoad: supportDeferredLoad, | 2550 supportDeferredLoad: supportDeferredLoad, |
| 2681 supportDumpInfo: supportDumpInfo); | 2551 supportDumpInfo: supportDumpInfo, |
| 2552 supportSerialization: supportSerialization); | |
| 2682 } | 2553 } |
| 2683 } | 2554 } |
| 2684 | 2555 |
| 2685 /// Handling of special annotations for tests. | 2556 /// Handling of special annotations for tests. |
| 2686 class Annotations { | 2557 class Annotations { |
| 2687 static final Uri PACKAGE_EXPECT = | 2558 static final Uri PACKAGE_EXPECT = |
| 2688 new Uri(scheme: 'package', path: 'expect/expect.dart'); | 2559 new Uri(scheme: 'package', path: 'expect/expect.dart'); |
| 2689 | 2560 |
| 2690 final Compiler compiler; | 2561 final Compiler compiler; |
| 2691 | 2562 |
| (...skipping 455 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3147 final Element annotatedElement; | 3018 final Element annotatedElement; |
| 3148 | 3019 |
| 3149 const Dependency(this.constant, this.annotatedElement); | 3020 const Dependency(this.constant, this.annotatedElement); |
| 3150 } | 3021 } |
| 3151 | 3022 |
| 3152 class JavaScriptImpactStrategy extends ImpactStrategy { | 3023 class JavaScriptImpactStrategy extends ImpactStrategy { |
| 3153 final Resolution resolution; | 3024 final Resolution resolution; |
| 3154 final DumpInfoTask dumpInfoTask; | 3025 final DumpInfoTask dumpInfoTask; |
| 3155 final bool supportDeferredLoad; | 3026 final bool supportDeferredLoad; |
| 3156 final bool supportDumpInfo; | 3027 final bool supportDumpInfo; |
| 3028 final bool supportSerialization; | |
| 3157 | 3029 |
| 3158 JavaScriptImpactStrategy(this.resolution, | 3030 JavaScriptImpactStrategy(this.resolution, |
| 3159 this.dumpInfoTask, | 3031 this.dumpInfoTask, |
| 3160 {this.supportDeferredLoad, | 3032 {this.supportDeferredLoad, |
| 3161 this.supportDumpInfo}); | 3033 this.supportDumpInfo, |
| 3034 this.supportSerialization}); | |
| 3162 | 3035 |
| 3163 @override | 3036 @override |
| 3164 void visitImpact(Element element, | 3037 void visitImpact(Element element, |
| 3165 WorldImpact impact, | 3038 WorldImpact impact, |
| 3166 WorldImpactVisitor visitor, | 3039 WorldImpactVisitor visitor, |
| 3167 ImpactUseCase impactUse) { | 3040 ImpactUseCase impactUse) { |
| 3168 // TODO(johnniwinther): Compute the application strategy once for each use. | 3041 // TODO(johnniwinther): Compute the application strategy once for each use. |
| 3169 if (impactUse == ResolutionEnqueuer.IMPACT_USE) { | 3042 if (impactUse == ResolutionEnqueuer.IMPACT_USE) { |
| 3170 if (supportDeferredLoad) { | 3043 if (supportDeferredLoad || supportSerialization) { |
| 3171 impact.apply(visitor); | 3044 impact.apply(visitor); |
| 3172 } else { | 3045 } else { |
| 3173 impact.apply(visitor); | 3046 impact.apply(visitor); |
| 3174 resolution.uncacheWorldImpact(element); | 3047 resolution.uncacheWorldImpact(element); |
| 3175 } | 3048 } |
| 3176 } else if (impactUse == DeferredLoadTask.IMPACT_USE) { | 3049 } else if (impactUse == DeferredLoadTask.IMPACT_USE) { |
| 3177 impact.apply(visitor); | 3050 impact.apply(visitor); |
| 3178 // Impacts are uncached globally in [onImpactUsed]. | 3051 // Impacts are uncached globally in [onImpactUsed]. |
| 3179 } else if (impactUse == DumpInfoTask.IMPACT_USE) { | 3052 } else if (impactUse == DumpInfoTask.IMPACT_USE) { |
| 3180 impact.apply(visitor); | 3053 impact.apply(visitor); |
| 3181 dumpInfoTask.unregisterImpact(element); | 3054 dumpInfoTask.unregisterImpact(element); |
| 3182 } else { | 3055 } else { |
| 3183 impact.apply(visitor); | 3056 impact.apply(visitor); |
| 3184 } | 3057 } |
| 3185 } | 3058 } |
| 3186 | 3059 |
| 3187 @override | 3060 @override |
| 3188 void onImpactUsed(ImpactUseCase impactUse) { | 3061 void onImpactUsed(ImpactUseCase impactUse) { |
| 3189 if (impactUse == DeferredLoadTask.IMPACT_USE) { | 3062 if (impactUse == DeferredLoadTask.IMPACT_USE && |
| 3063 !supportSerialization) { | |
| 3190 resolution.emptyCache(); | 3064 resolution.emptyCache(); |
| 3191 } | 3065 } |
| 3192 } | 3066 } |
| 3193 } | 3067 } |
| OLD | NEW |