diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
commit | 1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch) | |
tree | 46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WebCore/bindings/scripts/CodeGeneratorGObject.pm | |
parent | 32761a6cee1d0dee366b885b7b9c777e67885688 (diff) | |
download | WebKitGtk-tarball-master.tar.gz |
webkitgtk-2.16.5HEADwebkitgtk-2.16.5master
Diffstat (limited to 'Source/WebCore/bindings/scripts/CodeGeneratorGObject.pm')
-rw-r--r-- | Source/WebCore/bindings/scripts/CodeGeneratorGObject.pm | 1694 |
1 files changed, 0 insertions, 1694 deletions
diff --git a/Source/WebCore/bindings/scripts/CodeGeneratorGObject.pm b/Source/WebCore/bindings/scripts/CodeGeneratorGObject.pm deleted file mode 100644 index b5b1d8e43..000000000 --- a/Source/WebCore/bindings/scripts/CodeGeneratorGObject.pm +++ /dev/null @@ -1,1694 +0,0 @@ -# Copyright (C) 2008 Luke Kenneth Casson Leighton <lkcl@lkcl.net> -# Copyright (C) 2008 Martin Soto <soto@freedesktop.org> -# Copyright (C) 2008 Alp Toker <alp@atoker.com> -# Copyright (C) 2009 Adam Dingle <adam@yorba.org> -# Copyright (C) 2009 Jim Nelson <jim@yorba.org> -# Copyright (C) 2009, 2010 Igalia S.L. -# -# 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., 59 Temple Place - Suite 330, -# Boston, MA 02111-1307, USA. - -package CodeGeneratorGObject; - -use constant FileNamePrefix => "WebKitDOM"; - -# Global Variables -my %implIncludes = (); -my %hdrIncludes = (); - -my $defineTypeMacro = "G_DEFINE_TYPE"; -my $defineTypeInterfaceImplementation = ")"; -my @txtEventListeners = (); -my @txtInstallProps = (); -my @txtSetProps = (); -my @txtGetProps = (); - -my $className = ""; - -# FIXME: this should be replaced with a function that recurses up the tree -# to find the actual base type. -my %baseTypeHash = ("Object" => 1, "Node" => 1, "NodeList" => 1, "NamedNodeMap" => 1, "DOMImplementation" => 1, - "Event" => 1, "CSSRule" => 1, "CSSValue" => 1, "StyleSheet" => 1, "MediaList" => 1, - "Counter" => 1, "Rect" => 1, "RGBColor" => 1, "XPathExpression" => 1, "XPathResult" => 1, - "NodeIterator" => 1, "TreeWalker" => 1, "AbstractView" => 1, "Blob" => 1, "DOMTokenList" => 1, - "HTMLCollection" => 1); - -# Only objects derived from Node are released by the DOM object cache and can be -# transfer none. Ideally we could use GetBaseClass with the parent type to check -# whether it's Node, but unfortunately we only have the name of the return type, -# and we can't know its parent base class. Since there are fewer classes in the -# API that are not derived from Node, we will list them here to decide the -# transfer type. -my %transferFullTypeHash = ("AudioTrack" => 1, "AudioTrackList" => 1, "BarProp" => 1, "BatteryManager" => 1, - "CSSRuleList" => 1, "CSSStyleDeclaration" => 1, "CSSStyleSheet" => 1, - "DOMApplicationCache" => 1, "DOMMimeType" => 1, "DOMMimeTypeArray" => 1, "DOMNamedFlowCollection" => 1, - "DOMPlugin" => 1, "DOMPluginArray" => 1, "DOMSecurityPolicy" => 1, - "DOMSelection" => 1, "DOMSettableTokenList" => 1, "DOMStringList" => 1, - "DOMWindow" => 1, "DOMWindowCSS" => 1, "EventTarget" => 1, - "File" => 1, "FileList" => 1, "Gamepad" => 1, "GamepadList" => 1, - "Geolocation" => 1, "HTMLOptionsCollection" => 1, "History" => 1, - "KeyboardEvent" => 1, "MediaError" => 1, "MediaController" => 1, - "MouseEvent" => 1, "MediaQueryList" => 1, "Navigator" => 1, "NodeFilter" => 1, - "Performance" => 1, "PerformanceEntry" => 1, "PerformanceEntryList" => 1, "PerformanceNavigation" => 1, "PerformanceTiming" => 1, - "Range" => 1, "Screen" => 1, "SpeechSynthesis" => 1, "SpeechSynthesisVoice" => 1, - "Storage" => 1, "StyleMedia" => 1, "TextTrack" => 1, "TextTrackCueList" => 1, - "TimeRanges" => 1, "Touch" => 1, "UIEvent" => 1, "UserMessageHandler" => 1, "UserMessageHandlersNamespace" => 1, - "ValidityState" => 1, "VideoTrack" => 1, "WebKitNamedFlow" => 1, - "WebKitNamespace" => 1, "WebKitPoint" => 1, "WheelEvent" => 1, "XPathNSResolver" => 1); - -# List of function parameters that are allowed to be NULL -my $canBeNullParams = { - 'webkit_dom_document_create_attribute_ns' => ['namespaceURI'], - 'webkit_dom_document_create_element_ns' => ['namespaceURI'], - 'webkit_dom_document_create_entity_reference' => ['name'], - 'webkit_dom_document_evaluate' => ['inResult', 'resolver'], - 'webkit_dom_document_get_override_style' => ['pseudoElement'], - 'webkit_dom_dom_implementation_create_document' => ['namespaceURI', 'doctype'], - 'webkit_dom_dom_window_get_computed_style' => ['pseudoElement'], - 'webkit_dom_element_set_attribute_ns' => ['namespaceURI'], - 'webkit_dom_node_insert_before' => ['refChild'], -}; - -# Default constructor -sub new { - my $object = shift; - my $reference = { }; - - $codeGenerator = shift; - - bless($reference, $object); -} - -my $licenceTemplate = << "EOF"; -/* - * 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. - */ -EOF - -sub GetParentClassName { - my $interface = shift; - - return "WebKitDOMObject" unless $interface->parent; - return "WebKitDOM" . $interface->parent; -} - -sub GetParentImplClassName { - my $interface = shift; - - return "Object" unless $interface->parent; - return $interface->parent; -} - -sub IsBaseType -{ - my $type = shift; - - return 1 if $baseTypeHash{$type}; - return 0; -} - -sub GetBaseClass -{ - $parent = shift; - $interface = shift; - - return $parent if $parent eq "Object" or IsBaseType($parent); - return "Event" if $codeGenerator->InheritsInterface($interface, "Event"); - return "CSSValue" if $parent eq "SVGColor" or $parent eq "CSSValueList"; - return "Node"; -} - - -# From String::CamelCase 0.01 -sub camelize -{ - my $s = shift; - join('', map{ ucfirst $_ } split(/(?<=[A-Za-z])_(?=[A-Za-z])|\b/, $s)); -} - -sub decamelize -{ - my $s = shift; - $s =~ s{([^a-zA-Z]?)([A-Z]*)([A-Z])([a-z]?)}{ - my $fc = pos($s)==0; - my ($p0,$p1,$p2,$p3) = ($1,lc$2,lc$3,$4); - my $t = $p0 || $fc ? $p0 : '_'; - $t .= $p3 ? $p1 ? "${p1}_$p2$p3" : "$p2$p3" : "$p1$p2"; - $t; - }ge; - - # Some strings are not correctly decamelized, apply fix ups - for ($s) { - s/domcss/dom_css/; - s/domhtml/dom_html/; - s/domdom/dom_dom/; - s/domcdata/dom_cdata/; - s/domui/dom_ui/; - s/x_path/xpath/; - s/web_kit/webkit/; - s/htmli_frame/html_iframe/; - } - return $s; -} - -sub HumanReadableConditional { - my @conditional = split('_', shift); - my @upperCaseExceptions = ("SQL", "API"); - my @humanReadable; - - for $part (@conditional) { - if (!grep {$_ eq $part} @upperCaseExceptions) { - $part = camelize(lc($part)); - } - push(@humanReadable, $part); - } - - return join(' ', @humanReadable); -} - -sub GetParentGObjType { - my $interface = shift; - - return "WEBKIT_TYPE_DOM_OBJECT" unless $interface->parent; - return "WEBKIT_TYPE_DOM_" . uc(decamelize(($interface->parent))); -} - -sub GetClassName { - my $name = shift; - - return "WebKitDOM$name"; -} - -sub GetCoreObject { - my ($interfaceName, $name, $parameter) = @_; - - return "WebCore::${interfaceName}* $name = WebKit::core($parameter);"; -} - -sub SkipAttribute { - my $attribute = shift; - - if ($attribute->signature->extendedAttributes->{"Custom"} - || $attribute->signature->extendedAttributes->{"CustomGetter"}) { - return 1; - } - - my $propType = $attribute->signature->type; - if ($propType =~ /Constructor$/) { - return 1; - } - - return 1 if $attribute->isStatic; - return 1 if $codeGenerator->IsTypedArrayType($propType); - - $codeGenerator->AssertNotSequenceType($propType); - - if ($codeGenerator->GetArrayType($propType)) { - return 1; - } - - if ($codeGenerator->IsEnumType($propType)) { - return 1; - } - - # This is for DOMWindow.idl location attribute - if ($attribute->signature->name eq "location") { - return 1; - } - - # This is for HTMLInput.idl valueAsDate - if ($attribute->signature->name eq "valueAsDate") { - return 1; - } - - # This is for DOMWindow.idl Crypto attribute - if ($attribute->signature->type eq "Crypto") { - return 1; - } - - if ($attribute->signature->type eq "EventListener") { - return 1; - } - - if ($attribute->signature->type eq "MediaQueryListListener") { - return 1; - } - - # Skip indexed database attributes for now, they aren't yet supported for the GObject generator. - if ($attribute->signature->name =~ /^(?:webkit)?[Ii]ndexedDB/ or $attribute->signature->name =~ /^(?:webkit)?IDB/) { - return 1; - } - - return 0; -} - -sub SkipFunction { - my $object = shift; - my $function = shift; - my $parentNode = shift; - my $decamelize = shift; - my $prefix = shift; - - my $functionName = "webkit_dom_" . $decamelize . "_" . $prefix . decamelize($function->signature->name); - my $functionReturnType = $prefix eq "set_" ? "void" : $function->signature->type; - my $isCustomFunction = $function->signature->extendedAttributes->{"Custom"}; - my $callWith = $function->signature->extendedAttributes->{"CallWith"}; - my $isUnsupportedCallWith = $codeGenerator->ExtendedAttributeContains($callWith, "ScriptArguments") || $codeGenerator->ExtendedAttributeContains($callWith, "CallStack"); - - if (($isCustomFunction || $isUnsupportedCallWith) && - $functionName ne "webkit_dom_node_replace_child" && - $functionName ne "webkit_dom_node_insert_before" && - $functionName ne "webkit_dom_node_remove_child" && - $functionName ne "webkit_dom_node_append_child" && - $functionName ne "webkit_dom_html_collection_item" && - $functionName ne "webkit_dom_html_collection_named_item") { - return 1; - } - - # Skip functions that have callback parameters, because this code generator doesn't know - # how to auto-generate callbacks. Skip functions that have "MediaQueryListListener" or - # sequence<T> parameters, because this code generator doesn't know how to auto-generate - # MediaQueryListListener or sequence<T>. Skip EventListeners because they are handled elsewhere. - foreach my $param (@{$function->parameters}) { - if ($codeGenerator->IsCallbackInterface($param->type) || - $param->extendedAttributes->{"Clamp"} || - $param->type eq "MediaQueryListListener" || - $param->type eq "EventListener" || - $codeGenerator->GetSequenceType($param->type)) { - return 1; - } - } - - # Skip functions for which we have a custom implementation due to API breaks - if ($functionName eq "webkit_dom_html_media_element_set_current_time") { - return 1; - } - - # This is for DataTransferItemList.idl add(File) method - if ($functionName eq "webkit_dom_data_transfer_item_list_add" && @{$function->parameters} == 1) { - return 1; - } - - # Skip dispatch_event methods, except the one already deprecated. - if ($parentNode->extendedAttributes->{"EventTarget"} && $function->signature->name eq "dispatchEvent" - && $functionName ne "webkit_dom_audio_track_list_dispatch_event" - && $functionName ne "webkit_dom_battery_manager_dispatch_event" - && $functionName ne "webkit_dom_dom_application_cache_dispatch_event" - && $functionName ne "webkit_dom_dom_window_dispatch_event" - && $functionName ne "webkit_dom_node_dispatch_event" - && $functionName ne "webkit_dom_text_track_cue_dispatch_event" - && $functionName ne "webkit_dom_text_track_dispatch_event" - && $functionName ne "webkit_dom_text_track_list_dispatch_event" - && $functionName ne "webkit_dom_video_track_list_dispatch_event" - && $functionName ne "webkit_dom_webkit_named_flow_dispatch_event" - && $functionName ne "webkit_dom_test_event_target_dispatch_event") { - return 1; - } - - # Skip Console::profile() and Console::profileEnd() as they're not correctly generated for the moment. - if ($functionName eq "webkit_dom_console_profile" || $functionName eq "webkit_dom_console_profile_end") { - return 1; - } - - if ($function->signature->name eq "set" and $parentNode->extendedAttributes->{"TypedArray"}) { - return 1; - } - - if ($object eq "MediaQueryListListener") { - return 1; - } - - if ($function->signature->name eq "getSVGDocument") { - return 1; - } - - if ($function->signature->name eq "getCSSCanvasContext") { - return 1; - } - - if ($function->signature->name eq "setRangeText" && @{$function->parameters} == 1) { - return 1; - } - - if ($function->signature->name eq "timeEnd") { - return 1; - } - - if ($codeGenerator->GetSequenceType($functionReturnType)) { - return 1; - } - - if ($function->signature->name eq "supports" && @{$function->parameters} == 1) { - return 1; - } - - return 0; -} - -# Name type used in the g_value_{set,get}_* functions -sub GetGValueTypeName { - my $type = shift; - - my %types = ("DOMString", "string", - "DOMTimeStamp", "uint", - "float", "float", - "double", "double", - "boolean", "boolean", - "char", "char", - "long", "long", - "long long", "int64", - "byte", "int8", - "octet", "uint8", - "short", "int", - "uchar", "uchar", - "unsigned", "uint", - "int", "int", - "unsigned int", "uint", - "unsigned long long", "uint64", - "unsigned long", "ulong", - "unsigned short", "uint"); - - return $types{$type} ? $types{$type} : "object"; -} - -# Name type used in C declarations -sub GetGlibTypeName { - my $type = shift; - my $name = GetClassName($type); - - my %types = ("DOMString", "gchar*", - "DOMTimeStamp", "guint32", - "CompareHow", "gushort", - "float", "gfloat", - "double", "gdouble", - "boolean", "gboolean", - "char", "gchar", - "long", "glong", - "long long", "gint64", - "byte", "gint8", - "octet", "guint8", - "short", "gshort", - "uchar", "guchar", - "unsigned", "guint", - "int", "gint", - "unsigned int", "guint", - "unsigned long", "gulong", - "unsigned long long", "guint64", - "unsigned short", "gushort", - "void", "void"); - - return $types{$type} ? $types{$type} : "$name*"; -} - -sub IsGDOMClassType { - my $type = shift; - - return 0 if $codeGenerator->IsNonPointerType($type) || $codeGenerator->IsStringType($type); - return 1; -} - -sub IsPropertyReadable { - my $property = shift; - return !SkipAttribute($property); -} - -sub IsPropertyWriteable { - my $property = shift; - - if (!IsPropertyReadable($property)) { - return 0; - } - - if ($property->isReadOnly) { - return 0; - } - - my $gtype = GetGValueTypeName($property->signature->type); - my $hasGtypeSignature = $gtype eq "boolean" || $gtype eq "float" || $gtype eq "double" || - $gtype eq "int64" || $gtype eq "uint64" || - $gtype eq "long" || $gtype eq "ulong" || - $gtype eq "int" || $gtype eq "uint" || - $gtype eq "short" || $gtype eq "ushort" || - $gtype eq "int8" || $gtype eq "uint8" || - $gtype eq "char" || $gtype eq "uchar" || - $gtype eq "string"; - if (!$hasGtypeSignature) { - return 0; - } - - # FIXME: We are not generating setters for 'Replaceable' attributes now, but we should somehow. - if ($property->signature->extendedAttributes->{"Replaceable"}) { - return 0; - } - - if ($property->signature->extendedAttributes->{"CustomSetter"}) { - return 0; - } - - return 1; -} - -sub GenerateConditionalWarning -{ - my $node = shift; - my $indentSize = shift; - if (!$indentSize) { - $indentSize = 4; - } - - my $conditional = $node->extendedAttributes->{"Conditional"}; - my @warn; - - if ($conditional) { - if ($conditional =~ /&/) { - my @splitConditionals = split(/&/, $conditional); - foreach $condition (@splitConditionals) { - push(@warn, "#if !ENABLE($condition)\n"); - push(@warn, ' ' x $indentSize . "WEBKIT_WARN_FEATURE_NOT_PRESENT(\"" . HumanReadableConditional($condition) . "\")\n"); - push(@warn, "#endif\n"); - } - } elsif ($conditional =~ /\|/) { - foreach $condition (split(/\|/, $conditional)) { - push(@warn, ' ' x $indentSize . "WEBKIT_WARN_FEATURE_NOT_PRESENT(\"" . HumanReadableConditional($condition) . "\")\n"); - } - } else { - push(@warn, ' ' x $indentSize . "WEBKIT_WARN_FEATURE_NOT_PRESENT(\"" . HumanReadableConditional($conditional) . "\")\n"); - } - } - - return @warn; -} - -sub GenerateProperty { - my $attribute = shift; - my $interfaceName = shift; - my @writeableProperties = @{shift @_}; - my $parentNode = shift; - - my $conditionalString = $codeGenerator->GenerateConditionalString($attribute->signature); - my @conditionalWarn = GenerateConditionalWarning($attribute->signature, 8); - my $parentConditionalString = $codeGenerator->GenerateConditionalString($parentNode); - my @parentConditionalWarn = GenerateConditionalWarning($parentNode, 8); - my $camelPropName = $attribute->signature->name; - my $setPropNameFunction = $codeGenerator->WK_ucfirst($camelPropName); - my $getPropNameFunction = $codeGenerator->WK_lcfirst($camelPropName); - my $hasGetterException = $attribute->signature->extendedAttributes->{"GetterRaisesException"}; - my $hasSetterException = $attribute->signature->extendedAttributes->{"SetterRaisesException"}; - - my $propName = decamelize($camelPropName); - my $propNameCaps = uc($propName); - $propName =~ s/_/-/g; - my ${propEnum} = "PROP_${propNameCaps}"; - push(@cBodyProperties, " ${propEnum},\n"); - - my $propType = $attribute->signature->type; - my ${propGType} = decamelize($propType); - my ${ucPropGType} = uc($propGType); - - my $gtype = GetGValueTypeName($propType); - my $gparamflag = "WEBKIT_PARAM_READABLE"; - my $writeable = IsPropertyWriteable($attribute); - - my $mutableString = "read-only"; - my $hasCustomSetter = $attribute->signature->extendedAttributes->{"CustomSetter"}; - if ($writeable && $hasCustomSetter) { - $mutableString = "read-only (due to custom functions needed in webkitdom)"; - } elsif ($writeable) { - $gparamflag = "WEBKIT_PARAM_READWRITE"; - $mutableString = "read-write"; - } - - my $convertFunction = ""; - if ($gtype eq "string") { - $convertFunction = "WTF::String::fromUTF8"; - } - - my ($getterFunctionName, @getterArguments) = $codeGenerator->GetterExpression(\%implIncludes, $interfaceName, $attribute); - my ($setterFunctionName, @setterArguments) = $codeGenerator->SetterExpression(\%implIncludes, $interfaceName, $attribute); - - if ($attribute->signature->extendedAttributes->{"ImplementedBy"}) { - my $implementedBy = $attribute->signature->extendedAttributes->{"ImplementedBy"}; - $implIncludes{"${implementedBy}.h"} = 1; - push(@setterArguments, "${convertFunction}(g_value_get_$gtype(value))"); - unshift(@getterArguments, "coreSelf"); - unshift(@setterArguments, "coreSelf"); - $getterFunctionName = "WebCore::${implementedBy}::$getterFunctionName"; - $setterFunctionName = "WebCore::${implementedBy}::$setterFunctionName"; - } else { - push(@setterArguments, "${convertFunction}(g_value_get_$gtype(value))"); - $getterFunctionName = "coreSelf->$getterFunctionName"; - $setterFunctionName = "coreSelf->$setterFunctionName"; - } - push(@getterArguments, "isNull") if $attribute->signature->isNullable; - push(@getterArguments, "ec") if $hasGetterException; - push(@setterArguments, "ec") if $hasSetterException; - - if (grep {$_ eq $attribute} @writeableProperties) { - push(@txtSetProps, " case ${propEnum}: {\n"); - push(@txtSetProps, "#if ${parentConditionalString}\n") if $parentConditionalString; - push(@txtSetProps, "#if ${conditionalString}\n") if $conditionalString; - push(@txtSetProps, " WebCore::ExceptionCode ec = 0;\n") if $hasSetterException; - push(@txtSetProps, " ${setterFunctionName}(" . join(", ", @setterArguments) . ");\n"); - push(@txtSetProps, "#else\n") if $conditionalString; - push(@txtSetProps, @conditionalWarn) if scalar(@conditionalWarn); - push(@txtSetProps, "#endif /* ${conditionalString} */\n") if $conditionalString; - push(@txtSetProps, "#else\n") if $parentConditionalString; - push(@txtSetProps, @parentConditionalWarn) if scalar(@parentConditionalWarn); - push(@txtSetProps, "#endif /* ${parentConditionalString} */\n") if $parentConditionalString; - push(@txtSetProps, " break;\n }\n"); - } - - push(@txtGetProps, " case ${propEnum}: {\n"); - push(@txtGetProps, "#if ${parentConditionalString}\n") if $parentConditionalString; - push(@txtGetProps, "#if ${conditionalString}\n") if $conditionalString; - push(@txtGetProps, " bool isNull = false;\n") if $attribute->signature->isNullable; - push(@txtGetProps, " WebCore::ExceptionCode ec = 0;\n") if $hasGetterException; - - # FIXME: Should we return a default value when isNull == true? - - my $postConvertFunction = ""; - if ($gtype eq "string") { - push(@txtGetProps, " g_value_take_string(value, convertToUTF8String(${getterFunctionName}(" . join(", ", @getterArguments) . ")));\n"); - } elsif ($gtype eq "object") { - push(@txtGetProps, " RefPtr<WebCore::${propType}> ptr = ${getterFunctionName}(" . join(", ", @getterArguments) . ");\n"); - push(@txtGetProps, " g_value_set_object(value, WebKit::kit(ptr.get()));\n"); - } else { - push(@txtGetProps, " g_value_set_$gtype(value, ${convertFunction}${getterFunctionName}(" . join(", ", @getterArguments) . ")${postConvertFunction});\n"); - } - - push(@txtGetProps, "#else\n") if $conditionalString; - push(@txtGetProps, @conditionalWarn) if scalar(@conditionalWarn); - push(@txtGetProps, "#endif /* ${conditionalString} */\n") if $conditionalString; - push(@txtGetProps, "#else\n") if $parentConditionalString; - push(@txtGetProps, @parentConditionalWarn) if scalar(@parentConditionalWarn); - push(@txtGetProps, "#endif /* ${parentConditionalString} */\n") if $parentConditionalString; - push(@txtGetProps, " break;\n }\n"); - - my %parameterSpecOptions = ("int" => [ "G_MININT", "G_MAXINT", "0" ], - "int8" => [ "G_MININT8", "G_MAXINT8", "0" ], - "boolean" => [ "FALSE" ], - "float" => [ "-G_MAXFLOAT", "G_MAXFLOAT", "0" ], - "double" => [ "-G_MAXDOUBLE", "G_MAXDOUBLE", "0" ], - "uint64" => [ "0", "G_MAXUINT64", "0" ], - "long" => [ "G_MINLONG", "G_MAXLONG", "0" ], - "int64" => [ "G_MININT64", "G_MAXINT64", "0" ], - "ulong" => [ "0", "G_MAXULONG", "0" ], - "uint" => [ "0", "G_MAXUINT", "0" ], - "uint8" => [ "0", "G_MAXUINT8", "0" ], - "ushort" => [ "0", "G_MAXUINT16", "0" ], - "uchar" => [ "G_MININT8", "G_MAXINT8", "0" ], - "char" => [ "0", "G_MAXUINT8", "0" ], - "string" => [ '""', ], - "object" => [ "WEBKIT_TYPE_DOM_${ucPropGType}" ]); - - my $extraParameters = join(", ", @{$parameterSpecOptions{$gtype}}); - my $glibTypeName = GetGlibTypeName($propType); - my $txtInstallProp = << "EOF"; - g_object_class_install_property( - gobjectClass, - $propEnum, - g_param_spec_$gtype( - "$propName", - "$interfaceName:$propName", - "$mutableString $glibTypeName $interfaceName:$propName", - $extraParameters, - $gparamflag)); - -EOF - push(@txtInstallProps, $txtInstallProp); -} - -sub GenerateProperties { - my ($object, $interfaceName, $interface) = @_; - - my $decamelize = decamelize($interfaceName); - my $clsCaps = uc($decamelize); - my $lowerCaseIfaceName = "webkit_dom_$decamelize"; - my $parentImplClassName = GetParentImplClassName($interface); - - my $conditionGuardStart = ""; - my $conditionGuardEnd = ""; - my $conditionalString = $codeGenerator->GenerateConditionalString($interface); - if ($conditionalString) { - $conditionGuardStart = "#if ${conditionalString}"; - $conditionGuardEnd = "#endif // ${conditionalString}"; - } - - # Properties - my $implContent = ""; - my @readableProperties = grep { IsPropertyReadable($_) } @{$interface->attributes}; - my @writeableProperties = grep { IsPropertyWriteable($_) } @{$interface->attributes}; - my $numProperties = scalar @readableProperties; - - # Properties - my $privFunction = GetCoreObject($interfaceName, "coreSelf", "self"); - if ($numProperties > 0) { - $implContent = << "EOF"; -enum { - PROP_0, -EOF - push(@cBodyProperties, $implContent); - - my $txtGetProp = << "EOF"; -static void ${lowerCaseIfaceName}_get_property(GObject* object, guint propertyId, GValue* value, GParamSpec* pspec) -{ - WebCore::JSMainThreadNullState state; -EOF - push(@txtGetProps, $txtGetProp); - $txtGetProp = << "EOF"; -$conditionGuardStart - ${className}* self = WEBKIT_DOM_${clsCaps}(object); - $privFunction -$conditionGuardEnd -EOF - push(@txtGetProps, $txtGetProp); - - $txtGetProp = << "EOF"; - switch (propertyId) { -EOF - push(@txtGetProps, $txtGetProp); - - if (scalar @writeableProperties > 0) { - my $txtSetProps = << "EOF"; -static void ${lowerCaseIfaceName}_set_property(GObject* object, guint propertyId, const GValue* value, GParamSpec* pspec) -{ - WebCore::JSMainThreadNullState state; -EOF - push(@txtSetProps, $txtSetProps); - - $txtSetProps = << "EOF"; -$conditionGuardStart - ${className}* self = WEBKIT_DOM_${clsCaps}(object); - $privFunction -$conditionGuardEnd -EOF - push(@txtSetProps, $txtSetProps); - - $txtSetProps = << "EOF"; - switch (propertyId) { -EOF - push(@txtSetProps, $txtSetProps); - } - - foreach my $attribute (@readableProperties) { - GenerateProperty($attribute, $interfaceName, \@writeableProperties, $interface); - } - - push(@cBodyProperties, "};\n\n"); - - $txtGetProp = << "EOF"; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propertyId, pspec); - break; - } -} -EOF - push(@txtGetProps, $txtGetProp); - - if (scalar @writeableProperties > 0) { - $txtSetProps = << "EOF"; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propertyId, pspec); - break; - } -} -EOF - push(@txtSetProps, $txtSetProps); - } - } - - # Do not insert extra spaces when interpolating array variables - $" = ""; - - if ($parentImplClassName eq "Object") { - $implContent = << "EOF"; -static void ${lowerCaseIfaceName}_finalize(GObject* object) -{ - ${className}Private* priv = WEBKIT_DOM_${clsCaps}_GET_PRIVATE(object); -$conditionGuardStart - WebKit::DOMObjectCache::forget(priv->coreObject.get()); -$conditionGuardEnd - priv->~${className}Private(); - G_OBJECT_CLASS(${lowerCaseIfaceName}_parent_class)->finalize(object); -} - -EOF - push(@cBodyProperties, $implContent); - } - - if ($numProperties > 0) { - if (scalar @writeableProperties > 0) { - push(@cBodyProperties, @txtSetProps); - push(@cBodyProperties, "\n"); - } - push(@cBodyProperties, @txtGetProps); - push(@cBodyProperties, "\n"); - } - - # Add a constructor implementation only for direct subclasses of Object to make sure - # that the WebCore wrapped object is added only once to the DOM cache. The DOM garbage - # collector works because Node is a direct subclass of Object and the version of - # DOMObjectCache::put() that receives a Node (which is the one setting the frame) is - # always called for DOM objects derived from Node. - if ($parentImplClassName eq "Object") { - $implContent = << "EOF"; -static GObject* ${lowerCaseIfaceName}_constructor(GType type, guint constructPropertiesCount, GObjectConstructParam* constructProperties) -{ - GObject* object = G_OBJECT_CLASS(${lowerCaseIfaceName}_parent_class)->constructor(type, constructPropertiesCount, constructProperties); -$conditionGuardStart - ${className}Private* priv = WEBKIT_DOM_${clsCaps}_GET_PRIVATE(object); - priv->coreObject = static_cast<WebCore::${interfaceName}*>(WEBKIT_DOM_OBJECT(object)->coreObject); - WebKit::DOMObjectCache::put(priv->coreObject.get(), object); -$conditionGuardEnd - return object; -} - -EOF - push(@cBodyProperties, $implContent); - } - - $implContent = << "EOF"; -static void ${lowerCaseIfaceName}_class_init(${className}Class* requestClass) -{ -EOF - push(@cBodyProperties, $implContent); - - if ($parentImplClassName eq "Object" || $numProperties > 0) { - push(@cBodyProperties, " GObjectClass* gobjectClass = G_OBJECT_CLASS(requestClass);\n"); - - if ($parentImplClassName eq "Object") { - push(@cBodyProperties, " g_type_class_add_private(gobjectClass, sizeof(${className}Private));\n"); - push(@cBodyProperties, " gobjectClass->constructor = ${lowerCaseIfaceName}_constructor;\n"); - push(@cBodyProperties, " gobjectClass->finalize = ${lowerCaseIfaceName}_finalize;\n"); - } - - if ($numProperties > 0) { - if (scalar @writeableProperties > 0) { - push(@cBodyProperties, " gobjectClass->set_property = ${lowerCaseIfaceName}_set_property;\n"); - } - push(@cBodyProperties, " gobjectClass->get_property = ${lowerCaseIfaceName}_get_property;\n"); - push(@cBodyProperties, "\n"); - push(@cBodyProperties, @txtInstallProps); - } - } - $implContent = << "EOF"; -} - -static void ${lowerCaseIfaceName}_init(${className}* request) -{ -EOF - push(@cBodyProperties, $implContent); - - if ($parentImplClassName eq "Object") { - $implContent = << "EOF"; - ${className}Private* priv = WEBKIT_DOM_${clsCaps}_GET_PRIVATE(request); - new (priv) ${className}Private(); -EOF - push(@cBodyProperties, $implContent); - } - $implContent = << "EOF"; -} - -EOF - push(@cBodyProperties, $implContent); -} - -sub GenerateHeader { - my ($object, $interfaceName, $parentClassName) = @_; - - my $implContent = ""; - - # Add the default header template - @hPrefix = split("\r", $licenceTemplate); - push(@hPrefix, "\n"); - - # Force single header include. - my $headerCheck = << "EOF"; -#if !defined(__WEBKITDOM_H_INSIDE__) && !defined(BUILDING_WEBKIT) -#error "Only <webkitdom/webkitdom.h> can be included directly." -#endif - -EOF - push(@hPrefix, $headerCheck); - - # Header guard - my $guard = $className . "_h"; - - @hPrefixGuard = << "EOF"; -#ifndef $guard -#define $guard - -EOF - - $implContent = << "EOF"; -G_BEGIN_DECLS - -EOF - - push(@hBodyPre, $implContent); - - my $decamelize = decamelize($interfaceName); - my $clsCaps = uc($decamelize); - my $lowerCaseIfaceName = "webkit_dom_$decamelize"; - - $implContent = << "EOF"; -#define WEBKIT_TYPE_DOM_${clsCaps} (${lowerCaseIfaceName}_get_type()) -#define WEBKIT_DOM_${clsCaps}(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), WEBKIT_TYPE_DOM_${clsCaps}, ${className})) -#define WEBKIT_DOM_${clsCaps}_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), WEBKIT_TYPE_DOM_${clsCaps}, ${className}Class) -#define WEBKIT_DOM_IS_${clsCaps}(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), WEBKIT_TYPE_DOM_${clsCaps})) -#define WEBKIT_DOM_IS_${clsCaps}_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), WEBKIT_TYPE_DOM_${clsCaps})) -#define WEBKIT_DOM_${clsCaps}_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), WEBKIT_TYPE_DOM_${clsCaps}, ${className}Class)) - -struct _${className} { - ${parentClassName} parent_instance; -}; - -struct _${className}Class { - ${parentClassName}Class parent_class; -}; - -WEBKIT_API GType -${lowerCaseIfaceName}_get_type (void); - -EOF - - push(@hBody, $implContent); -} - -sub GetGReturnMacro { - my ($paramName, $paramIDLType, $returnType, $functionName) = @_; - - my $condition; - if ($paramIDLType eq "GError") { - $condition = "!$paramName || !*$paramName"; - } elsif (IsGDOMClassType($paramIDLType)) { - my $paramTypeCaps = uc(decamelize($paramIDLType)); - $condition = "WEBKIT_DOM_IS_${paramTypeCaps}($paramName)"; - if (ParamCanBeNull($functionName, $paramName)) { - $condition = "!$paramName || $condition"; - } - } else { - if (ParamCanBeNull($functionName, $paramName)) { - return ""; - } - $condition = "$paramName"; - } - - my $macro; - if ($returnType ne "void") { - $defaultReturn = $returnType eq "gboolean" ? "FALSE" : 0; - $macro = " g_return_val_if_fail($condition, $defaultReturn);\n"; - } else { - $macro = " g_return_if_fail($condition);\n"; - } - - return $macro; -} - -sub ParamCanBeNull { - my($functionName, $paramName) = @_; - - if (defined($functionName)) { - return scalar(grep {$_ eq $paramName} @{$canBeNullParams->{$functionName}}); - } - return 0; -} - -sub GetFunctionDeprecationInformation { - my($function, $parentNode) = @_; - - my $version; - my $replacement; - - if ($parentNode->extendedAttributes->{"EventTarget"} && $function->signature->name eq "dispatchEvent") { - # dispatchEvent is implemented already as part fo the WebKitDOMEventTarget interface. - # Mark it as deprecated for now in favor of the interface method, and skip it once - # we break the API. All other methods of WebKitDOMEventTarget interface are already - # skipped because they receive an EventListener as parameter. - $version = "2.4"; - $replacement = "webkit_dom_event_target_dispatch_event"; - } - - return ($version, $replacement); -} - -sub GetTransferTypeForReturnType { - my $returnType = shift; - - # Node is always transfer none. - return "none" if $returnType eq "Node"; - - # Any base class but Node is transfer full. - return "full" if IsBaseType($returnType); - - # Any other class not derived from Node is transfer full. - return "full" if $transferFullTypeHash{$returnType}; - return "none"; -} - -sub GenerateFunction { - my ($object, $interfaceName, $function, $prefix, $parentNode) = @_; - - my $decamelize = decamelize($interfaceName); - - if (SkipFunction($object, $function, $parentNode, $decamelize, $prefix)) { - return; - } - - my ($deprecationVersion, $deprecationReplacement) = GetFunctionDeprecationInformation($function, $parentNode); - my $functionSigType = $prefix eq "set_" ? "void" : $function->signature->type; - my $functionName = "webkit_dom_" . $decamelize . "_" . $prefix . decamelize($function->signature->name); - my $returnType = GetGlibTypeName($functionSigType); - my $returnValueIsGDOMType = IsGDOMClassType($functionSigType); - my $raisesException = $function->signature->extendedAttributes->{"RaisesException"}; - - my $conditionalString = $codeGenerator->GenerateConditionalString($function->signature); - my $parentConditionalString = $codeGenerator->GenerateConditionalString($parentNode); - my @conditionalWarn = GenerateConditionalWarning($function->signature); - my @parentConditionalWarn = GenerateConditionalWarning($parentNode); - - my $functionSig = "${className}* self"; - my $symbolSig = "${className}*"; - - my @callImplParams; - foreach my $param (@{$function->parameters}) { - my $paramIDLType = $param->type; - my $paramType = GetGlibTypeName($paramIDLType); - my $const = $paramType eq "gchar*" ? "const " : ""; - my $paramName = $param->name; - - $functionSig .= ", ${const}$paramType $paramName"; - $symbolSig .= ", ${const}$paramType"; - - my $paramIsGDOMType = IsGDOMClassType($paramIDLType); - if ($paramIsGDOMType) { - if ($paramIDLType ne "any") { - $implIncludes{"WebKitDOM${paramIDLType}Private.h"} = 1; - } - } - if ($paramIsGDOMType || ($paramIDLType eq "DOMString") || ($paramIDLType eq "CompareHow")) { - $paramName = "converted" . $codeGenerator->WK_ucfirst($paramName); - } - push(@callImplParams, $paramName); - } - - if ($returnType ne "void" && $returnValueIsGDOMType && $functionSigType ne "any") { - $implIncludes{"WebKitDOM${functionSigType}Private.h"} = 1; - } - - $functionSig .= ", GError** error" if $raisesException; - $symbolSig .= ", GError**" if $raisesException; - - push(@symbols, "$returnType $functionName($symbolSig)\n"); - - if ($deprecationVersion) { - push(@hBody, "#if !defined(WEBKIT_DISABLE_DEPRECATED)\n"); - } - - # Insert introspection annotations - push(@hBody, "/**\n"); - push(@hBody, " * ${functionName}:\n"); - push(@hBody, " * \@self: A #${className}\n"); - - foreach my $param (@{$function->parameters}) { - my $paramType = GetGlibTypeName($param->type); - # $paramType can have a trailing * in some cases - $paramType =~ s/\*$//; - my $paramName = $param->name; - my $paramAnnotations = ""; - if (ParamCanBeNull($functionName, $paramName)) { - $paramAnnotations = " (allow-none):"; - } - push(@hBody, " * \@${paramName}:${paramAnnotations} A #${paramType}\n"); - } - push(@hBody, " * \@error: #GError\n") if $raisesException; - push(@hBody, " *\n"); - my $returnTypeName = $returnType; - $returnTypeName =~ s/\*$//; - if ($returnValueIsGDOMType) { - my $transferType = GetTransferTypeForReturnType($functionSigType); - push(@hBody, " * Returns: (transfer $transferType): A #${returnTypeName}\n"); - } elsif ($returnType ne "void") { - push(@hBody, " * Returns: A #${returnTypeName}\n"); - } - if ($deprecationVersion) { - push(@hBody, " *\n"); - push(@hBody, " * Deprecated: $deprecationVersion"); - if ($deprecationReplacement) { - push(@hBody, ": Use $deprecationReplacement() instead."); - } - push(@hBody, "\n"); - } - push(@hBody, "**/\n"); - - if ($deprecationVersion && $deprecationReplacement) { - push(@hBody, "WEBKIT_DEPRECATED_FOR($deprecationReplacement) "); - } elsif ($deprecationVersion) { - push(@hBody, "WEBKIT_DEPRECATED "); - } else { - push(@hBody, "WEBKIT_API "); - } - push(@hBody, "$returnType\n$functionName($functionSig);\n"); - if ($deprecationVersion) { - push(@hBody, "#endif /* WEBKIT_DISABLE_DEPRECATED */\n"); - } - push(@hBody, "\n"); - - push(@cBody, "$returnType $functionName($functionSig)\n{\n"); - push(@cBody, "#if ${parentConditionalString}\n") if $parentConditionalString; - push(@cBody, "#if ${conditionalString}\n") if $conditionalString; - - push(@cBody, " WebCore::JSMainThreadNullState state;\n"); - - # g_return macros to check parameters of public methods. - $gReturnMacro = GetGReturnMacro("self", $interfaceName, $returnType); - push(@cBody, $gReturnMacro); - - foreach my $param (@{$function->parameters}) { - my $paramName = $param->name; - my $paramIDLType = $param->type; - my $paramTypeIsPointer = !$codeGenerator->IsNonPointerType($paramIDLType); - if ($paramTypeIsPointer) { - $gReturnMacro = GetGReturnMacro($paramName, $paramIDLType, $returnType, $functionName); - push(@cBody, $gReturnMacro); - } - } - - if ($raisesException) { - $gReturnMacro = GetGReturnMacro("error", "GError", $returnType); - push(@cBody, $gReturnMacro); - } - - # The WebKit::core implementations check for null already; no need to duplicate effort. - push(@cBody, " WebCore::${interfaceName}* item = WebKit::core(self);\n"); - - $returnParamName = ""; - foreach my $param (@{$function->parameters}) { - my $paramIDLType = $param->type; - my $paramName = $param->name; - - my $paramIsGDOMType = IsGDOMClassType($paramIDLType); - $convertedParamName = "converted" . $codeGenerator->WK_ucfirst($paramName); - if ($paramIDLType eq "DOMString") { - push(@cBody, " WTF::String ${convertedParamName} = WTF::String::fromUTF8($paramName);\n"); - } elsif ($paramIDLType eq "CompareHow") { - push(@cBody, " WebCore::Range::CompareHow ${convertedParamName} = static_cast<WebCore::Range::CompareHow>($paramName);\n"); - } elsif ($paramIsGDOMType) { - push(@cBody, " WebCore::${paramIDLType}* ${convertedParamName} = WebKit::core($paramName);\n"); - } - $returnParamName = $convertedParamName if $param->extendedAttributes->{"CustomReturn"}; - } - - my $assign = ""; - my $assignPre = ""; - my $assignPost = ""; - - # We need to special-case these Node methods because their C++ - # signature is different from what we'd expect given their IDL - # description; see Node.h. - my $functionHasCustomReturn = $functionName eq "webkit_dom_node_append_child" || - $functionName eq "webkit_dom_node_insert_before" || - $functionName eq "webkit_dom_node_replace_child" || - $functionName eq "webkit_dom_node_remove_child"; - - if ($returnType ne "void" && !$functionHasCustomReturn) { - if ($returnValueIsGDOMType) { - $assign = "RefPtr<WebCore::${functionSigType}> gobjectResult = "; - $assignPre = "WTF::getPtr("; - $assignPost = ")"; - } else { - $assign = "${returnType} result = "; - } - } - - # FIXME: Should we return a default value when isNull == true? - if ($function->signature->isNullable) { - push(@cBody, " bool isNull = false;\n"); - push(@callImplParams, "isNull"); - } - - if ($raisesException) { - push(@cBody, " WebCore::ExceptionCode ec = 0;\n"); - push(@callImplParams, "ec"); - } - - my $functionImplementationName = $function->signature->extendedAttributes->{"ImplementedAs"} || $function->signature->name; - - if ($functionHasCustomReturn) { - push(@cBody, " bool ok = item->${functionImplementationName}(" . join(", ", @callImplParams) . ");\n"); - my $customNodeAppendChild = << "EOF"; - if (ok) - return WebKit::kit($returnParamName); -EOF - push(@cBody, $customNodeAppendChild); - - if($raisesException) { - my $exceptionHandling = << "EOF"; - - WebCore::ExceptionCodeDescription ecdesc(ec); - g_set_error_literal(error, g_quark_from_string("WEBKIT_DOM"), ecdesc.code, ecdesc.name); -EOF - push(@cBody, $exceptionHandling); - } - push(@cBody, " return 0;\n"); - push(@cBody, "}\n\n"); - return; - } elsif ($functionSigType eq "DOMString") { - my $getterContentHead; - if ($prefix) { - my ($functionName, @arguments) = $codeGenerator->GetterExpression(\%implIncludes, $interfaceName, $function); - push(@arguments, @callImplParams); - if ($function->signature->extendedAttributes->{"ImplementedBy"}) { - my $implementedBy = $function->signature->extendedAttributes->{"ImplementedBy"}; - $implIncludes{"${implementedBy}.h"} = 1; - unshift(@arguments, "item"); - $functionName = "WebCore::${implementedBy}::${functionName}"; - } else { - $functionName = "item->${functionName}"; - } - $getterContentHead = "${assign}convertToUTF8String(${functionName}(" . join(", ", @arguments) . "));\n"; - } else { - my @arguments = @callImplParams; - if ($function->signature->extendedAttributes->{"ImplementedBy"}) { - my $implementedBy = $function->signature->extendedAttributes->{"ImplementedBy"}; - $implIncludes{"${implementedBy}.h"} = 1; - unshift(@arguments, "item"); - $getterContentHead = "${assign}convertToUTF8String(WebCore::${implementedBy}::${functionImplementationName}(" . join(", ", @arguments) . "));\n"; - } else { - $getterContentHead = "${assign}convertToUTF8String(item->${functionImplementationName}(" . join(", ", @arguments) . "));\n"; - } - } - push(@cBody, " ${getterContentHead}"); - } else { - my $contentHead; - if ($prefix eq "get_") { - my ($functionName, @arguments) = $codeGenerator->GetterExpression(\%implIncludes, $interfaceName, $function); - push(@arguments, @callImplParams); - if ($function->signature->extendedAttributes->{"ImplementedBy"}) { - my $implementedBy = $function->signature->extendedAttributes->{"ImplementedBy"}; - $implIncludes{"${implementedBy}.h"} = 1; - unshift(@arguments, "item"); - $functionName = "WebCore::${implementedBy}::${functionName}"; - } else { - $functionName = "item->${functionName}"; - } - $contentHead = "${assign}${assignPre}${functionName}(" . join(", ", @arguments) . "${assignPost});\n"; - } elsif ($prefix eq "set_") { - my ($functionName, @arguments) = $codeGenerator->SetterExpression(\%implIncludes, $interfaceName, $function); - push(@arguments, @callImplParams); - if ($function->signature->extendedAttributes->{"ImplementedBy"}) { - my $implementedBy = $function->signature->extendedAttributes->{"ImplementedBy"}; - $implIncludes{"${implementedBy}.h"} = 1; - unshift(@arguments, "item"); - $functionName = "WebCore::${implementedBy}::${functionName}"; - $contentHead = "${assign}${assignPre}${functionName}(" . join(", ", @arguments) . "${assignPost});\n"; - } else { - $functionName = "item->${functionName}"; - $contentHead = "${assign}${assignPre}${functionName}(" . join(", ", @arguments) . "${assignPost});\n"; - } - } else { - my @arguments = @callImplParams; - if ($function->signature->extendedAttributes->{"ImplementedBy"}) { - my $implementedBy = $function->signature->extendedAttributes->{"ImplementedBy"}; - $implIncludes{"${implementedBy}.h"} = 1; - unshift(@arguments, "item"); - $contentHead = "${assign}${assignPre}WebCore::${implementedBy}::${functionImplementationName}(" . join(", ", @arguments) . "${assignPost});\n"; - } else { - $contentHead = "${assign}${assignPre}item->${functionImplementationName}(" . join(", ", @arguments) . "${assignPost});\n"; - } - } - push(@cBody, " ${contentHead}"); - - if($raisesException) { - my $exceptionHandling = << "EOF"; - if (ec) { - WebCore::ExceptionCodeDescription ecdesc(ec); - g_set_error_literal(error, g_quark_from_string("WEBKIT_DOM"), ecdesc.code, ecdesc.name); - } -EOF - push(@cBody, $exceptionHandling); - } - } - - if ($returnType ne "void" && !$functionHasCustomReturn) { - if ($functionSigType ne "any") { - if ($returnValueIsGDOMType) { - push(@cBody, " return WebKit::kit(gobjectResult.get());\n"); - } else { - push(@cBody, " return result;\n"); - } - } else { - push(@cBody, " return 0; // TODO: return canvas object\n"); - } - } - - if ($conditionalString) { - push(@cBody, "#else\n"); - push(@cBody, @conditionalWarn) if scalar(@conditionalWarn); - if ($returnType ne "void") { - if ($codeGenerator->IsNonPointerType($functionSigType)) { - push(@cBody, " return static_cast<${returnType}>(0);\n"); - } else { - push(@cBody, " return 0;\n"); - } - } - push(@cBody, "#endif /* ${conditionalString} */\n"); - } - - if ($parentConditionalString) { - push(@cBody, "#else\n"); - push(@cBody, @parentConditionalWarn) if scalar(@parentConditionalWarn); - if ($returnType ne "void") { - if ($codeGenerator->IsNonPointerType($functionSigType)) { - push(@cBody, " return static_cast<${returnType}>(0);\n"); - } else { - push(@cBody, " return 0;\n"); - } - } - push(@cBody, "#endif /* ${parentConditionalString} */\n"); - } - - push(@cBody, "}\n\n"); -} - -sub ClassHasFunction { - my ($class, $name) = @_; - - foreach my $function (@{$class->functions}) { - if ($function->signature->name eq $name) { - return 1; - } - } - - return 0; -} - -sub GenerateFunctions { - my ($object, $interfaceName, $interface) = @_; - - foreach my $function (@{$interface->functions}) { - $object->GenerateFunction($interfaceName, $function, "", $interface); - } - - TOP: - foreach my $attribute (@{$interface->attributes}) { - if (SkipAttribute($attribute)) { - next TOP; - } - - if ($attribute->signature->name eq "type") { - # This will conflict with the get_type() function we define to return a GType - # according to GObject conventions. Skip this for now. - next TOP; - } - - my $attrNameUpper = $codeGenerator->WK_ucfirst($attribute->signature->name); - my $getname = "get${attrNameUpper}"; - my $setname = "set${attrNameUpper}"; - if (ClassHasFunction($interface, $getname) || ClassHasFunction($interface, $setname)) { - # Very occasionally an IDL file defines getter/setter functions for one of its - # attributes; in this case we don't need to autogenerate the getter/setter. - next TOP; - } - - # Generate an attribute getter. For an attribute "foo", this is a function named - # "get_foo" which calls a DOM class method named foo(). - my $function = new domFunction(); - $function->signature($attribute->signature); - $function->signature->extendedAttributes({%{$attribute->signature->extendedAttributes}}); - if ($attribute->signature->extendedAttributes->{"GetterRaisesException"}) { - $function->signature->extendedAttributes->{"RaisesException"} = "VALUE_IS_MISSING"; - } - $object->GenerateFunction($interfaceName, $function, "get_", $interface); - - # FIXME: We are not generating setters for 'Replaceable' - # attributes now, but we should somehow. - my $custom = $attribute->signature->extendedAttributes->{"CustomSetter"}; - if ($attribute->isReadOnly || $attribute->signature->extendedAttributes->{"Replaceable"} || $custom) { - next TOP; - } - - # Generate an attribute setter. For an attribute, "foo", this is a function named - # "set_foo" which calls a DOM class method named setFoo(). - $function = new domFunction(); - - $function->signature(new domSignature()); - $function->signature->name($attribute->signature->name); - $function->signature->type($attribute->signature->type); - $function->signature->extendedAttributes({%{$attribute->signature->extendedAttributes}}); - - my $param = new domSignature(); - $param->name("value"); - $param->type($attribute->signature->type); - my %attributes = (); - $param->extendedAttributes(\%attributes); - my $arrayRef = $function->parameters; - push(@$arrayRef, $param); - - if ($attribute->signature->extendedAttributes->{"SetterRaisesException"}) { - $function->signature->extendedAttributes->{"RaisesException"} = "VALUE_IS_MISSING"; - } else { - delete $function->signature->extendedAttributes->{"RaisesException"}; - } - - $object->GenerateFunction($interfaceName, $function, "set_", $interface); - } -} - -sub GenerateCFile { - my ($object, $interfaceName, $parentClassName, $parentGObjType, $interface) = @_; - - if ($interface->extendedAttributes->{"EventTarget"}) { - $object->GenerateEventTargetIface($interface); - } - - my $implContent = ""; - - my $decamelize = decamelize($interfaceName); - my $clsCaps = uc($decamelize); - my $lowerCaseIfaceName = "webkit_dom_$decamelize"; - my $parentImplClassName = GetParentImplClassName($interface); - my $baseClassName = GetBaseClass($parentImplClassName, $interface); - - # Add a private struct only for direct subclasses of Object so that we can use RefPtr - # for the WebCore wrapped object and make sure we only increment the reference counter once. - if ($parentImplClassName eq "Object") { - my $conditionalString = $codeGenerator->GenerateConditionalString($interface); - push(@cStructPriv, "#define WEBKIT_DOM_${clsCaps}_GET_PRIVATE(obj) G_TYPE_INSTANCE_GET_PRIVATE(obj, WEBKIT_TYPE_DOM_${clsCaps}, ${className}Private)\n\n"); - push(@cStructPriv, "typedef struct _${className}Private {\n"); - push(@cStructPriv, "#if ${conditionalString}\n") if $conditionalString; - push(@cStructPriv, " RefPtr<WebCore::${interfaceName}> coreObject;\n"); - push(@cStructPriv, "#endif // ${conditionalString}\n") if $conditionalString; - push(@cStructPriv, "} ${className}Private;\n\n"); - } - - $implContent = << "EOF"; -${defineTypeMacro}(${className}, ${lowerCaseIfaceName}, ${parentGObjType}${defineTypeInterfaceImplementation} - -EOF - push(@cBodyProperties, $implContent); - - if ($parentImplClassName eq "Object") { - push(@cBodyPriv, "${className}* kit(WebCore::$interfaceName* obj)\n"); - push(@cBodyPriv, "{\n"); - push(@cBodyPriv, " if (!obj)\n"); - push(@cBodyPriv, " return 0;\n\n"); - push(@cBodyPriv, " if (gpointer ret = DOMObjectCache::get(obj))\n"); - push(@cBodyPriv, " return WEBKIT_DOM_${clsCaps}(ret);\n\n"); - if (IsPolymorphic($interfaceName)) { - push(@cBodyPriv, " return wrap(obj);\n"); - } else { - push(@cBodyPriv, " return wrap${interfaceName}(obj);\n"); - } - push(@cBodyPriv, "}\n\n"); - } else { - push(@cBodyPriv, "${className}* kit(WebCore::$interfaceName* obj)\n"); - push(@cBodyPriv, "{\n"); - if (!IsPolymorphic($baseClassName)) { - push(@cBodyPriv, " if (!obj)\n"); - push(@cBodyPriv, " return 0;\n\n"); - push(@cBodyPriv, " if (gpointer ret = DOMObjectCache::get(obj))\n"); - push(@cBodyPriv, " return WEBKIT_DOM_${clsCaps}(ret);\n\n"); - push(@cBodyPriv, " return wrap${interfaceName}(obj);\n"); - } else { - push(@cBodyPriv, " return WEBKIT_DOM_${clsCaps}(kit(static_cast<WebCore::$baseClassName*>(obj)));\n"); - } - push(@cBodyPriv, "}\n\n"); - } - - $implContent = << "EOF"; -WebCore::${interfaceName}* core(${className}* request) -{ - return request ? static_cast<WebCore::${interfaceName}*>(WEBKIT_DOM_OBJECT(request)->coreObject) : 0; -} - -${className}* wrap${interfaceName}(WebCore::${interfaceName}* coreObject) -{ - ASSERT(coreObject); - return WEBKIT_DOM_${clsCaps}(g_object_new(WEBKIT_TYPE_DOM_${clsCaps}, "core-object", coreObject, NULL)); -} - -EOF - push(@cBodyPriv, $implContent); - - $object->GenerateProperties($interfaceName, $interface); - $object->GenerateFunctions($interfaceName, $interface); -} - -sub GenerateEndHeader { - my ($object) = @_; - - #Header guard - my $guard = $className . "_h"; - - push(@hBody, "G_END_DECLS\n\n"); - push(@hPrefixGuardEnd, "#endif /* $guard */\n"); -} - -sub IsPolymorphic { - my $type = shift; - - return scalar(grep {$_ eq $type} qw(Blob Event HTMLCollection Node StyleSheet)); -} - -sub GenerateEventTargetIface { - my $object = shift; - my $interface = shift; - - my $interfaceName = $interface->name; - my $decamelize = decamelize($interfaceName); - my $conditionalString = $codeGenerator->GenerateConditionalString($interface); - my @conditionalWarn = GenerateConditionalWarning($interface); - - $implIncludes{"GObjectEventListener.h"} = 1; - $implIncludes{"WebKitDOMEventTarget.h"} = 1; - $implIncludes{"WebKitDOMEventPrivate.h"} = 1; - - push(@cBodyProperties, "static gboolean webkit_dom_${decamelize}_dispatch_event(WebKitDOMEventTarget* target, WebKitDOMEvent* event, GError** error)\n{\n"); - push(@cBodyProperties, "#if ${conditionalString}\n") if $conditionalString; - push(@cBodyProperties, " WebCore::Event* coreEvent = WebKit::core(event);\n"); - push(@cBodyProperties, " WebCore::${interfaceName}* coreTarget = static_cast<WebCore::${interfaceName}*>(WEBKIT_DOM_OBJECT(target)->coreObject);\n\n"); - push(@cBodyProperties, " WebCore::ExceptionCode ec = 0;\n"); - push(@cBodyProperties, " gboolean result = coreTarget->dispatchEvent(coreEvent, ec);\n"); - push(@cBodyProperties, " if (ec) {\n WebCore::ExceptionCodeDescription description(ec);\n"); - push(@cBodyProperties, " g_set_error_literal(error, g_quark_from_string(\"WEBKIT_DOM\"), description.code, description.name);\n }\n"); - push(@cBodyProperties, " return result;\n"); - push(@cBodyProperties, "#else\n") if $conditionalString; - push(@cBodyProperties, @conditionalWarn) if scalar(@conditionalWarn); - push(@cBodyProperties, " return false;\n#endif // ${conditionalString}\n") if $conditionalString; - push(@cBodyProperties, "}\n\n"); - - push(@cBodyProperties, "static gboolean webkit_dom_${decamelize}_add_event_listener(WebKitDOMEventTarget* target, const char* eventName, GClosure* handler, gboolean useCapture)\n{\n"); - push(@cBodyProperties, "#if ${conditionalString}\n") if $conditionalString; - push(@cBodyProperties, " WebCore::${interfaceName}* coreTarget = static_cast<WebCore::${interfaceName}*>(WEBKIT_DOM_OBJECT(target)->coreObject);\n"); - push(@cBodyProperties, " return WebCore::GObjectEventListener::addEventListener(G_OBJECT(target), coreTarget, eventName, handler, useCapture);\n"); - push(@cBodyProperties, "#else\n") if $conditionalString; - push(@cBodyProperties, @conditionalWarn) if scalar(@conditionalWarn); - push(@cBodyProperties, " return false;\n#endif // ${conditionalString}\n") if $conditionalString; - push(@cBodyProperties, "}\n\n"); - - push(@cBodyProperties, "static gboolean webkit_dom_${decamelize}_remove_event_listener(WebKitDOMEventTarget* target, const char* eventName, GClosure* handler, gboolean useCapture)\n{\n"); - push(@cBodyProperties, "#if ${conditionalString}\n") if $conditionalString; - push(@cBodyProperties, " WebCore::${interfaceName}* coreTarget = static_cast<WebCore::${interfaceName}*>(WEBKIT_DOM_OBJECT(target)->coreObject);\n"); - push(@cBodyProperties, " return WebCore::GObjectEventListener::removeEventListener(G_OBJECT(target), coreTarget, eventName, handler, useCapture);\n"); - push(@cBodyProperties, "#else\n") if $conditionalString; - push(@cBodyProperties, @conditionalWarn) if scalar(@conditionalWarn); - push(@cBodyProperties, " return false;\n#endif // ${conditionalString}\n") if $conditionalString; - push(@cBodyProperties, "}\n\n"); - - push(@cBodyProperties, "static void webkit_dom_event_target_init(WebKitDOMEventTargetIface* iface)\n{\n"); - push(@cBodyProperties, " iface->dispatch_event = webkit_dom_${decamelize}_dispatch_event;\n"); - push(@cBodyProperties, " iface->add_event_listener = webkit_dom_${decamelize}_add_event_listener;\n"); - push(@cBodyProperties, " iface->remove_event_listener = webkit_dom_${decamelize}_remove_event_listener;\n}\n\n"); - - $defineTypeMacro = "G_DEFINE_TYPE_WITH_CODE"; - $defineTypeInterfaceImplementation = ", G_IMPLEMENT_INTERFACE(WEBKIT_TYPE_DOM_EVENT_TARGET, webkit_dom_event_target_init))"; -} - -sub Generate { - my ($object, $interface) = @_; - - my $parentClassName = GetParentClassName($interface); - my $parentGObjType = GetParentGObjType($interface); - my $interfaceName = $interface->name; - my $parentImplClassName = GetParentImplClassName($interface); - my $baseClassName = GetBaseClass($parentImplClassName, $interface); - - # Add the default impl header template - @cPrefix = split("\r", $licenceTemplate); - push(@cPrefix, "\n"); - - $implIncludes{"DOMObjectCache.h"} = 1; - $implIncludes{"WebKitDOMPrivate.h"} = 1; - $implIncludes{"gobject/ConvertToUTF8String.h"} = 1; - $implIncludes{"${className}Private.h"} = 1; - $implIncludes{"Document.h"} = 1; - $implIncludes{"JSMainThreadExecState.h"} = 1; - $implIncludes{"ExceptionCode.h"} = 1; - $implIncludes{"CSSImportRule.h"} = 1; - if ($parentImplClassName ne "Object" and IsPolymorphic($baseClassName)) { - $implIncludes{"WebKitDOM${baseClassName}Private.h"} = 1; - } - - $hdrIncludes{"webkitdom/${parentClassName}.h"} = 1; - - $object->GenerateHeader($interfaceName, $parentClassName); - $object->GenerateCFile($interfaceName, $parentClassName, $parentGObjType, $interface); - $object->GenerateEndHeader(); -} - -sub WriteData { - my $object = shift; - my $interface = shift; - my $outputDir = shift; - mkdir $outputDir; - - # Write a private header. - my $interfaceName = $interface->name; - my $filename = "$outputDir/" . $className . "Private.h"; - my $guard = "${className}Private_h"; - - # Add the guard if the 'Conditional' extended attribute exists - my $conditionalString = $codeGenerator->GenerateConditionalString($interface); - - open(PRIVHEADER, ">$filename") or die "Couldn't open file $filename for writing"; - - print PRIVHEADER split("\r", $licenceTemplate); - print PRIVHEADER "\n"; - - my $text = << "EOF"; -#ifndef $guard -#define $guard - -#include "${interfaceName}.h" -#include <webkitdom/${className}.h> -EOF - - print PRIVHEADER $text; - print PRIVHEADER "#if ${conditionalString}\n" if $conditionalString; - print PRIVHEADER map { "#include \"$_\"\n" } sort keys(%hdrPropIncludes); - print PRIVHEADER "\n"; - $text = << "EOF"; -namespace WebKit { -${className}* wrap${interfaceName}(WebCore::${interfaceName}*); -${className}* kit(WebCore::${interfaceName}*); -WebCore::${interfaceName}* core(${className}*); -EOF - - print PRIVHEADER $text; - - $text = << "EOF"; -} // namespace WebKit - -EOF - - print PRIVHEADER $text; - print PRIVHEADER "#endif /* ${conditionalString} */\n\n" if $conditionalString; - print PRIVHEADER "#endif /* ${guard} */\n"; - - close(PRIVHEADER); - - my $basename = FileNamePrefix . $interfaceName; - $basename =~ s/_//g; - - # Write public header. - my $fullHeaderFilename = "$outputDir/" . $basename . ".h"; - my $installedHeaderFilename = "${basename}.h"; - open(HEADER, ">$fullHeaderFilename") or die "Couldn't open file $fullHeaderFilename"; - - print HEADER @hPrefix; - print HEADER @hPrefixGuard; - print HEADER "#include <glib-object.h>\n"; - print HEADER map { "#include <$_>\n" } sort keys(%hdrIncludes); - print HEADER "#include <webkitdom/webkitdomdefines.h>\n\n"; - print HEADER @hBodyPre; - print HEADER @hBody; - print HEADER @hPrefixGuardEnd; - - close(HEADER); - - # Write the implementation sources - my $implFileName = "$outputDir/" . $basename . ".cpp"; - open(IMPL, ">$implFileName") or die "Couldn't open file $implFileName"; - - print IMPL @cPrefix; - print IMPL "#include \"config.h\"\n"; - print IMPL "#include \"$installedHeaderFilename\"\n\n"; - - # Remove the implementation header from the list of included files. - %includesCopy = %implIncludes; - print IMPL map { "#include \"$_\"\n" } sort keys(%includesCopy); - - print IMPL "#include <wtf/GetPtr.h>\n"; - print IMPL "#include <wtf/RefPtr.h>\n\n"; - print IMPL @cStructPriv; - print IMPL "#if ${conditionalString}\n\n" if $conditionalString; - - print IMPL "namespace WebKit {\n\n"; - print IMPL @cBodyPriv; - print IMPL "} // namespace WebKit\n\n"; - print IMPL "#endif // ${conditionalString}\n\n" if $conditionalString; - - print IMPL @cBodyProperties; - print IMPL @cBody; - - close(IMPL); - - # Write a symbols file. - my $symbolsFileName = "$outputDir/" . $basename . ".symbols"; - open(SYM, ">$symbolsFileName") or die "Couldn't open file $symbolsFileName"; - print SYM @symbols; - close(SYM); - - %implIncludes = (); - %hdrIncludes = (); - @hPrefix = (); - @hBody = (); - - @cPrefix = (); - @cBody = (); - @cBodyPriv = (); - @cBodyProperties = (); - @cStructPriv = (); - - @symbols = (); -} - -sub GenerateInterface { - my ($object, $interface, $defines) = @_; - - # Set up some global variables - $className = GetClassName($interface->name); - - $object->Generate($interface); -} - -1; |