[WebIDL] Add support for modern callback syntax
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 5 Nov 2016 00:03:32 +0000 (00:03 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 5 Nov 2016 00:03:32 +0000 (00:03 +0000)
https://bugs.webkit.org/show_bug.cgi?id=164435

Patch by Sam Weinig <sam@webkit.org> on 2016-11-04
Reviewed by Chris Dumez.

Support new callback syntax:
    callback Function = void (DOMString arg1, long arg2);

This replaces "callback interface" types with a Callback=FunctionOnly
extended attribute.

* Modules/geolocation/PositionCallback.idl:
* Modules/geolocation/PositionErrorCallback.idl:
* Modules/notifications/NotificationPermissionCallback.idl:
* Modules/quota/StorageErrorCallback.idl:
* Modules/quota/StorageQuotaCallback.idl:
* Modules/quota/StorageUsageCallback.idl:
* Modules/webaudio/AudioBufferCallback.idl:
* Modules/webdatabase/DatabaseCallback.idl:
* Modules/webdatabase/SQLStatementCallback.idl:
* Modules/webdatabase/SQLStatementErrorCallback.idl:
* Modules/webdatabase/SQLTransactionCallback.idl:
* Modules/webdatabase/SQLTransactionErrorCallback.idl:
* dom/RequestAnimationFrameCallback.idl:
* dom/StringCallback.idl:
* html/VoidCallback.idl:
* page/IntersectionObserverCallback.idl:
* css/MediaQueryListListener.idl:
Update to new syntax.

* css/MediaQueryListListener.h:
* css/MediaQueryMatcher.cpp:
(WebCore::MediaQueryMatcher::styleResolverChanged):
Switch to using the now required 'handleEvent' name. This is an implementation detail
that we should change.

* bindings/scripts/CodeGenerator.pm:
Update document processing to allow a callback only file. Update callback
type checks to look for a regex that matches in the new format.

* bindings/scripts/CodeGeneratorJS.pm:
(AddToImplIncludesForIDLType):
(AddToIncludesForIDLType):
(AddToImplIncludes):
(AddToIncludes):
Abstract includes functions to allow passing in an include hash.

(GenerateCallbackFunctionHeader):
(GenerateCallbackFunctionImplementation):
(GenerateCallbackInterfaceHeader):
(GenerateCallbackInterfaceImplementation):
(GenerateCallbackHeaderContent):
(GenerateCallbackImplementationContent):
Refactor callback generation code into GenerateCallbackHeaderContent and GenerateCallbackImplementationContent
to allow using it for both the new callbacks as well as the old callback interfaces.

* bindings/scripts/IDLParser.pm:
(Parse):
(applyTypedefs):
(applyTypedefsToOperation):
(parseCallbackRest):
Parse callbacks into the new IDLCallbackFunction type. Ensure that typedefs are applied as well.

* bindings/scripts/IDLAttributes.txt:
Remove support for Callback=FunctionOnly.

* bindings/scripts/test/JS/JSTestCallback.cpp: Removed.
* bindings/scripts/test/JS/JSTestCallback.h: Removed.
* bindings/scripts/test/JS/JSTestCallbackFunction.cpp:
* bindings/scripts/test/JS/JSTestCallbackFunction.h:
* bindings/scripts/test/JS/JSTestCallbackFunctionWithTypedefs.cpp: Added.
* bindings/scripts/test/JS/JSTestCallbackFunctionWithTypedefs.h: Added.
* bindings/scripts/test/JS/JSTestCallbackInterface.cpp: Copied from Source/WebCore/bindings/scripts/test/JS/JSTestCallback.cpp.
* bindings/scripts/test/JS/JSTestCallbackInterface.h: Copied from Source/WebCore/bindings/scripts/test/JS/JSTestCallback.h.
* bindings/scripts/test/JS/JSTestObj.cpp:
* bindings/scripts/test/JS/JSTestTypedefs.cpp:
* bindings/scripts/test/TestCallback.idl: Removed.
* bindings/scripts/test/TestCallbackFunction.idl:
* bindings/scripts/test/TestCallbackFunctionWithTypedefs.idl: Added.
* bindings/scripts/test/TestCallbackInterface.idl: Copied from Source/WebCore/bindings/scripts/test/TestCallback.idl.
* bindings/scripts/test/TestObj.idl:
* bindings/scripts/test/TestTypedefs.idl:
Update existing tests and add new ones to test callback functions specifically.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@208408 268f45cc-cd09-0410-ab3c-d52691b4dbfc

37 files changed:
Source/WebCore/ChangeLog
Source/WebCore/Modules/geolocation/PositionCallback.idl
Source/WebCore/Modules/geolocation/PositionErrorCallback.idl
Source/WebCore/Modules/notifications/NotificationPermissionCallback.idl
Source/WebCore/Modules/quota/StorageErrorCallback.idl
Source/WebCore/Modules/quota/StorageQuotaCallback.idl
Source/WebCore/Modules/quota/StorageUsageCallback.idl
Source/WebCore/Modules/webaudio/AudioBufferCallback.idl
Source/WebCore/Modules/webdatabase/DatabaseCallback.idl
Source/WebCore/Modules/webdatabase/SQLStatementCallback.idl
Source/WebCore/Modules/webdatabase/SQLStatementErrorCallback.idl
Source/WebCore/Modules/webdatabase/SQLTransactionCallback.idl
Source/WebCore/Modules/webdatabase/SQLTransactionErrorCallback.idl
Source/WebCore/bindings/scripts/CodeGenerator.pm
Source/WebCore/bindings/scripts/CodeGeneratorJS.pm
Source/WebCore/bindings/scripts/IDLAttributes.txt
Source/WebCore/bindings/scripts/IDLParser.pm
Source/WebCore/bindings/scripts/test/JS/JSTestCallbackFunction.cpp
Source/WebCore/bindings/scripts/test/JS/JSTestCallbackFunction.h
Source/WebCore/bindings/scripts/test/JS/JSTestCallbackFunctionWithTypedefs.cpp [new file with mode: 0644]
Source/WebCore/bindings/scripts/test/JS/JSTestCallbackFunctionWithTypedefs.h [new file with mode: 0644]
Source/WebCore/bindings/scripts/test/JS/JSTestCallbackInterface.cpp [moved from Source/WebCore/bindings/scripts/test/JS/JSTestCallback.cpp with 70% similarity]
Source/WebCore/bindings/scripts/test/JS/JSTestCallbackInterface.h [moved from Source/WebCore/bindings/scripts/test/JS/JSTestCallback.h with 77% similarity]
Source/WebCore/bindings/scripts/test/JS/JSTestObj.cpp
Source/WebCore/bindings/scripts/test/JS/JSTestTypedefs.cpp
Source/WebCore/bindings/scripts/test/TestCallbackFunction.idl
Source/WebCore/bindings/scripts/test/TestCallbackFunctionWithTypedefs.idl [new file with mode: 0644]
Source/WebCore/bindings/scripts/test/TestCallbackInterface.idl [moved from Source/WebCore/bindings/scripts/test/TestCallback.idl with 60% similarity]
Source/WebCore/bindings/scripts/test/TestObj.idl
Source/WebCore/bindings/scripts/test/TestTypedefs.idl
Source/WebCore/css/MediaQueryListListener.h
Source/WebCore/css/MediaQueryListListener.idl
Source/WebCore/css/MediaQueryMatcher.cpp
Source/WebCore/dom/RequestAnimationFrameCallback.idl
Source/WebCore/dom/StringCallback.idl
Source/WebCore/html/VoidCallback.idl
Source/WebCore/page/IntersectionObserverCallback.idl

index e90c082..7d61f1e 100644 (file)
@@ -1,3 +1,89 @@
+2016-11-04  Sam Weinig  <sam@webkit.org>
+
+        [WebIDL] Add support for modern callback syntax
+        https://bugs.webkit.org/show_bug.cgi?id=164435
+
+        Reviewed by Chris Dumez.
+
+        Support new callback syntax:
+            callback Function = void (DOMString arg1, long arg2);
+
+        This replaces "callback interface" types with a Callback=FunctionOnly
+        extended attribute.
+
+        * Modules/geolocation/PositionCallback.idl:
+        * Modules/geolocation/PositionErrorCallback.idl:
+        * Modules/notifications/NotificationPermissionCallback.idl:
+        * Modules/quota/StorageErrorCallback.idl:
+        * Modules/quota/StorageQuotaCallback.idl:
+        * Modules/quota/StorageUsageCallback.idl:
+        * Modules/webaudio/AudioBufferCallback.idl:
+        * Modules/webdatabase/DatabaseCallback.idl:
+        * Modules/webdatabase/SQLStatementCallback.idl:
+        * Modules/webdatabase/SQLStatementErrorCallback.idl:
+        * Modules/webdatabase/SQLTransactionCallback.idl:
+        * Modules/webdatabase/SQLTransactionErrorCallback.idl:
+        * dom/RequestAnimationFrameCallback.idl:
+        * dom/StringCallback.idl:
+        * html/VoidCallback.idl:
+        * page/IntersectionObserverCallback.idl:
+        * css/MediaQueryListListener.idl:
+        Update to new syntax.
+
+        * css/MediaQueryListListener.h:
+        * css/MediaQueryMatcher.cpp:
+        (WebCore::MediaQueryMatcher::styleResolverChanged):
+        Switch to using the now required 'handleEvent' name. This is an implementation detail
+        that we should change.
+
+        * bindings/scripts/CodeGenerator.pm:
+        Update document processing to allow a callback only file. Update callback
+        type checks to look for a regex that matches in the new format.
+
+        * bindings/scripts/CodeGeneratorJS.pm:
+        (AddToImplIncludesForIDLType):
+        (AddToIncludesForIDLType):
+        (AddToImplIncludes):
+        (AddToIncludes):
+        Abstract includes functions to allow passing in an include hash.
+
+        (GenerateCallbackFunctionHeader):
+        (GenerateCallbackFunctionImplementation):
+        (GenerateCallbackInterfaceHeader):
+        (GenerateCallbackInterfaceImplementation):
+        (GenerateCallbackHeaderContent):
+        (GenerateCallbackImplementationContent):
+        Refactor callback generation code into GenerateCallbackHeaderContent and GenerateCallbackImplementationContent
+        to allow using it for both the new callbacks as well as the old callback interfaces.
+
+        * bindings/scripts/IDLParser.pm:
+        (Parse):
+        (applyTypedefs):
+        (applyTypedefsToOperation):
+        (parseCallbackRest):
+        Parse callbacks into the new IDLCallbackFunction type. Ensure that typedefs are applied as well.
+
+        * bindings/scripts/IDLAttributes.txt:
+        Remove support for Callback=FunctionOnly.
+
+        * bindings/scripts/test/JS/JSTestCallback.cpp: Removed.
+        * bindings/scripts/test/JS/JSTestCallback.h: Removed.
+        * bindings/scripts/test/JS/JSTestCallbackFunction.cpp:
+        * bindings/scripts/test/JS/JSTestCallbackFunction.h:
+        * bindings/scripts/test/JS/JSTestCallbackFunctionWithTypedefs.cpp: Added.
+        * bindings/scripts/test/JS/JSTestCallbackFunctionWithTypedefs.h: Added.
+        * bindings/scripts/test/JS/JSTestCallbackInterface.cpp: Copied from Source/WebCore/bindings/scripts/test/JS/JSTestCallback.cpp.
+        * bindings/scripts/test/JS/JSTestCallbackInterface.h: Copied from Source/WebCore/bindings/scripts/test/JS/JSTestCallback.h.
+        * bindings/scripts/test/JS/JSTestObj.cpp:
+        * bindings/scripts/test/JS/JSTestTypedefs.cpp:
+        * bindings/scripts/test/TestCallback.idl: Removed.
+        * bindings/scripts/test/TestCallbackFunction.idl:
+        * bindings/scripts/test/TestCallbackFunctionWithTypedefs.idl: Added.
+        * bindings/scripts/test/TestCallbackInterface.idl: Copied from Source/WebCore/bindings/scripts/test/TestCallback.idl.
+        * bindings/scripts/test/TestObj.idl:
+        * bindings/scripts/test/TestTypedefs.idl:
+        Update existing tests and add new ones to test callback functions specifically.
+
 2016-11-04  Alex Christensen  <achristensen@webkit.org>
 
         Move isDefaultPortForProtocol from URLParser.cpp back to URL.cpp
index 819b385..e2ce962 100644 (file)
@@ -24,7 +24,4 @@
 
 [
     Conditional=GEOLOCATION,
-    Callback=FunctionOnly,
-] callback interface PositionCallback {
-    boolean handleEvent(Geoposition position);
-};
+] callback PositionCallback = void (Geoposition position);
index 2a609d3..57b493c 100644 (file)
@@ -24,7 +24,4 @@
 
 [
     Conditional=GEOLOCATION,
-    Callback=FunctionOnly,
-] callback interface PositionErrorCallback {
-    boolean handleEvent(PositionError error);
-};
+] callback PositionErrorCallback = void (PositionError error);
index e2c5eef..6d3d984 100644 (file)
@@ -25,8 +25,5 @@
 
 [
     Conditional=NOTIFICATIONS,
-    Callback=FunctionOnly,
-] callback interface NotificationPermissionCallback {
-    boolean handleEvent(DOMString permission);
-};
+] callback NotificationPermissionCallback = void (DOMString permission);
 
