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

Side by Side Diff: client/dom/scripts/systemfrog.py

Issue 9845043: Rename client/{dom,html} to lib/{dom,html} . (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 9 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 | « client/dom/scripts/systembase.py ('k') | client/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
(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 provides shared functionality for the systems to generate
7 frog binding from the IDL database."""
8
9 import os
10 from generator import *
11 from systembase import *
12
13 # Members (getters, setters, and methods) to suppress. These are
14 # either removed or custom implemented.
15 _dom_frog_omitted_members = set([
16 # Replace with custom.
17 'DOMWindow.get:top',
18 'HTMLIFrameElement.get:contentWindow',
19
20 # Remove.
21 'DOMWindow.get:frameElement',
22 'HTMLIFrameElement.get:contentDocument',
23 ])
24
25 class FrogSystem(System):
26
27 def __init__(self, templates, database, emitters, output_dir):
28 super(FrogSystem, self).__init__(
29 templates, database, emitters, output_dir)
30 self._impl_file_paths = []
31
32 def InterfaceGenerator(self,
33 interface,
34 common_prefix,
35 super_interface_name,
36 source_filter):
37 """."""
38 template_file = 'impl_%s.darttemplate' % interface.id
39 template = self._templates.TryLoad(template_file)
40 if not template:
41 template = self._templates.Load('frog_impl.darttemplate')
42
43 dart_code = self._ImplFileEmitter(interface.id)
44 return FrogInterfaceGenerator(self, interface, template,
45 super_interface_name, dart_code)
46
47 def GenerateLibraries(self, lib_dir):
48 self._GenerateLibFile(
49 'frog_dom.darttemplate',
50 os.path.join(lib_dir, 'dom_frog.dart'),
51 (self._interface_system._dart_interface_file_paths +
52 self._interface_system._dart_callback_file_paths +
53 self._impl_file_paths))
54
55 def Finish(self):
56 pass
57
58 def _ImplFileEmitter(self, name):
59 """Returns the file emitter of the Frog implementation file."""
60 path = os.path.join(self._output_dir, 'src', 'frog', '%s.dart' % name)
61 self._impl_file_paths.append(path)
62 return self._emitters.FileEmitter(path)
63
64 # ------------------------------------------------------------------------------
65
66 class FrogInterfaceGenerator(object):
67 """Generates a Frog class for a DOM IDL interface."""
68
69 def __init__(self, system, interface, template, super_interface, dart_code):
70 """Generates Dart code for the given interface.
71
72 Args:
73
74 interface: an IDLInterface instance. It is assumed that all types have
75 been converted to Dart types (e.g. int, String), unless they are in
76 the same package as the interface.
77 template: A string template.
78 super_interface: A string or None, the name of the common interface that
79 this interface implements, if any.
80 dart_code: an Emitter for the file containing the Dart implementation
81 class.
82 """
83 self._system = system
84 self._interface = interface
85 self._template = template
86 self._super_interface = super_interface
87 self._dart_code = dart_code
88 self._current_secondary_parent = None
89
90
91 def StartInterface(self):
92 interface = self._interface
93 interface_name = interface.id
94 self._class_name = self._ImplClassName(interface_name)
95
96 base = None
97 if interface.parents:
98 supertype = interface.parents[0].type.id
99 if IsDartCollectionType(supertype):
100 # List methods are injected in AddIndexer.
101 pass
102 else:
103 base = self._ImplClassName(supertype)
104
105 native_spec = MakeNativeSpec(interface.javascript_binding_name)
106
107 if base:
108 extends = ' extends ' + base
109 elif native_spec[0] == '=':
110 # The implementation is a singleton with no prototype.
111 extends = ''
112 else:
113 extends = ' extends _DOMTypeJs'
114
115 # TODO: Include all implemented interfaces, including other Lists.
116 implements = [interface_name]
117 element_type = MaybeTypedArrayElementType(self._interface)
118 if element_type:
119 implements.append('List<%s>' % DartType(element_type))
120
121 self._members_emitter = self._dart_code.Emit(
122 self._template,
123 #class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
124 #$!MEMBERS
125 #}
126 CLASSNAME=self._class_name,
127 EXTENDS=extends,
128 IMPLEMENTS=' implements ' + ', '.join(implements),
129 NATIVESPEC=' native "' + native_spec + '"')
130
131 element_type = MaybeTypedArrayElementType(interface)
132 if element_type:
133 self.AddTypedArrayConstructors(element_type)
134
135 # Emit a factory provider class for the constructor.
136 constructor_info = AnalyzeConstructor(interface)
137 if constructor_info:
138 self._EmitFactoryProvider(interface_name, constructor_info)
139
140
141 def FinishInterface(self):
142 """."""
143 pass
144
145 def _ImplClassName(self, type_name):
146 return '_' + type_name + 'Js'
147
148 def _EmitFactoryProvider(self, interface_name, constructor_info):
149 template_file = 'factoryprovider_%s.darttemplate' % interface_name
150 template = self._system._templates.TryLoad(template_file)
151 if not template:
152 template = self._system._templates.Load('factoryprovider.darttemplate')
153
154 factory_provider = '_' + interface_name + 'FactoryProvider'
155 emitter = self._system._ImplFileEmitter(factory_provider)
156 emitter.Emit(
157 template,
158 FACTORYPROVIDER=factory_provider,
159 CONSTRUCTOR=interface_name,
160 PARAMETERS=constructor_info.ParametersImplementationDeclaration(),
161 NAMEDCONSTRUCTOR=constructor_info.name or interface_name,
162 ARGUMENTS=constructor_info.ParametersAsArgumentList())
163
164 def _NarrowToImplementationType(self, type_name):
165 # TODO(sra): Move into the 'system' and cache the result.
166 if type_name == 'EventListener':
167 # Callbacks are typedef functions so don't have a class.
168 return type_name
169 if self._system._database.HasInterface(type_name):
170 interface = self._system._database.GetInterface(type_name)
171 if RecognizeCallback(interface):
172 # Callbacks are typedef functions so don't have a class.
173 return type_name
174 else:
175 return self._ImplClassName(type_name)
176 return type_name
177
178 def _NarrowInputType(self, type_name):
179 return self._NarrowToImplementationType(DartType(type_name))
180
181 def _NarrowOutputType(self, type_name):
182 return self._NarrowToImplementationType(DartType(type_name))
183
184 def AddConstant(self, constant):
185 # Since we are currently generating native classes without interfaces,
186 # generate the constants as part of the class. This will need to go away
187 # if we revert back to generating interfaces.
188 self._members_emitter.Emit('\n static final $TYPE $NAME = $VALUE;\n',
189 NAME=constant.id,
190 TYPE=DartType(constant.type.id),
191 VALUE=constant.value)
192
193 pass
194
195 def OverrideMember(self, member):
196 return self._interface.id + '.' + member in _dom_frog_omitted_members
197
198 def AddAttribute(self, getter, setter):
199 if getter and self.OverrideMember('get:' + getter.id):
200 getter = None
201 if setter and self.OverrideMember('set:' + setter.id):
202 setter = None
203 if not getter and not setter:
204 return
205
206 output_type = getter and self._NarrowOutputType(getter.type.id)
207 input_type = setter and self._NarrowInputType(setter.type.id)
208
209 # If the (getter, setter) pair is shadowing, we can't generate a shadowing
210 # field (Issue 1633).
211 (super_getter, super_getter_interface) = self._FindShadowedAttribute(getter)
212 (super_setter, super_setter_interface) = self._FindShadowedAttribute(setter)
213 if super_getter or super_setter:
214 if getter and not setter and super_getter and not super_setter:
215 if DartType(getter.type.id) == DartType(super_getter.type.id):
216 # Compatible getter, use the superclass property. This works because
217 # JavaScript will do its own dynamic dispatch.
218 self._members_emitter.Emit(
219 '\n'
220 ' // Use implementation from $SUPER.\n'
221 ' // final $TYPE $NAME;\n',
222 SUPER=super_getter_interface.id,
223 NAME=DartDomNameOfAttribute(getter), TYPE=output_type)
224 return
225
226 self._members_emitter.Emit('\n // Shadowing definition.')
227 self._AddAttributeUsingProperties(getter, setter)
228 return
229
230 # Can't generate field if attribute has different name in JS and Dart.
231 if self._AttributeChangesName(getter or setter):
232 self._AddAttributeUsingProperties(getter, setter)
233 return
234
235 if getter and setter and input_type == output_type:
236 self._members_emitter.Emit(
237 '\n $TYPE $NAME;\n',
238 NAME=DartDomNameOfAttribute(getter), TYPE=output_type)
239 return
240 if getter and not setter:
241 self._members_emitter.Emit(
242 '\n final $TYPE $NAME;\n',
243 NAME=DartDomNameOfAttribute(getter), TYPE=output_type)
244 return
245 self._AddAttributeUsingProperties(getter, setter)
246
247 def _AttributeChangesName(self, attr):
248 return attr.id != DartDomNameOfAttribute(attr)
249
250 def _AddAttributeUsingProperties(self, getter, setter):
251 if getter:
252 self._AddGetter(getter)
253 if setter:
254 self._AddSetter(setter)
255
256 def _AddGetter(self, attr):
257 # TODO(sra): Remove native body when Issue 829 fixed.
258 self._members_emitter.Emit(
259 '\n $TYPE get $NAME() native "return this.$NATIVE_NAME;";\n',
260 NAME=DartDomNameOfAttribute(attr),
261 NATIVE_NAME=attr.id,
262 TYPE=self._NarrowOutputType(attr.type.id))
263
264 def _AddSetter(self, attr):
265 # TODO(sra): Remove native body when Issue 829 fixed.
266 self._members_emitter.Emit(
267 ' void set $NAME($TYPE value) native "this.$NATIVE_NAME = value;";\n',
268 NAME=DartDomNameOfAttribute(attr),
269 NATIVE_NAME=attr.id,
270 TYPE=self._NarrowInputType(attr.type.id))
271
272 def _FindShadowedAttribute(self, attr):
273 """Returns (attribute, superinterface) or (None, None)."""
274 def FindInParent(interface):
275 """Returns matching attribute in parent, or None."""
276 if interface.parents:
277 parent = interface.parents[0]
278 if IsDartCollectionType(parent.type.id):
279 return (None, None)
280 if self._system._database.HasInterface(parent.type.id):
281 parent_interface = self._system._database.GetInterface(parent.type.id)
282 attr2 = FindMatchingAttribute(parent_interface, attr)
283 if attr2:
284 return (attr2, parent_interface)
285 return FindInParent(parent_interface)
286 return (None, None)
287
288 return FindInParent(self._interface) if attr else (None, None)
289
290
291 def AddSecondaryAttribute(self, interface, getter, setter):
292 self._SecondaryContext(interface)
293 self.AddAttribute(getter, setter)
294
295 def AddSecondaryOperation(self, interface, info):
296 self._SecondaryContext(interface)
297 self.AddOperation(info)
298
299 def _SecondaryContext(self, interface):
300 if interface is not self._current_secondary_parent:
301 self._current_secondary_parent = interface
302 self._members_emitter.Emit('\n // From $WHERE\n', WHERE=interface.id)
303
304 def AddIndexer(self, element_type):
305 """Adds all the methods required to complete implementation of List."""
306 # We would like to simply inherit the implementation of everything except
307 # get length(), [], and maybe []=. It is possible to extend from a base
308 # array implementation class only when there is no other implementation
309 # inheritance. There might be no implementation inheritance other than
310 # DOMBaseWrapper for many classes, but there might be some where the
311 # array-ness is introduced by a non-root interface:
312 #
313 # interface Y extends X, List<T> ...
314 #
315 # In the non-root case we have to choose between:
316 #
317 # class YImpl extends XImpl { add List<T> methods; }
318 #
319 # and
320 #
321 # class YImpl extends ListBase<T> { copies of transitive XImpl methods; }
322 #
323 self._members_emitter.Emit(
324 '\n'
325 ' $TYPE operator[](int index) native "return this[index];";\n',
326 TYPE=self._NarrowOutputType(element_type))
327
328 if 'CustomIndexedSetter' in self._interface.ext_attrs:
329 self._members_emitter.Emit(
330 '\n'
331 ' void operator[]=(int index, $TYPE value) native "this[index] = valu e";\n',
332 TYPE=self._NarrowInputType(element_type))
333 else:
334 self._members_emitter.Emit(
335 '\n'
336 ' void operator[]=(int index, $TYPE value) {\n'
337 ' throw new UnsupportedOperationException("Cannot assign element of immutable List.");\n'
338 ' }\n',
339 TYPE=self._NarrowInputType(element_type))
340
341 # TODO(sra): Use separate mixins for mutable implementations of List<T>.
342 # TODO(sra): Use separate mixins for typed array implementations of List<T>.
343 template_file = 'immutable_list_mixin.darttemplate'
344 template = self._system._templates.Load(template_file)
345 self._members_emitter.Emit(template, E=DartType(element_type))
346
347
348 def AddTypedArrayConstructors(self, element_type):
349 self._members_emitter.Emit(
350 '\n'
351 ' factory $CTOR(int length) => _construct_$CTOR(length);\n'
352 '\n'
353 ' factory $CTOR.fromList(List<$TYPE> list) => _construct_$CTOR(list);\n '
354 '\n'
355 ' factory $CTOR.fromBuffer(ArrayBuffer buffer) => _construct_$CTOR(buff er);\n'
356 '\n'
357 ' static _construct_$CTOR(arg) native \'return new $CTOR(arg);\';\n',
358 CTOR=self._interface.id,
359 TYPE=DartType(element_type))
360
361
362 def AddOperation(self, info):
363 """
364 Arguments:
365 info: An OperationInfo object.
366 """
367 # TODO(vsm): Handle overloads.
368 params = info.ParametersImplementationDeclaration(
369 lambda type_name: self._NarrowInputType(type_name))
370
371 native_body = dom_frog_native_bodies.get(
372 self._interface.id + '.' + info.name, '')
373 if native_body:
374 native_body = " '''" + native_body + "'''"
375
376 self._members_emitter.Emit(
377 '\n'
378 ' $TYPE $NAME($PARAMS) native$NATIVESTRING;\n',
379 TYPE=self._NarrowOutputType(info.type_name),
380 NAME=info.name,
381 PARAMS=params,
382 NATIVESTRING=native_body)
OLDNEW
« no previous file with comments | « client/dom/scripts/systembase.py ('k') | client/dom/scripts/systemhtml.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698