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

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

Issue 11016009: Remove dart:dom scripts. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 2 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 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, options, 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__(
77 options.database, options.type_registry, interface)
78 self._template_loader = options.templates
79 self._interface = interface
80 self._template = template
81 self._dart_code = dart_code
82 self._current_secondary_parent = None
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 name = type_name
138 if type_name in nativified_classes:
139 name = nativified_classes[type_name]
140 return '_' + type_name + 'Js'
141
142 def _EmitFactoryProvider(self, interface_name, constructor_info):
143 template_file = 'factoryprovider_%s.darttemplate' % interface_name
144 template = self._template_loader.TryLoad(template_file)
145 if not template:
146 template = self._template_loader.Load('factoryprovider.darttemplate')
147
148 factory_provider = '_' + interface_name + 'FactoryProvider'
149 emitter = self._system._ImplFileEmitter(factory_provider)
150 emitter.Emit(
151 template,
152 FACTORYPROVIDER=factory_provider,
153 CONSTRUCTOR=interface_name,
154 PARAMETERS=constructor_info.ParametersImplementationDeclaration(self._Da rtType),
155 NAMEDCONSTRUCTOR=constructor_info.name or interface_name,
156 ARGUMENTS=constructor_info.ParametersAsArgumentList())
157
158 def _ShouldNarrowToImplementationType(self, type_name):
159 # TODO(sra): Move into the 'system' and cache the result.
160 do_not_narrow = ['DOMStringList', 'DOMStringMap', 'EventListener',
161 'IDBAny', 'IDBKey', 'MediaQueryListListener']
162 if type_name in do_not_narrow:
163 return False
164 if self._database.HasInterface(type_name):
165 interface = self._database.GetInterface(type_name)
166 # Callbacks are typedef functions so don't have a class.
167 return 'Callback' not in interface.ext_attrs
168 return False
169
170 def _NarrowToImplementationType(self, type_name):
171 if self._ShouldNarrowToImplementationType(type_name):
172 return self._ImplClassName(self._DartType(type_name))
173 return self._DartType(type_name)
174
175 def _NarrowInputType(self, type_name):
176 return self._NarrowToImplementationType(type_name)
177
178 def _NarrowOutputType(self, type_name):
179 return self._NarrowToImplementationType(type_name)
180
181 def AddConstant(self, constant):
182 # Since we are currently generating native classes without interfaces,
183 # generate the constants as part of the class. This will need to go away
184 # if we revert back to generating interfaces.
185 self._members_emitter.Emit('\n static const $TYPE $NAME = $VALUE;\n',
186 NAME=constant.id,
187 TYPE=self._DartType(constant.type.id),
188 VALUE=constant.value)
189
190 pass
191
192 def OverrideMember(self, member):
193 return self._interface.id + '.' + member in _dom_dart2js_omitted_members
194
195 def AddAttribute(self, attribute):
196 getter = attribute
197 setter = attribute if not IsReadOnly(attribute) else None
198 if getter and self.OverrideMember('get:' + getter.id):
199 getter = None
200 if setter and self.OverrideMember('set:' + setter.id):
201 setter = None
202 if not getter and not setter:
203 return
204
205 output_type = getter and self._NarrowOutputType(getter.type.id)
206 input_type = setter and self._NarrowInputType(setter.type.id)
207
208 # If the (getter, setter) pair is shadowing, we can't generate a shadowing
209 # field (Issue 1633).
210 (super_getter, super_getter_interface) = self._FindShadowedAttribute(getter)
211 (super_setter, super_setter_interface) = self._FindShadowedAttribute(setter)
212 if super_getter or super_setter:
213 if getter and not setter and super_getter and not super_setter:
214 if self._DartType(getter.type.id) == self._DartType(super_getter.type.id ):
215 # Compatible getter, use the superclass property. This works because
216 # JavaScript will do its own dynamic dispatch.
217 self._members_emitter.Emit(
218 '\n'
219 ' // Use implementation from $SUPER.\n'
220 ' // final $TYPE $NAME;\n',
221 SUPER=super_getter_interface,
222 NAME=DartDomNameOfAttribute(getter),
223 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),
239 TYPE=TypeOrVar(output_type))
240 return
241 if getter and not setter:
242 self._members_emitter.Emit(
243 '\n final $OPT_TYPE$NAME;\n',
244 NAME=DartDomNameOfAttribute(getter),
245 OPT_TYPE=TypeOrNothing(output_type))
246 return
247 self._AddAttributeUsingProperties(getter, setter)
248
249 def _AttributeChangesName(self, attr):
250 return attr.id != DartDomNameOfAttribute(attr)
251
252 def _AddAttributeUsingProperties(self, getter, setter):
253 if getter:
254 self._AddGetter(getter)
255 if setter:
256 self._AddSetter(setter)
257
258 def _AddGetter(self, attr):
259 # TODO(sra): Remove native body when Issue 829 fixed.
260 self._members_emitter.Emit(
261 '\n $(OPT_TYPE)get $NAME native "return this.$NATIVE_NAME;";\n',
262 NAME=DartDomNameOfAttribute(attr),
263 NATIVE_NAME=attr.id,
264 OPT_TYPE=TypeOrNothing(self._NarrowOutputType(attr.type.id)))
265
266 def _AddSetter(self, attr):
267 # TODO(sra): Remove native body when Issue 829 fixed.
268 self._members_emitter.Emit(
269 ' void set $NAME($(OPT_TYPE)value)'
270 ' native "this.$NATIVE_NAME = value;";\n',
271 NAME=DartDomNameOfAttribute(attr),
272 NATIVE_NAME=attr.id,
273 OPT_TYPE=TypeOrNothing(self._NarrowInputType(attr.type.id)))
274
275 def _FindShadowedAttribute(self, attr, merged_interfaces={}):
276 """Returns (attribute, superinterface) or (None, None)."""
277 def FindInParent(interface):
278 """Returns matching attribute in parent, or None."""
279 if interface.parents:
280 parent = interface.parents[0]
281 if IsDartCollectionType(parent.type.id):
282 return (None, None)
283 if IsPureInterface(parent.type.id):
284 return (None, None)
285 if self._database.HasInterface(parent.type.id):
286 interfaces_to_search_in = []
287 if parent.type.id in merged_interfaces:
288 # IDL parent was merged into another interface, which became a
289 # parent interface in Dart.
290 interfaces_to_search_in.append(parent.type.id)
291 parent_interface_name = merged_interfaces[parent.type.id]
292 else:
293 parent_interface_name = parent.type.id
294
295 for interface_name in merged_interfaces:
296 if merged_interfaces[interface_name] == parent_interface_name:
297 # IDL parent has another interface that was merged into it.
298 interfaces_to_search_in.append(interface_name)
299
300 interfaces_to_search_in.append(parent_interface_name)
301 for interface_name in interfaces_to_search_in:
302 interface = self._database.GetInterface(interface_name)
303 attr2 = FindMatchingAttribute(interface, attr)
304 if attr2:
305 return (attr2, parent_interface_name)
306
307 return FindInParent(
308 self._database.GetInterface(parent_interface_name))
309 return (None, None)
310
311 return FindInParent(self._interface) if attr else (None, None)
312
313
314 def AddSecondaryAttribute(self, interface, attribute):
315 self.SecondaryContext(interface)
316 self.AddAttribute(attribute)
317
318 def AddSecondaryOperation(self, interface, info):
319 self.SecondaryContext(interface)
320 self.AddOperation(info)
321
322 def SecondaryContext(self, interface):
323 if interface is not self._current_secondary_parent:
324 self._current_secondary_parent = interface
325 self._members_emitter.Emit('\n // From $WHERE\n', WHERE=interface.id)
326
327 def AddIndexer(self, element_type):
328 """Adds all the methods required to complete implementation of List."""
329 # We would like to simply inherit the implementation of everything except
330 # length, [], and maybe []=. It is possible to extend from a base
331 # array implementation class only when there is no other implementation
332 # inheritance. There might be no implementation inheritance other than
333 # DOMBaseWrapper for many classes, but there might be some where the
334 # array-ness is introduced by a non-root interface:
335 #
336 # interface Y extends X, List<T> ...
337 #
338 # In the non-root case we have to choose between:
339 #
340 # class YImpl extends XImpl { add List<T> methods; }
341 #
342 # and
343 #
344 # class YImpl extends ListBase<T> { copies of transitive XImpl methods; }
345 #
346 self._members_emitter.Emit(
347 '\n'
348 ' $TYPE operator[](int index) native "return this[index];";\n',
349 TYPE=self._NarrowOutputType(element_type))
350
351 if 'CustomIndexedSetter' in self._interface.ext_attrs:
352 self._members_emitter.Emit(
353 '\n'
354 ' void operator[]=(int index, $TYPE value) native "this[index] = valu e";\n',
355 TYPE=self._NarrowInputType(element_type))
356 else:
357 self._members_emitter.Emit(
358 '\n'
359 ' void operator[]=(int index, $TYPE value) {\n'
360 ' throw new UnsupportedOperationException("Cannot assign element of immutable List.");\n'
361 ' }\n',
362 TYPE=self._NarrowInputType(element_type))
363
364 # TODO(sra): Use separate mixins for mutable implementations of List<T>.
365 # TODO(sra): Use separate mixins for typed array implementations of List<T>.
366 template_file = 'immutable_list_mixin.darttemplate'
367 template = self._template_loader.Load(template_file)
368 self._members_emitter.Emit(template, E=self._DartType(element_type))
369
370 def AddOperation(self, info):
371 """
372 Arguments:
373 info: An OperationInfo object.
374 """
375 # TODO(vsm): Handle overloads.
376 params = info.ParametersImplementationDeclaration(
377 lambda type_name: self._NarrowInputType(type_name))
378
379 native_string = ''
380 if info.declared_name != info.name:
381 native_string = " '%s'" % info.declared_name
382
383 self._members_emitter.Emit(
384 '\n'
385 ' $TYPE $NAME($PARAMS) native$NATIVESTRING;\n',
386 TYPE=self._NarrowOutputType(info.type_name),
387 NAME=info.name,
388 PARAMS=params,
389 NATIVESTRING=native_string)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698