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 Apple Inc. All rights reserved.
      7 # Copyright (C) 2009 Cameron McCormack <cam (at] mcc.id.au>
      8 #
      9 # This library is free software; you can redistribute it and/or
     10 # modify it under the terms of the GNU Library General Public
     11 # License as published by the Free Software Foundation; either
     12 # version 2 of the License, or (at your option) any later version.
     13 # 
     14 # This library is distributed in the hope that it will be useful,
     15 # but WITHOUT ANY WARRANTY; without even the implied warranty of
     16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     17 # Library General Public License for more details.
     18 # 
     19 # You should have received a copy of the GNU Library General Public License
     20 # aint with this library; see the file COPYING.LIB.  If not, write to
     21 # the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     22 # Boston, MA 02110-1301, USA.
     23 #
     24 
     25 package CodeGeneratorObjC;
     26 
     27 use File::stat;
     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, "SVGAnimatedPoints" => 1,
     61                         "ElementTimeControl" => 1);
     62 my %nativeObjCTypeHash = ("URL" => 1, "Color" => 1);
     63 
     64 # FIXME: this should be replaced with a function that recurses up the tree
     65 # to find the actual base type.
     66 my %baseTypeHash = ("Object" => 1, "Node" => 1, "NodeList" => 1, "NamedNodeMap" => 1, "DOMImplementation" => 1,
     67                     "Event" => 1, "CSSRule" => 1, "CSSValue" => 1, "StyleSheet" => 1, "MediaList" => 1,
     68                     "Counter" => 1, "Rect" => 1, "RGBColor" => 1, "XPathExpression" => 1, "XPathResult" => 1,
     69                     "NodeIterator" => 1, "TreeWalker" => 1, "AbstractView" => 1, "Blob" => 1,
     70                     "SVGAngle" => 1, "SVGAnimatedAngle" => 1, "SVGAnimatedBoolean" => 1, "SVGAnimatedEnumeration" => 1,
     71                     "SVGAnimatedInteger" => 1, "SVGAnimatedLength" => 1, "SVGAnimatedLengthList" => 1,
     72                     "SVGAnimatedNumber" => 1, "SVGAnimatedNumberList" => 1, "SVGAnimatedPoints" => 1,
     73                     "SVGAnimatedPreserveAspectRatio" => 1, "SVGAnimatedRect" => 1, "SVGAnimatedString" => 1,
     74                     "SVGAnimatedTransformList" => 1, "SVGLength" => 1, "SVGLengthList" => 1, "SVGMatrix" => 1,
     75                     "SVGNumber" => 1, "SVGNumberList" => 1, "SVGPathSeg" => 1, "SVGPathSegList" => 1, "SVGPoint" => 1,
     76                     "SVGPointList" => 1, "SVGPreserveAspectRatio" => 1, "SVGRect" => 1, "SVGRenderingIntent" => 1,
     77                     "SVGStringList" => 1, "SVGTransform" => 1, "SVGTransformList" => 1, "SVGUnitTypes" => 1);
     78 
     79 # Constants
     80 my $buildingForTigerOrEarlier = 1 if $ENV{"MACOSX_DEPLOYMENT_TARGET"} and $ENV{"MACOSX_DEPLOYMENT_TARGET"} <= 10.4;
     81 my $buildingForLeopardOrLater = 1 if $ENV{"MACOSX_DEPLOYMENT_TARGET"} and $ENV{"MACOSX_DEPLOYMENT_TARGET"} >= 10.5;
     82 my $exceptionInit = "WebCore::ExceptionCode ec = 0;";
     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; # $useLayerOnTop
    201     shift; # $preprocessor
    202     $writeDependencies = shift;
    203 
    204     bless($reference, $object);
    205     return $reference;
    206 }
    207 
    208 sub finish
    209 {
    210     my $object = shift;
    211 }
    212 
    213 sub ReadPublicInterfaces
    214 {
    215     my $class = shift;
    216     my $superClass = shift;
    217     my $defines = shift;
    218     my $isProtocol = shift;
    219 
    220     my $found = 0;
    221     my $actualSuperClass;
    222     %publicInterfaces = ();
    223 
    224     my $fileName = "WebCore/bindings/objc/PublicDOMInterfaces.h";
    225     open FILE, "-|", "/usr/bin/gcc", "-E", "-P", "-x", "objective-c", 
    226         (map { "-D$_" } split(/ +/, $defines)), "-DOBJC_CODE_GENERATION", $fileName or die "Could not open $fileName";
    227     my @documentContent = <FILE>;
    228     close FILE;
    229 
    230     foreach $line (@documentContent) {
    231         if (!$isProtocol && $line =~ /^\s*\@interface\s*$class\s*:\s*(\w+)\s*([A-Z0-9_]*)/) {
    232             if ($superClass ne $1) {
    233                 warn "Public API change. Superclass for \"$class\" differs ($1 != $superClass)";
    234                 $fatalError = 1;
    235             }
    236 
    237             $interfaceAvailabilityVersion = $2 if defined $2;
    238             $found = 1;
    239             next;
    240         } elsif ($isProtocol && $line =~ /^\s*\@protocol $class\s*<[^>]+>\s*([A-Z0-9_]*)/) {
    241             $interfaceAvailabilityVersion = $1 if defined $1;
    242             $found = 1;
    243             next;
    244         }
    245 
    246         last if $found and $line =~ /^\s?\@end\s?$/;
    247 
    248         if ($found) {
    249             # trim whitspace
    250             $line =~ s/^\s+//;
    251             $line =~ s/\s+$//;
    252 
    253             my $availabilityMacro = "";
    254             $line =~ s/\s([A-Z0-9_]+)\s*;$/;/;
    255             $availabilityMacro = $1 if defined $1;
    256 
    257             $publicInterfaces{$line} = $availabilityMacro if length $line;
    258         }
    259     }
    260 
    261     # If this class was not found in PublicDOMInterfaces.h then it should be considered as an entirely new public class.
    262     $newPublicClass = !$found;
    263     $interfaceAvailabilityVersion = "WEBKIT_VERSION_LATEST" if $newPublicClass;
    264 }
    265 
    266 # Params: 'domClass' struct
    267 sub GenerateInterface
    268 {
    269     my $object = shift;
    270     my $dataNode = shift;
    271     my $defines = shift;
    272 
    273     $fatalError = 0;
    274 
    275     my $name = $dataNode->name;
    276     my $className = GetClassName($name);
    277     my $parentClassName = "DOM" . GetParentImplClassName($dataNode);
    278     $isProtocol = $dataNode->extendedAttributes->{ObjCProtocol};
    279     $noImpl = $dataNode->extendedAttributes->{ObjCCustomImplementation} || $isProtocol;
    280 
    281     ReadPublicInterfaces($className, $parentClassName, $defines, $isProtocol);
    282 
    283     # Start actual generation..
    284     $object->GenerateHeader($dataNode);
    285     $object->GenerateImplementation($dataNode) unless $noImpl;
    286 
    287     # Write changes.
    288     $object->WriteData("DOM" . $name);
    289 
    290     # Check for missing public API
    291     if (keys %publicInterfaces > 0) {
    292         my $missing = join("\n", keys %publicInterfaces);
    293         warn "Public API change. There are missing public properties and/or methods from the \"$className\" class.\n$missing\n";
    294         $fatalError = 1;
    295     }
    296 
    297     die if $fatalError;
    298 }
    299 
    300 # Params: 'idlDocument' struct
    301 sub GenerateModule
    302 {
    303     my $object = shift;
    304     my $dataNode = shift;
    305 
    306     $module = $dataNode->module;
    307 }
    308 
    309 sub GetClassName
    310 {
    311     my $name = $codeGenerator->StripModule(shift);
    312 
    313     # special cases
    314     return "NSString" if $codeGenerator->IsStringType($name) or $name eq "SerializedScriptValue";
    315     return "NS$name" if IsNativeObjCType($name);
    316     return "BOOL" if $name eq "boolean";
    317     return "unsigned" if $name eq "unsigned long";
    318     return "int" if $name eq "long";
    319     return "NSTimeInterval" if $name eq "Date";
    320     return "DOMAbstractView" if $name eq "DOMWindow";
    321     return $name if $codeGenerator->IsPrimitiveType($name) or $name eq "DOMImplementation" or $name eq "DOMTimeStamp";
    322 
    323     # Default, assume Objective-C type has the same type name as
    324     # idl type prefixed with "DOM".
    325     return "DOM$name";
    326 }
    327 
    328 sub GetClassHeaderName
    329 {
    330     my $name = shift;
    331 
    332     return "DOMDOMImplementation" if $name eq "DOMImplementation";
    333     return $name;
    334 }
    335 
    336 sub GetImplClassName
    337 {
    338     my $name = $codeGenerator->StripModule(shift);
    339 
    340     return "DOMImplementationFront" if $name eq "DOMImplementation";
    341     return "DOMWindow" if $name eq "AbstractView";
    342     return $name;
    343 }
    344 
    345 sub GetParentImplClassName
    346 {
    347     my $dataNode = shift;
    348 
    349     return "Object" if @{$dataNode->parents} eq 0;
    350 
    351     my $parent = $codeGenerator->StripModule($dataNode->parents(0));
    352 
    353     # special cases
    354     return "Object" if $parent eq "HTMLCollection";
    355 
    356     return $parent;
    357 }
    358 
    359 sub GetParentAndProtocols
    360 {
    361     my $dataNode = shift;
    362     my $numParents = @{$dataNode->parents};
    363 
    364     my $parent = "";
    365     my @protocols = ();
    366     if ($numParents eq 0) {
    367         if ($isProtocol) {
    368             push(@protocols, "NSObject");
    369             push(@protocols, "NSCopying") if $dataNode->name eq "EventTarget";
    370         } else {
    371             $parent = "DOMObject";
    372         }
    373     } elsif ($numParents eq 1) {
    374         my $parentName = $codeGenerator->StripModule($dataNode->parents(0));
    375         if ($isProtocol) {
    376             die "Parents of protocols must also be protocols." unless IsProtocolType($parentName);
    377             push(@protocols, "DOM" . $parentName);
    378         } else {
    379             if (IsProtocolType($parentName)) {
    380                 push(@protocols, "DOM" . $parentName);
    381             } elsif ($parentName eq "HTMLCollection") {
    382                 $parent = "DOMObject";
    383             } else {
    384                 $parent = "DOM" . $parentName;
    385             }
    386         }
    387     } else {
    388         my @parents = @{$dataNode->parents};
    389         my $firstParent = $codeGenerator->StripModule(shift(@parents));
    390         if (IsProtocolType($firstParent)) {
    391             push(@protocols, "DOM" . $firstParent);
    392             if (!$isProtocol) {
    393                 $parent = "DOMObject";
    394             }
    395         } else {
    396             $parent = "DOM" . $firstParent;
    397         }
    398 
    399         foreach my $parentName (@parents) {
    400             $parentName = $codeGenerator->StripModule($parentName);
    401             die "Everything past the first class should be a protocol!" unless IsProtocolType($parentName);
    402 
    403             push(@protocols, "DOM" . $parentName);
    404         }
    405     }
    406 
    407     return ($parent, @protocols);
    408 }
    409 
    410 sub GetBaseClass
    411 {
    412     $parent = shift;
    413 
    414     return $parent if $parent eq "Object" or IsBaseType($parent);
    415     return "Event" if $parent eq "UIEvent";
    416     return "CSSValue" if $parent eq "SVGColor" or $parent eq "CSSValueList";
    417     return "Node";
    418 }
    419 
    420 sub IsBaseType
    421 {
    422     my $type = shift;
    423 
    424     return 1 if $baseTypeHash{$type};
    425     return 0;
    426 }
    427 
    428 sub IsProtocolType
    429 {
    430     my $type = shift;
    431 
    432     return 1 if $protocolTypeHash{$type};
    433     return 0;
    434 }
    435 
    436 sub IsNativeObjCType
    437 {
    438     my $type = shift;
    439 
    440     return 1 if $nativeObjCTypeHash{$type};
    441     return 0;
    442 }
    443 
    444 sub GetObjCType
    445 {
    446     my $type = shift;
    447     my $name = GetClassName($type);
    448 
    449     return "id <$name>" if IsProtocolType($type);
    450     return $name if $codeGenerator->IsPrimitiveType($type) or $type eq "DOMTimeStamp";
    451     return "unsigned short" if $type eq "CompareHow" or $type eq "SVGPaintType";
    452     return "$name *";
    453 }
    454 
    455 sub GetPropertyAttributes
    456 {
    457     my $type = $codeGenerator->StripModule(shift);
    458     my $readOnly = shift;
    459 
    460     my @attributes = ();
    461 
    462     push(@attributes, "readonly") if $readOnly;
    463 
    464     # FIXME: <rdar://problem/5049934> Consider using 'nonatomic' on the DOM @property declarations.
    465     if ($codeGenerator->IsStringType($type) || IsNativeObjCType($type)) {
    466         push(@attributes, "copy");
    467     } elsif ($codeGenerator->IsPodType($type) || $codeGenerator->IsSVGAnimatedType($type)) {
    468         push(@attributes, "retain");
    469     } elsif (!$codeGenerator->IsStringType($type) && !$codeGenerator->IsPrimitiveType($type) && $type ne "DOMTimeStamp" && $type ne "CompareHow" && $type ne "SVGPaintType") {
    470         push(@attributes, "retain");
    471     }
    472 
    473     return "" unless @attributes > 0;
    474     return "(" . join(", ", @attributes) . ")";
    475 }
    476 
    477 sub ConversionNeeded
    478 {
    479     my $type = $codeGenerator->StripModule(shift);
    480 
    481     return !$codeGenerator->IsNonPointerType($type) && !$codeGenerator->IsStringType($type) && !IsNativeObjCType($type);
    482 }
    483 
    484 sub GetObjCTypeGetter
    485 {
    486     my $argName = shift;
    487     my $type = $codeGenerator->StripModule(shift);
    488 
    489     return $argName if $codeGenerator->IsPrimitiveType($type) or $codeGenerator->IsStringType($type) or IsNativeObjCType($type);
    490     return $argName . "Node" if $type eq "EventTarget";
    491     return "static_cast<WebCore::Range::CompareHow>($argName)" if $type eq "CompareHow";
    492     return "static_cast<WebCore::SVGPaint::SVGPaintType>($argName)" if $type eq "SVGPaintType";
    493     return "WTF::getPtr(nativeEventListener)" if $type eq "EventListener";
    494     return "WTF::getPtr(nativeNodeFilter)" if $type eq "NodeFilter";
    495     return "WTF::getPtr(nativeResolver)" if $type eq "XPathNSResolver";
    496     
    497     if ($type eq "SerializedScriptValue") {
    498         $implIncludes{"SerializedScriptValue.h"} = 1;
    499         return "WebCore::SerializedScriptValue::create(WebCore::String($argName))";
    500     }
    501     return "core($argName)";
    502 }
    503 
    504 sub AddForwardDeclarationsForType
    505 {
    506     my $type = $codeGenerator->StripModule(shift);
    507     my $public = shift;
    508 
    509     return if $codeGenerator->IsNonPointerType($type) ;
    510 
    511     my $class = GetClassName($type);
    512 
    513     if (IsProtocolType($type)) {
    514         $headerForwardDeclarationsForProtocols{$class} = 1 if $public;
    515         $privateHeaderForwardDeclarationsForProtocols{$class} = 1 if !$public and !$headerForwardDeclarationsForProtocols{$class};
    516         return;
    517     }
    518 
    519     $headerForwardDeclarations{$class} = 1 if $public;
    520 
    521     # Private headers include the public header, so only add a forward declaration to the private header
    522     # if the public header does not already have the same forward declaration.
    523     $privateHeaderForwardDeclarations{$class} = 1 if !$public and !$headerForwardDeclarations{$class};
    524 }
    525 
    526 sub AddIncludesForType
    527 {
    528     my $type = $codeGenerator->StripModule(shift);
    529 
    530     return if $codeGenerator->IsNonPointerType($type);
    531 
    532     if (IsNativeObjCType($type)) {
    533         if ($type eq "Color") {
    534             $implIncludes{"ColorMac.h"} = 1;
    535         }
    536         return;
    537     }
    538 
    539     if ($codeGenerator->IsStringType($type)) {
    540         $implIncludes{"KURL.h"} = 1;
    541         return;
    542     }
    543 
    544     if ($type eq "DOMWindow") {
    545         $implIncludes{"DOMAbstractViewInternal.h"} = 1;
    546         $implIncludes{"DOMWindow.h"} = 1;
    547         return;
    548     }
    549 
    550     if ($type eq "DOMImplementation") {
    551         $implIncludes{"DOMDOMImplementationInternal.h"} = 1;
    552         $implIncludes{"DOMImplementationFront.h"} = 1;
    553         return;
    554     }
    555 
    556     if ($type eq "EventTarget") {
    557         $implIncludes{"Node.h"} = 1;
    558         $implIncludes{"DOMEventTarget.h"} = 1;
    559         return;
    560     }
    561 
    562     if ($codeGenerator->IsSVGAnimatedType($type)) {
    563         $implIncludes{"SVGAnimatedTemplate.h"} = 1;
    564         $implIncludes{"DOM${type}Internal.h"} = 1;
    565         return;
    566     }
    567 
    568     if ($type eq "SVGRect") {
    569         $implIncludes{"FloatRect.h"} = 1;
    570         $implIncludes{"DOMSVGRectInternal.h"} = 1;
    571         return;
    572     }
    573 
    574     if ($type eq "SVGPoint") {
    575         $implIncludes{"FloatPoint.h"} = 1;
    576         $implIncludes{"DOMSVGPointInternal.h"} = 1;
    577         return;
    578     }
    579 
    580     if ($type eq "SVGMatrix") {
    581         $implIncludes{"AffineTransform.h"} = 1;
    582         $implIncludes{"DOMSVGMatrixInternal.h"} = 1;
    583         $implIncludes{"SVGException.h"} = 1;
    584         return;
    585     }
    586 
    587     if ($type eq "SVGNumber") {
    588         $implIncludes{"DOMSVGNumberInternal.h"} = 1;
    589         return;
    590     }
    591 
    592     if ($type =~ /(\w+)(Abs|Rel)$/) {
    593         $implIncludes{"$1.h"} = 1;
    594         $implIncludes{"DOM${type}Internal.h"} = 1;
    595         return;
    596     }
    597 
    598     if ($type eq "NodeFilter") {
    599         $implIncludes{"NodeFilter.h"} = 1;
    600         $implIncludes{"ObjCNodeFilterCondition.h"} = 1;
    601         return;
    602     }
    603 
    604     if ($type eq "EventListener") {
    605         $implIncludes{"EventListener.h"} = 1;
    606         $implIncludes{"ObjCEventListener.h"} = 1;
    607         return;
    608     }
    609 
    610     if ($type eq "XPathNSResolver") {
    611         $implIncludes{"DOMCustomXPathNSResolver.h"} = 1;
    612         $implIncludes{"XPathNSResolver.h"} = 1;
    613         return;
    614     }
    615 
    616     if ($type eq "SerializedScriptValue") {
    617         $implIncludes{"SerializedScriptValue.h"} = 1;
    618         return;
    619     }
    620 
    621     # FIXME: won't compile without these
    622     $implIncludes{"CSSMutableStyleDeclaration.h"} = 1 if $type eq "CSSStyleDeclaration";
    623     $implIncludes{"NameNodeList.h"} = 1 if $type eq "NodeList";
    624 
    625     # Default, include the same named file (the implementation) and the same name prefixed with "DOM". 
    626     $implIncludes{"$type.h"} = 1;
    627     $implIncludes{"DOM${type}Internal.h"} = 1;
    628 }
    629 
    630 sub GenerateHeader
    631 {
    632     my $object = shift;
    633     my $dataNode = shift;
    634 
    635     my $interfaceName = $dataNode->name;
    636     my $className = GetClassName($interfaceName);
    637 
    638     my $parentName = "";
    639     my @protocolsToImplement = ();
    640     ($parentName, @protocolsToImplement) = GetParentAndProtocols($dataNode);
    641 
    642     my $numConstants = @{$dataNode->constants};
    643     my $numAttributes = @{$dataNode->attributes};
    644     my $numFunctions = @{$dataNode->functions};
    645 
    646     # - Add default header template
    647     @headerContentHeader = split("\r", $headerLicenseTemplate);
    648     push(@headerContentHeader, "\n");
    649 
    650     # - INCLUDES -
    651     my $includedWebKitAvailabilityHeader = 0;
    652     unless ($isProtocol) {
    653         my $parentHeaderName = GetClassHeaderName($parentName);
    654         push(@headerContentHeader, "#import <WebCore/$parentHeaderName.h>\n");
    655         $includedWebKitAvailabilityHeader = 1;
    656     }
    657 
    658     foreach my $parentProtocol (@protocolsToImplement) {
    659         next if $parentProtocol =~ /^NS/; 
    660         $parentProtocol = GetClassHeaderName($parentProtocol);
    661         push(@headerContentHeader, "#import <WebCore/$parentProtocol.h>\n");
    662         $includedWebKitAvailabilityHeader = 1;
    663     }
    664 
    665     # Special case needed for legacy support of DOMRange
    666     if ($interfaceName eq "Range") {
    667         push(@headerContentHeader, "#import <WebCore/DOMCore.h>\n");
    668         push(@headerContentHeader, "#import <WebCore/DOMDocument.h>\n");
    669         push(@headerContentHeader, "#import <WebCore/DOMRangeException.h>\n");
    670         $includedWebKitAvailabilityHeader = 1;
    671     }
    672 
    673     push(@headerContentHeader, "#import <JavaScriptCore/WebKitAvailability.h>\n") unless $includedWebKitAvailabilityHeader;
    674 
    675     my $interfaceAvailabilityVersionCheck = "#if WEBKIT_VERSION_MAX_ALLOWED >= $interfaceAvailabilityVersion\n\n";
    676 
    677     push(@headerContentHeader, "\n");
    678     push(@headerContentHeader, $interfaceAvailabilityVersionCheck) if length $interfaceAvailabilityVersion;
    679 
    680     # - Add constants.
    681     if ($numConstants > 0) {
    682         my @headerConstants = ();
    683 
    684         # FIXME: we need a way to include multiple enums.
    685         foreach my $constant (@{$dataNode->constants}) {
    686             my $constantName = $constant->name;
    687             my $constantValue = $constant->value;
    688 
    689             my $output = "    DOM_" . $constantName . " = " . $constantValue;
    690             push(@headerConstants, $output);
    691         }
    692 
    693         my $combinedConstants = join(",\n", @headerConstants);
    694 
    695         # FIXME: the formatting of the enums should line up the equal signs.
    696         # FIXME: enums are unconditionally placed in the public header.
    697         push(@headerContent, "enum {\n");
    698         push(@headerContent, $combinedConstants);
    699         push(@headerContent, "\n};\n\n");        
    700     }
    701 
    702     # - Begin @interface or @protocol
    703     my $interfaceDeclaration = ($isProtocol ? "\@protocol $className" : "\@interface $className : $parentName");
    704     $interfaceDeclaration .= " <" . join(", ", @protocolsToImplement) . ">" if @protocolsToImplement > 0;
    705     $interfaceDeclaration .= "\n";
    706 
    707     push(@headerContent, $interfaceDeclaration);
    708 
    709     my @headerAttributes = ();
    710     my @privateHeaderAttributes = ();
    711 
    712     # - Add attribute getters/setters.
    713     if ($numAttributes > 0) {
    714         foreach my $attribute (@{$dataNode->attributes}) {
    715             my $attributeName = $attribute->signature->name;
    716 
    717             if ($attributeName eq "id" or $attributeName eq "hash") {
    718                 # Special case attributes id and hash to be idName and hashName to avoid ObjC naming conflict.
    719                 $attributeName .= "Name";
    720             } elsif ($attributeName eq "frame") {
    721                 # Special case attribute frame to be frameBorders.
    722                 $attributeName .= "Borders";
    723             }
    724 
    725             my $attributeType = GetObjCType($attribute->signature->type);
    726             my $attributeIsReadonly = ($attribute->type =~ /^readonly/);
    727 
    728             my $property = "\@property" . GetPropertyAttributes($attribute->signature->type, $attributeIsReadonly);
    729             # Some SVGFE*Element.idl use 'operator' as attribute name, rewrite as '_operator' to avoid clashes with C/C++
    730             $attributeName =~ s/operator/_operator/ if ($attributeName =~ /operator/);
    731             $property .= " " . $attributeType . ($attributeType =~ /\*$/ ? "" : " ") . $attributeName;
    732 
    733             my $publicInterfaceKey = $property . ";";
    734 
    735             my $availabilityMacro = "";
    736             if (defined $publicInterfaces{$publicInterfaceKey} and length $publicInterfaces{$publicInterfaceKey}) {
    737                 $availabilityMacro = $publicInterfaces{$publicInterfaceKey};
    738             }
    739 
    740             $availabilityMacro = "WEBKIT_OBJC_METHOD_ANNOTATION($availabilityMacro)" if length $availabilityMacro and $buildingForTigerOrEarlier;
    741 
    742             my $declarationSuffix = ";\n";
    743             $declarationSuffix = " $availabilityMacro;\n" if length $availabilityMacro;
    744 
    745             my $public = (defined $publicInterfaces{$publicInterfaceKey} or $newPublicClass);
    746             delete $publicInterfaces{$publicInterfaceKey};
    747 
    748             AddForwardDeclarationsForType($attribute->signature->type, $public);
    749 
    750             my $setterName = "set" . ucfirst($attributeName) . ":";
    751 
    752             my $conflict = $conflictMethod{$attributeName};
    753             if ($conflict) {
    754                 warn "$className conflicts with $conflict method $attributeName\n";
    755                 $fatalError = 1;
    756             }
    757 
    758             $conflict = $conflictMethod{$setterName};
    759             if ($conflict) {
    760                 warn "$className conflicts with $conflict method $setterName\n";
    761                 $fatalError = 1;
    762             }
    763 
    764             if ($buildingForLeopardOrLater) {
    765                 $property .= $declarationSuffix;
    766                 push(@headerAttributes, $property) if $public;
    767                 push(@privateHeaderAttributes, $property) unless $public;
    768             } else {
    769                 # - GETTER
    770                 my $getter = "- (" . $attributeType . ")" . $attributeName . $declarationSuffix;
    771                 push(@headerAttributes, $getter) if $public;
    772                 push(@privateHeaderAttributes, $getter) unless $public;
    773 
    774                 # - SETTER
    775                 if (!$attributeIsReadonly) {
    776                     my $setter = "- (void)$setterName(" . $attributeType . ")new" . ucfirst($attributeName) . $declarationSuffix;
    777                     push(@headerAttributes, $setter) if $public;
    778                     push(@privateHeaderAttributes, $setter) unless $public;
    779                 }
    780             }
    781         }
    782 
    783         push(@headerContent, @headerAttributes) if @headerAttributes > 0;
    784     }
    785 
    786     my @headerFunctions = ();
    787     my @privateHeaderFunctions = ();
    788     my @deprecatedHeaderFunctions = ();
    789 
    790     # - Add functions.
    791     if ($numFunctions > 0) {
    792         foreach my $function (@{$dataNode->functions}) {
    793             my $functionName = $function->signature->name;
    794 
    795             my $returnType = GetObjCType($function->signature->type);
    796             my $needsDeprecatedVersion = (@{$function->parameters} > 1 and $function->signature->extendedAttributes->{"OldStyleObjC"});
    797             my $numberOfParameters = @{$function->parameters};
    798             my %typesToForwardDeclare = ($function->signature->type => 1);
    799 
    800             my $parameterIndex = 0;
    801             my $functionSig = "- ($returnType)$functionName";
    802             my $methodName = $functionName;
    803             foreach my $param (@{$function->parameters}) {
    804                 my $paramName = $param->name;
    805                 my $paramType = GetObjCType($param->type);
    806 
    807                 $typesToForwardDeclare{$param->type} = 1;
    808 
    809                 if ($parameterIndex >= 1) {
    810                     my $paramPrefix = $param->extendedAttributes->{"ObjCPrefix"};
    811                     $paramPrefix = $paramName unless defined($paramPrefix);
    812                     $functionSig .= " $paramPrefix";
    813                     $methodName .= $paramPrefix;
    814                 }
    815 
    816                 $functionSig .= ":($paramType)$paramName";
    817                 $methodName .= ":";
    818 
    819                 $parameterIndex++;
    820             }
    821 
    822             my $publicInterfaceKey = $functionSig . ";";
    823 
    824             my $conflict = $conflictMethod{$methodName};
    825             if ($conflict) {
    826                 warn "$className conflicts with $conflict method $methodName\n";
    827                 $fatalError = 1;
    828             }
    829 
    830             if ($isProtocol && !$newPublicClass && !defined $publicInterfaces{$publicInterfaceKey}) {
    831                 warn "Protocol method $publicInterfaceKey is not in PublicDOMInterfaces.h. Protocols require all methods to be public";
    832                 $fatalError = 1;
    833             }
    834 
    835             my $availabilityMacro = "";
    836             if (defined $publicInterfaces{$publicInterfaceKey} and length $publicInterfaces{$publicInterfaceKey}) {
    837                 $availabilityMacro = $publicInterfaces{$publicInterfaceKey};
    838             }
    839 
    840             $availabilityMacro = "WEBKIT_OBJC_METHOD_ANNOTATION($availabilityMacro)" if length $availabilityMacro and $buildingForTigerOrEarlier;
    841 
    842             my $functionDeclaration = $functionSig;
    843             $functionDeclaration .= " " . $availabilityMacro if length $availabilityMacro;
    844             $functionDeclaration .= ";\n";
    845 
    846             my $public = (defined $publicInterfaces{$publicInterfaceKey} or $newPublicClass);
    847             delete $publicInterfaces{$publicInterfaceKey};
    848 
    849             foreach my $type (keys %typesToForwardDeclare) {
    850                 # add any forward declarations to the public header if a deprecated version will be generated
    851                 AddForwardDeclarationsForType($type, 1) if $needsDeprecatedVersion;
    852                 AddForwardDeclarationsForType($type, $public) unless $public and $needsDeprecatedVersion;
    853             }
    854 
    855             push(@headerFunctions, $functionDeclaration) if $public;
    856             push(@privateHeaderFunctions, $functionDeclaration) unless $public;
    857 
    858             # generate the old style method names with un-named parameters, these methods are deprecated
    859             if ($needsDeprecatedVersion) {
    860                 my $deprecatedFunctionSig = $functionSig;
    861                 $deprecatedFunctionSig =~ s/\s\w+:/ :/g; # remove parameter names
    862 
    863                 $publicInterfaceKey = $deprecatedFunctionSig . ";";
    864 
    865                 my $availabilityMacro = "AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_3_0";
    866                 if (defined $publicInterfaces{$publicInterfaceKey} and length $publicInterfaces{$publicInterfaceKey}) {
    867                     $availabilityMacro = $publicInterfaces{$publicInterfaceKey};
    868                 }
    869 
    870                 $availabilityMacro = "WEBKIT_OBJC_METHOD_ANNOTATION($availabilityMacro)" if $buildingForTigerOrEarlier;
    871 
    872                 $functionDeclaration = "$deprecatedFunctionSig $availabilityMacro;\n";
    873 
    874                 push(@deprecatedHeaderFunctions, $functionDeclaration);
    875 
    876                 unless (defined $publicInterfaces{$publicInterfaceKey}) {
    877                     warn "Deprecated method $publicInterfaceKey is not in PublicDOMInterfaces.h. All deprecated methods need to be public, or should have the OldStyleObjC IDL attribute removed";
    878                     $fatalError = 1;
    879                 }
    880 
    881                 delete $publicInterfaces{$publicInterfaceKey};
    882             }
    883         }
    884 
    885         if (@headerFunctions > 0) {
    886             push(@headerContent, "\n") if $buildingForLeopardOrLater and @headerAttributes > 0;
    887             push(@headerContent, @headerFunctions);
    888         }
    889     }
    890 
    891     if (@deprecatedHeaderFunctions > 0 && $isProtocol) {
    892         push(@headerContent, @deprecatedHeaderFunctions);
    893     }
    894 
    895     # - End @interface or @protocol
    896     push(@headerContent, "\@end\n");
    897 
    898     if (@deprecatedHeaderFunctions > 0 && !$isProtocol) {
    899         # - Deprecated category @interface 
    900         push(@headerContent, "\n\@interface $className (" . $className . "Deprecated)\n");
    901         push(@headerContent, @deprecatedHeaderFunctions);
    902         push(@headerContent, "\@end\n");
    903     }
    904 
    905     push(@headerContent, "\n#endif\n") if length $interfaceAvailabilityVersion;
    906 
    907     my %alwaysGenerateForNoSVGBuild = map { $_ => 1 } qw(DOMHTMLEmbedElement DOMHTMLObjectElement);
    908 
    909     if (@privateHeaderAttributes > 0 or @privateHeaderFunctions > 0 or exists $alwaysGenerateForNoSVGBuild{$className}) {
    910         # - Private category @interface
    911         @privateHeaderContentHeader = split("\r", $headerLicenseTemplate);
    912         push(@privateHeaderContentHeader, "\n");
    913 
    914         my $classHeaderName = GetClassHeaderName($className);
    915         push(@privateHeaderContentHeader, "#import <WebCore/$classHeaderName.h>\n\n");
    916         push(@privateHeaderContentHeader, $interfaceAvailabilityVersionCheck) if length $interfaceAvailabilityVersion;
    917 
    918         @privateHeaderContent = ();
    919         push(@privateHeaderContent, "\@interface $className (" . $className . "Private)\n");
    920         push(@privateHeaderContent, @privateHeaderAttributes) if @privateHeaderAttributes > 0;
    921         push(@privateHeaderContent, "\n") if $buildingForLeopardOrLater and @privateHeaderAttributes > 0 and @privateHeaderFunctions > 0;
    922         push(@privateHeaderContent, @privateHeaderFunctions) if @privateHeaderFunctions > 0;
    923         push(@privateHeaderContent, "\@end\n");
    924 
    925         push(@privateHeaderContent, "\n#endif\n") if length $interfaceAvailabilityVersion;
    926     }
    927 
    928     unless ($isProtocol) {
    929         # Generate internal interfaces
    930         my $podType = $dataNode->extendedAttributes->{"PODType"};
    931 
    932         # Generate interface definitions. 
    933         @internalHeaderContent = split("\r", $implementationLicenseTemplate);
    934 
    935         push(@internalHeaderContent, "\n#import <WebCore/$className.h>\n\n");
    936         push(@internalHeaderContent, $interfaceAvailabilityVersionCheck) if length $interfaceAvailabilityVersion;
    937 
    938         if ($interfaceName eq "Node") {
    939             push(@internalHeaderContent, "\@protocol DOMEventTarget;\n\n");
    940         }
    941 
    942         my $startedNamespace = 0;
    943 
    944         my $implClassName = GetImplClassName($interfaceName);
    945 
    946         if ($codeGenerator->IsSVGAnimatedType($interfaceName)) {
    947             push(@internalHeaderContent, "#import <WebCore/SVGAnimatedTemplate.h>\n\n");
    948         } else {
    949             push(@internalHeaderContent, "namespace WebCore {\n");
    950             $startedNamespace = 1;
    951             if ($podType and $podType ne "float") {
    952                 push(@internalHeaderContent, "    class $podType;\n");
    953             } elsif ($interfaceName eq "Node") {
    954                 push(@internalHeaderContent, "    class EventTarget;\n    class Node;\n");
    955             } else {
    956                 push(@internalHeaderContent, "    class $implClassName;\n");
    957             }
    958             push(@internalHeaderContent, "}\n\n");
    959         }
    960 
    961         if ($podType) {
    962             if ($podType eq "float") {
    963                 push(@internalHeaderContent, "float core($className *);\n");
    964             } else {
    965                 push(@internalHeaderContent, "WebCore::$podType core($className *);\n");
    966             }
    967         } else {
    968             push(@internalHeaderContent, "WebCore::$implClassName* core($className *);\n");
    969         }
    970 
    971         if ($podType) {
    972             if ($podType eq "float") {
    973                 push(@internalHeaderContent, "$className *kit($podType);\n");
    974             } else {
    975                 push(@internalHeaderContent, "$className *kit(WebCore::$podType);\n");
    976             }
    977         } else {
    978             push(@internalHeaderContent, "$className *kit(WebCore::$implClassName*);\n");
    979         }
    980 
    981         if ($dataNode->extendedAttributes->{Polymorphic}) {
    982             push(@internalHeaderContent, "Class kitClass(WebCore::$implClassName*);\n");
    983         }
    984 
    985         if ($interfaceName eq "Node") {
    986             push(@internalHeaderContent, "id <DOMEventTarget> kit(WebCore::EventTarget*);\n");
    987         }
    988 
    989         push(@internalHeaderContent, "\n#endif\n") if length $interfaceAvailabilityVersion;
    990     }
    991 }
    992 
    993 sub GenerateImplementation
    994 {
    995     my $object = shift;
    996     my $dataNode = shift;
    997 
    998     my @ancestorInterfaceNames = ();
    999 
   1000     if (@{$dataNode->parents} > 1) {
   1001         $codeGenerator->AddMethodsConstantsAndAttributesFromParentClasses($dataNode, \@ancestorInterfaceNames);
   1002     }
   1003 
   1004     my $interfaceName = $dataNode->name;
   1005     my $className = GetClassName($interfaceName);
   1006     my $implClassName = GetImplClassName($interfaceName);
   1007     my $parentImplClassName = GetParentImplClassName($dataNode);
   1008     my $implClassNameWithNamespace = "WebCore::" . $implClassName;
   1009     my $baseClass = GetBaseClass($parentImplClassName);
   1010     my $classHeaderName = GetClassHeaderName($className);
   1011     my $conditional = $dataNode->extendedAttributes->{"Conditional"};
   1012 
   1013     my $numAttributes = @{$dataNode->attributes};
   1014     my $numFunctions = @{$dataNode->functions};
   1015 
   1016     my $podType = $dataNode->extendedAttributes->{"PODType"};
   1017     my $podTypeWithNamespace;
   1018 
   1019     if ($podType) {
   1020         $podTypeWithNamespace = ($podType eq "float") ? "$podType" : "WebCore::$podType";
   1021     }
   1022 
   1023     # - Add default header template.
   1024     @implContentHeader = split("\r", $implementationLicenseTemplate);
   1025 
   1026     # - INCLUDES -
   1027     push(@implContentHeader, "\n#import \"config.h\"\n");
   1028 
   1029     my $conditionalString;
   1030     if ($conditional) {
   1031         $conditionalString = "ENABLE(" . join(") && ENABLE(", split(/&/, $conditional)) . ")";
   1032         push(@implContentHeader, "\n#if ${conditionalString}\n\n");
   1033     }
   1034 
   1035     push(@implContentHeader, "#import \"DOMInternal.h\"\n\n");
   1036     push(@implContentHeader, "#import \"$classHeaderName.h\"\n\n");
   1037 
   1038     $implIncludes{"ExceptionHandlers.h"} = 1;
   1039     $implIncludes{"ThreadCheck.h"} = 1;
   1040     $implIncludes{"WebScriptObjectPrivate.h"} = 1;
   1041     $implIncludes{$classHeaderName . "Internal.h"} = 1;
   1042 
   1043     # FIXME: These includes are only needed when the class is a subclass of one of these polymorphic classes.
   1044     $implIncludes{"DOMBlobInternal.h"} = 1;
   1045     $implIncludes{"DOMCSSRuleInternal.h"} = 1;
   1046     $implIncludes{"DOMCSSValueInternal.h"} = 1;
   1047     $implIncludes{"DOMEventInternal.h"} = 1;
   1048     $implIncludes{"DOMNodeInternal.h"} = 1;
   1049     $implIncludes{"DOMStyleSheetInternal.h"} = 1;
   1050 
   1051     $implIncludes{"DOMSVGPathSegInternal.h"} = 1 if $interfaceName =~ /^SVGPathSeg.+/;
   1052 
   1053     if ($codeGenerator->IsSVGAnimatedType($interfaceName)) {
   1054         $implIncludes{"SVGAnimatedTemplate.h"} = 1;
   1055     } elsif ($interfaceName =~ /(\w+)(Abs|Rel)$/) {
   1056         $implIncludes{"$1.h"} = 1;
   1057     } else {
   1058         if (!$podType) {
   1059             $implIncludes{"$implClassName.h"} = 1;
   1060         } else {
   1061             $implIncludes{"$podType.h"} = 1 unless $podType eq "float";
   1062         }
   1063     } 
   1064 
   1065     @implContent = ();
   1066 
   1067     push(@implContent, "#import <wtf/GetPtr.h>\n\n");
   1068 
   1069     # add implementation accessor
   1070     if ($podType) {
   1071         push(@implContent, "#define IMPL reinterpret_cast<$podTypeWithNamespace*>(_internal)\n\n");
   1072     } elsif ($parentImplClassName eq "Object") {
   1073         push(@implContent, "#define IMPL reinterpret_cast<$implClassNameWithNamespace*>(_internal)\n\n");
   1074     } else {
   1075         my $baseClassWithNamespace = "WebCore::$baseClass";
   1076         push(@implContent, "#define IMPL static_cast<$implClassNameWithNamespace*>(reinterpret_cast<$baseClassWithNamespace*>(_internal))\n\n");
   1077     }
   1078 
   1079     # START implementation
   1080     push(@implContent, "\@implementation $className\n\n");
   1081 
   1082     # Only generate 'dealloc' and 'finalize' methods for direct subclasses of DOMObject.
   1083     if ($parentImplClassName eq "Object") {
   1084         $implIncludes{"WebCoreObjCExtras.h"} = 1;
   1085         push(@implContent, "- (void)dealloc\n");
   1086         push(@implContent, "{\n");
   1087         push(@implContent, "    if (WebCoreObjCScheduleDeallocateOnMainThread([$className class], self))\n");
   1088         push(@implContent, "        return;\n");
   1089         push(@implContent, "\n");
   1090         if ($interfaceName eq "NodeIterator") {
   1091             push(@implContent, "    if (_internal) {\n");
   1092             push(@implContent, "        [self detach];\n");
   1093             push(@implContent, "        IMPL->deref();\n");
   1094             push(@implContent, "    };\n");
   1095         } elsif ($podType) {
   1096             push(@implContent, "    delete IMPL;\n");
   1097         } else {
   1098             push(@implContent, "    if (_internal)\n");
   1099             push(@implContent, "        IMPL->deref();\n");
   1100         }
   1101         push(@implContent, "    [super dealloc];\n");
   1102         push(@implContent, "}\n\n");
   1103 
   1104         push(@implContent, "- (void)finalize\n");
   1105         push(@implContent, "{\n");
   1106         if ($interfaceName eq "NodeIterator") {
   1107             push(@implContent, "    if (_internal) {\n");
   1108             push(@implContent, "        [self detach];\n");
   1109             push(@implContent, "        IMPL->deref();\n");
   1110             push(@implContent, "    };\n");
   1111         } elsif ($podType) {
   1112             push(@implContent, "    delete IMPL;\n");
   1113         } else {
   1114             push(@implContent, "    if (_internal)\n");
   1115             push(@implContent, "        IMPL->deref();\n");
   1116         }
   1117         push(@implContent, "    [super finalize];\n");
   1118         push(@implContent, "}\n\n");
   1119         
   1120     }
   1121 
   1122     %attributeNames = ();
   1123 
   1124     # - Attributes
   1125     if ($numAttributes > 0) {
   1126         foreach my $attribute (@{$dataNode->attributes}) {
   1127             AddIncludesForType($attribute->signature->type);
   1128 
   1129             my $idlType = $codeGenerator->StripModule($attribute->signature->type);
   1130 
   1131             my $attributeName = $attribute->signature->name;
   1132             my $attributeType = GetObjCType($attribute->signature->type);
   1133             my $attributeIsReadonly = ($attribute->type =~ /^readonly/);
   1134             my $attributeClassName = GetClassName($attribute->signature->type);
   1135 
   1136             my $attributeInterfaceName = $attributeName;
   1137             if ($attributeName eq "id" or $attributeName eq "hash") {
   1138                 # Special case attributes id and hash to be idName and hashName to avoid ObjC naming conflict.
   1139                 $attributeInterfaceName .= "Name";
   1140             } elsif ($attributeName eq "frame") {
   1141                 # Special case attribute frame to be frameBorders.
   1142                 $attributeInterfaceName .= "Borders";
   1143             } elsif ($attributeName eq "ownerDocument") {
   1144                 # FIXME: for now special case attribute ownerDocument to call document, this is incorrect
   1145                 # legacy behavior. (see http://bugs.webkit.org/show_bug.cgi?id=10889)
   1146                 $attributeName = "document";
   1147             } elsif ($codeGenerator->IsSVGAnimatedType($idlType)) {
   1148                 # Special case for animated types.
   1149                 $attributeName .= "Animated";
   1150             }
   1151 
   1152             $attributeNames{$attributeInterfaceName} = 1;
   1153 
   1154             # - GETTER
   1155             my $getterSig = "- ($attributeType)$attributeInterfaceName\n";
   1156 
   1157             # Some SVGFE*Element.idl use 'operator' as attribute name, rewrite as '_operator' to avoid clashes with C/C++
   1158             $attributeName =~ s/operatorAnimated/_operatorAnimated/ if ($attributeName =~ /operatorAnimated/);
   1159             $getterSig =~ s/operator/_operator/ if ($getterSig =~ /operator/);
   1160 
   1161             my $hasGetterException = @{$attribute->getterExceptions};
   1162             my $getterContentHead;
   1163             my $reflect = $attribute->signature->extendedAttributes->{"Reflect"};
   1164             my $reflectURL = $attribute->signature->extendedAttributes->{"ReflectURL"};
   1165             if ($reflect || $reflectURL) {
   1166                 my $contentAttributeName = (($reflect || $reflectURL) eq "1") ? $attributeName : ($reflect || $reflectURL);
   1167                 my $namespace = $codeGenerator->NamespaceForAttributeName($interfaceName, $contentAttributeName);
   1168                 $implIncludes{"${namespace}.h"} = 1;
   1169                 my $getAttributeFunctionName = $reflectURL ? "getURLAttribute" : "getAttribute";
   1170                 $getterContentHead = "IMPL->${getAttributeFunctionName}(WebCore::${namespace}::${contentAttributeName}Attr";
   1171             } else {
   1172                 $getterContentHead = "IMPL->" . $codeGenerator->WK_lcfirst($attributeName) . "(";
   1173             }
   1174             my $getterContentTail = ")";
   1175 
   1176             # Special case for DOMSVGNumber
   1177             if ($podType and $podType eq "float") {
   1178                 $getterContentHead = "*IMPL";
   1179                 $getterContentTail = "";
   1180             }
   1181 
   1182             # TODO: Handle special case for DOMSVGLength
   1183             if ($podType and $podType eq "SVGLength" and $attributeName eq "value") {
   1184                 $getterContentHead = "IMPL->value(0 /* FIXME */";
   1185             }
   1186 
   1187             my $attributeTypeSansPtr = $attributeType;
   1188             $attributeTypeSansPtr =~ s/ \*$//; # Remove trailing " *" from pointer types.
   1189 
   1190             # special case for EventTarget protocol
   1191             $attributeTypeSansPtr = "DOMNode" if $idlType eq "EventTarget";
   1192 
   1193             # Special cases
   1194             my @customGetterContent = (); 
   1195             if ($attributeTypeSansPtr eq "DOMImplementation") {
   1196                 # FIXME: We have to special case DOMImplementation until DOMImplementationFront is removed
   1197                 $getterContentHead = "kit(implementationFront(IMPL";
   1198                 $getterContentTail .= ")";
   1199             } elsif ($attributeName =~ /(\w+)DisplayString$/) {
   1200                 my $attributeToDisplay = $1;
   1201                 $getterContentHead = "WebCore::displayString(IMPL->$attributeToDisplay(), core(self)";
   1202                 $implIncludes{"HitTestResult.h"} = 1;
   1203             } elsif ($attributeName =~ /^absolute(\w+)URL$/) {
   1204                 my $typeOfURL = $1;
   1205                 $getterContentHead = "[self _getURLAttribute:";
   1206                 if ($typeOfURL eq "Link") {
   1207                     $getterContentTail = "\@\"href\"]";
   1208                 } elsif ($typeOfURL eq "Image") {
   1209                     if ($interfaceName eq "HTMLObjectElement") {
   1210                         $getterContentTail = "\@\"data\"]";
   1211                     } else {
   1212                         $getterContentTail = "\@\"src\"]";
   1213                     }
   1214                     unless ($interfaceName eq "HTMLImageElement") {
   1215                         push(@customGetterContent, "    if (!IMPL->renderer() || !IMPL->renderer()->isImage())\n");
   1216                         push(@customGetterContent, "        return nil;\n");
   1217                         $implIncludes{"RenderObject.h"} = 1;
   1218                     }
   1219                 }
   1220                 $implIncludes{"DOMPrivate.h"} = 1;
   1221             } elsif ($attribute->signature->extendedAttributes->{"ConvertToString"}) {
   1222                 $getterContentHead = "WebCore::String::number(" . $getterContentHead;
   1223                 $getterContentTail .= ")";
   1224             } elsif ($attribute->signature->extendedAttributes->{"ConvertFromString"}) {
   1225                 $getterContentTail .= ".toInt()";
   1226             } elsif ($codeGenerator->IsPodType($idlType) or $idlType eq "Date") {
   1227                 $getterContentHead = "kit($getterContentHead";
   1228                 $getterContentTail .= ")";
   1229             } elsif (IsProtocolType($idlType) and $idlType ne "EventTarget") {
   1230                 $getterContentHead = "kit($getterContentHead";
   1231                 $getterContentTail .= ")";
   1232             } elsif ($idlType eq "Color") {
   1233                 $getterContentHead = "WebCore::nsColor($getterContentHead";
   1234                 $getterContentTail .= ")";
   1235             } elsif ($attribute->signature->type eq "SerializedScriptValue") {
   1236                 $getterContentHead = "$getterContentHead";
   1237                 $getterContentTail .= "->toString()";                
   1238             } elsif (ConversionNeeded($attribute->signature->type)) {
   1239                 $getterContentHead = "kit(WTF::getPtr($getterContentHead";
   1240                 $getterContentTail .= "))";
   1241             }
   1242 
   1243             my $getterContent;
   1244             if ($hasGetterException) {
   1245                 $getterContent = $getterContentHead . "ec" . $getterContentTail;
   1246             } else {
   1247                 $getterContent = $getterContentHead . $getterContentTail;
   1248             }
   1249 
   1250             push(@implContent, $getterSig);
   1251             push(@implContent, "{\n");
   1252             push(@implContent, @customGetterContent);
   1253             if ($hasGetterException) {
   1254                 # Differentiated between when the return type is a pointer and
   1255                 # not for white space issue (ie. Foo *result vs. int result).
   1256                 if ($attributeType =~ /\*$/) {
   1257                     $getterContent = $attributeType . "result = " . $getterContent;
   1258                 } else {
   1259                     $getterContent = $attributeType . " result = " . $getterContent;
   1260                 }
   1261 
   1262                 push(@implContent, "    $exceptionInit\n");
   1263                 push(@implContent, "    $getterContent;\n");
   1264                 push(@implContent, "    $exceptionRaiseOnError\n");
   1265                 push(@implContent, "    return result;\n");
   1266             } else {
   1267                 push(@implContent, "    return $getterContent;\n");
   1268             }
   1269             push(@implContent, "}\n\n");
   1270 
   1271             # - SETTER
   1272             if (!$attributeIsReadonly) {
   1273                 # Exception handling
   1274                 my $hasSetterException = @{$attribute->setterExceptions};
   1275 
   1276                 my $coreSetterName = "set" . $codeGenerator->WK_ucfirst($attributeName);
   1277                 my $setterName = "set" . ucfirst($attributeInterfaceName);
   1278                 my $argName = "new" . ucfirst($attributeInterfaceName);
   1279                 my $arg = GetObjCTypeGetter($argName, $idlType);
   1280 
   1281                 # The definition of ConvertFromString and ConvertToString is flipped for the setter
   1282                 if ($attribute->signature->extendedAttributes->{"ConvertFromString"}) {
   1283                     $arg = "WebCore::String::number($arg)";
   1284                 } elsif ($attribute->signature->extendedAttributes->{"ConvertToString"}) {
   1285                     $arg = "WebCore::String($arg).toInt()";
   1286                 }
   1287 
   1288                 my $setterSig = "- (void)$setterName:($attributeType)$argName\n";
   1289 
   1290                 push(@implContent, $setterSig);
   1291                 push(@implContent, "{\n");
   1292 
   1293                 unless ($codeGenerator->IsPrimitiveType($idlType) or $codeGenerator->IsStringType($idlType)) {
   1294                     push(@implContent, "    ASSERT($argName);\n\n");
   1295                 }
   1296 
   1297                 if ($idlType eq "Date") {
   1298                     $arg = "core(" . $arg . ")";
   1299                 }
   1300 
   1301                 if ($podType) {
   1302                     # Special case for DOMSVGNumber
   1303                     if ($podType eq "float") {
   1304                         push(@implContent, "    *IMPL = $arg;\n");
   1305                     } else {
   1306                         push(@implContent, "    IMPL->$coreSetterName($arg);\n");
   1307                     }
   1308                 } else {
   1309                     my $reflect = $attribute->signature->extendedAttributes->{"Reflect"};
   1310                     my $reflectURL = $attribute->signature->extendedAttributes->{"ReflectURL"};
   1311                     push(@implContent, "    $exceptionInit\n") if $hasSetterException;
   1312                     my $ec = $hasSetterException ? ", ec" : "";
   1313                     if ($reflect || $reflectURL) {
   1314                         my $contentAttributeName = (($reflect || $reflectURL) eq "1") ? $attributeName : ($reflect || $reflectURL);
   1315                         my $namespace = $codeGenerator->NamespaceForAttributeName($interfaceName, $contentAttributeName);
   1316                         $implIncludes{"${namespace}.h"} = 1;
   1317                         push(@implContent, "    IMPL->setAttribute(WebCore::${namespace}::${contentAttributeName}Attr, $arg$ec);\n");
   1318                     } else {
   1319                         push(@implContent, "    IMPL->$coreSetterName($arg$ec);\n");
   1320                     }
   1321                     push(@implContent, "    $exceptionRaiseOnError\n") if $hasSetterException;
   1322                 }
   1323 
   1324                 push(@implContent, "}\n\n");
   1325             }
   1326         }
   1327     }
   1328 
   1329     # - Functions
   1330     if ($numFunctions > 0) {
   1331         foreach my $function (@{$dataNode->functions}) {
   1332             AddIncludesForType($function->signature->type);
   1333 
   1334             my $functionName = $function->signature->name;
   1335             my $returnType = GetObjCType($function->signature->type);
   1336             my $hasParameters = @{$function->parameters};
   1337             my $raisesExceptions = @{$function->raisesExceptions};
   1338 
   1339             my @parameterNames = ();
   1340             my @needsAssert = ();
   1341             my %needsCustom = ();
   1342 
   1343             my $parameterIndex = 0;
   1344             my $functionSig = "- ($returnType)$functionName";
   1345             foreach my $param (@{$function->parameters}) {
   1346                 my $paramName = $param->name;
   1347                 my $paramType = GetObjCType($param->type);
   1348 
   1349                 # make a new parameter name if the original conflicts with a property name
   1350                 $paramName = "in" . ucfirst($paramName) if $attributeNames{$paramName};
   1351 
   1352                 AddIncludesForType($param->type);
   1353 
   1354                 my $idlType = $codeGenerator->StripModule($param->type);
   1355                 my $implGetter = GetObjCTypeGetter($paramName, $idlType);
   1356 
   1357                 push(@parameterNames, $implGetter);
   1358                 $needsCustom{"XPathNSResolver"} = $paramName if $idlType eq "XPathNSResolver";
   1359                 $needsCustom{"NodeFilter"} = $paramName if $idlType eq "NodeFilter";
   1360                 $needsCustom{"EventListener"} = $paramName if $idlType eq "EventListener";
   1361                 $needsCustom{"EventTarget"} = $paramName if $idlType eq "EventTarget";
   1362                 $needsCustom{"NodeToReturn"} = $paramName if $param->extendedAttributes->{"Return"};
   1363 
   1364                 unless ($codeGenerator->IsPrimitiveType($idlType) or $codeGenerator->IsStringType($idlType)) {
   1365                     push(@needsAssert, "    ASSERT($paramName);\n");
   1366                 }
   1367 
   1368                 if ($parameterIndex >= 1) {
   1369                     my $paramPrefix = $param->extendedAttributes->{"ObjCPrefix"};
   1370                     $paramPrefix = $param->name unless defined($paramPrefix);
   1371                     $functionSig .= " $paramPrefix";
   1372                 }
   1373 
   1374                 $functionSig .= ":($paramType)$paramName";
   1375 
   1376                 $parameterIndex++;
   1377             }
   1378 
   1379             my @functionContent = ();
   1380             my $caller = "IMPL";
   1381 
   1382             # special case the XPathNSResolver
   1383             if (defined $needsCustom{"XPathNSResolver"}) {
   1384                 my $paramName = $needsCustom{"XPathNSResolver"};
   1385                 push(@functionContent, "    WebCore::XPathNSResolver* nativeResolver = 0;\n");
   1386                 push(@functionContent, "    RefPtr<WebCore::XPathNSResolver> customResolver;\n");
   1387                 push(@functionContent, "    if ($paramName) {\n");
   1388                 push(@functionContent, "        if ([$paramName isMemberOfClass:[DOMNativeXPathNSResolver class]])\n");
   1389                 push(@functionContent, "            nativeResolver = core(static_cast<DOMNativeXPathNSResolver *>($paramName));\n");
   1390                 push(@functionContent, "        else {\n");
   1391                 push(@functionContent, "            customResolver = WebCore::DOMCustomXPathNSResolver::create($paramName);\n");
   1392                 push(@functionContent, "            nativeResolver = WTF::getPtr(customResolver);\n");
   1393                 push(@functionContent, "        }\n");
   1394                 push(@functionContent, "    }\n");
   1395             }
   1396 
   1397             # special case the EventTarget
   1398             if (defined $needsCustom{"EventTarget"}) {
   1399                 my $paramName = $needsCustom{"EventTarget"};
   1400                 push(@functionContent, "    DOMNode* ${paramName}ObjC = $paramName;\n");
   1401                 push(@functionContent, "    WebCore::Node* ${paramName}Node = core(${paramName}ObjC);\n");
   1402                 $implIncludes{"DOMNode.h"} = 1;
   1403                 $implIncludes{"Node.h"} = 1;
   1404             }
   1405 
   1406             if ($function->signature->extendedAttributes->{"UsesView"}) {
   1407                 push(@functionContent, "    WebCore::DOMWindow* dv = $caller->defaultView();\n");
   1408                 push(@functionContent, "    if (!dv)\n");
   1409                 push(@functionContent, "        return nil;\n");
   1410                 $implIncludes{"DOMWindow.h"} = 1;
   1411                 $caller = "dv";
   1412             }
   1413 
   1414             # special case the EventListener
   1415             if (defined $needsCustom{"EventListener"}) {
   1416                 my $paramName = $needsCustom{"EventListener"};
   1417                 push(@functionContent, "    RefPtr<WebCore::EventListener> nativeEventListener = WebCore::ObjCEventListener::wrap($paramName);\n");
   1418             }
   1419 
   1420             # special case the NodeFilter
   1421             if (defined $needsCustom{"NodeFilter"}) {
   1422                 my $paramName = $needsCustom{"NodeFilter"};
   1423                 push(@functionContent, "    RefPtr<WebCore::NodeFilter> nativeNodeFilter;\n");
   1424                 push(@functionContent, "    if ($paramName)\n");
   1425                 push(@functionContent, "        nativeNodeFilter = WebCore::NodeFilter::create(WebCore::ObjCNodeFilterCondition::create($paramName));\n");
   1426             }
   1427 
   1428             # FIXME! We need [Custom] support for ObjC, to move these hacks into DOMSVGLength/MatrixCustom.mm
   1429             my $svgMatrixRotateFromVector = ($podType and $podType eq "AffineTransform" and $functionName eq "rotateFromVector");
   1430             my $svgMatrixInverse = ($podType and $podType eq "AffineTransform" and $functionName eq "inverse");
   1431             my $svgLengthConvertToSpecifiedUnits = ($podType and $podType eq "SVGLength" and $functionName eq "convertToSpecifiedUnits");
   1432 
   1433             push(@parameterNames, "ec") if $raisesExceptions and !($svgMatrixRotateFromVector || $svgMatrixInverse);
   1434             my $content = $caller . "->" . $codeGenerator->WK_lcfirst($functionName) . "(" . join(", ", @parameterNames) . ")"; 
   1435 
   1436             if ($svgMatrixRotateFromVector) {
   1437                 # Special case with rotateFromVector & SVGMatrix        
   1438                 push(@functionContent, "    $exceptionInit\n");
   1439                 push(@functionContent, "    if (x == 0.0 || y == 0.0)\n");
   1440                 push(@functionContent, "        ec = WebCore::SVGException::SVG_INVALID_VALUE_ERR;\n");
   1441                 push(@functionContent, "    $exceptionRaiseOnError\n");
   1442                 push(@functionContent, "    return kit($content);\n");
   1443             } elsif ($svgMatrixInverse) {
   1444                 # Special case with inverse & SVGMatrix
   1445                 push(@functionContent, "    $exceptionInit\n");
   1446                 push(@functionContent, "    if (!$caller->isInvertible())\n");
   1447                 push(@functionContent, "        ec = WebCore::SVGException::SVG_MATRIX_NOT_INVERTABLE;\n");
   1448                 push(@functionContent, "    $exceptionRaiseOnError\n");
   1449                 push(@functionContent, "    return kit($content);\n");
   1450             } elsif ($svgLengthConvertToSpecifiedUnits) {
   1451                 push(@functionContent, "    IMPL->convertToSpecifiedUnits(inUnitType, 0 /* FIXME */);\n");
   1452             } elsif ($returnType eq "void") {
   1453                 # Special case 'void' return type.
   1454                 if ($raisesExceptions) {
   1455                     push(@functionContent, "    $exceptionInit\n");
   1456                     push(@functionContent, "    $content;\n");
   1457                     push(@functionContent, "    $exceptionRaiseOnError\n");
   1458                 } else {
   1459                     push(@functionContent, "    $content;\n");
   1460                 }
   1461             } elsif (defined $needsCustom{"NodeToReturn"}) {
   1462                 # Special case the insertBefore, replaceChild, removeChild 
   1463                 # and appendChild functions from DOMNode 
   1464                 my $toReturn = $needsCustom{"NodeToReturn"};
   1465                 if ($raisesExceptions) {
   1466                     push(@functionContent, "    $exceptionInit\n");
   1467                     push(@functionContent, "    if ($content)\n");
   1468                     push(@functionContent, "        return $toReturn;\n");
   1469                     push(@functionContent, "    $exceptionRaiseOnError\n");
   1470                     push(@functionContent, "    return nil;\n");
   1471                 } else {
   1472                     push(@functionContent, "    if ($content)\n");
   1473                     push(@functionContent, "        return $toReturn;\n");
   1474                     push(@functionContent, "    return nil;\n");
   1475                 }
   1476             } elsif ($returnType eq "SerializedScriptValue") {
   1477                 $content = "foo";
   1478             } else {
   1479                 if (ConversionNeeded($function->signature->type)) {
   1480                     if ($codeGenerator->IsPodType($function->signature->type)) {
   1481                         $content = "kit($content)";
   1482                     } else {
   1483                         $content = "kit(WTF::getPtr($content))";
   1484                     }
   1485                 }
   1486 
   1487                 if ($raisesExceptions) {
   1488                     # Differentiated between when the return type is a pointer and
   1489                     # not for white space issue (ie. Foo *result vs. int result).
   1490                     if ($returnType =~ /\*$/) {
   1491                         $content = $returnType . "result = " . $content;
   1492                     } else {
   1493                         $content = $returnType . " result = " . $content;
   1494                     }
   1495 
   1496                     push(@functionContent, "    $exceptionInit\n");
   1497                     push(@functionContent, "    $content;\n");
   1498                     push(@functionContent, "    $exceptionRaiseOnError\n");
   1499                     push(@functionContent, "    return result;\n");
   1500                 } else {
   1501                     push(@functionContent, "    return $content;\n");
   1502                 }
   1503             }
   1504 
   1505             push(@implContent, "$functionSig\n");
   1506             push(@implContent, "{\n");
   1507             push(@implContent, @functionContent);
   1508             push(@implContent, "}\n\n");
   1509 
   1510             # generate the old style method names with un-named parameters, these methods are deprecated
   1511             if (@{$function->parameters} > 1 and $function->signature->extendedAttributes->{"OldStyleObjC"}) {
   1512                 my $deprecatedFunctionSig = $functionSig;
   1513                 $deprecatedFunctionSig =~ s/\s\w+:/ :/g; # remove parameter names
   1514 
   1515                 push(@implContent, "$deprecatedFunctionSig\n");
   1516                 push(@implContent, "{\n");
   1517                 push(@implContent, @functionContent);
   1518                 push(@implContent, "}\n\n");
   1519             }
   1520 
   1521             # Clear the hash
   1522             %needsCustom = ();
   1523         }
   1524     }
   1525 
   1526     # END implementation
   1527     push(@implContent, "\@end\n");
   1528 
   1529     # Generate internal interfaces
   1530     if ($podType) {
   1531         my $prefixedPodType = $podType eq "float" ? $podType : "WebCore::$podType";
   1532         push(@implContent, "\n$prefixedPodType core($className *wrapper)\n");
   1533         push(@implContent, "{\n");
   1534         push(@implContent, "    return wrapper ? *reinterpret_cast<$prefixedPodType*>(wrapper->_internal) : $prefixedPodType();\n");
   1535         push(@implContent, "}\n\n");
   1536     } else {
   1537         push(@implContent, "\nWebCore::$implClassName* core($className *wrapper)\n");
   1538         push(@implContent, "{\n");
   1539         push(@implContent, "    return wrapper ? reinterpret_cast<WebCore::$implClassName*>(wrapper->_internal) : 0;\n");
   1540         push(@implContent, "}\n\n");
   1541     }
   1542 
   1543     if ($podType) {
   1544         # FIXME: Implement caching.
   1545         my $prefixedPodType = $podType eq "float" ? $podType : "WebCore::$podType";
   1546         push(@implContent, "$className *kit($prefixedPodType value)\n");
   1547         push(@implContent, "{\n");
   1548         push(@implContent, "    $assertMainThread;\n");
   1549         push(@implContent, "    $className *wrapper = [[$className alloc] _init];\n");
   1550         push(@implContent, "    wrapper->_internal = reinterpret_cast<DOMObjectInternal*>(new $prefixedPodType(value));\n");
   1551         push(@implContent, "    return [wrapper autorelease];\n");
   1552         push(@implContent, "}\n");
   1553     } elsif ($parentImplClassName eq "Object") {        
   1554         push(@implContent, "$className *kit(WebCore::$implClassName* value)\n");
   1555         push(@implContent, "{\n");
   1556         push(@implContent, "    $assertMainThread;\n");
   1557         push(@implContent, "    if (!value)\n");
   1558         push(@implContent, "        return nil;\n");
   1559         push(@implContent, "    if ($className *wrapper = getDOMWrapper(value))\n");
   1560         push(@implContent, "        return [[wrapper retain] autorelease];\n");
   1561         if ($dataNode->extendedAttributes->{Polymorphic}) {
   1562             push(@implContent, "    $className *wrapper = [[kitClass(value) alloc] _init];\n");
   1563             push(@implContent, "    if (!wrapper)\n");
   1564             push(@implContent, "        return nil;\n");
   1565         } else {
   1566             push(@implContent, "    $className *wrapper = [[$className alloc] _init];\n");
   1567         }
   1568         push(@implContent, "    wrapper->_internal = reinterpret_cast<DOMObjectInternal*>(value);\n");
   1569         push(@implContent, "    value->ref();\n");
   1570         push(@implContent, "    addDOMWrapper(wrapper, value);\n");
   1571         push(@implContent, "    return [wrapper autorelease];\n");
   1572         push(@implContent, "}\n");
   1573     } else {
   1574         push(@implContent, "$className *kit(WebCore::$implClassName* value)\n");
   1575         push(@implContent, "{\n");
   1576         push(@implContent, "    $assertMainThread;\n");
   1577         push(@implContent, "    return static_cast<$className*>(kit(static_cast<WebCore::$baseClass*>(value)));\n");
   1578         push(@implContent, "}\n");
   1579     }
   1580 
   1581     # - End the ifdef conditional if necessary
   1582     push(@implContent, "\n#endif // ${conditionalString}\n") if $conditional;
   1583 
   1584     # - Generate dependencies.
   1585     if ($writeDependencies && @ancestorInterfaceNames) {
   1586         push(@depsContent, "$className.h : ", join(" ", map { "$_.idl" } @ancestorInterfaceNames), "\n");
   1587         push(@depsContent, map { "$_.idl :\n" } @ancestorInterfaceNames); 
   1588     }
   1589 }
   1590 
   1591 # Internal helper
   1592 sub WriteData
   1593 {
   1594     my $object = shift;
   1595     my $name = shift;
   1596 
   1597     # Open files for writing...
   1598     my $headerFileName = "$outputDir/" . $name . ".h";
   1599     my $privateHeaderFileName = "$outputDir/" . $name . "Private.h";
   1600     my $implFileName = "$outputDir/" . $name . ".mm";
   1601     my $internalHeaderFileName = "$outputDir/" . $name . "Internal.h";
   1602     my $depsFileName = "$outputDir/" . $name . ".dep";
   1603 
   1604     # Remove old files.
   1605     unlink($headerFileName);
   1606     unlink($privateHeaderFileName);
   1607     unlink($implFileName);
   1608     unlink($internalHeaderFileName);
   1609     unlink($depsFileName);
   1610 
   1611     # Write public header.
   1612     open(HEADER, ">$headerFileName") or die "Couldn't open file $headerFileName";
   1613     
   1614     print HEADER @headerContentHeader;
   1615     print HEADER map { "\@class $_;\n" } sort keys(%headerForwardDeclarations);
   1616     print HEADER map { "\@protocol $_;\n" } sort keys(%headerForwardDeclarationsForProtocols);
   1617 
   1618     my $hasForwardDeclarations = keys(%headerForwardDeclarations) + keys(%headerForwardDeclarationsForProtocols);
   1619     print HEADER "\n" if $hasForwardDeclarations;
   1620     print HEADER @headerContent;
   1621 
   1622     close(HEADER);
   1623 
   1624     @headerContentHeader = ();
   1625     @headerContent = ();
   1626     %headerForwardDeclarations = ();
   1627     %headerForwardDeclarationsForProtocols = ();
   1628 
   1629     if (@privateHeaderContent > 0) {
   1630         open(PRIVATE_HEADER, ">$privateHeaderFileName") or die "Couldn't open file $privateHeaderFileName";
   1631 
   1632         print PRIVATE_HEADER @privateHeaderContentHeader;
   1633         print PRIVATE_HEADER map { "\@class $_;\n" } sort keys(%privateHeaderForwardDeclarations);
   1634         print PRIVATE_HEADER map { "\@protocol $_;\n" } sort keys(%privateHeaderForwardDeclarationsForProtocols);
   1635 
   1636         $hasForwardDeclarations = keys(%privateHeaderForwardDeclarations) + keys(%privateHeaderForwardDeclarationsForProtocols);
   1637         print PRIVATE_HEADER "\n" if $hasForwardDeclarations;
   1638         print PRIVATE_HEADER @privateHeaderContent;
   1639 
   1640         close(PRIVATE_HEADER);
   1641 
   1642         @privateHeaderContentHeader = ();
   1643         @privateHeaderContent = ();
   1644         %privateHeaderForwardDeclarations = ();
   1645         %privateHeaderForwardDeclarationsForProtocols = ();
   1646     }
   1647 
   1648     # Write implementation file.
   1649     unless ($noImpl) {
   1650         open(IMPL, ">$implFileName") or die "Couldn't open file $implFileName";
   1651 
   1652         print IMPL @implContentHeader;
   1653         print IMPL map { "#import \"$_\"\n" } sort keys(%implIncludes);
   1654         print IMPL @implContent;
   1655 
   1656         close(IMPL);
   1657 
   1658         @implContentHeader = ();
   1659         @implContent = ();
   1660         %implIncludes = ();
   1661     }
   1662     
   1663     if (@internalHeaderContent > 0) {
   1664        open(INTERNAL_HEADER, ">$internalHeaderFileName") or die "Couldn't open file $internalHeaderFileName";
   1665 
   1666        print INTERNAL_HEADER @internalHeaderContent;
   1667 
   1668        close(INTERNAL_HEADER);
   1669 
   1670        @internalHeaderContent = ();
   1671     }
   1672 
   1673     # Write dependency file.
   1674     if (@depsContent) {
   1675         open(DEPS, ">$depsFileName") or die "Couldn't open file $depsFileName";
   1676         print DEPS @depsContent;
   1677         close(DEPS);
   1678         @depsContent = ();
   1679     }
   1680 }
   1681 
   1682 1;
   1683