OLD | NEW |
---|---|
1 #!/usr/bin/perl -w | 1 #!/usr/bin/perl -w |
2 # | 2 # |
3 # Copyright (C) 2011 Google Inc. All rights reserved. | 3 # Copyright (C) 2011 Google Inc. All rights reserved. |
4 # | 4 # |
5 # This library is free software; you can redistribute it and/or | 5 # This library is free software; you can redistribute it and/or |
6 # modify it under the terms of the GNU Library General Public | 6 # modify it under the terms of the GNU Library General Public |
7 # License as published by the Free Software Foundation; either | 7 # License as published by the Free Software Foundation; either |
8 # version 2 of the License, or (at your option) any later version. | 8 # version 2 of the License, or (at your option) any later version. |
9 # | 9 # |
10 # This library is distributed in the hope that it will be useful, | 10 # This library is distributed in the hope that it will be useful, |
(...skipping 10 matching lines...) Expand all Loading... | |
21 use strict; | 21 use strict; |
22 | 22 |
23 use File::Basename; | 23 use File::Basename; |
24 use Getopt::Long; | 24 use Getopt::Long; |
25 use Cwd; | 25 use Cwd; |
26 | 26 |
27 my $defines; | 27 my $defines; |
28 my $preprocessor; | 28 my $preprocessor; |
29 my $idlFilesList; | 29 my $idlFilesList; |
30 my $supplementalDependencyFile; | 30 my $supplementalDependencyFile; |
31 my $windowConstructorsSupplementalFile; | |
31 my $supplementalMakefileDeps; | 32 my $supplementalMakefileDeps; |
32 | 33 |
33 GetOptions('defines=s' => \$defines, | 34 GetOptions('defines=s' => \$defines, |
34 'preprocessor=s' => \$preprocessor, | 35 'preprocessor=s' => \$preprocessor, |
35 'idlFilesList=s' => \$idlFilesList, | 36 'idlFilesList=s' => \$idlFilesList, |
36 'supplementalDependencyFile=s' => \$supplementalDependencyFile, | 37 'supplementalDependencyFile=s' => \$supplementalDependencyFile, |
38 'windowConstructorsSupplementalFile=s' => \$windowConstructorsSupplem entalFile, | |
37 'supplementalMakefileDeps=s' => \$supplementalMakefileDeps); | 39 'supplementalMakefileDeps=s' => \$supplementalMakefileDeps); |
38 | 40 |
39 die('Must specify an output file using --supplementalDependencyFile.') unless de fined($supplementalDependencyFile); | 41 die('Must specify an output file using --supplementalDependencyFile.') unless de fined($supplementalDependencyFile); |
42 die('Must specify an output file using --windowConstructorsSupplementalFile.') u nless defined($windowConstructorsSupplementalFile); | |
40 die('Must specify the file listing all IDLs using --idlFilesList.') unless defin ed($idlFilesList); | 43 die('Must specify the file listing all IDLs using --idlFilesList.') unless defin ed($idlFilesList); |
41 | 44 |
42 open FH, "< $idlFilesList" or die "Cannot open $idlFilesList\n"; | 45 open FH, "< $idlFilesList" or die "Cannot open $idlFilesList\n"; |
43 my @idlFiles = <FH>; | 46 my @idlFiles = <FH>; |
44 chomp(@idlFiles); | 47 chomp(@idlFiles); |
45 close FH; | 48 close FH; |
46 | 49 |
47 # Parse all IDL files. | 50 # Parse all IDL files. |
48 my %interfaceNameToIdlFile; | 51 my %interfaceNameToIdlFile; |
49 my %idlFileToInterfaceName; | 52 my %idlFileToInterfaceName; |
50 my %supplementalDependencies; | 53 my %supplementalDependencies; |
51 my %supplementals; | 54 my %supplementals; |
55 my $constructorAttributesCode = ""; | |
52 foreach my $idlFile (@idlFiles) { | 56 foreach my $idlFile (@idlFiles) { |
53 my $fullPath = Cwd::realpath($idlFile); | 57 my $fullPath = Cwd::realpath($idlFile); |
54 my $partialInterfaceName = getPartialInterfaceNameFromIDLFile($fullPath); | 58 my $idlFileContents = getFileContents($fullPath); |
59 my $partialInterfaceName = getPartialInterfaceNameFromIDL($idlFileContents); | |
55 if ($partialInterfaceName) { | 60 if ($partialInterfaceName) { |
56 $supplementalDependencies{$fullPath} = $partialInterfaceName; | 61 $supplementalDependencies{$fullPath} = $partialInterfaceName; |
62 next; | |
57 } | 63 } |
58 my $interfaceName = fileparse(basename($idlFile), ".idl"); | 64 my $interfaceName = fileparse(basename($idlFile), ".idl"); |
65 unless (isCallbackInterfaceFromIDL($idlFileContents)) { | |
66 my $extendedAttributes = getInterfaceExtendedAttributesFromIDL($idlFileC ontents); | |
67 unless ($extendedAttributes->{"NoInterfaceObject"}) { | |
68 $constructorAttributesCode .= GenerateConstructorAttribute($interfac eName, $extendedAttributes); | |
69 } | |
70 } | |
59 $interfaceNameToIdlFile{$interfaceName} = $fullPath; | 71 $interfaceNameToIdlFile{$interfaceName} = $fullPath; |
60 $idlFileToInterfaceName{$fullPath} = $interfaceName; | 72 $idlFileToInterfaceName{$fullPath} = $interfaceName; |
61 $supplementals{$fullPath} = []; | 73 $supplementals{$fullPath} = []; |
62 } | 74 } |
63 | 75 |
76 # Generate DOMWindow Constructors partial interface. | |
77 open PARTIAL_WINDOW_FH, "> $windowConstructorsSupplementalFile" or die "Cannot o pen $windowConstructorsSupplementalFile\n"; | |
78 print PARTIAL_WINDOW_FH "partial interface DOMWindow {\n"; | |
79 print PARTIAL_WINDOW_FH $constructorAttributesCode; | |
80 print PARTIAL_WINDOW_FH "};\n"; | |
81 close PARTIAL_WINDOW_FH; | |
82 $supplementalDependencies{$windowConstructorsSupplementalFile} = "DOMWindow"; | |
haraken
2013/05/07 01:12:06
Clever!
| |
83 | |
64 # Resolves partial interfaces dependencies. | 84 # Resolves partial interfaces dependencies. |
65 foreach my $idlFile (keys %supplementalDependencies) { | 85 foreach my $idlFile (keys %supplementalDependencies) { |
66 my $baseFile = $supplementalDependencies{$idlFile}; | 86 my $baseFile = $supplementalDependencies{$idlFile}; |
67 my $targetIdlFile = $interfaceNameToIdlFile{$baseFile}; | 87 my $targetIdlFile = $interfaceNameToIdlFile{$baseFile}; |
68 push(@{$supplementals{$targetIdlFile}}, $idlFile); | 88 push(@{$supplementals{$targetIdlFile}}, $idlFile); |
69 delete $supplementals{$idlFile}; | 89 delete $supplementals{$idlFile}; |
70 } | 90 } |
71 | 91 |
72 # Outputs the dependency. | 92 # Outputs the dependency. |
73 # The format of a supplemental dependency file: | 93 # The format of a supplemental dependency file: |
74 # | 94 # |
75 # DOMWindow.idl P.idl Q.idl R.idl | 95 # DOMWindow.idl P.idl Q.idl R.idl |
76 # Document.idl S.idl | 96 # Document.idl S.idl |
77 # Event.idl | 97 # Event.idl |
78 # ... | 98 # ... |
79 # | 99 # |
80 # The above indicates that DOMWindow.idl is supplemented by P.idl, Q.idl and R.i dl, | 100 # The above indicates that DOMWindow.idl is supplemented by P.idl, Q.idl and R.i dl, |
81 # Document.idl is supplemented by S.idl, and Event.idl is supplemented by no IDL s. | 101 # Document.idl is supplemented by S.idl, and Event.idl is supplemented by no IDL s. |
82 # The IDL that supplements another IDL (e.g. P.idl) never appears in the depende ncy file. | 102 # The IDL that supplements another IDL (e.g. P.idl) never appears in the depende ncy file. |
83 | 103 |
84 open FH, "> $supplementalDependencyFile" or die "Cannot open $supplementalDepend encyFile\n"; | 104 open FH, "> $supplementalDependencyFile" or die "Cannot open $supplementalDepend encyFile\n"; |
85 | 105 |
86 foreach my $idlFile (sort keys %supplementals) { | 106 foreach my $idlFile (sort keys %supplementals) { |
87 print FH $idlFile, " @{$supplementals{$idlFile}}\n"; | 107 print FH $idlFile, " @{$supplementals{$idlFile}}\n"; |
88 } | 108 } |
89 close FH; | 109 close FH; |
90 | 110 |
91 | |
92 if ($supplementalMakefileDeps) { | 111 if ($supplementalMakefileDeps) { |
93 open MAKE_FH, "> $supplementalMakefileDeps" or die "Cannot open $supplementa lMakefileDeps\n"; | 112 open MAKE_FH, "> $supplementalMakefileDeps" or die "Cannot open $supplementa lMakefileDeps\n"; |
94 my @all_dependencies = []; | 113 my @all_dependencies = []; |
95 foreach my $idlFile (sort keys %supplementals) { | 114 foreach my $idlFile (sort keys %supplementals) { |
96 my $basename = $idlFileToInterfaceName{$idlFile}; | 115 my $basename = $idlFileToInterfaceName{$idlFile}; |
97 | 116 |
98 my @dependencies = map { basename($_) } @{$supplementals{$idlFile}}; | 117 my @dependencies = map { basename($_) } @{$supplementals{$idlFile}}; |
99 | 118 |
100 print MAKE_FH "JS${basename}.h: @{dependencies}\n"; | 119 print MAKE_FH "JS${basename}.h: @{dependencies}\n"; |
101 print MAKE_FH "DOM${basename}.h: @{dependencies}\n"; | 120 print MAKE_FH "DOM${basename}.h: @{dependencies}\n"; |
102 print MAKE_FH "WebDOM${basename}.h: @{dependencies}\n"; | 121 print MAKE_FH "WebDOM${basename}.h: @{dependencies}\n"; |
103 foreach my $dependency (@dependencies) { | 122 foreach my $dependency (@dependencies) { |
104 print MAKE_FH "${dependency}:\n"; | 123 print MAKE_FH "${dependency}:\n"; |
105 } | 124 } |
106 } | 125 } |
107 | 126 |
108 close MAKE_FH; | 127 close MAKE_FH; |
109 } | 128 } |
110 | 129 |
130 sub GenerateConstructorAttribute | |
131 { | |
132 my $interfaceName = shift; | |
133 my $extendedAttributes = shift; | |
111 | 134 |
112 sub getPartialInterfaceNameFromIDLFile | 135 my $code = " "; |
136 my @extendedAttributesList; | |
137 foreach my $attributeName (keys $extendedAttributes) { | |
138 next unless ($attributeName eq "Conditional" || $attributeName eq "Enabled AtRuntime" || $attributeName eq "EnabledPerContext"); | |
139 my $extendedAttribute = $attributeName; | |
140 $extendedAttribute .= "=" . $extendedAttributes->{$attributeName} unless $ extendedAttributes->{$attributeName} eq "VALUE_IS_MISSING"; | |
141 push(@extendedAttributesList, $extendedAttribute); | |
142 } | |
143 $code .= "[" . join(', ', @extendedAttributesList) . "] " if @extendedAttrib utesList; | |
144 | |
145 my $originalInterfaceName = $interfaceName; | |
146 $interfaceName = $extendedAttributes->{"InterfaceName"} if $extendedAttribut es->{"InterfaceName"}; | |
147 $interfaceName = $extendedAttributes->{"ConstructorPrefix"} . $interfaceName if $extendedAttributes->{"ConstructorPrefix"}; | |
148 $code .= "attribute " . $originalInterfaceName . "Constructor $interfaceName ;\n"; | |
149 | |
150 # In addition to the regular property, for every [NamedConstructor] extended attribute on an interface, | |
151 # a corresponding property MUST exist on the ECMAScript global object. | |
152 if ($extendedAttributes->{"NamedConstructor"}) { | |
153 my $constructorName = $extendedAttributes->{"NamedConstructor"}; | |
154 $constructorName =~ s/\(.*//g; # Extract function name. | |
155 $code .= " "; | |
156 $code .= "[" . join(', ', @extendedAttributesList) . "] " if @extendedAt tributesList; | |
157 $code .= "attribute " . $originalInterfaceName . "ConstructorConstructor $constructorName;\n"; | |
158 } | |
159 return $code; | |
160 } | |
161 | |
162 sub getFileContents | |
113 { | 163 { |
114 my $idlFile = shift; | 164 my $idlFile = shift; |
115 | 165 |
116 open FILE, "<", $idlFile; | 166 open FILE, "<", $idlFile; |
117 my @lines = <FILE>; | 167 my @lines = <FILE>; |
118 close FILE; | 168 close FILE; |
119 | 169 |
120 my $fileContents = join('', @lines); | 170 # Filter out preprocessor lines. |
171 @lines = grep(!/^\s*#/, @lines); | |
172 | |
173 return join('', @lines); | |
174 } | |
175 | |
176 sub getPartialInterfaceNameFromIDL | |
177 { | |
178 my $fileContents = shift; | |
179 | |
121 if ($fileContents =~ /partial\s+interface\s+(\w+)/gs) { | 180 if ($fileContents =~ /partial\s+interface\s+(\w+)/gs) { |
122 return $1; | 181 return $1; |
123 } | 182 } |
124 } | 183 } |
184 | |
185 sub isCallbackInterfaceFromIDL | |
186 { | |
187 my $fileContents = shift; | |
188 return ($fileContents =~ /callback\s+interface\s+\w+/gs); | |
189 } | |
190 | |
191 sub trim | |
192 { | |
193 my $string = shift; | |
194 $string =~ s/^\s+|\s+$//g; | |
195 return $string; | |
196 } | |
197 | |
198 sub getInterfaceExtendedAttributesFromIDL | |
199 { | |
200 my $fileContents = shift; | |
201 | |
202 my $extendedAttributes = {}; | |
203 | |
204 if ($fileContents =~ /\[(.*)\]\s+(interface|exception)\s+(\w+)/gs) { | |
205 my @parts = split(',', $1); | |
206 foreach my $part (@parts) { | |
207 my @keyValue = split('=', $part); | |
208 my $key = trim($keyValue[0]); | |
209 next unless length($key); | |
210 my $value = "VALUE_IS_MISSING"; | |
211 $value = trim($keyValue[1]) if @keyValue > 1; | |
212 $extendedAttributes->{$key} = $value; | |
213 } | |
214 } | |
215 | |
216 return $extendedAttributes; | |
217 } | |
OLD | NEW |