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