Home | History | Annotate | Download | only in scripts
      1 # 
      2 # Copyright (C) 2005, 2006 Nikolas Zimmermann <zimmermann (at] kde.org>
      3 # Copyright (C) 2006 Anders Carlsson <andersca (at] mac.com> 
      4 # Copyright (C) 2006, 2007 Samuel Weinig <sam (at] webkit.org>
      5 # Copyright (C) 2006 Alexey Proskuryakov <ap (at] webkit.org>
      6 # Copyright (C) 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
      7 # Copyright (C) 2009 Cameron McCormack <cam (at] mcc.id.au>
      8 # Copyright (C) 2010 Google Inc.
      9 # Copyright (C) Research In Motion Limited 2010. All rights reserved.
     10 #
     11 # This library is free software; you can redistribute it and/or
     12 # modify it under the terms of the GNU Library General Public
     13 # License as published by the Free Software Foundation; either
     14 # version 2 of the License, or (at your option) any later version.
     15 # 
     16 # This library is distributed in the hope that it will be useful,
     17 # but WITHOUT ANY WARRANTY; without even the implied warranty of
     18 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     19 # Library General Public License for more details.
     20 # 
     21 # You should have received a copy of the GNU Library General Public License
     22 # along with this library; see the file COPYING.LIB.  If not, write to
     23 # the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     24 # Boston, MA 02110-1301, USA.
     25 #
     26 
     27 package CodeGeneratorObjC;
     28 
     29 # Global Variables
     30 my $module = "";
     31 my $outputDir = "";
     32 my $writeDependencies = 0;
     33 my %publicInterfaces = ();
     34 my $newPublicClass = 0;
     35 my $interfaceAvailabilityVersion = "";
     36 my $isProtocol = 0;
     37 my $noImpl = 0;
     38 
     39 my @headerContentHeader = ();
     40 my @headerContent = ();
     41 my %headerForwardDeclarations = ();
     42 my %headerForwardDeclarationsForProtocols = ();
     43 
     44 my @privateHeaderContentHeader = ();
     45 my @privateHeaderContent = ();
     46 my %privateHeaderForwardDeclarations = ();
     47 my %privateHeaderForwardDeclarationsForProtocols = ();
     48 
     49 my @internalHeaderContent = ();
     50 
     51 my @implContentHeader = ();
     52 my @implContent = ();
     53 my %implIncludes = ();
     54 my @depsContent = ();
     55 
     56 # Hashes
     57 my %protocolTypeHash = ("XPathNSResolver" => 1, "EventListener" => 1, "EventTarget" => 1, "NodeFilter" => 1,
     58                         "SVGLocatable" => 1, "SVGTransformable" => 1, "SVGStylable" => 1, "SVGFilterPrimitiveStandardAttributes" => 1, 
     59                         "SVGTests" => 1, "SVGLangSpace" => 1, "SVGExternalResourcesRequired" => 1, "SVGURIReference" => 1,
     60                         "SVGZoomAndPan" => 1, "SVGFitToViewBox" => 1, "SVGAnimatedPathData" => 1, "ElementTimeControl" => 1);
     61 my %nativeObjCTypeHash = ("URL" => 1, "Color" => 1);
     62 
     63 # FIXME: this should be replaced with a function that recurses up the tree
     64 # to find the actual base type.
     65 my %baseTypeHash = ("Object" => 1, "Node" => 1, "NodeList" => 1, "NamedNodeMap" => 1, "DOMImplementation" => 1,
     66                     "Event" => 1, "CSSRule" => 1, "CSSValue" => 1, "StyleSheet" => 1, "MediaList" => 1,
     67                     "Counter" => 1, "Rect" => 1, "RGBColor" => 1, "XPathExpression" => 1, "XPathResult" => 1,
     68                     "NodeIterator" => 1, "TreeWalker" => 1, "AbstractView" => 1, "Blob" => 1,
     69                     "SVGAngle" => 1, "SVGAnimatedAngle" => 1, "SVGAnimatedBoolean" => 1, "SVGAnimatedEnumeration" => 1,
     70                     "SVGAnimatedInteger" => 1, "SVGAnimatedLength" => 1, "SVGAnimatedLengthList" => 1,
     71                     "SVGAnimatedNumber" => 1, "SVGAnimatedNumberList" => 1,
     72                     "SVGAnimatedPreserveAspectRatio" => 1, "SVGAnimatedRect" => 1, "SVGAnimatedString" => 1,
     73                     "SVGAnimatedTransformList" => 1, "SVGLength" => 1, "SVGLengthList" => 1, "SVGMatrix" => 1,
     74                     "SVGNumber" => 1, "SVGNumberList" => 1, "SVGPathSeg" => 1, "SVGPathSegList" => 1, "SVGPoint" => 1,
     75                     "SVGPointList" => 1, "SVGPreserveAspectRatio" => 1, "SVGRect" => 1, "SVGRenderingIntent" => 1,
     76                     "SVGStringList" => 1, "SVGTransform" => 1, "SVGTransformList" => 1, "SVGUnitTypes" => 1);
     77 
     78 # Constants
     79 my $buildingForTigerOrEarlier = 1 if $ENV{"MACOSX_DEPLOYMENT_TARGET"} and $ENV{"MACOSX_DEPLOYMENT_TARGET"} <= 10.4;
     80 my $buildingForLeopardOrLater = 1 if $ENV{"MACOSX_DEPLOYMENT_TARGET"} and $ENV{"MACOSX_DEPLOYMENT_TARGET"} >= 10.5;
     81 my $exceptionInit = "WebCore::ExceptionCode ec = 0;";
     82 my $jsContextSetter = "WebCore::JSMainThreadNullState state;";
     83 my $exceptionRaiseOnError = "WebCore::raiseOnDOMError(ec);";
     84 my $assertMainThread = "{ DOM_ASSERT_MAIN_THREAD(); WebCoreThreadViolationCheckRoundOne(); }";
     85 
     86 my %conflictMethod = (
     87     # FIXME: Add C language keywords?
     88     # FIXME: Add other predefined types like "id"?
     89 
     90     "callWebScriptMethod:withArguments:" => "WebScriptObject",
     91     "evaluateWebScript:" => "WebScriptObject",
     92     "removeWebScriptKey:" => "WebScriptObject",
     93     "setException:" => "WebScriptObject",
     94     "setWebScriptValueAtIndex:value:" => "WebScriptObject",
     95     "stringRepresentation" => "WebScriptObject",
     96     "webScriptValueAtIndex:" => "WebScriptObject",
     97 
     98     "autorelease" => "NSObject",
     99     "awakeAfterUsingCoder:" => "NSObject",
    100     "class" => "NSObject",
    101     "classForCoder" => "NSObject",
    102     "conformsToProtocol:" => "NSObject",
    103     "copy" => "NSObject",
    104     "copyWithZone:" => "NSObject",
    105     "dealloc" => "NSObject",
    106     "description" => "NSObject",
    107     "doesNotRecognizeSelector:" => "NSObject",
    108     "encodeWithCoder:" => "NSObject",
    109     "finalize" => "NSObject",
    110     "forwardInvocation:" => "NSObject",
    111     "hash" => "NSObject",
    112     "init" => "NSObject",
    113     "initWithCoder:" => "NSObject",
    114     "isEqual:" => "NSObject",
    115     "isKindOfClass:" => "NSObject",
    116     "isMemberOfClass:" => "NSObject",
    117     "isProxy" => "NSObject",
    118     "methodForSelector:" => "NSObject",
    119     "methodSignatureForSelector:" => "NSObject",
    120     "mutableCopy" => "NSObject",
    121     "mutableCopyWithZone:" => "NSObject",
    122     "performSelector:" => "NSObject",
    123     "release" => "NSObject",
    124     "replacementObjectForCoder:" => "NSObject",
    125     "respondsToSelector:" => "NSObject",
    126     "retain" => "NSObject",
    127     "retainCount" => "NSObject",
    128     "self" => "NSObject",
    129     "superclass" => "NSObject",
    130     "zone" => "NSObject",
    131 );
    132 
    133 my $fatalError = 0;
    134 
    135 # Default License Templates
    136 my $headerLicenseTemplate = << "EOF";
    137 /*
    138  * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
    139  * Copyright (C) 2006 Samuel Weinig <sam.weinig\@gmail.com>
    140  *
    141  * Redistribution and use in source and binary forms, with or without
    142  * modification, are permitted provided that the following conditions
    143  * are met:
    144  * 1. Redistributions of source code must retain the above copyright
    145  *    notice, this list of conditions and the following disclaimer.
    146  * 2. Redistributions in binary form must reproduce the above copyright
    147  *    notice, this list of conditions and the following disclaimer in the
    148  *    documentation and/or other materials provided with the distribution.
    149  *
    150  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
    151  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    152  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
    153  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
    154  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
    155  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
    156  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
    157  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
    158  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    159  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    160  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
    161  */
    162 EOF
    163 
    164 my $implementationLicenseTemplate = << "EOF";
    165 /*
    166  * This file is part of the WebKit open source project.
    167  * This file has been generated by generate-bindings.pl. DO NOT MODIFY!
    168  *
    169  * Redistribution and use in source and binary forms, with or without
    170  * modification, are permitted provided that the following conditions
    171  * are met:
    172  * 1. Redistributions of source code must retain the above copyright
    173  *    notice, this list of conditions and the following disclaimer.
    174  * 2. Redistributions in binary form must reproduce the above copyright
    175  *    notice, this list of conditions and the following disclaimer in the
    176  *    documentation and/or other materials provided with the distribution.
    177  *
    178  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
    179  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    180  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
    181  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
    182  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
    183  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
    184  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
    185  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
    186  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    187  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    188  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
    189  */
    190 EOF
    191 
    192 # Default constructor
    193 sub new
    194 {
    195     my $object = shift;
    196     my $reference = { };
    197 
    198     $codeGenerator = shift;
    199     $outputDir = shift;
    200     shift; # $outputHeadersDir
    201     shift; # $useLayerOnTop
    202     shift; # $preprocessor
    203     $writeDependencies = shift;
    204 
    205     bless($reference, $object);
    206     return $reference;
    207 }
    208 
    209 sub finish
    210 {
    211     my $object = shift;
    212 }
    213 
    214 sub ReadPublicInterfaces
    215 {
    216     my $class = shift;
    217     my $superClass = shift;
    218     my $defines = shift;
    219     my $isProtocol = shift;
    220 
    221     my $found = 0;
    222     my $actualSuperClass;
    223     %publicInterfaces = ();
    224 
    225     my $fileName = "WebCore/bindings/objc/PublicDOMInterfaces.h";
    226     my $gccLocation = "";
    227     if ($ENV{CC}) {
    228         $gccLocation = $ENV{CC};
    229     } elsif (($Config::Config{'osname'}) =~ /solaris/i) {
    230         $gccLocation = "/usr/sfw/bin/gcc";
    231     } else {
    232         $gccLocation = "/usr/bin/gcc";
    233     }
    234     open FILE, "-|", $gccLocation, "-E", "-P", "-x", "objective-c",
    235         (map { "-D$_" } split(/ +/, $defines)), "-DOBJC_CODE_GENERATION", $fileName or die "Could not open $fileName";
    236     my @documentContent = <FILE>;
    237     close FILE;
    238 
    239     foreach $line (@documentContent) {
    240         if (!$isProtocol && $line =~ /^\s*\@interface\s*$class\s*:\s*(\w+)\s*([A-Z0-9_]*)/) {
    241             if ($superClass ne $1) {
    242                 warn "Public API change. Superclass for \"$class\" differs ($1 != $superClass)";
    243                 $fatalError = 1;
    244             }
    245 
    246             $interfaceAvailabilityVersion = $2 if defined $2;
    247             $found = 1;
    248             next;
    249         } elsif ($isProtocol && $line =~ /^\s*\@protocol $class\s*<[^>]+>\s*([A-Z0-9_]*)/) {
    250             $interfaceAvailabilityVersion = $1 if defined $1;
    251             $found = 1;
    252             next;
    253         }
    254 
    255         last if $found and $line =~ /^\s?\@end\s?$/;
    256 
    257         if ($found) {
    258             # trim whitspace
    259             $line =~ s/^\s+//;
    260             $line =~ s/\s+$//;
    261 
    262             my $availabilityMacro = "";
    263             $line =~ s/\s([A-Z0-9_]+)\s*;$/;/;
    264             $availabilityMacro = $1 if defined $1;
    265 
    266             $publicInterfaces{$line} = $availabilityMacro if length $line;
    267         }
    268     }
    269 
    270     # If this class was not found in PublicDOMInterfaces.h then it should be considered as an entirely new public class.
    271     $newPublicClass = !$found;
    272     $interfaceAvailabilityVersion = "WEBKIT_VERSION_LATEST" if $newPublicClass;
    273 }
    274 
    275 sub GenerateConditionalString
    276 {
    277     my $node = shift;
    278     my $conditional = $node->extendedAttributes->{"Conditional"};
    279     if ($conditional) {
    280         if ($conditional =~ /&/) {
    281             return "ENABLE(" . join(") && ENABLE(", split(/&/, $conditional)) . ")";
    282         } elsif ($conditional =~ /\|/) {
    283             return "ENABLE(" . join(") || ENABLE(", split(/\|/, $conditional)) . ")";
    284         } else {
    285             return "ENABLE(" . $conditional . ")";
    286         }
    287     } else {
    288         return "";
    289     }
    290 }
    291 
    292 # Params: 'domClass' struct
    293 sub GenerateInterface
    294 {
    295     my $object = shift;
    296     my $dataNode = shift;
    297     my $defines = shift;
    298 
    299     $fatalError = 0;
    300 
    301     my $name = $dataNode->name;
    302     my $className = GetClassName($name);
    303     my $parentClassName = "DOM" . GetParentImplClassName($dataNode);
    304     $isProtocol = $dataNode->extendedAttributes->{ObjCProtocol};
    305     $noImpl = $dataNode->extendedAttributes->{ObjCCustomImplementation} || $isProtocol;
    306 
    307     ReadPublicInterfaces($className, $parentClassName, $defines, $isProtocol);
    308 
    309     # Start actual generation..
    310     $object->GenerateHeader($dataNode);
    311     $object->GenerateImplementation($dataNode) unless $noImpl;
    312 
    313     # Write changes.
    314     $object->WriteData("DOM" . $name);
    315 
    316     # Check for missing public API
    317     if (keys %publicInterfaces > 0) {
    318         my $missing = join("\n", keys %publicInterfaces);
    319         warn "Public API change. There are missing public properties and/or methods from the \"$className\" class.\n$missing\n";
    320         $fatalError = 1;
    321     }
    322 
    323     die if $fatalError;
    324 }
    325 
    326 # Params: 'idlDocument' struct
    327 sub GenerateModule
    328 {
    329     my $object = shift;
    330     my $dataNode = shift;
    331 
    332     $module = $dataNode->module;
    333 }
    334 
    335 sub GetClassName
    336 {
    337     my $name = $codeGenerator->StripModule(shift);
    338 
    339     # special cases
    340     return "NSString" if $codeGenerator->IsStringType($name) or $name eq "SerializedScriptValue";
    341     return "NS$name" if IsNativeObjCType($name);
    342     return "BOOL" if $name eq "boolean";
    343     return "unsigned" if $name eq "unsigned long";
    344     return "int" if $name eq "long";
    345     return "NSTimeInterval" if $name eq "Date";
    346     return "DOMAbstractView" if $name eq "DOMWindow";
    347     return $name if $codeGenerator->IsPrimitiveType($name) or $name eq "DOMImplementation" or $name eq "DOMTimeStamp";
    348 
    349     # Default, assume Objective-C type has the same type name as
    350     # idl type prefixed with "DOM".
    351     return "DOM$name";
    352 }
    353 
    354 sub GetClassHeaderName
    355 {
    356     my $name = shift;
    357 
    358     return "DOMDOMImplementation" if $name eq "DOMImplementation";
    359     return $name;
    360 }
    361 
    362 sub GetImplClassName
    363 {
    364     my $name = $codeGenerator->StripModule(shift);
    365 
    366     return "DOMImplementationFront" if $name eq "DOMImplementation";
    367     return "DOMWindow" if $name eq "AbstractView";
    368     return $name;
    369 }
    370 
    371 sub GetParentImplClassName
    372 {
    373     my $dataNode = shift;
    374 
    375     return "Object" if @{$dataNode->parents} eq 0;
    376 
    377     my $parent = $codeGenerator->StripModule($dataNode->parents(0));
    378 
    379     # special cases
    380     return "Object" if $parent eq "HTMLCollection";
    381 
    382     return $parent;
    383 }
    384 
    385 sub GetParentAndProtocols
    386 {
    387     my $dataNode = shift;
    388     my $numParents = @{$dataNode->parents};
    389 
    390     my $parent = "";
    391     my @protocols = ();
    392     if ($numParents eq 0) {
    393         if ($isProtocol) {
    394             push(@protocols, "NSObject");
    395             push(@protocols, "NSCopying") if $dataNode->name eq "EventTarget";
    396         } else {
    397             $parent = "DOMObject";
    398         }
    399     } elsif ($numParents eq 1) {
    400         my $parentName = $codeGenerator->StripModule($dataNode->parents(0));
    401         if ($isProtocol) {
    402             die "Parents of protocols must also be protocols." unless IsProtocolType($parentName);
    403             push(@protocols, "DOM" . $parentName);
    404         } else {
    405             if (IsProtocolType($parentName)) {
    406                 push(@protocols, "DOM" . $parentName);
    407             } elsif ($parentName eq "HTMLCollection") {
    408                 $parent = "DOMObject";
    409             } else {
    410                 $parent = "DOM" . $parentName;
    411             }
    412         }
    413     } else {
    414         my @parents = @{$dataNode->parents};
    415         my $firstParent = $codeGenerator->StripModule(shift(@parents));
    416         if (IsProtocolType($firstParent)) {
    417             push(@protocols, "DOM" . $firstParent);
    418             if (!$isProtocol) {
    419                 $parent = "DOMObject";
    420             }
    421         } else {
    422             $parent = "DOM" . $firstParent;
    423         }
    424 
    425         foreach my $parentName (@parents) {
    426             $parentName = $codeGenerator->StripModule($parentName);
    427             die "Everything past the first class should be a protocol!" unless IsProtocolType($parentName);
    428 
    429             push(@protocols, "DOM" . $parentName);
    430         }
    431     }
    432 
    433     return ($parent, @protocols);
    434 }
    435 
    436 sub GetBaseClass
    437 {
    438     $parent = shift;
    439 
    440     return $parent if $parent eq "Object" or IsBaseType($parent);
    441     return "Event" if $parent eq "UIEvent";
    442     return "CSSValue" if $parent eq "SVGColor" or $parent eq "CSSValueList";
    443     return "Node";
    444 }
    445 
    446 sub IsBaseType
    447 {
    448     my $type = shift;
    449 
    450     return 1 if $baseTypeHash{$type};
    451     return 0;
    452 }
    453 
    454 sub IsProtocolType
    455 {
    456     my $type = shift;
    457 
    458     return 1 if $protocolTypeHash{$type};
    459     return 0;
    460 }
    461 
    462 sub IsNativeObjCType
    463 {
    464     my $type = shift;
    465 
    466     return 1 if $nativeObjCTypeHash{$type};
    467     return 0;
    468 }
    469 
    470 sub GetObjCType
    471 {
    472     my $type = shift;
    473     my $name = GetClassName($type);
    474 
    475     return "id <$name>" if IsProtocolType($type);
    476     return $name if $codeGenerator->IsPrimitiveType($type) or $type eq "DOMTimeStamp";
    477     return "unsigned short" if $type eq "CompareHow";
    478     return "$name *";
    479 }
    480 
    481 sub GetPropertyAttributes
    482 {
    483     my $type = $codeGenerator->StripModule(shift);
    484     my $readOnly = shift;
    485 
    486     my @attributes = ();
    487 
    488     push(@attributes, "readonly") if $readOnly;
    489 
    490     # FIXME: <rdar://problem/5049934> Consider using 'nonatomic' on the DOM @property declarations.
    491     if ($codeGenerator->IsStringType($type) || IsNativeObjCType($type)) {
    492         push(@attributes, "copy");
    493     } elsif ($codeGenerator->IsSVGAnimatedType($type)) {
    494         push(@attributes, "retain");
    495     } elsif (!$codeGenerator->IsStringType($type) && !$codeGenerator->IsPrimitiveType($type) && $type ne "DOMTimeStamp" && $type ne "CompareHow") {
    496         push(@attributes, "retain");
    497     }
    498 
    499     return "" unless @attributes > 0;
    500     return "(" . join(", ", @attributes) . ")";
    501 }
    502 
    503 sub ConversionNeeded
    504 {
    505     my $type = $codeGenerator->StripModule(shift);
    506 
    507     return !$codeGenerator->IsNonPointerType($type) && !$codeGenerator->IsStringType($type) && !IsNativeObjCType($type);
    508 }
    509 
    510 sub GetObjCTypeGetter
    511 {
    512     my $argName = shift;
    513     my $type = $codeGenerator->StripModule(shift);
    514 
    515     return $argName if $codeGenerator->IsPrimitiveType($type) or $codeGenerator->IsStringType($type) or IsNativeObjCType($type);
    516     return $argName . "Node" if $type eq "EventTarget";
    517     return "static_cast<WebCore::Range::CompareHow>($argName)" if $type eq "CompareHow";
    518     return "WTF::getPtr(nativeEventListener)" if $type eq "EventListener";
    519     return "WTF::getPtr(nativeNodeFilter)" if $type eq "NodeFilter";
    520     return "WTF::getPtr(nativeResolver)" if $type eq "XPathNSResolver";
    521     
    522     if ($type eq "SerializedScriptValue") {
    523         $implIncludes{"SerializedScriptValue.h"} = 1;
    524         return "WebCore::SerializedScriptValue::create(WTF::String($argName))";
    525     }
    526     return "core($argName)";
    527 }
    528 
    529 sub AddForwardDeclarationsForType
    530 {
    531     my $type = $codeGenerator->StripModule(shift);
    532     my $public = shift;
    533 
    534     return if $codeGenerator->IsNonPointerType($type) ;
    535 
    536     my $class = GetClassName($type);
    537 
    538     if (IsProtocolType($type)) {
    539         $headerForwardDeclarationsForProtocols{$class} = 1 if $public;
    540         $privateHeaderForwardDeclarationsForProtocols{$class} = 1 if !$public and !$headerForwardDeclarationsForProtocols{$class};
    541         return;
    542     }
    543 
    544     $headerForwardDeclarations{$class} = 1 if $public;
    545 
    546     # Private headers include the public header, so only add a forward declaration to the private header
    547     # if the public header does not already have the same forward declaration.
    548     $privateHeaderForwardDeclarations{$class} = 1 if !$public and !$headerForwardDeclarations{$class};
    549 }
    550 
    551 sub AddIncludesForType
    552 {
    553     my $type = $codeGenerator->StripModule(shift);
    554 
    555     return if $codeGenerator->IsNonPointerType($type);
    556 
    557     if (IsNativeObjCType($type)) {
    558         if ($type eq "Color") {
    559             $implIncludes{"ColorMac.h"} = 1;
    560         }
    561         return;
    562     }
    563 
    564     if ($codeGenerator->IsStringType($type)) {
    565         $implIncludes{"KURL.h"} = 1;
    566         return;
    567     }
    568 
    569     if ($type eq "DOMWindow") {
    570         $implIncludes{"DOMAbstractViewInternal.h"} = 1;
    571         $implIncludes{"DOMWindow.h"} = 1;
    572         return;
    573     }
    574 
    575     if ($type eq "DOMImplementation") {
    576         $implIncludes{"DOMDOMImplementationInternal.h"} = 1;
    577         $implIncludes{"DOMImplementationFront.h"} = 1;
    578         return;
    579     }
    580 
    581     if ($type eq "EventTarget") {
    582         $implIncludes{"Node.h"} = 1;
    583         $implIncludes{"DOMEventTarget.h"} = 1;
    584         return;
    585     }
    586 
    587     if ($codeGenerator->IsSVGAnimatedType($type)) {
    588         $implIncludes{"${type}.h"} = 1;
    589         $implIncludes{"DOM${type}Internal.h"} = 1;
    590         return;
    591     }
    592 
    593     if ($type =~ /(\w+)(Abs|Rel)$/) {
    594         $implIncludes{"$1.h"} = 1;
    595         $implIncludes{"DOM${type}Internal.h"} = 1;
    596         return;
    597     }
    598 
    599     if ($type eq "NodeFilter") {
    600         $implIncludes{"NodeFilter.h"} = 1;
    601         $implIncludes{"ObjCNodeFilterCondition.h"} = 1;
    602         return;
    603     }
    604 
    605     if ($type eq "EventListener") {
    606         $implIncludes{"EventListener.h"} = 1;
    607         $implIncludes{"ObjCEventListener.h"} = 1;
    608         return;
    609     }
    610 
    611     if ($type eq "XPathNSResolver") {
    612         $implIncludes{"DOMCustomXPathNSResolver.h"} = 1;
    613         $implIncludes{"XPathNSResolver.h"} = 1;
    614         return;
    615     }
    616 
    617     if ($type eq "SerializedScriptValue") {
    618         $implIncludes{"SerializedScriptValue.h"} = 1;
    619         return;
    620     }
    621 
    622     # FIXME: won't compile without these
    623     $implIncludes{"CSSMutableStyleDeclaration.h"} = 1 if $type eq "CSSStyleDeclaration";
    624     $implIncludes{"NameNodeList.h"} = 1 if $type eq "NodeList";
    625 
    626     # Default, include the same named file (the implementation) and the same name prefixed with "DOM". 
    627     $implIncludes{"$type.h"} = 1 if not $codeGenerator->AvoidInclusionOfType($type);
    628     $implIncludes{"DOM${type}Internal.h"} = 1;
    629 }
    630 
    631 sub GetSVGTypeWithNamespace
    632 {
    633     my $type = shift;
    634     my $typeWithNamespace = "WebCore::" . $codeGenerator->GetSVGTypeNeedingTearOff($type);
    635 
    636     # Special case for DOMSVGNumber
    637     $typeWithNamespace =~ s/</\<WebCore::/ unless $type eq "SVGNumber";
    638     return $typeWithNamespace;
    639 }
    640 
    641 sub GetSVGPropertyTypes
    642 {
    643     my $implType = shift;
    644 
    645     my $svgPropertyType;
    646     my $svgListPropertyType;
    647     my $svgNativeType;
    648 
    649     return ($svgPropertyType, $svgListPropertyType, $svgNativeType) if not $implType =~ /SVG/;
    650 
    651     $svgNativeType = $codeGenerator->GetSVGTypeNeedingTearOff($implType);
    652     return ($svgPropertyType, $svgListPropertyType, $svgNativeType) if not $svgNativeType;
    653 
    654     # Append space to avoid compilation errors when using  PassRefPtr<$svgNativeType>
    655     $svgNativeType = "WebCore::$svgNativeType ";
    656     $svgNativeType =~ s/</\<WebCore::/ if not $svgNativeType =~ /float/;
    657 
    658     my $svgWrappedNativeType = $codeGenerator->GetSVGWrappedTypeNeedingTearOff($implType);
    659     if ($svgNativeType =~ /SVGPropertyTearOff/) {
    660         if ($svgWrappedNativeType eq "float") {
    661             # Special case for DOMSVGNumber
    662             $svgPropertyType = $svgWrappedNativeType;
    663         } else {
    664             $svgPropertyType = "WebCore::$svgWrappedNativeType";
    665             $svgPropertyType =~ s/</\<WebCore::/;
    666         }
    667     } elsif ($svgNativeType =~ /SVGListPropertyTearOff/ or $svgNativeType =~ /SVGStaticListPropertyTearOff/) {
    668         $svgListPropertyType = "WebCore::$svgWrappedNativeType";
    669         $svgListPropertyType =~ s/</\<WebCore::/;
    670     } elsif ($svgNativeType =~ /SVGTransformListPropertyTearOff/) {
    671         $svgListPropertyType = "WebCore::$svgWrappedNativeType";
    672         $svgListPropertyType =~ s/</\<WebCore::/;
    673     } elsif ($svgNativeType =~ /SVGPathSegListPropertyTearOff/) {
    674         $svgListPropertyType = "WebCore::$svgWrappedNativeType";
    675         $svgListPropertyType =~ s/</\<WebCore::/;
    676     }
    677 
    678     return ($svgPropertyType, $svgListPropertyType, $svgNativeType);
    679 }
    680 
    681 sub GenerateHeader
    682 {
    683     my $object = shift;
    684     my $dataNode = shift;
    685 
    686     my $interfaceName = $dataNode->name;
    687     my $className = GetClassName($interfaceName);
    688 
    689     my $parentName = "";
    690     my @protocolsToImplement = ();
    691     ($parentName, @protocolsToImplement) = GetParentAndProtocols($dataNode);
    692 
    693     my $numConstants = @{$dataNode->constants};
    694     my $numAttributes = @{$dataNode->attributes};
    695     my $numFunctions = @{$dataNode->functions};
    696 
    697     # - Add default header template
    698     @headerContentHeader = split("\r", $headerLicenseTemplate);
    699     push(@headerContentHeader, "\n");
    700 
    701     # - INCLUDES -
    702     my $includedWebKitAvailabilityHeader = 0;
    703     unless ($isProtocol) {
    704         my $parentHeaderName = GetClassHeaderName($parentName);
    705         push(@headerContentHeader, "#import <WebCore/$parentHeaderName.h>\n");
    706         $includedWebKitAvailabilityHeader = 1;
    707     }
    708 
    709     foreach my $parentProtocol (@protocolsToImplement) {
    710         next if $parentProtocol =~ /^NS/; 
    711         $parentProtocol = GetClassHeaderName($parentProtocol);
    712         push(@headerContentHeader, "#import <WebCore/$parentProtocol.h>\n");
    713         $includedWebKitAvailabilityHeader = 1;
    714     }
    715 
    716     # Special case needed for legacy support of DOMRange
    717     if ($interfaceName eq "Range") {
    718         push(@headerContentHeader, "#import <WebCore/DOMCore.h>\n");
    719         push(@headerContentHeader, "#import <WebCore/DOMDocument.h>\n");
    720         push(@headerContentHeader, "#import <WebCore/DOMRangeException.h>\n");
    721         $includedWebKitAvailabilityHeader = 1;
    722     }
    723 
    724     push(@headerContentHeader, "#import <JavaScriptCore/WebKitAvailability.h>\n") unless $includedWebKitAvailabilityHeader;
    725 
    726     my $interfaceAvailabilityVersionCheck = "#if WEBKIT_VERSION_MAX_ALLOWED >= $interfaceAvailabilityVersion\n\n";
    727 
    728     push(@headerContentHeader, "\n");
    729     push(@headerContentHeader, $interfaceAvailabilityVersionCheck) if length $interfaceAvailabilityVersion;
    730 
    731     # - Add constants.
    732     if ($numConstants > 0) {
    733         my @headerConstants = ();
    734 
    735         # FIXME: we need a way to include multiple enums.
    736         foreach my $constant (@{$dataNode->constants}) {
    737             my $constantName = $constant->name;
    738             my $constantValue = $constant->value;
    739 
    740             my $output = "    DOM_" . $constantName . " = " . $constantValue;
    741             push(@headerConstants, $output);
    742         }
    743 
    744         my $combinedConstants = join(",\n", @headerConstants);
    745 
    746         # FIXME: the formatting of the enums should line up the equal signs.
    747         # FIXME: enums are unconditionally placed in the public header.
    748         push(@headerContent, "enum {\n");
    749         push(@headerContent, $combinedConstants);
    750         push(@headerContent, "\n};\n\n");        
    751     }
    752 
    753     # - Begin @interface or @protocol
    754     my $interfaceDeclaration = ($isProtocol ? "\@protocol $className" : "\@interface $className : $parentName");
    755     $interfaceDeclaration .= " <" . join(", ", @protocolsToImplement) . ">" if @protocolsToImplement > 0;
    756     $interfaceDeclaration .= "\n";
    757 
    758     push(@headerContent, $interfaceDeclaration);
    759 
    760     my @headerAttributes = ();
    761     my @privateHeaderAttributes = ();
    762 
    763     # - Add attribute getters/setters.
    764     if ($numAttributes > 0) {
    765         foreach my $attribute (@{$dataNode->attributes}) {
    766             my $attributeName = $attribute->signature->name;
    767 
    768             if ($attributeName eq "id" or $attributeName eq "hash" or $attributeName eq "description") {
    769                 # Special case some attributes (like id and hash) to have a "Name" suffix to avoid ObjC naming conflicts.
    770                 $attributeName .= "Name";
    771             } elsif ($attributeName eq "frame") {
    772                 # Special case attribute frame to be frameBorders.
    773                 $attributeName .= "Borders";
    774             }
    775 
    776             my $attributeType = GetObjCType($attribute->signature->type);
    777             my $attributeIsReadonly = ($attribute->type =~ /^readonly/);
    778 
    779             my $property = "\@property" . GetPropertyAttributes($attribute->signature->type, $attributeIsReadonly);
    780             # Some SVGFE*Element.idl use 'operator' as attribute name, rewrite as '_operator' to avoid clashes with C/C++
    781             $attributeName =~ s/operator/_operator/ if ($attributeName =~ /operator/);
    782             $property .= " " . $attributeType . ($attributeType =~ /\*$/ ? "" : " ") . $attributeName;
    783 
    784             my $publicInterfaceKey = $property . ";";
    785 
    786             my $availabilityMacro = "";
    787             if (defined $publicInterfaces{$publicInterfaceKey} and length $publicInterfaces{$publicInterfaceKey}) {
    788                 $availabilityMacro = $publicInterfaces{$publicInterfaceKey};
    789             }
    790 
    791             $availabilityMacro = "WEBKIT_OBJC_METHOD_ANNOTATION($availabilityMacro)" if length $availabilityMacro and $buildingForTigerOrEarlier;
    792 
    793             my $declarationSuffix = ";\n";
    794             $declarationSuffix = " $availabilityMacro;\n" if length $availabilityMacro;
    795 
    796             my $public = (defined $publicInterfaces{$publicInterfaceKey} or $newPublicClass);
    797             delete $publicInterfaces{$publicInterfaceKey};
    798 
    799             AddForwardDeclarationsForType($attribute->signature->type, $public);
    800 
    801             my $setterName = "set" . ucfirst($attributeName) . ":";
    802 
    803             my $conflict = $conflictMethod{$attributeName};
    804             if ($conflict) {
    805                 warn "$className conflicts with $conflict method $attributeName\n";
    806                 $fatalError = 1;
    807             }
    808 
    809             $conflict = $conflictMethod{$setterName};
    810             if ($conflict) {
    811                 warn "$className conflicts with $conflict method $setterName\n";
    812                 $fatalError = 1;
    813             }
    814 
    815             if ($buildingForLeopardOrLater) {
    816                 $property .= $declarationSuffix;
    817                 push(@headerAttributes, $property) if $public;
    818                 push(@privateHeaderAttributes, $property) unless $public;
    819             } else {
    820                 my $attributeConditionalString = GenerateConditionalString($attribute->signature);
    821                 if ($attributeConditionalString) {
    822                     push(@headerAttributes, "#if ${attributeConditionalString}\n") if $public;
    823                     push(@privateHeaderAttributes, "#if ${attributeConditionalString}\n") unless $public;
    824                 }
    825 
    826                 # - GETTER
    827                 my $getter = "- (" . $attributeType . ")" . $attributeName . $declarationSuffix;
    828                 push(@headerAttributes, $getter) if $public;
    829                 push(@privateHeaderAttributes, $getter) unless $public;
    830 
    831                 # - SETTER
    832                 if (!$attributeIsReadonly) {
    833                     my $setter = "- (void)$setterName(" . $attributeType . ")new" . ucfirst($attributeName) . $declarationSuffix;
    834                     push(@headerAttributes, $setter) if $public;
    835                     push(@privateHeaderAttributes, $setter) unless $public;
    836                 }
    837 
    838                 if ($attributeConditionalString) {
    839                     push(@headerAttributes, "#endif\n") if $public;
    840                     push(@privateHeaderAttributes, "#endif\n") unless $public;
    841                 }
    842             }
    843         }
    844 
    845         push(@headerContent, @headerAttributes) if @headerAttributes > 0;
    846     }
    847 
    848     my @headerFunctions = ();
    849     my @privateHeaderFunctions = ();
    850     my @deprecatedHeaderFunctions = ();
    851 
    852     # - Add functions.
    853     if ($numFunctions > 0) {
    854         foreach my $function (@{$dataNode->functions}) {
    855             my $functionName = $function->signature->name;
    856 
    857             my $returnType = GetObjCType($function->signature->type);
    858             my $needsDeprecatedVersion = (@{$function->parameters} > 1 and $function->signature->extendedAttributes->{"OldStyleObjC"});
    859             my $numberOfParameters = @{$function->parameters};
    860             my %typesToForwardDeclare = ($function->signature->type => 1);
    861 
    862             my $parameterIndex = 0;
    863             my $functionSig = "- ($returnType)$functionName";
    864             my $methodName = $functionName;
    865             foreach my $param (@{$function->parameters}) {
    866                 my $paramName = $param->name;
    867                 my $paramType = GetObjCType($param->type);
    868 
    869                 $typesToForwardDeclare{$param->type} = 1;
    870 
    871                 if ($parameterIndex >= 1) {
    872                     my $paramPrefix = $param->extendedAttributes->{"ObjCPrefix"};
    873                     $paramPrefix = $paramName unless defined($paramPrefix);
    874                     $functionSig .= " $paramPrefix";
    875                     $methodName .= $paramPrefix;
    876                 }
    877 
    878                 $functionSig .= ":($paramType)$paramName";
    879                 $methodName .= ":";
    880 
    881                 $parameterIndex++;
    882             }
    883 
    884             my $publicInterfaceKey = $functionSig . ";";
    885 
    886             my $conflict = $conflictMethod{$methodName};
    887             if ($conflict) {
    888                 warn "$className conflicts with $conflict method $methodName\n";
    889                 $fatalError = 1;
    890             }
    891 
    892             if ($isProtocol && !$newPublicClass && !defined $publicInterfaces{$publicInterfaceKey}) {
    893                 warn "Protocol method $publicInterfaceKey is not in PublicDOMInterfaces.h. Protocols require all methods to be public";
    894                 $fatalError = 1;
    895             }
    896 
    897             my $availabilityMacro = "";
    898             if (defined $publicInterfaces{$publicInterfaceKey} and length $publicInterfaces{$publicInterfaceKey}) {
    899                 $availabilityMacro = $publicInterfaces{$publicInterfaceKey};
    900             }
    901 
    902             $availabilityMacro = "WEBKIT_OBJC_METHOD_ANNOTATION($availabilityMacro)" if length $availabilityMacro and $buildingForTigerOrEarlier;
    903 
    904             my $functionDeclaration = $functionSig;
    905             $functionDeclaration .= " " . $availabilityMacro if length $availabilityMacro;
    906             $functionDeclaration .= ";\n";
    907 
    908             my $public = (defined $publicInterfaces{$publicInterfaceKey} or $newPublicClass);
    909             delete $publicInterfaces{$publicInterfaceKey};
    910 
    911             foreach my $type (keys %typesToForwardDeclare) {
    912                 # add any forward declarations to the public header if a deprecated version will be generated
    913                 AddForwardDeclarationsForType($type, 1) if $needsDeprecatedVersion;
    914                 AddForwardDeclarationsForType($type, $public) unless $public and $needsDeprecatedVersion;
    915             }
    916 
    917             push(@headerFunctions, $functionDeclaration) if $public;
    918             push(@privateHeaderFunctions, $functionDeclaration) unless $public;
    919 
    920             # generate the old style method names with un-named parameters, these methods are deprecated
    921             if ($needsDeprecatedVersion) {
    922                 my $deprecatedFunctionSig = $functionSig;
    923                 $deprecatedFunctionSig =~ s/\s\w+:/ :/g; # remove parameter names
    924 
    925                 $publicInterfaceKey = $deprecatedFunctionSig . ";";
    926 
    927                 my $availabilityMacro = "AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_3_0";
    928                 if (defined $publicInterfaces{$publicInterfaceKey} and length $publicInterfaces{$publicInterfaceKey}) {
    929                     $availabilityMacro = $publicInterfaces{$publicInterfaceKey};
    930                 }
    931 
    932                 $availabilityMacro = "WEBKIT_OBJC_METHOD_ANNOTATION($availabilityMacro)" if $buildingForTigerOrEarlier;
    933 
    934                 $functionDeclaration = "$deprecatedFunctionSig $availabilityMacro;\n";
    935 
    936                 push(@deprecatedHeaderFunctions, $functionDeclaration);
    937 
    938                 unless (defined $publicInterfaces{$publicInterfaceKey}) {
    939                     warn "Deprecated method $publicInterfaceKey is not in PublicDOMInterfaces.h. All deprecated methods need to be public, or should have the OldStyleObjC IDL attribute removed";
    940                     $fatalError = 1;
    941                 }
    942 
    943                 delete $publicInterfaces{$publicInterfaceKey};
    944             }
    945         }
    946 
    947         if (@headerFunctions > 0) {
    948             push(@headerContent, "\n") if $buildingForLeopardOrLater and @headerAttributes > 0;
    949             push(@headerContent, @headerFunctions);
    950         }
    951     }
    952 
    953     if (@deprecatedHeaderFunctions > 0 && $isProtocol) {
    954         push(@headerContent, @deprecatedHeaderFunctions);
    955     }
    956 
    957     # - End @interface or @protocol
    958     push(@headerContent, "\@end\n");
    959 
    960     if (@deprecatedHeaderFunctions > 0 && !$isProtocol) {
    961         # - Deprecated category @interface 
    962         push(@headerContent, "\n\@interface $className (" . $className . "Deprecated)\n");
    963         push(@headerContent, @deprecatedHeaderFunctions);
    964         push(@headerContent, "\@end\n");
    965     }
    966 
    967     push(@headerContent, "\n#endif\n") if length $interfaceAvailabilityVersion;
    968 
    969     my %alwaysGenerateForNoSVGBuild = map { $_ => 1 } qw(DOMHTMLEmbedElement DOMHTMLObjectElement);
    970 
    971     if (@privateHeaderAttributes > 0 or @privateHeaderFunctions > 0 or exists $alwaysGenerateForNoSVGBuild{$className}) {
    972         # - Private category @interface
    973         @privateHeaderContentHeader = split("\r", $headerLicenseTemplate);
    974         push(@privateHeaderContentHeader, "\n");
    975 
    976         my $classHeaderName = GetClassHeaderName($className);
    977         push(@privateHeaderContentHeader, "#import <WebCore/$classHeaderName.h>\n\n");
    978         push(@privateHeaderContentHeader, $interfaceAvailabilityVersionCheck) if length $interfaceAvailabilityVersion;
    979 
    980         @privateHeaderContent = ();
    981         push(@privateHeaderContent, "\@interface $className (" . $className . "Private)\n");
    982         push(@privateHeaderContent, @privateHeaderAttributes) if @privateHeaderAttributes > 0;
    983         push(@privateHeaderContent, "\n") if $buildingForLeopardOrLater and @privateHeaderAttributes > 0 and @privateHeaderFunctions > 0;
    984         push(@privateHeaderContent, @privateHeaderFunctions) if @privateHeaderFunctions > 0;
    985         push(@privateHeaderContent, "\@end\n");
    986 
    987         push(@privateHeaderContent, "\n#endif\n") if length $interfaceAvailabilityVersion;
    988     }
    989 
    990     unless ($isProtocol) {
    991         # Generate internal interfaces
    992         my $implClassName = GetImplClassName($interfaceName);
    993         my $implClassNameWithNamespace = "WebCore::" . $implClassName;
    994 
    995         my $implType = $implClassNameWithNamespace;
    996         my ($svgPropertyType, $svgListPropertyType, $svgNativeType) = GetSVGPropertyTypes($implClassName);
    997         $implType = $svgNativeType if $svgNativeType;
    998 
    999         # Generate interface definitions. 
   1000         @internalHeaderContent = split("\r", $implementationLicenseTemplate);
   1001 
   1002         push(@internalHeaderContent, "\n#import <WebCore/$className.h>\n\n");
   1003         push(@internalHeaderContent, "#import <WebCore/SVGAnimatedPropertyTearOff.h>\n\n") if $svgPropertyType;
   1004         if ($svgListPropertyType) {
   1005             push(@internalHeaderContent, "#import <WebCore/SVGAnimatedListPropertyTearOff.h>\n\n");
   1006             push(@internalHeaderContent, "#import <WebCore/SVGTransformListPropertyTearOff.h>\n\n") if $svgListPropertyType =~ /SVGTransformList/;
   1007             push(@internalHeaderContent, "#import <WebCore/SVGPathSegListPropertyTearOff.h>\n\n") if $svgListPropertyType =~ /SVGPathSegList/;
   1008         }
   1009         push(@internalHeaderContent, $interfaceAvailabilityVersionCheck) if length $interfaceAvailabilityVersion;
   1010 
   1011         if ($interfaceName eq "Node") {
   1012             push(@internalHeaderContent, "\@protocol DOMEventTarget;\n\n");
   1013         }
   1014 
   1015         my $startedNamespace = 0;
   1016 
   1017         if ($codeGenerator->IsSVGAnimatedType($interfaceName)) {
   1018             push(@internalHeaderContent, "#import <WebCore/$implClassName.h>\n\n");
   1019         } else {
   1020             push(@internalHeaderContent, "namespace WebCore {\n");
   1021             $startedNamespace = 1;
   1022             if ($interfaceName eq "Node") {
   1023                 push(@internalHeaderContent, "    class EventTarget;\n    class Node;\n");
   1024             } else {
   1025                 push(@internalHeaderContent, "    class $implClassName;\n");
   1026             }
   1027             push(@internalHeaderContent, "}\n\n");
   1028         }
   1029 
   1030         push(@internalHeaderContent, "$implType* core($className *);\n");
   1031         push(@internalHeaderContent, "$className *kit($implType*);\n");
   1032 
   1033         if ($dataNode->extendedAttributes->{Polymorphic}) {
   1034             push(@internalHeaderContent, "Class kitClass($implType*);\n");
   1035         }
   1036 
   1037         if ($interfaceName eq "Node") {
   1038             push(@internalHeaderContent, "id <DOMEventTarget> kit(WebCore::EventTarget*);\n");
   1039         }
   1040 
   1041         push(@internalHeaderContent, "\n#endif\n") if length $interfaceAvailabilityVersion;
   1042     }
   1043 }
   1044 
   1045 sub GenerateImplementation
   1046 {
   1047     my $object = shift;
   1048     my $dataNode = shift;
   1049 
   1050     my @ancestorInterfaceNames = ();
   1051 
   1052     if (@{$dataNode->parents} > 1) {
   1053         $codeGenerator->AddMethodsConstantsAndAttributesFromParentClasses($dataNode, \@ancestorInterfaceNames);
   1054     }
   1055 
   1056     my $interfaceName = $dataNode->name;
   1057     my $className = GetClassName($interfaceName);
   1058     my $implClassName = GetImplClassName($interfaceName);
   1059     my $parentImplClassName = GetParentImplClassName($dataNode);
   1060     my $implClassNameWithNamespace = "WebCore::" . $implClassName;
   1061     my $baseClass = GetBaseClass($parentImplClassName);
   1062     my $classHeaderName = GetClassHeaderName($className);
   1063 
   1064     my $numAttributes = @{$dataNode->attributes};
   1065     my $numFunctions = @{$dataNode->functions};
   1066     my $implType = $implClassNameWithNamespace;
   1067 
   1068     my ($svgPropertyType, $svgListPropertyType, $svgNativeType) = GetSVGPropertyTypes($implClassName);
   1069     $implType = $svgNativeType if $svgNativeType;
   1070 
   1071     # - Add default header template.
   1072     @implContentHeader = split("\r", $implementationLicenseTemplate);
   1073 
   1074     # - INCLUDES -
   1075     push(@implContentHeader, "\n#import \"config.h\"\n");
   1076 
   1077     my $conditionalString = GenerateConditionalString($dataNode);
   1078     push(@implContentHeader, "\n#if ${conditionalString}\n\n") if $conditionalString;
   1079 
   1080     push(@implContentHeader, "#import \"DOMInternal.h\"\n\n");
   1081     push(@implContentHeader, "#import \"$classHeaderName.h\"\n\n");
   1082 
   1083     $implIncludes{"ExceptionHandlers.h"} = 1;
   1084     $implIncludes{"ThreadCheck.h"} = 1;
   1085     $implIncludes{"JSMainThreadExecState.h"} = 1;
   1086     $implIncludes{"WebScriptObjectPrivate.h"} = 1;
   1087     $implIncludes{$classHeaderName . "Internal.h"} = 1;
   1088 
   1089     # FIXME: These includes are only needed when the class is a subclass of one of these polymorphic classes.
   1090     $implIncludes{"DOMBlobInternal.h"} = 1;
   1091     $implIncludes{"DOMCSSRuleInternal.h"} = 1;
   1092     $implIncludes{"DOMCSSValueInternal.h"} = 1;
   1093     $implIncludes{"DOMEventInternal.h"} = 1;
   1094     $implIncludes{"DOMNodeInternal.h"} = 1;
   1095     $implIncludes{"DOMStyleSheetInternal.h"} = 1;
   1096 
   1097     $implIncludes{"DOMSVGPathSegInternal.h"} = 1 if $interfaceName =~ /^SVGPathSeg.+/;
   1098 
   1099     if ($interfaceName =~ /(\w+)(Abs|Rel)$/) {
   1100         $implIncludes{"$1.h"} = 1;
   1101     } else {
   1102         if (!$codeGenerator->AvoidInclusionOfType($implClassName)) {
   1103             $implIncludes{"$implClassName.h"} = 1 ;
   1104         } elsif ($codeGenerator->IsSVGTypeNeedingTearOff($implClassName)) {
   1105             my $includeType = $codeGenerator->GetSVGWrappedTypeNeedingTearOff($implClassName);
   1106             $implIncludes{"${includeType}.h"} = 1;
   1107         }
   1108     } 
   1109 
   1110     @implContent = ();
   1111 
   1112     push(@implContent, "#import <wtf/GetPtr.h>\n\n");
   1113 
   1114     # add implementation accessor
   1115     if ($parentImplClassName eq "Object") {
   1116         push(@implContent, "#define IMPL reinterpret_cast<$implType*>(_internal)\n\n");
   1117     } else {
   1118         my $baseClassWithNamespace = "WebCore::$baseClass";
   1119         push(@implContent, "#define IMPL static_cast<$implClassNameWithNamespace*>(reinterpret_cast<$baseClassWithNamespace*>(_internal))\n\n");
   1120     }
   1121 
   1122     # START implementation
   1123     push(@implContent, "\@implementation $className\n\n");
   1124 
   1125     # Only generate 'dealloc' and 'finalize' methods for direct subclasses of DOMObject.
   1126     if ($parentImplClassName eq "Object") {
   1127         $implIncludes{"WebCoreObjCExtras.h"} = 1;
   1128         push(@implContent, "- (void)dealloc\n");
   1129         push(@implContent, "{\n");
   1130         push(@implContent, "    if (WebCoreObjCScheduleDeallocateOnMainThread([$className class], self))\n");
   1131         push(@implContent, "        return;\n");
   1132         push(@implContent, "\n");
   1133         if ($interfaceName eq "NodeIterator") {
   1134             push(@implContent, "    if (_internal) {\n");
   1135             push(@implContent, "        [self detach];\n");
   1136             push(@implContent, "        IMPL->deref();\n");
   1137             push(@implContent, "    };\n");
   1138         } else {
   1139             push(@implContent, "    if (_internal)\n");
   1140             push(@implContent, "        IMPL->deref();\n");
   1141         }
   1142         push(@implContent, "    [super dealloc];\n");
   1143         push(@implContent, "}\n\n");
   1144 
   1145         push(@implContent, "- (void)finalize\n");
   1146         push(@implContent, "{\n");
   1147         if ($interfaceName eq "NodeIterator") {
   1148             push(@implContent, "    if (_internal) {\n");
   1149             push(@implContent, "        [self detach];\n");
   1150             push(@implContent, "        IMPL->deref();\n");
   1151             push(@implContent, "    };\n");
   1152         } else {
   1153             push(@implContent, "    if (_internal)\n");
   1154             push(@implContent, "        IMPL->deref();\n");
   1155         }
   1156         push(@implContent, "    [super finalize];\n");
   1157         push(@implContent, "}\n\n");
   1158         
   1159     }
   1160 
   1161     %attributeNames = ();
   1162 
   1163     # - Attributes
   1164     if ($numAttributes > 0) {
   1165         foreach my $attribute (@{$dataNode->attributes}) {
   1166             AddIncludesForType($attribute->signature->type);
   1167 
   1168             my $idlType = $codeGenerator->StripModule($attribute->signature->type);
   1169 
   1170             my $attributeName = $attribute->signature->name;
   1171             my $attributeType = GetObjCType($attribute->signature->type);
   1172             my $attributeIsReadonly = ($attribute->type =~ /^readonly/);
   1173             my $attributeClassName = GetClassName($attribute->signature->type);
   1174 
   1175             my $attributeInterfaceName = $attributeName;
   1176             if ($attributeName eq "id" or $attributeName eq "hash" or $attributeName eq "description") {
   1177                 # Special case some attributes (like id and hash) to have a "Name" suffix to avoid ObjC naming conflicts.
   1178                 $attributeInterfaceName .= "Name";
   1179             } elsif ($attributeName eq "frame") {
   1180                 # Special case attribute frame to be frameBorders.
   1181                 $attributeInterfaceName .= "Borders";
   1182             } elsif ($attributeName eq "operator") {
   1183                 # Avoid clash with C++ keyword.
   1184                 $attributeInterfaceName = "_operator";
   1185             }
   1186 
   1187             $attributeNames{$attributeInterfaceName} = 1;
   1188 
   1189             # - GETTER
   1190             my $getterSig = "- ($attributeType)$attributeInterfaceName\n";
   1191 
   1192             my $getterExpressionPrefix = $codeGenerator->GetterExpressionPrefix(\%implIncludes, $interfaceName, $attribute);
   1193 
   1194             # FIXME: Special case attribute ownerDocument to call document. This makes it return the
   1195             # document when called on the document itself. Legacy behavior, see <https://bugs.webkit.org/show_bug.cgi?id=10889>.
   1196             $getterExpressionPrefix =~ s/\bownerDocument\b/document/;
   1197 
   1198             my $hasGetterException = @{$attribute->getterExceptions};
   1199             my $getterContentHead = "IMPL->$getterExpressionPrefix";
   1200             my $getterContentTail = ")";
   1201 
   1202             if ($svgPropertyType) {
   1203                 $getterContentHead = "$getterExpressionPrefix";
   1204 
   1205                 # TODO: Handle special case for DOMSVGLength. We do need Custom code support for this.
   1206                 if ($svgPropertyType eq "WebCore::SVGLength" and $attributeName eq "value") {
   1207                     $getterContentHead = "value(IMPL->contextElement(), ";
   1208                 }
   1209             }
   1210 
   1211             my $attributeTypeSansPtr = $attributeType;
   1212             $attributeTypeSansPtr =~ s/ \*$//; # Remove trailing " *" from pointer types.
   1213 
   1214             # special case for EventTarget protocol
   1215             $attributeTypeSansPtr = "DOMNode" if $idlType eq "EventTarget";
   1216 
   1217             # Special cases
   1218             my @customGetterContent = (); 
   1219             if ($attributeTypeSansPtr eq "DOMImplementation") {
   1220                 # FIXME: We have to special case DOMImplementation until DOMImplementationFront is removed
   1221                 $getterContentHead = "kit(implementationFront(IMPL";
   1222                 $getterContentTail .= ")";
   1223             } elsif ($attributeName =~ /(\w+)DisplayString$/) {
   1224                 my $attributeToDisplay = $1;
   1225                 $getterContentHead = "WebCore::displayString(IMPL->$attributeToDisplay(), core(self)";
   1226                 $implIncludes{"HitTestResult.h"} = 1;
   1227             } elsif ($attributeName =~ /^absolute(\w+)URL$/) {
   1228                 my $typeOfURL = $1;
   1229                 $getterContentHead = "[self _getURLAttribute:";
   1230                 if ($typeOfURL eq "Link") {
   1231                     $getterContentTail = "\@\"href\"]";
   1232                 } elsif ($typeOfURL eq "Image") {
   1233                     if ($interfaceName eq "HTMLObjectElement") {
   1234                         $getterContentTail = "\@\"data\"]";
   1235                     } else {
   1236                         $getterContentTail = "\@\"src\"]";
   1237                     }
   1238                     unless ($interfaceName eq "HTMLImageElement") {
   1239                         push(@customGetterContent, "    if (!IMPL->renderer() || !IMPL->renderer()->isImage())\n");
   1240                         push(@customGetterContent, "        return nil;\n");
   1241                         $implIncludes{"RenderObject.h"} = 1;
   1242                     }
   1243                 }
   1244                 $implIncludes{"DOMPrivate.h"} = 1;
   1245             } elsif ($attribute->signature->extendedAttributes->{"ConvertToString"}) {
   1246                 $getterContentHead = "WTF::String::number(" . $getterContentHead;
   1247                 $getterContentTail .= ")";
   1248             } elsif ($idlType eq "Date") {
   1249                 $getterContentHead = "kit($getterContentHead";
   1250                 $getterContentTail .= ")";
   1251             } elsif ($svgPropertyType) {
   1252                 # Special case for DOMSVGNumber
   1253                 if ($svgPropertyType eq "float") {
   1254                     # Intentional leave out closing brace, it's already contained in getterContentTail
   1255                     $getterContentHead = "IMPL->propertyReference(";
   1256                 } else {    
   1257                     $getterContentHead = "IMPL->propertyReference().$getterContentHead";
   1258                 }
   1259 
   1260                 if ($codeGenerator->IsSVGTypeWithWritablePropertiesNeedingTearOff($idlType) and not defined $attribute->signature->extendedAttributes->{"Immutable"}) {
   1261                     my $getter = $getterContentHead;
   1262                     $getter =~ s/\(\)//;
   1263                     
   1264                     my $tearOffType = GetSVGTypeWithNamespace($idlType);
   1265                     my $selfIsTearOffType = $codeGenerator->IsSVGTypeNeedingTearOff($implClassName);
   1266                     if ($selfIsTearOffType) {
   1267                         $implIncludes{"SVGStaticPropertyWithParentTearOff.h"} = 1;
   1268                         $tearOffType =~ s/SVGPropertyTearOff</SVGStaticPropertyWithParentTearOff<$implClassNameWithNamespace, /;
   1269 
   1270                         my $getter = $getterExpressionPrefix;
   1271                         $getter =~ s/IMPL->//;
   1272                         $getter =~ s/\(//;
   1273                         my $updateMethod = "&${implClassNameWithNamespace}::update" . $codeGenerator->WK_ucfirst($getter);
   1274 
   1275                         if ($getterContentHead =~ /matrix/ and $implClassName eq "SVGTransform") {
   1276                             # SVGTransform offers a matrix() method for internal usage that returns an AffineTransform
   1277                             # and a svgMatrix() method returning a SVGMatrix, used for the bindings.
   1278                             $getterContentHead =~ s/matrix/svgMatrix/;
   1279                         }
   1280 
   1281                         $getterContentHead = "${tearOffType}::create(IMPL, $getterContentHead$getterContentTail, $updateMethod)";
   1282 
   1283                         $getterContentHead = "kit(WTF::getPtr($getterContentHead";
   1284                         $getterContentTail = "))";
   1285                     }
   1286                 }
   1287             } elsif ($codeGenerator->IsSVGAnimatedType($implClassName) and $codeGenerator->IsSVGTypeNeedingTearOff($idlType)) {
   1288                 my $idlTypeWithNamespace = GetSVGTypeWithNamespace($idlType);
   1289                 $getterContentHead = "kit(static_cast<$idlTypeWithNamespace*>($getterContentHead)";
   1290                 $getterContentTail .= ")";
   1291             } elsif (IsProtocolType($idlType) and $idlType ne "EventTarget") {
   1292                 $getterContentHead = "kit($getterContentHead";
   1293                 $getterContentTail .= ")";
   1294             } elsif ($idlType eq "Color") {
   1295                 $getterContentHead = "WebCore::nsColor($getterContentHead";
   1296                 $getterContentTail .= ")";
   1297             } elsif ($attribute->signature->type eq "SerializedScriptValue") {
   1298                 $getterContentHead = "$getterContentHead";
   1299                 $getterContentTail .= "->toString()";                
   1300             } elsif (ConversionNeeded($attribute->signature->type)) {
   1301                 my $type = $attribute->signature->type;
   1302                 if ($codeGenerator->IsSVGTypeNeedingTearOff($type) and not $implClassName =~ /List$/) {
   1303                     my $idlTypeWithNamespace = GetSVGTypeWithNamespace($type);
   1304                     $implIncludes{"$type.h"} = 1 if not $codeGenerator->AvoidInclusionOfType($type);
   1305                     if ($codeGenerator->IsSVGTypeWithWritablePropertiesNeedingTearOff($type) and not defined $attribute->signature->extendedAttributes->{"Immutable"}) {
   1306                         $idlTypeWithNamespace =~ s/SVGPropertyTearOff</SVGStaticPropertyTearOff<$implClassNameWithNamespace, /;
   1307                         $implIncludes{"SVGStaticPropertyTearOff.h"} = 1;
   1308 
   1309                         my $getter = $getterContentHead;
   1310                         $getter =~ s/IMPL->//;
   1311                         $getter =~ s/\(//;
   1312                         my $updateMethod = "&${implClassNameWithNamespace}::update" . $codeGenerator->WK_ucfirst($getter);
   1313                         $getterContentHead = "kit(WTF::getPtr(${idlTypeWithNamespace}::create(IMPL, $getterContentHead$getterContentTail, $updateMethod";
   1314                         $getterContentTail .= "))";
   1315                     } elsif ($idlTypeWithNamespace =~ /SVG(Point|PathSeg)List/) {
   1316                         $getterContentHead = "kit(WTF::getPtr($getterContentHead";
   1317                         $getterContentTail .= "))";
   1318                     } elsif ($idlTypeWithNamespace =~ /SVGStaticListPropertyTearOff/) {
   1319                         my $extraImp = "WebCore::GetOwnerElementForType<$implClassNameWithNamespace, WebCore::IsDerivedFromSVGElement<$implClassNameWithNamespace>::value>::ownerElement(IMPL), ";
   1320                         $getterContentHead = "kit(WTF::getPtr(${idlTypeWithNamespace}::create($extraImp$getterContentHead";
   1321                         $getterContentTail .= ")))";
   1322                     } else {
   1323                         $getterContentHead = "kit(WTF::getPtr(${idlTypeWithNamespace}::create($getterContentHead";
   1324                         $getterContentTail .= ")))";
   1325                     }
   1326                 } else {
   1327                     $getterContentHead = "kit(WTF::getPtr($getterContentHead";
   1328                     $getterContentTail .= "))";
   1329                 }
   1330             }
   1331 
   1332             my $getterContent;
   1333             if ($hasGetterException) {
   1334                 $getterContent = $getterContentHead . "ec" . $getterContentTail;
   1335             } else {
   1336                 $getterContent = $getterContentHead . $getterContentTail;
   1337             }
   1338 
   1339             my $attributeConditionalString = GenerateConditionalString($attribute->signature);
   1340             push(@implContent, "#if ${attributeConditionalString}\n") if $attributeConditionalString;
   1341             push(@implContent, $getterSig);
   1342             push(@implContent, "{\n");
   1343             push(@implContent, "    $jsContextSetter\n");
   1344             push(@implContent, @customGetterContent);
   1345             if ($hasGetterException) {
   1346                 # Differentiated between when the return type is a pointer and
   1347                 # not for white space issue (ie. Foo *result vs. int result).
   1348                 if ($attributeType =~ /\*$/) {
   1349                     $getterContent = $attributeType . "result = " . $getterContent;
   1350                 } else {
   1351                     $getterContent = $attributeType . " result = " . $getterContent;
   1352                 }
   1353 
   1354                 push(@implContent, "    $exceptionInit\n");
   1355                 push(@implContent, "    $getterContent;\n");
   1356                 push(@implContent, "    $exceptionRaiseOnError\n");
   1357                 push(@implContent, "    return result;\n");
   1358             } else {
   1359                 push(@implContent, "    return $getterContent;\n");
   1360             }
   1361             push(@implContent, "}\n");
   1362 
   1363             # - SETTER
   1364             if (!$attributeIsReadonly) {
   1365                 # Exception handling
   1366                 my $hasSetterException = @{$attribute->setterExceptions};
   1367 
   1368                 my $coreSetterName = "set" . $codeGenerator->WK_ucfirst($attributeName);
   1369                 my $setterName = "set" . ucfirst($attributeInterfaceName);
   1370                 my $argName = "new" . ucfirst($attributeInterfaceName);
   1371                 my $arg = GetObjCTypeGetter($argName, $idlType);
   1372 
   1373                 # The definition of ConvertToString is flipped for the setter
   1374                 if ($attribute->signature->extendedAttributes->{"ConvertToString"}) {
   1375                     $arg = "WTF::String($arg).toInt()";
   1376                 }
   1377 
   1378                 my $setterSig = "- (void)$setterName:($attributeType)$argName\n";
   1379 
   1380                 push(@implContent, "\n");
   1381                 push(@implContent, $setterSig);
   1382                 push(@implContent, "{\n");
   1383                 push(@implContent, "    $jsContextSetter\n");
   1384 
   1385                 unless ($codeGenerator->IsPrimitiveType($idlType) or $codeGenerator->IsStringType($idlType)) {
   1386                     push(@implContent, "    ASSERT($argName);\n\n");
   1387                 }
   1388 
   1389                 if ($idlType eq "Date") {
   1390                     $arg = "core(" . $arg . ")";
   1391                 }
   1392 
   1393                 if ($svgPropertyType) {
   1394                     $getterContentHead = "$getterExpressionPrefix";
   1395                     push(@implContent, "    if (IMPL->role() == WebCore::AnimValRole) {\n");
   1396                     push(@implContent, "        WebCore::raiseOnDOMError(WebCore::NO_MODIFICATION_ALLOWED_ERR);\n");
   1397                     push(@implContent, "        return;\n");
   1398                     push(@implContent, "    }\n");
   1399                     push(@implContent, "    $svgPropertyType& podImpl = IMPL->propertyReference();\n");
   1400                     my $ec = $hasSetterException ? ", ec" : "";
   1401                     push(@implContent, "    $exceptionInit\n") if $hasSetterException;
   1402 
   1403                     # Special case for DOMSVGNumber
   1404                     if ($svgPropertyType eq "float") {
   1405                         push(@implContent, "    podImpl = $arg;\n");
   1406                     } else {
   1407                         # FIXME: Special case for DOMSVGLength. We do need Custom code support for this.
   1408                         if ($svgPropertyType eq "WebCore::SVGLength" and $attributeName eq "value") {
   1409                             push(@implContent, "    podImpl.$coreSetterName($arg, IMPL->contextElement()$ec);\n");
   1410                         } else {
   1411                             push(@implContent, "    podImpl.$coreSetterName($arg$ec);\n");
   1412                         }
   1413                     }
   1414 
   1415                     if ($hasSetterException) {
   1416                         push(@implContent, "    if (!ec)\n");
   1417                         push(@implContent, "        IMPL->commitChange();\n");
   1418                         push(@implContent, "    $exceptionRaiseOnError\n");
   1419                     } else {
   1420                         push(@implContent, "    IMPL->commitChange();\n");
   1421                     }
   1422                 } elsif ($svgListPropertyType) {
   1423                     $getterContentHead = "$getterExpressionPrefix";
   1424                     push(@implContent, "    IMPL->$coreSetterName($arg);\n");
   1425                 } else {
   1426                     my $setterExpressionPrefix = $codeGenerator->SetterExpressionPrefix(\%implIncludes, $interfaceName, $attribute);
   1427                     my $ec = $hasSetterException ? ", ec" : "";
   1428                     push(@implContent, "    $exceptionInit\n") if $hasSetterException;
   1429                     push(@implContent, "    IMPL->$setterExpressionPrefix$arg$ec);\n");
   1430                     push(@implContent, "    $exceptionRaiseOnError\n") if $hasSetterException;
   1431                 }
   1432 
   1433                 push(@implContent, "}\n");
   1434             }
   1435 
   1436             push(@implContent, "#endif\n") if $attributeConditionalString;
   1437             push(@implContent, "\n");
   1438         }
   1439     }
   1440 
   1441     # - Functions
   1442     if ($numFunctions > 0) {
   1443         foreach my $function (@{$dataNode->functions}) {
   1444             AddIncludesForType($function->signature->type);
   1445 
   1446             my $functionName = $function->signature->name;
   1447             my $returnType = GetObjCType($function->signature->type);
   1448             my $hasParameters = @{$function->parameters};
   1449             my $raisesExceptions = @{$function->raisesExceptions};
   1450 
   1451             my @parameterNames = ();
   1452             my @needsAssert = ();
   1453             my %needsCustom = ();
   1454 
   1455             my $parameterIndex = 0;
   1456             my $functionSig = "- ($returnType)$functionName";
   1457             foreach my $param (@{$function->parameters}) {
   1458                 my $paramName = $param->name;
   1459                 my $paramType = GetObjCType($param->type);
   1460 
   1461                 # make a new parameter name if the original conflicts with a property name
   1462                 $paramName = "in" . ucfirst($paramName) if $attributeNames{$paramName};
   1463 
   1464                 AddIncludesForType($param->type);
   1465 
   1466                 my $idlType = $codeGenerator->StripModule($param->type);
   1467                 my $implGetter = GetObjCTypeGetter($paramName, $idlType);
   1468 
   1469                 push(@parameterNames, $implGetter);
   1470                 $needsCustom{"XPathNSResolver"} = $paramName if $idlType eq "XPathNSResolver";
   1471                 $needsCustom{"NodeFilter"} = $paramName if $idlType eq "NodeFilter";
   1472                 $needsCustom{"EventListener"} = $paramName if $idlType eq "EventListener";
   1473                 $needsCustom{"EventTarget"} = $paramName if $idlType eq "EventTarget";
   1474                 $needsCustom{"NodeToReturn"} = $paramName if $param->extendedAttributes->{"Return"};
   1475 
   1476                 unless ($codeGenerator->IsPrimitiveType($idlType) or $codeGenerator->IsStringType($idlType)) {
   1477                     push(@needsAssert, "    ASSERT($paramName);\n");
   1478                 }
   1479 
   1480                 if ($parameterIndex >= 1) {
   1481                     my $paramPrefix = $param->extendedAttributes->{"ObjCPrefix"};
   1482                     $paramPrefix = $param->name unless defined($paramPrefix);
   1483                     $functionSig .= " $paramPrefix";
   1484                 }
   1485 
   1486                 $functionSig .= ":($paramType)$paramName";
   1487 
   1488                 $parameterIndex++;
   1489             }
   1490 
   1491             my @functionContent = ();
   1492             my $caller = "IMPL";
   1493 
   1494             # special case the XPathNSResolver
   1495             if (defined $needsCustom{"XPathNSResolver"}) {
   1496                 my $paramName = $needsCustom{"XPathNSResolver"};
   1497                 push(@functionContent, "    WebCore::XPathNSResolver* nativeResolver = 0;\n");
   1498                 push(@functionContent, "    RefPtr<WebCore::XPathNSResolver> customResolver;\n");
   1499                 push(@functionContent, "    if ($paramName) {\n");
   1500                 push(@functionContent, "        if ([$paramName isMemberOfClass:[DOMNativeXPathNSResolver class]])\n");
   1501                 push(@functionContent, "            nativeResolver = core(static_cast<DOMNativeXPathNSResolver *>($paramName));\n");
   1502                 push(@functionContent, "        else {\n");
   1503                 push(@functionContent, "            customResolver = WebCore::DOMCustomXPathNSResolver::create($paramName);\n");
   1504                 push(@functionContent, "            nativeResolver = WTF::getPtr(customResolver);\n");
   1505                 push(@functionContent, "        }\n");
   1506                 push(@functionContent, "    }\n");
   1507             }
   1508 
   1509             # special case the EventTarget
   1510             if (defined $needsCustom{"EventTarget"}) {
   1511                 my $paramName = $needsCustom{"EventTarget"};
   1512                 push(@functionContent, "    DOMNode* ${paramName}ObjC = $paramName;\n");
   1513                 push(@functionContent, "    WebCore::Node* ${paramName}Node = core(${paramName}ObjC);\n");
   1514                 $implIncludes{"DOMNode.h"} = 1;
   1515                 $implIncludes{"Node.h"} = 1;
   1516             }
   1517 
   1518             if ($function->signature->extendedAttributes->{"UsesView"}) {
   1519                 push(@functionContent, "    WebCore::DOMWindow* dv = $caller->defaultView();\n");
   1520                 push(@functionContent, "    if (!dv)\n");
   1521                 push(@functionContent, "        return nil;\n");
   1522                 $implIncludes{"DOMWindow.h"} = 1;
   1523                 $caller = "dv";
   1524             }
   1525 
   1526             # special case the EventListener
   1527             if (defined $needsCustom{"EventListener"}) {
   1528                 my $paramName = $needsCustom{"EventListener"};
   1529                 push(@functionContent, "    RefPtr<WebCore::EventListener> nativeEventListener = WebCore::ObjCEventListener::wrap($paramName);\n");
   1530             }
   1531 
   1532             # special case the NodeFilter
   1533             if (defined $needsCustom{"NodeFilter"}) {
   1534                 my $paramName = $needsCustom{"NodeFilter"};
   1535                 push(@functionContent, "    RefPtr<WebCore::NodeFilter> nativeNodeFilter;\n");
   1536                 push(@functionContent, "    if ($paramName)\n");
   1537                 push(@functionContent, "        nativeNodeFilter = WebCore::NodeFilter::create(WebCore::ObjCNodeFilterCondition::create($paramName));\n");
   1538             }
   1539 
   1540             # FIXME! We need [Custom] support for ObjC, to move these hacks into DOMSVGLength/MatrixCustom.mm
   1541             my $svgLengthConvertToSpecifiedUnits = ($svgPropertyType and $svgPropertyType eq "WebCore::SVGLength" and $functionName eq "convertToSpecifiedUnits");
   1542 
   1543             push(@parameterNames, "IMPL->contextElement()") if $svgLengthConvertToSpecifiedUnits; 
   1544             push(@parameterNames, "ec") if $raisesExceptions;
   1545 
   1546             # Handle arguments that are 'SVGProperty' based (SVGAngle/SVGLength). We need to convert from SVGPropertyTearOff<Type>* to Type,
   1547             # to be able to call the desired WebCore function. If the conversion fails, we can't extract Type and need to raise an exception.
   1548             my $currentParameter = -1;
   1549             foreach my $param (@{$function->parameters}) {
   1550                 $currentParameter++;
   1551 
   1552                 my $paramName = $param->name;
   1553 
   1554                 # make a new parameter name if the original conflicts with a property name
   1555                 $paramName = "in" . ucfirst($paramName) if $attributeNames{$paramName};
   1556 
   1557                 my $idlType = $codeGenerator->StripModule($param->type);
   1558                 next if not $codeGenerator->IsSVGTypeNeedingTearOff($idlType) or $implClassName =~ /List$/;
   1559 
   1560                 my $implGetter = GetObjCTypeGetter($paramName, $idlType);
   1561                 my $idlTypeWithNamespace = GetSVGTypeWithNamespace($idlType);
   1562 
   1563                 push(@functionContent, "    $idlTypeWithNamespace* ${paramName}Core = $implGetter;\n");
   1564                 push(@functionContent, "    if (!${paramName}Core) {\n");
   1565                 push(@functionContent, "        WebCore::ExceptionCode ec = WebCore::TYPE_MISMATCH_ERR;\n");
   1566                 push(@functionContent, "        $exceptionRaiseOnError\n");
   1567                 if ($returnType eq "void") { 
   1568                     push(@functionContent, "        return;\n");
   1569                 } else {
   1570                     push(@functionContent, "        return nil;\n");
   1571                 }
   1572                 push(@functionContent, "    }\n");
   1573 
   1574                 # Replace the paramter core() getter, by the cached variable.
   1575                 splice(@parameterNames, $currentParameter, 1, "${paramName}Core->propertyReference()");
   1576             }
   1577 
   1578             my $content = $codeGenerator->WK_lcfirst($functionName) . "(" . join(", ", @parameterNames) . ")"; 
   1579 
   1580             if ($svgPropertyType) {
   1581                 push(@functionContent, "    if (IMPL->role() == WebCore::AnimValRole) {\n");
   1582                 push(@functionContent, "        WebCore::raiseOnDOMError(WebCore::NO_MODIFICATION_ALLOWED_ERR);\n");
   1583                 if ($returnType eq "void") {
   1584                     push(@functionContent, "        return;\n");
   1585                 } else {
   1586                     push(@functionContent, "        return nil;\n");
   1587                 }
   1588                 push(@functionContent, "    }\n");
   1589                 push(@functionContent, "    $svgPropertyType& podImpl = IMPL->propertyReference();\n");
   1590                 $content = "podImpl.$content"; 
   1591             } else {
   1592                 $content = $caller . "->$content";
   1593             }
   1594 
   1595             if ($returnType eq "void") {
   1596                 # Special case 'void' return type.
   1597                 if ($raisesExceptions) {
   1598                     push(@functionContent, "    $exceptionInit\n");
   1599                     push(@functionContent, "    $content;\n");
   1600                     if ($svgPropertyType) {
   1601                         push(@functionContent, "    if (!ec)\n");
   1602                         push(@functionContent, "        IMPL->commitChange();\n");
   1603                     }
   1604                     push(@functionContent, "    $exceptionRaiseOnError\n");
   1605                 } else {
   1606                     push(@functionContent, "    $content;\n");
   1607                     push(@functionContent, "    IMPL->commitChange();\n") if $svgPropertyType;
   1608                 }
   1609             } elsif (defined $needsCustom{"NodeToReturn"}) {
   1610                 # Special case the insertBefore, replaceChild, removeChild 
   1611                 # and appendChild functions from DOMNode 
   1612                 my $toReturn = $needsCustom{"NodeToReturn"};
   1613                 if ($raisesExceptions) {
   1614                     push(@functionContent, "    $exceptionInit\n");
   1615                     push(@functionContent, "    if ($content)\n");
   1616                     push(@functionContent, "        return $toReturn;\n");
   1617                     push(@functionContent, "    $exceptionRaiseOnError\n");
   1618                     push(@functionContent, "    return nil;\n");
   1619                 } else {
   1620                     push(@functionContent, "    if ($content)\n");
   1621                     push(@functionContent, "        return $toReturn;\n");
   1622                     push(@functionContent, "    return nil;\n");
   1623                 }
   1624             } elsif ($returnType eq "SerializedScriptValue") {
   1625                 $content = "foo";
   1626             } else {
   1627                 if (ConversionNeeded($function->signature->type)) {
   1628                     if ($codeGenerator->IsSVGTypeNeedingTearOff($function->signature->type) and not $implClassName =~ /List$/) {
   1629                         my $idlTypeWithNamespace = GetSVGTypeWithNamespace($function->signature->type);
   1630                         $content = "kit(WTF::getPtr(${idlTypeWithNamespace}::create($content)))";
   1631                     } else {
   1632                         $content = "kit(WTF::getPtr($content))";
   1633                     }
   1634                 }
   1635 
   1636                 if ($raisesExceptions) {
   1637                     # Differentiated between when the return type is a pointer and
   1638                     # not for white space issue (ie. Foo *result vs. int result).
   1639                     if ($returnType =~ /\*$/) {
   1640                         $content = $returnType . "result = " . $content;
   1641                     } else {
   1642                         $content = $returnType . " result = " . $content;
   1643                     }
   1644 
   1645                     push(@functionContent, "    $exceptionInit\n");
   1646                     push(@functionContent, "    $content;\n");
   1647                     push(@functionContent, "    $exceptionRaiseOnError\n");
   1648                     push(@functionContent, "    return result;\n");
   1649                 } else {
   1650                     push(@functionContent, "    return $content;\n");
   1651                 }
   1652             }
   1653 
   1654             push(@implContent, "$functionSig\n");
   1655             push(@implContent, "{\n");
   1656             push(@implContent, "    $jsContextSetter\n");
   1657             push(@implContent, @functionContent);
   1658             push(@implContent, "}\n\n");
   1659 
   1660             # generate the old style method names with un-named parameters, these methods are deprecated
   1661             if (@{$function->parameters} > 1 and $function->signature->extendedAttributes->{"OldStyleObjC"}) {
   1662                 my $deprecatedFunctionSig = $functionSig;
   1663                 $deprecatedFunctionSig =~ s/\s\w+:/ :/g; # remove parameter names
   1664 
   1665                 push(@implContent, "$deprecatedFunctionSig\n");
   1666                 push(@implContent, "{\n");
   1667                 push(@implContent, "    $jsContextSetter\n");
   1668                 push(@implContent, @functionContent);
   1669                 push(@implContent, "}\n\n");
   1670             }
   1671 
   1672             # Clear the hash
   1673             %needsCustom = ();
   1674         }
   1675     }
   1676 
   1677     # END implementation
   1678     push(@implContent, "\@end\n");
   1679 
   1680     # Generate internal interfaces
   1681     push(@implContent, "\n$implType* core($className *wrapper)\n");
   1682     push(@implContent, "{\n");
   1683     push(@implContent, "    return wrapper ? reinterpret_cast<$implType*>(wrapper->_internal) : 0;\n");
   1684     push(@implContent, "}\n\n");
   1685 
   1686     if ($parentImplClassName eq "Object") {        
   1687         push(@implContent, "$className *kit($implType* value)\n");
   1688         push(@implContent, "{\n");
   1689         push(@implContent, "    $assertMainThread;\n");
   1690         push(@implContent, "    if (!value)\n");
   1691         push(@implContent, "        return nil;\n");
   1692         push(@implContent, "    if ($className *wrapper = getDOMWrapper(value))\n");
   1693         push(@implContent, "        return [[wrapper retain] autorelease];\n");
   1694         if ($dataNode->extendedAttributes->{Polymorphic}) {
   1695             push(@implContent, "    $className *wrapper = [[kitClass(value) alloc] _init];\n");
   1696             push(@implContent, "    if (!wrapper)\n");
   1697             push(@implContent, "        return nil;\n");
   1698         } else {
   1699             push(@implContent, "    $className *wrapper = [[$className alloc] _init];\n");
   1700         }
   1701         push(@implContent, "    wrapper->_internal = reinterpret_cast<DOMObjectInternal*>(value);\n");
   1702         push(@implContent, "    value->ref();\n");
   1703         push(@implContent, "    addDOMWrapper(wrapper, value);\n");
   1704         push(@implContent, "    return [wrapper autorelease];\n");
   1705         push(@implContent, "}\n");
   1706     } else {
   1707         push(@implContent, "$className *kit($implType* value)\n");
   1708         push(@implContent, "{\n");
   1709         push(@implContent, "    $assertMainThread;\n");
   1710         push(@implContent, "    return static_cast<$className*>(kit(static_cast<WebCore::$baseClass*>(value)));\n");
   1711         push(@implContent, "}\n");
   1712     }
   1713 
   1714     # - End the ifdef conditional if necessary
   1715     push(@implContent, "\n#endif // ${conditionalString}\n") if $conditionalString;
   1716 
   1717     # - Generate dependencies.
   1718     if ($writeDependencies && @ancestorInterfaceNames) {
   1719         push(@depsContent, "$className.h : ", join(" ", map { "$_.idl" } @ancestorInterfaceNames), "\n");
   1720         push(@depsContent, map { "$_.idl :\n" } @ancestorInterfaceNames); 
   1721     }
   1722 }
   1723 
   1724 # Internal helper
   1725 sub WriteData
   1726 {
   1727     my $object = shift;
   1728     my $name = shift;
   1729 
   1730     # Open files for writing...
   1731     my $headerFileName = "$outputDir/" . $name . ".h";
   1732     my $privateHeaderFileName = "$outputDir/" . $name . "Private.h";
   1733     my $implFileName = "$outputDir/" . $name . ".mm";
   1734     my $internalHeaderFileName = "$outputDir/" . $name . "Internal.h";
   1735     my $depsFileName = "$outputDir/" . $name . ".dep";
   1736 
   1737     # Remove old files.
   1738     unlink($headerFileName);
   1739     unlink($privateHeaderFileName);
   1740     unlink($implFileName);
   1741     unlink($internalHeaderFileName);
   1742     unlink($depsFileName);
   1743 
   1744     # Write public header.
   1745     open(HEADER, ">$headerFileName") or die "Couldn't open file $headerFileName";
   1746     
   1747     print HEADER @headerContentHeader;
   1748     print HEADER map { "\@class $_;\n" } sort keys(%headerForwardDeclarations);
   1749     print HEADER map { "\@protocol $_;\n" } sort keys(%headerForwardDeclarationsForProtocols);
   1750 
   1751     my $hasForwardDeclarations = keys(%headerForwardDeclarations) + keys(%headerForwardDeclarationsForProtocols);
   1752     print HEADER "\n" if $hasForwardDeclarations;
   1753     print HEADER @headerContent;
   1754 
   1755     close(HEADER);
   1756 
   1757     @headerContentHeader = ();
   1758     @headerContent = ();
   1759     %headerForwardDeclarations = ();
   1760     %headerForwardDeclarationsForProtocols = ();
   1761 
   1762     if (@privateHeaderContent > 0) {
   1763         open(PRIVATE_HEADER, ">$privateHeaderFileName") or die "Couldn't open file $privateHeaderFileName";
   1764 
   1765         print PRIVATE_HEADER @privateHeaderContentHeader;
   1766         print PRIVATE_HEADER map { "\@class $_;\n" } sort keys(%privateHeaderForwardDeclarations);
   1767         print PRIVATE_HEADER map { "\@protocol $_;\n" } sort keys(%privateHeaderForwardDeclarationsForProtocols);
   1768 
   1769         $hasForwardDeclarations = keys(%privateHeaderForwardDeclarations) + keys(%privateHeaderForwardDeclarationsForProtocols);
   1770         print PRIVATE_HEADER "\n" if $hasForwardDeclarations;
   1771         print PRIVATE_HEADER @privateHeaderContent;
   1772 
   1773         close(PRIVATE_HEADER);
   1774 
   1775         @privateHeaderContentHeader = ();
   1776         @privateHeaderContent = ();
   1777         %privateHeaderForwardDeclarations = ();
   1778         %privateHeaderForwardDeclarationsForProtocols = ();
   1779     }
   1780 
   1781     # Write implementation file.
   1782     unless ($noImpl) {
   1783         open(IMPL, ">$implFileName") or die "Couldn't open file $implFileName";
   1784 
   1785         print IMPL @implContentHeader;
   1786         print IMPL map { "#import \"$_\"\n" } sort keys(%implIncludes);
   1787         print IMPL @implContent;
   1788 
   1789         close(IMPL);
   1790 
   1791         @implContentHeader = ();
   1792         @implContent = ();
   1793         %implIncludes = ();
   1794     }
   1795     
   1796     if (@internalHeaderContent > 0) {
   1797        open(INTERNAL_HEADER, ">$internalHeaderFileName") or die "Couldn't open file $internalHeaderFileName";
   1798 
   1799        print INTERNAL_HEADER @internalHeaderContent;
   1800 
   1801        close(INTERNAL_HEADER);
   1802 
   1803        @internalHeaderContent = ();
   1804     }
   1805 
   1806     # Write dependency file.
   1807     if (@depsContent) {
   1808         open(DEPS, ">$depsFileName") or die "Couldn't open file $depsFileName";
   1809         print DEPS @depsContent;
   1810         close(DEPS);
   1811         @depsContent = ();
   1812     }
   1813 }
   1814 
   1815 1;
   1816