OLD | NEW |
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 |
(...skipping 759 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
770 dart_declaration, 'Callback', True) | 770 dart_declaration, 'Callback', True) |
771 return | 771 return |
772 | 772 |
773 body = self._members_emitter.Emit( | 773 body = self._members_emitter.Emit( |
774 '\n' | 774 '\n' |
775 ' $DECLARATION {\n' | 775 ' $DECLARATION {\n' |
776 '$!BODY' | 776 '$!BODY' |
777 ' }\n', | 777 ' }\n', |
778 DECLARATION=dart_declaration) | 778 DECLARATION=dart_declaration) |
779 | 779 |
| 780 if self._interface.id == 'IDBObjectStore' and info.name == 'openCursor': |
| 781 # FIXME: implement v8-like overload resolver and remove this hack. |
| 782 info.overloads = info.overloads[1:] |
| 783 |
780 self._native_version = 0 | 784 self._native_version = 0 |
781 overloads = self.CombineOverloads(info.overloads) | 785 overloads = self.CombineOverloads(info.overloads) |
782 fallthrough = self.GenerateDispatch(body, info, ' ', overloads) | 786 fallthrough = self.GenerateDispatch(body, info, ' ', overloads) |
783 if fallthrough: | 787 if fallthrough: |
784 body.Emit(' throw "Incorrect number or type of arguments";\n'); | 788 body.Emit(' throw "Incorrect number or type of arguments";\n'); |
785 | 789 |
786 def CombineOverloads(self, overloads): | 790 def CombineOverloads(self, overloads): |
787 # Combine overloads that can be implemented by the same native method. This | 791 # Combine overloads that can be implemented by the same native method. This |
788 # undoes the expansion of optional arguments into multiple overloads unless | 792 # undoes the expansion of optional arguments into multiple overloads unless |
789 # IDL merging has made the overloads necessary. Starting with overload with | 793 # IDL merging has made the overloads necessary. Starting with overload with |
790 # no optional arguments and grow it by adding optional arguments, then the | 794 # no optional arguments and grow it by adding optional arguments, then the |
791 # longest overload can serve for all the shorter ones. | 795 # longest overload can serve for all the shorter ones. |
792 out = [] | 796 out = [] |
793 seed_index = 0 | 797 seed_index = 0 |
794 while seed_index < len(overloads): | 798 while seed_index < len(overloads): |
795 seed = overloads[seed_index] | 799 seed = overloads[seed_index] |
796 if len(seed.arguments) > 0 and seed.arguments[-1].is_optional: | 800 if len(seed.arguments) > 0 and IsOptional(seed.arguments[-1]): |
797 # Must start with no optional arguments. | 801 # Must start with no optional arguments. |
798 out.append(seed) | 802 out.append(seed) |
799 seed_index += 1 | 803 seed_index += 1 |
800 continue | 804 continue |
801 | 805 |
802 prev = seed | 806 prev = seed |
803 probe_index = seed_index + 1 | 807 probe_index = seed_index + 1 |
804 while probe_index < len(overloads): | 808 while probe_index < len(overloads): |
805 probe = overloads[probe_index] | 809 probe = overloads[probe_index] |
806 # Check that 'probe' extends 'prev' by one optional argument. | 810 # Check that 'probe' extends 'prev' by one optional argument. |
807 if len(probe.arguments) != len(prev.arguments) + 1: | 811 if len(probe.arguments) != len(prev.arguments) + 1: |
808 break | 812 break |
809 if probe.arguments[:-1] != prev.arguments: | 813 if probe.arguments[:-1] != prev.arguments: |
810 break | 814 break |
811 if not probe.arguments[-1].is_optional: | 815 if not IsOptional(probe.arguments[-1]): |
812 break | 816 break |
813 # See Issue 3177. This test against known implemented types is to | 817 # See Issue 3177. This test against known implemented types is to |
814 # prevent combining a possibly unimplemented type. Combining with an | 818 # prevent combining a possibly unimplemented type. Combining with an |
815 # unimplemented type will cause all set of combined overloads to become | 819 # unimplemented type will cause all set of combined overloads to become |
816 # 'unimplemented', even if no argument is passed to the the | 820 # 'unimplemented', even if no argument is passed to the the |
817 # unimplemented parameter. | 821 # unimplemented parameter. |
818 if DartType(probe.arguments[-1].type.id) not in [ | 822 if DartType(probe.arguments[-1].type.id) not in [ |
819 'String', 'int', 'num', 'double', 'bool', | 823 'String', 'int', 'num', 'double', 'bool', |
820 'IDBKeyRange']: | 824 'IDBKeyRange']: |
821 break | 825 break |
822 probe_index += 1 | 826 probe_index += 1 |
823 prev = probe | 827 prev = probe |
824 out.append(prev) | 828 out.append(prev) |
825 seed_index = probe_index | 829 seed_index = probe_index |
826 | 830 |
827 return out | 831 return out |
828 | 832 |
829 def PrintOverloadsComment(self, emitter, info, indent, note, overloads): | 833 def PrintOverloadsComment(self, emitter, info, indent, note, overloads): |
830 emitter.Emit('$(INDENT)//$NOTE\n', INDENT=indent, NOTE=note) | 834 emitter.Emit('$(INDENT)//$NOTE\n', INDENT=indent, NOTE=note) |
831 for operation in overloads: | 835 for operation in overloads: |
832 params = ', '.join([ | 836 params = ', '.join([ |
833 ('[Optional] ' if arg.is_optional else '') + DartType(arg.type.id) + '
' | 837 ('[Optional] ' if IsOptional(arg) else '') + DartType(arg.type.id) + '
' |
834 + arg.id for arg in operation.arguments]) | 838 + arg.id for arg in operation.arguments]) |
835 emitter.Emit('$(INDENT)// $NAME($PARAMS)\n', | 839 emitter.Emit('$(INDENT)// $NAME($PARAMS)\n', |
836 INDENT=indent, | 840 INDENT=indent, |
837 NAME=info.name, | 841 NAME=info.name, |
838 PARAMS=params) | 842 PARAMS=params) |
839 emitter.Emit('$(INDENT)//\n', INDENT=indent) | 843 emitter.Emit('$(INDENT)//\n', INDENT=indent) |
840 | 844 |
841 def GenerateDispatch(self, emitter, info, indent, overloads): | 845 def GenerateDispatch(self, emitter, info, indent, overloads): |
842 """Generates a dispatch to one of the overloads. | 846 """Generates a dispatch to one of the overloads. |
843 | 847 |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
917 dart_type = self._DartType(arg.type.id) | 921 dart_type = self._DartType(arg.type.id) |
918 if dart_type == param.dart_type: | 922 if dart_type == param.dart_type: |
919 # The overload type matches the method parameter type exactly. We | 923 # The overload type matches the method parameter type exactly. We |
920 # will have already tested this type in checked mode, and the target | 924 # will have already tested this type in checked mode, and the target |
921 # will expect (i.e. check) this type. This case happens when all | 925 # will expect (i.e. check) this type. This case happens when all |
922 # the overloads have the same type in this position, including the | 926 # the overloads have the same type in this position, including the |
923 # trivial case of one overload. | 927 # trivial case of one overload. |
924 test = None | 928 test = None |
925 else: | 929 else: |
926 test = TypeCheck(param.name, dart_type) | 930 test = TypeCheck(param.name, dart_type) |
927 if IsNullable(dart_type) or arg.is_optional: | 931 if IsNullable(dart_type) or IsOptional(arg): |
928 test = '(%s || %s)' % (NullCheck(param.name), test) | 932 test = '(%s || %s)' % (NullCheck(param.name), test) |
929 else: | 933 else: |
930 test = NullCheck(param.name) | 934 test = NullCheck(param.name) |
931 if test: | 935 if test: |
932 tests.append(test) | 936 tests.append(test) |
933 if tests: | 937 if tests: |
934 cond = ' && '.join(tests) | 938 cond = ' && '.join(tests) |
935 if len(cond) + len(indent) + 7 > 80: | 939 if len(cond) + len(indent) + 7 > 80: |
936 cond = (' &&\n' + indent + ' ').join(tests) | 940 cond = (' &&\n' + indent + ' ').join(tests) |
937 call = emitter.Emit( | 941 call = emitter.Emit( |
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1192 for parent in interface.parents: | 1196 for parent in interface.parents: |
1193 parent_name = parent.type.id | 1197 parent_name = parent.type.id |
1194 if not database.HasInterface(parent.type.id): | 1198 if not database.HasInterface(parent.type.id): |
1195 continue | 1199 continue |
1196 parent_interface = database.GetInterface(parent.type.id) | 1200 parent_interface = database.GetInterface(parent.type.id) |
1197 if callback(parent_interface): | 1201 if callback(parent_interface): |
1198 return parent_interface | 1202 return parent_interface |
1199 parent_interface = _FindParent(parent_interface, database, callback) | 1203 parent_interface = _FindParent(parent_interface, database, callback) |
1200 if parent_interface: | 1204 if parent_interface: |
1201 return parent_interface | 1205 return parent_interface |
OLD | NEW |