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

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

Issue 11691009: Moved most of html lib generating scripts into tools. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 11 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 | « sdk/lib/html/scripts/dartdomgenerator.py ('k') | sdk/lib/html/scripts/dartgenerator_test.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 from generator import *
15
16 _logger = logging.getLogger('dartgenerator')
17
18 def MergeNodes(node, other):
19 node.operations.extend(other.operations)
20 for attribute in other.attributes:
21 if not node.has_attribute(attribute):
22 node.attributes.append(attribute)
23
24 node.constants.extend(other.constants)
25
26 class DartGenerator(object):
27 """Utilities to generate Dart APIs and corresponding JavaScript."""
28
29 def __init__(self):
30 self._auxiliary_files = {}
31 self._dart_templates_re = re.compile(r'[\w.:]+<([\w\.<>:]+)>')
32
33 def _StripModules(self, type_name):
34 return type_name.split('::')[-1]
35
36 def _IsCompoundType(self, database, type_name):
37 if IsRegisteredType(type_name):
38 return True
39
40 if type_name.endswith('?'):
41 return self._IsCompoundType(database, type_name[:-len('?')])
42
43 if type_name.endswith('[]'):
44 return self._IsCompoundType(database, type_name[:-len('[]')])
45
46 stripped_type_name = self._StripModules(type_name)
47 if database.HasInterface(stripped_type_name):
48 return True
49
50 dart_template_match = self._dart_templates_re.match(type_name)
51 if dart_template_match:
52 # Dart templates
53 parent_type_name = type_name[0 : dart_template_match.start(1) - 1]
54 sub_type_name = dart_template_match.group(1)
55 return (self._IsCompoundType(database, parent_type_name) and
56 self._IsCompoundType(database, sub_type_name))
57 return False
58
59 def _IsDartType(self, type_name):
60 return '.' in type_name
61
62 def LoadAuxiliary(self, auxiliary_dir):
63 def Visitor(_, dirname, names):
64 for name in names:
65 if name.endswith('.dart'):
66 name = name[0:-5] # strip off ".dart"
67 self._auxiliary_files[name] = os.path.join(dirname, name)
68 os.path.walk(auxiliary_dir, Visitor, None)
69
70 def FilterMembersWithUnidentifiedTypes(self, database):
71 """Removes unidentified types.
72
73 Removes constants, attributes, operations and parents with unidentified
74 types.
75 """
76
77 for interface in database.GetInterfaces():
78 def IsIdentified(idl_node):
79 node_name = idl_node.id if idl_node.id else 'parent'
80 for idl_type in idl_node.all(idlnode.IDLType):
81 type_name = idl_type.id
82 if (type_name is not None and
83 self._IsCompoundType(database, type_name)):
84 continue
85 _logger.warn('removing %s in %s which has unidentified type %s' %
86 (node_name, interface.id, type_name))
87 return False
88 return True
89
90 interface.constants = filter(IsIdentified, interface.constants)
91 interface.attributes = filter(IsIdentified, interface.attributes)
92 interface.operations = filter(IsIdentified, interface.operations)
93 interface.parents = filter(IsIdentified, interface.parents)
94
95 def FilterInterfaces(self, database,
96 and_annotations=[],
97 or_annotations=[],
98 exclude_displaced=[],
99 exclude_suppressed=[]):
100 """Filters a database to remove interfaces and members that are missing
101 annotations.
102
103 The FremontCut IDLs use annotations to specify implementation
104 status in various platforms. For example, if a member is annotated
105 with @WebKit, this means that the member is supported by WebKit.
106
107 Args:
108 database -- the database to filter
109 all_annotations -- a list of annotation names a member has to
110 have or it will be filtered.
111 or_annotations -- if a member has one of these annotations, it
112 won't be filtered even if it is missing some of the
113 all_annotations.
114 exclude_displaced -- if a member has this annotation and it
115 is marked as displaced it will always be filtered.
116 exclude_suppressed -- if a member has this annotation and it
117 is marked as suppressed it will always be filtered.
118 """
119
120 # Filter interfaces and members whose annotations don't match.
121 for interface in database.GetInterfaces():
122 def HasAnnotations(idl_node):
123 """Utility for determining if an IDLNode has all
124 the required annotations"""
125 for a in exclude_displaced:
126 if (a in idl_node.annotations
127 and 'via' in idl_node.annotations[a]):
128 return False
129 for a in exclude_suppressed:
130 if (a in idl_node.annotations
131 and 'suppressed' in idl_node.annotations[a]):
132 return False
133 for a in or_annotations:
134 if a in idl_node.annotations:
135 return True
136 if and_annotations == []:
137 return False
138 for a in and_annotations:
139 if a not in idl_node.annotations:
140 return False
141 return True
142
143 if HasAnnotations(interface):
144 interface.constants = filter(HasAnnotations, interface.constants)
145 interface.attributes = filter(HasAnnotations, interface.attributes)
146 interface.operations = filter(HasAnnotations, interface.operations)
147 interface.parents = filter(HasAnnotations, interface.parents)
148 else:
149 database.DeleteInterface(interface.id)
150
151 # Ugly temporary hack
152 websocket_interface = database.GetInterface('WebSocket')
153 def make_object(**fields):
154 o = type('Anon', (object,), {})()
155 for k, v in fields.items(): setattr(o, k, v)
156 o.ext_attrs = {}
157 return o
158 arg = make_object(id = 'url', type = make_object(id = 'DOMString'))
159 websocket_interface.ext_attrs['Constructor'] = make_object(arguments = [ar g])
160 websocket_interface.ext_attrs['CustomConstructor'] = True
161
162 self.FilterMembersWithUnidentifiedTypes(database)
163
164 def Generate(self, database, super_database, generate_interface):
165 self._database = database
166
167 # Collect interfaces
168 interfaces = []
169 for interface in database.GetInterfaces():
170 if not MatchSourceFilter(interface):
171 # Skip this interface since it's not present in the required source
172 _logger.info('Omitting interface - %s' % interface.id)
173 continue
174 interfaces.append(interface)
175
176 # TODO(sra): Use this list of exception names to generate information to
177 # tell dart2js which exceptions can be passed from JS to Dart code.
178 exceptions = self._CollectExceptions(interfaces)
179
180 # Render all interfaces into Dart and save them in files.
181 for interface in self._PreOrderInterfaces(interfaces):
182 interface_name = interface.id
183 auxiliary_file = self._auxiliary_files.get(interface_name)
184 if auxiliary_file is not None:
185 _logger.info('Skipping %s because %s exists' % (
186 interface_name, auxiliary_file))
187 continue
188
189 _logger.info('Generating %s' % interface.id)
190 generate_interface(interface)
191
192 def _PreOrderInterfaces(self, interfaces):
193 """Returns the interfaces in pre-order, i.e. parents first."""
194 seen = set()
195 ordered = []
196 def visit(interface):
197 if interface.id in seen:
198 return
199 seen.add(interface.id)
200 for parent in interface.parents:
201 if IsDartCollectionType(parent.type.id):
202 continue
203 if self._database.HasInterface(parent.type.id):
204 parent_interface = self._database.GetInterface(parent.type.id)
205 visit(parent_interface)
206 ordered.append(interface)
207
208 for interface in interfaces:
209 visit(interface)
210 return ordered
211
212 def _CollectExceptions(self, interfaces):
213 """Returns the names of all exception classes raised."""
214 exceptions = set()
215 for interface in interfaces:
216 for attribute in interface.attributes:
217 if attribute.get_raises:
218 exceptions.add(attribute.get_raises.id)
219 if attribute.set_raises:
220 exceptions.add(attribute.set_raises.id)
221 for operation in interface.operations:
222 if operation.raises:
223 exceptions.add(operation.raises.id)
224 return exceptions
225
226
227 def FixEventTargets(self, database):
228 for interface in database.GetInterfaces():
229 # Create fake EventTarget parent interface for interfaces that have
230 # 'EventTarget' extended attribute.
231 if 'EventTarget' in interface.ext_attrs:
232 ast = [('Annotation', [('Id', 'WebKit')]),
233 ('InterfaceType', ('ScopedName', 'EventTarget'))]
234 interface.parents.append(idlnode.IDLParentInterface(ast))
235
236 def AddMissingArguments(self, database):
237 ARG = idlnode.IDLArgument([('Type', ('ScopedName', 'object')), ('Id', 'arg') ])
238 for interface in database.GetInterfaces():
239 for operation in interface.operations:
240 if operation.ext_attrs.get('CallWith') == 'ScriptArguments|ScriptState':
241 operation.arguments.append(ARG)
OLDNEW
« no previous file with comments | « sdk/lib/html/scripts/dartdomgenerator.py ('k') | sdk/lib/html/scripts/dartgenerator_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698