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

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

Issue 9424035: Move native system generator to a separate script. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: 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/generator.py ('k') | client/dom/scripts/systemwrapping.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 native binding from the IDL database."""
8
9 import emitter
10 import os
11 import systemwrapping
12 from generator import *
13 from systembase import *
14
15 class NativeImplementationSystem(System):
16
17 def __init__(self, templates, database, emitters, auxiliary_dir, output_dir):
18 super(NativeImplementationSystem, self).__init__(
19 templates, database, emitters, output_dir)
20
21 self._auxiliary_dir = auxiliary_dir
22 self._dom_public_files = []
23 self._dom_impl_files = []
24 self._cpp_header_files = []
25 self._cpp_impl_files = []
26
27 def InterfaceGenerator(self,
28 interface,
29 common_prefix,
30 super_interface_name,
31 source_filter):
32 interface_name = interface.id
33
34 dart_interface_path = self._FilePathForDartInterface(interface_name)
35 self._dom_public_files.append(dart_interface_path)
36
37 pure_interfaces = set([
sra1 2012/02/21 19:22:13 This could be moved to generator.py
38 'ElementTimeControl',
39 'ElementTraversal',
40 'MediaQueryListListener',
41 'NodeSelector',
42 'SVGExternalResourcesRequired',
43 'SVGFilterPrimitiveStandardAttributes',
44 'SVGFitToViewBox',
45 'SVGLangSpace',
46 'SVGLocatable',
47 'SVGStylable',
48 'SVGTests',
49 'SVGTransformable',
50 'SVGURIReference',
51 'SVGViewSpec',
52 'SVGZoomAndPan'])
53 if interface_name in pure_interfaces:
54 return None
55
56 dart_impl_path = self._FilePathForDartImplementation(interface_name)
57 self._dom_impl_files.append(dart_impl_path)
58
59 cpp_header_path = self._FilePathForCppHeader(interface_name)
60 self._cpp_header_files.append(cpp_header_path)
61
62 cpp_impl_path = self._FilePathForCppImplementation(interface_name)
63 self._cpp_impl_files.append(cpp_impl_path)
64
65 return NativeImplementationGenerator(interface, super_interface_name,
66 self._emitters.FileEmitter(dart_impl_path),
67 self._emitters.FileEmitter(cpp_header_path),
68 self._emitters.FileEmitter(cpp_impl_path),
69 self._BaseDefines(interface),
70 self._templates)
71
72 def ProcessCallback(self, interface, info):
73 self._interface = interface
74
75 dart_interface_path = self._FilePathForDartInterface(self._interface.id)
76 self._dom_public_files.append(dart_interface_path)
77
78 cpp_header_handlers_emitter = emitter.Emitter()
79 cpp_impl_handlers_emitter = emitter.Emitter()
80 class_name = 'Dart%s' % self._interface.id
81 for operation in interface.operations:
82 if operation.type.id == 'void':
83 return_type = 'void'
84 return_prefix = ''
85 else:
86 return_type = 'bool'
87 return_prefix = 'return '
88
89 parameters = []
90 arguments = []
91 for argument in operation.arguments:
92 argument_type_info = GetIDLTypeInfo(argument.type)
93 parameters.append('%s %s' % (argument_type_info.parameter_type(),
94 argument.id))
95 arguments.append(argument.id)
96
97 cpp_header_handlers_emitter.Emit(
98 '\n'
99 ' virtual $TYPE handleEvent($PARAMETERS);\n',
100 TYPE=return_type, PARAMETERS=', '.join(parameters))
101
102 cpp_impl_handlers_emitter.Emit(
103 '\n'
104 '$TYPE $CLASS_NAME::handleEvent($PARAMETERS)\n'
105 '{\n'
106 ' $(RETURN_PREFIX)m_callback.handleEvent($ARGUMENTS);\n'
107 '}\n',
108 TYPE=return_type,
109 CLASS_NAME=class_name,
110 PARAMETERS=', '.join(parameters),
111 RETURN_PREFIX=return_prefix,
112 ARGUMENTS=', '.join(arguments))
113
114 cpp_header_path = self._FilePathForCppHeader(self._interface.id)
115 cpp_header_emitter = self._emitters.FileEmitter(cpp_header_path)
116 cpp_header_emitter.Emit(
117 self._templates.Load('cpp_callback_header.template'),
118 INTERFACE=self._interface.id,
119 HANDLERS=cpp_header_handlers_emitter.Fragments())
120
121 cpp_impl_path = self._FilePathForCppImplementation(self._interface.id)
122 self._cpp_impl_files.append(cpp_impl_path)
123 cpp_impl_emitter = self._emitters.FileEmitter(cpp_impl_path)
124 cpp_impl_emitter.Emit(
125 self._templates.Load('cpp_callback_implementation.template'),
126 INTERFACE=self._interface.id,
127 HANDLERS=cpp_impl_handlers_emitter.Fragments())
128
129 def GenerateLibraries(self, lib_dir):
130 auxiliary_dir = os.path.relpath(self._auxiliary_dir, self._output_dir)
131
132 # Generate dom_public.dart.
133 self._GenerateLibFile(
134 'dom_public.darttemplate',
135 os.path.join(self._output_dir, 'dom_public.dart'),
136 self._dom_public_files,
137 AUXILIARY_DIR=auxiliary_dir);
138
139 # Generate dom_impl.dart.
140 self._GenerateLibFile(
141 'dom_impl.darttemplate',
142 os.path.join(self._output_dir, 'dom_impl.dart'),
143 self._dom_impl_files,
144 AUXILIARY_DIR=auxiliary_dir);
145
146 # Generate DartDerivedSourcesAll.cpp.
147 cpp_all_in_one_path = os.path.join(self._output_dir,
148 'DartDerivedSourcesAll.cpp')
149
150 includes_emitter = emitter.Emitter()
151 for f in self._cpp_impl_files:
152 path = os.path.relpath(f, os.path.dirname(cpp_all_in_one_path))
153 includes_emitter.Emit('#include "$PATH"\n', PATH=path)
154
155 cpp_all_in_one_emitter = self._emitters.FileEmitter(cpp_all_in_one_path)
156 cpp_all_in_one_emitter.Emit(
157 self._templates.Load('cpp_all_in_one.template'),
158 INCLUDES=includes_emitter.Fragments())
159
160 # Generate DartResolver.cpp.
161 cpp_resolver_path = os.path.join(self._output_dir, 'DartResolver.cpp')
162
163 includes_emitter = emitter.Emitter()
164 resolver_body_emitter = emitter.Emitter()
165 for f in self._cpp_header_files:
166 path = os.path.relpath(f, os.path.dirname(cpp_resolver_path))
167 includes_emitter.Emit('#include "$PATH"\n', PATH=path)
168 resolver_body_emitter.Emit(
169 ' if (Dart_NativeFunction func = $CLASS_NAME::resolver(name, argume ntCount))\n'
170 ' return func;\n',
171 CLASS_NAME=os.path.splitext(os.path.basename(path))[0])
172
173 cpp_resolver_emitter = self._emitters.FileEmitter(cpp_resolver_path)
174 cpp_resolver_emitter.Emit(
175 self._templates.Load('cpp_resolver.template'),
176 INCLUDES=includes_emitter.Fragments(),
177 RESOLVER_BODY=resolver_body_emitter.Fragments())
178
179 # Generate DartDerivedSourcesAll.cpp
180 cpp_all_in_one_path = os.path.join(self._output_dir,
181 'DartDerivedSourcesAll.cpp')
182
183 includes_emitter = emitter.Emitter()
184 for file in self._cpp_impl_files:
185 path = os.path.relpath(file, os.path.dirname(cpp_all_in_one_path))
186 includes_emitter.Emit('#include "$PATH"\n', PATH=path)
187
188 cpp_all_in_one_emitter = self._emitters.FileEmitter(cpp_all_in_one_path)
189 cpp_all_in_one_emitter.Emit(
190 self._templates.Load('cpp_all_in_one.template'),
191 INCLUDES=includes_emitter.Fragments())
192
193 # Generate DartResolver.cpp
194 cpp_resolver_path = os.path.join(self._output_dir, 'DartResolver.cpp')
195
196 includes_emitter = emitter.Emitter()
197 resolver_body_emitter = emitter.Emitter()
198 for file in self._cpp_header_files:
199 path = os.path.relpath(file, os.path.dirname(cpp_resolver_path))
200 includes_emitter.Emit('#include "$PATH"\n', PATH=path)
201 resolver_body_emitter.Emit(
202 ' if (Dart_NativeFunction func = $CLASS_NAME::resolver(name, argu mentCount))\n'
203 ' return func;\n',
204 CLASS_NAME=os.path.splitext(os.path.basename(path))[0])
205
206 cpp_resolver_emitter = self._emitters.FileEmitter(cpp_resolver_path)
207 cpp_resolver_emitter.Emit(
208 self._templates.Load('cpp_resolver.template'),
209 INCLUDES=includes_emitter.Fragments(),
210 RESOLVER_BODY=resolver_body_emitter.Fragments())
211
212 def Finish(self):
213 pass
214
215 def _FilePathForDartInterface(self, interface_name):
216 return os.path.join(self._output_dir, 'src', 'interface',
217 '%s.dart' % interface_name)
218
219 def _FilePathForDartImplementation(self, interface_name):
220 return os.path.join(self._output_dir, 'dart',
221 '%sImplementation.dart' % interface_name)
222
223 def _FilePathForCppHeader(self, interface_name):
224 return os.path.join(self._output_dir, 'cpp', 'Dart%s.h' % interface_name)
225
226 def _FilePathForCppImplementation(self, interface_name):
227 return os.path.join(self._output_dir, 'cpp', 'Dart%s.cpp' % interface_name)
228
229
230 class NativeImplementationGenerator(systemwrapping.WrappingInterfaceGenerator):
231 """Generates Dart implementation for one DOM IDL interface."""
232
233 def __init__(self, interface, super_interface,
234 dart_impl_emitter, cpp_header_emitter, cpp_impl_emitter,
235 base_members, templates):
236 """Generates Dart and C++ code for the given interface.
237
238 Args:
239
240 interface: an IDLInterface instance. It is assumed that all types have
241 been converted to Dart types (e.g. int, String), unless they are in
242 the same package as the interface.
243 super_interface: A string or None, the name of the common interface that
244 this interface implements, if any.
245 dart_impl_emitter: an Emitter for the file containing the Dart
246 implementation class.
247 cpp_header_emitter: an Emitter for the file containing the C++ header.
248 cpp_impl_emitter: an Emitter for the file containing the C++
249 implementation.
250 base_members: a set of names of members defined in a base class. This is
251 used to avoid static member 'overriding' in the generated Dart code.
252 """
253 self._interface = interface
254 self._super_interface = super_interface
255 self._dart_impl_emitter = dart_impl_emitter
256 self._cpp_header_emitter = cpp_header_emitter
257 self._cpp_impl_emitter = cpp_impl_emitter
258 self._base_members = base_members
259 self._templates = templates
260 self._current_secondary_parent = None
261
262 def StartInterface(self):
263 self._class_name = self._ImplClassName(self._interface.id)
264 self._interface_type_info = GetIDLTypeInfoByName(self._interface.id)
265 self._members_emitter = emitter.Emitter()
266 self._cpp_declarations_emitter = emitter.Emitter()
267 self._cpp_impl_includes = {}
268 self._cpp_definitions_emitter = emitter.Emitter()
269 self._cpp_resolver_emitter = emitter.Emitter()
270
271 # Generate constructor.
272 # FIXME: add proper support for non-custom constructors.
273 if ('CustomConstructor' in self._interface.ext_attrs or
274 'V8CustomConstructor' in self._interface.ext_attrs or
275 self._interface.id in ['FileReader', 'WebKitCSSMatrix', 'XSLTProcessor'] ):
276 self._cpp_resolver_emitter.Emit(
277 ' if (name == "$(INTERFACE_NAME)_constructor_Callback")\n'
278 ' return Dart$(INTERFACE_NAME)Internal::constructorCallback;\n' ,
279 INTERFACE_NAME=self._interface.id)
280 self._cpp_declarations_emitter.Emit(
281 '\n'
282 'void constructorCallback(Dart_NativeArguments);\n')
283
284 def _ImplClassName(self, interface_name):
285 return interface_name + 'Implementation'
286
287 def FinishInterface(self):
288 base = self._BaseClassName(self._interface)
289 self._dart_impl_emitter.Emit(
290 self._templates.Load('dart_implementation.darttemplate'),
291 CLASS=self._class_name, BASE=base, INTERFACE=self._interface.id,
292 MEMBERS=self._members_emitter.Fragments())
293
294 self._GenerateCppHeader()
295
296 self._cpp_impl_emitter.Emit(
297 self._templates.Load('cpp_implementation.template'),
298 INTERFACE=self._interface.id,
299 INCLUDES=''.join(['#include "%s.h"\n' %
300 k for k in self._cpp_impl_includes.keys()]),
301 CALLBACKS=self._cpp_definitions_emitter.Fragments(),
302 RESOLVER=self._cpp_resolver_emitter.Fragments())
303
304 def _GenerateCppHeader(self):
305 webcore_include = self._interface_type_info.webcore_include()
306 if webcore_include:
307 webcore_include = '#include "%s.h"\n' % webcore_include
308 else:
309 webcore_include = ''
310
311 if ('CustomToJS' in self._interface.ext_attrs or
312 'CustomToJSObject' in self._interface.ext_attrs or
313 'PureInterface' in self._interface.ext_attrs or
314 'CPPPureInterface' in self._interface.ext_attrs or
315 self._interface_type_info.custom_to_dart()):
316 to_dart_value_template = (
317 'Dart_Handle toDartValue($(WEBCORE_CLASS_NAME)* value);\n')
318 else:
319 to_dart_value_template = (
320 'inline Dart_Handle toDartValue($(WEBCORE_CLASS_NAME)* value)\n'
321 '{\n'
322 ' return DartDOMWrapper::toDart<Dart$(INTERFACE)>(value);\n'
323 '}\n')
324 to_dart_value_emitter = emitter.Emitter()
325 to_dart_value_emitter.Emit(
326 to_dart_value_template,
327 INTERFACE=self._interface.id,
328 WEBCORE_CLASS_NAME=self._interface_type_info.native_type())
329
330 self._cpp_header_emitter.Emit(
331 self._templates.Load('cpp_header.template'),
332 INTERFACE=self._interface.id,
333 WEBCORE_INCLUDE=webcore_include,
334 ADDITIONAL_INCLUDES='',
335 WEBCORE_CLASS_NAME=self._interface_type_info.native_type(),
336 TO_DART_VALUE=to_dart_value_emitter.Fragments(),
337 DECLARATIONS=self._cpp_declarations_emitter.Fragments())
338
339 def AddAttribute(self, getter, setter):
340 # FIXME: Dartium does not support attribute event listeners. However, JS
341 # implementation falls back to them when addEventListener is not available.
342 # Make sure addEventListener is available in all EventTargets and remove
343 # this check.
344 if (getter or setter).type.id == 'EventListener':
345 return
346
347 # FIXME: support 'ImplementedBy'.
348 if 'ImplementedBy' in (getter or setter).ext_attrs:
349 return
350
351 # FIXME: these should go away.
352 classes_with_unsupported_custom_getters = [
353 'Clipboard', 'Console', 'Coordinates', 'DeviceMotionEvent',
354 'DeviceOrientationEvent', 'FileReader', 'JavaScriptCallFrame',
355 'HTMLInputElement', 'HTMLOptionsCollection', 'HTMLOutputElement',
356 'ScriptProfileNode', 'WebKitAnimation']
357 if (self._interface.id in classes_with_unsupported_custom_getters and
358 getter and set(['Custom', 'CustomGetter']) & set(getter.ext_attrs)):
359 return
360
361 if getter:
362 self._AddGetter(getter)
363 if setter:
364 self._AddSetter(setter)
365
366 def _AddGetter(self, attr):
367 dart_declaration = '%s get %s()' % (attr.type.id, attr.id)
368 is_custom = 'Custom' in attr.ext_attrs or 'CustomGetter' in attr.ext_attrs
369 cpp_callback_name = self._GenerateNativeBinding(attr.id, 1,
370 dart_declaration, 'Getter', is_custom)
371 if is_custom:
372 return
373
374 arguments = []
375 if 'Reflect' in attr.ext_attrs:
376 webcore_function_name = GetIDLTypeInfo(attr.type).webcore_getter_name()
377 if 'URL' in attr.ext_attrs:
378 if 'NonEmpty' in attr.ext_attrs:
379 webcore_function_name = 'getNonEmptyURLAttribute'
380 else:
381 webcore_function_name = 'getURLAttribute'
382 arguments.append(self._GenerateWebCoreReflectionAttributeName(attr))
383 else:
384 if attr.id == 'operator':
385 webcore_function_name = '_operator'
386 elif attr.id == 'target' and attr.type.id == 'SVGAnimatedString':
387 webcore_function_name = 'svgTarget'
388 else:
389 webcore_function_name = re.sub(r'^(HTML|URL|JS|XML|XSLT|\w)',
390 lambda s: s.group(1).lower(),
391 attr.id)
392 webcore_function_name = re.sub(r'^(create|exclusive)',
393 lambda s: 'is' + s.group(1).capitalize(),
394 webcore_function_name)
395 if attr.type.id.startswith('SVGAnimated'):
396 webcore_function_name += 'Animated'
397
398 self._GenerateNativeCallback(cpp_callback_name, attr, '',
399 webcore_function_name, arguments, idl_return_type=attr.type,
400 raises_dart_exceptions=attr.get_raises,
401 raises_dom_exceptions=attr.get_raises)
402
403 def _AddSetter(self, attr):
404 dart_declaration = 'void set %s(%s)' % (attr.id, attr.type.id)
405 is_custom = set(['Custom', 'CustomSetter', 'V8CustomSetter']) & set(attr.ext _attrs)
406 cpp_callback_name = self._GenerateNativeBinding(attr.id, 2,
407 dart_declaration, 'Setter', is_custom)
408 if is_custom:
409 return
410
411 arguments = []
412 if 'Reflect' in attr.ext_attrs:
413 webcore_function_name = GetIDLTypeInfo(attr.type).webcore_setter_name()
414 arguments.append(self._GenerateWebCoreReflectionAttributeName(attr))
415 else:
416 webcore_function_name = re.sub(r'^(xml(?=[A-Z])|\w)',
417 lambda s: s.group(1).upper(),
418 attr.id)
419 webcore_function_name = 'set%s' % webcore_function_name
420 if attr.type.id.startswith('SVGAnimated'):
421 webcore_function_name += 'Animated'
422
423 arguments.append(attr.id)
424 parameter_definitions_emitter = emitter.Emitter()
425 self._GenerateParameterAdapter(parameter_definitions_emitter, attr, 0)
426 parameter_definitions = parameter_definitions_emitter.Fragments()
427 self._GenerateNativeCallback(cpp_callback_name, attr, parameter_definitions,
428 webcore_function_name, arguments, idl_return_type=None,
429 raises_dart_exceptions=True,
430 raises_dom_exceptions=attr.set_raises)
431
432 def _HasNativeIndexGetter(self, interface):
433 return ('CustomIndexedGetter' in interface.ext_attrs or
434 'NumericIndexedGetter' in interface.ext_attrs)
435
436 def _EmitNativeIndexGetter(self, interface, element_type):
437 dart_declaration = '%s operator[](int index)' % element_type
438 self._GenerateNativeBinding('numericIndexGetter', 2, dart_declaration,
439 'Callback', True)
440
441 def _EmitNativeIndexSetter(self, interface, element_type):
442 dart_declaration = 'void operator[]=(int index, %s value)' % element_type
443 self._GenerateNativeBinding('numericIndexSetter', 3, dart_declaration,
444 'Callback', True)
445
446 def AddOperation(self, info):
447 """
448 Arguments:
449 info: An OperationInfo object.
450 """
451
452 if 'Custom' in info.overloads[0].ext_attrs:
453 parameters = info.ParametersImplementationDeclaration()
454 dart_declaration = '%s %s(%s)' % (info.type_name, info.name, parameters)
455 argument_count = 1 + len(info.arg_infos)
456 self._GenerateNativeBinding(info.name, argument_count, dart_declaration,
457 'Callback', True)
458 return
459
460 body = self._members_emitter.Emit(
461 '\n'
462 ' $TYPE $NAME($PARAMETERS) {\n'
463 '$!BODY'
464 ' }\n',
465 TYPE=info.type_name,
466 NAME=info.name,
467 PARAMETERS=info.ParametersImplementationDeclaration())
468
469 # Process in order of ascending number of arguments to ensure missing
470 # optional arguments are processed early.
471 overloads = sorted(info.overloads,
472 key=lambda overload: len(overload.arguments))
473 self._native_version = 0
474 fallthrough = self.GenerateDispatch(body, info, ' ', 0, overloads)
475 if fallthrough:
476 body.Emit(' throw "Incorrect number or type of arguments";\n');
477
478 def GenerateSingleOperation(self, dispatch_emitter, info, indent, operation):
479 """Generates a call to a single operation.
480
481 Arguments:
482 dispatch_emitter: an dispatch_emitter for the body of a block of code.
483 info: the compound information about the operation and its overloads.
484 indent: an indentation string for generated code.
485 operation: the IDLOperation to call.
486 """
487
488 # FIXME: support ImplementedBy callbacks.
489 if 'ImplementedBy' in operation.ext_attrs:
490 return
491
492 for op in self._interface.operations:
493 if op.id != operation.id or len(op.arguments) <= len(operation.arguments):
494 continue
495 next_argument = op.arguments[len(operation.arguments)]
496 if next_argument.is_optional and 'Callback' in next_argument.ext_attrs:
497 # FIXME: '[Optional, Callback]' arguments could be non-optional in
498 # webcore. We need to fix overloads handling to generate native
499 # callbacks properly.
500 return
501
502 self._native_version += 1
503 native_name = info.name
504 if self._native_version > 1:
505 native_name = '%s_%s' % (native_name, self._native_version)
506 argument_list = ', '.join([info.arg_infos[i][0]
507 for (i, arg) in enumerate(operation.arguments)])
508
509 # Generate dispatcher.
510 if info.type_name != 'void':
511 dispatch_emitter.Emit('$(INDENT)return _$NATIVENAME($ARGS);\n',
512 INDENT=indent,
513 NATIVENAME=native_name,
514 ARGS=argument_list)
515 else:
516 dispatch_emitter.Emit('$(INDENT)_$NATIVENAME($ARGS);\n'
517 '$(INDENT)return;\n',
518 INDENT=indent,
519 NATIVENAME=native_name,
520 ARGS=argument_list)
521 # Generate binding.
522 dart_declaration = '%s _%s(%s)' % (info.type_name, native_name,
523 argument_list)
524 is_custom = 'Custom' in operation.ext_attrs
525 cpp_callback_name = self._GenerateNativeBinding(
526 native_name, 1 + len(operation.arguments), dart_declaration, 'Callback',
527 is_custom)
528 if is_custom:
529 return
530
531 # Generate callback.
532 webcore_function_name = operation.id
533 if 'ImplementedAs' in operation.ext_attrs:
534 webcore_function_name = operation.ext_attrs['ImplementedAs']
535
536 parameter_definitions_emitter = emitter.Emitter()
537 raises_dart_exceptions = len(operation.arguments) > 0 or operation.raises
538 arguments = []
539
540 # Process 'CallWith' argument.
541 if 'CallWith' in operation.ext_attrs:
542 call_with = operation.ext_attrs['CallWith']
543 if call_with == 'ScriptExecutionContext':
544 parameter_definitions_emitter.Emit(
545 ' ScriptExecutionContext* context = DartUtilities::scriptExec utionContext();\n'
546 ' if (!context)\n'
547 ' return;\n')
548 arguments.append('context')
549 elif call_with == 'ScriptArguments|CallStack':
550 raises_dart_exceptions = True
551 self._cpp_impl_includes['ScriptArguments'] = 1
552 self._cpp_impl_includes['ScriptCallStack'] = 1
553 self._cpp_impl_includes['V8Proxy'] = 1
554 self._cpp_impl_includes['v8'] = 1
555 parameter_definitions_emitter.Emit(
556 ' v8::HandleScope handleScope;\n'
557 ' v8::Context::Scope scope(V8Proxy::mainWorldContext(DartUtil ities::domWindowForCurrentIsolate()->frame()));\n'
558 ' Dart_Handle customArgument = Dart_GetNativeArgument(args, $ INDEX);\n'
559 ' RefPtr<ScriptArguments> scriptArguments(DartUtilities::crea teScriptArguments(customArgument, exception));\n'
560 ' if (!scriptArguments)\n'
561 ' goto fail;\n'
562 ' RefPtr<ScriptCallStack> scriptCallStack(DartUtilities::crea teScriptCallStack());\n'
563 ' if (!scriptCallStack->size())\n'
564 ' return;\n',
565 INDEX=len(operation.arguments))
566 arguments.extend(['scriptArguments', 'scriptCallStack'])
567
568 # Process Dart arguments.
569 for (i, argument) in enumerate(operation.arguments):
570 if i == len(operation.arguments) - 1 and self._interface.id == 'Console' a nd argument.id == 'arg':
571 # FIXME: we are skipping last argument here because it was added in
572 # supplemental dart.idl. Cleanup dart.idl and remove this check.
573 break
574 self._GenerateParameterAdapter(parameter_definitions_emitter, argument, i)
575 arguments.append(argument.id)
576
577 if operation.id in ['addEventListener', 'removeEventListener']:
578 # addEventListener's and removeEventListener's last argument is marked
579 # as optional in idl, but is not optional in webcore implementation.
580 if len(operation.arguments) == 2:
581 arguments.append('false')
582
583 if self._interface.id == 'CSSStyleDeclaration' and operation.id == 'setPrope rty':
584 # CSSStyleDeclaration.setProperty priority parameter is optional in Dart
585 # idl, but is not optional in webcore implementation.
586 if len(operation.arguments) == 2:
587 arguments.append('String()')
588
589 if 'NeedsUserGestureCheck' in operation.ext_attrs:
590 arguments.extend('DartUtilities::processingUserGesture')
591
592 parameter_definitions = parameter_definitions_emitter.Fragments()
593 self._GenerateNativeCallback(cpp_callback_name, operation,
594 parameter_definitions, webcore_function_name, arguments,
595 idl_return_type=operation.type,
596 raises_dart_exceptions=raises_dart_exceptions,
597 raises_dom_exceptions=operation.raises)
598
599 def _GenerateNativeCallback(self, callback_name, idl_node,
600 parameter_definitions, function_name, arguments, idl_return_type,
601 raises_dart_exceptions, raises_dom_exceptions):
602 receiver = self._interface_type_info.receiver()
603 if raises_dom_exceptions:
604 arguments.append('ec')
605 callback = '%s%s(%s)' % (receiver, function_name, ', '.join(arguments))
606
607 nested_templates = []
608 if idl_return_type and idl_return_type.id != 'void':
609 return_type_info = GetIDLTypeInfo(idl_return_type)
610 conversion_cast = return_type_info.conversion_cast('$BODY')
611 if isinstance(return_type_info, SVGTearOffIDLTypeInfo):
612 svg_primitive_types = ['SVGAngle', 'SVGLength', 'SVGMatrix',
613 'SVGNumber', 'SVGPoint', 'SVGRect', 'SVGTransform']
614 conversion_cast = '%s::create($BODY)'
615 if self._interface.id.startswith('SVGAnimated'):
616 conversion_cast = 'static_cast<%s*>($BODY)'
617 elif return_type_info.idl_type() == 'SVGStringList':
618 conversion_cast = '%s::create(receiver, $BODY)'
619 elif self._interface.id.endswith('List'):
620 conversion_cast = 'static_cast<%s*>($BODY.get())'
621 elif return_type_info.idl_type() in svg_primitive_types:
622 conversion_cast = '%s::create($BODY)'
623 else:
624 conversion_cast = 'static_cast<%s*>($BODY)'
625 conversion_cast = conversion_cast % return_type_info.native_type()
626 nested_templates.append(conversion_cast)
627
628 if return_type_info.conversion_include():
629 self._cpp_impl_includes[return_type_info.conversion_include()] = 1
630 if (return_type_info.idl_type() in ['DOMString', 'AtomicString'] and
631 'TreatReturnedNullStringAs' in idl_node.ext_attrs):
632 nested_templates.append('$BODY, ConvertDefaultToNull')
633 nested_templates.append(
634 ' Dart_Handle returnValue = toDartValue($BODY);\n'
635 ' if (returnValue)\n'
636 ' Dart_SetReturnValue(args, returnValue);\n')
637 else:
638 nested_templates.append(' $BODY;\n')
639
640 if raises_dom_exceptions:
641 nested_templates.append(
642 ' ExceptionCode ec = 0;\n'
643 '$BODY'
644 ' if (UNLIKELY(ec)) {\n'
645 ' exception = DartDOMWrapper::exceptionCodeToDartException( ec);\n'
646 ' goto fail;\n'
647 ' }\n')
648
649 nested_templates.append(
650 ' {\n'
651 ' $WEBCORE_CLASS_NAME* receiver = DartDOMWrapper::receiver< $WEBC ORE_CLASS_NAME >(args);\n'
652 '$PARAMETER_DEFINITIONS'
653 '\n'
654 '$BODY'
655 ' return;\n'
656 ' }\n')
657
658 if raises_dart_exceptions:
659 nested_templates.append(
660 ' Dart_Handle exception;\n'
661 '$BODY'
662 '\n'
663 'fail:\n'
664 ' Dart_ThrowException(exception);\n'
665 ' ASSERT_NOT_REACHED();\n')
666
667 nested_templates.append(
668 '\n'
669 'static void $CALLBACK_NAME(Dart_NativeArguments args)\n'
670 '{\n'
671 ' DartApiScope dartApiScope;\n'
672 '$BODY'
673 '}\n')
674
675 template_parameters = {
676 'CALLBACK_NAME': callback_name,
677 'WEBCORE_CLASS_NAME': self._interface_type_info.native_type(),
678 'PARAMETER_DEFINITIONS': parameter_definitions,
679 }
680 for template in nested_templates:
681 template_parameters['BODY'] = callback
682 callback_emitter = emitter.Emitter()
683 callback_emitter.Emit(template, **template_parameters)
684 callback = ''.join(callback_emitter.Fragments())
685
686 self._cpp_definitions_emitter.Emit(callback)
687
688 def _GenerateParameterAdapter(self, emitter, idl_argument, index):
689 type_info = GetIDLTypeInfo(idl_argument.type)
690 (adapter_type, include_name) = type_info.parameter_adapter_info()
691 if include_name:
692 self._cpp_impl_includes[include_name] = 1
693 emitter.Emit(
694 '\n'
695 ' const $ADAPTER_TYPE $NAME(Dart_GetNativeArgument(args, $INDEX)) ;\n'
696 ' if (!$NAME.conversionSuccessful()) {\n'
697 ' exception = $NAME.exception();\n'
698 ' goto fail;\n'
699 ' }\n',
700 ADAPTER_TYPE=adapter_type,
701 NAME=idl_argument.id,
702 INDEX=index + 1)
703
704 def _GenerateNativeBinding(self, idl_name, argument_count, dart_declaration,
705 native_suffix, is_custom):
706 native_binding = '%s_%s_%s' % (self._interface.id, idl_name, native_suffix)
707 self._members_emitter.Emit(
708 '\n'
709 ' $DART_DECLARATION native "$NATIVE_BINDING";\n',
710 DART_DECLARATION=dart_declaration, NATIVE_BINDING=native_binding)
711
712 cpp_callback_name = '%s%s' % (idl_name, native_suffix)
713 self._cpp_resolver_emitter.Emit(
714 ' if (argumentCount == $ARGC && name == "$NATIVE_BINDING")\n'
715 ' return Dart$(INTERFACE_NAME)Internal::$CPP_CALLBACK_NAME;\n',
716 ARGC=argument_count,
717 NATIVE_BINDING=native_binding,
718 INTERFACE_NAME=self._interface.id,
719 CPP_CALLBACK_NAME=cpp_callback_name)
720
721 if is_custom:
722 self._cpp_declarations_emitter.Emit(
723 '\n'
724 'void $CPP_CALLBACK_NAME(Dart_NativeArguments);\n',
725 CPP_CALLBACK_NAME=cpp_callback_name)
726
727 return cpp_callback_name
728
729 def _GenerateWebCoreReflectionAttributeName(self, attr):
730 namespace = 'HTMLNames'
731 svg_exceptions = ['class', 'id', 'onabort', 'onclick', 'onerror', 'onload',
732 'onmousedown', 'onmousemove', 'onmouseout', 'onmouseover',
733 'onmouseup', 'onresize', 'onscroll', 'onunload']
734 if self._interface.id.startswith('SVG') and not attr.id in svg_exceptions:
735 namespace = 'SVGNames'
736 self._cpp_impl_includes[namespace] = 1
737
738 attribute_name = attr.ext_attrs['Reflect'] or attr.id.lower()
739 return 'WebCore::%s::%sAttr' % (namespace, attribute_name)
740
OLDNEW
« no previous file with comments | « client/dom/scripts/generator.py ('k') | client/dom/scripts/systemwrapping.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698