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

Side by Side Diff: client/dom/scripts/systemnative.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/systeminterface.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 if IsPureInterface(interface_name):
38 return None
39
40 dart_impl_path = self._FilePathForDartImplementation(interface_name)
41 self._dom_impl_files.append(dart_impl_path)
42
43 cpp_header_path = self._FilePathForCppHeader(interface_name)
44 self._cpp_header_files.append(cpp_header_path)
45
46 cpp_impl_path = self._FilePathForCppImplementation(interface_name)
47 self._cpp_impl_files.append(cpp_impl_path)
48
49 return NativeImplementationGenerator(self, interface, super_interface_name,
50 self._emitters.FileEmitter(dart_impl_path),
51 self._emitters.FileEmitter(cpp_header_path),
52 self._emitters.FileEmitter(cpp_impl_path),
53 self._BaseDefines(interface),
54 self._templates)
55
56 def ProcessCallback(self, interface, info):
57 self._interface = interface
58
59 dart_interface_path = self._FilePathForDartInterface(self._interface.id)
60 self._dom_public_files.append(dart_interface_path)
61
62 cpp_impl_includes = set()
63 cpp_header_handlers_emitter = emitter.Emitter()
64 cpp_impl_handlers_emitter = emitter.Emitter()
65 class_name = 'Dart%s' % self._interface.id
66 for operation in interface.operations:
67 if operation.type.id == 'void':
68 return_type = 'void'
69 return_prefix = ''
70 else:
71 return_type = 'bool'
72 return_prefix = 'return '
73
74 parameters = []
75 arguments = []
76 for argument in operation.arguments:
77 argument_type_info = GetIDLTypeInfo(argument.type.id)
78 parameters.append('%s %s' % (argument_type_info.parameter_type(),
79 argument.id))
80 arguments.append(argument.id)
81 cpp_impl_includes |= set(argument_type_info.conversion_includes())
82
83 cpp_header_handlers_emitter.Emit(
84 '\n'
85 ' virtual $TYPE handleEvent($PARAMETERS);\n',
86 TYPE=return_type, PARAMETERS=', '.join(parameters))
87
88 cpp_impl_handlers_emitter.Emit(
89 '\n'
90 '$TYPE $CLASS_NAME::handleEvent($PARAMETERS)\n'
91 '{\n'
92 ' $(RETURN_PREFIX)m_callback.handleEvent($ARGUMENTS);\n'
93 '}\n',
94 TYPE=return_type,
95 CLASS_NAME=class_name,
96 PARAMETERS=', '.join(parameters),
97 RETURN_PREFIX=return_prefix,
98 ARGUMENTS=', '.join(arguments))
99
100 cpp_header_path = self._FilePathForCppHeader(self._interface.id)
101 cpp_header_emitter = self._emitters.FileEmitter(cpp_header_path)
102 cpp_header_emitter.Emit(
103 self._templates.Load('cpp_callback_header.template'),
104 INTERFACE=self._interface.id,
105 HANDLERS=cpp_header_handlers_emitter.Fragments())
106
107 cpp_impl_path = self._FilePathForCppImplementation(self._interface.id)
108 self._cpp_impl_files.append(cpp_impl_path)
109 cpp_impl_emitter = self._emitters.FileEmitter(cpp_impl_path)
110 cpp_impl_emitter.Emit(
111 self._templates.Load('cpp_callback_implementation.template'),
112 INCLUDES=_GenerateCPPIncludes(cpp_impl_includes),
113 INTERFACE=self._interface.id,
114 HANDLERS=cpp_impl_handlers_emitter.Fragments())
115
116 def GenerateLibraries(self, lib_dir):
117 auxiliary_dir = os.path.relpath(self._auxiliary_dir, self._output_dir)
118
119 # Generate dom_public.dart.
120 self._GenerateLibFile(
121 'dom_public.darttemplate',
122 os.path.join(self._output_dir, 'dom_public.dart'),
123 self._dom_public_files,
124 AUXILIARY_DIR=MassagePath(auxiliary_dir));
125
126 # Generate dom_impl.dart.
127 self._GenerateLibFile(
128 'dom_impl.darttemplate',
129 os.path.join(self._output_dir, 'dom_impl.dart'),
130 self._dom_impl_files,
131 AUXILIARY_DIR=MassagePath(auxiliary_dir));
132
133 # Generate DartDerivedSourcesXX.cpp.
134 partitions = 20 # FIXME: this should be configurable.
135 sources_count = len(self._cpp_impl_files)
136 for i in range(0, partitions):
137 derived_sources_path = os.path.join(self._output_dir,
138 'DartDerivedSources%02i.cpp' % (i + 1))
139
140 includes_emitter = emitter.Emitter()
141 for impl_file in self._cpp_impl_files[i::partitions]:
142 path = os.path.relpath(impl_file, os.path.dirname(derived_sources_path ))
143 includes_emitter.Emit('#include "$PATH"\n', PATH=path)
144
145 derived_sources_emitter = self._emitters.FileEmitter(derived_sources_path)
146 derived_sources_emitter.Emit(
147 self._templates.Load('cpp_derived_sources.template'),
148 INCLUDES=includes_emitter.Fragments())
149
150 # Generate DartResolver.cpp.
151 cpp_resolver_path = os.path.join(self._output_dir, 'DartResolver.cpp')
152
153 includes_emitter = emitter.Emitter()
154 resolver_body_emitter = emitter.Emitter()
155 for file in self._cpp_header_files:
156 path = os.path.relpath(file, os.path.dirname(cpp_resolver_path))
157 includes_emitter.Emit('#include "$PATH"\n', PATH=path)
158 resolver_body_emitter.Emit(
159 ' if (Dart_NativeFunction func = $CLASS_NAME::resolver(name, argu mentCount))\n'
160 ' return func;\n',
161 CLASS_NAME=os.path.splitext(os.path.basename(path))[0])
162
163 cpp_resolver_emitter = self._emitters.FileEmitter(cpp_resolver_path)
164 cpp_resolver_emitter.Emit(
165 self._templates.Load('cpp_resolver.template'),
166 INCLUDES=includes_emitter.Fragments(),
167 RESOLVER_BODY=resolver_body_emitter.Fragments())
168
169 def Finish(self):
170 pass
171
172 def _FilePathForDartInterface(self, interface_name):
173 return os.path.join(self._output_dir, 'src', 'interface',
174 '%s.dart' % interface_name)
175
176 def _FilePathForDartImplementation(self, interface_name):
177 return os.path.join(self._output_dir, 'dart',
178 '%sImplementation.dart' % interface_name)
179
180 def _FilePathForDartFactoryProvider(self, interface_name):
181 return os.path.join(self._output_dir, 'dart',
182 '_%sFactoryProvider.dart' % interface_name)
183
184 def _FilePathForDartFactoryProviderImplementation(self, interface_name):
185 return os.path.join(self._output_dir, 'dart',
186 '%sFactoryProviderImplementation.dart' % interface_name)
187
188 def _FilePathForCppHeader(self, interface_name):
189 return os.path.join(self._output_dir, 'cpp', 'Dart%s.h' % interface_name)
190
191 def _FilePathForCppImplementation(self, interface_name):
192 return os.path.join(self._output_dir, 'cpp', 'Dart%s.cpp' % interface_name)
193
194
195 class NativeImplementationGenerator(systemwrapping.WrappingInterfaceGenerator):
196 """Generates Dart implementation for one DOM IDL interface."""
197
198 def __init__(self, system, interface, super_interface,
199 dart_impl_emitter, cpp_header_emitter, cpp_impl_emitter,
200 base_members, templates):
201 """Generates Dart and C++ code for the given interface.
202
203 Args:
204 system: The NativeImplementationSystem.
205 interface: an IDLInterface instance. It is assumed that all types have
206 been converted to Dart types (e.g. int, String), unless they are in
207 the same package as the interface.
208 super_interface: A string or None, the name of the common interface that
209 this interface implements, if any.
210 dart_impl_emitter: an Emitter for the file containing the Dart
211 implementation class.
212 cpp_header_emitter: an Emitter for the file containing the C++ header.
213 cpp_impl_emitter: an Emitter for the file containing the C++
214 implementation.
215 base_members: a set of names of members defined in a base class. This is
216 used to avoid static member 'overriding' in the generated Dart code.
217 """
218 self._system = system
219 self._interface = interface
220 self._super_interface = super_interface
221 self._dart_impl_emitter = dart_impl_emitter
222 self._cpp_header_emitter = cpp_header_emitter
223 self._cpp_impl_emitter = cpp_impl_emitter
224 self._base_members = base_members
225 self._templates = templates
226 self._current_secondary_parent = None
227
228 def StartInterface(self):
229 self._class_name = self._ImplClassName(self._interface.id)
230 self._interface_type_info = GetIDLTypeInfo(self._interface.id)
231 self._members_emitter = emitter.Emitter()
232 self._cpp_declarations_emitter = emitter.Emitter()
233 self._cpp_impl_includes = set()
234 self._cpp_definitions_emitter = emitter.Emitter()
235 self._cpp_resolver_emitter = emitter.Emitter()
236
237 self._GenerateConstructors()
238
239 def _GenerateConstructors(self):
240 if not self._IsConstructable():
241 return
242
243 # TODO(antonm): currently we don't have information about number of argument s expected by
244 # the constructor, so name only dispatch.
245 self._cpp_resolver_emitter.Emit(
246 ' if (name == "$(INTERFACE_NAME)_constructor_Callback")\n'
247 ' return Dart$(INTERFACE_NAME)Internal::constructorCallback;\n',
248 INTERFACE_NAME=self._interface.id)
249
250
251 constructor_info = AnalyzeConstructor(self._interface)
252 if constructor_info:
253 self._EmitFactoryProvider(self._interface.id, constructor_info)
254
255 if constructor_info is None:
256 # We have a custom implementation for it.
257 self._cpp_declarations_emitter.Emit(
258 '\n'
259 'void constructorCallback(Dart_NativeArguments);\n')
260 return
261
262 raises_dom_exceptions = 'ConstructorRaisesException' in self._interface.ext_ attrs
263 raises_exceptions = raises_dom_exceptions or len(constructor_info.idl_args) > 0
264 arguments = []
265 parameter_definitions_emitter = emitter.Emitter()
266 create_function = 'create'
267 if 'NamedConstructor' in self._interface.ext_attrs:
268 raises_exceptions = True
269 parameter_definitions_emitter.Emit(
270 ' DOMWindow* domWindow = DartUtilities::domWindowForCurrentIs olate();\n'
271 ' if (!domWindow) {\n'
272 ' exception = Dart_NewString("Failed to fetch domWindow") ;\n'
273 ' goto fail;\n'
274 ' }\n'
275 ' Document* document = domWindow->document();\n')
276 self._cpp_impl_includes.add('"DOMWindow.h"')
277 arguments.append('document')
278 create_function = 'createForJSConstructor'
279 if 'CallWith' in self._interface.ext_attrs:
280 call_with = self._interface.ext_attrs['CallWith']
281 if call_with == 'ScriptExecutionContext':
282 raises_exceptions = True
283 parameter_definitions_emitter.Emit(
284 ' ScriptExecutionContext* context = DartUtilities::scriptExec utionContext();\n'
285 ' if (!context) {\n'
286 ' exception = Dart_NewString("Failed to create an object" );\n'
287 ' goto fail;\n'
288 ' }\n')
289 arguments.append('context')
290 else:
291 raise Exception('Unsupported CallWith=%s attribute' % call_with)
292
293 # Process constructor arguments.
294 for (i, arg) in enumerate(constructor_info.idl_args):
295 self._GenerateParameterAdapter(parameter_definitions_emitter, arg, i - 1)
296 arguments.append(arg.id)
297
298 function_expression = '%s::%s' % (self._interface_type_info.native_type(), c reate_function)
299 invocation = self._GenerateWebCoreInvocation(function_expression, arguments,
300 self._interface.id, self._interface.ext_attrs, raises_dom_exceptions)
301 self._GenerateNativeCallback(callback_name='constructorCallback',
302 parameter_definitions=parameter_definitions_emitter.Fragments(),
303 needs_receiver=False, invocation=invocation,
304 raises_exceptions=raises_exceptions)
305
306 def _ImplClassName(self, interface_name):
307 return interface_name + 'Implementation'
308
309 def _IsConstructable(self):
310 # FIXME: support ConstructorTemplate.
311 return set(['CustomConstructor', 'V8CustomConstructor', 'Constructor', 'Name dConstructor']) & set(self._interface.ext_attrs)
312
313 def _EmitFactoryProvider(self, interface_name, constructor_info):
314 factory_provider = '_' + interface_name + 'FactoryProvider'
315 implementation_class = interface_name + 'FactoryProviderImplementation'
316 implementation_function = 'create' + interface_name
317 native_implementation_function = '%s_constructor_Callback' % interface_name
318
319 # Emit private factory provider in public library.
320 template_file = 'factoryprovider_%s.darttemplate' % interface_name
321 template = self._system._templates.TryLoad(template_file)
322 if not template:
323 template = self._system._templates.Load('factoryprovider.darttemplate')
324
325 dart_impl_path = self._system._FilePathForDartFactoryProvider(
326 interface_name)
327 self._system._dom_public_files.append(dart_impl_path)
328
329 emitter = self._system._emitters.FileEmitter(dart_impl_path)
330 emitter.Emit(
331 template,
332 FACTORY_PROVIDER=factory_provider,
333 CONSTRUCTOR=interface_name,
334 PARAMETERS=constructor_info.ParametersImplementationDeclaration(),
335 IMPL_CLASS=implementation_class,
336 IMPL_FUNCTION=implementation_function,
337 ARGUMENTS=constructor_info.ParametersAsArgumentList())
338
339 # Emit public implementation in implementation libary.
340 dart_impl_path = self._system._FilePathForDartFactoryProviderImplementation(
341 interface_name)
342 self._system._dom_impl_files.append(dart_impl_path)
343 emitter = self._system._emitters.FileEmitter(dart_impl_path)
344 emitter.Emit(
345 'class $IMPL_CLASS {\n'
346 ' static $INTERFACE_NAME $IMPL_FUNCTION($PARAMETERS)\n'
347 ' native "$NATIVE_NAME";\n'
348 '}',
349 INTERFACE_NAME=interface_name,
350 PARAMETERS=constructor_info.ParametersImplementationDeclaration(),
351 IMPL_CLASS=implementation_class,
352 IMPL_FUNCTION=implementation_function,
353 NATIVE_NAME=native_implementation_function)
354
355 def FinishInterface(self):
356 base = self._BaseClassName(self._interface)
357 self._dart_impl_emitter.Emit(
358 self._templates.Load('dart_implementation.darttemplate'),
359 CLASS=self._class_name, BASE=base, INTERFACE=self._interface.id,
360 MEMBERS=self._members_emitter.Fragments())
361
362 self._GenerateCppHeader()
363
364 self._cpp_impl_emitter.Emit(
365 self._templates.Load('cpp_implementation.template'),
366 INTERFACE=self._interface.id,
367 INCLUDES=_GenerateCPPIncludes(self._cpp_impl_includes),
368 CALLBACKS=self._cpp_definitions_emitter.Fragments(),
369 RESOLVER=self._cpp_resolver_emitter.Fragments())
370
371 def _GenerateCppHeader(self):
372 webcore_includes = _GenerateCPPIncludes(self._interface_type_info.webcore_in cludes())
373
374 if ('CustomToJS' in self._interface.ext_attrs or
375 'CustomToJSObject' in self._interface.ext_attrs or
376 'PureInterface' in self._interface.ext_attrs or
377 'CPPPureInterface' in self._interface.ext_attrs or
378 self._interface_type_info.custom_to_dart()):
379 to_dart_value_template = (
380 'Dart_Handle toDartValue($(WEBCORE_CLASS_NAME)* value);\n')
381 else:
382 to_dart_value_template = (
383 'inline Dart_Handle toDartValue($(WEBCORE_CLASS_NAME)* value)\n'
384 '{\n'
385 ' return DartDOMWrapper::toDart<Dart$(INTERFACE)>(value);\n'
386 '}\n')
387 to_dart_value_emitter = emitter.Emitter()
388 to_dart_value_emitter.Emit(
389 to_dart_value_template,
390 INTERFACE=self._interface.id,
391 WEBCORE_CLASS_NAME=self._interface_type_info.native_type())
392
393 self._cpp_header_emitter.Emit(
394 self._templates.Load('cpp_header.template'),
395 INTERFACE=self._interface.id,
396 WEBCORE_INCLUDES=webcore_includes,
397 WEBCORE_CLASS_NAME=self._interface_type_info.native_type(),
398 TO_DART_VALUE=to_dart_value_emitter.Fragments(),
399 DECLARATIONS=self._cpp_declarations_emitter.Fragments())
400
401 def _GenerateCallWithHandling(self, node, parameter_definitions_emitter, argum ents):
402 if 'CallWith' not in node.ext_attrs:
403 return False
404
405 call_with = node.ext_attrs['CallWith']
406 if call_with == 'ScriptExecutionContext':
407 parameter_definitions_emitter.Emit(
408 '\n'
409 ' ScriptExecutionContext* context = DartUtilities::scriptExecut ionContext();\n'
410 ' if (!context)\n'
411 ' return;\n')
412 arguments.append('context')
413 return False
414
415 if call_with == 'ScriptArguments|CallStack':
416 self._cpp_impl_includes.add('"DOMWindow.h"')
417 self._cpp_impl_includes.add('"ScriptArguments.h"')
418 self._cpp_impl_includes.add('"ScriptCallStack.h"')
419 self._cpp_impl_includes.add('"V8Proxy.h"')
420 self._cpp_impl_includes.add('"v8.h"')
421 parameter_definitions_emitter.Emit(
422 '\n'
423 ' v8::HandleScope handleScope;\n'
424 ' v8::Context::Scope scope(V8Proxy::mainWorldContext(DartUtilit ies::domWindowForCurrentIsolate()->frame()));\n'
425 ' Dart_Handle customArgument = Dart_GetNativeArgument(args, $IN DEX);\n'
426 ' RefPtr<ScriptArguments> scriptArguments(DartUtilities::create ScriptArguments(customArgument, exception));\n'
427 ' if (!scriptArguments)\n'
428 ' goto fail;\n'
429 ' RefPtr<ScriptCallStack> scriptCallStack(DartUtilities::create ScriptCallStack());\n'
430 ' if (!scriptCallStack->size())\n'
431 ' return;\n',
432 INDEX=len(node.arguments))
433 arguments.extend(['scriptArguments', 'scriptCallStack'])
434 return True
435
436 return False
437
438 def AddAttribute(self, getter, setter):
439 # FIXME: Dartium does not support attribute event listeners. However, JS
440 # implementation falls back to them when addEventListener is not available.
441 # Make sure addEventListener is available in all EventTargets and remove
442 # this check.
443 if (getter or setter).type.id == 'EventListener':
444 return
445
446 if 'CheckSecurityForNode' in (getter or setter).ext_attrs:
447 # FIXME: exclude from interface as well.
448 return
449
450 # FIXME: these should go away.
451 classes_with_unsupported_custom_getters = [
452 'Clipboard', 'Console', 'Coordinates', 'DeviceMotionEvent',
453 'DeviceOrientationEvent', 'FileReader', 'JavaScriptCallFrame',
454 'HTMLInputElement', 'HTMLOptionsCollection', 'HTMLOutputElement',
455 'ScriptProfileNode', 'WebKitAnimation']
456 if (self._interface.id in classes_with_unsupported_custom_getters and
457 getter and set(['Custom', 'CustomGetter']) & set(getter.ext_attrs)):
458 return
459
460 if getter:
461 self._AddGetter(getter)
462 if setter:
463 self._AddSetter(setter)
464
465 def _AddGetter(self, attr):
466 type_info = GetIDLTypeInfo(attr.type.id)
467 dart_declaration = '%s get %s()' % (
468 type_info.dart_type(), DartDomNameOfAttribute(attr))
469 is_custom = 'Custom' in attr.ext_attrs or 'CustomGetter' in attr.ext_attrs
470 cpp_callback_name = self._GenerateNativeBinding(attr.id, 1,
471 dart_declaration, 'Getter', is_custom)
472 if is_custom:
473 return
474
475 arguments = []
476 parameter_definitions_emitter = emitter.Emitter()
477 raises_exceptions = self._GenerateCallWithHandling(attr, parameter_definitio ns_emitter, arguments)
478 raises_exceptions = raises_exceptions or attr.get_raises
479
480 if 'Reflect' in attr.ext_attrs:
481 webcore_function_name = GetIDLTypeInfo(attr.type.id).webcore_getter_name()
482 if 'URL' in attr.ext_attrs:
483 if 'NonEmpty' in attr.ext_attrs:
484 webcore_function_name = 'getNonEmptyURLAttribute'
485 else:
486 webcore_function_name = 'getURLAttribute'
487 arguments.append(self._GenerateWebCoreReflectionAttributeName(attr))
488 else:
489 if attr.id == 'operator':
490 webcore_function_name = '_operator'
491 elif attr.id == 'target' and attr.type.id == 'SVGAnimatedString':
492 webcore_function_name = 'svgTarget'
493 else:
494 webcore_function_name = re.sub(r'^(HTML|URL|JS|XML|XSLT|\w)',
495 lambda s: s.group(1).lower(),
496 attr.id)
497 webcore_function_name = re.sub(r'^(create|exclusive)',
498 lambda s: 'is' + s.group(1).capitalize(),
499 webcore_function_name)
500 if attr.type.id.startswith('SVGAnimated'):
501 webcore_function_name += 'Animated'
502
503 function_expression = self._GenerateWebCoreFunctionExpression(webcore_functi on_name, attr)
504 invocation = self._GenerateWebCoreInvocation(function_expression,
505 arguments, attr.type.id, attr.ext_attrs, attr.get_raises)
506 self._GenerateNativeCallback(cpp_callback_name, parameter_definitions_emitte r.Fragments(),
507 True, invocation, raises_exceptions=raises_exceptions)
508
509 def _AddSetter(self, attr):
510 type_info = GetIDLTypeInfo(attr.type.id)
511 dart_declaration = 'void set %s(%s)' % (
512 DartDomNameOfAttribute(attr), type_info.dart_type())
513 is_custom = set(['Custom', 'CustomSetter', 'V8CustomSetter']) & set(attr.ext _attrs)
514 cpp_callback_name = self._GenerateNativeBinding(attr.id, 2,
515 dart_declaration, 'Setter', is_custom)
516 if is_custom:
517 return
518
519 arguments = []
520 parameter_definitions_emitter = emitter.Emitter()
521 self._GenerateCallWithHandling(attr, parameter_definitions_emitter, argument s)
522
523 if 'Reflect' in attr.ext_attrs:
524 webcore_function_name = GetIDLTypeInfo(attr.type.id).webcore_setter_name()
525 arguments.append(self._GenerateWebCoreReflectionAttributeName(attr))
526 else:
527 webcore_function_name = re.sub(r'^(xml(?=[A-Z])|\w)',
528 lambda s: s.group(1).upper(),
529 attr.id)
530 webcore_function_name = 'set%s' % webcore_function_name
531 if attr.type.id.startswith('SVGAnimated'):
532 webcore_function_name += 'Animated'
533
534 arguments.append('value')
535
536 self._GenerateParameterAdapter(
537 parameter_definitions_emitter, attr, 0, adapter_name='value')
538 parameter_definitions = parameter_definitions_emitter.Fragments()
539
540 function_expression = self._GenerateWebCoreFunctionExpression(webcore_functi on_name, attr)
541 invocation = self._GenerateWebCoreInvocation(function_expression,
542 arguments, 'void', attr.ext_attrs, attr.set_raises)
543
544 self._GenerateNativeCallback(cpp_callback_name, parameter_definitions_emitte r.Fragments(),
545 True, invocation, raises_exceptions=True)
546
547 def _HasNativeIndexGetter(self, interface):
548 return ('CustomIndexedGetter' in interface.ext_attrs or
549 'NumericIndexedGetter' in interface.ext_attrs)
550
551 def _EmitNativeIndexGetter(self, interface, element_type):
552 dart_declaration = '%s operator[](int index)' % element_type
553 self._GenerateNativeBinding('numericIndexGetter', 2, dart_declaration,
554 'Callback', True)
555
556 def _EmitNativeIndexSetter(self, interface, element_type):
557 dart_declaration = 'void operator[]=(int index, %s value)' % element_type
558 self._GenerateNativeBinding('numericIndexSetter', 3, dart_declaration,
559 'Callback', True)
560
561 def AddOperation(self, info):
562 """
563 Arguments:
564 info: An OperationInfo object.
565 """
566
567 if 'CheckSecurityForNode' in info.overloads[0].ext_attrs:
568 # FIXME: exclude from interface as well.
569 return
570
571 if 'Custom' in info.overloads[0].ext_attrs:
572 parameters = info.ParametersImplementationDeclaration()
573 dart_declaration = '%s %s(%s)' % (info.type_name, info.name, parameters)
574 argument_count = 1 + len(info.arg_infos)
575 self._GenerateNativeBinding(info.name, argument_count, dart_declaration,
576 'Callback', True)
577 return
578
579 body = self._members_emitter.Emit(
580 '\n'
581 ' $TYPE $NAME($PARAMETERS) {\n'
582 '$!BODY'
583 ' }\n',
584 TYPE=info.type_name,
585 NAME=info.name,
586 PARAMETERS=info.ParametersImplementationDeclaration())
587
588 # Process in order of ascending number of arguments to ensure missing
589 # optional arguments are processed early.
590 overloads = sorted(info.overloads,
591 key=lambda overload: len(overload.arguments))
592 self._native_version = 0
593 fallthrough = self.GenerateDispatch(body, info, ' ', 0, overloads)
594 if fallthrough:
595 body.Emit(' throw "Incorrect number or type of arguments";\n');
596
597 def GenerateSingleOperation(self, dispatch_emitter, info, indent, operation):
598 """Generates a call to a single operation.
599
600 Arguments:
601 dispatch_emitter: an dispatch_emitter for the body of a block of code.
602 info: the compound information about the operation and its overloads.
603 indent: an indentation string for generated code.
604 operation: the IDLOperation to call.
605 """
606
607 self._native_version += 1
608 native_name = info.name
609 if self._native_version > 1:
610 native_name = '%s_%s' % (native_name, self._native_version)
611 argument_list = ', '.join([info.arg_infos[i][0]
612 for (i, arg) in enumerate(operation.arguments)])
613
614 # Generate dispatcher.
615 if info.type_name != 'void':
616 dispatch_emitter.Emit('$(INDENT)return _$NATIVENAME($ARGS);\n',
617 INDENT=indent,
618 NATIVENAME=native_name,
619 ARGS=argument_list)
620 else:
621 dispatch_emitter.Emit('$(INDENT)_$NATIVENAME($ARGS);\n'
622 '$(INDENT)return;\n',
623 INDENT=indent,
624 NATIVENAME=native_name,
625 ARGS=argument_list)
626 # Generate binding.
627 dart_declaration = '%s _%s(%s)' % (info.type_name, native_name,
628 argument_list)
629 is_custom = 'Custom' in operation.ext_attrs
630 cpp_callback_name = self._GenerateNativeBinding(
631 native_name, 1 + len(operation.arguments), dart_declaration, 'Callback',
632 is_custom)
633 if is_custom:
634 return
635
636 # Generate callback.
637 webcore_function_name = operation.ext_attrs.get('ImplementedAs', operation.i d)
638
639 parameter_definitions_emitter = emitter.Emitter()
640 arguments = []
641 raises_exceptions = self._GenerateCallWithHandling(
642 operation, parameter_definitions_emitter, arguments)
643 raises_exceptions = raises_exceptions or len(operation.arguments) > 0 or ope ration.raises
644
645 # Process Dart arguments.
646 for (i, argument) in enumerate(operation.arguments):
647 if (i == len(operation.arguments) - 1 and
648 self._interface.id == 'Console' and
649 argument.id == 'arg'):
650 # FIXME: we are skipping last argument here because it was added in
651 # supplemental dart.idl. Cleanup dart.idl and remove this check.
652 break
653 self._GenerateParameterAdapter(parameter_definitions_emitter, argument, i)
654 arguments.append(argument.id)
655
656 if operation.id in ['addEventListener', 'removeEventListener']:
657 # addEventListener's and removeEventListener's last argument is marked
658 # as optional in idl, but is not optional in webcore implementation.
659 if len(operation.arguments) == 2:
660 arguments.append('false')
661
662 if self._interface.id == 'CSSStyleDeclaration' and operation.id == 'setPrope rty':
663 # CSSStyleDeclaration.setProperty priority parameter is optional in Dart
664 # idl, but is not optional in webcore implementation.
665 if len(operation.arguments) == 2:
666 arguments.append('String()')
667
668 if 'NeedsUserGestureCheck' in operation.ext_attrs:
669 arguments.append('DartUtilities::processingUserGesture')
670
671 function_expression = self._GenerateWebCoreFunctionExpression(webcore_functi on_name, operation)
672 invocation = self._GenerateWebCoreInvocation(function_expression, arguments,
673 operation.type.id, operation.ext_attrs, operation.raises)
674 self._GenerateNativeCallback(cpp_callback_name,
675 parameter_definitions=parameter_definitions_emitter.Fragments(),
676 needs_receiver=True, invocation=invocation,
677 raises_exceptions=raises_exceptions)
678
679 def _GenerateNativeCallback(self, callback_name, parameter_definitions,
680 needs_receiver, invocation, raises_exceptions):
681
682 if needs_receiver:
683 parameter_definitions = emitter.Format(
684 ' $WEBCORE_CLASS_NAME* receiver = DartDOMWrapper::receiver< $WE BCORE_CLASS_NAME >(args);\n'
685 ' $PARAMETER_DEFINITIONS\n',
686 WEBCORE_CLASS_NAME=self._interface_type_info.native_type(),
687 PARAMETER_DEFINITIONS=parameter_definitions)
688
689 body = emitter.Format(
690 ' {\n'
691 '$PARAMETER_DEFINITIONS'
692 '$INVOCATION'
693 ' return;\n'
694 ' }\n',
695 PARAMETER_DEFINITIONS=parameter_definitions,
696 INVOCATION=invocation)
697
698 if raises_exceptions:
699 body = emitter.Format(
700 ' Dart_Handle exception;\n'
701 '$BODY'
702 '\n'
703 'fail:\n'
704 ' Dart_ThrowException(exception);\n'
705 ' ASSERT_NOT_REACHED();\n',
706 BODY=body)
707
708 self._cpp_definitions_emitter.Emit(
709 '\n'
710 'static void $CALLBACK_NAME(Dart_NativeArguments args)\n'
711 '{\n'
712 ' DartApiScope dartApiScope;\n'
713 '$BODY'
714 '}\n',
715 CALLBACK_NAME=callback_name,
716 BODY=body)
717
718 def _GenerateParameterAdapter(self, emitter, idl_node, index,
719 adapter_name=None):
720 """idl_node is IDLArgument or IDLAttribute."""
721 type_info = GetIDLTypeInfo(idl_node.type.id)
722 (adapter_type, include_name) = type_info.parameter_adapter_info()
723 if include_name:
724 self._cpp_impl_includes.add(include_name)
725 flags = ''
726 if (idl_node.ext_attrs.get('Optional') == 'DefaultIsNullString' or
727 'RequiredCppParameter' in idl_node.ext_attrs):
728 flags = ', DartUtilities::ConvertNullToDefaultValue'
729 emitter.Emit(
730 '\n'
731 ' const $ADAPTER_TYPE $NAME(Dart_GetNativeArgument(args, $INDEX)$ FLAGS);\n'
732 ' if (!$NAME.conversionSuccessful()) {\n'
733 ' exception = $NAME.exception();\n'
734 ' goto fail;\n'
735 ' }\n',
736 ADAPTER_TYPE=adapter_type,
737 NAME=adapter_name or idl_node.id,
738 INDEX=index + 1,
739 FLAGS=flags)
740
741 def _GenerateNativeBinding(self, idl_name, argument_count, dart_declaration,
742 native_suffix, is_custom):
743 native_binding = '%s_%s_%s' % (self._interface.id, idl_name, native_suffix)
744 self._members_emitter.Emit(
745 '\n'
746 ' $DART_DECLARATION native "$NATIVE_BINDING";\n',
747 DART_DECLARATION=dart_declaration, NATIVE_BINDING=native_binding)
748
749 cpp_callback_name = '%s%s' % (idl_name, native_suffix)
750 self._cpp_resolver_emitter.Emit(
751 ' if (argumentCount == $ARGC && name == "$NATIVE_BINDING")\n'
752 ' return Dart$(INTERFACE_NAME)Internal::$CPP_CALLBACK_NAME;\n',
753 ARGC=argument_count,
754 NATIVE_BINDING=native_binding,
755 INTERFACE_NAME=self._interface.id,
756 CPP_CALLBACK_NAME=cpp_callback_name)
757
758 if is_custom:
759 self._cpp_declarations_emitter.Emit(
760 '\n'
761 'void $CPP_CALLBACK_NAME(Dart_NativeArguments);\n',
762 CPP_CALLBACK_NAME=cpp_callback_name)
763
764 return cpp_callback_name
765
766 def _GenerateWebCoreReflectionAttributeName(self, attr):
767 namespace = 'HTMLNames'
768 svg_exceptions = ['class', 'id', 'onabort', 'onclick', 'onerror', 'onload',
769 'onmousedown', 'onmousemove', 'onmouseout', 'onmouseover',
770 'onmouseup', 'onresize', 'onscroll', 'onunload']
771 if self._interface.id.startswith('SVG') and not attr.id in svg_exceptions:
772 namespace = 'SVGNames'
773 self._cpp_impl_includes.add('"%s.h"' % namespace)
774
775 attribute_name = attr.ext_attrs['Reflect'] or attr.id.lower()
776 return 'WebCore::%s::%sAttr' % (namespace, attribute_name)
777
778 def _GenerateWebCoreFunctionExpression(self, function_name, idl_node):
779 if 'ImplementedBy' in idl_node.ext_attrs:
780 return '%s::%s' % (idl_node.ext_attrs['ImplementedBy'], function_name)
781 return '%s%s' % (self._interface_type_info.receiver(), function_name)
782
783 def _GenerateWebCoreInvocation(self, function_expression, arguments,
784 idl_return_type, attributes, raises_dom_exceptions):
785 invocation_template = ' $FUNCTION_CALL;\n'
786 if idl_return_type != 'void':
787 return_type_info = GetIDLTypeInfo(idl_return_type)
788 self._cpp_impl_includes |= set(return_type_info.conversion_includes())
789
790 # Generate C++ cast based on idl return type.
791 conversion_cast = return_type_info.conversion_cast('$FUNCTION_CALL')
792 if isinstance(return_type_info, SVGTearOffIDLTypeInfo):
793 svg_primitive_types = ['SVGAngle', 'SVGLength', 'SVGMatrix',
794 'SVGNumber', 'SVGPoint', 'SVGRect', 'SVGTransform']
795 conversion_cast = '%s::create($FUNCTION_CALL)'
796 if self._interface.id.startswith('SVGAnimated'):
797 conversion_cast = 'static_cast<%s*>($FUNCTION_CALL)'
798 elif return_type_info.idl_type() == 'SVGStringList':
799 conversion_cast = '%s::create(receiver, $FUNCTION_CALL)'
800 elif self._interface.id.endswith('List'):
801 conversion_cast = 'static_cast<%s*>($FUNCTION_CALL.get())'
802 elif return_type_info.idl_type() in svg_primitive_types:
803 conversion_cast = '%s::create($FUNCTION_CALL)'
804 else:
805 conversion_cast = 'static_cast<%s*>($FUNCTION_CALL)'
806 conversion_cast = conversion_cast % return_type_info.native_type()
807
808 # Generate to Dart conversion of C++ value.
809 conversion_arguments = [conversion_cast]
810 if (return_type_info.idl_type() in ['DOMString', 'AtomicString'] and
811 'TreatReturnedNullStringAs' in attributes):
812 conversion_arguments.append('ConvertDefaultToNull')
813
814 invocation_template = emitter.Format(
815 ' Dart_Handle returnValue = toDartValue($ARGUMENTS);\n'
816 ' if (returnValue)\n'
817 ' Dart_SetReturnValue(args, returnValue);\n',
818 ARGUMENTS=', '.join(conversion_arguments))
819
820 if raises_dom_exceptions:
821 # Add 'ec' argument to WebCore invocation and convert DOM exception to Dar t exception.
822 arguments.append('ec')
823 invocation_template = emitter.Format(
824 ' ExceptionCode ec = 0;\n'
825 '$INVOCATION'
826 ' if (UNLIKELY(ec)) {\n'
827 ' exception = DartDOMWrapper::exceptionCodeToDartException( ec);\n'
828 ' goto fail;\n'
829 ' }\n',
830 INVOCATION=invocation_template)
831
832 if 'ImplementedBy' in attributes:
833 arguments.insert(0, 'receiver')
834 self._cpp_impl_includes.add('"%s.h"' % attributes['ImplementedBy'])
835
836 return emitter.Format(invocation_template,
837 FUNCTION_CALL='%s(%s)' % (function_expression, ', '.join(arguments)))
838
839 def _GenerateCPPIncludes(includes):
840 return ''.join(['#include %s\n' % include for include in includes])
OLDNEW
« no previous file with comments | « client/dom/scripts/systeminterface.py ('k') | client/dom/scripts/systemwrapping.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698