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

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

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

Powered by Google App Engine
This is Rietveld 408576698