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

Side by Side Diff: lib/dom/scripts/systemhtml.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
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 system to generate 6 """This module provides shared functionality for the system to generate
7 Dart:html APIs from the IDL database.""" 7 Dart:html APIs from the IDL database."""
8 8
9 import generator
9 from systemfrog import * 10 from systemfrog import *
10 from systeminterface import * 11 from systeminterface import *
11 12
12 # Members from the standard dom that should not be exposed publicly in dart:html 13 # Members from the standard dom that should not be exposed publicly in dart:html
13 # but need to be exposed internally to implement dart:html on top of a standard 14 # but need to be exposed internally to implement dart:html on top of a standard
14 # browser. 15 # browser.
15 _private_html_members = set([ 16 _private_html_members = set([
16 'Document.createElement', 17 'Document.createElement',
17 'Document.createElementNS', 18 'Document.createElementNS',
18 'Document.createEvent', 19 'Document.createEvent',
(...skipping 1547 matching lines...) Expand 10 before | Expand all | Expand 10 after
1566 ' }\n', 1567 ' }\n',
1567 TYPE=info.type_name, 1568 TYPE=info.type_name,
1568 HTML_NAME=html_name, 1569 HTML_NAME=html_name,
1569 PARAMS=info.ParametersImplementationDeclaration()) 1570 PARAMS=info.ParametersImplementationDeclaration())
1570 1571
1571 # Process in order of ascending number of arguments to ensure missing 1572 # Process in order of ascending number of arguments to ensure missing
1572 # optional arguments are processed early. 1573 # optional arguments are processed early.
1573 overloads = sorted(info.overloads, 1574 overloads = sorted(info.overloads,
1574 key=lambda overload: len(overload.arguments)) 1575 key=lambda overload: len(overload.arguments))
1575 self._native_version = 0 1576 self._native_version = 0
1576 fallthrough = self.GenerateDispatch(body, info, ' ', 0, overloads) 1577 fallthrough = generator.GenerateDispatch(self, body, info, ' ', 0, overlo ads)
1577 if fallthrough: 1578 if fallthrough:
1578 body.Emit(' throw "Incorrect number or type of arguments";\n'); 1579 body.Emit(' throw "Incorrect number or type of arguments";\n');
1579 1580
1580 def AddStaticOperation(self, info): 1581 def AddStaticOperation(self, info):
1581 pass 1582 pass
1582 1583
1583 def GenerateSingleOperation(self, emitter, info, indent, operation): 1584 def GenerateSingleOperation(self, emitter, info, indent, operation):
1584 """Generates a call to a single operation. 1585 """Generates a call to a single operation.
1585 1586
1586 Arguments: 1587 Arguments:
(...skipping 15 matching lines...) Expand all
1602 THIS=self.DomObjectName(), 1603 THIS=self.DomObjectName(),
1603 NAME=info.name, 1604 NAME=info.name,
1604 ARGS=argument_expressions) 1605 ARGS=argument_expressions)
1605 else: 1606 else:
1606 emitter.Emit('$(INDENT)$(THIS).$NAME($ARGS);\n' 1607 emitter.Emit('$(INDENT)$(THIS).$NAME($ARGS);\n'
1607 '$(INDENT)return;\n', 1608 '$(INDENT)return;\n',
1608 INDENT=indent, 1609 INDENT=indent,
1609 THIS=self.DomObjectName(), 1610 THIS=self.DomObjectName(),
1610 NAME=info.name, 1611 NAME=info.name,
1611 ARGS=argument_expressions) 1612 ARGS=argument_expressions)
1612
1613 def GenerateDispatch(self, emitter, info, indent, position, overloads):
1614 """Generates a dispatch to one of the overloads.
1615
1616 Arguments:
1617 emitter: an Emitter for the body of a block of code.
1618 info: the compound information about the operation and its overloads.
1619 indent: an indentation string for generated code.
1620 position: the index of the parameter to dispatch on.
1621 overloads: a list of the remaining IDLOperations to dispatch.
1622
1623 Returns True if the dispatch can fall through on failure, False if the code
1624 always dispatches.
1625 """
1626
1627 def NullCheck(name):
1628 return '%s === null' % name
1629
1630 def TypeCheck(name, type):
1631 return '%s is %s' % (name, type)
1632
1633 if position == len(info.param_infos):
1634 if len(overloads) > 1:
1635 raise Exception('Duplicate operations ' + str(overloads))
1636 operation = overloads[0]
1637 self.GenerateSingleOperation(emitter, info, indent, operation)
1638 return False
1639
1640 # FIXME: Consider a simpler dispatch that iterates over the
1641 # overloads and generates an overload specific check. Revisit
1642 # when we move to named optional arguments.
1643
1644 # Partition the overloads to divide and conquer on the dispatch.
1645 positive = []
1646 negative = []
1647 first_overload = overloads[0]
1648 param = info.param_infos[position]
1649
1650 if position < len(first_overload.arguments):
1651 # FIXME: This will not work if the second overload has a more
1652 # precise type than the first. E.g.,
1653 # void foo(Node x);
1654 # void foo(Element x);
1655 type = DartType(first_overload.arguments[position].type.id)
1656 test = TypeCheck(param.name, type)
1657 pred = lambda op: (len(op.arguments) > position and
1658 DartType(op.arguments[position].type.id) == type)
1659 else:
1660 type = None
1661 test = NullCheck(param.name)
1662 pred = lambda op: position >= len(op.arguments)
1663
1664 for overload in overloads:
1665 if pred(overload):
1666 positive.append(overload)
1667 else:
1668 negative.append(overload)
1669
1670 if positive and negative:
1671 (true_code, false_code) = emitter.Emit(
1672 '$(INDENT)if ($COND) {\n'
1673 '$!TRUE'
1674 '$(INDENT)} else {\n'
1675 '$!FALSE'
1676 '$(INDENT)}\n',
1677 COND=test, INDENT=indent)
1678 fallthrough1 = self.GenerateDispatch(
1679 true_code, info, indent + ' ', position + 1, positive)
1680 fallthrough2 = self.GenerateDispatch(
1681 false_code, info, indent + ' ', position, negative)
1682 return fallthrough1 or fallthrough2
1683
1684 if negative:
1685 raise Exception('Internal error, must be all positive')
1686
1687 # All overloads require the same test. Do we bother?
1688
1689 # If the test is the same as the method's formal parameter then checked mode
1690 # will have done the test already. (It could be null too but we ignore that
1691 # case since all the overload behave the same and we don't know which types
1692 # in the IDL are not nullable.)
1693 if type == param.dart_type:
1694 return self.GenerateDispatch(
1695 emitter, info, indent, position + 1, positive)
1696
1697 # Otherwise the overloads have the same type but the type is a substype of
1698 # the method's synthesized formal parameter. e.g we have overloads f(X) and
1699 # f(Y), implemented by the synthesized method f(Z) where X<Z and Y<Z. The
1700 # dispatch has removed f(X), leaving only f(Y), but there is no guarantee
1701 # that Y = Z-X, so we need to check for Y.
1702 true_code = emitter.Emit(
1703 '$(INDENT)if ($COND) {\n'
1704 '$!TRUE'
1705 '$(INDENT)}\n',
1706 COND=test, INDENT=indent)
1707 self.GenerateDispatch(
1708 true_code, info, indent + ' ', position + 1, positive)
1709 return True
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698