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

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

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

Powered by Google App Engine
This is Rietveld 408576698