PageRenderTime 157ms CodeModel.GetById 12ms app.highlight 133ms RepoModel.GetById 1ms app.codeStats 1ms

/platform/external/webkit/WebCore/bindings/scripts/CodeGeneratorObjC.pm

https://github.com/aharish/totoro-gb-opensource-update2
Perl | 1682 lines | 1283 code | 277 blank | 122 comment | 269 complexity | f82566f35999c88a5338f2124ece5f34 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   1# 
   2# Copyright (C) 2005, 2006 Nikolas Zimmermann <zimmermann@kde.org>
   3# Copyright (C) 2006 Anders Carlsson <andersca@mac.com> 
   4# Copyright (C) 2006, 2007 Samuel Weinig <sam@webkit.org>
   5# Copyright (C) 2006 Alexey Proskuryakov <ap@webkit.org>
   6# Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
   7# Copyright (C) 2009 Cameron McCormack <cam@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
  25package CodeGeneratorObjC;
  26
  27use File::stat;
  28
  29# Global Variables
  30my $module = "";
  31my $outputDir = "";
  32my $writeDependencies = 0;
  33my %publicInterfaces = ();
  34my $newPublicClass = 0;
  35my $interfaceAvailabilityVersion = "";
  36my $isProtocol = 0;
  37my $noImpl = 0;
  38
  39my @headerContentHeader = ();
  40my @headerContent = ();
  41my %headerForwardDeclarations = ();
  42my %headerForwardDeclarationsForProtocols = ();
  43
  44my @privateHeaderContentHeader = ();
  45my @privateHeaderContent = ();
  46my %privateHeaderForwardDeclarations = ();
  47my %privateHeaderForwardDeclarationsForProtocols = ();
  48
  49my @internalHeaderContent = ();
  50
  51my @implContentHeader = ();
  52my @implContent = ();
  53my %implIncludes = ();
  54my @depsContent = ();
  55
  56# Hashes
  57my %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);
  62my %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.
  66my %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
  80my $buildingForTigerOrEarlier = 1 if $ENV{"MACOSX_DEPLOYMENT_TARGET"} and $ENV{"MACOSX_DEPLOYMENT_TARGET"} <= 10.4;
  81my $buildingForLeopardOrLater = 1 if $ENV{"MACOSX_DEPLOYMENT_TARGET"} and $ENV{"MACOSX_DEPLOYMENT_TARGET"} >= 10.5;
  82my $exceptionInit = "WebCore::ExceptionCode ec = 0;";
  83my $exceptionRaiseOnError = "WebCore::raiseOnDOMError(ec);";
  84my $assertMainThread = "{ DOM_ASSERT_MAIN_THREAD(); WebCoreThreadViolationCheckRoundOne(); }";
  85
  86my %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
 133my $fatalError = 0;
 134
 135# Default License Templates
 136my $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 */
 162EOF
 163
 164my $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 */
 190EOF
 191
 192# Default constructor
 193sub 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
 208sub finish
 209{
 210    my $object = shift;
 211}
 212
 213sub 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
 267sub 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
 301sub GenerateModule
 302{
 303    my $object = shift;
 304    my $dataNode = shift;
 305
 306    $module = $dataNode->module;
 307}
 308
 309sub 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
 328sub GetClassHeaderName
 329{
 330    my $name = shift;
 331
 332    return "DOMDOMImplementation" if $name eq "DOMImplementation";
 333    return $name;
 334}
 335
 336sub 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
 345sub 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
 359sub 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
 410sub 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
 420sub IsBaseType
 421{
 422    my $type = shift;
 423
 424    return 1 if $baseTypeHash{$type};
 425    return 0;
 426}
 427
 428sub IsProtocolType
 429{
 430    my $type = shift;
 431
 432    return 1 if $protocolTypeHash{$type};
 433    return 0;
 434}
 435
 436sub IsNativeObjCType
 437{
 438    my $type = shift;
 439
 440    return 1 if $nativeObjCTypeHash{$type};
 441    return 0;
 442}
 443
 444sub 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
 455sub 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
 477sub ConversionNeeded
 478{
 479    my $type = $codeGenerator->StripModule(shift);
 480
 481    return !$codeGenerator->IsNonPointerType($type) && !$codeGenerator->IsStringType($type) && !IsNativeObjCType($type);
 482}
 483
 484sub 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
 504sub 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
 526sub 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
 630sub 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
 993sub 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

Large files files are truncated, but you can click here to view the full file