Fix the issue that Web Audio test case fails on PR3.
[framework/web/webkit-efl.git] / Source / WebCore / bindings / scripts / preprocess-idls.pl
1 #!/usr/bin/perl -w
2 #
3 # Copyright (C) 2011 Google Inc.  All rights reserved.
4 #
5 # This library is free software; you can redistribute it and/or
6 # modify it under the terms of the GNU Library General Public
7 # License as published by the Free Software Foundation; either
8 # version 2 of the License, or (at your option) any later version.
9 #
10 # This library is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 # Library General Public License for more details.
14 #
15 # You should have received a copy of the GNU Library General Public License
16 # along with this library; see the file COPYING.LIB.  If not, write to
17 # the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 # Boston, MA 02110-1301, USA.
19 #
20
21 use strict;
22
23 use File::Basename;
24 use Getopt::Long;
25 use Cwd;
26
27 use IDLParser;
28
29 my $defines;
30 my $preprocessor;
31 my $verbose;
32 my $idlFilesList;
33 my $idlAttributesFile;
34 my $supplementalDependencyFile;
35 my $supplementalMakefileDeps;
36
37 GetOptions('defines=s' => \$defines,
38            'preprocessor=s' => \$preprocessor,
39            'verbose' => \$verbose,
40            'idlFilesList=s' => \$idlFilesList,
41            'idlAttributesFile=s' => \$idlAttributesFile,
42            'supplementalDependencyFile=s' => \$supplementalDependencyFile,
43            'supplementalMakefileDeps=s' => \$supplementalMakefileDeps);
44
45 die('Must specify #define macros using --defines.') unless defined($defines);
46 die('Must specify an output file using --supplementalDependencyFile.') unless defined($supplementalDependencyFile);
47 die('Must specify the file listing all IDLs using --idlFilesList.') unless defined($idlFilesList);
48
49 if ($verbose) {
50     print "Resolving [Supplemental=XXX] dependencies in all IDL files.\n";
51 }
52
53 open FH, "< $idlFilesList" or die "Cannot open $idlFilesList\n";
54 my @idlFiles = <FH>;
55 chomp(@idlFiles);
56 close FH;
57
58 # Parse all IDL files.
59 my %documents;
60 my %interfaceNameToIdlFile;
61 my %idlFileToInterfaceName;
62 foreach my $idlFile (@idlFiles) {
63     my $fullPath = Cwd::realpath($idlFile);
64     my $parser = IDLParser->new(!$verbose);
65     $documents{$fullPath} = $parser->Parse($idlFile, $defines, $preprocessor);
66     my $interfaceName = fileparse(basename($idlFile), ".idl");
67     $interfaceNameToIdlFile{$interfaceName} = $fullPath;
68     $idlFileToInterfaceName{$fullPath} = $interfaceName;
69 }
70
71 # Runs the IDL attribute checker.
72 my $idlAttributes = loadIDLAttributes($idlAttributesFile);
73 foreach my $idlFile (keys %documents) {
74     checkIDLAttributes($idlAttributes, $documents{$idlFile}, basename($idlFile));
75 }
76
77 # Resolves [Supplemental=XXX] dependencies.
78 my %supplementals;
79 foreach my $idlFile (keys %documents) {
80     $supplementals{$idlFile} = [];
81 }
82 foreach my $idlFile (keys %documents) {
83     foreach my $dataNode (@{$documents{$idlFile}->classes}) {
84         if ($dataNode->extendedAttributes->{"Supplemental"}) {
85             my $targetIdlFile = $interfaceNameToIdlFile{$dataNode->extendedAttributes->{"Supplemental"}};
86             push(@{$supplementals{$targetIdlFile}}, $idlFile);
87             # Treats as if this IDL file does not exist.
88             delete $supplementals{$idlFile};
89         }
90     }
91 }
92
93 # Outputs the dependency.
94 # The format of a supplemental dependency file:
95 #
96 # DOMWindow.idl P.idl Q.idl R.idl
97 # Document.idl S.idl
98 # Event.idl
99 # ...
100 #
101 # The above indicates that DOMWindow.idl is supplemented by P.idl, Q.idl and R.idl,
102 # Document.idl is supplemented by S.idl, and Event.idl is supplemented by no IDLs.
103 # The IDL that supplements another IDL (e.g. P.idl) never appears in the dependency file.
104
105 open FH, "> $supplementalDependencyFile" or die "Cannot open $supplementalDependencyFile\n";
106
107 foreach my $idlFile (sort keys %supplementals) {
108     print FH $idlFile, " @{$supplementals{$idlFile}}\n";
109 }
110 close FH;
111
112
113 if ($supplementalMakefileDeps) {
114     open MAKE_FH, "> $supplementalMakefileDeps" or die "Cannot open $supplementalMakefileDeps\n";
115     my @all_dependencies = [];
116     foreach my $idlFile (sort keys %supplementals) {
117         my $basename = $idlFileToInterfaceName{$idlFile};
118
119         my @dependencies = map { basename($_) } @{$supplementals{$idlFile}};
120
121         print MAKE_FH "JS${basename}.h: @{dependencies}\n";
122         print MAKE_FH "DOM${basename}.h: @{dependencies}\n";
123         print MAKE_FH "WebDOM${basename}.h: @{dependencies}\n";
124         foreach my $dependency (@dependencies) {
125             print MAKE_FH "${dependency}:\n";
126         }
127     }
128
129     close MAKE_FH;
130 }
131
132
133 sub loadIDLAttributes
134 {
135     my $idlAttributesFile = shift;
136
137     my %idlAttributes;
138     open FH, "<", $idlAttributesFile or die "Couldn't open $idlAttributesFile: $!";
139     while (my $line = <FH>) {
140         chomp $line;
141         next if $line =~ /^\s*#/;
142         next if $line =~ /^\s*$/;
143
144         if ($line =~ /^\s*([^=\s]*)\s*=?\s*(.*)/) {
145             my $name = $1;
146             $idlAttributes{$name} = {};
147             if ($2) {
148                 foreach my $rightValue (split /\|/, $2) {
149                     $rightValue =~ s/^\s*|\s*$//g;
150                     $rightValue = "VALUE_IS_MISSING" unless $rightValue;
151                     $idlAttributes{$name}{$rightValue} = 1;
152                 }
153             } else {
154                 $idlAttributes{$name}{"VALUE_IS_MISSING"} = 1;
155             }
156         } else {
157             die "The format of " . basename($idlAttributesFile) . " is wrong: line $.\n";
158         }
159     }
160     close FH;
161
162     return \%idlAttributes;
163 }
164
165 sub checkIDLAttributes
166 {
167     my $idlAttributes = shift;
168     my $document = shift;
169     my $idlFile = shift;
170
171     foreach my $dataNode (@{$document->classes}) {
172         checkIfIDLAttributesExists($idlAttributes, $dataNode->extendedAttributes, $idlFile);
173
174         foreach my $attribute (@{$dataNode->attributes}) {
175             checkIfIDLAttributesExists($idlAttributes, $attribute->signature->extendedAttributes, $idlFile);
176         }
177
178         foreach my $function (@{$dataNode->functions}) {
179             checkIfIDLAttributesExists($idlAttributes, $function->signature->extendedAttributes, $idlFile);
180             foreach my $parameter (@{$function->parameters}) {
181                 checkIfIDLAttributesExists($idlAttributes, $parameter->extendedAttributes, $idlFile);
182             }
183         }
184     }
185 }
186
187 sub checkIfIDLAttributesExists
188 {
189     my $idlAttributes = shift;
190     my $extendedAttributes = shift;
191     my $idlFile = shift;
192
193     my $error;
194     OUTER: for my $name (keys %$extendedAttributes) {
195         if (!exists $idlAttributes->{$name}) {
196             $error = "Unknown IDL attribute [$name] is found at $idlFile.";
197             last OUTER;
198         }
199         if ($idlAttributes->{$name}{"*"}) {
200             next;
201         }
202         for my $rightValue (split /\s*\|\s*/, $extendedAttributes->{$name}) {
203             if (!exists $idlAttributes->{$name}{$rightValue}) {
204                 $error = "Unknown IDL attribute [$name=" . $extendedAttributes->{$name} . "] is found at $idlFile.";
205                 last OUTER;
206             }
207         }
208     }
209     if ($error) {
210         die "IDL ATTRIBUTE CHECKER ERROR: $error
211 If you want to add a new IDL attribute, you need to add it to WebCore/bindings/scripts/IDLAttributes.txt and add explanations to the WebKit IDL document (https://trac.webkit.org/wiki/WebKitIDL).
212 ";
213     }
214 }