📄 codegeneratorobjc.pm
字号:
push(@implContent, $getterSig); push(@implContent, "{\n"); push(@implContent, @customGetterContent); if ($hasGetterException) { # Differentiated between when the return type is a pointer and # not for white space issue (ie. Foo *result vs. int result). if ($attributeType =~ /\*$/) { $getterContent = $attributeType . "result = " . $getterContent; } else { $getterContent = $attributeType . " result = " . $getterContent; } push(@implContent, " $exceptionInit\n"); push(@implContent, " $getterContent;\n"); push(@implContent, " $exceptionRaiseOnError\n"); push(@implContent, " return result;\n"); } else { push(@implContent, " return $getterContent;\n"); } push(@implContent, "}\n\n"); # - SETTER if (!$attributeIsReadonly) { # Exception handling my $hasSetterException = @{$attribute->setterExceptions}; $attributeName = "set" . $codeGenerator->WK_ucfirst($attributeName); my $setterName = "set" . ucfirst($attributeInterfaceName); my $argName = "new" . ucfirst($attributeInterfaceName); my $arg = GetObjCTypeGetter($argName, $idlType); # The definition of ConvertFromString and ConvertToString is flipped for the setter if ($attribute->signature->extendedAttributes->{"ConvertFromString"}) { $arg = "WebCore::String::number($arg)"; } elsif ($attribute->signature->extendedAttributes->{"ConvertToString"}) { $arg = "WebCore::String($arg).toInt()"; } my $setterSig = "- (void)$setterName:($attributeType)$argName\n"; push(@implContent, $setterSig); push(@implContent, "{\n"); unless ($codeGenerator->IsPrimitiveType($idlType) or $codeGenerator->IsStringType($idlType)) { push(@implContent, " ASSERT($argName);\n\n"); } if ($podType) { # Special case for DOMSVGNumber if ($podType eq "float") { push(@implContent, " *IMPL = $arg;\n"); } else { push(@implContent, " IMPL->$attributeName($arg);\n"); } } elsif ($hasSetterException) { push(@implContent, " $exceptionInit\n"); push(@implContent, " IMPL->$attributeName($arg, ec);\n"); push(@implContent, " $exceptionRaiseOnError\n"); } else { push(@implContent, " IMPL->$attributeName($arg);\n"); } push(@implContent, "}\n\n"); } } } # - Functions if ($numFunctions > 0) { foreach my $function (@{$dataNode->functions}) { AddIncludesForType($function->signature->type); my $functionName = $function->signature->name; my $returnType = GetObjCType($function->signature->type); my $hasParameters = @{$function->parameters}; my $raisesExceptions = @{$function->raisesExceptions}; my @parameterNames = (); my @needsAssert = (); my %needsCustom = (); my $parameterIndex = 0; my $functionSig = "- ($returnType)$functionName"; foreach my $param (@{$function->parameters}) { my $paramName = $param->name; my $paramType = GetObjCType($param->type); # make a new parameter name if the original conflicts with a property name $paramName = "in" . ucfirst($paramName) if $attributeNames{$paramName}; AddIncludesForType($param->type); my $idlType = $codeGenerator->StripModule($param->type); my $implGetter = GetObjCTypeGetter($paramName, $idlType); push(@parameterNames, $implGetter); $needsCustom{"XPathNSResolver"} = $paramName if $idlType eq "XPathNSResolver"; $needsCustom{"NodeFilter"} = $paramName if $idlType eq "NodeFilter"; $needsCustom{"EventListener"} = $paramName if $idlType eq "EventListener"; $needsCustom{"EventTarget"} = $paramName if $idlType eq "EventTarget"; $needsCustom{"NodeToReturn"} = $paramName if $param->extendedAttributes->{"Return"}; unless ($codeGenerator->IsPrimitiveType($idlType) or $codeGenerator->IsStringType($idlType)) { push(@needsAssert, " ASSERT($paramName);\n"); } if ($parameterIndex >= 1) { my $paramPrefix = $param->extendedAttributes->{"ObjCPrefix"}; $paramPrefix = $param->name unless defined($paramPrefix); $functionSig .= " $paramPrefix"; } $functionSig .= ":($paramType)$paramName"; $parameterIndex++; } my @functionContent = (); my $caller = "IMPL"; # special case the XPathNSResolver if (defined $needsCustom{"XPathNSResolver"}) { my $paramName = $needsCustom{"XPathNSResolver"}; push(@functionContent, " WebCore::XPathNSResolver* nativeResolver = 0;\n"); push(@functionContent, " RefPtr<WebCore::XPathNSResolver> customResolver;\n"); push(@functionContent, " if ($paramName) {\n"); push(@functionContent, " if ([$paramName isMemberOfClass:[DOMNativeXPathNSResolver class]])\n"); push(@functionContent, " nativeResolver = [(DOMNativeXPathNSResolver *)$paramName _xpathNSResolver];\n"); push(@functionContent, " else {\n"); push(@functionContent, " customResolver = WebCore::DOMCustomXPathNSResolver::create($paramName);\n"); push(@functionContent, " nativeResolver = WTF::getPtr(customResolver);\n"); push(@functionContent, " }\n"); push(@functionContent, " }\n"); } # special case the EventTarget if (defined $needsCustom{"EventTarget"}) { my $paramName = $needsCustom{"EventTarget"}; push(@functionContent, " DOMNode* ${paramName}ObjC = $paramName;\n"); push(@functionContent, " WebCore::Node* ${paramName}Node = [${paramName}ObjC _node];\n"); $implIncludes{"DOMNode.h"} = 1; $implIncludes{"Node.h"} = 1; } if ($function->signature->extendedAttributes->{"UsesView"}) { push(@functionContent, " WebCore::DOMWindow* dv = $caller->defaultView();\n"); push(@functionContent, " if (!dv)\n"); push(@functionContent, " return nil;\n"); $implIncludes{"DOMWindow.h"} = 1; $caller = "dv"; } # special case the EventListener if (defined $needsCustom{"EventListener"}) { my $paramName = $needsCustom{"EventListener"}; push(@functionContent, " RefPtr<WebCore::EventListener> nativeEventListener = WebCore::ObjCEventListener::wrap($paramName);\n"); } # special case the NodeFilter if (defined $needsCustom{"NodeFilter"}) { my $paramName = $needsCustom{"NodeFilter"}; push(@functionContent, " RefPtr<WebCore::NodeFilter> nativeNodeFilter;\n"); push(@functionContent, " if ($paramName)\n"); push(@functionContent, " nativeNodeFilter = WebCore::NodeFilter::create(WebCore::ObjCNodeFilterCondition::create($paramName));\n"); } # FIXME! We need [Custom] support for ObjC, to move these hacks into DOMSVGLength/MatrixCustom.mm my $svgMatrixRotateFromVector = ($podType and $podType eq "TransformationMatrix" and $functionName eq "rotateFromVector"); my $svgMatrixInverse = ($podType and $podType eq "TransformationMatrix" and $functionName eq "inverse"); my $svgLengthConvertToSpecifiedUnits = ($podType and $podType eq "SVGLength" and $functionName eq "convertToSpecifiedUnits"); push(@parameterNames, "ec") if $raisesExceptions and !($svgMatrixRotateFromVector || $svgMatrixInverse); my $content = $caller . "->" . $codeGenerator->WK_lcfirst($functionName) . "(" . join(", ", @parameterNames) . ")"; if ($svgMatrixRotateFromVector) { # Special case with rotateFromVector & SVGMatrix push(@functionContent, " $exceptionInit\n"); push(@functionContent, " if (x == 0.0 || y == 0.0)\n"); push(@functionContent, " ec = WebCore::SVGException::SVG_INVALID_VALUE_ERR;\n"); push(@functionContent, " $exceptionRaiseOnError\n"); push(@functionContent, " return [DOMSVGMatrix _wrapSVGMatrix:$content];\n"); } elsif ($svgMatrixInverse) { # Special case with inverse & SVGMatrix push(@functionContent, " $exceptionInit\n"); push(@functionContent, " if (!$caller->isInvertible())\n"); push(@functionContent, " ec = WebCore::SVGException::SVG_MATRIX_NOT_INVERTABLE;\n"); push(@functionContent, " $exceptionRaiseOnError\n"); push(@functionContent, " return [DOMSVGMatrix _wrapSVGMatrix:$content];\n"); } elsif ($svgLengthConvertToSpecifiedUnits) { push(@functionContent, " IMPL->convertToSpecifiedUnits(inUnitType, 0 /* FIXME */);\n"); } elsif ($returnType eq "void") { # Special case 'void' return type. if ($raisesExceptions) { push(@functionContent, " $exceptionInit\n"); push(@functionContent, " $content;\n"); push(@functionContent, " $exceptionRaiseOnError\n"); } else { push(@functionContent, " $content;\n"); } } elsif (defined $needsCustom{"NodeToReturn"}) { # Special case the insertBefore, replaceChild, removeChild # and appendChild functions from DOMNode my $toReturn = $needsCustom{"NodeToReturn"}; if ($raisesExceptions) { push(@functionContent, " $exceptionInit\n"); push(@functionContent, " if ($content)\n"); push(@functionContent, " return $toReturn;\n"); push(@functionContent, " $exceptionRaiseOnError\n"); push(@functionContent, " return nil;\n"); } else { push(@functionContent, " if ($content)\n"); push(@functionContent, " return $toReturn;\n"); push(@functionContent, " return nil;\n"); } } else { my $typeMaker = GetObjCTypeMaker($function->signature->type); unless ($typeMaker eq "") { my $returnTypeClass = ""; if ($function->signature->type eq "XPathNSResolver") { # Special case XPathNSResolver $returnTypeClass = "DOMNativeXPathNSResolver"; } else { # Remove trailing " *" from pointer types. $returnTypeClass = $returnType; $returnTypeClass =~ s/ \*$//; } # Surround getter with TypeMaker my $idlType = $returnTypeClass; $idlType =~ s/^DOM//; if ($codeGenerator->IsPodType($idlType)) { $content = "[$returnTypeClass $typeMaker:" . $content . "]"; } else { $content = "[$returnTypeClass $typeMaker:WTF::getPtr(" . $content . ")]"; } } if ($raisesExceptions) { # Differentiated between when the return type is a pointer and # not for white space issue (ie. Foo *result vs. int result). if ($returnType =~ /\*$/) { $content = $returnType . "result = " . $content; } else { $content = $returnType . " result = " . $content; } push(@functionContent, " $exceptionInit\n"); push(@functionContent, " $content;\n"); push(@functionContent, " $exceptionRaiseOnError\n"); push(@functionContent, " return result;\n"); } else { push(@functionContent, " return $content;\n"); } } push(@implContent, "$functionSig\n"); push(@implContent, "{\n"); push(@implContent, @functionContent); push(@implContent, "}\n\n"); # generate the old style method names with un-named parameters, these methods are deprecated if (@{$function->parameters} > 1 and $function->signature->extendedAttributes->{"OldStyleObjC"}) { my $deprecatedFunctionSig = $functionSig; $deprecatedFunctionSig =~ s/\s\w+:/ :/g; # remove parameter names push(@implContent, "$deprecatedFunctionSig\n"); push(@implContent, "{\n"); push(@implContent, @functionContent); push(@implContent, "}\n\n"); } # Clear the hash %needsCustom = (); } } # END implementation push(@implContent, "\@end\n"); # Generate internal interfaces unless ($dataNode->extendedAttributes->{ObjCCustomInternalImpl}) { # - BEGIN WebCoreInternal category @implementation push(@implContent, "\n\@implementation $className (WebCoreInternal)\n\n"); my $typeGetterSig = GetInternalTypeGetterSignature($interfaceName, $podType); push(@implContent, "$typeGetterSig\n"); push(@implContent, "{\n"); if ($podType) { push(@implContent, " return *IMPL;\n"); } else { push(@implContent, " return IMPL;\n"); } push(@implContent, "}\n\n"); my ($typeMakerSig, $typeMakerSigAddition, $ivarsToInit) = GetInternalTypeMakerSignature($interfaceName, $podType); if ($podType) { # - (id)_initWithFooBar:(WebCore::FooBar)impl for implementation class FooBar my $initWithImplName = "_initWith" . $implClassName; my $initWithSig = "- (id)$initWithImplName:($podTypeWithNamespace)impl" . $typeMakerSigAddition; # FIXME: Implement Caching push(@implContent, "$initWithSig\n"); push(@implContent, "{\n"); push(@implContent, " $assertMainThread;\n"); push(@implContent, " [super _init];\n"); push(@implContent, " $podTypeWithNamespace* _impl = new $podTypeWithNamespace(impl);\n"); push(@implContent, " _internal = reinterpret_cast<DOMObjectInternal*>(_impl);\n"); push(@implContent, " return self;\n"); push(@implContent, "}\n\n");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -