| OLD | NEW |
| 1 #!/usr/bin/perl -w | 1 #!/usr/bin/perl -w |
| 2 # | 2 # |
| 3 # Copyright (C) 2005 Apple Computer, Inc. | 3 # Copyright (C) 2005 Apple Computer, Inc. |
| 4 # Copyright (C) 2006 Anders Carlsson <andersca@mac.com> | 4 # Copyright (C) 2006 Anders Carlsson <andersca@mac.com> |
| 5 # | 5 # |
| 6 # This file is part of WebKit | 6 # This file is part of WebKit |
| 7 # | 7 # |
| 8 # This library is free software; you can redistribute it and/or | 8 # This library is free software; you can redistribute it and/or |
| 9 # modify it under the terms of the GNU Library General Public | 9 # modify it under the terms of the GNU Library General Public |
| 10 # License as published by the Free Software Foundation; either | 10 # License as published by the Free Software Foundation; either |
| (...skipping 15 matching lines...) Expand all Loading... |
| 26 # to the DerivedSources directory. | 26 # to the DerivedSources directory. |
| 27 # This should also eventually be a build rule driven off of .idl files | 27 # This should also eventually be a build rule driven off of .idl files |
| 28 # however a build rule only solution is blocked by several radars: | 28 # however a build rule only solution is blocked by several radars: |
| 29 # <rdar://problems/4251781&4251785> | 29 # <rdar://problems/4251781&4251785> |
| 30 | 30 |
| 31 use strict; | 31 use strict; |
| 32 | 32 |
| 33 use File::Path; | 33 use File::Path; |
| 34 use File::Basename; | 34 use File::Basename; |
| 35 use Getopt::Long; | 35 use Getopt::Long; |
| 36 use Text::ParseWords; | |
| 37 use Cwd; | 36 use Cwd; |
| 38 | 37 |
| 39 use IDLParser; | 38 use IDLParser; |
| 40 use CodeGeneratorV8; | 39 use CodeGeneratorV8; |
| 40 use InterfaceMerger qw(computeIdlDependencies mergePartialInterfaces); |
| 41 | 41 |
| 42 my @idlDirectories; | 42 my @idlDirectories; |
| 43 my $outputDirectory; | 43 my $outputDirectory; |
| 44 my $outputHeadersDirectory; | 44 my $outputHeadersDirectory; |
| 45 my $defines; | 45 my $defines = ""; |
| 46 my $filename; | 46 my $filename; |
| 47 my $preprocessor; | 47 my $preprocessor; |
| 48 my $verbose; | 48 my $verbose; |
| 49 my $supplementalDependencyFile; | 49 my $dependenciesFile; |
| 50 my $additionalIdlFiles; | 50 my $additionalIdlFiles; |
| 51 my $idlAttributesFile; | 51 my $idlAttributesFile; |
| 52 my $writeFileOnlyIfChanged; | 52 my $writeFileOnlyIfChanged; |
| 53 | 53 |
| 54 GetOptions('include=s@' => \@idlDirectories, | 54 GetOptions('include=s@' => \@idlDirectories, |
| 55 'outputDir=s' => \$outputDirectory, | 55 'outputDir=s' => \$outputDirectory, |
| 56 'outputHeadersDir=s' => \$outputHeadersDirectory, | 56 'outputHeadersDir=s' => \$outputHeadersDirectory, |
| 57 'defines=s' => \$defines, | 57 'defines=s' => \$defines, |
| 58 'filename=s' => \$filename, | 58 'filename=s' => \$filename, |
| 59 'preprocessor=s' => \$preprocessor, | 59 'preprocessor=s' => \$preprocessor, |
| 60 'verbose' => \$verbose, | 60 'verbose' => \$verbose, |
| 61 'supplementalDependencyFile=s' => \$supplementalDependencyFile, | 61 'dependenciesFile=s' => \$dependenciesFile, |
| 62 'additionalIdlFiles=s' => \$additionalIdlFiles, | 62 'additionalIdlFiles=s' => \$additionalIdlFiles, |
| 63 'idlAttributesFile=s' => \$idlAttributesFile, | 63 'idlAttributesFile=s' => \$idlAttributesFile, |
| 64 'write-file-only-if-changed=s' => \$writeFileOnlyIfChanged); | 64 'write-file-only-if-changed=s' => \$writeFileOnlyIfChanged); |
| 65 | 65 |
| 66 my $targetIdlFile = $ARGV[0]; | 66 my $targetIdlFile = $ARGV[0]; |
| 67 | 67 |
| 68 die('Must specify input file.') unless defined($targetIdlFile); | 68 die('Must specify input file.') unless defined($targetIdlFile); |
| 69 die('Must specify output directory.') unless defined($outputDirectory); | 69 die('Must specify output directory.') unless defined($outputDirectory); |
| 70 $defines = "" unless defined($defines); | 70 $outputHeadersDirectory = $outputHeadersDirectory || $outputDirectory; |
| 71 | |
| 72 if (!$outputHeadersDirectory) { | |
| 73 $outputHeadersDirectory = $outputDirectory; | |
| 74 } | |
| 75 $targetIdlFile = Cwd::realpath($targetIdlFile); | 71 $targetIdlFile = Cwd::realpath($targetIdlFile); |
| 76 if ($verbose) { | 72 if ($verbose) { |
| 77 print "$targetIdlFile\n"; | 73 print "$targetIdlFile\n"; |
| 78 } | 74 } |
| 79 my $targetInterfaceName = fileparse(basename($targetIdlFile), ".idl"); | 75 my $targetInterfaceName = fileparse(basename($targetIdlFile), ".idl"); |
| 80 | 76 |
| 81 my $idlFound = 0; | 77 my $idlDependencies = []; |
| 82 my @supplementedIdlFiles; | 78 if ($dependenciesFile) { |
| 83 if ($supplementalDependencyFile) { | 79 $idlDependencies = computeIdlDependencies(basename($targetIdlFile), $depende
nciesFile, $additionalIdlFiles); |
| 84 # The format of a supplemental dependency file: | 80 if (!ref($idlDependencies)) { |
| 85 # | |
| 86 # DOMWindow.idl P.idl Q.idl R.idl | |
| 87 # Document.idl S.idl | |
| 88 # Event.idl | |
| 89 # ... | |
| 90 # | |
| 91 # The above indicates that DOMWindow.idl is supplemented by P.idl, Q.idl and
R.idl, | |
| 92 # Document.idl is supplemented by S.idl, and Event.idl is supplemented by no
IDLs. | |
| 93 # The IDL that supplements another IDL (e.g. P.idl) never appears in the dep
endency file. | |
| 94 open FH, "< $supplementalDependencyFile" or die "Cannot open $supplementalDe
pendencyFile\n"; | |
| 95 while (my $line = <FH>) { | |
| 96 my ($idlFile, @followingIdlFiles) = split(/\s+/, $line); | |
| 97 if ($idlFile and basename($idlFile) eq basename($targetIdlFile)) { | |
| 98 $idlFound = 1; | |
| 99 @supplementedIdlFiles = @followingIdlFiles; | |
| 100 } | |
| 101 } | |
| 102 close FH; | |
| 103 | |
| 104 # $additionalIdlFiles is list of IDL files which should not be included in | |
| 105 # DerivedSources*.cpp (i.e. they are not described in the supplemental | |
| 106 # dependency file) but should generate .h and .cpp files. | |
| 107 if (!$idlFound and $additionalIdlFiles) { | |
| 108 my @idlFiles = shellwords($additionalIdlFiles); | |
| 109 $idlFound = grep { $_ and basename($_) eq basename($targetIdlFile) } @id
lFiles; | |
| 110 } | |
| 111 | |
| 112 if (!$idlFound) { | |
| 113 # We generate empty .h and .cpp files just to tell build scripts that .h
and .cpp files are created. | 81 # We generate empty .h and .cpp files just to tell build scripts that .h
and .cpp files are created. |
| 114 generateEmptyHeaderAndCpp($targetInterfaceName, $outputHeadersDirectory,
$outputDirectory); | 82 generateEmptyHeaderAndCpp($targetInterfaceName, $outputHeadersDirectory,
$outputDirectory); |
| 115 exit 0; | 83 exit 0; |
| 116 } | 84 } |
| 117 } | 85 } |
| 118 | 86 |
| 119 # Parse the target IDL file. | 87 # Parse the target IDL file. |
| 120 my $targetParser = IDLParser->new(!$verbose); | 88 my $targetParser = IDLParser->new(!$verbose); |
| 121 my $targetDocument = $targetParser->Parse($targetIdlFile, $defines, $preprocesso
r); | 89 my $targetDocument = $targetParser->Parse($targetIdlFile, $defines, $preprocesso
r); |
| 122 | 90 |
| 123 if ($idlAttributesFile) { | 91 if ($idlAttributesFile) { |
| 124 my $idlAttributes = loadIDLAttributes($idlAttributesFile); | 92 my $idlAttributes = loadIDLAttributes($idlAttributesFile); |
| 125 checkIDLAttributes($idlAttributes, $targetDocument, basename($targetIdlFile)
); | 93 checkIDLAttributes($idlAttributes, $targetDocument, basename($targetIdlFile)
); |
| 126 } | 94 } |
| 127 | 95 |
| 128 foreach my $idlFile (@supplementedIdlFiles) { | 96 mergePartialInterfaces($targetDocument, $targetInterfaceName, $targetIdlFile, $i
dlDependencies, $defines, $preprocessor, $verbose); |
| 129 next if $idlFile eq $targetIdlFile; | |
| 130 | |
| 131 my $interfaceName = fileparse(basename($idlFile), ".idl"); | |
| 132 my $parser = IDLParser->new(!$verbose); | |
| 133 my $document = $parser->Parse($idlFile, $defines, $preprocessor); | |
| 134 | |
| 135 foreach my $interface (@{$document->interfaces}) { | |
| 136 if ($interface->isPartial and $interface->name eq $targetInterfaceName)
{ | |
| 137 my $targetDataNode; | |
| 138 foreach my $interface (@{$targetDocument->interfaces}) { | |
| 139 if ($interface->name eq $targetInterfaceName) { | |
| 140 $targetDataNode = $interface; | |
| 141 last; | |
| 142 } | |
| 143 } | |
| 144 die "Not found an interface ${targetInterfaceName} in ${targetInterf
aceName}.idl." unless defined $targetDataNode; | |
| 145 | |
| 146 # Support for attributes of partial interfaces. | |
| 147 foreach my $attribute (@{$interface->attributes}) { | |
| 148 # Record that this attribute is implemented by $interfaceName. | |
| 149 $attribute->signature->extendedAttributes->{"ImplementedBy"} = $
interfaceName; | |
| 150 | |
| 151 # Add interface-wide extended attributes to each attribute. | |
| 152 foreach my $extendedAttributeName (keys %{$interface->extendedAt
tributes}) { | |
| 153 $attribute->signature->extendedAttributes->{$extendedAttribu
teName} = $interface->extendedAttributes->{$extendedAttributeName}; | |
| 154 } | |
| 155 push(@{$targetDataNode->attributes}, $attribute); | |
| 156 } | |
| 157 | |
| 158 # Support for methods of partial interfaces. | |
| 159 foreach my $function (@{$interface->functions}) { | |
| 160 # Record that this method is implemented by $interfaceName. | |
| 161 $function->signature->extendedAttributes->{"ImplementedBy"} = $i
nterfaceName; | |
| 162 | |
| 163 # Add interface-wide extended attributes to each method. | |
| 164 foreach my $extendedAttributeName (keys %{$interface->extendedAt
tributes}) { | |
| 165 $function->signature->extendedAttributes->{$extendedAttribut
eName} = $interface->extendedAttributes->{$extendedAttributeName}; | |
| 166 } | |
| 167 push(@{$targetDataNode->functions}, $function); | |
| 168 } | |
| 169 | |
| 170 # Support for constants of partial interfaces. | |
| 171 foreach my $constant (@{$interface->constants}) { | |
| 172 # Record that this constant is implemented by $interfaceName. | |
| 173 $constant->extendedAttributes->{"ImplementedBy"} = $interfaceNam
e; | |
| 174 | |
| 175 # Add interface-wide extended attributes to each constant. | |
| 176 foreach my $extendedAttributeName (keys %{$interface->extendedAt
tributes}) { | |
| 177 $constant->extendedAttributes->{$extendedAttributeName} = $i
nterface->extendedAttributes->{$extendedAttributeName}; | |
| 178 } | |
| 179 push(@{$targetDataNode->constants}, $constant); | |
| 180 } | |
| 181 } else { | |
| 182 die "$idlFile is not a supplemental dependency of $targetIdlFile. Th
ere maybe a bug in the the supplemental dependency generator (preprocess_idls.py
).\n"; | |
| 183 } | |
| 184 } | |
| 185 } | |
| 186 | 97 |
| 187 # Generate desired output for the target IDL file. | 98 # Generate desired output for the target IDL file. |
| 188 my @dependentIdlFiles = ($targetDocument->fileName(), @supplementedIdlFiles); | 99 my @dependentIdlFiles = ($targetDocument->fileName(), @$idlDependencies); |
| 189 my $codeGenerator = CodeGeneratorV8->new($targetDocument, \@idlDirectories, $pre
processor, $defines, $verbose, \@dependentIdlFiles, $writeFileOnlyIfChanged); | 100 my $codeGenerator = CodeGeneratorV8->new($targetDocument, \@idlDirectories, $pre
processor, $defines, $verbose, \@dependentIdlFiles, $writeFileOnlyIfChanged); |
| 190 my $interfaces = $targetDocument->interfaces; | 101 my $interfaces = $targetDocument->interfaces; |
| 191 foreach my $interface (@$interfaces) { | 102 foreach my $interface (@$interfaces) { |
| 192 print "Generating bindings code for IDL interface \"" . $interface->name . "
\"...\n" if $verbose; | 103 print "Generating bindings code for IDL interface \"" . $interface->name . "
\"...\n" if $verbose; |
| 193 $codeGenerator->GenerateInterface($interface); | 104 $codeGenerator->GenerateInterface($interface); |
| 194 $codeGenerator->WriteData($interface, $outputDirectory, $outputHeadersDirect
ory); | 105 $codeGenerator->WriteData($interface, $outputDirectory, $outputHeadersDirect
ory); |
| 195 } | 106 } |
| 196 | 107 |
| 197 sub generateEmptyHeaderAndCpp | 108 sub generateEmptyHeaderAndCpp |
| 198 { | 109 { |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 291 last OUTER; | 202 last OUTER; |
| 292 } | 203 } |
| 293 } | 204 } |
| 294 } | 205 } |
| 295 if ($error) { | 206 if ($error) { |
| 296 die "IDL ATTRIBUTE CHECKER ERROR: $error | 207 die "IDL ATTRIBUTE CHECKER ERROR: $error |
| 297 If you want to add a new IDL attribute, you need to add it to bindings/scripts/I
DLAttributes.txt and add explanations to the Blink IDL document (http://chromium
.org/blink/webidl). | 208 If you want to add a new IDL attribute, you need to add it to bindings/scripts/I
DLAttributes.txt and add explanations to the Blink IDL document (http://chromium
.org/blink/webidl). |
| 298 "; | 209 "; |
| 299 } | 210 } |
| 300 } | 211 } |
| OLD | NEW |