⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 codegeneratorcom.pm

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 PM
📖 第 1 页 / 共 4 页
字号:
    my $noReturn = ($returnType eq "void");    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 @paramArgList = ();    foreach my $param (@{$function->parameters}) {        my $paramName = $param->name;        my $paramType = GetCOMTypeIn($param->type);        my $parameter = "/* [in] */ ${paramType} ${paramName}";        push(@paramArgList, $parameter);    }    unless ($noReturn) {        my $resultParameter .= "/* [out, retval] */ ${returnType}* result";        push(@paramArgList, $resultParameter);    }    my $functionSig = $indent . $virtual . "HRESULT STDMETHODCALLTYPE " . $class . $functionName . "(";    $functionSig .= $joiner . join("," . $joiner, @paramArgList) if @paramArgList > 0;    $functionSig .= ")" . $semicolon . $newline;    if ($forwarder) {        my @paramNameList = ();        push(@paramNameList, $_->name) foreach (@{$function->parameters});        push(@paramNameList, "result") unless $noReturn;        $functionSig .= " { return " . $$options{"Forwarder"} . "::" . $functionName . "(" . join(", ", @paramNameList) . "); }\n";    }    return $functionSig}sub GenerateCPPFunction{    my ($function, $className, $implementationClass) = @_;    my @functionImplementation = ();    my $signature = GenerateCPPFunctionSignature($function, $className, { "NewLines" => 1,                                                                          "Indent" => 0,                                                                          "IncludeSemiColon" => 0,                                                                          "UseClassName" => 1,                                                                          "AddVirtualKeyword" => 0 });    my $implementationClassWithoutNamespace = StripNamespace($implementationClass);    my $functionName = $function->signature->name;    my $returnIDLType = $function->signature->type;    my $noReturn = ($returnIDLType eq "void");    my $raisesExceptions = @{$function->raisesExceptions};    AddIncludesForTypeInCPPImplementation($returnIDLType);    $CPPImplementationWebCoreIncludes{"ExceptionCode.h"} = 1 if $raisesExceptions;    my %needsCustom = ();    my @parameterInitialization = ();    my @parameterList = ();    foreach my $param (@{$function->parameters}) {        my $paramName = $param->name;        my $paramIDLType = $param->type;        my $paramTypeIsPrimitive = $codeGenerator->IsPrimitiveType($paramIDLType);        my $paramTypeIsString = $codeGenerator->IsStringType($paramIDLType);        $needsCustom{"NodeToReturn"} = $paramName if $param->extendedAttributes->{"Return"};        AddIncludesForTypeInCPPImplementation($paramIDLType);        # FIXME: We may need to null check the arguments as well        if ($paramTypeIsString) {            push(@parameterList, $paramName);        } elsif ($paramTypeIsPrimitive) {            if ($paramIDLType eq "boolean") {                push(@parameterList, "!!${paramName}");            } else {                my $primitiveImplementationType = IDLTypeToImplementationType($paramIDLType);                push(@parameterList, "static_cast<${primitiveImplementationType}>(${paramName})");            }        } else {            $CPPImplementationWebCoreIncludes{"COMPtr.h"} = 1;            $needsCustom{"CanReturnEarly"} = 1;            my $paramTypeCOMClassName = GetClassName($paramIDLType);            my $paramTypeImplementationWithoutNamespace = StripNamespace(IDLTypeToImplementationType($paramIDLType));            my $ptrName = "ptrFor" . $codeGenerator->WK_ucfirst($paramName);            my $paramInit = "    COMPtr<${paramTypeCOMClassName}> ${ptrName}(Query, ${paramName});\n";            $paramInit .= "    if (!${ptrName})\n";            $paramInit .= "        return E_NOINTERFACE;";            push(@parameterInitialization, $paramInit);            push(@parameterList, "${ptrName}->impl${paramTypeImplementationWithoutNamespace}()");        }    }    push(@parameterList, "ec") if $raisesExceptions;    my $implementationGetter = "impl${implementationClassWithoutNamespace}()";    my $callSigBegin = "    ";    my $callSigMiddle = "${implementationGetter}->" . $codeGenerator->WK_lcfirst($functionName) . "(" . join(", ", @parameterList) . ")";    my $callSigEnd = ";\n";    if (defined $needsCustom{"NodeToReturn"}) {        my $nodeToReturn = $needsCustom{"NodeToReturn"};        $callSigBegin .= "if (";        $callSigEnd = ")\n";        $callSigEnd .= "        *result = ${nodeToReturn};";    } elsif (!$noReturn) {        my $returnTypeIsString =  $codeGenerator->IsStringType($returnIDLType);        my $returnTypeIsPrimitive = $codeGenerator->IsPrimitiveType($returnIDLType);        if ($returnTypeIsString) {            $callSigBegin .= "*result = WebCore::BString(";            $callSigEnd = ").release();\n";        } elsif ($returnTypeIsPrimitive) {            my $primitiveCOMType = GetClassName($returnIDLType);            $callSigBegin .= "*result = static_cast<${primitiveCOMType}>(";            $callSigEnd = ");";        } else {            $CPPImplementationIncludesAngle{"wtf/GetPtr.h"} = 1;            my $returnImplementationType = IDLTypeToImplementationType($returnIDLType);            my $returnTypeCOMInterfaceName = GetInterfaceName($returnIDLType);            $callSigBegin .= "${returnImplementationType}* resultImpl = WTF::getPtr(";            $callSigEnd = ");\n";            $callSigEnd .= "    if (!resultImpl)\n";            $callSigEnd .= "        return E_POINTER;\n\n";            $callSigEnd .= "    *result = to${returnTypeCOMInterfaceName}(resultImpl);";        }    }    push(@functionImplementation, $signature);    push(@functionImplementation, "{\n");    unless ($noReturn) {        push(@functionImplementation, "    if (!result)\n");        push(@functionImplementation, "        return E_POINTER;\n\n");        push(@functionImplementation, "    *result = 0;\n\n") if $needsCustom{"CanReturnEarly"};    }    push(@functionImplementation, "    WebCore::ExceptionCode ec = 0;\n") if $raisesExceptions; # FIXME: CHECK EXCEPTION AND DO SOMETHING WITH IT    push(@functionImplementation, join("\n", @parameterInitialization) . (@parameterInitialization > 0 ? "\n" : ""));    push(@functionImplementation, $callSigBegin . $callSigMiddle . $callSigEnd . "\n");    push(@functionImplementation, "    return S_OK;\n");    push(@functionImplementation, "}\n\n");    return join("", @functionImplementation);}# -----------------------------------------------------------------------------#    CPP Header# -----------------------------------------------------------------------------sub GenerateCPPHeader{    my ($object, $dataNode) = @_;    my $IDLType = $dataNode->name;    my $implementationClass = IDLTypeToImplementationType($IDLType);    my $implementationClassWithoutNamespace = StripNamespace($implementationClass);    my $className = GetClassName($IDLType);    my $interfaceName = GetInterfaceName($IDLType);    my $parentClassName = GetParentClass($dataNode);    my @otherInterfacesImplemented = GetAdditionalInterfaces($IDLType);    foreach my $otherInterface (@otherInterfacesImplemented) {        push(@additionalInterfaceDefinitions, $codeGenerator->ParseInterface($otherInterface));    }    # FIXME: strip whitespace from UUID    my $uuid = $dataNode->extendedAttributes->{"ImplementationUUID"} || die "All classes require an ImplementationUUID extended attribute.";    my $numAttributes = @{$dataNode->attributes};    my $numFunctions = @{$dataNode->functions};    # - Add default header template    @CPPHeaderHeader = @licenseTemplate;    push(@CPPHeaderHeader, "\n");    # - Header guards -    push(@CPPHeaderHeader, "#ifndef " . $className . "_h\n");    push(@CPPHeaderHeader, "#define " . $className . "_h\n\n");    AddIncludesForTypeInCPPHeader($interfaceName);    AddIncludesForTypeInCPPHeader($parentClassName);    $CPPHeaderDontForwardDeclarations{$className} = 1;    $CPPHeaderDontForwardDeclarations{$interfaceName} = 1;    $CPPHeaderDontForwardDeclarations{$parentClassName} = 1;    # -- Forward declare implementation type    push(@CPPHeaderContent, "namespace WebCore {\n");    push(@CPPHeaderContent, "    class ". StripNamespace($implementationClass) . ";\n");    push(@CPPHeaderContent, "}\n\n");    # -- Start Class --    my @parentsClasses = ($parentClassName, $interfaceName);    push(@parentsClasses, map { GetInterfaceName($_) } @otherInterfacesImplemented);    push(@CPPHeaderContent, "class __declspec(uuid(\"$uuid\")) ${className} : " . join(", ", map { "public $_" } @parentsClasses) . " {\n");    # Add includes for all additional interfaces to implement    map { AddIncludesForTypeInCPPHeader(GetInterfaceName($_)) } @otherInterfacesImplemented;    # -- BASICS --    # FIXME: The constructor and destructor should be protected, but the current design of    # createInstance requires them to be public.  One solution is to friend the constructor    # of the top-level-class with every one of its child classes, but that requires information    # this script currently does not have, though possibly could determine.    push(@CPPHeaderContent, "public:\n");    push(@CPPHeaderContent, "   ${className}(${implementationClass}*);\n");    push(@CPPHeaderContent, "   virtual ~${className}();\n\n");    push(@CPPHeaderContent, "public:\n");    push(@CPPHeaderContent, "    static ${className}* createInstance(${implementationClass}*);\n\n");    push(@CPPHeaderContent, "    // IUnknown\n");    push(@CPPHeaderContent, "    virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID, void** ppvObject);\n");    push(@CPPHeaderContent, "    virtual ULONG STDMETHODCALLTYPE AddRef() { return ${parentClassName}::AddRef(); }\n");    push(@CPPHeaderContent, "    virtual ULONG STDMETHODCALLTYPE Release() { return ${parentClassName}::Release(); }\n\n");    # -- Parent Class Forwards --    if (@{$dataNode->parents}) {        my %attributeNameSet = map {($_->signature->name, 1)} @{$dataNode->attributes};        my %functionNameSet = map {($_->signature->name, 1)} @{$dataNode->functions};        my @parentLists = $codeGenerator->GetMethodsAndAttributesFromParentClasses($dataNode);        push(@CPPHeaderContent, "\n");        foreach my $parentHash (@parentLists) {            push(@CPPHeaderContent, "    // " . GetInterfaceName($parentHash->{'name'}) . $DASHES . "\n");            my @attributeList = @{$parentHash->{'attributes'}};            push(@CPPHeaderContent, "    // Attributes\n");            foreach my $attribute (@attributeList) {                # Don't forward an attribute that this class redefines.                next if $attributeNameSet{$attribute->signature->name};                AddForwardDeclarationsForTypeInCPPHeader($attribute->signature->type);                my %attributes = GenerateCPPAttributeSignature($attribute, $className, { "NewLines" => 0,                                                                                         "Indent" => 4,                                                                                         "IncludeSemiColon" => 0,                                                                                         "AddVirtualKeyword" => 1,                                                                                         "UseClassName" => 0,                                                                                         "Forwarder" => $parentClassName });                push(@CPPHeaderContent, values(%attributes));            }                        # Add attribute names to attribute names set in case other ancestors             # also define them.            $attributeNameSet{$_->signature->name} = 1 foreach @attributeList;            push(@CPPHeaderContent, "\n");            my @functionList = @{$parentHash->{'functions'}};            push(@CPPHeaderContent, "    // Functions\n");            foreach my $function (@functionList) {                # Don't forward a function that this class redefines.                next if $functionNameSet{$function->signature->name};                AddForwardDeclarationsForTypeInCPPHeader($function->signature->type);                AddForwardDeclarationsForTypeInCPPHeader($_->type) foreach (@{$function->parameters});                my $functionSig = GenerateCPPFunctionSignature($function, $className, { "NewLines" => 0,                                                                                        "Indent" => 4,                                                                                        "IncludeSemiColon" => 0,                                                                                        "AddVirtualKeyword" => 1,                                                                                        "UseClassName" => 0,                                                                                        "Forwarder" => $parentClassName });                push(@CPPHeaderContent, $functionSig);            }            # Add functions names to functions names set in case other ancestors             # also define them.            $functionNameSet{$_->signature->name} = 1 foreach @functionList;            push(@CPPHeaderContent, "\n");        }    }    # - Additional interfaces to implement -    foreach my $interfaceToImplement (@additionalInterfaceDefinitions) {        my $IDLTypeOfInterfaceToImplement = $interfaceToImplement->name;        my $nameOfInterfaceToImplement = GetInterfaceName($IDLTypeOfInterfaceToImplement);        my $numAttributesInInterface = @{$interfaceToImplement->attributes};        my $numFunctionsInInterface = @{$interfaceToImplement->functions};        push(@CPPHeaderContent, "    // ${nameOfInterfaceToImplement} ${DASHES}\n\n");        # - Add attribute getters/setters.        if ($numAttributesInInterface > 0) {            push(@CPPHeaderContent, "    // Attributes\n\n");            foreach my $attribute (@{$interfaceToImplement->attributes}) {                AddForwardDeclarationsForTypeInCPPHeader($attribute->signature->type);                my %attributeSigs = GenerateCPPAttributeSignature($attribute, $className, { "NewLines" => 1,                                                                                            "Indent" => 4,                                                                                            "IncludeSemiColon" => 1,                                                                                            "AddVirtualKeyword" => 1,                                                                                            "UseClassName" => 0 });                push(@CPPHeaderContent, values(%attributeSigs));                push(@CPPHeaderContent, "\n");            }        }        # - Add functions.        if ($numFunctionsInInterface > 0) {            push(@CPPHeaderContent, "    // Functions\n\n");            foreach my $function (@{$interfaceToImplement->functions}) {                AddForwardDeclarationsForTypeInCPPHeader($function->signature->type);                AddForwardDeclarationsForTypeInCPPHeader($_->type) foreach (@{$function->parameters});                my $functionSig = GenerateCPPFunctionSignature($function, $className, { "NewLines" => 1,                                                                                        "Indent" => 4,                                                                                        "IncludeSemiColon" => 1,                                                                                        "AddVirtualKeyword" => 1,                                                                                        "UseClassName" => 0 });                push(@CPPHeaderContent, $functionSig);                push(@CPPHeaderContent, "\n");            }        }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -