Access GCController instance via GCController::singleton() instead of a free function
[WebKit-https.git] / Source / WebCore / bindings / scripts / InFilesCompiler.pm
1 #!/usr/bin/perl -w
2
3 # Copyright (C) 2011 Adam Barth <abarth@webkit.org>
4 #
5 # Redistribution and use in source and binary forms, with or without
6 # modification, are permitted provided that the following conditions
7 # are met:
8 # 1. Redistributions of source code must retain the above copyright
9 #    notice, this list of conditions and the following disclaimer.
10 # 2. Redistributions in binary form must reproduce the above copyright
11 #    notice, this list of conditions and the following disclaimer in the
12 #    documentation and/or other materials provided with the distribution.
13 #
14 # THIS SOFTWARE IS PROVIDED BY GOOGLE, INC. ``AS IS'' AND ANY
15 # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 # PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
18 # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21 # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22 # OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
25 #
26
27 use strict;
28
29 use Config;
30 use Getopt::Long;
31 use File::Path;
32 use File::Spec;
33 use IO::File;
34 use InFilesParser;
35
36 require Config;
37
38 package InFilesCompiler;
39
40 my $inputFile = "";
41 my $outputDir = ".";
42 my $defaultItemFactory;
43
44 my %parsedItems;
45 my %parsedParameters;
46
47 sub itemHandler($$$)
48 {
49     my ($itemName, $property, $value) = @_;
50
51     $parsedItems{$itemName} = { &$defaultItemFactory($itemName) } if !defined($parsedItems{$itemName});
52
53     return unless $property;
54
55     die "Unknown property $property for $itemName\n" if !defined($parsedItems{$itemName}{$property});
56     $parsedItems{$itemName}{$property} = $value;
57 }
58
59 sub parameterHandler($$)
60 {
61     my ($parameter, $value) = @_;
62
63     die "Unknown parameter $parameter\n" if !defined($parsedParameters{$parameter});
64     $parsedParameters{$parameter} = $value;
65 }
66
67 sub new()
68 {
69     my $object = shift;
70     my $reference = { };
71
72     my $defaultParametersRef = shift;
73     %parsedParameters = %{ $defaultParametersRef };
74     $defaultItemFactory = shift;
75
76     %parsedItems = ();
77
78     bless($reference, $object);
79     return $reference;
80 }
81
82 sub initializeFromCommandLine()
83 {
84     ::GetOptions(
85         'input=s' => \$inputFile,
86         'outputDir=s' => \$outputDir,
87     );
88
89     die "You must specify --input <file>" unless length($inputFile);
90
91     ::mkpath($outputDir);
92
93     # FIXME: Should we provide outputDir via an accessor?
94     return $outputDir;
95 }
96
97 sub compile()
98 {
99     my $object = shift;
100     my $generateCode = shift;
101
102     my $file = new IO::File;
103     open($file, $inputFile) or die "Failed to open file: $!";
104
105     my $InParser = InFilesParser->new();
106     $InParser->parse($file, \&parameterHandler, \&itemHandler);
107
108     close($file);
109     die "Failed to read from file: $inputFile" if (keys %parsedItems == 0);
110
111     &$generateCode(\%parsedParameters, \%parsedItems);
112 }
113
114 sub license()
115 {
116     return "/*
117  * THIS FILE WAS AUTOMATICALLY GENERATED, DO NOT EDIT.
118  *
119  * Copyright (C) 2011 Google Inc.  All rights reserved.
120  *
121  * Redistribution and use in source and binary forms, with or without
122  * modification, are permitted provided that the following conditions
123  * are met:
124  * 1. Redistributions of source code must retain the above copyright
125  *    notice, this list of conditions and the following disclaimer.
126  * 2. Redistributions in binary form must reproduce the above copyright
127  *    notice, this list of conditions and the following disclaimer in the
128  *    documentation and/or other materials provided with the distribution.
129  *
130  * THIS SOFTWARE IS PROVIDED BY GOOGLE, INC. ``AS IS'' AND ANY
131  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
132  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
133  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
134  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
135  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
136  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
137  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
138  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
139  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
140  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
141  */
142
143 ";
144 }
145
146 sub interfaceForItem($)
147 {
148     my $object = shift;
149     my $itemName = shift;
150
151     my $interfaceName = $parsedItems{$itemName}{"interfaceName"};
152     $interfaceName = $itemName unless $interfaceName;
153
154     return $interfaceName;
155 }
156
157 sub toMacroStyle($$)
158 {
159     my $object = shift;
160     my $camelCase = shift;
161
162     return "EVENT" if $camelCase eq "Event";
163     return "EVENT_TARGET" if $camelCase eq "EventTarget";
164     return "EXCEPTION" if $camelCase eq "Exception";
165
166     die "Ok, you got me. This script is really just a giant hack. (\$camelCase=${camelCase})";
167 }
168
169 sub preferredConditional()
170 {
171     my $object = shift;
172     my $conditional = shift;
173
174     my @conditionals = split('\\|', $conditional);
175     return $conditionals[0];
176 }
177
178 sub conditionalStringFromAttributeValue()
179 {
180     my $object = shift;
181     my $conditional = shift;
182     
183     return "ENABLE(" . join(') || ENABLE(', split('\\|', $conditional)) . ")";
184 }
185
186 sub generateInterfacesHeader()
187 {
188     my $object = shift;
189
190     my $F;
191     my $namespace = $parsedParameters{"namespace"};
192     my $outputFile = "$outputDir/${namespace}Interfaces.h";
193
194     open F, ">$outputFile" or die "Failed to open file: $!";
195
196     print F license();
197
198     print F "#ifndef ${namespace}Interfaces_h\n";
199     print F "#define ${namespace}Interfaces_h\n";
200     print F "\n";
201
202     my %unconditionalInterfaces = ();
203     my %interfacesByConditional = ();
204
205     for my $itemName (sort keys %parsedItems) {
206         my $conditional = $parsedItems{$itemName}{"conditional"};
207         my $interfaceName = $object->interfaceForItem($itemName);
208
209         if ($conditional) {
210             if (!defined($interfacesByConditional{$conditional})) {
211                 $interfacesByConditional{$conditional} = ();
212             }
213             $interfacesByConditional{$conditional}{$interfaceName} = 1;
214         } else {
215             $unconditionalInterfaces{$interfaceName} = 1
216         }
217     }
218
219     my $macroStyledNamespace = $object->toMacroStyle($namespace);
220
221     for my $conditional (sort keys %interfacesByConditional) {
222         my $preferredConditional = $object->preferredConditional($conditional);
223         print F "#if " . $object->conditionalStringFromAttributeValue($conditional) . "\n";
224         print F "#define DOM_${macroStyledNamespace}_INTERFACES_FOR_EACH_$preferredConditional(macro) \\\n";
225
226         for my $interface (sort keys %{ $interfacesByConditional{$conditional} }) {
227             next if defined($unconditionalInterfaces{$interface});
228             print F "    macro($interface) \\\n";
229         }
230
231         print F "// End of DOM_${macroStyledNamespace}_INTERFACES_FOR_EACH_$preferredConditional\n";
232         print F "#else\n";
233         print F "#define DOM_${macroStyledNamespace}_INTERFACES_FOR_EACH_$preferredConditional(macro)\n";
234         print F "#endif\n";
235         print F "\n";
236     }
237
238     print F "#define DOM_${macroStyledNamespace}_INTERFACES_FOR_EACH(macro) \\\n";
239     print F "    \\\n";
240     for my $interface (sort keys %unconditionalInterfaces) {
241             print F "    macro($interface) \\\n";
242     }
243     print F "    \\\n";
244     for my $conditional (sort keys %interfacesByConditional) {
245         my $preferredConditional = $object->preferredConditional($conditional);
246         print F "    DOM_${macroStyledNamespace}_INTERFACES_FOR_EACH_$preferredConditional(macro) \\\n";
247     }
248
249     print F "\n";
250     print F "#endif // ${namespace}Interfaces_h\n";
251
252     close F;
253 }
254
255 sub generateHeadersHeader()
256 {
257     my $object = shift;
258
259     my $F;
260     my $namespace = $parsedParameters{"namespace"};
261     my $outputFile = "$outputDir/${namespace}Headers.h";
262
263     open F, ">$outputFile" or die "Failed to open file: $!";
264
265     print F license();
266
267     print F "#ifndef ${namespace}Headers_h\n";
268     print F "#define ${namespace}Headers_h\n";
269     print F "\n";
270
271     my %includedInterfaces = ();
272
273     for my $itemName (sort keys %parsedItems) {
274         my $conditional = $parsedItems{$itemName}{"conditional"};
275         my $interfaceName = $object->interfaceForItem($itemName);
276
277         next if defined($includedInterfaces{$interfaceName});
278         $includedInterfaces{$interfaceName} = 1;
279
280         print F "#if " . $object->conditionalStringFromAttributeValue($conditional) . "\n" if $conditional;
281         print F "#include \"$interfaceName.h\"\n";
282         print F "#include \"JS$interfaceName.h\"\n";
283         print F "#endif\n" if $conditional;
284     }
285
286     print F "\n";
287     print F "#endif // ${namespace}Headers_h\n";
288
289     close F;
290 }
291
292 1;