|
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; |