📄 codegeneratorcom.pm
字号:
sub GetAdditionalInterfaces{ my $type = $codeGenerator->StripModule(shift); return ("EventTarget") if $type eq "Node"; return ();}sub GenerateIDL{ my ($object, $dataNode, $pureInterface) = @_; my $inInterfaceName = $dataNode->name; my $outInterfaceName = GetInterfaceName($inInterfaceName); my $uuid = $dataNode->extendedAttributes->{"InterfaceUUID"} || die "All classes require an InterfaceUUID extended attribute."; my $parentInterfaceName = ($pureInterface) ? "IUnknown" : GetParentInterface($dataNode); my $numConstants = @{$dataNode->constants}; my $numAttributes = @{$dataNode->attributes}; my $numFunctions = @{$dataNode->functions}; # - Add default header template @IDLHeader = @licenseTemplate; push(@IDLHeader, "\n"); # - INCLUDES - push(@IDLHeader, "#ifndef DO_NO_IMPORTS\n"); push(@IDLHeader, "import \"oaidl.idl\";\n"); push(@IDLHeader, "import \"ocidl.idl\";\n"); push(@IDLHeader, "#endif\n\n"); unless ($pureInterface) { push(@IDLHeader, "#ifndef DO_NO_IMPORTS\n"); push(@IDLHeader, "import \"${parentInterfaceName}.idl\";\n"); push(@IDLHeader, "#endif\n\n"); $IDLDontForwardDeclare{$outInterfaceName} = 1; $IDLDontImport{$outInterfaceName} = 1; $IDLDontForwardDeclare{$parentInterfaceName} = 1; $IDLDontImport{$parentInterfaceName} = 1; } # - Begin # -- Attributes push(@IDLContent, "[\n"); push(@IDLContent, " object,\n"); push(@IDLContent, " oleautomation,\n"); push(@IDLContent, " uuid(" . $uuid . "),\n"); push(@IDLContent, " pointer_default(unique)\n"); push(@IDLContent, "]\n"); # -- Interface push(@IDLContent, "interface " . $outInterfaceName . " : " . $parentInterfaceName . "\n"); push(@IDLContent, "{\n"); # - FIXME: Add constants. # - Add attribute getters/setters. if ($numAttributes > 0) { foreach my $attribute (@{$dataNode->attributes}) { my $attributeName = $attribute->signature->name; my $attributeIDLType = $attribute->signature->type; my $attributeTypeIn = GetCOMTypeIn($attributeIDLType); my $attributeTypeOut = GetCOMTypeOut($attributeIDLType); my $attributeIsReadonly = ($attribute->type =~ /^readonly/); AddForwardDeclarationsForTypeInIDL($attributeIDLType); unless ($attributeIsReadonly) { # Setter my $setterName = "set" . $codeGenerator->WK_ucfirst($attributeName); my $setter = " HRESULT " . $setterName . "([in] " . $attributeTypeIn . ");\n"; push(@IDLContent, $setter); } # Getter my $getter = " HRESULT " . $attributeName . "([out, retval] " . $attributeTypeOut . "*);\n\n"; push(@IDLContent, $getter); } } # - Add functions. if ($numFunctions > 0) { foreach my $function (@{$dataNode->functions}) { my $functionName = $function->signature->name; my $returnIDLType = $function->signature->type; my $returnType = GetCOMTypeOut($returnIDLType); my $noReturn = ($returnType eq "void"); AddForwardDeclarationsForTypeInIDL($returnIDLType); my @paramArgList = (); foreach my $param (@{$function->parameters}) { my $paramName = $param->name; my $paramIDLType = $param->type; my $paramType = GetCOMTypeIn($param->type); AddForwardDeclarationsForTypeInIDL($paramIDLType); # Form parameter my $parameter = "[in] ${paramType} ${paramName}"; # Add parameter to function signature push(@paramArgList, $parameter); } unless ($noReturn) { my $resultParameter = "[out, retval] " . $returnType . "* result"; push(@paramArgList, $resultParameter); } my $functionSig = " HRESULT " . $functionName . "("; $functionSig .= join(", ", @paramArgList); $functionSig .= ");\n\n"; push(@IDLContent, $functionSig); } } # - End push(@IDLContent, "}\n\n");}sub GenerateInterfaceHeader{ my ($object, $dataNode) = @_; my $IDLType = $dataNode->name; my $implementationClass = IDLTypeToImplementationType($IDLType); my $implementationClassWithoutNamespace = StripNamespace($implementationClass); my $className = GetClassName($IDLType); my $interfaceName = GetInterfaceName($IDLType); # - Add default header template @CPPInterfaceHeader = @licenseTemplate; push(@CPPInterfaceHeader, "\n"); # - Header guards - push(@CPPInterfaceHeader, "#ifndef " . $className . "_h\n"); push(@CPPInterfaceHeader, "#define " . $className . "_h\n\n"); # - Forward Declarations - push(@CPPInterfaceHeader, "interface ${interfaceName};\n\n"); push(@CPPInterfaceHeader, "namespace WebCore {\n"); push(@CPPInterfaceHeader, " class ${implementationClassWithoutNamespace};\n"); push(@CPPInterfaceHeader, "}\n\n"); # - Default Interface Creator - push(@CPPInterfaceHeader, "${interfaceName}* to${interfaceName}(${implementationClass}*) { return 0; }\n\n"); push(@CPPInterfaceHeader, "#endif // " . $className . "_h\n");}# -----------------------------------------------------------------------------# CPP Helper Functions# -----------------------------------------------------------------------------sub GenerateCPPAttributeSignature{ my ($attribute, $className, $options) = @_; my $attributeName = $attribute->signature->name; my $isReadonly = ($attribute->type =~ /^readonly/); my $newline = $$options{"NewLines"} ? "\n" : ""; my $indent = $$options{"Indent"} ? " " x $$options{"Indent"} : ""; my $semicolon = $$options{"IncludeSemiColon"} ? ";" : ""; my $virtual = $$options{"AddVirtualKeyword"} ? "virtual " : ""; my $class = $$options{"UseClassName"} ? "${className}::" : ""; my $forwarder = $$options{"Forwarder"} ? 1 : 0; my $joiner = ($$options{"NewLines"} ? "\n" . $indent . " " : ""); my %attributeSignatures = (); unless ($isReadonly) { my $attributeTypeIn = GetCOMTypeIn($attribute->signature->type); my $setterName = "set" . $codeGenerator->WK_ucfirst($attributeName); my $setter = $indent . $virtual . "HRESULT STDMETHODCALLTYPE ". $class . $setterName . "("; $setter .= $joiner . "/* [in] */ ${attributeTypeIn} ${attributeName})" . $semicolon . $newline; if ($forwarder) { $setter .= " { return " . $$options{"Forwarder"} . "::" . $setterName . "(${attributeName}); }\n"; } $attributeSignatures{"Setter"} = $setter; } my $attributeTypeOut = GetCOMTypeOut($attribute->signature->type); my $getter = $indent . $virtual . "HRESULT STDMETHODCALLTYPE " . $class . $attributeName . "("; $getter .= $joiner . "/* [retval][out] */ ${attributeTypeOut}* result)" . $semicolon . $newline; if ($forwarder) { $getter .= " { return " . $$options{"Forwarder"} . "::" . $attributeName . "(result); }\n"; } $attributeSignatures{"Getter"} = $getter; return %attributeSignatures;}sub GenerateCPPAttribute{ my ($attribute, $className, $implementationClass) = @_; my $implementationClassWithoutNamespace = StripNamespace($implementationClass); my $attributeName = $attribute->signature->name; my $attributeIDLType = $attribute->signature->type; my $hasSetterException = @{$attribute->setterExceptions}; my $hasGetterException = @{$attribute->getterExceptions}; my $isReadonly = ($attribute->type =~ /^readonly/); my $attributeTypeIsPrimitive = $codeGenerator->IsPrimitiveType($attributeIDLType); my $attributeTypeIsString = $codeGenerator->IsStringType($attributeIDLType); my $attributeImplementationType = IDLTypeToImplementationType($attributeIDLType); my $attributeImplementationTypeWithoutNamespace = StripNamespace($attributeImplementationType); my $attributeTypeCOMClassName = GetClassName($attributeIDLType); $CPPImplementationWebCoreIncludes{"ExceptionCode.h"} = 1 if $hasSetterException or $hasGetterException; my %signatures = GenerateCPPAttributeSignature($attribute, $className, { "NewLines" => 1, "Indent" => 0, "IncludeSemiColon" => 0, "UseClassName" => 1, "AddVirtualKeyword" => 0 }); my %attrbutesToReturn = (); unless ($isReadonly) { my @setterImplementation = (); push(@setterImplementation, $signatures{"Setter"}); push(@setterImplementation, "{\n"); my $setterName = "set" . $codeGenerator->WK_ucfirst($attributeName); my @setterParams = (); if ($attributeTypeIsString) { push(@setterParams, $attributeName); if ($hasSetterException) { push(@setterImplementation, " WebCore::ExceptionCode ec = 0;\n"); push(@setterParams, "ec"); } } elsif ($attributeTypeIsPrimitive) { if ($attribute->signature->extendedAttributes->{"ConvertFromString"}) { push(@setterParams, "WebCore::String::number(${attributeName})"); } elsif ($attributeIDLType eq "boolean") { push(@setterParams, "!!${attributeName}"); } else { my $primitiveImplementationType = IDLTypeToImplementationType($attributeIDLType); push(@setterParams, "static_cast<${primitiveImplementationType}>(${attributeName})"); } if ($hasSetterException) { push(@setterImplementation, " WebCore::ExceptionCode ec = 0;\n"); push(@setterParams, "ec"); } } else { $CPPImplementationWebCoreIncludes{"COMPtr.h"} = 1; push(@setterImplementation, " if (!${attributeName})\n"); push(@setterImplementation, " return E_POINTER;\n\n"); push(@setterImplementation, " COMPtr<${attributeTypeCOMClassName}> ptr(Query, ${attributeName});\n"); push(@setterImplementation, " if (!ptr)\n"); push(@setterImplementation, " return E_NOINTERFACE;\n"); push(@setterParams, "ptr->impl${attributeImplementationTypeWithoutNamespace}()"); if ($hasSetterException) { push(@setterImplementation, " WebCore::ExceptionCode ec = 0;\n"); push(@setterParams, "ec"); } } # FIXME: CHECK EXCEPTION AND DO SOMETHING WITH IT my $setterCall = " impl${implementationClassWithoutNamespace}()->${setterName}(" . join(", ", @setterParams) . ");\n"; push(@setterImplementation, $setterCall); push(@setterImplementation, " return S_OK;\n"); push(@setterImplementation, "}\n\n"); $attrbutesToReturn{"Setter"} = join("", @setterImplementation); } my @getterImplementation = (); push(@getterImplementation, $signatures{"Getter"}); push(@getterImplementation, "{\n"); push(@getterImplementation, " if (!result)\n"); push(@getterImplementation, " return E_POINTER;\n\n"); my $implementationGetter = "impl${implementationClassWithoutNamespace}()->" . $codeGenerator->WK_lcfirst($attributeName) . "(" . ($hasGetterException ? "ec" : ""). ")"; push(@getterImplementation, " WebCore::ExceptionCode ec = 0;\n") if $hasGetterException; if ($attributeTypeIsString) { push(@getterImplementation, " *result = WebCore::BString(${implementationGetter}).release();\n"); } elsif ($attributeTypeIsPrimitive) { if ($attribute->signature->extendedAttributes->{"ConvertFromString"}) { push(@getterImplementation, " *result = static_cast<${attributeTypeCOMClassName}>(${implementationGetter}.toInt());\n"); } else { push(@getterImplementation, " *result = static_cast<${attributeTypeCOMClassName}>(${implementationGetter});\n"); } } else { $CPPImplementationIncludesAngle{"wtf/GetPtr.h"} = 1; my $attributeTypeCOMInterfaceName = GetInterfaceName($attributeIDLType); push(@getterImplementation, " *result = 0;\n"); push(@getterImplementation, " ${attributeImplementationType}* resultImpl = WTF::getPtr(${implementationGetter});\n"); push(@getterImplementation, " if (!resultImpl)\n"); push(@getterImplementation, " return E_POINTER;\n\n"); push(@getterImplementation, " *result = to${attributeTypeCOMInterfaceName}(resultImpl);\n"); } # FIXME: CHECK EXCEPTION AND DO SOMETHING WITH IT push(@getterImplementation, " return S_OK;\n"); push(@getterImplementation, "}\n\n"); $attrbutesToReturn{"Getter"} = join("", @getterImplementation); return %attrbutesToReturn;}sub GenerateCPPFunctionSignature{ my ($function, $className, $options) = @_; my $functionName = $function->signature->name; my $returnIDLType = $function->signature->type; my $returnType = GetCOMTypeOut($returnIDLType);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -