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

Side by Side Diff: pkg/compiler/lib/src/js_backend/backend.dart

Issue 1408043002: Move native and js interop properties from the element model to the JS backend (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Cleanup Created 5 years, 2 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
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 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 672 matching lines...) Expand 10 before | Expand all | Expand 10 after
683 683
684 Resolution get resolution => compiler.resolution; 684 Resolution get resolution => compiler.resolution;
685 685
686 /// Returns constant environment for the JavaScript interpretation of the 686 /// Returns constant environment for the JavaScript interpretation of the
687 /// constants. 687 /// constants.
688 JavaScriptConstantCompiler get constants { 688 JavaScriptConstantCompiler get constants {
689 return constantCompilerTask.jsConstantCompiler; 689 return constantCompilerTask.jsConstantCompiler;
690 } 690 }
691 691
692 FunctionElement resolveExternalFunction(FunctionElement element) { 692 FunctionElement resolveExternalFunction(FunctionElement element) {
693 if (isForeign(element) || element.isJsInterop) return element; 693 if (isForeign(element) || isJsInterop(element)) return element;
694 return patchResolverTask.measure(() { 694 return patchResolverTask.measure(() {
695 return patchResolverTask.resolveExternalFunction(element); 695 return patchResolverTask.resolveExternalFunction(element);
696 }); 696 });
697 } 697 }
698 698
699 // TODO(karlklose): Split into findHelperFunction and findHelperClass and 699 // TODO(karlklose): Split into findHelperFunction and findHelperClass and
700 // add a check that the element has the expected kind. 700 // add a check that the element has the expected kind.
701 Element findHelper(String name) => find(jsHelperLibrary, name); 701 Element findHelper(String name) => find(jsHelperLibrary, name);
702 Element findAsyncHelper(String name) => find(asyncLibrary, name); 702 Element findAsyncHelper(String name) => find(asyncLibrary, name);
703 Element findInterceptor(String name) => find(interceptorsLibrary, name); 703 Element findInterceptor(String name) => find(interceptorsLibrary, name);
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
748 748
749 return isAccessibleByReflection(element.declaration); 749 return isAccessibleByReflection(element.declaration);
750 } 750 }
751 751
752 bool canBeUsedForGlobalOptimizations(Element element) { 752 bool canBeUsedForGlobalOptimizations(Element element) {
753 return !usedByBackend(element) && !invokedReflectively(element); 753 return !usedByBackend(element) && !invokedReflectively(element);
754 } 754 }
755 755
756 bool isInterceptorClass(ClassElement element) { 756 bool isInterceptorClass(ClassElement element) {
757 if (element == null) return false; 757 if (element == null) return false;
758 if (Elements.isNativeOrExtendsNative(element)) return true; 758 if (isNativeOrExtendsNative(element)) return true;
759 if (interceptedClasses.contains(element)) return true; 759 if (interceptedClasses.contains(element)) return true;
760 if (classesMixedIntoInterceptedClasses.contains(element)) return true; 760 if (classesMixedIntoInterceptedClasses.contains(element)) return true;
761 return false; 761 return false;
762 } 762 }
763 763
764 jsAst.Name registerOneShotInterceptor(Selector selector) { 764 jsAst.Name registerOneShotInterceptor(Selector selector) {
765 Set<ClassElement> classes = getInterceptedClassesOn(selector.name); 765 Set<ClassElement> classes = getInterceptedClassesOn(selector.name);
766 jsAst.Name name = namer.nameForGetOneShotInterceptor(selector, classes); 766 jsAst.Name name = namer.nameForGetOneShotInterceptor(selector, classes);
767 if (!oneShotInterceptors.containsKey(name)) { 767 if (!oneShotInterceptors.containsKey(name)) {
768 registerSpecializedGetInterceptor(classes); 768 registerSpecializedGetInterceptor(classes);
(...skipping 22 matching lines...) Expand all
791 return !selector.isGetter && !compiler.hasIncrementalSupport; 791 return !selector.isGetter && !compiler.hasIncrementalSupport;
792 } 792 }
793 793
794 /** 794 /**
795 * Returns `true` if [member] is called from a subclass via `super`. 795 * Returns `true` if [member] is called from a subclass via `super`.
796 */ 796 */
797 bool isAliasedSuperMember(FunctionElement member) { 797 bool isAliasedSuperMember(FunctionElement member) {
798 return aliasedSuperMembers.contains(member); 798 return aliasedSuperMembers.contains(member);
799 } 799 }
800 800
801 /// The JavaScript names for elements implemented via typed JavaScript
802 /// interop.
803 Map<Element, String> jsInteropNames = <Element, String>{};
804
805 /// The JavaScript names for native JavaScript elements implemented.
806 Map<Element, String> nativeMemberName = <Element, String>{};
807
808 /// Tag infor for native JavaScript classes names. See
sigurdm 2015/10/21 10:28:28 Remove "infor"?
Johnni Winther 2015/10/22 09:06:03 Done.
809 /// [setNativeClassTagInfo].
810 Map<ClassElement, String> nativeClassTagInfo = <ClassElement, String>{};
811
812 /// Returns `true` if [element] is explicitly mark as part of JsInterop.
sigurdm 2015/10/21 10:28:28 mark -> marked
Johnni Winther 2015/10/22 09:06:03 Done.
813 bool _isJsInterop(Element element) {
814 return jsInteropNames.containsKey(element.declaration);
815 }
816
817 /// Returns [element] as an explicit part of JsInterop. The js interop name is
818 /// expected to be computed later.
819 void markAsJsInterop(Element element) {
820 jsInteropNames[element.declaration] = null;
821 }
822
823 /// Sets the explicit js interop [name] for [element].
824 void setJsInteropName(Element element, String name) {
825 assert(invariant(element,
826 isJsInterop(element),
827 message:
828 'Element $element is not js interop but given a js interop name.'));
829 jsInteropNames[element.declaration] = name;
830 }
831
832 /// Returns the explicit js interop name for [element].
833 String getJsInteropName(Element element) {
834 return jsInteropNames[element.declaration];
835 }
836
837 /// Returns `true` if [element] is part of JsInterop.
838 @override
839 bool isJsInterop(Element element) {
840 // An function is part of JsInterop in the following cases:
841 // * It has a jsInteropName annotation
842 // * It is external member of a class or library tagged as JsInterop.
843 if (element.isFunction || element.isConstructor || element.isAccessor) {
844 FunctionElement function = element;
845 if (!function.isExternal) return false;
846
847 if (_isJsInterop(function)) return true;
848 if (function.isClassMember) return isJsInterop(function.contextClass);
849 if (function.isTopLevel) return isJsInterop(function.library);
850 return false;
851 } else {
852 return _isJsInterop(element);
853 }
854 }
855
856 /// Returns `true` if the name of [element] is fixed by
857 bool hasFixedBackendName(Element element) {
858 return isJsInterop(element) ||
859 nativeMemberName.containsKey(element.declaration);
860 }
861
862 String _jsNameHelper(Element element) {
863 String jsInteropName = jsInteropNames[element.declaration];
864 assert(invariant(element,
865 !(_isJsInterop(element) && jsInteropName == null),
866 message:
867 'Element $element is js interop but js interop name has not yet '
868 'been computed.'));
869 if (jsInteropName != null && jsInteropName.isNotEmpty) {
870 return jsInteropName;
871 }
872 return element.isLibrary ? 'self' : element.name;
873 }
874
875 /// Computes the name for [element] to use in the generated JavaScript. This
876 /// is either given through a native annotation or a
sigurdm 2015/10/21 10:28:28 or a...?? the suspense is killing me!
Johnni Winther 2015/10/22 09:06:03 Cliffhanger... ;)
877 String getFixedBackendName(Element element) {
878 String name = nativeMemberName[element.declaration];
879 if (name == null && isJsInterop(element)) {
880 // If an element isJsInterop but _isJsInterop is false that means it is
881 // considered interop as the parent class is interop.
882 name = _jsNameHelper(
883 element.isConstructor ? element.enclosingClass : element);
884 nativeMemberName[element.declaration] = name;
885 }
886 return name;
887 }
888
889 /// Whether [element] corresponds to a native JavaScript construct either
890 /// through the native mechanism (`@Native(...)` or the `native` pseudo
891 /// keyword) which is only allowed for internal libraries or via the typed
892 /// JavaScriptInterop mechanism which is allowed for user libraries.
893 @override
894 bool isNative(Element element) {
895 if (isJsInterop(element)) return true;
896 if (element.isClass) {
897 return nativeClassTagInfo.containsKey(element.declaration);
898 } else {
899 return nativeMemberName.containsKey(element.declaration);
900 }
901 }
902
903 /// Sets the native [name] for the member [element]. This name is used for
904 /// [element] in the generated JavaScript.
905 void setNativeMemberName(MemberElement element, String name) {
906 // TODO(johnniwinther): Avoid setting this more than once. The enqueuer
907 // might enqueue [element] several times (before processing it) and computes
908 // name on each call to `internalAddToWorkList`.
909 assert(invariant(element,
910 nativeMemberName[element.declaration] == null ||
911 nativeMemberName[element.declaration] == name,
912 message:
913 "Native member name set inconsistently on $element: "
914 "Existing name '${nativeMemberName[element.declaration]}', "
915 "new name '$name'."));
916 nativeMemberName[element.declaration] = name;
917 }
918
919 /// Sets the native tag info for [cls].
920 ///
921 /// The tag info string contains comma-separated 'words' which are either
922 /// dispatch tags (having JavaScript identifier syntax) and directives that
923 /// begin with `!`.
924 void setNativeClassTagInfo(ClassElement cls, String tagInfo) {
925 // TODO(johnniwinther): Assert that this is only called once. The memory
926 // compiler copies pre-processed elements into a new compiler through
927 // [Compiler.onLibraryScanned] and thereby causes multiple calls to this
928 // method.
929 assert(invariant(cls,
930 nativeClassTagInfo[cls.declaration] == null ||
931 nativeClassTagInfo[cls.declaration] == tagInfo,
932 message:
933 "Native tag info set inconsistently on $cls: "
934 "Existing tag info '${nativeClassTagInfo[cls.declaration]}', "
935 "new tag info '$tagInfo'."));
936 nativeClassTagInfo[cls.declaration] = tagInfo;
937 }
938
939 /// Returns the list of native tag words for [cls].
940 List<String> getNativeTagsOfClassRaw(ClassElement cls) {
941 String quotedName = nativeClassTagInfo[cls.declaration];
942 return quotedName.substring(1, quotedName.length - 1).split(',');
943 }
944
945 /// Returns the list of non-directive native tag words for [cls].
946 List<String> getNativeTagsOfClass(ClassElement cls) {
947 return getNativeTagsOfClassRaw(cls).where(
948 (s) => !s.startsWith('!')).toList();
949 }
950
951 /// Returns `true` if [cls] has a `!nonleaf` tag word.
952 bool hasNativeTagsForcedNonLeaf(ClassElement cls) {
953 return getNativeTagsOfClassRaw(cls).contains('!nonleaf');
954 }
955
956 bool isNativeOrExtendsNative(ClassElement element) {
957 if (element == null) return false;
958 if (isNative(element) || isJsInterop(element)) {
959 return true;
960 }
961 assert(element.isResolved);
962 return isNativeOrExtendsNative(element.superclass);
963 }
964
801 bool isInterceptedMethod(Element element) { 965 bool isInterceptedMethod(Element element) {
802 if (!element.isInstanceMember) return false; 966 if (!element.isInstanceMember) return false;
803 if (element.isGenerativeConstructorBody) { 967 if (element.isGenerativeConstructorBody) {
804 return Elements.isNativeOrExtendsNative(element.enclosingClass); 968 return isNativeOrExtendsNative(element.enclosingClass);
805 } 969 }
806 return interceptedElements[element.name] != null; 970 return interceptedElements[element.name] != null;
807 } 971 }
808 972
809 bool fieldHasInterceptedGetter(Element element) { 973 bool fieldHasInterceptedGetter(Element element) {
810 assert(element.isField); 974 assert(element.isField);
811 return interceptedElements[element.name] != null; 975 return interceptedElements[element.name] != null;
812 } 976 }
813 977
814 bool fieldHasInterceptedSetter(Element element) { 978 bool fieldHasInterceptedSetter(Element element) {
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
859 */ 1023 */
860 Set<ClassElement> getInterceptedClassesOn(String name) { 1024 Set<ClassElement> getInterceptedClassesOn(String name) {
861 Set<Element> intercepted = interceptedElements[name]; 1025 Set<Element> intercepted = interceptedElements[name];
862 if (intercepted == null) return null; 1026 if (intercepted == null) return null;
863 return interceptedClassesCache.putIfAbsent(name, () { 1027 return interceptedClassesCache.putIfAbsent(name, () {
864 // Populate the cache by running through all the elements and 1028 // Populate the cache by running through all the elements and
865 // determine if the given selector applies to them. 1029 // determine if the given selector applies to them.
866 Set<ClassElement> result = new Set<ClassElement>(); 1030 Set<ClassElement> result = new Set<ClassElement>();
867 for (Element element in intercepted) { 1031 for (Element element in intercepted) {
868 ClassElement classElement = element.enclosingClass; 1032 ClassElement classElement = element.enclosingClass;
869 if (Elements.isNativeOrExtendsNative(classElement) 1033 if (isNativeOrExtendsNative(classElement)
870 || interceptedClasses.contains(classElement)) { 1034 || interceptedClasses.contains(classElement)) {
871 result.add(classElement); 1035 result.add(classElement);
872 } 1036 }
873 if (classesMixedIntoInterceptedClasses.contains(classElement)) { 1037 if (classesMixedIntoInterceptedClasses.contains(classElement)) {
874 Set<ClassElement> nativeSubclasses = 1038 Set<ClassElement> nativeSubclasses =
875 nativeSubclassesOfMixin(classElement); 1039 nativeSubclassesOfMixin(classElement);
876 if (nativeSubclasses != null) result.addAll(nativeSubclasses); 1040 if (nativeSubclasses != null) result.addAll(nativeSubclasses);
877 } 1041 }
878 } 1042 }
879 return result; 1043 return result;
880 }); 1044 });
881 } 1045 }
882 1046
883 Set<ClassElement> nativeSubclassesOfMixin(ClassElement mixin) { 1047 Set<ClassElement> nativeSubclassesOfMixin(ClassElement mixin) {
884 ClassWorld classWorld = compiler.world; 1048 ClassWorld classWorld = compiler.world;
885 Iterable<MixinApplicationElement> uses = classWorld.mixinUsesOf(mixin); 1049 Iterable<MixinApplicationElement> uses = classWorld.mixinUsesOf(mixin);
886 Set<ClassElement> result = null; 1050 Set<ClassElement> result = null;
887 for (MixinApplicationElement use in uses) { 1051 for (MixinApplicationElement use in uses) {
888 Iterable<ClassElement> subclasses = classWorld.strictSubclassesOf(use); 1052 Iterable<ClassElement> subclasses = classWorld.strictSubclassesOf(use);
889 for (ClassElement subclass in subclasses) { 1053 for (ClassElement subclass in subclasses) {
890 if (Elements.isNativeOrExtendsNative(subclass)) { 1054 if (isNativeOrExtendsNative(subclass)) {
891 if (result == null) result = new Set<ClassElement>(); 1055 if (result == null) result = new Set<ClassElement>();
892 result.add(subclass); 1056 result.add(subclass);
893 } 1057 }
894 } 1058 }
895 } 1059 }
896 return result; 1060 return result;
897 } 1061 }
898 1062
899 bool operatorEqHandlesNullArgument(FunctionElement operatorEqfunction) { 1063 bool operatorEqHandlesNullArgument(FunctionElement operatorEqfunction) {
900 return specialOperatorEqClasses.contains( 1064 return specialOperatorEqClasses.contains(
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after
1083 // The backend will use a literal list to initialize the entries 1247 // The backend will use a literal list to initialize the entries
1084 // of the map. 1248 // of the map.
1085 enqueueClass(enqueuer, compiler.listClass, registry); 1249 enqueueClass(enqueuer, compiler.listClass, registry);
1086 enqueueClass(enqueuer, mapLiteralClass, registry); 1250 enqueueClass(enqueuer, mapLiteralClass, registry);
1087 // For map literals, the dependency between the implementation class 1251 // For map literals, the dependency between the implementation class
1088 // and [Map] is not visible, so we have to add it manually. 1252 // and [Map] is not visible, so we have to add it manually.
1089 rti.registerRtiDependency(mapLiteralClass, cls); 1253 rti.registerRtiDependency(mapLiteralClass, cls);
1090 } else if (cls == boundClosureClass) { 1254 } else if (cls == boundClosureClass) {
1091 // TODO(johnniwinther): Is this a noop? 1255 // TODO(johnniwinther): Is this a noop?
1092 enqueueClass(enqueuer, boundClosureClass, registry); 1256 enqueueClass(enqueuer, boundClosureClass, registry);
1093 } else if (Elements.isNativeOrExtendsNative(cls)) { 1257 } else if (isNativeOrExtendsNative(cls)) {
1094 enqueue(enqueuer, getNativeInterceptorMethod, registry); 1258 enqueue(enqueuer, getNativeInterceptorMethod, registry);
1095 enqueueClass(enqueuer, jsInterceptorClass, compiler.globalDependencies); 1259 enqueueClass(enqueuer, jsInterceptorClass, compiler.globalDependencies);
1096 enqueueClass(enqueuer, jsJavaScriptObjectClass, registry); 1260 enqueueClass(enqueuer, jsJavaScriptObjectClass, registry);
1097 enqueueClass(enqueuer, jsPlainJavaScriptObjectClass, registry); 1261 enqueueClass(enqueuer, jsPlainJavaScriptObjectClass, registry);
1098 enqueueClass(enqueuer, jsJavaScriptFunctionClass, registry); 1262 enqueueClass(enqueuer, jsJavaScriptFunctionClass, registry);
1099 } else if (cls == mapLiteralClass) { 1263 } else if (cls == mapLiteralClass) {
1100 // For map literals, the dependency between the implementation class 1264 // For map literals, the dependency between the implementation class
1101 // and [Map] is not visible, so we have to add it manually. 1265 // and [Map] is not visible, so we have to add it manually.
1102 Element getFactory(String name, int arity) { 1266 Element getFactory(String name, int arity) {
1103 // The constructor is on the patch class, but dart2js unit tests don't 1267 // The constructor is on the patch class, but dart2js unit tests don't
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
1173 addInterceptors(jsDoubleClass, enqueuer, registry); 1337 addInterceptors(jsDoubleClass, enqueuer, registry);
1174 addInterceptors(jsNumberClass, enqueuer, registry); 1338 addInterceptors(jsNumberClass, enqueuer, registry);
1175 } else if (cls == jsJavaScriptObjectClass) { 1339 } else if (cls == jsJavaScriptObjectClass) {
1176 addInterceptors(jsJavaScriptObjectClass, enqueuer, registry); 1340 addInterceptors(jsJavaScriptObjectClass, enqueuer, registry);
1177 } else if (cls == jsPlainJavaScriptObjectClass) { 1341 } else if (cls == jsPlainJavaScriptObjectClass) {
1178 addInterceptors(jsPlainJavaScriptObjectClass, enqueuer, registry); 1342 addInterceptors(jsPlainJavaScriptObjectClass, enqueuer, registry);
1179 } else if (cls == jsUnknownJavaScriptObjectClass) { 1343 } else if (cls == jsUnknownJavaScriptObjectClass) {
1180 addInterceptors(jsUnknownJavaScriptObjectClass, enqueuer, registry); 1344 addInterceptors(jsUnknownJavaScriptObjectClass, enqueuer, registry);
1181 } else if (cls == jsJavaScriptFunctionClass) { 1345 } else if (cls == jsJavaScriptFunctionClass) {
1182 addInterceptors(jsJavaScriptFunctionClass, enqueuer, registry); 1346 addInterceptors(jsJavaScriptFunctionClass, enqueuer, registry);
1183 } else if (Elements.isNativeOrExtendsNative(cls)) { 1347 } else if (isNativeOrExtendsNative(cls)) {
1184 addInterceptorsForNativeClassMembers(cls, enqueuer); 1348 addInterceptorsForNativeClassMembers(cls, enqueuer);
1185 } else if (cls == jsIndexingBehaviorInterface) { 1349 } else if (cls == jsIndexingBehaviorInterface) {
1186 // These two helpers are used by the emitter and the codegen. 1350 // These two helpers are used by the emitter and the codegen.
1187 // Because we cannot enqueue elements at the time of emission, 1351 // Because we cannot enqueue elements at the time of emission,
1188 // we make sure they are always generated. 1352 // we make sure they are always generated.
1189 enqueue(enqueuer, findHelper('isJsIndexable'), registry); 1353 enqueue(enqueuer, findHelper('isJsIndexable'), registry);
1190 } 1354 }
1191 1355
1192 customElementsAnalysis.registerInstantiatedClass(cls, enqueuer); 1356 customElementsAnalysis.registerInstantiatedClass(cls, enqueuer);
1193 if (!enqueuer.isResolutionQueue) { 1357 if (!enqueuer.isResolutionQueue) {
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
1342 } 1506 }
1343 // We also need the native variant of the check (for DOM types). 1507 // We also need the native variant of the check (for DOM types).
1344 helper = getNativeCheckedModeHelper(type, typeCast: false); 1508 helper = getNativeCheckedModeHelper(type, typeCast: false);
1345 if (helper != null) { 1509 if (helper != null) {
1346 enqueue(world, helper.getElement(compiler), registry); 1510 enqueue(world, helper.getElement(compiler), registry);
1347 } 1511 }
1348 } 1512 }
1349 if (!type.treatAsRaw || type.containsTypeVariables) { 1513 if (!type.treatAsRaw || type.containsTypeVariables) {
1350 enqueueClass(world, compiler.listClass, registry); 1514 enqueueClass(world, compiler.listClass, registry);
1351 } 1515 }
1352 if (type.element != null && type.element.isNative) { 1516 if (type.element != null && isNative(type.element)) {
1353 // We will neeed to add the "$is" and "$as" properties on the 1517 // We will neeed to add the "$is" and "$as" properties on the
1354 // JavaScript object prototype, so we make sure 1518 // JavaScript object prototype, so we make sure
1355 // [:defineProperty:] is compiled. 1519 // [:defineProperty:] is compiled.
1356 enqueue(world, findHelper('defineProperty'), registry); 1520 enqueue(world, findHelper('defineProperty'), registry);
1357 } 1521 }
1358 } 1522 }
1359 1523
1360 void registerTypeVariableBoundsSubtypeCheck(DartType typeArgument, 1524 void registerTypeVariableBoundsSubtypeCheck(DartType typeArgument,
1361 DartType bound) { 1525 DartType bound) {
1362 rti.registerTypeVariableBoundsSubtypeCheck(typeArgument, bound); 1526 rti.registerTypeVariableBoundsSubtypeCheck(typeArgument, bound);
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after
1596 1760
1597 native.NativeEnqueuer nativeResolutionEnqueuer(Enqueuer world) { 1761 native.NativeEnqueuer nativeResolutionEnqueuer(Enqueuer world) {
1598 return new native.NativeResolutionEnqueuer(world, compiler); 1762 return new native.NativeResolutionEnqueuer(world, compiler);
1599 } 1763 }
1600 1764
1601 native.NativeEnqueuer nativeCodegenEnqueuer(Enqueuer world) { 1765 native.NativeEnqueuer nativeCodegenEnqueuer(Enqueuer world) {
1602 return new native.NativeCodegenEnqueuer(world, compiler, emitter); 1766 return new native.NativeCodegenEnqueuer(world, compiler, emitter);
1603 } 1767 }
1604 1768
1605 ClassElement defaultSuperclass(ClassElement element) { 1769 ClassElement defaultSuperclass(ClassElement element) {
1606 if (element.isJsInterop) return jsJavaScriptObjectClass; 1770 if (isJsInterop(element)) return jsJavaScriptObjectClass;
1607 // Native classes inherit from Interceptor. 1771 // Native classes inherit from Interceptor.
1608 return element.isNative ? jsInterceptorClass : compiler.objectClass; 1772 return isNative(element) ? jsInterceptorClass : compiler.objectClass;
1609 } 1773 }
1610 1774
1611 /** 1775 /**
1612 * Unit test hook that returns code of an element as a String. 1776 * Unit test hook that returns code of an element as a String.
1613 * 1777 *
1614 * Invariant: [element] must be a declaration element. 1778 * Invariant: [element] must be a declaration element.
1615 */ 1779 */
1616 String getGeneratedCode(Element element) { 1780 String getGeneratedCode(Element element) {
1617 assert(invariant(element, element.isDeclaration)); 1781 assert(invariant(element, element.isDeclaration));
1618 return jsAst.prettyPrint(generatedCode[element], compiler).getText(); 1782 return jsAst.prettyPrint(generatedCode[element], compiler).getText();
(...skipping 908 matching lines...) Expand 10 before | Expand all | Expand 10 after
2527 lookupMapAnalysis.onCodegenStart(); 2691 lookupMapAnalysis.onCodegenStart();
2528 } 2692 }
2529 2693
2530 void onElementResolved(Element element, TreeElements elements) { 2694 void onElementResolved(Element element, TreeElements elements) {
2531 if ((element.isFunction || element.isGenerativeConstructor) && 2695 if ((element.isFunction || element.isGenerativeConstructor) &&
2532 annotations.noInline(element)) { 2696 annotations.noInline(element)) {
2533 inlineCache.markAsNonInlinable(element); 2697 inlineCache.markAsNonInlinable(element);
2534 } 2698 }
2535 2699
2536 LibraryElement library = element.library; 2700 LibraryElement library = element.library;
2537 if (!library.isPlatformLibrary && !library.canUseNative) return; 2701 if (!library.isPlatformLibrary && !canLibraryUseNative(library)) return;
2538 bool hasNoInline = false; 2702 bool hasNoInline = false;
2539 bool hasForceInline = false; 2703 bool hasForceInline = false;
2540 bool hasNoThrows = false; 2704 bool hasNoThrows = false;
2541 bool hasNoSideEffects = false; 2705 bool hasNoSideEffects = false;
2542 for (MetadataAnnotation metadata in element.implementation.metadata) { 2706 for (MetadataAnnotation metadata in element.implementation.metadata) {
2543 metadata.ensureResolved(resolution); 2707 metadata.ensureResolved(resolution);
2544 ConstantValue constantValue = 2708 ConstantValue constantValue =
2545 compiler.constants.getConstantValue(metadata.constant); 2709 compiler.constants.getConstantValue(metadata.constant);
2546 if (!constantValue.isConstructedObject) continue; 2710 if (!constantValue.isConstructedObject) continue;
2547 ObjectConstantValue value = constantValue; 2711 ObjectConstantValue value = constantValue;
(...skipping 480 matching lines...) Expand 10 before | Expand all | Expand 10 after
3028 registerBackendImpact(transformed, impacts.typeVariableTypeCheck); 3192 registerBackendImpact(transformed, impacts.typeVariableTypeCheck);
3029 if (inCheckedMode) { 3193 if (inCheckedMode) {
3030 registerBackendImpact(transformed, 3194 registerBackendImpact(transformed,
3031 impacts.typeVariableCheckedModeTypeCheck); 3195 impacts.typeVariableCheckedModeTypeCheck);
3032 } 3196 }
3033 } 3197 }
3034 } 3198 }
3035 if (type is FunctionType) { 3199 if (type is FunctionType) {
3036 registerBackendImpact(transformed, impacts.functionTypeCheck); 3200 registerBackendImpact(transformed, impacts.functionTypeCheck);
3037 } 3201 }
3038 if (type.element != null && type.element.isNative) { 3202 if (type.element != null && backend.isNative(type.element)) {
3039 registerBackendImpact(transformed, impacts.nativeTypeCheck); 3203 registerBackendImpact(transformed, impacts.nativeTypeCheck);
3040 } 3204 }
3041 } 3205 }
3042 } 3206 }
3043 3207
3044 /// Records that [constant] is used by the element behind [registry]. 3208 /// Records that [constant] is used by the element behind [registry].
3045 class Dependency { 3209 class Dependency {
3046 final ConstantValue constant; 3210 final ConstantValue constant;
3047 final Element annotatedElement; 3211 final Element annotatedElement;
3048 3212
3049 const Dependency(this.constant, this.annotatedElement); 3213 const Dependency(this.constant, this.annotatedElement);
3050 } 3214 }
3051 3215
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698