1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591 |
- # 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);
- # List of function parameters that are allowed to be NULL
- my $canBeNullParams = {
- 'webkit_dom_document_evaluate' => ['inResult', 'resolver'],
- 'webkit_dom_node_insert_before' => ['refChild'],
- 'webkit_dom_dom_window_get_computed_style' => ['pseudoElement']
- };
- # 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" if @{$interface->parents} eq 0;
- return "WebKitDOM" . $interface->parents(0);
- }
- sub GetParentImplClassName {
- my $interface = shift;
- return "Object" if @{$interface->parents} eq 0;
- return $interface->parents(0);
- }
- sub IsBaseType
- {
- my $type = shift;
- return 1 if $baseTypeHash{$type};
- return 0;
- }
- sub GetBaseClass
- {
- $parent = shift;
- return $parent if $parent eq "Object" or IsBaseType($parent);
- return "Event" if $parent eq "UIEvent" or $parent eq "MouseEvent";
- 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;
- $s;
- }
- sub FixUpDecamelizedName {
- my $classname = shift;
- # FIXME: try to merge this somehow with the fixes in ClassNameToGobjectType
- $classname =~ s/x_path/xpath/;
- $classname =~ s/web_kit/webkit/;
- $classname =~ s/htmli_frame/html_iframe/;
- return $classname;
- }
- 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 ClassNameToGObjectType {
- my $className = shift;
- my $CLASS_NAME = uc(decamelize($className));
- # Fixup: with our prefix being 'WebKitDOM' decamelize can't get
- # WebKitDOMCSS and similar names right, so we have to fix it
- # manually.
- $CLASS_NAME =~ s/DOMCSS/DOM_CSS/;
- $CLASS_NAME =~ s/DOMHTML/DOM_HTML/;
- $CLASS_NAME =~ s/DOMDOM/DOM_DOM/;
- $CLASS_NAME =~ s/DOMCDATA/DOM_CDATA/;
- $CLASS_NAME =~ s/DOMX_PATH/DOM_XPATH/;
- $CLASS_NAME =~ s/DOM_WEB_KIT/DOM_WEBKIT/;
- $CLASS_NAME =~ s/DOMUI/DOM_UI/;
- $CLASS_NAME =~ s/HTMLI_FRAME/HTML_IFRAME/;
- return $CLASS_NAME;
- }
- sub GetParentGObjType {
- my $interface = shift;
- return "WEBKIT_TYPE_DOM_OBJECT" if @{$interface->parents} eq 0;
- return "WEBKIT_TYPE_DOM_" . ClassNameToGObjectType($interface->parents(0));
- }
- 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"}
- || $attribute->signature->extendedAttributes->{"CustomSetter"}) {
- 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;
- }
- # 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 $function = 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;
- }
- 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;
- }
- # This is for DataTransferItemList.idl add(File) method
- if ($functionName eq "webkit_dom_data_transfer_item_list_add" &&
- @{$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;
- }
- # 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>.
- foreach my $param (@{$function->parameters}) {
- if ($codeGenerator->IsCallbackInterface($param->type) ||
- $param->extendedAttributes->{"Clamp"} ||
- $param->type eq "MediaQueryListListener" ||
- $codeGenerator->GetSequenceType($param->type)) {
- 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 GetReadableProperties {
- my $properties = shift;
- my @result = ();
- foreach my $property (@{$properties}) {
- if (!SkipAttribute($property)) {
- push(@result, $property);
- }
- }
- return @result;
- }
- sub GetWriteableProperties {
- my $properties = shift;
- my @result = ();
- foreach my $property (@{$properties}) {
- my $gtype = GetGValueTypeName($property->signature->type);
- my $hasGtypeSignature = ($gtype eq "boolean" || $gtype eq "float" || $gtype eq "double" ||
- $gtype eq "uint64" || $gtype eq "ulong" || $gtype eq "long" ||
- $gtype eq "uint" || $gtype eq "ushort" || $gtype eq "int8" ||
- $gtype eq "uint8" || $gtype eq "uchar" || $gtype eq "char" ||
- $gtype eq "string");
- # FIXME: We are not generating setters for 'Replaceable'
- # attributes now, but we should somehow.
- my $replaceable = $property->signature->extendedAttributes->{"Replaceable"};
- if (!$property->isReadOnly && $hasGtypeSignature && !$replaceable) {
- push(@result, $property);
- }
- }
- return @result;
- }
- 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 = !$attribute->isReadOnly;
- my $const = "read-only ";
- my $custom = $attribute->signature->extendedAttributes->{"Custom"};
- if ($writeable && $custom) {
- $const = "read-only (due to custom functions needed in webkitdom)";
- return;
- }
- if ($writeable && !$custom) {
- $gparamflag = "WEBKIT_PARAM_READWRITE";
- $const = "read-write ";
- }
- my $type = GetGlibTypeName($propType);
- $nick = decamelize("${interfaceName}_${propName}");
- $long = "${const} ${type} ${interfaceName}.${propName}";
- 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 = "";
- my $done = 0;
- if ($gtype eq "string") {
- push(@txtGetProps, " g_value_take_string(value, convertToUTF8String(${getterFunctionName}(" . join(", ", @getterArguments) . ")));\n");
- $done = 1;
- } 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");
- $done = 1;
- }
- # FIXME: get rid of this glitch?
- my $_gtype = $gtype;
- if ($gtype eq "ushort") {
- $_gtype = "uint";
- }
- if (!$done) {
- if ($attribute->signature->extendedAttributes->{"ImplementedBy"}) {
- my $implementedBy = $attribute->signature->extendedAttributes->{"ImplementedBy"};
- $implIncludes{"${implementedBy}.h"} = 1;
- push(@txtGetProps, " g_value_set_$_gtype(value, ${convertFunction}${getterFunctionName}(" . join(", ", @getterArguments) . ")${postConvertFunction});\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 %param_spec_options = ("int", "G_MININT, /* min */\nG_MAXINT, /* max */\n0, /* default */",
- "int8", "G_MININT8, /* min */\nG_MAXINT8, /* max */\n0, /* default */",
- "boolean", "FALSE, /* default */",
- "float", "-G_MAXFLOAT, /* min */\nG_MAXFLOAT, /* max */\n0.0, /* default */",
- "double", "-G_MAXDOUBLE, /* min */\nG_MAXDOUBLE, /* max */\n0.0, /* default */",
- "uint64", "0, /* min */\nG_MAXUINT64, /* min */\n0, /* default */",
- "long", "G_MINLONG, /* min */\nG_MAXLONG, /* max */\n0, /* default */",
- "int64", "G_MININT64, /* min */\nG_MAXINT64, /* max */\n0, /* default */",
- "ulong", "0, /* min */\nG_MAXULONG, /* max */\n0, /* default */",
- "uint", "0, /* min */\nG_MAXUINT, /* max */\n0, /* default */",
- "uint8", "0, /* min */\nG_MAXUINT8, /* max */\n0, /* default */",
- "ushort", "0, /* min */\nG_MAXUINT16, /* max */\n0, /* default */",
- "uchar", "G_MININT8, /* min */\nG_MAXINT8, /* max */\n0, /* default */",
- "char", "0, /* min */\nG_MAXUINT8, /* max */\n0, /* default */",
- "string", "\"\", /* default */",
- "object", "WEBKIT_TYPE_DOM_${ucPropGType}, /* gobject type */");
- my $txtInstallProp = << "EOF";
- g_object_class_install_property(gobjectClass,
- ${propEnum},
- g_param_spec_${_gtype}("${propName}", /* name */
- "$nick", /* short description */
- "$long", /* longer - could do with some extra doc stuff here */
- $param_spec_options{$gtype}
- ${gparamflag}));
- EOF
- push(@txtInstallProps, $txtInstallProp);
- }
- sub GenerateProperties {
- my ($object, $interfaceName, $interface) = @_;
- my $clsCaps = substr(ClassNameToGObjectType($className), 12);
- my $lowerCaseIfaceName = "webkit_dom_" . (FixUpDecamelizedName(decamelize($interfaceName)));
- 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 = GetReadableProperties($interface->attributes);
- my @writeableProperties = GetWriteableProperties(\@readableProperties);
- 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) {
- if ($attribute->signature->type ne "EventListener" &&
- $attribute->signature->type ne "MediaQueryListListener") {
- 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 = FixUpDecamelizedName(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(FixUpDecamelizedName(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(/$paramName/, @{$canBeNullParams->{$functionName}}));
- }
- return 0;
- }
- sub GenerateFunction {
- my ($object, $interfaceName, $function, $prefix, $parentNode) = @_;
- my $decamelize = FixUpDecamelizedName(decamelize($interfaceName));
- if ($object eq "MediaQueryListListener") {
- return;
- }
- if (SkipFunction($function, $decamelize, $prefix)) {
- return;
- }
- return if ($function->signature->name eq "set" and $parentNode->extendedAttributes->{"TypedArray"});
- 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 @callImplParams;
- foreach my $param (@{$function->parameters}) {
- my $paramIDLType = $param->type;
- if ($paramIDLType eq "EventListener" || $paramIDLType eq "MediaQueryListListener") {
- # EventListeners are handled elsewhere.
- return;
- }
- my $paramType = GetGlibTypeName($paramIDLType);
- my $const = $paramType eq "gchar*" ? "const " : "";
- my $paramName = $param->name;
- $functionSig .= ", ${const}$paramType $paramName";
- 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;
- # 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;
- push(@hBody, " * \@${paramName}: A #${paramType}\n");
- }
- push(@hBody, " * \@error: #GError\n") if $raisesException;
- push(@hBody, " *\n");
- if (IsGDOMClassType($function->signature->type)) {
- push(@hBody, " * Returns: (transfer none):\n");
- } else {
- push(@hBody, " * Returns:\n");
- }
- push(@hBody, " *\n");
- push(@hBody, "**/\n");
- push(@hBody, "WEBKIT_API $returnType\n$functionName($functionSig);\n");
- push(@hBody, "\n");
- push(@cBody, "$returnType\n$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 $paramTypeIsPrimitive = $codeGenerator->IsPrimitiveType($paramIDLType);
- my $paramIsGDOMType = IsGDOMClassType($paramIDLType);
- if (!$paramTypeIsPrimitive) {
- $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) ||
- $attribute->signature->type eq "EventListener" ||
- $attribute->signature->type eq "MediaQueryListListener") {
- 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.
- || $attribute->signature->name eq "URL" # TODO: handle this
- ) {
- 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.
- if ($attribute->isReadOnly || $attribute->signature->extendedAttributes->{"Replaceable"}) {
- 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 $clsCaps = uc(FixUpDecamelizedName(decamelize($interfaceName)));
- my $lowerCaseIfaceName = "webkit_dom_" . FixUpDecamelizedName(decamelize($interfaceName));
- my $parentImplClassName = GetParentImplClassName($interface);
- my $baseClassName = GetBaseClass($parentImplClassName);
- # 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 = FixUpDecamelizedName(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 void 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, " 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, "#else\n") if $conditionalString;
- push(@cBodyProperties, @conditionalWarn) if scalar(@conditionalWarn);
- push(@cBodyProperties, "#endif // ${conditionalString}\n") if $conditionalString;
- push(@cBodyProperties, "}\n\n");
- push(@cBodyProperties, "static gboolean webkit_dom_${decamelize}_add_event_listener(WebKitDOMEventTarget* target, const char* eventName, GCallback handler, gboolean bubble, gpointer userData)\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, bubble, userData);\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, GCallback handler, gboolean bubble)\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, bubble);\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);
- # 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{"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);
- %implIncludes = ();
- %hdrIncludes = ();
- @hPrefix = ();
- @hBody = ();
- @cPrefix = ();
- @cBody = ();
- @cBodyPriv = ();
- @cBodyProperties = ();
- @cStructPriv = ();
- }
- sub GenerateInterface {
- my ($object, $interface, $defines) = @_;
- # Set up some global variables
- $className = GetClassName($interface->name);
- $object->Generate($interface);
- }
- 1;
|