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

Side by Side Diff: tools/dom/scripts/systemnative.py

Issue 671023003: More dart:blink entry point tweaks (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Static permission getter Created 6 years, 1 month 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 #!/usr/bin/python 1 #!/usr/bin/python
2 # Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 2 # Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
3 # for details. All rights reserved. Use of this source code is governed by a 3 # for details. All rights reserved. Use of this source code is governed by a
4 # BSD-style license that can be found in the LICENSE file. 4 # BSD-style license that can be found in the LICENSE file.
5 5
6 """This module provides shared functionality for the systems to generate 6 """This module provides shared functionality for the systems to generate
7 native binding from the IDL database.""" 7 native binding from the IDL database."""
8 8
9 import emitter 9 import emitter
10 import os 10 import os
11 from generator import * 11 from generator import *
12 from htmldartgenerator import * 12 from htmldartgenerator import *
13 from idlnode import IDLArgument, IDLAttribute, IDLEnum, IDLMember 13 from idlnode import IDLArgument, IDLAttribute, IDLEnum, IDLMember
14 from systemhtml import js_support_checks, GetCallbackInfo, HTML_LIBRARY_NAMES 14 from systemhtml import js_support_checks, GetCallbackInfo, HTML_LIBRARY_NAMES
15 15
16 # This is an ugly hack to get things working on the M35 roll. Once we
17 # generate dart:blink from the new scripts, this shouldn't be needed.
18 _cpp_resolver_string_map = {
19 # These custom constructors all resolve to a common entry, so choosing any
20 # of the generated strings works.
21 'ConsoleBase_assertCondition_Callback_boolean_object':
22 'ConsoleBase_assert_Callback_boolean_object',
23 'FormData_constructorCallback':
24 'FormData_constructorCallback_HTMLFormElement',
25 # This callback name just gets generated sligtly different and we don't
26 # want to bother fixing it.
27 'ScriptProcessorNode__setEventListener_Callback':
28 'ScriptProcessorNode_setEventListener_Callback',
29 # We don't know how to get GLenum to show up as the correct type in this
30 # script and don't want to bother fixing it the right way.
31 'WebGLDrawBuffers_drawBuffersWEBGL_Callback_sequence<GLenum>' :
32 'WebGLDrawBuffers_drawBuffersWEBGL_Callback_sequence<unsigned long>',
33 # Blink 36 fixes.
34 'CanvasRenderingContext2D_setLineDash_Callback_sequence<float>' :
35 'CanvasRenderingContext2D_setLineDash_Callback_sequence<unrestricted flo at>',
36
37 # SVGGraphicsElement is base class.
38 'SVGUseElement_hasExtension_Callback_DOMString' :
39 'SVGGraphicsElement_hasExtension_Callback_DOMString',
40 'SVGUseElement_systemLanguage_Getter' :
41 'SVGGraphicsElement_systemLanguage_Getter',
42 'SVGUseElement_requiredFeatures_Getter' :
43 'SVGGraphicsElement_requiredFeatures_Getter',
44 'SVGUseElement_requiredExtensions_Getter' :
45 'SVGGraphicsElement_requiredExtensions_Getter',
46
47 'Gamepad_buttons_Getter' : 'WebKitGamepad_buttons_Getter',
48 }
49
50 # TODO(vsm): This logic needs to pulled from the source IDL. These tables are 16 # TODO(vsm): This logic needs to pulled from the source IDL. These tables are
51 # an ugly workaround. 17 # an ugly workaround.
52 _cpp_callback_map = { 18 _cpp_callback_map = {
53 ('DataTransferItem', 'webkitGetAsEntry'): 'DataTransferItemFileSystem', 19 ('DataTransferItem', 'webkitGetAsEntry'): 'DataTransferItemFileSystem',
54 ('Document', 'fonts'): 'DocumentFontFaceSet', 20 ('Document', 'fonts'): 'DocumentFontFaceSet',
55 ('Document', 'webkitIsFullScreen'): 'DocumentFullscreen', 21 ('Document', 'webkitIsFullScreen'): 'DocumentFullscreen',
56 ('Document', 'webkitFullScreenKeyboardInputAllowed'): 'DocumentFullscreen', 22 ('Document', 'webkitFullScreenKeyboardInputAllowed'): 'DocumentFullscreen',
57 ('Document', 'webkitCurrentFullScreenElement'): 'DocumentFullscreen', 23 ('Document', 'webkitCurrentFullScreenElement'): 'DocumentFullscreen',
58 ('Document', 'webkitCancelFullScreen'): 'DocumentFullscreen', 24 ('Document', 'webkitCancelFullScreen'): 'DocumentFullscreen',
59 ('Document', 'webkitFullscreenEnabled'): 'DocumentFullscreen', 25 ('Document', 'webkitFullscreenEnabled'): 'DocumentFullscreen',
(...skipping 544 matching lines...) Expand 10 before | Expand all | Expand 10 after
604 tag = "%s_Callback" % name 570 tag = "%s_Callback" % name
605 blink_entry = tag 571 blink_entry = tag
606 572
607 interface_id = TypeIdToBlinkName(interface_id, database) 573 interface_id = TypeIdToBlinkName(interface_id, database)
608 574
609 def mkPublic(s): 575 def mkPublic(s):
610 if s.startswith("_") or s.startswith("$"): 576 if s.startswith("_") or s.startswith("$"):
611 return "$" + s 577 return "$" + s
612 return s 578 return s
613 579
614 if count: 580 if count is not None:
615 arity = str(count) 581 arity = str(count)
616 dart_name = mkPublic("_".join([tag, arity])) 582 dart_name = mkPublic("_".join([tag, arity]))
617 else: 583 else:
618 dart_name = mkPublic(tag) 584 dart_name = mkPublic(tag)
619 resolver_string = "_".join([interface_id, tag]) 585 resolver_string = "_".join([interface_id, tag])
620 586
621 return (dart_name, resolver_string) 587 return (dart_name, resolver_string)
622 588
623 589
624 def DeriveNativeName(self, name, suffix=""): 590 def DeriveNativeName(self, name, suffix=""):
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
685 '\n' 651 '\n'
686 'class $INTERFACE_NAME {' 652 'class $INTERFACE_NAME {'
687 '$!METHODS' 653 '$!METHODS'
688 '}\n', 654 '}\n',
689 INTERFACE_NAME=DeriveBlinkClassName(self._interface.id)) 655 INTERFACE_NAME=DeriveBlinkClassName(self._interface.id))
690 # TODO(vsm): Should we check for collisions between EventConstructors and ot hers? 656 # TODO(vsm): Should we check for collisions between EventConstructors and ot hers?
691 # Should we unify at some point? 657 # Should we unify at some point?
692 if 'EventConstructor' in self._interface.ext_attrs: 658 if 'EventConstructor' in self._interface.ext_attrs:
693 self._native_class_emitter.Emit( 659 self._native_class_emitter.Emit(
694 '\n' 660 '\n'
695 ' static constructorCallback(type, options) native "$(INTERFACE_NAM E)_constructorCallback";\n', 661 ' static constructorCallback_2(type, options) native "$(INTERFACE_N AME)_constructorCallback";\n',
696 INTERFACE_NAME=self._interface.id 662 INTERFACE_NAME=self._interface.id
697 ) 663 )
698 self._blink_entries = set() 664 self._blink_entries = {}
699 665
700 def _EmitConstructorInfrastructure(self, 666 def _EmitConstructorInfrastructure(self,
701 constructor_info, cpp_prefix, cpp_suffix, factory_method_name, 667 constructor_info, cpp_prefix, cpp_suffix, factory_method_name,
702 arguments=None, emit_to_native=False, is_custom=False): 668 arguments=None, emit_to_native=False, is_custom=False):
703 669
704 constructor_callback_cpp_name = cpp_prefix + cpp_suffix 670 constructor_callback_cpp_name = cpp_prefix + cpp_suffix
705 671
706 if arguments is None: 672 if arguments is None:
707 arguments = constructor_info.idl_args[0] 673 arguments = constructor_info.idl_args[0]
708 argument_count = len(arguments) 674 argument_count = len(arguments)
709 else: 675 else:
710 argument_count = len(arguments) 676 argument_count = len(arguments)
711 677
712 typed_formals = constructor_info.ParametersAsArgumentList(argument_count) 678 typed_formals = constructor_info.ParametersAsArgumentList(argument_count)
713 parameters = constructor_info.ParametersAsStringOfVariables(argument_count) 679 parameters = constructor_info.ParametersAsStringOfVariables(argument_count)
714 interface_name = self._interface_type_info.interface_name() 680 interface_name = self._interface_type_info.interface_name()
715 681
716 dart_native_name, constructor_callback_id = \ 682 dart_native_name, constructor_callback_id = \
717 self.DeriveNativeEntry(cpp_suffix, 'Constructor', argument_count) 683 self.DeriveNativeEntry(cpp_suffix, 'Constructor', argument_count)
718 if constructor_callback_id in _cpp_resolver_string_map:
719 constructor_callback_id = \
720 _cpp_resolver_string_map[constructor_callback_id]
721 if dart_native_name not in self._blink_entries: 684 if dart_native_name not in self._blink_entries:
722 self._blink_entries.add(dart_native_name) 685 entry = ' static %s(%s) native "%s";' % \
723 self._native_class_emitter.Emit( 686 (dart_native_name, parameters, constructor_callback_id)
724 '\n' 687 self._blink_entries[dart_native_name] = entry
725 ' static $FACTORY_METHOD_NAME($PARAMETERS) native "$ID";\n',
726 FACTORY_METHOD_NAME=dart_native_name,
727 PARAMETERS=parameters,
728 ID=constructor_callback_id)
729 688
730 # Then we emit the impedance matching wrapper to call out to the 689 # Then we emit the impedance matching wrapper to call out to the
731 # toplevel wrapper 690 # toplevel wrapper
732 if not emit_to_native: 691 if not emit_to_native:
733 toplevel_name = \ 692 toplevel_name = \
734 self.DeriveQualifiedBlinkName(self._interface.id, 693 self.DeriveQualifiedBlinkName(self._interface.id,
735 dart_native_name) 694 dart_native_name)
736 self._members_emitter.Emit( 695 self._members_emitter.Emit(
737 '\n @DocsEditable()\n' 696 '\n @DocsEditable()\n'
738 ' static $INTERFACE_NAME $FACTORY_METHOD_NAME($PARAMETERS) => ' 697 ' static $INTERFACE_NAME $FACTORY_METHOD_NAME($PARAMETERS) => '
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
818 777
819 def FinishInterface(self): 778 def FinishInterface(self):
820 interface = self._interface 779 interface = self._interface
821 if interface.parents: 780 if interface.parents:
822 supertype = '%sClassId' % interface.parents[0].type.id 781 supertype = '%sClassId' % interface.parents[0].type.id
823 else: 782 else:
824 supertype = '-1' 783 supertype = '-1'
825 784
826 self._GenerateCPPHeader() 785 self._GenerateCPPHeader()
827 786
787 for entry in sorted(self._blink_entries):
788 self._native_class_emitter.Emit(
789 '\n' + self._blink_entries[entry] + '\n')
790
791 self._native_class_emitter.Emit('\n')
792
828 self._cpp_impl_emitter.Emit( 793 self._cpp_impl_emitter.Emit(
829 self._template_loader.Load('cpp_implementation.template'), 794 self._template_loader.Load('cpp_implementation.template'),
830 INTERFACE=self._interface.id, 795 INTERFACE=self._interface.id,
831 SUPER_INTERFACE=supertype, 796 SUPER_INTERFACE=supertype,
832 INCLUDES=self._GenerateCPPIncludes(self._cpp_impl_includes), 797 INCLUDES=self._GenerateCPPIncludes(self._cpp_impl_includes),
833 CALLBACKS=self._cpp_definitions_emitter.Fragments(), 798 CALLBACKS=self._cpp_definitions_emitter.Fragments(),
834 RESOLVER=self._cpp_resolver_emitter.Fragments(), 799 RESOLVER=self._cpp_resolver_emitter.Fragments(),
835 WEBCORE_CLASS_NAME=self._interface_type_info.native_type(), 800 WEBCORE_CLASS_NAME=self._interface_type_info.native_type(),
836 WEBCORE_CLASS_NAME_ESCAPED= 801 WEBCORE_CLASS_NAME_ESCAPED=
837 self._interface_type_info.native_type().replace('<', '_').replace('>', ' _'), 802 self._interface_type_info.native_type().replace('<', '_').replace('>', ' _'),
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
1009 is_custom = _IsCustom(attr) and (_IsCustomValue(attr, None) or 974 is_custom = _IsCustom(attr) and (_IsCustomValue(attr, None) or
1010 _IsCustomValue(attr, 'Getter')) 975 _IsCustomValue(attr, 'Getter'))
1011 # This seems to have been replaced with Custom=Getter (see above), but 976 # This seems to have been replaced with Custom=Getter (see above), but
1012 # check to be sure we don't see the old syntax 977 # check to be sure we don't see the old syntax
1013 assert(not ('CustomGetter' in attr.ext_attrs)) 978 assert(not ('CustomGetter' in attr.ext_attrs))
1014 native_suffix = 'Getter' 979 native_suffix = 'Getter'
1015 auto_scope_setup = self._GenerateAutoSetupScope(attr.id, native_suffix) 980 auto_scope_setup = self._GenerateAutoSetupScope(attr.id, native_suffix)
1016 native_entry = \ 981 native_entry = \
1017 self.DeriveNativeEntry(attr.id, 'Getter', None) 982 self.DeriveNativeEntry(attr.id, 'Getter', None)
1018 cpp_callback_name = self._GenerateNativeBinding(attr.id, 1, 983 cpp_callback_name = self._GenerateNativeBinding(attr.id, 1,
1019 dart_declaration, False, return_type, parameters, 984 dart_declaration, attr.is_static, return_type, parameters,
1020 native_suffix, is_custom, auto_scope_setup, native_entry=native_entry) 985 native_suffix, is_custom, auto_scope_setup, native_entry=native_entry)
1021 if is_custom: 986 if is_custom:
1022 return 987 return
1023 988
1024 if 'Reflect' in attr.ext_attrs: 989 if 'Reflect' in attr.ext_attrs:
1025 webcore_function_name = self._TypeInfo(attr.type.id).webcore_getter_name() 990 webcore_function_name = self._TypeInfo(attr.type.id).webcore_getter_name()
1026 if 'URL' in attr.ext_attrs: 991 if 'URL' in attr.ext_attrs:
1027 if 'NonEmpty' in attr.ext_attrs: 992 if 'NonEmpty' in attr.ext_attrs:
1028 webcore_function_name = 'getNonEmptyURLAttribute' 993 webcore_function_name = 'getNonEmptyURLAttribute'
1029 else: 994 else:
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1064 _IsCustomValue(attr, 'Setter')) 1029 _IsCustomValue(attr, 'Setter'))
1065 # This seems to have been replaced with Custom=Setter (see above), but 1030 # This seems to have been replaced with Custom=Setter (see above), but
1066 # check to be sure we don't see the old syntax 1031 # check to be sure we don't see the old syntax
1067 assert(not ('CustomSetter' in attr.ext_attrs)) 1032 assert(not ('CustomSetter' in attr.ext_attrs))
1068 assert(not ('V8CustomSetter' in attr.ext_attrs)) 1033 assert(not ('V8CustomSetter' in attr.ext_attrs))
1069 native_suffix = 'Setter' 1034 native_suffix = 'Setter'
1070 auto_scope_setup = self._GenerateAutoSetupScope(attr.id, native_suffix) 1035 auto_scope_setup = self._GenerateAutoSetupScope(attr.id, native_suffix)
1071 native_entry = \ 1036 native_entry = \
1072 self.DeriveNativeEntry(attr.id, 'Setter', None) 1037 self.DeriveNativeEntry(attr.id, 'Setter', None)
1073 cpp_callback_name = self._GenerateNativeBinding(attr.id, 2, 1038 cpp_callback_name = self._GenerateNativeBinding(attr.id, 2,
1074 dart_declaration, False, return_type, parameters, 1039 dart_declaration, attr.is_static, return_type, parameters,
1075 native_suffix, is_custom, auto_scope_setup, native_entry=native_entry) 1040 native_suffix, is_custom, auto_scope_setup, native_entry=native_entry)
1076 if is_custom: 1041 if is_custom:
1077 return 1042 return
1078 1043
1079 if 'Reflect' in attr.ext_attrs: 1044 if 'Reflect' in attr.ext_attrs:
1080 webcore_function_name = self._TypeInfo(attr.type.id).webcore_setter_name() 1045 webcore_function_name = self._TypeInfo(attr.type.id).webcore_setter_name()
1081 else: 1046 else:
1082 if 'ImplementedAs' in attr.ext_attrs: 1047 if 'ImplementedAs' in attr.ext_attrs:
1083 attr_name = attr.ext_attrs['ImplementedAs'] 1048 attr_name = attr.ext_attrs['ImplementedAs']
1084 else: 1049 else:
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1126 if self._HasNativeIndexGetter(): 1091 if self._HasNativeIndexGetter():
1127 self._EmitNativeIndexGetter(dart_element_type) 1092 self._EmitNativeIndexGetter(dart_element_type)
1128 elif self._HasExplicitIndexedGetter(): 1093 elif self._HasExplicitIndexedGetter():
1129 self._EmitExplicitIndexedGetter(dart_element_type) 1094 self._EmitExplicitIndexedGetter(dart_element_type)
1130 else: 1095 else:
1131 is_custom = any((op.id == 'item' and _IsCustom(op)) for op in self._interf ace.operations) 1096 is_custom = any((op.id == 'item' and _IsCustom(op)) for op in self._interf ace.operations)
1132 # First emit a toplevel function to do the native call 1097 # First emit a toplevel function to do the native call
1133 # Calls to this are emitted elsewhere, 1098 # Calls to this are emitted elsewhere,
1134 dart_native_name, resolver_string = \ 1099 dart_native_name, resolver_string = \
1135 self.DeriveNativeEntry("item", 'Method', 1) 1100 self.DeriveNativeEntry("item", 'Method', 1)
1136 if resolver_string in _cpp_resolver_string_map:
1137 resolver_string = \
1138 _cpp_resolver_string_map[resolver_string]
1139 1101
1140 # Emit the method which calls the toplevel function, along with 1102 # Emit the method which calls the toplevel function, along with
1141 # the [] operator. 1103 # the [] operator.
1142 dart_qualified_name = \ 1104 dart_qualified_name = \
1143 self.DeriveQualifiedBlinkName(self._interface.id, 1105 self.DeriveQualifiedBlinkName(self._interface.id,
1144 dart_native_name) 1106 dart_native_name)
1145 self._members_emitter.Emit( 1107 self._members_emitter.Emit(
1146 '\n' 1108 '\n'
1147 ' $TYPE operator[](int index) {\n' 1109 ' $TYPE operator[](int index) {\n'
1148 ' if (index < 0 || index >= length)\n' 1110 ' if (index < 0 || index >= length)\n'
(...skipping 558 matching lines...) Expand 10 before | Expand all | Expand 10 after
1707 native_binding_id = TypeIdToBlinkName(native_binding_id, self._database) 1669 native_binding_id = TypeIdToBlinkName(native_binding_id, self._database)
1708 native_binding = \ 1670 native_binding = \
1709 '%s_%s_%s' % (native_binding_id, idl_name, native_suffix) 1671 '%s_%s_%s' % (native_binding_id, idl_name, native_suffix)
1710 1672
1711 if not static: 1673 if not static:
1712 formals = ", ".join(['mthis'] + parameters) 1674 formals = ", ".join(['mthis'] + parameters)
1713 actuals = ", ".join(['this'] + parameters) 1675 actuals = ", ".join(['this'] + parameters)
1714 else: 1676 else:
1715 formals = ", ".join(parameters) 1677 formals = ", ".join(parameters)
1716 actuals = ", ".join(parameters) 1678 actuals = ", ".join(parameters)
1717 if native_binding in _cpp_resolver_string_map:
1718 native_binding = \
1719 _cpp_resolver_string_map[native_binding]
1720 if dart_native_name not in self._blink_entries: 1679 if dart_native_name not in self._blink_entries:
1721 self._blink_entries.add(dart_native_name) 1680 entry = ' static %s(%s) native "%s";' % \
1722 self._native_class_emitter.Emit( 1681 (dart_native_name, formals, native_binding)
1723 '\n' 1682 self._blink_entries[dart_native_name] = entry
1724 ' static $DART_NAME($FORMALS) native "$NATIVE_BINDING";\n',
1725 DART_NAME=dart_native_name,
1726 FORMALS=formals,
1727 NATIVE_BINDING=native_binding)
1728 1683
1729 if not emit_to_native: 1684 if not emit_to_native:
1730 caller_emitter = self._members_emitter 1685 caller_emitter = self._members_emitter
1731 full_dart_name = \ 1686 full_dart_name = \
1732 self.DeriveQualifiedBlinkName(self._interface.id, 1687 self.DeriveQualifiedBlinkName(self._interface.id,
1733 dart_native_name) 1688 dart_native_name)
1734 caller_emitter.Emit( 1689 if IsPureInterface(self._interface.id):
1735 '\n' 1690 caller_emitter.Emit(
1736 ' $METADATA$DART_DECLARATION => $DART_NAME($ACTUALS);\n', 1691 '\n'
1737 METADATA=metadata, 1692 ' $METADATA$DART_DECLARATION;\n',
1738 DART_DECLARATION=dart_declaration, 1693 METADATA=metadata,
1739 DART_NAME=full_dart_name, 1694 DART_DECLARATION=dart_declaration)
1740 ACTUALS=actuals) 1695 else:
1696 caller_emitter.Emit(
1697 '\n'
1698 ' $METADATA$DART_DECLARATION => $DART_NAME($ACTUALS);\n',
1699 METADATA=metadata,
1700 DART_DECLARATION=dart_declaration,
1701 DART_NAME=full_dart_name,
1702 ACTUALS=actuals)
1741 cpp_callback_name = '%s%s' % (idl_name, native_suffix) 1703 cpp_callback_name = '%s%s' % (idl_name, native_suffix)
1742 1704
1743 self._cpp_resolver_emitter.Emit( 1705 self._cpp_resolver_emitter.Emit(
1744 ' if (argumentCount == $ARGC && name == "$NATIVE_BINDING") {\n' 1706 ' if (argumentCount == $ARGC && name == "$NATIVE_BINDING") {\n'
1745 ' *autoSetupScope = $AUTO_SCOPE_SETUP;\n' 1707 ' *autoSetupScope = $AUTO_SCOPE_SETUP;\n'
1746 ' return Dart$(INTERFACE_NAME)Internal::$CPP_CALLBACK_NAME;\n' 1708 ' return Dart$(INTERFACE_NAME)Internal::$CPP_CALLBACK_NAME;\n'
1747 ' }\n', 1709 ' }\n',
1748 ARGC=argument_count, 1710 ARGC=argument_count,
1749 NATIVE_BINDING=native_binding, 1711 NATIVE_BINDING=native_binding,
1750 INTERFACE_NAME=self._interface.id, 1712 INTERFACE_NAME=self._interface.id,
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after
2009 1971
2010 def _IsCustom(op_or_attr): 1972 def _IsCustom(op_or_attr):
2011 assert(isinstance(op_or_attr, IDLMember)) 1973 assert(isinstance(op_or_attr, IDLMember))
2012 return 'Custom' in op_or_attr.ext_attrs or 'DartCustom' in op_or_attr.ext_attr s 1974 return 'Custom' in op_or_attr.ext_attrs or 'DartCustom' in op_or_attr.ext_attr s
2013 1975
2014 def _IsCustomValue(op_or_attr, value): 1976 def _IsCustomValue(op_or_attr, value):
2015 if _IsCustom(op_or_attr): 1977 if _IsCustom(op_or_attr):
2016 return op_or_attr.ext_attrs.get('Custom') == value \ 1978 return op_or_attr.ext_attrs.get('Custom') == value \
2017 or op_or_attr.ext_attrs.get('DartCustom') == value 1979 or op_or_attr.ext_attrs.get('DartCustom') == value
2018 return False 1980 return False
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698