index 088f78f..ece8ce7 100644 (file)
@@ -30,7 +30,4 @@
 
 [
     Conditional=QUOTA,
-    Callback=FunctionOnly,
-] callback interface StorageErrorCallback {
-    boolean handleEvent(DOMCoreException error);
-};
+] callback StorageErrorCallback = void (DOMCoreException error);
index 89a82e7..0481a95 100644 (file)
@@ -30,7 +30,4 @@
 
 [
     Conditional=QUOTA,
-    Callback=FunctionOnly,
-] callback interface StorageQuotaCallback {
-    boolean handleEvent(unsigned long long grantedQuotaInBytes);
-};
+] callback StorageQuotaCallback = void (unsigned long long grantedQuotaInBytes);
index 7e50f5d..d6bd5ca 100644 (file)
@@ -30,7 +30,4 @@
 
 [
     Conditional=QUOTA,
-    Callback=FunctionOnly,
-] callback interface StorageUsageCallback {
-    boolean handleEvent(unsigned long long currentUsageInBytes, unsigned long long currentQuotaInBytes);
-};
+] callback StorageUsageCallback = void (unsigned long long currentUsageInBytes, unsigned long long currentQuotaInBytes);
index c031bde..74577fd 100644 (file)
@@ -25,7 +25,4 @@
 [
     Conditional=WEB_AUDIO,
     JSGenerateToJSObject,
-    Callback=FunctionOnly,
-] callback interface AudioBufferCallback {
-    boolean handleEvent(AudioBuffer audioBuffer);
-};
+] callback AudioBufferCallback = void (AudioBuffer audioBuffer);
index b5c8036..9e0a5de 100644 (file)
@@ -26,8 +26,4 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-[
-    Callback=FunctionOnly,
-] callback interface DatabaseCallback {
-    boolean handleEvent(Database database);
-};
+callback DatabaseCallback = void (Database database);
index 9bf63bf..75f81f5 100644 (file)
@@ -25,8 +25,5 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-[
-    Callback=FunctionOnly,
-] callback interface SQLStatementCallback {
-    boolean handleEvent(SQLTransaction transaction, SQLResultSet resultSet);
-};
+
+callback SQLStatementCallback = void (SQLTransaction transaction, SQLResultSet resultSet);
index a27ce4c..c684823 100644 (file)
@@ -25,8 +25,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
+
 [
-    Callback=FunctionOnly,
-] callback interface SQLStatementErrorCallback {
-    [Custom] boolean handleEvent(SQLTransaction transaction, SQLError error);
-};
+    Custom
+] callback SQLStatementErrorCallback = boolean (SQLTransaction transaction, SQLError error);
index d5afbdb..24f9fa8 100644 (file)
@@ -25,8 +25,5 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-[
-    Callback=FunctionOnly,
-] callback interface SQLTransactionCallback {
-    boolean handleEvent(SQLTransaction transaction);
-};
+
+callback SQLTransactionCallback = void (SQLTransaction transaction);
index 510dc6c..450a460 100644 (file)
@@ -26,8 +26,4 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-[
-    Callback=FunctionOnly,
-] callback interface SQLTransactionErrorCallback {
-    boolean handleEvent(SQLError error);
-};
+callback SQLTransactionErrorCallback = void (SQLError error);
index 1b3efcd..452643c 100644 (file)
@@ -64,18 +64,11 @@ my %floatingPointTypeHash = (
     "unrestricted double" => 1,
 );
 
-my %primitiveTypeHash = ( "boolean" => 1, "void" => 1, "Date" => 1 );
-
-# WebCore types used directly in IDL files.
-my %webCoreTypeHash = (
-    "Dictionary" => 1,
-    "SerializedScriptValue" => 1,
+my %stringTypeHash = (
+    "DOMString" => 1,
+    "USVString" => 1,
 );
 
-my %dictionaryTypeImplementationNameOverrides = ();
-my %enumTypeImplementationNameOverrides = ();
-
-
 my %typedArrayTypes = (
     "ArrayBuffer" => 1,
     "ArrayBufferView" => 1,
@@ -91,6 +84,21 @@ my %typedArrayTypes = (
     "Uint8ClampedArray" => 1,
 );
 
+my %primitiveTypeHash = ( 
+    "boolean" => 1, 
+    "void" => 1,
+    "Date" => 1
+);
+
+# WebCore types used directly in IDL files.
+my %webCoreTypeHash = (
+    "Dictionary" => 1,
+    "SerializedScriptValue" => 1,
+);
+
+my %dictionaryTypeImplementationNameOverrides = ();
+my %enumTypeImplementationNameOverrides = ();
+
 my %svgAttributesInHTMLHash = (
     "class" => 1,
     "id" => 1,
@@ -209,6 +217,17 @@ sub ProcessDocument
         return;
     }
 
+    my $callbackFunctions = $useDocument->callbackFunctions;
+    if (@$callbackFunctions) {
+        die "Multiple standalone callback functions per document are not supported" if @$callbackFunctions > 1;
+
+        my $callbackFunction = @$callbackFunctions[0];
+        print "Generating $useGenerator bindings code for IDL callback function \"" . $callbackFunction->type->name . "\"...\n" if $verbose;
+        $codeGenerator->GenerateCallbackFunction($callbackFunction, $useDocument->enumerations, $useDocument->dictionaries);
+        $codeGenerator->WriteData($callbackFunction, $useOutputDir, $useOutputHeadersDir);
+        return;
+    }
+
     my $dictionaries = $useDocument->dictionaries;
     if (@$dictionaries) {
         die "Multiple standalone dictionaries per document are not supported" if @$dictionaries > 1;
@@ -364,8 +383,7 @@ sub SkipIncludeHeader
     return 1 if $integerTypeHash{$typeName};
     return 1 if $floatingPointTypeHash{$typeName};
     return 1 if $typedArrayTypes{$typeName};
-    return 1 if $typeName eq "DOMString";
-    return 1 if $typeName eq "USVString";
+    return 1 if $stringTypeHash{$typeName};
     return 1 if $typeName eq "BufferSource";
     return 1 if $typeName eq "SVGNumber";
     return 1 if $typeName eq "any";
@@ -426,15 +444,13 @@ sub IsPrimitiveType
     return 0;
 }
 
-# Currently used outside WebKit in an internal Apple project; can be removed soon.
 sub IsStringType
 {
     my ($object, $type) = @_;
 
     assert("Not a type") if ref($type) ne "IDLType";
 
-    return 1 if $type->name eq "DOMString";
-    return 1 if $type->name eq "USVString";
+    return 1 if $stringTypeHash{$type->name};
     return 0;
 }
 
@@ -1031,16 +1047,13 @@ sub IsCallbackInterface
     return $result;
 }
 
-# Callback interface with [Callback=FunctionOnly].
-# FIXME: This should be a callback function:
-# https://heycam.github.io/webidl/#idl-callback-functions
-sub ComputeIsFunctionOnlyCallbackInterface
+sub ComputeIsCallbackFunction
 {
     my ($object, $type) = @_;
 
     assert("Not a type") if ref($type) ne "IDLType";
 
-    return 0 unless $object->IsCallbackInterface($type);
+    return 0 unless $object->IsWrapperType($type);
 
     my $typeName = $type->name;
     my $idlFile = $object->IDLFileForInterface($typeName) or assert("Could NOT find IDL file for interface \"$typeName\"!\n");
@@ -1050,25 +1063,12 @@ sub ComputeIsFunctionOnlyCallbackInterface
     close FILE;
 
     my $fileContents = join('', @lines);
-    if ($fileContents =~ /\[(.*)\]\s+callback\s+interface\s+(\w+)/gs) {
-        my @parts = split(',', $1);
-        foreach my $part (@parts) {
-            my @keyValue = split('=', $part);
-            my $key = trim($keyValue[0]);
-            next unless length($key);
-            my $value = "VALUE_IS_MISSING";
-            $value = trim($keyValue[1]) if @keyValue > 1;
-
-            return 1 if ($key eq "Callback" && $value eq "FunctionOnly");
-        }
-    }
-
-    return 0;
+    return ($fileContents =~ /(.*)callback\s+(\w+)\s+=/gs);
 }
 
-my %isFunctionOnlyCallbackInterface = ();
+my %isCallbackFunction = ();
 
-sub IsFunctionOnlyCallbackInterface
+sub IsCallbackFunction
 {
     # FIXME: It's bad to have a function like this that opens another IDL file to answer a question.
     # Overusing this kind of function can make things really slow. Lets avoid these if we can.
@@ -1078,9 +1078,9 @@ sub IsFunctionOnlyCallbackInterface
 
     assert("Not a type") if ref($type) ne "IDLType";
 
-    return $isFunctionOnlyCallbackInterface{$type->name} if exists $isFunctionOnlyCallbackInterface{$type->name};
-    my $result = $object->ComputeIsFunctionOnlyCallbackInterface($type);
-    $isFunctionOnlyCallbackInterface{$type->name} = $result;
+    return $isCallbackFunction{$type->name} if exists $isCallbackFunction{$type->name};
+    my $result = $object->ComputeIsCallbackFunction($type);
+    $isCallbackFunction{$type->name} = $result;
     return $result;
 }
 
index ca6b002..b3686cb 100644 (file)
@@ -150,6 +150,14 @@ sub GenerateDictionary
     $object->GenerateDictionaryImplementation($dictionary, $className, $enumerations);
 }
 
+sub GenerateCallbackFunction
+{
+    my ($object, $callbackFunction, $enumerations, $dictionaries) = @_;
+
+    $object->GenerateCallbackFunctionHeader($callbackFunction, $enumerations, $dictionaries);
+    $object->GenerateCallbackFunctionImplementation($callbackFunction, $enumerations, $dictionaries);
+}
+
 sub GenerateInterface
 {
     my ($object, $interface, $defines, $enumerations, $dictionaries) = @_;
@@ -158,8 +166,8 @@ sub GenerateInterface
     AddStringifierOperationIfNeeded($interface);
 
     if ($interface->isCallback) {
-        $object->GenerateCallbackHeader($interface, $enumerations, $dictionaries);
-        $object->GenerateCallbackImplementation($interface, $enumerations, $dictionaries);
+        $object->GenerateCallbackInterfaceHeader($interface, $enumerations, $dictionaries);
+        $object->GenerateCallbackInterfaceImplementation($interface, $enumerations, $dictionaries);
     } else {
         $object->GenerateHeader($interface, $enumerations, $dictionaries);
         $object->GenerateImplementation($interface, $enumerations, $dictionaries);
@@ -222,9 +230,9 @@ sub GetCallbackClassName
 
 sub GetJSCallbackDataType
 {
-    my $callbackInterface = shift;
+    my $callback = shift;
 
-    return $callbackInterface->extendedAttributes->{IsWeakCallback} ? "JSCallbackDataWeak" : "JSCallbackDataStrong";
+    return $callback->extendedAttributes->{IsWeakCallback} ? "JSCallbackDataWeak" : "JSCallbackDataStrong";
 }
 
 sub GetExportMacroForJSClass
@@ -261,6 +269,13 @@ sub AddIncludesForImplementationType
 sub AddToImplIncludesForIDLType
 {
     my ($type, $conditional) = @_;
+
+    return AddToIncludesForIDLType($type, \%implIncludes, $conditional)
+}
+
+sub AddToIncludesForIDLType
+{
+    my ($type, $includesRef, $conditional) = @_;
     
     return if $codeGenerator->IsPrimitiveType($type);
     return if $codeGenerator->IsStringType($type);
@@ -269,49 +284,55 @@ sub AddToImplIncludesForIDLType
     return if $type->name eq "any";
 
     if ($type->isUnion) {
-        AddToImplIncludes("<wtf/Variant.h>", $conditional);
+        AddToIncludes("<wtf/Variant.h>", $includesRef, $conditional);
 
         foreach my $memberType (@{$type->subtypes}) {
-            AddToImplIncludesForIDLType($memberType, $conditional);
+            AddToIncludesForIDLType($memberType, $includesRef, $conditional);
         }
 
         return;
     }
 
     if ($codeGenerator->IsSequenceOrFrozenArrayType($type)) {
-        AddToImplIncludes("<runtime/JSArray.h>", $conditional);
-        AddToImplIncludesForIDLType(@{$type->subtypes}[0], $conditional);
+        AddToIncludes("<runtime/JSArray.h>", $includesRef, $conditional);
+        AddToIncludesForIDLType(@{$type->subtypes}[0], $includesRef, $conditional);
         return;
     }
 
     if ($codeGenerator->IsWrapperType($type) || $codeGenerator->IsExternalDictionaryType($type) || $codeGenerator->IsExternalEnumType($type)) {
-        AddToImplIncludes("JS" . $type->name . ".h", $conditional);
+        AddToIncludes("JS" . $type->name . ".h", $includesRef, $conditional);
         return;
     }
     
     if ($type->name eq "SerializedScriptValue") {
-        AddToImplIncludes("SerializedScriptValue.h", $conditional);
+        AddToIncludes("SerializedScriptValue.h", $includesRef, $conditional);
         return;
     }
 
     if ($type->name eq "Dictionary") {
-        AddToImplIncludes("Dictionary.h", $conditional);
+        AddToIncludes("Dictionary.h", $includesRef, $conditional);
         return;
     }
 }
 
 sub AddToImplIncludes
 {
-    my $header = shift;
-    my $conditional = shift;
+    my ($header, $conditional) = @_;
+
+    AddToIncludes($header, \%implIncludes, $conditional);
+}
+
+sub AddToIncludes
+{
+    my ($header, $includesRef, $conditional) = @_;
 
     if (not $conditional) {
-        $implIncludes{$header} = 1;
-    } elsif (not exists($implIncludes{$header})) {
-        $implIncludes{$header} = $conditional;
+        $includesRef->{$header} = 1;
+    } elsif (not exists($includesRef->{$header})) {
+        $includesRef->{$header} = $conditional;
     } else {
-        my $oldValue = $implIncludes{$header};
-        $implIncludes{$header} = "$oldValue|$conditional" if $oldValue ne 1;
+        my $oldValue = $includesRef->{$header};
+        $includesRef->{$header} = "$oldValue|$conditional" if $oldValue ne 1;
     }
 }
 
@@ -2028,7 +2049,7 @@ sub AreTypesDistinguishableForOverloadResolution
     };
     my $isCallbackFunctionOrDictionary = sub {
         my $type = shift;
-        return $codeGenerator->IsFunctionOnlyCallbackInterface($type) || &$isDictionary($type);
+        return $codeGenerator->IsCallbackFunction($type) || &$isDictionary($type);
     };
 
     # Two types are distinguishable for overload resolution if at most one of the two includes a nullable type.
@@ -2183,7 +2204,7 @@ sub GenerateOverloadedFunctionOrConstructor
     };
     my $isObjectOrCallbackFunctionParameter = sub {
         my ($type, $optionality) = @_;
-        return $type->name eq "object" || $codeGenerator->IsFunctionOnlyCallbackInterface($type);
+        return $type->name eq "object" || $codeGenerator->IsCallbackFunction($type);
     };
     my $isSequenceOrFrozenArrayParameter = sub {
         my ($type, $optionality) = @_;
@@ -2193,7 +2214,7 @@ sub GenerateOverloadedFunctionOrConstructor
         my ($type, $optionality) = @_;
         return 1 if &$isDictionaryParameter($type, $optionality);
         return 1 if $type->name eq "object";
-        return 1 if $codeGenerator->IsCallbackInterface($type) && !$codeGenerator->IsFunctionOnlyCallbackInterface($type);
+        return 1 if $codeGenerator->IsCallbackInterface($type) && !$codeGenerator->IsCallbackFunction($type);
         return 0;
     };
     my $isBooleanParameter = sub {
@@ -4444,20 +4465,20 @@ sub GenerateParametersCheck
             $argument->default("null") if $type->isNullable;
 
             # For callback arguments, the generated bindings treat undefined as null, so use null as implicit default value.
-            $argument->default("null") if $codeGenerator->IsCallbackInterface($type);
+            $argument->default("null") if $codeGenerator->IsCallbackInterface($type) || $codeGenerator->IsCallbackFunction($type);
         }
 
         my $name = $argument->name;
         my $value = $name;
 
