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

Side by Side Diff: Source/WebCore/bindings/dart/gyp/scripts/CodeGeneratorDart.pm

Issue 9350041: Switch to dartgenerator.py for C++ callbacks generation. (Closed) Base URL: svn://svn.chromium.org/multivm/trunk/webkit
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
OLDNEW
(Empty)
1 # Copyright (C) 2005, 2006 Nikolas Zimmermann <zimmermann@kde.org>
2 # Copyright (C) 2006 Anders Carlsson <andersca@mac.com>
3 # Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
4 # Copyright (C) 2006 Alexey Proskuryakov <ap@webkit.org>
5 # Copyright (C) 2006 Apple Computer, Inc.
6 # Copyright (C) 2007, 2008, 2009 Google Inc.
7 # Copyright (C) 2009 Cameron McCormack <cam@mcc.id.au>
8 # Copyright (C) Research In Motion Limited 2010. All rights reserved.
9 # Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
10 #
11 # This library is free software; you can redistribute it and/or
12 # modify it under the terms of the GNU Library General Public
13 # License as published by the Free Software Foundation; either
14 # version 2 of the License, or (at your option) any later version.
15 #
16 # This library is distributed in the hope that it will be useful,
17 # but WITHOUT ANY WARRANTY; without even the implied warranty of
18 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 # Library General Public License for more details.
20 #
21 # You should have received a copy of the GNU Library General Public License
22 # along with this library; see the file COPYING.LIB. If not, write to
23 # the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
24 # Boston, MA 02111-1307, USA.
25 #
26
27 package CodeGeneratorDart;
28
29 use Class::Struct;
30
31 my $outputDir = "";
32 my $outputHeadersDir = "";
33
34 my @headerContent = ();
35 my %headerIncludes = ();
36
37 my @allParents = ();
38
39 my @customCallbackDeclarations = ();
40 my @implContentHeader = ();
41 my @implFixedHeader = ();
42 my @implContent = ();
43 my %implIncludes = ();
44 my @dartNatives = ();
45
46 my @dartInterfaceContent = ();
47 my @dartImplContent = ();
48
49 # Default .h template
50 my $headerTemplate = << "EOF";
51 /*
52 This file is part of the WebKit open source project.
53 This file has been generated by generate-bindings.pl. DO NOT MODIFY!
54
55 This library is free software; you can redistribute it and/or
56 modify it under the terms of the GNU Library General Public
57 License as published by the Free Software Foundation; either
58 version 2 of the License, or (at your option) any later version.
59
60 This library is distributed in the hope that it will be useful,
61 but WITHOUT ANY WARRANTY; without even the implied warranty of
62 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
63 Library General Public License for more details.
64
65 You should have received a copy of the GNU Library General Public License
66 along with this library; see the file COPYING.LIB. If not, write to
67 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
68 Boston, MA 02111-1307, USA.
69 */
70 EOF
71
72 struct(NativeBindingDescriptor => {
73 cppCallbackName => '$',
74 nativeId => '$',
75 argumentCount => '$',
76 });
77
78 struct(IDLTypeInfoStruct => {
79 additionalInterfaces => '@',
80 superClass => '$',
81 auxilaryMethods => '@',
82 isTypedArray => '$',
83 });
84
85 # Default constructor
86 sub new
87 {
88 my $object = shift;
89
90 $codeGenerator = shift;
91 $outputDir = shift;
92 $outputHeadersDir = shift;
93
94 my $reference = { };
95 bless($reference, $object);
96 return $reference;
97 }
98
99 sub GenerateModule
100 {
101 my ($object, $dataNode) = @_;
102 }
103
104 my %overrideConstructorParameters = (
105 "Float32Array" => 3,
106 "Float64Array" => 3,
107 "Int8Array" => 3,
108 "Int16Array" => 3,
109 "Int32Array" => 3,
110 "Uint8Array" => 3,
111 "Uint16Array" => 3,
112 "Uint32Array" => 3,
113 );
114
115 sub ConstructorParameterCount
116 {
117 my ($dataNode) = @_;
118 return $overrideConstructorParameters{$dataNode->name} if (exists $overrideC onstructorParameters{$dataNode->name});
119 return $dataNode->extendedAttributes->{ConstructorParameters} if (exists $da taNode->extendedAttributes->{ConstructorParameters});
120 return 0;
121 }
122
123 sub GenerateInterface
124 {
125 my ($object, $dataNode, $defines) = @_;
126
127 # Add parent classes (for multiple-inheritance) fields as needed.
128 @allParents = ();
129 $codeGenerator->AddMethodsConstantsAndAttributesFromParentClasses($dataNode, \@allParents, 0);
130 # Prepare internal structures.
131 $codeGenerator->LinkOverloadedFunctions($dataNode);
132
133 # Start actual generation
134 if ($dataNode->extendedAttributes->{Callback}) {
135 $object->GenerateCallbackDartInterface($dataNode);
136 $object->GenerateCallbackHeader($dataNode);
137 $object->GenerateCallbackImplementation($dataNode);
138 } else {
139 $object->GenerateSource($dataNode);
140 $object->GenerateHeader($dataNode);
141 }
142
143 my $name = $dataNode->name;
144
145 # Open files for writing
146 my $headerFileName = "$outputHeadersDir/Dart${name}.h";
147 my $implFileName = "$outputDir/Dart${name}.cpp";
148
149 open($IMPL, ">$implFileName") || die "Couldn't open file $implFileName";
150 open($HEADER, ">$headerFileName") || die "Couldn't open file $headerFileName ";
151
152 $object->WriteData($dataNode);
153 }
154
155 # If the node has a [Conditional=XXX] attribute, returns an "ENABLE(XXX)" string for use in an #if.
156 # FIXME: common with CodeGeneratorV8
157 sub GenerateConditionalStringForAttributes
158 {
159 my ($attributes,) = @_;
160
161 my $conditional = $attributes->{Conditional};
162 if ($conditional) {
163 if ($conditional =~ /&/) {
164 return "ENABLE(" . join(") && ENABLE(", split(/&/, $conditional)) . ")";
165 } elsif ($conditional =~ /\|/) {
166 return "ENABLE(" . join(") || ENABLE(", split(/\|/, $conditional)) . ")";
167 } else {
168 return "ENABLE(" . $conditional . ")";
169 }
170 } else {
171 return "";
172 }
173 }
174
175 sub GenerateConditionalString
176 {
177 my ($node,) = @_;
178 return GenerateConditionalStringForAttributes($node->extendedAttributes);
179 }
180
181 sub GenerateCustomCallbackDeclaration
182 {
183 my ($callbackName) = @_;
184 return "void $callbackName(Dart_NativeArguments);";
185 }
186
187 sub ClassName
188 {
189 my ($interfaceName,) = @_;
190 return "Dart$interfaceName";
191 }
192
193 sub HasOverloads
194 {
195 my ($function,) = @_;
196 return 1 if @{$function->{overloads}} > 1;
197 }
198
199 sub MaxOverloadParameterCount
200 {
201 my ($function,) = @_;
202
203 my $maxParameterCount = 0;
204 foreach my $overload (@{$function->{overloads}}) {
205 my $parameterCount = @{$overload->parameters};
206 $maxParameterCount = $maxParameterCount > $parameterCount ? $maxParamete rCount : $parameterCount;
207 }
208 return $maxParameterCount;
209 }
210
211 sub HasOptionalParameters
212 {
213 my ($function) = @_;
214
215 foreach my $parameter (@{$function->parameters}) {
216 return 1 if IsParameterOptionalInWebKit($parameter);
217 }
218 }
219
220 sub CanBeConstructed
221 {
222 my ($dataNode) = @_;
223
224 return $dataNode->extendedAttributes->{CanBeConstructed} ||
225 $dataNode->extendedAttributes->{Constructor} ||
226 HasCustomConstructor($dataNode);
227 }
228
229 sub HasCustomConstructor
230 {
231 my ($dataNode) = @_;
232
233 return ($dataNode->extendedAttributes->{CustomConstructor} ||
234 $dataNode->extendedAttributes->{V8CustomConstructor} ||
235 ($dataNode->name eq "WebKitCSSMatrix") ||
236 ($dataNode->name eq "FileReader")) &&
237 not ($dataNode->name =~ "Event") &&
238 not ($dataNode->name eq "MessageChannel");
239 }
240
241 sub IsParameterOptionalInWebKit
242 {
243 my ($parameter) = @_;
244
245 # Optional callbacks are not optional parameters in native implementations, they always have a default value (0).
246 my $optional = $parameter->extendedAttributes->{Optional};
247 return $optional && $optional ne "CallWithDefaultValue" && !$parameter->exte ndedAttributes->{Callback};
248 }
249
250 my %renames = (
251 "IDBCursor" => {
252 "continue" => "continueFunction",
253 },
254 "IDBIndex" => {
255 "get" => "getObject",
256 },
257 "IDBObjectStore" => {
258 "get" => "getObject",
259 },
260 "Int8Array" => {
261 "set" => "setElements",
262 },
263 "Int16Array" => {
264 "set" => "setElements",
265 },
266 "Int32Array" => {
267 "set" => "setElements",
268 },
269 "Uint8Array" => {
270 "set" => "setElements",
271 },
272 "Uint16Array" => {
273 "set" => "setElements",
274 },
275 "Uint32Array" => {
276 "set" => "setElements",
277 },
278 "Float32Array" => {
279 "set" => "setElements",
280 },
281 "Float64Array" => {
282 "set" => "setElements",
283 },
284 "SVGFEMorphologyElement" => {
285 "operator" => "operatorValue",
286 },
287 "SVGFECompositeElement" => {
288 "operator" => "operatorValue",
289 },
290 "Console" => {
291 "assert" => "assert_",
292 },
293 );
294
295 sub DartName
296 {
297 my ($interfaceName, $memberName) = @_;
298 return $memberName unless $renames{$interfaceName};
299 my $class = $renames{$interfaceName};
300 return $memberName unless $class->{$memberName};
301 return $class->{$memberName};
302 }
303
304 # FIXME: eventually those should go away.
305 my %classesWithUnsupportedCustomGetters = (
306 "Clipboard" => 1,
307 "Console" => 1,
308 "Coordinates" => 1,
309 "DeviceMotionEvent" => 1,
310 "DeviceOrientationEvent" => 1,
311 "FileReader" => 1,
312 "JavaScriptCallFrame" => 1,
313 "HTMLInputElement" => 1,
314 "HTMLOptionsCollection" => 1,
315 "HTMLOutputElement" => 1,
316 "ScriptProfileNode" => 1,
317 "WebKitAnimation" => 1,
318 );
319
320 sub IgnoredAttribute
321 {
322 my ($interfaceName, $attribute) = @_;
323
324 # FIXME: reconsider if need to be supported in Dart bindings at all.
325 return 1 if $attribute->signature->type =~ /Constructor$/;
326
327 # Attribute event listeners are not supported in Dart.
328 return 1 if $attribute->signature->type eq "EventListener";
329
330 # FIXME: support float[].
331 return 1 if $attribute->signature->type eq "float[]";
332
333 # The only usage is HTMLIFrameElement.contentDocument.
334 return 1 if $attribute->signature->extendedAttributes->{CheckFrameSecurity};
335
336 return 1 if HasCustomGetter($attribute) && exists $classesWithUnsupportedCus tomGetters{$interfaceName};
337
338 return 0;
339 }
340
341
342 sub HasSetter
343 {
344 my ($attribute,) = @_;
345
346 return 0 if $attribute->type =~ /^readonly/;
347 # FIXME: Replaceable apparently means that the value can be overwritten by J S and
348 # hence there is no correspondence to this in Dart.
349 return 0 if $attribute->signature->extendedAttributes->{"Replaceable"};
350 return 1;
351 }
352
353
354 sub IgnoredCallback
355 {
356 my ($interfaceName, $function) = @_;
357
358 # FIXME: WebGLContextEvent.initEvent overloads initEvent in base interface E vent and adds
359 # another argument.
360 # In the current architecture it's difficult to solve as IDL files are proce ssed one by one.
361 # As this is the only case, I'd suggest to put Custom attribute on WebGLCont extEvent.initEvent.
362 return 1 if $interfaceName eq "WebGLContextEvent" && $function->signature->n ame eq "initEvent";
363
364 # FIXME: implement callbacks with ScriptState.
365 my $callWith = $function->signature->extendedAttributes->{CallWith};
366 return 1 if $callWith and $callWith eq "ScriptState";
367
368 return 0;
369 }
370
371 # FIXME: Consider adding this to IDL as an attribute.
372 my %idlTypeToW3C = (
373 "DOMWindow" => "Window",
374 "DOMCoreException" => "DOMException"
375 );
376
377 sub HasW3CName
378 {
379 my ($idlType,) = @_;
380 return 1 if exists $idlTypeToW3C{$idlType};
381 return 0;
382 }
383
384 sub IDLTypeToW3C
385 {
386 my ($idlType,) = @_;
387 return $idlTypeToW3C{$idlType} if exists $idlTypeToW3C{$idlType};
388 return $idlType;
389 }
390
391 my %idlTypeToDart = (
392 "any" => "Object",
393 "any[]" => "List",
394 "boolean" => "bool",
395 "custom" => "Object",
396 "object" => "Object",
397 "Array" => "List",
398 "DOMObject" => "Object",
399 "DOMString" => "String",
400 "DOMString[]" => "DOMStringList",
401 "DOMTimeStamp" => "int",
402 "ObjectArray" => "List",
403 "SerializedScriptValue" => "Object",
404 "Date" => "Date",
405 "float" => "num",
406 "short" => "int",
407 "long" => "int",
408 "long long" => "int",
409 "unsigned int" => "int",
410 "unsigned short" => "int",
411 "unsigned long" => "int",
412 "unsigned long long" => "int",
413 "string" => "String",
414 "WebKitFlags" => "num",
415 );
416
417 my %primitiveDartTypes = (
418 "int" => 1,
419 "String" => 1,
420 "Object" => 1,
421 "Date" => 1,
422 "SerializedScriptValue" => 1,
423 );
424
425 sub IDLTypeToDart
426 {
427 my ($idlType,) = @_;
428 return $idlTypeToDart{$idlType} if exists $idlTypeToDart{$idlType};
429 return $idlType;
430 }
431
432 # FIXME: pretty much %non_wrapper_types in CodeGeneratorV8.
433 my %nonWrapperTypes = (
434 "CompareHow" => 1,
435 "EventListener" => 1,
436 "EventTarget" => 1,
437 "MediaQueryListListener" => 1,
438 "OptionsObject" => 1,
439 "VoidCallback" => 1,
440 "WebKitFlags" => 1,
441 );
442
443 sub DartInterfaceName
444 {
445 my ($interfaceName,) = @_;
446 return "DOMException" if $interfaceName eq "DOMCoreException";
447 return $interfaceName;
448 }
449
450 sub IsIDLTypeWithDartBindings
451 {
452 my ($idlType,) = @_;
453
454 return 0 if exists $idlTypeToDart{$idlType};
455 return 0 if exists $primitiveDartTypes{$idlType};
456 return 0 if !IsRefPtrType(IDLTypeToDart($idlType));
457 return 0 if exists $nonWrapperTypes{$idlType};
458
459 return 1;
460 }
461
462 sub ParameterAdapterType
463 {
464 my ($idlType,) = @_;
465
466 my $webkitParameterType = IDLTypeToWebkit($idlType);
467
468 my $suffix = "";
469 if (IsIDLTypeWithDartBindings($idlType)) {
470 my $bindingsClass = ClassName($idlType);
471 $implIncludes{"$bindingsClass.h"} = 1;
472 $suffix = ", $bindingsClass";
473 }
474
475 return "ParameterAdapter< $webkitParameterType$suffix >";
476 }
477
478 # FIXME: common with CodeGeneratorV8
479 sub GetNativeTypeForConversions
480 {
481 my ($type,) = @_;
482 $type = $codeGenerator->GetSVGTypeNeedingTearOff($type) if $codeGenerator->I sSVGTypeNeedingTearOff($type);
483 return $type;
484 }
485
486
487 sub AddHeaderForIDLType
488 {
489 my ($idlType, $includes) = @_;
490
491 $idlType =~ s/Abs|Rel// if $idlType =~ /SVGPathSeg/;
492
493 return if $codeGenerator->IsPrimitiveType($idlType);
494
495 return if exists $primitiveDartTypes{IDLTypeToDart($idlType)};
496
497 return if $codeGenerator->AvoidInclusionOfType($idlType);
498
499 return if $idlType eq "CompareHow";
500
501 $includes->{"$idlType.h"} = 1;
502 $includes->{"SVGPropertyTearOff.h"} = 1 if $codeGenerator->IsSVGTypeNeedingT earOff($idlType);
503 }
504
505 # FIXME: common with CodeGeneratorV8
506 sub AddHeaderClassIncludes
507 {
508 my ($idlType,) = @_;
509
510 AddHeaderForIDLType($idlType, \%headerIncludes);
511
512 $headerIncludes{"DartDOMWrapper.h"} = 1;
513 }
514
515 sub GenerateIncludes
516 {
517 return map { "#include " . (/wtf|dart_api\.h/ ? "<$_>" : "\"$_\"") . "\n"; } sort(@_);
518 }
519
520 my %withCustomConverters = (
521 "DOMWindow" => 1,
522 "Element" => 1,
523 "HTMLElement" => 1,
524 "SVGElement" => 1,
525 );
526
527 sub RequiresCustomToDartConverter
528 {
529 my ($dataNode,) = @_;
530
531 return 1 if $dataNode->extendedAttributes->{CustomToJS};
532 return 1 if $dataNode->extendedAttributes->{PureInterface};
533 return exists $withCustomConverters{$dataNode->name};
534 }
535
536 sub GenerateHeader
537 {
538 my ($object, $dataNode) = @_;
539
540 my $interfaceName = $dataNode->name;
541 my $className = ClassName($interfaceName);
542 my $webkitClassName = GetNativeTypeForConversions($interfaceName);
543
544 my $conditionalString = GenerateConditionalString($dataNode);
545
546 my $toDartValue = "";
547 if (!RequiresCustomToDartConverter($dataNode)) {
548 $toDartValue = <<END;
549 inline Dart_Handle toDartValue($webkitClassName* value)
550 {
551 return DartDOMWrapper::toDart<$className>(value);
552 }
553 END
554 } else {
555 $toDartValue = <<END;
556 Dart_Handle toDartValue($webkitClassName*);
557 END
558 }
559
560 $toDartValue .= <<END;
561 inline Dart_Handle toDartValue(PassRefPtr< $webkitClassName > value)
562 {
563 return toDartValue(value.get());
564 }
565 END
566
567 my $customCallbackDeclarations = join("\n\n", @customCallbackDeclarations);
568
569 push(@headerContent, $headerTemplate);
570
571 push(@headerContent, "\n#if ${conditionalString}\n") if $conditionalString;
572 push(@headerContent, <<END);
573
574 #ifndef ${className}_h
575 #define ${className}_h
576
577 END
578
579 AddHeaderClassIncludes($interfaceName);
580
581 $headerIncludes{"dart_api.h"} = 1;
582 push(@headerContent, GenerateIncludes(keys(%headerIncludes)));
583
584 push(@headerContent, <<END);
585
586 namespace WebCore {
587
588 struct $className {
589 static const char* const dartImplementationClassName;
590 typedef $webkitClassName NativeType;
591
592 static PassRefPtr<NativeType> toNative(Dart_Handle handle, Dart_Handle& exce ption)
593 {
594 return DartDOMWrapper::unwrapDartWrapper<$className>(handle, exception);
595 }
596
597 static bool instanceOf(Dart_Handle handle)
598 {
599 return DartDOMWrapper::instanceOf(dartImplementationClassName, handle);
600 }
601
602 static Dart_NativeFunction resolver(Dart_Handle name, int argumentCount);
603 };
604
605 $toDartValue
606 namespace Dart${interfaceName}Internal {
607
608 $customCallbackDeclarations
609
610 }
611
612 }
613
614 #endif // ${className}_h
615 END
616
617 push(@headerContent, "\n#endif // ${conditionalString}\n") if $conditionalSt ring;
618 }
619
620 sub HasCustomGetter
621 {
622 my ($attribute,) = @_;
623 my $extendedAttributes = $attribute->signature->extendedAttributes;
624 return $extendedAttributes->{"CustomGetter"} || $extendedAttributes->{"Custo m"};
625 }
626
627 sub HasCustomSetter
628 {
629 my ($attribute,) = @_;
630 my $extendedAttributes = $attribute->signature->extendedAttributes;
631 return $extendedAttributes->{"CustomSetter"} || $extendedAttributes->{"Custo m"} || $extendedAttributes->{"V8CustomSetter"};
632 }
633
634 sub WithTearOffNotList
635 {
636 my ($interfaceName) = @_;
637
638 return ($codeGenerator->IsSVGTypeNeedingTearOff($interfaceName) and (not ($i nterfaceName =~ /List$/)));
639 }
640
641 sub PrepareInvocation
642 {
643 my ($receiver, $interfaceName, $invocationPrefix, $invocationParameters) = @ _;
644
645 my $invocationPostfix;
646 $receiver .= "->";
647 if ($interfaceName eq "SVGNumber") {
648 $receiver .= "propertyReference()";
649 if ($invocationPrefix =~ /^setValue/) {
650 $invocationPrefix = " = ";
651 } else {
652 $invocationPrefix = "";
653 }
654 $invocationPostfix = "";
655 } else {
656 $receiver .= "propertyReference()." if WithTearOffNotList($interfaceName );
657 $invocationPostfix = ")";
658 }
659 return "$receiver$invocationPrefix$invocationParameters$invocationPostfix";
660 }
661
662 my %svgPrimitiveTypes = (
663 "SVGAngle" => 1,
664 "SVGLength" => 1,
665 "SVGMatrix" => 1,
666 "SVGNumber" => 1,
667 "SVGPoint" => 1,
668 "SVGRect" => 1,
669 "SVGTransform" => 1);
670
671 sub ProcessInvocationResult
672 {
673 my ($invocation, $interfaceName, $returnType) = @_;
674 my $svgNativeReturnType = $codeGenerator->GetSVGTypeNeedingTearOff($returnTy pe);
675
676 return $invocation if (not $svgNativeReturnType);
677
678 return "static_cast<${svgNativeReturnType}*>(${invocation})" if ($interfaceN ame =~ /^SVGAnimated/);
679
680 return "${svgNativeReturnType}::create(receiver, ${invocation})" if ($return Type eq "SVGStringList");
681
682 return "static_cast<${svgNativeReturnType}*>(${invocation}.get())" if ($inte rfaceName =~ /List$/);
683
684 if (exists $svgPrimitiveTypes{$returnType}) {
685 return "${svgNativeReturnType}::create(${invocation})";
686 } else {
687 return "static_cast<${svgNativeReturnType}*>(${invocation})";
688 }
689 }
690
691 sub GenerateGenericBindingsFunction
692 {
693 my ($name, $interfaceName, $functionName, $constantParameters, $parameters, $returnType, $raisesExceptions, $attributes, $isSetter) = @_;
694
695 my $webkitClassName = GetNativeTypeForConversions($interfaceName);
696 my $invocationPrefix = "$functionName(";
697
698 my $exceptionManagementPrologue = "";
699 my $exceptionManagementEpilogue = "";
700 if (@{$parameters} || $raisesExceptions || $attributes->{CustomArgumentHandl ing}) {
701 $exceptionManagementPrologue = <<END;
702 Dart_Handle exception;
703 END
704 $exceptionManagementEpilogue = <<END;
705
706 fail:
707 Dart_ThrowException(exception);
708 ASSERT_NOT_REACHED();
709 END
710 }
711
712 my @defineInvocationParameters = ();
713 my @invocationParameters = @{$constantParameters};
714
715 my $callWith = $attributes->{CallWith};
716 if ($callWith) {
717 # Generate code for "CallWith" parameter.
718 if ($callWith eq "ScriptExecutionContext") {
719 push(@defineInvocationParameters, <<END);
720 ScriptExecutionContext* context = DartUtilities::scriptExecutionContext( );
721 if (!context)
722 return;
723 END
724 push(@invocationParameters, "context");
725 }
726 }
727
728 # Generate code for parameters conversion.
729 my $parameterCount = @$parameters;
730 foreach my $parameterIndex (0..$parameterCount - 1) {
731 my $parameter = @$parameters[$parameterIndex];
732 my $parameterType = $parameter->type;
733 $parameterType = "DOMStringList" if $parameterType eq "DOMString[]";
734 AddHeaderForIDLType($parameterType, \%implIncludes);
735 my $name = $parameter->name;
736 my $parameterAdapterType = ParameterAdapterType($parameterType);
737 my $dartArgumentIndex = $parameterIndex + 1; # 0 is for the receiver.
738 my @adapterParameters = ("Dart_GetNativeArgument(args, $dartArgumentInde x)");
739 my $adapterParameters = join(", ", @adapterParameters);
740 push(@defineInvocationParameters, <<END);
741 const $parameterAdapterType $name($adapterParameters);
742 if (!$name.conversionSuccessful()) {
743 exception = $name.exception();
744 goto fail;
745 }
746 END
747 }
748 @invocationParameters = (@invocationParameters, map { $_->name; } @{$paramet ers});
749
750 if ($functionName eq "addEventListener" or $functionName eq "removeEventList ener") {
751 # addEventListener's and removeEventListener's last argument is marked
752 # as optional in idl, but is not optional in c++ implementation.
753 push(@invocationParameters, "false") if (@invocationParameters == 2);
754 }
755
756 if ($interfaceName eq "CSSStyleDeclaration" and $functionName eq "setPropert y") {
757 # CSSStyleDeclaration.setProperty priority parameter is optional in Dart
758 # idl, but is not optional in c++ implementation.
759 push(@invocationParameters, "String()") if (@invocationParameters == 2);
760 }
761
762 if ($attributes->{CustomArgumentHandling}) {
763 $implIncludes{"ScriptArguments.h"} = 1;
764 $implIncludes{"ScriptCallStack.h"} = 1;
765 $implIncludes{"V8Proxy.h"} = 1;
766 $implIncludes{"v8.h"} = 1;
767 my $customArgument = $parameterCount + 1;
768 push(@defineInvocationParameters, <<END);
769 v8::HandleScope handleScope;
770 v8::Context::Scope scope(V8Proxy::mainWorldContext(DartUtilities::domWin dowForCurrentIsolate()->frame()));
771
772 Dart_Handle customArgument = Dart_GetNativeArgument(args, $customArgumen t);
773 RefPtr<ScriptArguments> scriptArguments(DartUtilities::createScriptArgum ents(customArgument, exception));
774 if (!scriptArguments)
775 goto fail;
776
777 RefPtr<ScriptCallStack> scriptCallStack(DartUtilities::createScriptCallS tack());
778 if (!scriptCallStack->size())
779 return;
780 END
781 push(@invocationParameters, "scriptArguments", "scriptCallStack");
782 }
783
784 if ($attributes->{NeedsUserGestureCheck}) {
785 push(@invocationParameters, "DartUtilities::processingUserGesture()");
786 }
787
788 if ($raisesExceptions) {
789 push(@invocationParameters, "ec");
790 }
791
792 my $defineInvocationParameters = join "", @defineInvocationParameters;
793 my $invocationParameters = join ", ", @invocationParameters;
794 my $invocation = PrepareInvocation("receiver", $interfaceName, $invocationPr efix, $invocationParameters);
795 # Generate code for setting return value.
796 my $invocationAndReturn = <<END;
797 $invocation;
798 END
799 if ($returnType ne "void") {
800 $invocation = ProcessInvocationResult($invocation, $interfaceName, $retu rnType);
801 my $dartType = IDLTypeToDart($returnType);
802 if (!$codeGenerator->IsPrimitiveType($returnType) && !exists $primitiveD artTypes{$dartType}) {
803 $implIncludes{"@{[ClassName($dartType)]}.h"} = 1;
804 }
805 $invocation = "static_pointer_cast<SVGAnimatedEnumeration>($invocation)" if $returnType eq "SVGAnimatedEnumeration";
806 # Special case: some IDL's unsigned shorts/shorts are mapped to WebCore C++ enums, so we insert a
807 # static_cast<int> here not to provide overloads for all enums.
808 $invocation = "static_cast<int>($invocation)" if $returnType eq "unsigne d short" or $returnType eq "short";
809 # There is GC3Dboolean which is not a bool, but unsigned char for OpenGL compatibility.
810 $invocation = "static_cast<bool>($invocation)" if $dartType eq "bool";
811 $conversion = ($codeGenerator->IsStringType($returnType) and defined
812 $attributes->{ConvertNullStringTo}) ? ", ConvertDefaultToNull" : "";
813 $invocationAndReturn = <<END;
814 Dart_Handle returnValue = toDartValue($invocation$conversion);
815 if (returnValue)
816 Dart_SetReturnValue(args, returnValue);
817 END
818 }
819
820 my $webkitInvocation = $invocationAndReturn;
821 if ($raisesExceptions) {
822 $implIncludes{"ExceptionCode.h"} = 1;
823 $webkitInvocation = <<END;
824 ExceptionCode ec = 0;
825 $invocationAndReturn;
826 if (UNLIKELY(ec)) {
827 exception = DartDOMWrapper::exceptionCodeToDartException(ec);
828 goto fail;
829 }
830 END
831 }
832
833 my $conditionalString = GenerateConditionalStringForAttributes($attributes);
834 if ($conditionalString) {
835 push(@implContent, <<END);
836 #if $conditionalString
837 END
838 }
839
840 push(@implContent, <<END);
841 static void $name(Dart_NativeArguments args)
842 {
843 DartApiScope dartApiScope;
844 $exceptionManagementPrologue {
845 $webkitClassName* receiver = DartDOMWrapper::receiver< $webkitClassName >(args);
846 $defineInvocationParameters
847 $webkitInvocation return;
848 }
849 $exceptionManagementEpilogue}
850
851 END
852
853 if ($conditionalString) {
854 push(@implContent, <<END);
855 #else
856 static void $name(Dart_NativeArguments args)
857 {
858 DartApiScope dartApiScope;
859 Dart_ThrowException(DartUtilities::conditionalFunctionalityException());
860 }
861 #endif
862
863 END
864 }
865 }
866
867 # FIXME: copied from CodeGeneratorV8.pm
868 sub IsRefPtrType
869 {
870 my ($type,) = @_;
871
872 return 0 if $type eq "boolean";
873 return 0 if $type eq "float";
874 return 0 if $type eq "int";
875 return 0 if $type eq "Date";
876 return 0 if $type eq "DOMString";
877 return 0 if $type eq "double";
878 return 0 if $type eq "short";
879 return 0 if $type eq "long";
880 return 0 if $type eq "unsigned";
881 return 0 if $type eq "unsigned long";
882 return 0 if $type eq "unsigned short";
883
884 return 1;
885 }
886
887 # FIXME: partially copied from GetNativeType of CodeGeneratorV8.pm
888 sub IDLTypeToWebkit
889 {
890 my ($type, $isParameter) = @_;
891
892 my $svgNativeType = $codeGenerator->GetSVGTypeNeedingTearOff($type);
893 if ($svgNativeType) {
894 if ($svgNativeType =~ /List$/) {
895 return "${svgNativeType}*";
896 } else {
897 return "RefPtr<${svgNativeType} >";
898 }
899 }
900
901 if ($type eq "float" or $type eq "double") {
902 return $type;
903 }
904
905 return ($isParameter ? "const String&" : "String") if ($type eq "DOMString" or $type eq "DOMUserData");
906 return "int" if $type eq "int";
907 return "int" if $type eq "short" or $type eq "unsigned short";
908 return "unsigned" if $type eq "unsigned long";
909 return "int" if $type eq "long";
910 return "long long" if $type eq "long long";
911 return "unsigned long long" if $type eq "unsigned long long";
912 return "bool" if $type eq "boolean";
913 return "Range::CompareHow" if $type eq "CompareHow";
914 return "DOMTimeStamp" if $type eq "DOMTimeStamp";
915 return "unsigned" if $type eq "unsigned int";
916 # FIXME: EventTarget are evils!
917 # return "Node*" if $type eq "EventTarget" and $isParameter;
918 return "double" if $type eq "Date";
919 return "ScriptValue" if $type eq "DOMObject";
920 return "OptionsObject" if $type eq "OptionsObject";
921
922 # temporary hack
923 return "RefPtr<NodeFilter>" if $type eq "NodeFilter";
924
925 return "RefPtr<SerializedScriptValue>" if $type eq "SerializedScriptValue";
926
927 return "RefPtr<IDBKey>" if $type eq "IDBKey";
928
929 # necessary as resolvers could be constructed on fly.
930 return "RefPtr<XPathNSResolver>" if $type eq "XPathNSResolver";
931
932 return ($isParameter ? "${type}*" : "RefPtr<${type}>") if IsRefPtrType($type );
933
934 return "RefPtr<DOMStringList>" if $type eq "DOMStringList";
935
936 return "RefPtr<MediaQueryListListener>" if $type eq "MediaQueryListListener" ;
937
938 # Default, assume native type is a pointer with same type name as idl type
939 return "${type}*";
940 }
941
942 sub GenerateResolver
943 {
944 my ($interfaceName,) = @_;
945
946 my $className = ClassName($interfaceName);
947
948 push(@implContent, <<END);
949
950 Dart_NativeFunction ${className}::resolver(Dart_Handle name, int argumentCount)
951 {
952 String str = DartUtilities::dartStringToString(name);
953
954 END
955
956 foreach my $nativeDescriptor (@dartNatives) {
957 my $cppCallbackName = $nativeDescriptor->cppCallbackName;
958 my $nativeId = $nativeDescriptor->nativeId;
959 my $argumentCount = $nativeDescriptor->argumentCount;
960 push(@implContent, <<END);
961 if ($argumentCount == argumentCount && str == "$nativeId")
962 return Dart${interfaceName}Internal::$cppCallbackName;
963 END
964 }
965
966 push(@implContent, <<END);
967 return 0;
968 }
969
970 END
971 }
972
973 sub GenerateDartImplementationClassname
974 {
975 my ($interfaceName,) = @_;
976
977 my $className = ClassName($interfaceName);
978 my $dartInterfaceName = DartInterfaceName($interfaceName);
979
980 push(@implContent, <<END);
981
982 const char* const ${className}::dartImplementationClassName = "${dartInterfaceNa me}Implementation";
983 END
984 }
985
986 sub GenerateImplementationPrologue
987 {
988 my ($dataNode) = @_;
989
990 my $interfaceName = $dataNode->name;
991 my $className = ClassName($interfaceName);
992 my $internalNamespaceName = "Dart${interfaceName}Internal";
993
994 my $conditionalString = GenerateConditionalString($dataNode);
995
996 push(@implContentHeader, $headerTemplate);
997
998 push(@implContentHeader, <<END);
999
1000 #include "config.h"
1001 #include "$className.h"
1002
1003 END
1004
1005 push(@implContentHeader, "#if $conditionalString\n\n") if $conditionalString ;
1006
1007 $implIncludes{"DartBindingsCommonIncludes.h"} = 1;
1008
1009 push(@implContent, <<END);
1010 namespace WebCore {
1011
1012 namespace $internalNamespaceName {
1013 END
1014 }
1015
1016 sub GenerateImplementationEpilogue
1017 {
1018 my ($dataNode) = @_;
1019
1020 my $interfaceName = $dataNode->name;
1021 my $className = ClassName($interfaceName);
1022 my $internalNamespaceName = "Dart${interfaceName}Internal";
1023
1024 my $conditionalString = GenerateConditionalString($dataNode);
1025
1026 push(@implContent, "}\n");
1027
1028 GenerateResolver($interfaceName);
1029 GenerateDartImplementationClassname($interfaceName);
1030
1031 push(@implContent, <<END);
1032 }
1033 END
1034
1035 push(@implContent, "\n#endif // $conditionalString\n") if $conditionalString ;
1036
1037 # We've already added the header for this file in implFixedHeader, so remove
1038 # it from implIncludes to ensure we don't #include it twice.
1039 delete $implIncludes{"$className.h"};
1040 }
1041
1042 sub GenerateCallbackDartInterface
1043 {
1044 my ($object, $dataNode) = @_;
1045 my $function = $dataNode->functions->[0];
1046 my $functionDecl = DartInterfaceMethodDeclaration($interfaceName, $function, $dataNode->name);
1047 push(@dartInterfaceContent, $headerTemplate);
1048 push(@dartInterfaceContent, <<END);
1049 typedef $functionDecl;
1050 END
1051 }
1052
1053 sub FormatCallbackArgument
1054 {
1055 my ($argument,) = @_;
1056 my $webkitType = IDLTypeToWebkit($argument->type, 1);
1057 my $name = $argument->name;
1058 return "$webkitType $name";
1059 }
1060
1061 sub GenerateCallbackHeader
1062 {
1063 my ($object, $dataNode) = @_;
1064
1065 my $interfaceName = $dataNode->name;
1066 my $className = ClassName($interfaceName);
1067 my $webkitClassName = GetNativeTypeForConversions($interfaceName);
1068
1069 my $conditionalString = GenerateConditionalString($dataNode);
1070
1071 push(@headerContent, $headerTemplate);
1072
1073 push(@headerContent, "\n#if ${conditionalString}\n") if $conditionalString;
1074 push(@headerContent, <<END);
1075
1076 #ifndef ${className}_h
1077 #define ${className}_h
1078
1079 END
1080
1081 AddHeaderClassIncludes($interfaceName);
1082
1083 $headerIncludes{"ActiveDOMCallback.h"} = 1;
1084 $headerIncludes{"DartCallback.h"} = 1;
1085 push(@headerContent, GenerateIncludes(keys(%headerIncludes)));
1086
1087 my @handleEventMethods = ();
1088 foreach my $function (@{$dataNode->functions}) {
1089 die "Expect only handleEvent methods" if ($function->signature->type ne "boolean") || ($function->signature->name ne "handleEvent");
1090
1091 my $arguments = join ", ", map { FormatCallbackArgument($_); } @{$functi on->parameters};
1092 push(@handleEventMethods, " virtual bool handleEvent($arguments);");
1093 }
1094 my $methods = join "\n", @handleEventMethods;
1095
1096 push(@headerContent, <<END);
1097
1098 namespace WebCore {
1099
1100 class ScriptExecutionContext;
1101
1102 class $className : public $interfaceName, public ActiveDOMCallback {
1103 public:
1104 typedef $interfaceName NativeType;
1105
1106 static PassRefPtr<NativeType> toNative(Dart_Handle object, Dart_Handle& exce ption)
1107 {
1108 return adoptRef(new $className(object, exception, DartUtilities::scriptE xecutionContext()));
1109 }
1110
1111 $methods
1112
1113 private:
1114 $className(Dart_Handle object, Dart_Handle& exception, ScriptExecutionContex t* context)
1115 : ActiveDOMCallback(context)
1116 , m_callback(object, exception)
1117 {
1118 }
1119
1120 DartCallback m_callback;
1121 };
1122
1123 }
1124
1125 #endif // ${className}_h
1126 END
1127
1128 push(@headerContent, "\n#endif // ${conditionalString}\n") if $conditionalSt ring;
1129 }
1130
1131 sub GenerateCallbackImplementation
1132 {
1133 my ($object, $dataNode) = @_;
1134
1135 my $interfaceName = $dataNode->name;
1136 my $className = ClassName($interfaceName);
1137 my $internalNamespaceName = "Dart${interfaceName}Internal";
1138
1139 my $conditionalString = GenerateConditionalString($dataNode);
1140
1141 push(@implContentHeader, $headerTemplate);
1142
1143 $implIncludes{"DartBindingsCommonIncludes.h"} = 1;
1144
1145 push(@implContentHeader, <<END);
1146
1147 #include "config.h"
1148 #include "$className.h"
1149
1150 END
1151
1152 push(@implContentHeader, "#if $conditionalString\n\n") if $conditionalString ;
1153
1154 my @handleEventMethods = ();
1155 foreach my $function (@{$dataNode->functions}) {
1156 die "Expect only handleEvent methods" if ($function->signature->type ne "boolean") || ($function->signature->name ne "handleEvent");
1157
1158 my $arguments = join ", ", map { FormatCallbackArgument($_); } @{$functi on->parameters};
1159 my $parameters = join ", ", map { $_->name; } @{$function->parameters};
1160 push(@handleEventMethods, <<END);
1161 bool ${className}::handleEvent($arguments)
1162 {
1163 return m_callback.handleEvent($parameters);
1164 }
1165 END
1166 }
1167 my $methods = join "\n", @handleEventMethods;
1168
1169 push(@implContent, <<END);
1170 namespace WebCore {
1171
1172 $methods
1173
1174 }
1175 END
1176
1177 push(@implContent, "\n#endif // $conditionalString\n") if $conditionalString ;
1178
1179 # We've already added the header for this file in implFixedHeader, so remove
1180 # it from implIncludes to ensure we don't #include it twice.
1181 delete $implIncludes{"$className.h"};
1182 }
1183
1184 sub DartMethodDeclaration
1185 {
1186 my ($functionName, $parameters, $returnType) = @_;
1187
1188 $returnType = IDLTypeToDart($codeGenerator->StripModule($returnType));
1189 return "$returnType $functionName($parameters)";
1190 }
1191
1192 sub DartInterfaceMethodDeclaration
1193 {
1194 my ($interfaceName, $function, $name) = @_;
1195
1196 my $parameters;
1197 if (HasOverloads($function)) {
1198 my $maxParameterCount = MaxOverloadParameterCount($function);
1199 $parameters = DartAnonymousNamedOptionalParameters($maxParameterCount);
1200 } else {
1201 $parameters = DartParameters($function, $function->parameters, 1);
1202 }
1203 return DartMethodDeclaration($name || DartName($interfaceName, $function->si gnature->name), $parameters, $function->signature->type);
1204 }
1205
1206 sub DartParameters
1207 {
1208 my ($function, $parameters, $useDefaultValues) = @_;
1209
1210 my @mandatoryParameters = ();
1211 my @optionalParameters = ();
1212 foreach my $parameter (@{$parameters}) {
1213 # FIXME: parameter modifiers.
1214 my $type = IDLTypeToDart($parameter->type);
1215 my $name = $parameter->name;
1216 if ($useDefaultValues && IsParameterOptionalInWebKit($parameter)) {
1217 push(@optionalParameters, "$type ${name}");
1218 } else {
1219 push(@mandatoryParameters, "$type ${name}");
1220 }
1221 }
1222 if ($function->signature->extendedAttributes->{CustomArgumentHandling}) {
1223 die "Optional parameters in function with custom argument handling. " if @optionalParameters;
1224 push(@mandatoryParameters, "argument");
1225 }
1226 my $dartParameters = join(", ", @mandatoryParameters);
1227 if (@optionalParameters) {
1228 $dartParameters .= ", " if $dartParameters;
1229 $dartParameters .= "[" . join(", ", @optionalParameters) . "]";
1230 }
1231 return $dartParameters;
1232 }
1233
1234 sub DartParameterCount
1235 {
1236 my ($function, $parameters) = @_;
1237
1238 my $parameterCount = @{$parameters};
1239 $parameterCount += 1 if $function->signature->extendedAttributes->{CustomArg umentHandling};
1240 return $parameterCount;
1241 }
1242
1243 sub DartAnonymousArguments
1244 {
1245 my ($parameterCount) = @_;
1246 return "" unless $parameterCount;
1247 return join(", ", map { "_arg$_" } (0..$parameterCount - 1));
1248 }
1249
1250 sub DartAnonymousNamedOptionalParameters
1251 {
1252 my ($parameterCount) = @_;
1253 return "" unless $parameterCount;
1254 return "[" . DartAnonymousArguments($parameterCount) . "]";
1255 }
1256
1257 sub CreateFunctionNativeDescriptor
1258 {
1259 my ($interfaceName, $functionName, $argumentCount) = @_;
1260
1261 my $dartInterfaceName = DartInterfaceName($interfaceName);
1262 my $descriptor = NativeBindingDescriptor->new(
1263 cppCallbackName => "${functionName}Callback",
1264 nativeId => "${dartInterfaceName}_${functionName}_Callback",
1265 argumentCount => $argumentCount);
1266 push(@dartNatives, $descriptor);
1267 return $descriptor;
1268 }
1269
1270 sub CreateGetterNativeDescriptor
1271 {
1272 my ($interfaceName, $attributeName) = @_;
1273 my $dartInterfaceName = DartInterfaceName($interfaceName);
1274 my $descriptor = NativeBindingDescriptor->new(
1275 cppCallbackName => "${attributeName}Getter",
1276 nativeId => "${dartInterfaceName}_${attributeName}_Getter",
1277 argumentCount => 1);
1278 push(@dartNatives, $descriptor);
1279 return $descriptor;
1280 }
1281
1282 sub CreateSetterNativeDescriptor
1283 {
1284 my ($interfaceName, $attributeName) = @_;
1285 my $dartInterfaceName = DartInterfaceName($interfaceName);
1286 my $descriptor = NativeBindingDescriptor->new(
1287 cppCallbackName => "${attributeName}Setter",
1288 nativeId => "${dartInterfaceName}_${attributeName}_Setter",
1289 argumentCount => 2);
1290 push(@dartNatives, $descriptor);
1291 return $descriptor;
1292 }
1293
1294 sub GenerateDartOptionalArgumentsResolver
1295 {
1296 my ($interfaceName, $function) = @_;
1297
1298 my $interfaceMethodDeclaration = DartInterfaceMethodDeclaration($interfaceNa me, $function);
1299 push(@dartInterfaceContent, " $interfaceMethodDeclaration;\n");
1300
1301 my @resolver = ();
1302 push(@resolver, " $interfaceMethodDeclaration {\n");
1303 my @parameters = ();
1304 foreach my $parameterIndex (0..@{$function->parameters}) {
1305 my $parameter = @{$function->parameters}[$parameterIndex];
1306 if (!$parameter || IsParameterOptionalInWebKit($parameter)) {
1307 my $functionName = GenerateNativeBinding($interfaceName, $function, \@parameters);
1308 if ($parameter) {
1309 my $parameterName = $parameter->name;
1310 push(@resolver, " if ($parameterName === null)\n ");
1311 }
1312 my $parameterNames = join(", ", map { $_->name } @parameters);
1313 push(@resolver, " return $functionName($parameterNames);\n");
1314 }
1315 push(@parameters, $parameter);
1316 }
1317 push(@resolver, " }\n");
1318 push(@dartImplContent, join("", @resolver));
1319 }
1320
1321 sub GenerateDartOverloadResolver
1322 {
1323 my ($interfaceName, $function) = @_;
1324
1325 # Generate code for choosing the correct overload to call. Overloads are
1326 # chosen based on the the type of the arguments. When more than a single
1327 # overload is applicable, precedence is given according to the order of
1328 # declaration in the IDL.
1329
1330 my $interfaceMethodDeclaration = DartInterfaceMethodDeclaration($interfaceNa me, $function);
1331 push(@dartInterfaceContent, " $interfaceMethodDeclaration;\n");
1332
1333 my @resolver = ();
1334 push(@resolver, " $interfaceMethodDeclaration {\n");
1335 my $maxParameterCount = MaxOverloadParameterCount($function);
1336 foreach my $overload (@{$function->{overloads}}) {
1337 my @parameters = ();
1338 my @parameterNames = ();
1339 my @parameterChecks = map { "_arg$_ === null" } (0..$maxParameterCount - 1);
1340 foreach my $parameterIndex (0..@{$overload->parameters}) {
1341 my $parameter = @{$overload->parameters}[$parameterIndex];
1342 if (!$parameter || IsParameterOptionalInWebKit($parameter)) {
1343 my $functionName = GenerateNativeBinding($interfaceName, $overlo ad, \@parameters);
1344 my $parameterNames = join(", ", @parameterNames);
1345 my $parameterChecks = join(" && ", @parameterChecks);
1346 push(@resolver, <<END);
1347 if ($parameterChecks)
1348 return $functionName($parameterNames);
1349 END
1350 }
1351 last if !$parameter;
1352 my $idlType = $codeGenerator->StripModule($parameter->type);
1353 my $dartType = IDLTypeToDart($idlType);
1354 push(@parameterNames, "_arg$parameterIndex");
1355 $parameterChecks[$parameterIndex] = "_arg$parameterIndex is $dartTyp e";
1356 push(@parameters, $parameter);
1357 }
1358 }
1359
1360 # FIXME: throw appropriate exception when overload is not found.
1361 push(@resolver, <<END);
1362 throw "Failed to find overload of @{[$function->signature->name]}";
1363 }
1364 END
1365 push(@dartImplContent, join("", @resolver));
1366 }
1367
1368 sub ParentInterface
1369 {
1370 my $dataNode = shift;
1371
1372 foreach (@{$dataNode->parents}) {
1373 my $parent = $codeGenerator->StripModule($_);
1374 if ($parent eq "EventTarget") {
1375 next;
1376 }
1377 return $parent;
1378 }
1379 }
1380
1381 my %excludedInterfaces = (
1382 "SVGURIReference" => 1, # Is not in the list of SVG idls files (see WebCore.gy pi), v8 bindings do not immediately compile
1383 # Explicitly excluded in WebCore.gyp
1384 "ElementTimeControl" => 1,
1385 "SVGExternalResourcesRequired" => 1,
1386 "SVGFilterPrimitiveStandardAttributes" => 1,
1387 "SVGFitToViewBox" => 1,
1388 "SVGLangSpace" => 1,
1389 "SVGLocatable" => 1,
1390 "SVGStylable" => 1,
1391 "SVGTests" => 1,
1392 "SVGTransformable" => 1,
1393 "SVGViewSpec" => 1,
1394 "SVGZoomAndPan" => 1,
1395 );
1396
1397 sub ListLikeWithBase
1398 {
1399 my ($elementType, $baseClass, $needsAuxiliaryAccessors, $isTypedArray) = @_;
1400
1401 my @auxiliaryMethods = ();
1402 if ($needsAuxiliaryAccessors) {
1403 push(@auxiliaryMethods, ["$elementType operator [] (int index)", "numeri cIndexGetter", 2]);
1404 push(@auxiliaryMethods, ["void operator []= (int index, $elementType val ue)", "numericIndexSetter", 3]);
1405 }
1406
1407 return IDLTypeInfoStruct->new(
1408 additionalInterfaces => ["List<$elementType>"],
1409 superClass => "$baseClass",
1410 auxilaryMethods => \@auxiliaryMethods,
1411 isTypedArray => $isTypedArray,
1412 );
1413 }
1414
1415 sub ListLike
1416 {
1417 my ($elementType, $needsAuxiliaryAccessors) = @_;
1418
1419 return ListLikeWithBase($elementType, "ListBase<$elementType>", $needsAuxili aryAccessors, 0);
1420 }
1421
1422 sub ArrayBufferLike
1423 {
1424 my ($elementType, $needsAuxiliaryAccessors) = @_;
1425
1426 return ListLikeWithBase($elementType, "ArrayBufferViewImplementation", $need sAuxiliaryAccessors, 1);
1427 }
1428
1429 sub MapLike
1430 {
1431 # FIXME: most probably we need to deduce more types using hints like
1432 # HasNameGetter, CustomDeleteProperty, CustomGetPropertyNames, DelegatingPut Function
1433 # attributes.
1434 # FIXME: technically at least DOMStringMap.setItem and DOMStringMap.item cou ld be automatically
1435 # generated and then used from [] and []=. I don't do it for now not to mes s up with IDLs too
1436 # much.
1437 # FIXME: support removal of elements if allowed (it is at least for DOMStrin gMap.)
1438 my ($interfaceName, $keyType, $elementType) = @_;
1439 return IDLTypeInfoStruct->new(
1440 additionalInterfaces => ["Map<$keyType, $elementType>"],
1441 superClass => "MapBase<$keyType, $elementType>",
1442 auxilaryMethods => [
1443 ["Collection<$keyType> getKeys()", "getKeys", 1],
1444 ["$elementType operator [] ($keyType k)", "item", 2],
1445 ["operator []= ($keyType k, $elementType v)", "setItem", 3],
1446 ["$elementType remove($keyType k)", "deleteItem", 2],
1447 ],
1448 );
1449 }
1450
1451 my %idlTypeInfoOverrides = (
1452 "CanvasPixelArray" => ListLike("int", 1),
1453 "DOMStringMap" => MapLike("DOMStringMap", "String", "String"),
1454 "HTMLCollection" => ListLike("Node"),
1455 "NodeList" => ListLike("Node"),
1456 "StyleSheetList" => ListLike("StyleSheet"),
1457 "ArrayBufferView" => ListLikeWithBase("num", "ListBase<num>"),
1458 "Float32Array" => ArrayBufferLike("double", 1),
1459 "Float64Array" => ArrayBufferLike("double", 1),
1460 "Int8Array" => ArrayBufferLike("int", 1),
1461 "Int16Array" => ArrayBufferLike("int", 1),
1462 "Int32Array" => ArrayBufferLike("int", 1),
1463 "Uint8Array" => ArrayBufferLike("int", 1),
1464 "Uint16Array" => ArrayBufferLike("int", 1),
1465 "Uint32Array" => ArrayBufferLike("int", 1),
1466 );
1467
1468 # FIXME: turn into the single IDL type info registry.
1469 sub IDLTypeInfo
1470 {
1471 my ($dataNode,) = @_;
1472 my $override = $idlTypeInfoOverrides{$dataNode->name};
1473 return $override if $override;
1474
1475 my $parentInterface = ParentInterface($dataNode);
1476 return IDLTypeInfoStruct->new(
1477 superClass => $parentInterface ? "${parentInterface}Implementation" : "D OMType",
1478 );
1479 }
1480
1481 sub GenerateSource
1482 {
1483 my ($object, $dataNode) = @_;
1484
1485 my $interfaceName = $dataNode->name;
1486 my $w3cInterfaceName = IDLTypeToW3C($interfaceName);
1487
1488 push(@dartInterfaceContent, $headerTemplate);
1489
1490 # Build extends clause if any.
1491 my $extendsClause = "";
1492 my $parentInterface = ParentInterface($dataNode);
1493 my $isEventTarget = $dataNode->extendedAttributes->{EventTarget};
1494 my @implementedInterfaces = ();
1495 push(@implementedInterfaces, $parentInterface) if $parentInterface;
1496 push(@implementedInterfaces, "EventTarget") if $isEventTarget;
1497
1498 push(@implementedInterfaces, @{IDLTypeInfo($dataNode)->additionalInterfaces} );
1499 push(@implementedInterfaces, @allParents);
1500
1501 if (@implementedInterfaces) {
1502 $extendsClause = " extends " . join(", ", @implementedInterfaces);
1503 }
1504
1505 # Build default clause if any.
1506 my $defaultClause = "";
1507 if (CanBeConstructed($dataNode)) {
1508 $defaultClause = " default ${w3cInterfaceName}Implementation";
1509 push(@customCallbackDeclarations, GenerateCustomCallbackDeclaration("con structorCallback"));
1510 }
1511
1512 push(@dartInterfaceContent, "\ninterface ${w3cInterfaceName}${extendsClause} ${defaultClause} {\n");
1513 push(@dartInterfaceContent, "\n // Constants.\n");
1514 foreach my $constant (@{$dataNode->constants}) {
1515 my $name = $constant->name;
1516 my $value = $constant->value;
1517
1518 push(@dartInterfaceContent, " static final int $name = $value;\n");
1519 }
1520
1521 # Generate Dart implementation prologue.
1522 my $implementationClassName = "${interfaceName}Implementation";
1523 my $superClass = IDLTypeInfo($dataNode)->superClass;
1524 push(@dartImplContent, $headerTemplate);
1525 push(@dartImplContent, "\nclass $implementationClassName extends $superClass implements $interfaceName {\n");
1526
1527 GenerateImplementationPrologue($dataNode);
1528
1529 # Generate fields.
1530 # FIXME: special treatment of constructors attributes (see V8 code generator ).
1531 push(@dartInterfaceContent, "\n // Fields.\n");
1532 push(@dartImplContent, "\n // Fields.\n");
1533 push(@implContent, "\n// Getters & setters.\n");
1534 foreach my $attribute (@{$dataNode->attributes}) {
1535 next if IgnoredAttribute($interfaceName, $attribute);
1536 GenerateField($interfaceName, $attribute);
1537 }
1538
1539 # Generate methods.
1540 push(@dartInterfaceContent, "\n // Methods.\n");
1541 push(@dartImplContent, "\n // Methods.\n");
1542 push(@implContent, "\n// Callbacks.\n");
1543 foreach my $function (@{$dataNode->functions}) {
1544 next if IgnoredCallback($interfaceName, $function);
1545 next if HasOverloads($function) && $function->{overloadIndex} != 1;
1546 GenerateMethod($interfaceName, $function);
1547 }
1548
1549 foreach my $auxilaryMethod (@{IDLTypeInfo($dataNode)->auxilaryMethods}) {
1550 my $dartDeclaration = $auxilaryMethod->[0];
1551 my $descriptor = CreateFunctionNativeDescriptor($interfaceName, $auxilar yMethod->[1], $auxilaryMethod->[2]);
1552 my $nativeId = $descriptor->nativeId;
1553 push(@dartImplContent, " $dartDeclaration native \"$nativeId\";\n");
1554 push(@customCallbackDeclarations, GenerateCustomCallbackDeclaration($des criptor->cppCallbackName));
1555 }
1556
1557 if (CanBeConstructed($dataNode)) {
1558 my $parameterCount = ConstructorParameterCount($dataNode);
1559 my $parameters = DartAnonymousNamedOptionalParameters($parameterCount);
1560 my $arguments = DartAnonymousArguments($parameterCount);
1561 push(@dartInterfaceContent, " $w3cInterfaceName($parameters);\n");
1562 push(@dartImplContent, <<END);
1563 $implementationClassName($parameters) {
1564 this._bind($arguments);
1565 }
1566 END
1567
1568 if (IDLTypeInfo($dataNode)->isTypedArray)
1569 {
1570 push(@dartInterfaceContent, <<END);
1571 $w3cInterfaceName.fromBuffer(ArrayBuffer buffer, [int start, int length]);
1572 $w3cInterfaceName.fromList(List<num> list);
1573 END
1574 push(@dartImplContent, <<END);
1575 $implementationClassName.fromBuffer(ArrayBuffer buffer, [int start, int length ]) {
1576 this._bind(buffer, start, length);
1577 }
1578 $implementationClassName.fromList(List<num> list) {
1579 this._bind(list, null, null);
1580 }
1581 END
1582 }
1583 if (HasCustomConstructor($dataNode)) {
1584 my $descriptor = CreateFunctionNativeDescriptor($interfaceName, "cons tructor", $parameterCount);
1585 my $nativeId = $descriptor->nativeId;
1586 push(@dartImplContent, " void _bind($arguments) native \"$nativeId\" ;\n");
1587 } else {
1588 push(@dartImplContent, " void _bind($arguments) { /* FIXME: bind to the real object */ throw 'Binding unimplemented'; }\n");
1589 }
1590 }
1591
1592 # Generate implementation support.
1593 # FIXME: get rid of implementation support completely.
1594 push(@dartImplContent, <<END);
1595 // Implementation support.
1596 static $implementationClassName _create$implementationClassName() => new $impl ementationClassName._create$implementationClassName();
1597 $implementationClassName._create$implementationClassName();
1598
1599 String get typeName() => \"$interfaceName\";
1600 END
1601
1602 push(@dartInterfaceContent, "}\n");
1603 push(@dartImplContent, "}\n");
1604
1605 if (HasW3CName($interfaceName)) {
1606 push(@dartInterfaceContent, "\ninterface ${interfaceName} extends ${w3cI nterfaceName} {}\n");
1607 }
1608
1609 GenerateImplementationEpilogue($dataNode);
1610 }
1611
1612 sub GenerateField
1613 {
1614 my ($interfaceName, $attribute) = @_;
1615
1616 my $attributeName = DartName($interfaceName, $attribute->signature->name);
1617 my $attributeType = $attribute->signature->type;
1618 my $dartAttributeType = IDLTypeToDart($attributeType);
1619
1620 # Generate field declaration.
1621 my $final = HasSetter($attribute) ? "" : "final ";
1622 push(@dartInterfaceContent, " $final$dartAttributeType $attributeName;\n");
1623
1624 # Generate getter implementation.
1625 my $getterDescriptor = CreateGetterNativeDescriptor($interfaceName, $attribu teName);
1626 my $getterNativeId = $getterDescriptor->nativeId;
1627 push(@dartImplContent, " $dartAttributeType get $attributeName() native \"$ getterNativeId\";\n");
1628 if (HasCustomGetter($attribute)) {
1629 push(@customCallbackDeclarations, GenerateCustomCallbackDeclaration($get terDescriptor->cppCallbackName));
1630 } else {
1631 my ($functionName, @arguments) = $codeGenerator->GetterExpression(\%impl Includes, $interfaceName, $attribute);
1632 my $raisesExceptions = scalar(@{$attribute->getterExceptions});
1633 GenerateGenericBindingsFunction($getterDescriptor->cppCallbackName, $int erfaceName, $functionName, \@arguments, [], $attributeType, $raisesExceptions, $ attribute->signature->extendedAttributes);
1634 }
1635
1636 return unless HasSetter($attribute);
1637
1638 # Generate setter implementation.
1639 my $setterDescriptor = CreateSetterNativeDescriptor($interfaceName, $attribu teName);
1640 my $setterNativeId = $setterDescriptor->nativeId;
1641 push(@dartImplContent, " void set $attributeName($dartAttributeType) native \"$setterNativeId\";\n");
1642 if (HasCustomSetter($attribute)) {
1643 push(@customCallbackDeclarations, GenerateCustomCallbackDeclaration($set terDescriptor->cppCallbackName));
1644 } else {
1645 my ($functionName, @arguments) = $codeGenerator->SetterExpression(\%impl Includes, $interfaceName, $attribute);
1646 my $raisesExceptions = scalar(@{$attribute->setterExceptions});
1647 GenerateGenericBindingsFunction($setterDescriptor->cppCallbackName, $int erfaceName, $functionName, \@arguments, [$attribute->signature], "void", $raises Exceptions, $attribute->signature->extendedAttributes, 1);
1648 }
1649 }
1650
1651 sub GenerateMethod
1652 {
1653 my ($interfaceName, $function) = @_;
1654
1655 if ($interfaceName eq "CSSStyleDeclaration" && $function->signature->name eq "setProperty") {
1656 my $priorityParameter = @{$function->parameters}[2];
1657 $priorityParameter->extendedAttributes->{Optional} = 1;
1658 }
1659
1660 my $functionName = DartName($interfaceName, $function->signature->name);
1661
1662 if (!$function->signature->extendedAttributes->{"Custom"}) {
1663 if (HasOverloads($function)) {
1664 GenerateDartOverloadResolver($interfaceName, $function);
1665 } elsif (HasOptionalParameters($function)) {
1666 GenerateDartOptionalArgumentsResolver($interfaceName, $function);
1667 } else {
1668 my $interfaceMethodDeclaration = DartInterfaceMethodDeclaration($int erfaceName, $function);
1669 push(@dartInterfaceContent, " $interfaceMethodDeclaration;\n");
1670 my $bindingFunctionName = GenerateNativeBinding($interfaceName, $fun ction, $function->parameters);
1671 die if $bindingFunctionName ne $functionName;
1672 }
1673 } else {
1674 my $parameters;
1675 my $parameterCount;
1676 if (HasOverloads($function)) {
1677 $parameterCount = MaxOverloadParameterCount($function);
1678 $parameters = DartAnonymousNamedOptionalParameters($parameterCount);
1679 } else {
1680 $parameters = DartParameters($function, $function->parameters, 1);
1681 $parameterCount = DartParameterCount($function, $function->parameter s);
1682 }
1683 my $methodDeclaration = DartMethodDeclaration($functionName, $parameters , $function->signature->type);
1684 my $descriptor = CreateFunctionNativeDescriptor($interfaceName, $functio nName, 1 + $parameterCount);
1685 my $nativeId = $descriptor->nativeId;
1686 push(@dartInterfaceContent, " $methodDeclaration;\n");
1687 push(@dartImplContent, " $methodDeclaration native \"$nativeId\";\n");
1688 push(@customCallbackDeclarations, GenerateCustomCallbackDeclaration($des criptor->cppCallbackName));
1689 }
1690
1691 # If there is a method named "item", duplicate it as operator [].
1692 if ($functionName eq "item") {
1693 # Consider operator [] should support overloads and optional arguments.
1694 die "$interfaceName.item has overloads" if HasOverloads($function);
1695 die "$interfaceName.item has optional arguments" if HasOptionalParameter s($function);
1696
1697 my $subscriptOperatorDeclaration = DartInterfaceMethodDeclaration($inter faceName, $function, "operator []");
1698 my $parameters = join ", ", (map { $_->name } @{$function->parameters});
1699 push(@dartInterfaceContent, " $subscriptOperatorDeclaration;\n");
1700 push(@dartImplContent, " $subscriptOperatorDeclaration { return item($p arameters); }\n");
1701 }
1702 }
1703
1704 sub GenerateNativeBinding
1705 {
1706 my ($interfaceName, $function, $parameters) = @_;
1707
1708 my $functionName = DartName($interfaceName, $function->signature->name);
1709 my $index = 0;
1710 foreach my $overload (@{$function->{overloads}}) {
1711 $index += 1;
1712 last if $overload == $function;
1713 foreach my $parameter (@{$overload->parameters}) {
1714 $index += 1 if IsParameterOptionalInWebKit($parameter);
1715 }
1716 }
1717 my $mandatoryParameterCount = 0;
1718 foreach my $parameter (@{$function->parameters}) {
1719 last if IsParameterOptionalInWebKit($parameter);
1720 $mandatoryParameterCount += 1;
1721 }
1722 $index += @{$parameters} - $mandatoryParameterCount;
1723 if ($index != 1) {
1724 $functionName .= "_" . $index;
1725 }
1726
1727 my $extendedAttributes = $function->signature->extendedAttributes;
1728 my $returnType = $function->signature->type;
1729
1730 my $dartParameters = DartParameters($function, $parameters, 0);
1731 my $dartParameterCount = DartParameterCount($function, $parameters);
1732 my $methodDeclaration = DartMethodDeclaration($functionName, $dartParameters , $returnType);
1733 my $descriptor = CreateFunctionNativeDescriptor($interfaceName, $functionNam e, 1 + $dartParameterCount);
1734 my $nativeId = $descriptor->nativeId;
1735 push(@dartImplContent, <<END);
1736 $methodDeclaration native "$nativeId";
1737 END
1738
1739 my $nativeFunctionName;
1740 if ($extendedAttributes->{ImplementationFunction}) {
1741 $nativeFunctionName = $extendedAttributes->{ImplementationFunction};
1742 } else {
1743 $nativeFunctionName = $function->signature->name;
1744 }
1745 my $raisesExceptions = scalar(@{$function->raisesExceptions});
1746 GenerateGenericBindingsFunction($descriptor->cppCallbackName, $interfaceName , $nativeFunctionName, [], $parameters, $returnType, $raisesExceptions, $extende dAttributes);
1747
1748 return $functionName;
1749 }
1750
1751 # Internal helper
1752 sub WriteData
1753 {
1754 if (defined($IMPL)) {
1755 # Write content to file.
1756 print $IMPL @implContentHeader;
1757
1758 print $IMPL @implFixedHeader;
1759
1760 print $IMPL GenerateIncludes(keys(%implIncludes));
1761
1762 print $IMPL "\n";
1763 print $IMPL @implContent;
1764 close($IMPL);
1765 undef($IMPL);
1766
1767 %implIncludes = ();
1768 @implFixedHeader = ();
1769 @implHeaderContent = ();
1770 @implContent = ();
1771 @dartNatives = ();
1772 }
1773
1774 if (defined($HEADER)) {
1775 # Write content to file.
1776 print $HEADER @headerContent;
1777 close($HEADER);
1778 undef($HEADER);
1779
1780 @headerContent = ();
1781 }
1782 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698