📄 codegeneratorobjc.pm
字号:
push(@headerContent, "\n") if $buildingForLeopardOrLater and @headerAttributes > 0; push(@headerContent, @headerFunctions); } } if (@deprecatedHeaderFunctions > 0 && $isProtocol) { push(@headerContent, @deprecatedHeaderFunctions); } # - End @interface or @protocol push(@headerContent, "\@end\n"); if (@deprecatedHeaderFunctions > 0 && !$isProtocol) { # - Deprecated category @interface push(@headerContent, "\n\@interface $className (" . $className . "Deprecated)\n"); push(@headerContent, @deprecatedHeaderFunctions); push(@headerContent, "\@end\n"); } push(@headerContent, "\n#endif\n") if length $interfaceAvailabilityVersion; my %alwaysGenerateForNoSVGBuild = map { $_ => 1 } qw(DOMHTMLEmbedElement DOMHTMLObjectElement); if (@privateHeaderAttributes > 0 or @privateHeaderFunctions > 0 or exists $alwaysGenerateForNoSVGBuild{$className}) { # - Private category @interface @privateHeaderContentHeader = split("\r", $headerLicenceTemplate); push(@privateHeaderContentHeader, "\n"); my $classHeaderName = GetClassHeaderName($className); push(@privateHeaderContentHeader, "#import <WebCore/$classHeaderName.h>\n\n"); push(@privateHeaderContentHeader, $interfaceAvailabilityVersionCheck) if length $interfaceAvailabilityVersion; @privateHeaderContent = (); push(@privateHeaderContent, "\@interface $className (" . $className . "Private)\n"); push(@privateHeaderContent, @privateHeaderAttributes) if @privateHeaderAttributes > 0; push(@privateHeaderContent, "\n") if $buildingForLeopardOrLater and @privateHeaderAttributes > 0 and @privateHeaderFunctions > 0; push(@privateHeaderContent, @privateHeaderFunctions) if @privateHeaderFunctions > 0; push(@privateHeaderContent, "\@end\n"); push(@privateHeaderContent, "\n#endif\n") if length $interfaceAvailabilityVersion; } unless ($isProtocol) { # Generate internal interfaces my $podType = $dataNode->extendedAttributes->{"PODType"}; my $typeGetterSig = GetInternalTypeGetterSignature($interfaceName, $podType); my ($typeMakerSig, $typeMakerSigAddition, $ivarsToInit) = GetInternalTypeMakerSignature($interfaceName, $podType); # Generate interface definitions. @internalHeaderContent = split("\r", $implementationLicenceTemplate); push(@internalHeaderContent, "\n#import <WebCore/$className.h>\n\n"); push(@internalHeaderContent, $interfaceAvailabilityVersionCheck) if length $interfaceAvailabilityVersion; if ($interfaceName eq "Node" or $interfaceName eq "SVGElementInstance") { push(@internalHeaderContent, "\@protocol DOMEventTarget;\n\n"); } if ($codeGenerator->IsSVGAnimatedType($interfaceName)) { push(@internalHeaderContent, "#import <WebCore/SVGAnimatedTemplate.h>\n\n"); } elsif ($interfaceName eq "RGBColor") { push(@internalHeaderContent, "#import <WebCore/Color.h>\n\n"); } else { if ($podType and $podType ne "float") { push(@internalHeaderContent, "namespace WebCore { class $podType; }\n\n"); } elsif ($interfaceName eq "Node") { push(@internalHeaderContent, "namespace WebCore { class Node; class EventTarget; }\n\n"); } elsif ($interfaceName eq "SVGElementInstance") { push(@internalHeaderContent, "namespace WebCore { class SVGElementInstance; class EventTarget; }\n\n"); } else { my $implClassName = GetImplClassName($interfaceName); push(@internalHeaderContent, "namespace WebCore { class $implClassName; }\n\n"); } } push(@internalHeaderContent, "\@interface $className (WebCoreInternal)\n"); push(@internalHeaderContent, $typeGetterSig . ";\n"); push(@internalHeaderContent, $typeMakerSig . ";\n"); if ($interfaceName eq "Node" or $interfaceName eq "SVGElementInstance") { push(@internalHeaderContent, "+ (id <DOMEventTarget>)_wrapEventTarget:(WebCore::EventTarget *)eventTarget;\n"); } push(@internalHeaderContent, "\@end\n"); push(@internalHeaderContent, "\n#endif\n") if length $interfaceAvailabilityVersion; }}sub GenerateImplementation{ my $object = shift; my $dataNode = shift; if (@{$dataNode->parents} > 1) { $codeGenerator->AddMethodsConstantsAndAttributesFromParentClasses($dataNode); } my $interfaceName = $dataNode->name; my $className = GetClassName($interfaceName); my $implClassName = GetImplClassName($interfaceName); my $parentImplClassName = GetParentImplClassName($dataNode); my $implClassNameWithNamespace = "WebCore::" . $implClassName; my $baseClass = GetBaseClass($parentImplClassName); my $classHeaderName = GetClassHeaderName($className); my $conditional = $dataNode->extendedAttributes->{"Conditional"}; my $numAttributes = @{$dataNode->attributes}; my $numFunctions = @{$dataNode->functions}; my $podType = $dataNode->extendedAttributes->{"PODType"}; my $podTypeWithNamespace; if ($podType) { $podTypeWithNamespace = ($podType eq "float") ? "$podType" : "WebCore::$podType"; } # - Add default header template. @implContentHeader = split("\r", $implementationLicenceTemplate); # - INCLUDES - push(@implContentHeader, "\n#import \"config.h\"\n"); my $conditionalString; if ($conditional) { $conditionalString = "ENABLE(" . join(") && ENABLE(", split(/&/, $conditional)) . ")"; push(@implContentHeader, "\n#if ${conditionalString}\n"); } push(@implContentHeader, "\n#import \"$classHeaderName.h\"\n\n"); push(@implContentHeader, "#import \"ThreadCheck.h\"\n"); push(@implContentHeader, "#import <wtf/GetPtr.h>\n\n"); if ($codeGenerator->IsSVGAnimatedType($interfaceName)) { $implIncludes{"SVGAnimatedTemplate.h"} = 1; } elsif ($interfaceName =~ /(\w+)(Abs|Rel)$/) { $implIncludes{"$1.h"} = 1; } else { if (!$podType) { $implIncludes{"$implClassName.h"} = 1; } else { $implIncludes{"$podType.h"} = 1 unless $podType eq "float"; } } $implIncludes{"DOMInternal.h"} = 1; $implIncludes{"ExceptionHandlers.h"} = 1; @implContent = (); # add implementation accessor if ($podType) { push(@implContent, "#define IMPL reinterpret_cast<$podTypeWithNamespace*>(_internal)\n\n"); } elsif ($parentImplClassName eq "Object") { push(@implContent, "#define IMPL reinterpret_cast<$implClassNameWithNamespace*>(_internal)\n\n"); } else { my $baseClassWithNamespace = "WebCore::$baseClass"; push(@implContent, "#define IMPL static_cast<$implClassNameWithNamespace*>(reinterpret_cast<$baseClassWithNamespace*>(_internal))\n\n"); } # START implementation push(@implContent, "\@implementation $className\n\n"); # Only generate 'dealloc' and 'finalize' methods for direct subclasses of DOMObject. if ($parentImplClassName eq "Object") { my @ivarsToRelease = (); if (@ivars > 0) { foreach $attribute (@ivars) { my $name = "m_" . $attribute->signature->name; push(@ivarsToRelease, " [$name release];\n"); } } push(@implContent, "- (void)dealloc\n"); push(@implContent, "{\n"); push(@implContent, " $assertMainThread\n"); push(@implContent, @ivarsToRelease); if ($interfaceName eq "NodeIterator") { push(@implContent, " if (_internal) {\n"); push(@implContent, " [self detach];\n"); push(@implContent, " IMPL->deref();\n"); push(@implContent, " };\n"); } elsif ($podType) { push(@implContent, " delete IMPL;\n"); } else { push(@implContent, " if (_internal)\n"); push(@implContent, " IMPL->deref();\n"); } push(@implContent, " [super dealloc];\n"); push(@implContent, "}\n\n"); push(@implContent, "- (void)finalize\n"); push(@implContent, "{\n"); if ($interfaceName eq "NodeIterator") { push(@implContent, " if (_internal) {\n"); push(@implContent, " [self detach];\n"); push(@implContent, " IMPL->deref();\n"); push(@implContent, " };\n"); } elsif ($podType) { push(@implContent, " delete IMPL;\n"); } else { push(@implContent, " if (_internal)\n"); push(@implContent, " IMPL->deref();\n"); } push(@implContent, " [super finalize];\n"); push(@implContent, "}\n\n"); } %attributeNames = (); # - Attributes if ($numAttributes > 0) { foreach my $attribute (@{$dataNode->attributes}) { AddIncludesForType($attribute->signature->type); my $idlType = $codeGenerator->StripModule($attribute->signature->type); my $attributeName = $attribute->signature->name; my $attributeType = GetObjCType($attribute->signature->type); my $attributeIsReadonly = ($attribute->type =~ /^readonly/); my $attributeClassName = GetClassName($attribute->signature->type); my $attributeInterfaceName = $attributeName; if ($attributeName eq "id" or $attributeName eq "hash") { # Special case attributes id and hash to be idName and hashName to avoid ObjC naming conflict. $attributeInterfaceName .= "Name"; } elsif ($attributeName eq "frame") { # Special case attribute frame to be frameBorders. $attributeInterfaceName .= "Borders"; } elsif ($attributeName eq "ownerDocument") { # FIXME: for now special case attribute ownerDocument to call document, this is incorrect # legacy behavior. (see http://bugs.webkit.org/show_bug.cgi?id=10889) $attributeName = "document"; } elsif ($codeGenerator->IsSVGAnimatedType($idlType)) { # Special case for animated types. $attributeName .= "Animated"; } $attributeNames{$attributeInterfaceName} = 1; # - GETTER my $getterSig = "- ($attributeType)$attributeInterfaceName\n"; my $hasGetterException = @{$attribute->getterExceptions}; my $getterContentHead = "IMPL->" . $codeGenerator->WK_lcfirst($attributeName) . "("; my $getterContentTail = ")"; # Special case for DOMSVGNumber if ($podType and $podType eq "float") { $getterContentHead = "*IMPL"; $getterContentTail = ""; } # TODO: Handle special case for DOMSVGLength if ($podType and $podType eq "SVGLength" and $attributeName eq "value") { $getterContentHead = "IMPL->value(0 /* FIXME */"; } my $attributeTypeSansPtr = $attributeType; $attributeTypeSansPtr =~ s/ \*$//; # Remove trailing " *" from pointer types. # special case for EventTarget protocol $attributeTypeSansPtr = "DOMNode" if $idlType eq "EventTarget"; my $typeMaker = GetObjCTypeMaker($attribute->signature->type); # Special cases my @customGetterContent = (); if ($attributeTypeSansPtr eq "DOMImplementation") { # FIXME: We have to special case DOMImplementation until DOMImplementationFront is removed $getterContentHead = "[$attributeTypeSansPtr $typeMaker:implementationFront(IMPL"; $getterContentTail .= "]"; } elsif ($attributeName =~ /(\w+)DisplayString$/) { my $attributeToDisplay = $1; $getterContentHead = "WebCore::displayString(IMPL->$attributeToDisplay(), [self _element]"; } elsif ($attributeName =~ /^absolute(\w+)URL$/) { my $typeOfURL = $1; $getterContentHead = "[self _getURLAttribute:"; if ($typeOfURL eq "Link") { $getterContentTail = "\@\"href\"]"; } elsif ($typeOfURL eq "Image") { if ($interfaceName eq "HTMLObjectElement") { $getterContentTail = "\@\"data\"]"; } else { $getterContentTail = "\@\"src\"]"; } unless ($interfaceName eq "HTMLImageElement") { push(@customGetterContent, " if (!IMPL->renderer() || !IMPL->renderer()->isImage())\n"); push(@customGetterContent, " return nil;\n"); $implIncludes{"RenderObject.h"} = 1; } } $implIncludes{"DOMPrivate.h"} = 1; } elsif ($attribute->signature->extendedAttributes->{"ConvertToString"}) { $getterContentHead = "WebCore::String::number(" . $getterContentHead; $getterContentTail .= ")"; } elsif ($attribute->signature->extendedAttributes->{"ConvertFromString"}) { $getterContentTail .= ".toInt()"; } elsif ($codeGenerator->IsPodType($idlType)) { $getterContentHead = "[$attributeTypeSansPtr $typeMaker:" . $getterContentHead; $getterContentTail .= "]"; } elsif (IsProtocolType($idlType) and $idlType ne "EventTarget") { $getterContentHead = "[$attributeClassName $typeMaker:WTF::getPtr(" . $getterContentHead; $getterContentTail .= ")]"; } elsif ($typeMaker ne "") { # Surround getter with TypeMaker $getterContentHead = "[$attributeTypeSansPtr $typeMaker:WTF::getPtr(" . $getterContentHead; $getterContentTail .= ")]"; } my $getterContent; if ($hasGetterException) { $getterContent = $getterContentHead . "ec" . $getterContentTail; } else { $getterContent = $getterContentHead . $getterContentTail; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -