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

Side by Side Diff: sdk/lib/html/scripts/htmldartgenerator.py

Issue 11363130: Cleaning up dart:html generation after interface/implementation merge. Removing most of the interfa… (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 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 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 from generator import DartDomNameOfAttribute 9 from generator import AnalyzeOperation, ConstantOutputOrder, \
10 DartDomNameOfAttribute, FindMatchingAttribute, IsDartCollectionType, \
11 IsPureInterface
12
13 # Types that are accessible cross-frame in a limited fashion.
14 # In these cases, the base type (e.g., Window) provides restricted access
15 # while the subtype (e.g., LocalWindow) provides full access to the
16 # corresponding objects if there are from the same frame.
17 _secure_base_types = {
18 'LocalWindow': 'Window',
19 'LocalLocation': 'Location',
20 'LocalHistory': 'History',
21 }
10 22
11 class HtmlDartGenerator(object): 23 class HtmlDartGenerator(object):
12 def __init__(self, interface, options): 24 def __init__(self, interface, options):
25 self._database = options.database
13 self._interface = interface 26 self._interface = interface
27 self._type_registry = options.type_registry
28 self._interface_type_info = self._type_registry.TypeInfo(self._interface.id)
29 self._renamer = options.renamer
14 30
15 def EmitAttributeDocumentation(self, attribute): 31 def EmitAttributeDocumentation(self, attribute):
16 dom_name = DartDomNameOfAttribute(attribute) 32 dom_name = DartDomNameOfAttribute(attribute)
17 self._members_emitter.Emit('\n /** @domName $DOMINTERFACE.$DOMNAME */', 33 self._members_emitter.Emit('\n /** @domName $DOMINTERFACE.$DOMNAME */',
18 DOMINTERFACE=attribute.doc_js_interface_name, 34 DOMINTERFACE=attribute.doc_js_interface_name,
19 DOMNAME=dom_name) 35 DOMNAME=dom_name)
20 36
21 def EmitOperationDocumentation(self, operation): 37 def EmitOperationDocumentation(self, operation):
22 self._members_emitter.Emit('\n /** @domName $DOMINTERFACE.$DOMNAME */', 38 self._members_emitter.Emit('\n /** @domName $DOMINTERFACE.$DOMNAME */',
23 DOMINTERFACE=operation.overloads[0].doc_js_interface_name, 39 DOMINTERFACE=operation.overloads[0].doc_js_interface_name,
24 DOMNAME=operation.name) 40 DOMNAME=operation.name)
25 41
42 def EmitEventGetter(self, events_class_name):
43 self._members_emitter.Emit(
44 '\n /**'
45 '\n * @domName EventTarget.addEventListener, '
46 'EventTarget.removeEventListener, EventTarget.dispatchEvent'
47 '\n */'
48 '\n $TYPE get on =>\n new $TYPE(this);\n',
49 TYPE=events_class_name)
50
51 def AddMembers(self, interface, declare_only=False):
vsm 2012/11/07 22:31:28 Is declare_only ever True now?
blois 2012/11/08 00:08:34 Yes, this is used for merged classes in Dartium.
52 for const in sorted(interface.constants, ConstantOutputOrder):
53 self.AddConstant(const)
54
55 for attr in sorted(interface.attributes, ConstantOutputOrder):
56 if attr.type.id != 'EventListener':
57 self.AddAttribute(attr, declare_only)
58
59 # The implementation should define an indexer if the interface directly
60 # extends List.
61 element_type = None
62 requires_indexer = False
63 if self._interface_type_info.list_item_type():
64 self.AddIndexer(self._interface_type_info.list_item_type())
65 else:
66 for parent in self._database.Hierarchy(self._interface):
67 if parent == self._interface:
68 continue
69 parent_type_info = self._type_registry.TypeInfo(parent.id)
70 if parent_type_info.list_item_type():
71 self.AmendIndexer(parent_type_info.list_item_type())
72 break
73
74 # Group overloaded operations by id
75 operationsById = {}
76 for operation in interface.operations:
77 if operation.id not in operationsById:
78 operationsById[operation.id] = []
79 operationsById[operation.id].append(operation)
80
81 # Generate operations
82 for id in sorted(operationsById.keys()):
83 operations = operationsById[id]
84 info = AnalyzeOperation(interface, operations)
85 self.AddOperation(info, declare_only)
86
87 def AddSecondaryMembers(self, interface):
88 # With multiple inheritance, attributes and operations of non-first
89 # interfaces need to be added. Sometimes the attribute or operation is
90 # defined in the current interface as well as a parent. In that case we
91 # avoid making a duplicate definition and pray that the signatures match.
92 secondary_parents = self._TransitiveSecondaryParents(interface)
93 for parent_interface in sorted(secondary_parents):
94 if isinstance(parent_interface, str): # IsDartCollectionType(parent_inter face)
vsm 2012/11/07 22:31:28 nit: line length
blois 2012/11/08 00:08:34 Done.
95 continue
96 for attr in sorted(parent_interface.attributes, ConstantOutputOrder):
97 if not FindMatchingAttribute(interface, attr):
98 self.SecondaryContext(parent_interface)
99 self.AddAttribute(attr)
100
101 # Group overloaded operations by id
102 operationsById = {}
103 for operation in parent_interface.operations:
104 if operation.id not in operationsById:
105 operationsById[operation.id] = []
106 operationsById[operation.id].append(operation)
107
108 # Generate operations
109 for id in sorted(operationsById.keys()):
110 if not any(op.id == id for op in interface.operations):
111 operations = operationsById[id]
112 info = AnalyzeOperation(interface, operations)
113 self.SecondaryContext(parent_interface)
114 self.AddOperation(info)
115
116 def AddAttribute(self, attribute, declare_only=False):
117 dom_name = DartDomNameOfAttribute(attribute)
118 html_name = self._renamer.RenameMember(
119 self._interface.id, attribute, dom_name, 'get:')
120 if not html_name or self._IsPrivate(html_name):
121 return
122
123 html_setter_name = self._renamer.RenameMember(
124 self._interface.id, attribute, dom_name, 'set:')
125 read_only = (attribute.is_read_only or 'Replaceable' in attribute.ext_attrs
126 or not html_setter_name)
127
128 # We don't yet handle inconsistent renames of the getter and setter yet.
129 assert(not html_setter_name or html_name == html_setter_name)
130
131 if declare_only:
132 self.DeclareAttribute(attribute,
133 self.SecureOutputType(attribute.type.id), html_name, read_only)
134 else:
135 self.EmitAttribute(attribute, html_name, read_only)
136
137 def AddOperation(self, info, declare_only=False):
138 """
139 Arguments:
140 operations - contains the overloads, one or more operations with the same
141 name.
142 """
143 # FIXME: When we pass in operations[0] below, we're assuming all
144 # overloaded operations have the same security attributes. This
145 # is currently true, but we should consider filtering earlier or
146 # merging the relevant data into info itself.
147 html_name = self._renamer.RenameMember(self._interface.id,
148 info.operations[0],
149 info.name)
150 if not html_name:
151 if info.name == 'item':
152 # FIXME: item should be renamed to operator[], not removed.
153 self.EmitOperation(info, '_item')
154 return
155
156 if declare_only:
157 self.DeclareOperation(info,
158 self.SecureOutputType(info.type_name), html_name)
159 else:
160 self.EmitOperation(info, html_name)
161
26 def AdditionalImplementedInterfaces(self): 162 def AdditionalImplementedInterfaces(self):
27 # TODO: Include all implemented interfaces, including other Lists. 163 # TODO: Include all implemented interfaces, including other Lists.
28 implements = [] 164 implements = []
29 if self._interface_type_info.is_typed_array(): 165 if self._interface_type_info.is_typed_array():
30 element_type = self._interface_type_info.list_item_type() 166 element_type = self._interface_type_info.list_item_type()
31 implements.append('List<%s>' % self._DartType(element_type)) 167 implements.append('List<%s>' % self._DartType(element_type))
32 if self._interface_type_info.list_item_type(): 168 if self._interface_type_info.list_item_type():
33 item_type_info = self._type_registry.TypeInfo( 169 item_type_info = self._type_registry.TypeInfo(
34 self._interface_type_info.list_item_type()) 170 self._interface_type_info.list_item_type())
35 implements.append('List<%s>' % item_type_info.dart_type()) 171 implements.append('List<%s>' % item_type_info.dart_type())
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
79 215
80 def DeclareOperation(self, operation, type_name, html_name): 216 def DeclareOperation(self, operation, type_name, html_name):
81 # Declares an operation but does not include the code to invoke it. 217 # Declares an operation but does not include the code to invoke it.
82 self.EmitOperationDocumentation(operation) 218 self.EmitOperationDocumentation(operation)
83 self._members_emitter.Emit( 219 self._members_emitter.Emit(
84 '\n' 220 '\n'
85 ' $TYPE $NAME($PARAMS);\n', 221 ' $TYPE $NAME($PARAMS);\n',
86 TYPE=type_name, 222 TYPE=type_name,
87 NAME=html_name, 223 NAME=html_name,
88 PARAMS=operation.ParametersDeclaration(self._DartType)) 224 PARAMS=operation.ParametersDeclaration(self._DartType))
225
226 def SecureOutputType(self, type_name, is_dart_type=False):
227 if is_dart_type:
228 dart_name = type_name
229 else:
230 dart_name = self._DartType(type_name)
231 # We only need to secure Window. Only local History and Location are return ed
vsm 2012/11/07 22:31:28 nit: line len
blois 2012/11/08 00:08:34 Done.
232 # in generated code.
233 if dart_name == 'LocalWindow':
234 return _secure_base_types[dart_name]
235 return dart_name
236
237 def SecureBaseName(self, type_name):
238 if type_name in _secure_base_types:
239 return _secure_base_types[type_name]
240
241 def _TransitiveSecondaryParents(self, interface):
242 """Returns a list of all non-primary parents.
243
244 The list contains the interface objects for interfaces defined in the
245 database, and the name for undefined interfaces.
246 """
247 def walk(parents):
248 for parent in parents:
249 parent_name = parent.type.id
250 if parent_name == 'EventTarget':
251 # Currently EventTarget is implemented as a mixin, not a proper
252 # super interface---ignore its members.
253 continue
254 if IsDartCollectionType(parent_name):
255 result.append(parent_name)
256 continue
257 if self._database.HasInterface(parent_name):
258 parent_interface = self._database.GetInterface(parent_name)
259 result.append(parent_interface)
260 walk(parent_interface.parents)
261
262 result = []
263 if interface.parents:
264 parent = interface.parents[0]
265 if IsPureInterface(parent.type.id):
266 walk(interface.parents)
267 else:
268 walk(interface.parents[1:])
269 return result
270
271 def _DartType(self, type_name):
272 return self._type_registry.DartType(type_name)
273
274 def _IsPrivate(self, name):
275 return name.startswith('_')
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698