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

Side by Side Diff: lib/dom/scripts/generator.py

Issue 10375026: Start GenerateDispatch refactoring. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 7 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | lib/dom/scripts/systemhtml.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 systems to generate 6 """This module provides shared functionality for systems to generate
7 Dart APIs from the IDL database.""" 7 Dart APIs from the IDL database."""
8 8
9 import re 9 import re
10 10
(...skipping 703 matching lines...) Expand 10 before | Expand all | Expand 10 after
714 '"SVGAnimatedListPropertyTearOff.h"', 714 '"SVGAnimatedListPropertyTearOff.h"',
715 '"SVGTransformListPropertyTearOff.h"', 715 '"SVGTransformListPropertyTearOff.h"',
716 '"SVGPathSegListPropertyTearOff.h"', 716 '"SVGPathSegListPropertyTearOff.h"',
717 ] 717 ]
718 718
719 def GetIDLTypeInfo(idl_type_name): 719 def GetIDLTypeInfo(idl_type_name):
720 match = re.match(r'sequence<(\w+)>$', idl_type_name) 720 match = re.match(r'sequence<(\w+)>$', idl_type_name)
721 if match: 721 if match:
722 return SequenceIDLTypeInfo(idl_type_name, GetIDLTypeInfo(match.group(1))) 722 return SequenceIDLTypeInfo(idl_type_name, GetIDLTypeInfo(match.group(1)))
723 return _idl_type_registry.get(idl_type_name, IDLTypeInfo(idl_type_name)) 723 return _idl_type_registry.get(idl_type_name, IDLTypeInfo(idl_type_name))
724
725 def GenerateDispatch(generator, emitter, info, indent, position, overloads):
podivilov 2012/05/05 16:44:12 I don't think it's a good idea to move this method
sra1 2012/05/05 18:02:06 Pavel, could you say why? My concern is that nati
podivilov 2012/05/10 10:51:43 We currently use this method in two systems - nati
Anton Muhin 2012/05/10 11:30:13 I am not sure we should be that picky about how ma
Anton Muhin 2012/05/10 11:30:13 Stephen, this CL just gets rid of code duplication
podivilov 2012/05/10 15:57:13 Why is it needed? We are going to get rid of dupli
Anton Muhin 2012/05/10 16:11:55 What do you suggest? Wait until we get rid of it?
podivilov 2012/05/10 16:20:36 Personally, I prefer that you wait until migration
Anton Muhin 2012/05/10 16:24:08 What's ETA? If it's a day or two, I'd better wait
726 """Generates a dispatch to one of the overloads.
727
728 Arguments:
729 emitter: an Emitter for the body of a block of code.
730 info: the compound information about the operation and its overloads.
731 indent: an indentation string for generated code.
732 position: the index of the parameter to dispatch on.
733 overloads: a list of the remaining IDLOperations to dispatch.
734
735 Returns True if the dispatch can fall through on failure, False if the code
736 always dispatches.
737 """
738
739 def NullCheck(name):
740 return '%s === null' % name
741
742 def TypeCheck(name, type):
743 return '%s is %s' % (name, type)
744
745 def ShouldGenerateSingleOperation():
746 if position == len(info.param_infos):
747 if len(overloads) > 1:
748 raise Exception('Duplicate operations ' + str(overloads))
749 return True
750
751 # Check if we dispatch on RequiredCppParameter arguments. In this
752 # case all trailing arguments must be RequiredCppParameter and there
753 # is no need in dispatch.
754 # TODO(antonm): better diagnositics.
755 if position >= len(overloads[0].arguments):
756 def IsRequiredCppParameter(arg):
757 return 'RequiredCppParameter' in arg.ext_attrs
758 last_overload = overloads[-1]
759 if (len(last_overload.arguments) > position and
760 IsRequiredCppParameter(last_overload.arguments[position])):
761 for overload in overloads:
762 args = overload.arguments[position:]
763 if not all([IsRequiredCppParameter(arg) for arg in args]):
764 raise Exception('Invalid overload for RequiredCppParameter')
765 return True
766
767 return False
768
769 if ShouldGenerateSingleOperation():
770 generator.GenerateSingleOperation(emitter, info, indent, overloads[-1])
771 return False
772
773 # FIXME: Consider a simpler dispatch that iterates over the
774 # overloads and generates an overload specific check. Revisit
775 # when we move to named optional arguments.
776
777 # Partition the overloads to divide and conquer on the dispatch.
778 positive = []
779 negative = []
780 first_overload = overloads[0]
781 param = info.param_infos[position]
782
783 if position < len(first_overload.arguments):
784 # FIXME: This will not work if the second overload has a more
785 # precise type than the first. E.g.,
786 # void foo(Node x);
787 # void foo(Element x);
788 type = DartType(first_overload.arguments[position].type.id)
789 test = TypeCheck(param.name, type)
790 pred = lambda op: len(op.arguments) > position and DartType(op.arguments[pos ition].type.id) == type
791 else:
792 type = None
793 test = NullCheck(param.name)
794 pred = lambda op: position >= len(op.arguments)
795
796 for overload in overloads:
797 if pred(overload):
798 positive.append(overload)
799 else:
800 negative.append(overload)
801
802 if positive and negative:
803 (true_code, false_code) = emitter.Emit(
804 '$(INDENT)if ($COND) {\n'
805 '$!TRUE'
806 '$(INDENT)} else {\n'
807 '$!FALSE'
808 '$(INDENT)}\n',
809 COND=test, INDENT=indent)
810 fallthrough1 = GenerateDispatch(generator,
811 true_code, info, indent + ' ', position + 1, positive)
812 fallthrough2 = GenerateDispatch(generator,
813 false_code, info, indent + ' ', position, negative)
814 return fallthrough1 or fallthrough2
815
816 if negative:
817 raise Exception('Internal error, must be all positive')
818
819 # All overloads require the same test. Do we bother?
820
821 # If the test is the same as the method's formal parameter then checked mode
822 # will have done the test already. (It could be null too but we ignore that
823 # case since all the overload behave the same and we don't know which types
824 # in the IDL are not nullable.)
825 if type == param.dart_type:
826 return GenerateDispatch(generator,
827 emitter, info, indent, position + 1, positive)
828
829 # Otherwise the overloads have the same type but the type is a subtype of
830 # the method's synthesized formal parameter. e.g we have overloads f(X) and
831 # f(Y), implemented by the synthesized method f(Z) where X<Z and Y<Z. The
832 # dispatch has removed f(X), leaving only f(Y), but there is no guarantee
833 # that Y = Z-X, so we need to check for Y.
834 true_code = emitter.Emit(
835 '$(INDENT)if ($COND) {\n'
836 '$!TRUE'
837 '$(INDENT)}\n',
838 COND=test, INDENT=indent)
839 GenerateDispatch(generator,
840 true_code, info, indent + ' ', position + 1, positive)
841 return True
OLDNEW
« no previous file with comments | « no previous file | lib/dom/scripts/systemhtml.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698