-        if ($codeGenerator->IsCallbackInterface($type)) {
+        if ($codeGenerator->IsCallbackInterface($type) || $codeGenerator->IsCallbackFunction($type)) {
             my $callbackClassName = GetCallbackClassName($type->name);
             my $typeName = $type->name;
             $implIncludes{"$callbackClassName.h"} = 1;
             if ($argument->isOptional) {
                 push(@$outputArray, "    RefPtr<$typeName> $name;\n");
                 push(@$outputArray, "    if (!state->argument($argumentIndex).isUndefinedOrNull()) {\n");
-                if ($codeGenerator->IsFunctionOnlyCallbackInterface($type)) {
+                if ($codeGenerator->IsCallbackFunction($type)) {
                     push(@$outputArray, "        if (!state->uncheckedArgument($argumentIndex).isFunction())\n");
                 } else {
                     push(@$outputArray, "        if (!state->uncheckedArgument($argumentIndex).isObject())\n");
@@ -4472,7 +4493,7 @@ sub GenerateParametersCheck
                 push(@$outputArray, "    }\n");
             } else {
                 die "CallbackInterface does not support Variadic arguments" if $argument->isVariadic;
-                if ($codeGenerator->IsFunctionOnlyCallbackInterface($type)) {
+                if ($codeGenerator->IsCallbackFunction($type)) {
                     push(@$outputArray, "    if (UNLIKELY(!state->uncheckedArgument($argumentIndex).isFunction()))\n");
                 } else {
                     push(@$outputArray, "    if (UNLIKELY(!state->uncheckedArgument($argumentIndex).isObject()))\n");
@@ -4676,138 +4697,210 @@ sub GenerateDictionaryImplementation
     push(@implContent, "\n#endif // ${conditionalString}\n") if $conditionalString;
 }
 
-sub GenerateCallbackHeader
+sub GenerateCallbackFunctionHeader
 {
-    my ($object, $interface, $enumerations, $dictionaries) = @_;
+    my ($object, $callbackFunction, $enumerations, $dictionaries) = @_;
 
-    my $interfaceName = $interface->type->name;
-    my $className = "JS$interfaceName";
+    push(@headerContentHeader, GenerateHeaderContentHeader($callbackFunction));
 
-    # - Add default header template and header protection
-    push(@headerContentHeader, GenerateHeaderContentHeader($interface));
+    push(@headerContent, "\nnamespace WebCore {\n\n");
+
+    my @functions = ();
+    push(@functions, $callbackFunction->operation);
+    my @constants = ();
+
+    $object->GenerateCallbackHeaderContent($callbackFunction, \@functions, \@constants, \@headerContent, \%headerIncludes);
+
+    push(@headerContent, GenerateEnumerationsHeaderContent($callbackFunction, $enumerations));
+    push(@headerContent, GenerateDictionariesHeaderContent($callbackFunction, $dictionaries));
+
+    push(@headerContent, "} // namespace WebCore\n");
+
+    my $conditionalString = $codeGenerator->GenerateConditionalString($callbackFunction);
+    push(@headerContent, "\n#endif // ${conditionalString}\n") if $conditionalString;
+}
+
+sub GenerateCallbackFunctionImplementation
+{
+    my ($object, $callbackFunction, $enumerations, $dictionaries) = @_;
+
+    push(@implContentHeader, GenerateImplementationContentHeader($callbackFunction));
+
+    push(@implContent, "\nusing namespace JSC;\n\n");
+    push(@implContent, "namespace WebCore {\n\n");
 
-    $headerIncludes{"ActiveDOMCallback.h"} = 1;
-    $headerIncludes{"$interfaceName.h"} = 1;
-    $headerIncludes{"JSCallbackData.h"} = 1;
-    $headerIncludes{"<wtf/Forward.h>"} = 1;
+    push(@implContent, GenerateEnumerationsImplementationContent($callbackFunction, $enumerations));
+    push(@implContent, GenerateDictionariesImplementationContent($callbackFunction, $dictionaries));
+
+    my @functions = ();
+    push(@functions, $callbackFunction->operation);
+    my @constants = ();
+
+    $object->GenerateCallbackImplementationContent($callbackFunction, \@functions, \@constants, \@implContent, \%implIncludes);
+
+    push(@implContent, "} // namespace WebCore\n");
+
+    my $conditionalString = $codeGenerator->GenerateConditionalString($callbackFunction);
+    push(@implContent, "\n#endif // ${conditionalString}\n") if $conditionalString;
+}
+
+sub GenerateCallbackInterfaceHeader
+{
+    my ($object, $callbackInterface, $enumerations, $dictionaries) = @_;
+
+    push(@headerContentHeader, GenerateHeaderContentHeader($callbackInterface));
 
     push(@headerContent, "\nnamespace WebCore {\n\n");
-    push(@headerContent, "class $className : public $interfaceName, public ActiveDOMCallback {\n");
-    push(@headerContent, "public:\n");
+    
+    $object->GenerateCallbackHeaderContent($callbackInterface, $callbackInterface->functions, $callbackInterface->constants, \@headerContent, \%headerIncludes);
+
+    push(@headerContent, GenerateEnumerationsHeaderContent($callbackInterface, $enumerations));
+    push(@headerContent, GenerateDictionariesHeaderContent($callbackInterface, $dictionaries));
+
+    push(@headerContent, "} // namespace WebCore\n");
+
+    my $conditionalString = $codeGenerator->GenerateConditionalString($callbackInterface);
+    push(@headerContent, "\n#endif // ${conditionalString}\n") if $conditionalString;
+}
+
+sub GenerateCallbackInterfaceImplementation
+{
+    my ($object, $callbackInterface, $enumerations, $dictionaries) = @_;
+
+    push(@implContentHeader, GenerateImplementationContentHeader($callbackInterface));
+
+    push(@implContent, "\nusing namespace JSC;\n\n");
+    push(@implContent, "namespace WebCore {\n\n");
+
+    push(@implContent, GenerateEnumerationsImplementationContent($callbackInterface, $enumerations));
+    push(@implContent, GenerateDictionariesImplementationContent($callbackInterface, $dictionaries));
+
+    $object->GenerateCallbackImplementationContent($callbackInterface, $callbackInterface->functions, $callbackInterface->constants, \@implContent, \%implIncludes);
+
+    push(@implContent, "} // namespace WebCore\n");
+
+    my $conditionalString = $codeGenerator->GenerateConditionalString($callbackInterface);
+    push(@implContent, "\n#endif // ${conditionalString}\n") if $conditionalString;
+}
+
+sub GenerateCallbackHeaderContent
+{
+    my ($object, $interfaceOrCallback, $functions, $constants, $contentRef, $includesRef) = @_;
+
+    my $name = $interfaceOrCallback->type->name;
+    my $callbackDataType = GetJSCallbackDataType($interfaceOrCallback);
+    my $className = "JS${name}";
+
+    $includesRef->{"ActiveDOMCallback.h"} = 1;
+    $includesRef->{"JSCallbackData.h"} = 1;
+    $includesRef->{"<wtf/Forward.h>"} = 1;
+    $includesRef->{"${name}.h"} = 1;
+
+    push(@$contentRef, "class $className : public ${name}, public ActiveDOMCallback {\n");
+    push(@$contentRef, "public:\n");
 
     # The static create() method.
-    push(@headerContent, "    static Ref<$className> create(JSC::JSObject* callback, JSDOMGlobalObject* globalObject)\n");
-    push(@headerContent, "    {\n");
-    push(@headerContent, "        return adoptRef(*new $className(callback, globalObject));\n");
-    push(@headerContent, "    }\n\n");
+    push(@$contentRef, "    static Ref<$className> create(JSC::JSObject* callback, JSDOMGlobalObject* globalObject)\n");
+    push(@$contentRef, "    {\n");
+    push(@$contentRef, "        return adoptRef(*new ${className}(callback, globalObject));\n");
+    push(@$contentRef, "    }\n\n");
 
-    push(@headerContent, "    virtual ScriptExecutionContext* scriptExecutionContext() const { return ContextDestructionObserver::scriptExecutionContext(); }\n\n");
+    push(@$contentRef, "    virtual ScriptExecutionContext* scriptExecutionContext() const { return ContextDestructionObserver::scriptExecutionContext(); }\n\n");
 
-    push(@headerContent, "    virtual ~$className();\n");
+    push(@$contentRef, "    virtual ~$className();\n");
 
-    push(@headerContent, "    " . GetJSCallbackDataType($interface) . "* callbackData() { return m_data; }\n");
+    push(@$contentRef, "    ${callbackDataType}* callbackData() { return m_data; }\n");
 
-    push(@headerContent, "    static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*);\n") if @{$interface->constants};
+    push(@$contentRef, "    static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*);\n") if @{$constants};
 
-    push(@headerContent, "    virtual bool operator==(const $interfaceName&) const;\n\n") if $interface->extendedAttributes->{CallbackNeedsOperatorEqual};
+    push(@$contentRef, "    virtual bool operator==(const ${name}&) const;\n\n") if $interfaceOrCallback->extendedAttributes->{CallbackNeedsOperatorEqual};
 
     # Functions
-    my $numFunctions = @{$interface->functions};
+    my $numFunctions = @{$functions};
     if ($numFunctions > 0) {
-        push(@headerContent, "\n    // Functions\n");
-        foreach my $function (@{$interface->functions}) {
+        push(@$contentRef, "\n    // Functions\n");
+        foreach my $function (@{$functions}) {
             my @arguments = ();
             foreach my $argument (@{$function->arguments}) {
-                push(@arguments, GetNativeTypeForCallbacks($interface, $argument->type) . " " . $argument->name);
+                push(@arguments, GetNativeTypeForCallbacks($argument->type, $interfaceOrCallback) . " " . $argument->name);
             }
-            push(@headerContent, "    virtual " . GetNativeTypeForCallbacks($interface, $function->type) . " " . $function->name . "(" . join(", ", @arguments) . ");\n");
+
+            # FIXME: Add support for non-void return types (the bool actually is returning exception state), for non-custom functions.
+            my $nativeReturnType = $function->extendedAttributes->{Custom} ? GetNativeTypeForCallbacks($function->type, $interfaceOrCallback) : "bool";
+            
+            # FIXME: Change the default name (used for callback functions) to something other than handleEvent. It makes little sense.
+            my $functionName = $function->name ? $function->name : "handleEvent";
+
+            push(@$contentRef, "    virtual ${nativeReturnType} ${functionName}(" . join(", ", @arguments) . ");\n");
         }
     }
 
-    push(@headerContent, "\nprivate:\n");
+    push(@$contentRef, "\nprivate:\n");
 
     # Constructor
-    push(@headerContent, "    $className(JSC::JSObject* callback, JSDOMGlobalObject*);\n\n");
+    push(@$contentRef, "    $className(JSC::JSObject* callback, JSDOMGlobalObject*);\n\n");
 
     # Private members
-    push(@headerContent, "    " . GetJSCallbackDataType($interface) . "* m_data;\n");
-    push(@headerContent, "};\n\n");
+    push(@$contentRef, "    ${callbackDataType}* m_data;\n");
+    push(@$contentRef, "};\n\n");
 
     # toJS().
-    push(@headerContent, "JSC::JSValue toJS(JSC::ExecState*, JSDOMGlobalObject*, $interfaceName&);\n");
-    push(@headerContent, "inline JSC::JSValue toJS(JSC::ExecState* state, JSDOMGlobalObject* globalObject, $interfaceName* impl) { return impl ? toJS(state, globalObject, *impl) : JSC::jsNull(); }\n\n");
-
-    push(@headerContent, GenerateEnumerationsHeaderContent($interface, $enumerations));
-    push(@headerContent, GenerateDictionariesHeaderContent($interface, $dictionaries));
-
-    push(@headerContent, "} // namespace WebCore\n");
-
-    my $conditionalString = $codeGenerator->GenerateConditionalString($interface);
-    push(@headerContent, "\n#endif // ${conditionalString}\n") if $conditionalString;
+    push(@$contentRef, "JSC::JSValue toJS(JSC::ExecState*, JSDOMGlobalObject*, ${name}&);\n");
+    push(@$contentRef, "inline JSC::JSValue toJS(JSC::ExecState* state, JSDOMGlobalObject* globalObject, ${name}* impl) { return impl ? toJS(state, globalObject, *impl) : JSC::jsNull(); }\n\n");
 }
 
-sub GenerateCallbackImplementation
+sub GenerateCallbackImplementationContent
 {
-    my ($object, $interface, $enumerations, $dictionaries) = @_;
-
-    my $interfaceName = $interface->type->name;
-    my $visibleInterfaceName = $codeGenerator->GetVisibleInterfaceName($interface);
-    my $className = "JS$interfaceName";
+    my ($object, $interfaceOrCallback, $functions, $constants, $contentRef, $includesRef) = @_;
 
-    # - Add default header template
-    push(@implContentHeader, GenerateImplementationContentHeader($interface));
-
-    $implIncludes{"ScriptExecutionContext.h"} = 1;
-    $implIncludes{"<runtime/JSLock.h>"} = 1;
-
-    @implContent = ();
-
-    push(@implContent, "\nusing namespace JSC;\n\n");
-    push(@implContent, "namespace WebCore {\n\n");
+    my $name = $interfaceOrCallback->type->name;
+    my $callbackDataType = GetJSCallbackDataType($interfaceOrCallback);
+    my $visibleName = $codeGenerator->GetVisibleInterfaceName($interfaceOrCallback);
+    my $className = "JS${name}";
 
-    push(@implContent, GenerateEnumerationsImplementationContent($interface, $enumerations));
-    push(@implContent, GenerateDictionariesImplementationContent($interface, $dictionaries));
+    $includesRef->{"ScriptExecutionContext.h"} = 1;
+    $includesRef->{"<runtime/JSLock.h>"} = 1;
 
     # Constructor
-    push(@implContent, "${className}::${className}(JSObject* callback, JSDOMGlobalObject* globalObject)\n");
-    if ($interface->extendedAttributes->{CallbackNeedsOperatorEqual}) {
-        push(@implContent, "    : ${interfaceName}(${className}Type)\n");
+    push(@$contentRef, "${className}::${className}(JSObject* callback, JSDOMGlobalObject* globalObject)\n");
+    if ($interfaceOrCallback->extendedAttributes->{CallbackNeedsOperatorEqual}) {
+        push(@$contentRef, "    : ${name}(${className}Type)\n");
     } else {
-        push(@implContent, "    : ${interfaceName}()\n");
+        push(@$contentRef, "    : ${name}()\n");
     }
-    push(@implContent, "    , ActiveDOMCallback(globalObject->scriptExecutionContext())\n");
-    push(@implContent, "    , m_data(new " . GetJSCallbackDataType($interface) . "(callback, this))\n");
-    push(@implContent, "{\n");
-    push(@implContent, "}\n\n");
+    push(@$contentRef, "    , ActiveDOMCallback(globalObject->scriptExecutionContext())\n");
+    push(@$contentRef, "    , m_data(new ${callbackDataType}(callback, this))\n");
+    push(@$contentRef, "{\n");
+    push(@$contentRef, "}\n\n");
 
     # Destructor
-    push(@implContent, "${className}::~${className}()\n");
-    push(@implContent, "{\n");
-    push(@implContent, "    ScriptExecutionContext* context = scriptExecutionContext();\n");
-    push(@implContent, "    // When the context is destroyed, all tasks with a reference to a callback\n");
-    push(@implContent, "    // should be deleted. So if the context is 0, we are on the context thread.\n");
-    push(@implContent, "    if (!context || context->isContextThread())\n");
-    push(@implContent, "        delete m_data;\n");
-    push(@implContent, "    else\n");
-    push(@implContent, "        context->postTask(DeleteCallbackDataTask(m_data));\n");
-    push(@implContent, "#ifndef NDEBUG\n");
-    push(@implContent, "    m_data = nullptr;\n");
-    push(@implContent, "#endif\n");
-    push(@implContent, "}\n\n");
-
-    if ($interface->extendedAttributes->{CallbackNeedsOperatorEqual}) {
-        push(@implContent, "bool ${className}::operator==(const ${interfaceName}& other) const\n");
-        push(@implContent, "{\n");
-        push(@implContent, "    if (other.type() != type())\n");
-        push(@implContent, "        return false;\n");
-        push(@implContent, "    return static_cast<const ${className}*>(&other)->m_data->callback() == m_data->callback();\n");
-        push(@implContent, "}\n\n");
+    push(@$contentRef, "${className}::~${className}()\n");
+    push(@$contentRef, "{\n");
+    push(@$contentRef, "    ScriptExecutionContext* context = scriptExecutionContext();\n");
+    push(@$contentRef, "    // When the context is destroyed, all tasks with a reference to a callback\n");
+    push(@$contentRef, "    // should be deleted. So if the context is 0, we are on the context thread.\n");
+    push(@$contentRef, "    if (!context || context->isContextThread())\n");
+    push(@$contentRef, "        delete m_data;\n");
+    push(@$contentRef, "    else\n");
+    push(@$contentRef, "        context->postTask(DeleteCallbackDataTask(m_data));\n");
+    push(@$contentRef, "#ifndef NDEBUG\n");
+    push(@$contentRef, "    m_data = nullptr;\n");
+    push(@$contentRef, "#endif\n");
+    push(@$contentRef, "}\n\n");
+
+    if ($interfaceOrCallback->extendedAttributes->{CallbackNeedsOperatorEqual}) {
+        push(@$contentRef, "bool ${className}::operator==(const ${name}& other) const\n");
+        push(@$contentRef, "{\n");
+        push(@$contentRef, "    if (other.type() != type())\n");
+        push(@$contentRef, "        return false;\n");
+        push(@$contentRef, "    return static_cast<const ${className}*>(&other)->m_data->callback() == m_data->callback();\n");
+        push(@$contentRef, "}\n\n");
     }
 
     # Constants.
-    my $numConstants = @{$interface->constants};
+    my $numConstants = @{$constants};
     if ($numConstants > 0) {
-        GenerateConstructorDeclaration(\@implContent, $className, $interface, $interfaceName);
+        GenerateConstructorDeclaration($contentRef, $className, $interfaceOrCallback, $name);
 
         my $hashSize = 0;
         my $hashName = $className . "ConstructorTable";
@@ -4818,7 +4911,7 @@ sub GenerateCallbackImplementation
         my @hashSpecials = ();
         my %conditionals = ();
 
-        foreach my $constant (@{$interface->constants}) {
+        foreach my $constant (@{$constants}) {
             my $name = $constant->name;
             push(@hashKeys, $name);
             push(@hashValue1, $constant->value);
@@ -4835,93 +4928,71 @@ sub GenerateCallbackImplementation
         }
         $object->GenerateHashTable($hashName, $hashSize, \@hashKeys, \@hashSpecials, \@hashValue1, \@hashValue2, \%conditionals, 1) if $hashSize > 0;
 
-        push(@implContent, $codeGenerator->GenerateCompileTimeCheckForEnumsIfNeeded($interface));
+        push(@$contentRef, $codeGenerator->GenerateCompileTimeCheckForEnumsIfNeeded($interfaceOrCallback));
 
-        GenerateConstructorDefinitions(\@implContent, $className, "", $visibleInterfaceName, $interface);
+        GenerateConstructorDefinitions($contentRef, $className, "", $visibleName, $interfaceOrCallback);
 
-        push(@implContent, "JSValue ${className}::getConstructor(VM& vm, const JSGlobalObject* globalObject)\n{\n");
-        push(@implContent, "    return getDOMConstructor<${className}Constructor>(vm, *jsCast<const JSDOMGlobalObject*>(globalObject));\n");
-        push(@implContent, "}\n\n");
+        push(@$contentRef, "JSValue ${className}::getConstructor(VM& vm, const JSGlobalObject* globalObject)\n{\n");
+        push(@$contentRef, "    return getDOMConstructor<${className}Constructor>(vm, *jsCast<const JSDOMGlobalObject*>(globalObject));\n");
+        push(@$contentRef, "}\n\n");
     }
 
     # Functions.
-    my $numFunctions = @{$interface->functions};
+    my $numFunctions = @{$functions};
     if ($numFunctions > 0) {
-        push(@implContent, "\n// Functions\n");
-        foreach my $function (@{$interface->functions}) {
-            my @params = @{$function->arguments};
-            if ($function->extendedAttributes->{Custom} || GetNativeType($interface, $function->type) ne "bool") {
-                next;
-            }
+        foreach my $function (@{$functions}) {
+            next if $function->extendedAttributes->{Custom};
+        
+            assert("Unsupport return type: " . $function->type->name . ".") unless $function->type->name eq "void";
 
-            AddToImplIncludesForIDLType($function->type);
-            my $functionName = $function->name;
-            push(@implContent, "\n" . GetNativeTypeForCallbacks($interface, $function->type) . " ${className}::${functionName}(");
+            AddToIncludesForIDLType($function->type, $includesRef);
+            
+            # FIXME: Change the default name (used for callback functions) to something other than handleEvent. It makes little sense.
+            my $functionName = $function->name ? $function->name : "handleEvent";
 
             my @args = ();
-            my @argsCheck = ();
-            foreach my $param (@params) {
-                my $paramName = $param->name;
-                AddToImplIncludesForIDLType($param->type, 1);
-                push(@args, GetNativeTypeForCallbacks($interface, $param->type) . " " . $paramName);
+            foreach my $argument (@{$function->arguments}) {
+                AddToIncludesForIDLType($argument->type, $includesRef, 1);
+                push(@args, GetNativeTypeForCallbacks($argument->type, $interfaceOrCallback) . " " . $argument->name);
             }
-            push(@implContent, join(", ", @args));
-            push(@implContent, ")\n");
+            push(@$contentRef, "bool ${className}::${functionName}(" . join(", ", @args) . ")\n");
+            push(@$contentRef, "{\n");
+            push(@$contentRef, "    if (!canInvokeCallback())\n");
+            push(@$contentRef, "        return true;\n\n");
+            push(@$contentRef, "    Ref<$className> protectedThis(*this);\n\n");
+            push(@$contentRef, "    JSLockHolder lock(m_data->globalObject()->vm());\n\n");
+            push(@$contentRef, "    ExecState* state = m_data->globalObject()->globalExec();\n");
+            push(@$contentRef, "    MarkedArgumentBuffer args;\n");
 
-            push(@implContent, "{\n");
-            push(@implContent, @argsCheck) if @argsCheck;
-            push(@implContent, "    if (!canInvokeCallback())\n");
-            push(@implContent, "        return true;\n\n");
-            push(@implContent, "    Ref<$className> protectedThis(*this);\n\n");
-            push(@implContent, "    JSLockHolder lock(m_data->globalObject()->vm());\n\n");
-            push(@implContent, "    ExecState* state = m_data->globalObject()->globalExec();\n");
-            push(@implContent, "    MarkedArgumentBuffer args;\n");
-
-            foreach my $param (@params) {
-                my $paramName = $param->name;
-                push(@implContent, "    args.append(" . NativeToJSValueUsingPointers($param, 1, $interface, $paramName, "m_data") . ");\n");
+            foreach my $argument (@{$function->arguments}) {
+                push(@$contentRef, "    args.append(" . NativeToJSValueUsingPointers($argument, 1, $interfaceOrCallback, $argument->name, "m_data") . ");\n");
             }
 
-            push(@implContent, "\n    NakedPtr<JSC::Exception> returnedException;\n");
+            push(@$contentRef, "\n    NakedPtr<JSC::Exception> returnedException;\n");
 
-            my $propertyToLookup = "Identifier::fromString(state, \"${functionName}\")";
-            my $invokeMethod = "JSCallbackData::CallbackType::FunctionOrObject";
-            if ($codeGenerator->ExtendedAttributeContains($interface->extendedAttributes->{Callback}, "FunctionOnly")) {
-                # For callback functions, do not look up callable property on the user object.
-                # https://heycam.github.io/webidl/#es-callback-function
-                $invokeMethod = "JSCallbackData::CallbackType::Function";
-                $propertyToLookup = "Identifier()";
-                push(@implContent, "    UNUSED_PARAM(state);\n");
-            } elsif ($numFunctions > 1) {
-                # The callback interface has more than one operation so we should not call the user object as a function.
-                # instead, we should look for a property with the same name as the operation on the user object.
-                # https://heycam.github.io/webidl/#es-user-objects
-                $invokeMethod = "JSCallbackData::CallbackType::Object";
+            if (ref($interfaceOrCallback) eq "IDLCallbackFunction") {
+                push(@$contentRef, "    m_data->invokeCallback(args, JSCallbackData::CallbackType::Function, Identifier(), returnedException);\n");
+            } else {
+                my $callbackType = $numFunctions > 1 ? "Object" : "FunctionOrObject";
+                push(@$contentRef, "    m_data->invokeCallback(args, JSCallbackData::CallbackType::${callbackType}, Identifier::fromString(state, \"${functionName}\"), returnedException);\n");
             }
-            push(@implContent, "    m_data->invokeCallback(args, $invokeMethod, $propertyToLookup, returnedException);\n");
 
             # FIXME: We currently just report the exception. We should probably add an extended attribute to indicate when
             # we want the exception to be rethrown instead.
-            push(@implContent, "    if (returnedException)\n");
-            push(@implContent, "        reportException(state, returnedException);\n");
-            push(@implContent, "    return !returnedException;\n");
-            push(@implContent, "}\n");
+            push(@$contentRef, "    if (returnedException)\n");
+            push(@$contentRef, "        reportException(state, returnedException);\n");
+            push(@$contentRef, "    return !returnedException;\n");
+            push(@$contentRef, "}\n\n");
         }
     }
 
     # toJS() implementation.
-    push(@implContent, "\nJSC::JSValue toJS(JSC::ExecState*, JSDOMGlobalObject*, $interfaceName& impl)\n");
-    push(@implContent, "{\n");
-    push(@implContent, "    if (!static_cast<${className}&>(impl).callbackData())\n");
-    push(@implContent, "        return jsNull();\n\n");
-    push(@implContent, "    return static_cast<${className}&>(impl).callbackData()->callback();\n\n");
-    push(@implContent, "}\n");
-
-    push(@implContent, "\n}\n");
-    my $conditionalString = $codeGenerator->GenerateConditionalString($interface);
-    push(@implContent, "\n#endif // ${conditionalString}\n") if $conditionalString;
-
-    push(@implContent, split("\r", $endAppleCopyright)) if $interface->extendedAttributes->{AppleCopyright};
+    push(@$contentRef, "JSC::JSValue toJS(JSC::ExecState*, JSDOMGlobalObject*, ${name}& impl)\n");
+    push(@$contentRef, "{\n");
+    push(@$contentRef, "    if (!static_cast<${className}&>(impl).callbackData())\n");
+    push(@$contentRef, "        return jsNull();\n\n");
+    push(@$contentRef, "    return static_cast<${className}&>(impl).callbackData()->callback();\n\n");
+    push(@$contentRef, "}\n\n");
 }
 
 sub GenerateImplementationFunctionCall()
@@ -5282,7 +5353,7 @@ sub ShouldPassWrapperByReference
 {
     my ($parameter, $interface) = @_;
 
-    return 0 if $codeGenerator->IsCallbackInterface($parameter->type);
+    return 0 if $codeGenerator->IsCallbackInterface($parameter->type) || $codeGenerator->IsCallbackFunction($parameter->type);
 
     my $nativeType = GetNativeType($interface, $parameter->type);
     return $codeGenerator->ShouldPassWrapperByReference($parameter) && (substr($nativeType, -1) eq '*' || $nativeType =~ /^RefPtr/);
@@ -5300,7 +5371,7 @@ sub GetNativeVectorInnerType
 
 sub GetNativeTypeForCallbacks
 {
-    my ($interface, $type) = @_;
+    my ($type, $interface) = @_;
 
     return "RefPtr<SerializedScriptValue>&&" if $type->name eq "SerializedScriptValue";
     return "const String&" if $codeGenerator->IsStringType($type);
index 1398d94..defdbcd 100644 (file)
@@ -24,7 +24,6 @@ AtomicString
 CEReactions
 CachedAttribute
 CallbackNeedsOperatorEqual
-Callback=FunctionOnly
 CallWith=Document|ScriptExecutionContext|ScriptState|ScriptArguments|CallStack|ActiveWindow|FirstWindow|CallerDocument|CallerWindow
 CheckSecurity
 CheckSecurityForNode
index 11f91b4..3360f49 100644 (file)
@@ -41,6 +41,7 @@ struct( IDLDocument => {
     interfaces => '@', # List of 'IDLInterface'
     enumerations => '@', # List of 'IDLEnum'
     dictionaries => '@', # List of 'IDLDictionary'
+    callbackFunctions => '@', # List of 'IDLCallbackFunction'
     fileName => '$',
 });
 
@@ -135,7 +136,7 @@ struct( IDLEnum => {
     extendedAttributes => '$',
 });
 
-
+# https://heycam.github.io/webidl/#dfn-dictionary-member
 struct( IDLDictionaryMember => {
     name => '$',
     type => 'IDLType',
@@ -144,7 +145,6 @@ struct( IDLDictionaryMember => {
     extendedAttributes => '$',
 });
 
-
 # https://heycam.github.io/webidl/#idl-dictionaries
 struct( IDLDictionary => {
     type => 'IDLType',
@@ -153,7 +153,14 @@ struct( IDLDictionary => {
     extendedAttributes => '$',
 });
 
-# https://heycam.github.io/webidl/#idl-enums
+# https://heycam.github.io/webidl/#idl-callback-functions
+struct( IDLCallbackFunction => {
+    type => '$',
+    operation => 'IDLOperation',
+    extendedAttributes => '$',
+});
+
+# https://heycam.github.io/webidl/#idl-typedefs
 struct( IDLTypedef => {
     type => 'IDLType',
 });
@@ -276,6 +283,8 @@ sub Parse
             push(@{$document->enumerations}, $definition);
         } elsif (ref($definition) eq "IDLDictionary") {
             push(@{$document->dictionaries}, $definition);
+        } elsif (ref($definition) eq "IDLCallbackFunction") {
+            push(@{$document->callbackFunctions}, $definition);
         } else {
             die "Unrecognized IDL definition kind: \"" . ref($definition) . "\"";
         }
@@ -467,23 +476,33 @@ sub applyTypedefs
             foreach my $attribute (@{$definition->attributes}) {
                 $attribute->type($self->typeByApplyingTypedefs($attribute->type));
             }
-            foreach my $function (@{$definition->functions}, @{$definition->anonymousFunctions}, @{$definition->constructors}, @{$definition->customConstructors}) {
-                if ($function->type) {
-                    $function->type($self->typeByApplyingTypedefs($function->type));
-                }
-
-                foreach my $argument (@{$function->arguments}) {
-                    $argument->type($self->typeByApplyingTypedefs($argument->type));
-                }
+            foreach my $operation (@{$definition->functions}, @{$definition->anonymousFunctions}, @{$definition->constructors}, @{$definition->customConstructors}) {
+                $self->applyTypedefsToOperation($operation);
             }
         } elsif (ref($definition) eq "IDLDictionary") {
             foreach my $member (@{$definition->members}) {
                 $member->type($self->typeByApplyingTypedefs($member->type));
             }
+        } elsif (ref($definition) eq "IDLCallbackFunction") {
+            $self->applyTypedefsToOperation($definition->operation);
         }
     }
 }
 
+sub applyTypedefsToOperation
+{
+    my $self = shift;
+    my $operation = shift;
+
+    if ($operation->type) {
+        $operation->type($self->typeByApplyingTypedefs($operation->type));
+    }
+
+    foreach my $argument (@{$operation->arguments}) {
+        $argument->type($self->typeByApplyingTypedefs($argument->type));
+    }
+}
+
 sub typeByApplyingTypedefs
 {
     my $self = shift;
@@ -950,14 +969,30 @@ sub parseCallbackRest
 
     my $next = $self->nextToken();
     if ($next->type() == IdentifierToken) {
-        $self->assertTokenType($self->getToken(), IdentifierToken);
+        my $callback = IDLCallbackFunction->new();
+
+        my $nameToken = $self->getToken();
+        $self->assertTokenType($nameToken, IdentifierToken);
+
+        $callback->type(makeSimpleType($nameToken->value()));
+
         $self->assertTokenValue($self->getToken(), "=", __LINE__);
-        $self->parseReturnType();
+
+        my $operation = IDLOperation->new();
+        $operation->type($self->parseReturnType());
+        $operation->extendedAttributes($extendedAttributeList);
+
         $self->assertTokenValue($self->getToken(), "(", __LINE__);
-        $self->parseArgumentList();
+
+        push(@{$operation->arguments}, @{$self->parseArgumentList()});
+
         $self->assertTokenValue($self->getToken(), ")", __LINE__);
         $self->assertTokenValue($self->getToken(), ";", __LINE__);
-        return;
+
+        $callback->operation($operation);
+        $callback->extendedAttributes($extendedAttributeList);
+
+        return $callback;
     }
     $self->assertUnexpectedToken($next->value(), __LINE__);
 }
index e39776d..347952f 100644 (file)
@@ -25,7 +25,6 @@
 #include "JSTestCallbackFunction.h"
 
 #include "JSDOMConvert.h"
-#include "JSDOMStringList.h"
 #include "JSTestNode.h"
 #include "ScriptExecutionContext.h"
 #include "SerializedScriptValue.h"
@@ -56,30 +55,7 @@ JSTestCallbackFunction::~JSTestCallbackFunction()
 #endif
 }
 
-
-// Functions
-
-bool JSTestCallbackFunction::callbackWithNoParam()
-{
-    if (!canInvokeCallback())
-        return true;
-
-    Ref<JSTestCallbackFunction> protectedThis(*this);
-
-    JSLockHolder lock(m_data->globalObject()->vm());
-
-    ExecState* state = m_data->globalObject()->globalExec();
-    MarkedArgumentBuffer args;
-
-    NakedPtr<JSC::Exception> returnedException;
-    UNUSED_PARAM(state);
-    m_data->invokeCallback(args, JSCallbackData::CallbackType::Function, Identifier(), returnedException);
-    if (returnedException)
-        reportException(state, returnedException);
-    return !returnedException;
-}
-
-bool JSTestCallbackFunction::callbackWithArrayParam(RefPtr<Float32Array> arrayParam)
+bool JSTestCallbackFunction::handleEvent(RefPtr<Float32Array> arrayParam, RefPtr<SerializedScriptValue>&& srzParam, const String& strArg, bool boolParam, int32_t longParam, TestNode* testNodeParam)
 {
     if (!canInvokeCallback())
         return true;
@@ -91,95 +67,13 @@ bool JSTestCallbackFunction::callbackWithArrayParam(RefPtr<Float32Array> arrayPa
     ExecState* state = m_data->globalObject()->globalExec();
     MarkedArgumentBuffer args;
     args.append(toJS<IDLInterface<Float32Array>>(*state, *m_data->globalObject(), arrayParam));
-
-    NakedPtr<JSC::Exception> returnedException;
-    UNUSED_PARAM(state);
-    m_data->invokeCallback(args, JSCallbackData::CallbackType::Function, Identifier(), returnedException);
-    if (returnedException)
-        reportException(state, returnedException);
-    return !returnedException;
-}
-
-bool JSTestCallbackFunction::callbackWithSerializedScriptValueParam(RefPtr<SerializedScriptValue>&& srzParam, const String& strArg)
-{
-    if (!canInvokeCallback())
-        return true;
-
-    Ref<JSTestCallbackFunction> protectedThis(*this);
-
-    JSLockHolder lock(m_data->globalObject()->vm());
-
-    ExecState* state = m_data->globalObject()->globalExec();
-    MarkedArgumentBuffer args;
     args.append(srzParam ? srzParam->deserialize(*state, m_data->globalObject()) : jsNull());
     args.append(toJS<IDLDOMString>(*state, strArg));
-
-    NakedPtr<JSC::Exception> returnedException;
-    UNUSED_PARAM(state);
-    m_data->invokeCallback(args, JSCallbackData::CallbackType::Function, Identifier(), returnedException);
-    if (returnedException)
-        reportException(state, returnedException);
-    return !returnedException;
-}
-
-bool JSTestCallbackFunction::callbackWithStringList(DOMStringList* listParam)
-{
-    if (!canInvokeCallback())
-        return true;
-
-    Ref<JSTestCallbackFunction> protectedThis(*this);
-
-    JSLockHolder lock(m_data->globalObject()->vm());
-
-    ExecState* state = m_data->globalObject()->globalExec();
-    MarkedArgumentBuffer args;
-    args.append(toJS<IDLInterface<DOMStringList>>(*state, *m_data->globalObject(), listParam));
-
-    NakedPtr<JSC::Exception> returnedException;
-    UNUSED_PARAM(state);
-    m_data->invokeCallback(args, JSCallbackData::CallbackType::Function, Identifier(), returnedException);
-    if (returnedException)
-        reportException(state, returnedException);
-    return !returnedException;
-}
-
-bool JSTestCallbackFunction::callbackWithBoolean(bool boolParam)
-{
-    if (!canInvokeCallback())
-        return true;
-
-    Ref<JSTestCallbackFunction> protectedThis(*this);
-
-    JSLockHolder lock(m_data->globalObject()->vm());
-
-    ExecState* state = m_data->globalObject()->globalExec();
-    MarkedArgumentBuffer args;
     args.append(toJS<IDLBoolean>(boolParam));
-
-    NakedPtr<JSC::Exception> returnedException;
-    UNUSED_PARAM(state);
-    m_data->invokeCallback(args, JSCallbackData::CallbackType::Function, Identifier(), returnedException);
-    if (returnedException)
-        reportException(state, returnedException);
-    return !returnedException;
-}
-
-bool JSTestCallbackFunction::callbackRequiresThisToPass(int32_t longParam, TestNode* testNodeParam)
-{
-    if (!canInvokeCallback())
-        return true;
-
-    Ref<JSTestCallbackFunction> protectedThis(*this);
-
-    JSLockHolder lock(m_data->globalObject()->vm());
-
-    ExecState* state = m_data->globalObject()->globalExec();
-    MarkedArgumentBuffer args;
     args.append(toJS<IDLLong>(longParam));
     args.append(toJS<IDLInterface<TestNode>>(*state, *m_data->globalObject(), testNodeParam));
 
     NakedPtr<JSC::Exception> returnedException;
-    UNUSED_PARAM(state);
     m_data->invokeCallback(args, JSCallbackData::CallbackType::Function, Identifier(), returnedException);
     if (returnedException)
         reportException(state, returnedException);
@@ -195,6 +89,6 @@ JSC::JSValue toJS(JSC::ExecState*, JSDOMGlobalObject*, TestCallbackFunction& imp
 
 }
 
-}
+} // namespace WebCore
 
 #endif // ENABLE(SPEECH_SYNTHESIS)
index 6963609..dbb5298 100644 (file)
@@ -42,14 +42,7 @@ public:
     JSCallbackDataStrong* callbackData() { return m_data; }
 
     // Functions
-    virtual bool callbackWithNoParam();
-    virtual bool callbackWithArrayParam(RefPtr<Float32Array> arrayParam);
-    virtual bool callbackWithSerializedScriptValueParam(RefPtr<SerializedScriptValue>&& srzParam, const String& strArg);
-    virtual int32_t callbackWithNonBoolReturnType(const String& strArg);
-    virtual int32_t customCallback(Class5* class5Param, Class6* class6Param);
-    virtual bool callbackWithStringList(DOMStringList* listParam);
-    virtual bool callbackWithBoolean(bool boolParam);
-    virtual bool callbackRequiresThisToPass(int32_t longParam, TestNode* testNodeParam);
+    virtual bool handleEvent(RefPtr<Float32Array> arrayParam, RefPtr<SerializedScriptValue>&& srzParam, const String& strArg, bool boolParam, int32_t longParam, TestNode* testNodeParam);
 
 private:
     JSTestCallbackFunction(JSC::JSObject* callback, JSDOMGlobalObject*);
diff --git a/Source/WebCore/bindings/scripts/test/JS/JSTestCallbackFunctionWithTypedefs.cpp b/Source/WebCore/bindings/scripts/test/JS/JSTestCallbackFunctionWithTypedefs.cpp
new file mode 100644 (file)
index 0000000..701ec38
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+    This file is part of the WebKit open source project.
+    This file has been generated by generate-bindings.pl. DO NOT MODIFY!
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public License
+    along with this library; see the file COPYING.LIB.  If not, write to
+    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+    Boston, MA 02110-1301, USA.
+*/
+
+#include "config.h"
+#include "JSTestCallbackFunctionWithTypedefs.h"
+
+#include "JSDOMConvert.h"
+#include "JSLONG.h"
+#include "ScriptExecutionContext.h"
+#include <runtime/JSArray.h>
+#include <runtime/JSLock.h>
+
+using namespace JSC;
+
+namespace WebCore {
+
+JSTestCallbackFunctionWithTypedefs::JSTestCallbackFunctionWithTypedefs(JSObject* callback, JSDOMGlobalObject* globalObject)
+    : TestCallbackFunctionWithTypedefs()
+    , ActiveDOMCallback(globalObject->scriptExecutionContext())
+    , m_data(new JSCallbackDataStrong(callback, this))
+{
+}
+
+JSTestCallbackFunctionWithTypedefs::~JSTestCallbackFunctionWithTypedefs()
+{
+    ScriptExecutionContext* context = scriptExecutionContext();
+    // When the context is destroyed, all tasks with a reference to a callback
+    // should be deleted. So if the context is 0, we are on the context thread.
+    if (!context || context->isContextThread())
+        delete m_data;
+    else
+        context->postTask(DeleteCallbackDataTask(m_data));
+#ifndef NDEBUG
+    m_data = nullptr;
+#endif
+}
+
+bool JSTestCallbackFunctionWithTypedefs::handleEvent(Vector<RefPtr<LONG>> sequenceArg, int32_t longArg)
+{
+    if (!canInvokeCallback())
+        return true;
+
+    Ref<JSTestCallbackFunctionWithTypedefs> protectedThis(*this);
+
+    JSLockHolder lock(m_data->globalObject()->vm());
+
+    ExecState* state = m_data->globalObject()->globalExec();
+    MarkedArgumentBuffer args;
+    args.append(toJS<IDLSequence<IDLNullable<IDLInterface<LONG>>>>(*state, *m_data->globalObject(), sequenceArg));
+    args.append(toJS<IDLLong>(longArg));
+
+    NakedPtr<JSC::Exception> returnedException;
+    m_data->invokeCallback(args, JSCallbackData::CallbackType::Function, Identifier(), returnedException);
+    if (returnedException)
+        reportException(state, returnedException);
+    return !returnedException;
+}
+
+JSC::JSValue toJS(JSC::ExecState*, JSDOMGlobalObject*, TestCallbackFunctionWithTypedefs& impl)
+{
+    if (!static_cast<JSTestCallbackFunctionWithTypedefs&>(impl).callbackData())
+        return jsNull();
+
+    return static_cast<JSTestCallbackFunctionWithTypedefs&>(impl).callbackData()->callback();
+
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/bindings/scripts/test/JS/JSTestCallbackFunctionWithTypedefs.h b/Source/WebCore/bindings/scripts/test/JS/JSTestCallbackFunctionWithTypedefs.h
new file mode 100644 (file)
index 0000000..5681437
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+    This file is part of the WebKit open source project.
+    This file has been generated by generate-bindings.pl. DO NOT MODIFY!
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public License
+    along with this library; see the file COPYING.LIB.  If not, write to
+    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+    Boston, MA 02110-1301, USA.
+*/
+
+#pragma once
+
+#include "ActiveDOMCallback.h"
+#include "JSCallbackData.h"
+#include "TestCallbackFunctionWithTypedefs.h"
+#include <wtf/Forward.h>
+
+namespace WebCore {
+
+class JSTestCallbackFunctionWithTypedefs : public TestCallbackFunctionWithTypedefs, public ActiveDOMCallback {
+public:
+    static Ref<JSTestCallbackFunctionWithTypedefs> create(JSC::JSObject* callback, JSDOMGlobalObject* globalObject)
+    {
+        return adoptRef(*new JSTestCallbackFunctionWithTypedefs(callback, globalObject));
+    }
+
+    virtual ScriptExecutionContext* scriptExecutionContext() const { return ContextDestructionObserver::scriptExecutionContext(); }
+
+    virtual ~JSTestCallbackFunctionWithTypedefs();
+    JSCallbackDataStrong* callbackData() { return m_data; }
+
+    // Functions
+    virtual bool handleEvent(Vector<RefPtr<LONG>> sequenceArg, int32_t longArg);
+
+private:
+    JSTestCallbackFunctionWithTypedefs(JSC::JSObject* callback, JSDOMGlobalObject*);
+
+    JSCallbackDataStrong* m_data;
+};
+
+JSC::JSValue toJS(JSC::ExecState*, JSDOMGlobalObject*, TestCallbackFunctionWithTypedefs&);
+inline JSC::JSValue toJS(JSC::ExecState* state, JSDOMGlobalObject* globalObject, TestCallbackFunctionWithTypedefs* impl) { return impl ? toJS(state, globalObject, *impl) : JSC::jsNull(); }
+
+} // namespace WebCore
@@ -22,7 +22,7 @@
 
 #if ENABLE(SPEECH_SYNTHESIS)
 
-#include "JSTestCallback.h"
+#include "JSTestCallbackInterface.h"
 
 #include "JSDOMConstructor.h"
 #include "JSDOMConvert.h"
@@ -37,14 +37,14 @@ using namespace JSC;
 
 namespace WebCore {
 
-JSTestCallback::JSTestCallback(JSObject* callback, JSDOMGlobalObject* globalObject)
-    : TestCallback()
+JSTestCallbackInterface::JSTestCallbackInterface(JSObject* callback, JSDOMGlobalObject* globalObject)
+    : TestCallbackInterface()
     , ActiveDOMCallback(globalObject->scriptExecutionContext())
     , m_data(new JSCallbackDataStrong(callback, this))
 {
 }
 
-JSTestCallback::~JSTestCallback()
+JSTestCallbackInterface::~JSTestCallbackInterface()
 {
     ScriptExecutionContext* context = scriptExecutionContext();
     // When the context is destroyed, all tasks with a reference to a callback
@@ -58,49 +58,46 @@ JSTestCallback::~JSTestCallback()
 #endif
 }
 
-using JSTestCallbackConstructor = JSDOMConstructorNotConstructable<JSTestCallback>;
+using JSTestCallbackInterfaceConstructor = JSDOMConstructorNotConstructable<JSTestCallbackInterface>;
 
 /* Hash table for constructor */
 
-static const HashTableValue JSTestCallbackConstructorTableValues[] =
+static const HashTableValue JSTestCallbackInterfaceConstructorTableValues[] =
 {
     { "CONSTANT1", DontDelete | ReadOnly | ConstantInteger, NoIntrinsic, { (long long)(1) } },
     { "CONSTANT2", DontDelete | ReadOnly | ConstantInteger, NoIntrinsic, { (long long)(2) } },
 };
 
-static_assert(TestCallback::CONSTANT1 == 1, "CONSTANT1 in TestCallback does not match value from IDL");
-static_assert(TestCallback::CONSTANT2 == 2, "CONSTANT2 in TestCallback does not match value from IDL");
+static_assert(TestCallbackInterface::CONSTANT1 == 1, "CONSTANT1 in TestCallbackInterface does not match value from IDL");
+static_assert(TestCallbackInterface::CONSTANT2 == 2, "CONSTANT2 in TestCallbackInterface does not match value from IDL");
 
-template<> JSValue JSTestCallbackConstructor::prototypeForStructure(JSC::VM& vm, const JSDOMGlobalObject& globalObject)
+template<> JSValue JSTestCallbackInterfaceConstructor::prototypeForStructure(JSC::VM& vm, const JSDOMGlobalObject& globalObject)
 {
     UNUSED_PARAM(vm);
     return globalObject.objectPrototype();
 }
 
-template<> void JSTestCallbackConstructor::initializeProperties(VM& vm, JSDOMGlobalObject& globalObject)
+template<> void JSTestCallbackInterfaceConstructor::initializeProperties(VM& vm, JSDOMGlobalObject& globalObject)
 {
     UNUSED_PARAM(globalObject);
-    putDirect(vm, vm.propertyNames->name, jsNontrivialString(&vm, String(ASCIILiteral("TestCallback"))), ReadOnly | DontEnum);
+    putDirect(vm, vm.propertyNames->name, jsNontrivialString(&vm, String(ASCIILiteral("TestCallbackInterface"))), ReadOnly | DontEnum);
     putDirect(vm, vm.propertyNames->length, jsNumber(0), ReadOnly | DontEnum);
-    reifyStaticProperties(vm, JSTestCallbackConstructorTableValues, *this);
+    reifyStaticProperties(vm, JSTestCallbackInterfaceConstructorTableValues, *this);
 }
 
-template<> const ClassInfo JSTestCallbackConstructor::s_info = { "TestCallback", &Base::s_info, 0, CREATE_METHOD_TABLE(JSTestCallbackConstructor) };
+template<> const ClassInfo JSTestCallbackInterfaceConstructor::s_info = { "TestCallbackInterface", &Base::s_info, 0, CREATE_METHOD_TABLE(JSTestCallbackInterfaceConstructor) };
 
-JSValue JSTestCallback::getConstructor(VM& vm, const JSGlobalObject* globalObject)
+JSValue JSTestCallbackInterface::getConstructor(VM& vm, const JSGlobalObject* globalObject)
 {
-    return getDOMConstructor<JSTestCallbackConstructor>(vm, *jsCast<const JSDOMGlobalObject*>(globalObject));
+    return getDOMConstructor<JSTestCallbackInterfaceConstructor>(vm, *jsCast<const JSDOMGlobalObject*>(globalObject));
 }
 
-
-// Functions
-
-bool JSTestCallback::callbackWithNoParam()
+bool JSTestCallbackInterface::callbackWithNoParam()
 {
     if (!canInvokeCallback())
         return true;
 
-    Ref<JSTestCallback> protectedThis(*this);
+    Ref<JSTestCallbackInterface> protectedThis(*this);
 
     JSLockHolder lock(m_data->globalObject()->vm());
 
@@ -114,12 +111,12 @@ bool JSTestCallback::callbackWithNoParam()
     return !returnedException;
 }
 
-bool JSTestCallback::callbackWithArrayParam(RefPtr<Float32Array> arrayParam)
+bool JSTestCallbackInterface::callbackWithArrayParam(RefPtr<Float32Array> arrayParam)
 {
     if (!canInvokeCallback())
         return true;
 
-    Ref<JSTestCallback> protectedThis(*this);
+    Ref<JSTestCallbackInterface> protectedThis(*this);
 
     JSLockHolder lock(m_data->globalObject()->vm());
 
@@ -134,19 +131,19 @@ bool JSTestCallback::callbackWithArrayParam(RefPtr<Float32Array> arrayParam)
     return !returnedException;
 }
 
-bool JSTestCallback::callbackWithSerializedScriptValueParam(RefPtr<SerializedScriptValue>&& srzParam, const String& strArg)
+bool JSTestCallbackInterface::callbackWithSerializedScriptValueParam(RefPtr<SerializedScriptValue>&& srzParam, const String& strParam)
 {
     if (!canInvokeCallback())
         return true;
 
-    Ref<JSTestCallback> protectedThis(*this);
+    Ref<JSTestCallbackInterface> protectedThis(*this);
 
     JSLockHolder lock(m_data->globalObject()->vm());
 
     ExecState* state = m_data->globalObject()->globalExec();
     MarkedArgumentBuffer args;
     args.append(srzParam ? srzParam->deserialize(*state, m_data->globalObject()) : jsNull());
-    args.append(toJS<IDLDOMString>(*state, strArg));
+    args.append(toJS<IDLDOMString>(*state, strParam));
 
     NakedPtr<JSC::Exception> returnedException;
     m_data->invokeCallback(args, JSCallbackData::CallbackType::Object, Identifier::fromString(state, "callbackWithSerializedScriptValueParam"), returnedException);
@@ -155,12 +152,12 @@ bool JSTestCallback::callbackWithSerializedScriptValueParam(RefPtr<SerializedScr
     return !returnedException;
 }
 
-bool JSTestCallback::callbackWithStringList(DOMStringList* listParam)
+bool JSTestCallbackInterface::callbackWithStringList(DOMStringList* listParam)
 {
     if (!canInvokeCallback())
         return true;
 
-    Ref<JSTestCallback> protectedThis(*this);
+    Ref<JSTestCallbackInterface> protectedThis(*this);
 
     JSLockHolder lock(m_data->globalObject()->vm());
 
@@ -175,12 +172,12 @@ bool JSTestCallback::callbackWithStringList(DOMStringList* listParam)
     return !returnedException;
 }
 
-bool JSTestCallback::callbackWithBoolean(bool boolParam)
+bool JSTestCallbackInterface::callbackWithBoolean(bool boolParam)
 {
     if (!canInvokeCallback())
         return true;
 
-    Ref<JSTestCallback> protectedThis(*this);
+    Ref<JSTestCallbackInterface> protectedThis(*this);
 
     JSLockHolder lock(m_data->globalObject()->vm());
 
@@ -195,12 +192,12 @@ bool JSTestCallback::callbackWithBoolean(bool boolParam)
     return !returnedException;
 }
 
-bool JSTestCallback::callbackRequiresThisToPass(int32_t longParam, TestNode* testNodeParam)
+bool JSTestCallbackInterface::callbackRequiresThisToPass(int32_t longParam, TestNode* testNodeParam)
 {
     if (!canInvokeCallback())
         return true;
 
-    Ref<JSTestCallback> protectedThis(*this);
+    Ref<JSTestCallbackInterface> protectedThis(*this);
 
     JSLockHolder lock(m_data->globalObject()->vm());
 
@@ -216,15 +213,15 @@ bool JSTestCallback::callbackRequiresThisToPass(int32_t longParam, TestNode* tes
     return !returnedException;
 }
 
-JSC::JSValue toJS(JSC::ExecState*, JSDOMGlobalObject*, TestCallback& impl)
+JSC::JSValue toJS(JSC::ExecState*, JSDOMGlobalObject*, TestCallbackInterface& impl)
 {
-    if (!static_cast<JSTestCallback&>(impl).callbackData())
+    if (!static_cast<JSTestCallbackInterface&>(impl).callbackData())
         return jsNull();
 
-    return static_cast<JSTestCallback&>(impl).callbackData()->callback();
+    return static_cast<JSTestCallbackInterface&>(impl).callbackData()->callback();
 
 }
 
-}
+} // namespace WebCore
 
 #endif // ENABLE(SPEECH_SYNTHESIS)
 
 #include "ActiveDOMCallback.h"
 #include "JSCallbackData.h"
-#include "TestCallback.h"
+#include "TestCallbackInterface.h"
 #include <wtf/Forward.h>
 
 namespace WebCore {
 
-class JSTestCallback : public TestCallback, public ActiveDOMCallback {
+class JSTestCallbackInterface : public TestCallbackInterface, public ActiveDOMCallback {
 public:
-    static Ref<JSTestCallback> create(JSC::JSObject* callback, JSDOMGlobalObject* globalObject)
+    static Ref<JSTestCallbackInterface> create(JSC::JSObject* callback, JSDOMGlobalObject* globalObject)
     {
-        return adoptRef(*new JSTestCallback(callback, globalObject));
+        return adoptRef(*new JSTestCallbackInterface(callback, globalObject));
     }
 
     virtual ScriptExecutionContext* scriptExecutionContext() const { return ContextDestructionObserver::scriptExecutionContext(); }
 
-    virtual ~JSTestCallback();
+    virtual ~JSTestCallbackInterface();
     JSCallbackDataStrong* callbackData() { return m_data; }
     static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*);
 
     // Functions
     virtual bool callbackWithNoParam();
     virtual bool callbackWithArrayParam(RefPtr<Float32Array> arrayParam);
-    virtual bool callbackWithSerializedScriptValueParam(RefPtr<SerializedScriptValue>&& srzParam, const String& strArg);
-    virtual int32_t callbackWithNonBoolReturnType(const String& strArg);
+    virtual bool callbackWithSerializedScriptValueParam(RefPtr<SerializedScriptValue>&& srzParam, const String& strParam);
     virtual int32_t customCallback(Class5* class5Param, Class6* class6Param);
     virtual bool callbackWithStringList(DOMStringList* listParam);
     virtual bool callbackWithBoolean(bool boolParam);
     virtual bool callbackRequiresThisToPass(int32_t longParam, TestNode* testNodeParam);
 
 private:
-    JSTestCallback(JSC::JSObject* callback, JSDOMGlobalObject*);
+    JSTestCallbackInterface(JSC::JSObject* callback, JSDOMGlobalObject*);
 
     JSCallbackDataStrong* m_data;
 };
 
-JSC::JSValue toJS(JSC::ExecState*, JSDOMGlobalObject*, TestCallback&);
-inline JSC::JSValue toJS(JSC::ExecState* state, JSDOMGlobalObject* globalObject, TestCallback* impl) { return impl ? toJS(state, globalObject, *impl) : JSC::jsNull(); }
+JSC::JSValue toJS(JSC::ExecState*, JSDOMGlobalObject*, TestCallbackInterface&);
+inline JSC::JSValue toJS(JSC::ExecState* state, JSDOMGlobalObject* globalObject, TestCallbackInterface* impl) { return impl ? toJS(state, globalObject, *impl) : JSC::jsNull(); }
 
 } // namespace WebCore
 
index 46f2545..850c1c1 100644 (file)
@@ -44,8 +44,8 @@
 #include "JSPromise.h"
 #include "JSSVGDocument.h"
 #include "JSSVGPoint.h"
-#include "JSTestCallback.h"
 #include "JSTestCallbackFunction.h"
+#include "JSTestCallbackInterface.h"
 #include "JSTestInterface.h"
 #include "JSTestNode.h"
 #include "JSTestObj.h"
@@ -1407,7 +1407,7 @@ template<> EncodedJSValue JSC_HOST_CALL JSTestObjConstructor::construct(ExecStat
         return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
     if (UNLIKELY(!state->uncheckedArgument(0).isObject()))
         return throwArgumentMustBeFunctionError(*state, throwScope, 0, "testCallback", "TestObject", nullptr);
-    auto testCallback = JSTestCallback::create(asObject(state->uncheckedArgument(0)), castedThis->globalObject());
+    auto testCallback = JSTestCallbackInterface::create(asObject(state->uncheckedArgument(0)), castedThis->globalObject());
     if (UNLIKELY(!state->uncheckedArgument(1).isFunction()))
         return throwArgumentMustBeFunctionError(*state, throwScope, 1, "testCallbackFunction", "TestObject", nullptr);
     auto testCallbackFunction = JSTestCallbackFunction::create(asObject(state->uncheckedArgument(1)), castedThis->globalObject());
@@ -6292,7 +6292,7 @@ static inline JSC::EncodedJSValue jsTestObjPrototypeFunctionMethodWithCallbackAr
         return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
     if (UNLIKELY(!state->uncheckedArgument(0).isObject()))
         return throwArgumentMustBeFunctionError(*state, throwScope, 0, "callback", "TestObject", "methodWithCallbackArg");
-    auto callback = JSTestCallback::create(asObject(state->uncheckedArgument(0)), castedThis->globalObject());
+    auto callback = JSTestCallbackInterface::create(asObject(state->uncheckedArgument(0)), castedThis->globalObject());
     impl.methodWithCallbackArg(WTFMove(callback));
     return JSValue::encode(jsUndefined());
 }
@@ -6315,7 +6315,7 @@ static inline JSC::EncodedJSValue jsTestObjPrototypeFunctionMethodWithNonCallbac
     RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
     if (UNLIKELY(!state->uncheckedArgument(1).isObject()))
         return throwArgumentMustBeFunctionError(*state, throwScope, 1, "callback", "TestObject", "methodWithNonCallbackArgAndCallbackArg");
-    auto callback = JSTestCallback::create(asObject(state->uncheckedArgument(1)), castedThis->globalObject());
+    auto callback = JSTestCallbackInterface::create(asObject(state->uncheckedArgument(1)), castedThis->globalObject());
     impl.methodWithNonCallbackArgAndCallbackArg(WTFMove(nonCallback), WTFMove(callback));
     return JSValue::encode(jsUndefined());
 }
@@ -6332,11 +6332,11 @@ static inline JSC::EncodedJSValue jsTestObjPrototypeFunctionMethodWithCallbackAn
     UNUSED_PARAM(state);
     UNUSED_PARAM(throwScope);
     auto& impl = castedThis->wrapped();
-    RefPtr<TestCallback> callback;
+    RefPtr<TestCallbackInterface> callback;
     if (!state->argument(0).isUndefinedOrNull()) {
         if (!state->uncheckedArgument(0).isObject())
             return throwArgumentMustBeFunctionError(*state, throwScope, 0, "callback", "TestObject", "methodWithCallbackAndOptionalArg");
-        callback = JSTestCallback::create(asObject(state->uncheckedArgument(0)), castedThis->globalObject());
+        callback = JSTestCallbackInterface::create(asObject(state->uncheckedArgument(0)), castedThis->globalObject());
     }
     impl.methodWithCallbackAndOptionalArg(WTFMove(callback));
     return JSValue::encode(jsUndefined());
@@ -6413,11 +6413,11 @@ EncodedJSValue JSC_HOST_CALL jsTestObjConstructorFunctionStaticMethodWithCallbac
     VM& vm = state->vm();
     auto throwScope = DECLARE_THROW_SCOPE(vm);
     UNUSED_PARAM(throwScope);
-    RefPtr<TestCallback> callback;
+    RefPtr<TestCallbackInterface> callback;
     if (!state->argument(0).isUndefinedOrNull()) {
         if (!state->uncheckedArgument(0).isObject())
             return throwArgumentMustBeFunctionError(*state, throwScope, 0, "callback", "TestObject", "staticMethodWithCallbackAndOptionalArg");
-        callback = createFunctionOnlyCallback<JSTestCallback>(state, jsCast<JSDOMGlobalObject*>(state->lexicalGlobalObject()), state->uncheckedArgument(0));
+        callback = createFunctionOnlyCallback<JSTestCallbackInterface>(state, jsCast<JSDOMGlobalObject*>(state->lexicalGlobalObject()), state->uncheckedArgument(0));
     }
     TestObj::staticMethodWithCallbackAndOptionalArg(WTFMove(callback));
     return JSValue::encode(jsUndefined());
@@ -6432,7 +6432,7 @@ EncodedJSValue JSC_HOST_CALL jsTestObjConstructorFunctionStaticMethodWithCallbac
         return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
     if (UNLIKELY(!state->uncheckedArgument(0).isObject()))
         return throwArgumentMustBeFunctionError(*state, throwScope, 0, "callback", "TestObject", "staticMethodWithCallbackArg");
-    auto callback = createFunctionOnlyCallback<JSTestCallback>(state, jsCast<JSDOMGlobalObject*>(state->lexicalGlobalObject()), state->uncheckedArgument(0));
+    auto callback = createFunctionOnlyCallback<JSTestCallbackInterface>(state, jsCast<JSDOMGlobalObject*>(state->lexicalGlobalObject()), state->uncheckedArgument(0));
     TestObj::staticMethodWithCallbackArg(WTFMove(callback));
     return JSValue::encode(jsUndefined());
 }
@@ -6594,7 +6594,7 @@ static inline JSC::EncodedJSValue jsTestObjPrototypeFunctionOverloadedMethod5Cal
         return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
     if (UNLIKELY(!state->uncheckedArgument(0).isObject()))
         return throwArgumentMustBeFunctionError(*state, throwScope, 0, "callback", "TestObject", "overloadedMethod");
-    auto callback = JSTestCallback::create(asObject(state->uncheckedArgument(0)), castedThis->globalObject());
+    auto callback = JSTestCallbackInterface::create(asObject(state->uncheckedArgument(0)), castedThis->globalObject());
     impl.overloadedMethod(WTFMove(callback));
     return JSValue::encode(jsUndefined());
 }
@@ -6772,7 +6772,7 @@ EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionOverloadedMethod(ExecStat
             return jsTestObjPrototypeFunctionOverloadedMethod2(state);
         if (distinguishingArg.isObject() && asObject(distinguishingArg)->inherits(JSTestObj::info()))
             return jsTestObjPrototypeFunctionOverloadedMethod2(state);
-        if (distinguishingArg.isObject() && asObject(distinguishingArg)->inherits(JSTestCallback::info()))
+        if (distinguishingArg.isObject() && asObject(distinguishingArg)->inherits(JSTestCallbackInterface::info()))
             return jsTestObjPrototypeFunctionOverloadedMethod5(state);
         if (distinguishingArg.isObject() && asObject(distinguishingArg)->inherits(JSDOMStringList::info()))
             return jsTestObjPrototypeFunctionOverloadedMethod6(state);
index fd3d759..ba0c095 100644 (file)
@@ -26,7 +26,8 @@
 #include "JSDOMConstructor.h"
 #include "JSDOMConvert.h"
 #include "JSSVGPoint.h"
-#include "JSTestCallback.h"
+#include "JSTestCallbackFunction.h"
+#include "JSTestCallbackInterface.h"
 #include "JSTestEventTarget.h"
 #include "JSTestSubObj.h"
 #include "SerializedScriptValue.h"
@@ -130,14 +131,17 @@ template<> EncodedJSValue JSC_HOST_CALL JSTestTypedefsConstructor::construct(Exe
     UNUSED_PARAM(throwScope);
     auto* castedThis = jsCast<JSTestTypedefsConstructor*>(state->callee());
     ASSERT(castedThis);
-    if (UNLIKELY(state->argumentCount() < 2))
+    if (UNLIKELY(state->argumentCount() < 3))
         return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
     auto hello = convert<IDLDOMString>(*state, state->uncheckedArgument(0), StringConversionConfiguration::Normal);
     RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
-    if (UNLIKELY(!state->uncheckedArgument(1).isObject()))
-        return throwArgumentMustBeFunctionError(*state, throwScope, 1, "testCallback", "TestTypedefs", nullptr);
-    auto testCallback = JSTestCallback::create(asObject(state->uncheckedArgument(1)), castedThis->globalObject());
-    auto object = TestTypedefs::create(WTFMove(hello), WTFMove(testCallback));
+    if (UNLIKELY(!state->uncheckedArgument(1).isFunction()))
+        return throwArgumentMustBeFunctionError(*state, throwScope, 1, "testCallbackFunction", "TestTypedefs", nullptr);
+    auto testCallbackFunction = JSTestCallbackFunction::create(asObject(state->uncheckedArgument(1)), castedThis->globalObject());
+    if (UNLIKELY(!state->uncheckedArgument(2).isObject()))
+        return throwArgumentMustBeFunctionError(*state, throwScope, 2, "testCallbackInterface", "TestTypedefs", nullptr);
+    auto testCallbackInterface = JSTestCallbackInterface::create(asObject(state->uncheckedArgument(2)), castedThis->globalObject());
+    auto object = TestTypedefs::create(WTFMove(hello), WTFMove(testCallbackFunction), WTFMove(testCallbackInterface));
     return JSValue::encode(toJSNewlyCreated(state, castedThis->globalObject(), WTFMove(object)));
 }
 
@@ -151,7 +155,7 @@ template<> void JSTestTypedefsConstructor::initializeProperties(VM& vm, JSDOMGlo
 {
     putDirect(vm, vm.propertyNames->prototype, JSTestTypedefs::prototype(vm, &globalObject), DontDelete | ReadOnly | DontEnum);
     putDirect(vm, vm.propertyNames->name, jsNontrivialString(&vm, String(ASCIILiteral("TestTypedefs"))), ReadOnly | DontEnum);
-    putDirect(vm, vm.propertyNames->length, jsNumber(2), ReadOnly | DontEnum);
+    putDirect(vm, vm.propertyNames->length, jsNumber(3), ReadOnly | DontEnum);
     reifyStaticProperties(vm, JSTestTypedefsConstructorTableValues, *this);
 }
 
index 48387d7..2b24ad2 100644 (file)
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-// This IDL file is for testing the bindings code generator with function only callback
-// interface and for tracking changes in its ouput.
 [
     Conditional=SPEECH_SYNTHESIS,
-    Callback=FunctionOnly,
-] callback interface TestCallbackFunction {
-  boolean callbackWithNoParam();
-  boolean callbackWithArrayParam(Float32Array arrayParam);
-  boolean callbackWithSerializedScriptValueParam(SerializedScriptValue srzParam, DOMString strArg);
-  long callbackWithNonBoolReturnType(DOMString strArg);
-  [Custom] long customCallback(Class5 class5Param, Class6 class6Param);
-  boolean callbackWithStringList(DOMStringList listParam);
-  boolean callbackWithBoolean(boolean boolParam);
-  boolean callbackRequiresThisToPass(long longParam, TestNode testNodeParam);
-};
+] callback TestCallbackFunction = void (Float32Array arrayParam, SerializedScriptValue srzParam, DOMString strArg, boolean boolParam, long longParam, TestNode testNodeParam);
diff --git a/Source/WebCore/bindings/scripts/test/TestCallbackFunctionWithTypedefs.idl b/Source/WebCore/bindings/scripts/test/TestCallbackFunctionWithTypedefs.idl
new file mode 100644 (file)
index 0000000..c24bbd2
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+typedef long LONG;
+typedef sequence<LONG?> SEQUENCE_OF_NULLABLE_LONGS;
+typedef void VOID;
+
+callback TestCallbackFunctionWithTypedefs = VOID (SEQUENCE_OF_NULLABLE_LONGS sequenceArg, LONG longArg);
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 2009 Google Inc. All rights reserved.
  *
- * Redistribution and use in source and binary formstrArg, with or without
+ * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
  *
@@ -15,7 +15,7 @@
  *     from this software without specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIEstrArg, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-// This IDL file is for testing the bindings code generator with a callback
-// interface and for tracking changes in its ouput.
 [
     Conditional=SPEECH_SYNTHESIS,
-] callback interface TestCallback {
-  // Constants
-  const unsigned short CONSTANT1 = 1;
-  const unsigned short CONSTANT2 = 2;
+] callback interface TestCallbackInterface {
+    // Constants
+    const unsigned short CONSTANT1 = 1;
+    const unsigned short CONSTANT2 = 2;
 
-  // Operations.
-  boolean callbackWithNoParam();
-  boolean callbackWithArrayParam(Float32Array arrayParam);
-  boolean callbackWithSerializedScriptValueParam(SerializedScriptValue srzParam, DOMString strArg);
-  long callbackWithNonBoolReturnType(DOMString strArg);
-  [Custom] long customCallback(Class5 class5Param, Class6 class6Param);
-  boolean callbackWithStringList(DOMStringList listParam);
-  boolean callbackWithBoolean(boolean boolParam);
-  boolean callbackRequiresThisToPass(long longParam, TestNode testNodeParam);
+    // Operations.
+    void callbackWithNoParam();
+    void callbackWithArrayParam(Float32Array arrayParam);
+    void callbackWithSerializedScriptValueParam(SerializedScriptValue srzParam, DOMString strParam);
+    [Custom] long customCallback(Class5 class5Param, Class6 class6Param);
+    void callbackWithStringList(DOMStringList listParam);
+    void callbackWithBoolean(boolean boolParam);
+    void callbackRequiresThisToPass(long longParam, TestNode testNodeParam);
 };
index 234b935..ca3c738 100644 (file)
@@ -47,7 +47,7 @@ enum TestConfidence { "high", "kinda-low" };
 
 [
     ConstructorCallWith=Document,
-    Constructor(TestCallback testCallback, TestCallbackFunction testCallbackFunction),
+    Constructor(TestCallbackInterface testCallback, TestCallbackFunction testCallbackFunction),
     InterfaceName=TestObject
 ] interface TestObj {
     // Attributes
@@ -242,9 +242,9 @@ enum TestConfidence { "high", "kinda-low" };
 
 #if defined(TESTING_JS)
     // Callback interface parameters.
-    void    methodWithCallbackArg(TestCallback callback);
-    void    methodWithNonCallbackArgAndCallbackArg(long nonCallback, TestCallback callback);
-    void    methodWithCallbackAndOptionalArg(optional TestCallback? callback);
+    void    methodWithCallbackArg(TestCallbackInterface callback);
+    void    methodWithNonCallbackArgAndCallbackArg(long nonCallback, TestCallbackInterface callback);
+    void    methodWithCallbackAndOptionalArg(optional TestCallbackInterface? callback);
 
     // Callback function parameters.
     void    methodWithCallbackFunctionArg(TestCallbackFunction callback);
@@ -252,8 +252,8 @@ enum TestConfidence { "high", "kinda-low" };
     void    methodWithCallbackFunctionAndOptionalArg(optional TestCallbackFunction? callback);
 
     // static methods with 'Callback' extended attribute
-    static void    staticMethodWithCallbackAndOptionalArg(optional TestCallback? callback);
-    static void    staticMethodWithCallbackArg(TestCallback callback);
+    static void    staticMethodWithCallbackAndOptionalArg(optional TestCallbackInterface? callback);
+    static void    staticMethodWithCallbackArg(TestCallbackInterface callback);
 #endif
 
     // 'Conditional' extended attribute
@@ -285,7 +285,7 @@ enum TestConfidence { "high", "kinda-low" };
     void    overloadedMethod(TestObj? objArg, optional long longArg);
     void    overloadedMethod(DOMString strArg);
     void    overloadedMethod(long longArg);
-    void    overloadedMethod(TestCallback callback);
+    void    overloadedMethod(TestCallbackInterface callback);
     void    overloadedMethod(DOMStringList? listArg);
     void    overloadedMethod(sequence<DOMString>? arrayArg);
     void    overloadedMethod(TestObj objArg);
index e20c54c..ebf6bde 100644 (file)
@@ -32,7 +32,7 @@
 // changes in its output.
 
 [
-    Constructor(STRING hello, TEST_CALLBACK testCallback),
+    Constructor(STRING hello, TEST_CALLBACK_FUNCTION testCallbackFunction, TEST_CALLBACK_INTERFACE testCallbackInterface),
 ] interface TestTypedefs {
     attribute ULONGLONG unsignedLongLongAttr;
 
@@ -79,7 +79,8 @@ typedef SVGPoint                   SVGPOINT;
 typedef DOMString                  STRING;
 typedef sequence<DOMString>        SEQUENCE_OF_STRINGS;
 typedef sequence<DOMString?>       SEQUENCE_OF_NULLABLE_STRINGS;
-typedef TestCallback               TEST_CALLBACK;
+typedef TestCallbackFunction       TEST_CALLBACK_FUNCTION;
+typedef TestCallbackInterface      TEST_CALLBACK_INTERFACE;
 typedef TestSubObjConstructor      T;
 typedef Int32Array                 ARRAY;
 typedef DOMException               E;
index 737d71c..5625677 100644 (file)
@@ -32,7 +32,7 @@ public:
         JSMediaQueryListListenerType
     };
 
-    virtual bool queryChanged(MediaQueryList*) = 0;
+    virtual bool handleEvent(MediaQueryList*) = 0;
     virtual bool operator==(const MediaQueryListListener&) const = 0;
     virtual ~MediaQueryListListener() { }
 
index 3e6b0fd..5b6b027 100644 (file)
@@ -18,8 +18,6 @@
  */
 
 [
-    CallbackNeedsOperatorEqual,
-    Callback=FunctionOnly,
-] callback interface MediaQueryListListener {
-    boolean queryChanged(optional MediaQueryList? list = null);
-};
+    CallbackNeedsOperatorEqual
+] callback MediaQueryListListener = void (optional MediaQueryList? list = null);
+
index 38214fd..7867963 100644 (file)
@@ -127,7 +127,7 @@ void MediaQueryMatcher::styleResolverChanged()
         bool notify;
         listener.query->evaluate(evaluator, notify);
         if (notify)
-            listener.listener->queryChanged(listener.query.ptr());
+            listener.listener->handleEvent(listener.query.ptr());
     }
 }
 
index c5f5c71..8eb1596 100644 (file)
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+// highResTime is passed as high resolution timestamp, see
+// http://www.w3.org/TR/hr-time/ for details.
+
 [
     Conditional=REQUEST_ANIMATION_FRAME,
-    Callback=FunctionOnly,
-] callback interface RequestAnimationFrameCallback {
-    // highResTime is passed as high resolution timestamp, see
-    // http://www.w3.org/TR/hr-time/ for details.
-    boolean handleEvent(unrestricted double highResTime);
-};
+] callback RequestAnimationFrameCallback = void (unrestricted double highResTime);
index 923687a..5ccd31a 100644 (file)
@@ -28,8 +28,4 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-[
-    Callback=FunctionOnly,
-] callback interface StringCallback {
-    boolean handleEvent(DOMString data);
-};
+callback StringCallback = void (DOMString data);
index 9fc49af..6618d7d 100644 (file)
@@ -22,8 +22,5 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
  */
-[
-    Callback=FunctionOnly,
-] callback interface VoidCallback {
-    boolean handleEvent();
-};
+
+callback VoidCallback = void ();
index f3f0eec..7bc9fa4 100644 (file)
@@ -26,8 +26,5 @@
 // https://wicg.github.io/IntersectionObserver/
 
 [
-    Conditional=INTERSECTION_OBSERVER,
-    Callback=FunctionOnly,
-] callback interface IntersectionObserverCallback {
-    boolean handleEvent(sequence<IntersectionObserverEntry> entries, IntersectionObserver observer);
-};
+    Conditional=INTERSECTION_OBSERVER
+] callback IntersectionObserverCallback = void (sequence<IntersectionObserverEntry> entries, IntersectionObserver observer);