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

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

Issue 10913125: Remove lib/dom directory! (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 3 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
(Empty)
1 #!/usr/bin/python
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
4 # BSD-style license that can be found in the LICENSE file.
5
6 """This module generates Dart APIs from the IDL database."""
7
8 import emitter
9 import idlnode
10 import logging
11 import os
12 import re
13 import shutil
14 import systembase
15 from generator import *
16
17 _logger = logging.getLogger('dartgenerator')
18
19 def MergeNodes(node, other):
20 node.operations.extend(other.operations)
21 for attribute in other.attributes:
22 if not node.has_attribute(attribute):
23 node.attributes.append(attribute)
24
25 node.constants.extend(other.constants)
26
27 class DartGenerator(object):
28 """Utilities to generate Dart APIs and corresponding JavaScript."""
29
30 def __init__(self):
31 self._auxiliary_files = {}
32 self._dart_templates_re = re.compile(r'[\w.:]+<([\w\.<>:]+)>')
33
34 def _StripModules(self, type_name):
35 return type_name.split('::')[-1]
36
37 def _IsCompoundType(self, database, type_name):
38 if IsRegisteredType(type_name):
39 return True
40
41 if type_name.endswith('?'):
42 return self._IsCompoundType(database, type_name[:-len('?')])
43
44 if type_name.endswith('[]'):
45 return self._IsCompoundType(database, type_name[:-len('[]')])
46
47 stripped_type_name = self._StripModules(type_name)
48 if database.HasInterface(stripped_type_name):
49 return True
50
51 dart_template_match = self._dart_templates_re.match(type_name)
52 if dart_template_match:
53 # Dart templates
54 parent_type_name = type_name[0 : dart_template_match.start(1) - 1]
55 sub_type_name = dart_template_match.group(1)
56 return (self._IsCompoundType(database, parent_type_name) and
57 self._IsCompoundType(database, sub_type_name))
58 return False
59
60 def _IsDartType(self, type_name):
61 return '.' in type_name
62
63 def LoadAuxiliary(self, auxiliary_dir):
64 def Visitor(_, dirname, names):
65 for name in names:
66 if name.endswith('.dart'):
67 name = name[0:-5] # strip off ".dart"
68 self._auxiliary_files[name] = os.path.join(dirname, name)
69 os.path.walk(auxiliary_dir, Visitor, None)
70
71 def RenameTypes(self, database, conversion_table, rename_javascript_binding_na mes):
72 """Renames interfaces using the given conversion table.
73
74 References through all interfaces will be renamed as well.
75
76 Args:
77 database: the database to apply the renames to.
78 conversion_table: maps old names to new names.
79 """
80
81 if conversion_table is None:
82 conversion_table = {}
83
84 # Rename interfaces:
85 for old_name, new_name in conversion_table.items():
86 if database.HasInterface(old_name):
87 _logger.info('renaming interface %s to %s' % (old_name, new_name))
88 interface = database.GetInterface(old_name)
89 if not database.HasInterface(new_name):
90 interface.id = new_name
91 database.DeleteInterface(old_name)
92 database.AddInterface(interface)
93
94 if rename_javascript_binding_names:
95 interface.javascript_binding_name = new_name
96 interface.doc_js_name = new_name
97 for member in (interface.operations + interface.constants
98 + interface.attributes):
99 member.doc_js_interface_name = new_name
100
101
102 # Fix references:
103 for interface in database.GetInterfaces():
104 for idl_type in interface.all(idlnode.IDLType):
105 type_name = self._StripModules(idl_type.id)
106 if type_name in conversion_table:
107 idl_type.id = conversion_table[type_name]
108
109 def FilterMembersWithUnidentifiedTypes(self, database):
110 """Removes unidentified types.
111
112 Removes constants, attributes, operations and parents with unidentified
113 types.
114 """
115
116 for interface in database.GetInterfaces():
117 def IsIdentified(idl_node):
118 node_name = idl_node.id if idl_node.id else 'parent'
119 for idl_type in idl_node.all(idlnode.IDLType):
120 type_name = idl_type.id
121 if (type_name is not None and
122 self._IsCompoundType(database, type_name)):
123 continue
124 _logger.warn('removing %s in %s which has unidentified type %s' %
125 (node_name, interface.id, type_name))
126 return False
127 return True
128
129 interface.constants = filter(IsIdentified, interface.constants)
130 interface.attributes = filter(IsIdentified, interface.attributes)
131 interface.operations = filter(IsIdentified, interface.operations)
132 interface.parents = filter(IsIdentified, interface.parents)
133
134 def FilterInterfaces(self, database,
135 and_annotations=[],
136 or_annotations=[],
137 exclude_displaced=[],
138 exclude_suppressed=[]):
139 """Filters a database to remove interfaces and members that are missing
140 annotations.
141
142 The FremontCut IDLs use annotations to specify implementation
143 status in various platforms. For example, if a member is annotated
144 with @WebKit, this means that the member is supported by WebKit.
145
146 Args:
147 database -- the database to filter
148 all_annotations -- a list of annotation names a member has to
149 have or it will be filtered.
150 or_annotations -- if a member has one of these annotations, it
151 won't be filtered even if it is missing some of the
152 all_annotations.
153 exclude_displaced -- if a member has this annotation and it
154 is marked as displaced it will always be filtered.
155 exclude_suppressed -- if a member has this annotation and it
156 is marked as suppressed it will always be filtered.
157 """
158
159 # Filter interfaces and members whose annotations don't match.
160 for interface in database.GetInterfaces():
161 def HasAnnotations(idl_node):
162 """Utility for determining if an IDLNode has all
163 the required annotations"""
164 for a in exclude_displaced:
165 if (a in idl_node.annotations
166 and 'via' in idl_node.annotations[a]):
167 return False
168 for a in exclude_suppressed:
169 if (a in idl_node.annotations
170 and 'suppressed' in idl_node.annotations[a]):
171 return False
172 for a in or_annotations:
173 if a in idl_node.annotations:
174 return True
175 if and_annotations == []:
176 return False
177 for a in and_annotations:
178 if a not in idl_node.annotations:
179 return False
180 return True
181
182 if HasAnnotations(interface):
183 interface.constants = filter(HasAnnotations, interface.constants)
184 interface.attributes = filter(HasAnnotations, interface.attributes)
185 interface.operations = filter(HasAnnotations, interface.operations)
186 interface.parents = filter(HasAnnotations, interface.parents)
187 else:
188 database.DeleteInterface(interface.id)
189
190 self.FilterMembersWithUnidentifiedTypes(database)
191
192 def Generate(self, database, system, super_database=None, webkit_renames={}):
193 self._database = database
194
195 # Collect interfaces
196 interfaces = []
197 for interface in database.GetInterfaces():
198 if not MatchSourceFilter(interface):
199 # Skip this interface since it's not present in the required source
200 _logger.info('Omitting interface - %s' % interface.id)
201 continue
202 interfaces.append(interface)
203
204 # TODO(sra): Use this list of exception names to generate information to
205 # tell dart2js which exceptions can be passed from JS to Dart code.
206 exceptions = self._CollectExceptions(interfaces)
207
208 super_map = dict((v, k) for k, v in webkit_renames.iteritems())
209
210 # Render all interfaces into Dart and save them in files.
211 for interface in self._PreOrderInterfaces(interfaces):
212
213 super_name = interface.id
214
215 if super_name in super_map:
216 super_name = super_map[super_name]
217
218 if (super_database is not None and
219 super_database.HasInterface(super_name)):
220 interface.ext_attrs['synthesizedSuperInterfaceName'] = super_name
221
222 interface_name = interface.id
223 auxiliary_file = self._auxiliary_files.get(interface_name)
224 if auxiliary_file is not None:
225 _logger.info('Skipping %s because %s exists' % (
226 interface_name, auxiliary_file))
227 continue
228
229 if 'Callback' in interface.ext_attrs:
230 handlers = [op for op in interface.operations if op.id == 'handleEvent']
231 info = AnalyzeOperation(interface, handlers)
232 system.ProcessCallback(interface, info)
233 else:
234 _logger.info('Generating %s' % interface.id)
235 system.ProcessInterface(interface)
236
237 system.GenerateLibraries()
238 system.Finish()
239
240 def _PreOrderInterfaces(self, interfaces):
241 """Returns the interfaces in pre-order, i.e. parents first."""
242 seen = set()
243 ordered = []
244 def visit(interface):
245 if interface.id in seen:
246 return
247 seen.add(interface.id)
248 for parent in interface.parents:
249 if IsDartCollectionType(parent.type.id):
250 continue
251 if self._database.HasInterface(parent.type.id):
252 parent_interface = self._database.GetInterface(parent.type.id)
253 visit(parent_interface)
254 ordered.append(interface)
255
256 for interface in interfaces:
257 visit(interface)
258 return ordered
259
260 def _CollectExceptions(self, interfaces):
261 """Returns the names of all exception classes raised."""
262 exceptions = set()
263 for interface in interfaces:
264 for attribute in interface.attributes:
265 if attribute.get_raises:
266 exceptions.add(attribute.get_raises.id)
267 if attribute.set_raises:
268 exceptions.add(attribute.set_raises.id)
269 for operation in interface.operations:
270 if operation.raises:
271 exceptions.add(operation.raises.id)
272 return exceptions
273
274
275 def FixEventTargets(self, database):
276 for interface in database.GetInterfaces():
277 # Create fake EventTarget parent interface for interfaces that have
278 # 'EventTarget' extended attribute.
279 if 'EventTarget' in interface.ext_attrs:
280 ast = [('Annotation', [('Id', 'WebKit')]),
281 ('InterfaceType', ('ScopedName', 'EventTarget'))]
282 interface.parents.append(idlnode.IDLParentInterface(ast))
283
284 def AddMissingArguments(self, database):
285 ARG = idlnode.IDLArgument([('Type', ('ScopedName', 'Object')), ('Id', 'arg') ])
286 for interface in database.GetInterfaces():
287 for operation in interface.operations:
288 if operation.ext_attrs.get('CallWith') == 'ScriptArguments|CallStack':
289 operation.arguments.append(ARG)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698