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

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

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