WebCore/inspector/CodeGeneratorInspector.pm
changeset 0 4f2f89ce4247
equal deleted inserted replaced
-1:000000000000 0:4f2f89ce4247
       
     1 # Copyright (c) 2010 The Chromium Authors. All rights reserved.
       
     2 # Use of this source code is governed by a BSD-style license that can be
       
     3 # found in the LICENSE file.
       
     4 
       
     5 package CodeGeneratorInspector;
       
     6 
       
     7 use strict;
       
     8 
       
     9 use Class::Struct;
       
    10 use File::stat;
       
    11 
       
    12 my %typeTransform;
       
    13 $typeTransform{"InspectorClient"} = {
       
    14     "forward" => "InspectorClient",
       
    15     "header" => "InspectorClient.h",
       
    16 };
       
    17 $typeTransform{"PassRefPtr"} = {
       
    18     "forwardHeader" => "wtf/PassRefPtr.h",
       
    19 };
       
    20 $typeTransform{"Object"} = {
       
    21     "param" => "PassRefPtr<InspectorObject>",
       
    22     "retVal" => "PassRefPtr<InspectorObject>",
       
    23     "forward" => "InspectorObject",
       
    24     "header" => "InspectorValues.h",
       
    25     "accessorSuffix" => ""
       
    26 };
       
    27 $typeTransform{"Array"} = {
       
    28     "param" => "PassRefPtr<InspectorArray>",
       
    29     "retVal" => "PassRefPtr<InspectorArray>",
       
    30     "forward" => "InspectorArray",
       
    31     "header" => "InspectorValues.h",
       
    32     "accessorSuffix" => ""
       
    33 };
       
    34 $typeTransform{"Value"} = {
       
    35     "param" => "PassRefPtr<InspectorValue>",
       
    36     "retVal" => "PassRefPtr<InspectorValue>",
       
    37     "forward" => "InspectorValue",
       
    38     "header" => "InspectorValues.h",
       
    39     "accessorSuffix" => ""
       
    40 };
       
    41 $typeTransform{"String"} = {
       
    42     "param" => "const String&",
       
    43     "retVal" => "String",
       
    44     "forward" => "String",
       
    45     "header" => "PlatformString.h",
       
    46     "accessorSuffix" => "String"
       
    47 };
       
    48 $typeTransform{"long"} = {
       
    49     "param" => "long",
       
    50     "retVal" => "long",
       
    51     "forward" => "",
       
    52     "header" => "",
       
    53     "accessorSuffix" => "Number"
       
    54 };
       
    55 $typeTransform{"int"} = {
       
    56     "param" => "int",
       
    57     "retVal" => "int",
       
    58     "forward" => "",
       
    59     "header" => "",
       
    60     "accessorSuffix" => "Number",
       
    61 };
       
    62 $typeTransform{"unsigned long"} = {
       
    63     "param" => "unsigned long",
       
    64     "retVal" => "unsigned long",
       
    65     "forward" => "",
       
    66     "header" => "",
       
    67     "accessorSuffix" => "Number"
       
    68 };
       
    69 $typeTransform{"boolean"} = {
       
    70     "param" => "bool",
       
    71     "retVal"=> "bool",
       
    72     "forward" => "",
       
    73     "header" => "",
       
    74     "accessorSuffix" => "Bool"
       
    75 };
       
    76 $typeTransform{"void"} = {
       
    77     "retVal" => "void",
       
    78     "forward" => "",
       
    79     "header" => ""
       
    80 };
       
    81 
       
    82 # Default License Templates
       
    83 
       
    84 my $licenseTemplate = << "EOF";
       
    85 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
       
    86 // Use of this source code is governed by a BSD-style license that can be
       
    87 // found in the LICENSE file.
       
    88 EOF
       
    89 
       
    90 my $codeGenerator;
       
    91 my $outputDir;
       
    92 my $outputHeadersDir;
       
    93 my $writeDependencies;
       
    94 my $verbose;
       
    95 
       
    96 my $namespace;
       
    97 
       
    98 my $frontendClassName;
       
    99 my %frontendTypes;
       
   100 my %frontendMethods;
       
   101 my @frontendMethodsImpl;
       
   102 my $frontendConstructor;
       
   103 my $frontendFooter;
       
   104 
       
   105 my $callId = new domSignature(); # it is just structure for describing parameters from IDLStructure.pm.
       
   106 $callId->type("long");
       
   107 $callId->name("callId");
       
   108 
       
   109 # Default constructor
       
   110 sub new
       
   111 {
       
   112     my $object = shift;
       
   113     my $reference = { };
       
   114 
       
   115     $codeGenerator = shift;
       
   116     $outputDir = shift;
       
   117     $outputHeadersDir = shift;
       
   118     shift; # $useLayerOnTop
       
   119     shift; # $preprocessor
       
   120     $writeDependencies = shift;
       
   121     $verbose = shift;
       
   122 
       
   123     bless($reference, $object);
       
   124     return $reference;
       
   125 }
       
   126 
       
   127 # Params: 'idlDocument' struct
       
   128 sub GenerateModule
       
   129 {
       
   130     my $object = shift;
       
   131     my $dataNode = shift;
       
   132 
       
   133     $namespace = $dataNode->module;
       
   134     $namespace =~ s/core/WebCore/;
       
   135 }
       
   136 
       
   137 # Params: 'idlDocument' struct
       
   138 sub GenerateInterface
       
   139 {
       
   140     my $object = shift;
       
   141     my $interface = shift;
       
   142     my $defines = shift;
       
   143 
       
   144     my $className = $interface->name;
       
   145 
       
   146     $frontendClassName = "Remote" . $className . "Frontend";
       
   147     $frontendConstructor = "    ${frontendClassName}(InspectorClient* inspectorClient) : m_inspectorClient(inspectorClient) { }";
       
   148     $frontendFooter = "    InspectorClient* m_inspectorClient;";
       
   149     $frontendTypes{"String"} = 1;
       
   150     $frontendTypes{"InspectorClient"} = 1;
       
   151     $frontendTypes{"PassRefPtr"} = 1;
       
   152 
       
   153     generateFunctions($interface);
       
   154 }
       
   155 
       
   156 sub generateFunctions
       
   157 {
       
   158     my $interface = shift;
       
   159 
       
   160     foreach my $function (@{$interface->functions}) {
       
   161         generateFrontendFunction($function);
       
   162     }
       
   163 }
       
   164 
       
   165 sub generateFrontendFunction
       
   166 {
       
   167     my $function = shift;
       
   168 
       
   169     my $functionName;
       
   170     my $notify = $function->signature->extendedAttributes->{"notify"};
       
   171     if ($notify) {
       
   172         $functionName = $function->signature->name;
       
   173     } else {
       
   174         my $customResponse = $function->signature->extendedAttributes->{"customResponse"};
       
   175         $functionName = $customResponse ? $customResponse : "did" . ucfirst($function->signature->name);
       
   176     }
       
   177 
       
   178     my @argsFiltered = grep($_->direction eq "out", @{$function->parameters}); # just keep only out parameters for frontend interface.
       
   179     unshift(@argsFiltered, $callId) if !$notify; # Add callId as the first argument for all frontend did* methods.
       
   180     map($frontendTypes{$_->type} = 1, @argsFiltered); # register required types.
       
   181     my $arguments = join(", ", map($typeTransform{$_->type}->{"param"} . " " . $_->name, @argsFiltered)); # prepare arguments for function signature.
       
   182     my @pushArguments = map("    arguments->push" . $typeTransform{$_->type}->{"accessorSuffix"} . "(" . $_->name . ");", @argsFiltered);
       
   183 
       
   184     my $signature = "    void ${functionName}(${arguments});";
       
   185     if (!$frontendMethods{${signature}}) {
       
   186         $frontendMethods{${signature}} = 1;
       
   187 
       
   188         my @function;
       
   189         push(@function, "void ${frontendClassName}::${functionName}(${arguments})");
       
   190         push(@function, "{");
       
   191         push(@function, "    RefPtr<InspectorArray> arguments = InspectorArray::create();");
       
   192         push(@function, "    arguments->pushString(\"$functionName\");");
       
   193         push(@function, @pushArguments);
       
   194         push(@function, "    m_inspectorClient->sendMessageToFrontend(arguments->toJSONString());");
       
   195         push(@function, "}");
       
   196         push(@function, "");
       
   197         push(@frontendMethodsImpl, @function);
       
   198     }
       
   199 }
       
   200 
       
   201 sub generateHeader
       
   202 {
       
   203     my $className = shift;
       
   204     my $types = shift;
       
   205     my $constructor = shift;
       
   206     my $methods = shift;
       
   207     my $footer = shift;
       
   208 
       
   209     my $forwardHeaders = join("\n", sort(map("#include <" . $typeTransform{$_}->{"forwardHeader"} . ">", grep($typeTransform{$_}->{"forwardHeader"}, keys %{$types}))));
       
   210     my $forwardDeclarations = join("\n", sort(map("class " . $typeTransform{$_}->{"forward"} . ";", grep($typeTransform{$_}->{"forward"}, keys %{$types}))));
       
   211     my $methodsDeclarations = join("\n", keys %{$methods});
       
   212 
       
   213     my $headerBody = << "EOF";
       
   214 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
       
   215 // Use of this source code is governed by a BSD-style license that can be
       
   216 // found in the LICENSE file.
       
   217 #ifndef ${className}_h
       
   218 #define ${className}_h
       
   219 
       
   220 ${forwardHeaders}
       
   221 
       
   222 namespace $namespace {
       
   223 
       
   224 $forwardDeclarations
       
   225 
       
   226 class $className {
       
   227 public:
       
   228 $constructor
       
   229 
       
   230 $methodsDeclarations
       
   231 
       
   232 private:
       
   233 $footer
       
   234 };
       
   235 
       
   236 } // namespace $namespace
       
   237 #endif // !defined(${className}_h)
       
   238 
       
   239 EOF
       
   240     return $headerBody;
       
   241 }
       
   242 
       
   243 sub generateSource
       
   244 {
       
   245     my $className = shift;
       
   246     my $types = shift;
       
   247     my $methods = shift;
       
   248 
       
   249     my @sourceContent = split("\r", $licenseTemplate);
       
   250     push(@sourceContent, "\n#include \"config.h\"");
       
   251     push(@sourceContent, "#include \"$className.h\"");
       
   252     push(@sourceContent, "");
       
   253     push(@sourceContent, "#if ENABLE(INSPECTOR)");
       
   254     push(@sourceContent, "");
       
   255 
       
   256     my %headers;
       
   257     foreach my $type (keys %{$types}) {
       
   258         $headers{"#include \"" . $typeTransform{$type}->{"header"} . "\""} = 1 if !$typeTransform{$type}->{"header"} eq  "";
       
   259     }
       
   260     push(@sourceContent, sort keys %headers);
       
   261     push(@sourceContent, "");
       
   262     push(@sourceContent, "namespace $namespace {");
       
   263     push(@sourceContent, "");
       
   264     push(@sourceContent, @{$methods});
       
   265     push(@sourceContent, "");
       
   266     push(@sourceContent, "} // namespace $namespace");
       
   267     push(@sourceContent, "");
       
   268     push(@sourceContent, "#endif // ENABLE(INSPECTOR)");
       
   269     push(@sourceContent, "");
       
   270     return @sourceContent;
       
   271 }
       
   272 
       
   273 sub finish
       
   274 {
       
   275     my $object = shift;
       
   276 
       
   277     open(my $SOURCE, ">$outputDir/$frontendClassName.cpp") || die "Couldn't open file $outputDir/$frontendClassName.cpp";
       
   278     print $SOURCE join("\n", generateSource($frontendClassName, \%frontendTypes, \@frontendMethodsImpl));
       
   279     close($SOURCE);
       
   280     undef($SOURCE);
       
   281 
       
   282     open(my $HEADER, ">$outputHeadersDir/$frontendClassName.h") || die "Couldn't open file $outputHeadersDir/$frontendClassName.h";
       
   283     print $HEADER generateHeader($frontendClassName, \%frontendTypes, $frontendConstructor, \%frontendMethods, $frontendFooter);
       
   284     close($HEADER);
       
   285     undef($HEADER);
       
   286 
       
   287 }
       
   288 
       
   289 1;