diff options
Diffstat (limited to 'Source/WebCore/bindings/scripts/preprocess-idls.pl')
-rw-r--r-- | Source/WebCore/bindings/scripts/preprocess-idls.pl | 111 |
1 files changed, 88 insertions, 23 deletions
diff --git a/Source/WebCore/bindings/scripts/preprocess-idls.pl b/Source/WebCore/bindings/scripts/preprocess-idls.pl index d65df33cf..a984ab7c5 100644 --- a/Source/WebCore/bindings/scripts/preprocess-idls.pl +++ b/Source/WebCore/bindings/scripts/preprocess-idls.pl @@ -19,10 +19,13 @@ # use strict; +use FindBin; +use lib $FindBin::Bin; use File::Basename; use Getopt::Long; use Cwd; +use Config; my $defines; my $preprocessor; @@ -30,7 +33,6 @@ my $idlFilesList; my $supplementalDependencyFile; my $windowConstructorsFile; my $workerGlobalScopeConstructorsFile; -my $sharedWorkerGlobalScopeConstructorsFile; my $dedicatedWorkerGlobalScopeConstructorsFile; my $supplementalMakefileDeps; @@ -40,7 +42,6 @@ GetOptions('defines=s' => \$defines, 'supplementalDependencyFile=s' => \$supplementalDependencyFile, 'windowConstructorsFile=s' => \$windowConstructorsFile, 'workerGlobalScopeConstructorsFile=s' => \$workerGlobalScopeConstructorsFile, - 'sharedWorkerGlobalScopeConstructorsFile=s' => \$sharedWorkerGlobalScopeConstructorsFile, 'dedicatedWorkerGlobalScopeConstructorsFile=s' => \$dedicatedWorkerGlobalScopeConstructorsFile, 'supplementalMakefileDeps=s' => \$supplementalMakefileDeps); @@ -48,13 +49,22 @@ die('Must specify #define macros using --defines.') unless defined($defines); die('Must specify an output file using --supplementalDependencyFile.') unless defined($supplementalDependencyFile); die('Must specify an output file using --windowConstructorsFile.') unless defined($windowConstructorsFile); die('Must specify an output file using --workerGlobalScopeConstructorsFile.') unless defined($workerGlobalScopeConstructorsFile); -die('Must specify an output file using --sharedWorkerGlobalScopeConstructorsFile.') unless defined($sharedWorkerGlobalScopeConstructorsFile); die('Must specify an output file using --dedicatedWorkerGlobalScopeConstructorsFile.') unless defined($dedicatedWorkerGlobalScopeConstructorsFile); die('Must specify the file listing all IDLs using --idlFilesList.') unless defined($idlFilesList); +$supplementalDependencyFile = CygwinPathIfNeeded($supplementalDependencyFile); +$windowConstructorsFile = CygwinPathIfNeeded($windowConstructorsFile); +$workerGlobalScopeConstructorsFile = CygwinPathIfNeeded($workerGlobalScopeConstructorsFile); +$dedicatedWorkerGlobalScopeConstructorsFile = CygwinPathIfNeeded($dedicatedWorkerGlobalScopeConstructorsFile); +$supplementalMakefileDeps = CygwinPathIfNeeded($supplementalMakefileDeps); + open FH, "< $idlFilesList" or die "Cannot open $idlFilesList\n"; -my @idlFiles = <FH>; -chomp(@idlFiles); +my @idlFilesIn = <FH>; +chomp(@idlFilesIn); +my @idlFiles = (); +foreach (@idlFilesIn) { + push @idlFiles, CygwinPathIfNeeded($_); +} close FH; my %interfaceNameToIdlFile; @@ -63,14 +73,13 @@ my %supplementalDependencies; my %supplementals; my $windowConstructorsCode = ""; my $workerGlobalScopeConstructorsCode = ""; -my $sharedWorkerGlobalScopeConstructorsCode = ""; my $dedicatedWorkerGlobalScopeConstructorsCode = ""; # Get rid of duplicates in idlFiles array. my %idlFileHash = map { $_, 1 } @idlFiles; # Populate $idlFileToInterfaceName and $interfaceNameToIdlFile. -foreach my $idlFile (keys %idlFileHash) { +foreach my $idlFile (sort keys %idlFileHash) { my $fullPath = Cwd::realpath($idlFile); my $interfaceName = fileparse(basename($idlFile), ".idl"); $idlFileToInterfaceName{$fullPath} = $interfaceName; @@ -87,6 +96,13 @@ foreach my $idlFile (sort keys %idlFileHash) { $supplementalDependencies{$fullPath} = [$partialInterfaceName]; next; } + + $supplementals{$fullPath} = []; + + # Skip if the IDL file does not contain an interface, a callback interface or an exception. + # The IDL may contain a dictionary. + next unless containsInterfaceOrExceptionFromIDL($idlFileContents); + my $interfaceName = fileparse(basename($idlFile), ".idl"); # Handle implements statements. my $implementedInterfaces = getImplementedInterfacesFromIDL($idlFileContents, $interfaceName); @@ -99,29 +115,41 @@ foreach my $idlFile (sort keys %idlFileHash) { $supplementalDependencies{$implementedIdlFile} = [$interfaceName]; } } - # Handle [NoInterfaceObject]. - unless (isCallbackInterfaceFromIDL($idlFileContents)) { - my $extendedAttributes = getInterfaceExtendedAttributesFromIDL($idlFileContents); - unless ($extendedAttributes->{"NoInterfaceObject"}) { - my @globalContexts = split("&", $extendedAttributes->{"GlobalContext"} || "DOMWindow"); + + # For every interface that is exposed in a given ECMAScript global environment and: + # - is a callback interface that has constants declared on it, or + # - is a non-callback interface that is not declared with the [NoInterfaceObject] extended attribute, a corresponding + # property must exist on the ECMAScript environment's global object. + # See https://heycam.github.io/webidl/#es-interfaces + my $extendedAttributes = getInterfaceExtendedAttributesFromIDL($idlFileContents); + unless ($extendedAttributes->{"NoInterfaceObject"}) { + if (!isCallbackInterfaceFromIDL($idlFileContents) || interfaceHasConstantAttribute($idlFileContents)) { + my $exposedAttribute = $extendedAttributes->{"Exposed"} || "Window"; + $exposedAttribute = substr($exposedAttribute, 1, -1) if substr($exposedAttribute, 0, 1) eq "("; + my @globalContexts = split(",", $exposedAttribute); my $attributeCode = GenerateConstructorAttribute($interfaceName, $extendedAttributes); - $windowConstructorsCode .= $attributeCode if grep(/^DOMWindow$/, @globalContexts); - $workerGlobalScopeConstructorsCode .= $attributeCode if grep(/^WorkerGlobalScope$/, @globalContexts); - $sharedWorkerGlobalScopeConstructorsCode .= $attributeCode if grep(/^SharedWorkerGlobalScope$/, @globalContexts); - $dedicatedWorkerGlobalScopeConstructorsCode .= $attributeCode if grep(/^DedicatedWorkerGlobalScope$/, @globalContexts); + foreach my $globalContext (@globalContexts) { + if ($globalContext eq "Window") { + $windowConstructorsCode .= $attributeCode; + } elsif ($globalContext eq "Worker") { + $workerGlobalScopeConstructorsCode .= $attributeCode; + } elsif ($globalContext eq "DedicatedWorker") { + $dedicatedWorkerGlobalScopeConstructorsCode .= $attributeCode; + } else { + die "Unsupported global context '$globalContext' used in [Exposed] at $idlFile"; + } + } } } - $supplementals{$fullPath} = []; } # Generate partial interfaces for Constructors. GeneratePartialInterface("DOMWindow", $windowConstructorsCode, $windowConstructorsFile); GeneratePartialInterface("WorkerGlobalScope", $workerGlobalScopeConstructorsCode, $workerGlobalScopeConstructorsFile); -GeneratePartialInterface("SharedWorkerGlobalScope", $sharedWorkerGlobalScopeConstructorsCode, $sharedWorkerGlobalScopeConstructorsFile); GeneratePartialInterface("DedicatedWorkerGlobalScope", $dedicatedWorkerGlobalScopeConstructorsCode, $dedicatedWorkerGlobalScopeConstructorsFile); # Resolves partial interfaces and implements dependencies. -foreach my $idlFile (keys %supplementalDependencies) { +foreach my $idlFile (sort keys %supplementalDependencies) { my $baseFiles = $supplementalDependencies{$idlFile}; foreach my $baseFile (@{$baseFiles}) { my $targetIdlFile = $interfaceNameToIdlFile{$baseFile}; @@ -165,6 +193,21 @@ if ($supplementalMakefileDeps) { WriteFileIfChanged($supplementalMakefileDeps, $makefileDeps); } +my $cygwinPathAdded; +sub CygwinPathIfNeeded +{ + my $path = shift; + if ($path && $Config{osname} eq "cygwin") { + if (not $cygwinPathAdded) { + $ENV{PATH} = "$ENV{PATH}:/cygdrive/c/cygwin/bin"; + $cygwinPathAdded = 1; + } + chomp($path = `cygpath -u '$path'`); + $path =~ s/[\r\n]//; + } + return $path; +} + sub WriteFileIfChanged { my $fileName = shift; @@ -202,8 +245,8 @@ sub GenerateConstructorAttribute my $code = " "; my @extendedAttributesList; - foreach my $attributeName (keys %{$extendedAttributes}) { - next unless ($attributeName eq "Conditional" || $attributeName eq "EnabledAtRuntime" || $attributeName eq "EnabledBySetting"); + foreach my $attributeName (sort keys %{$extendedAttributes}) { + next unless ($attributeName eq "Conditional" || $attributeName eq "EnabledAtRuntime" || $attributeName eq "EnabledForWorld" || $attributeName eq "EnabledBySetting" || $attributeName eq "PrivateIdentifier" || $attributeName eq "PublicIdentifier"); my $extendedAttribute = $attributeName; $extendedAttribute .= "=" . $extendedAttributes->{$attributeName} unless $extendedAttributes->{$attributeName} eq "VALUE_IS_MISSING"; push(@extendedAttributesList, $extendedAttribute); @@ -270,6 +313,16 @@ sub isCallbackInterfaceFromIDL return ($fileContents =~ /callback\s+interface\s+\w+/gs); } +sub containsInterfaceOrExceptionFromIDL +{ + my $fileContents = shift; + + return 1 if $fileContents =~ /\bcallback\s+interface\s+\w+/gs; + return 1 if $fileContents =~ /\binterface\s+\w+/gs; + return 1 if $fileContents =~ /\bexception\s+\w+/gs; + return 0; +} + sub trim { my $string = shift; @@ -283,8 +336,13 @@ sub getInterfaceExtendedAttributesFromIDL my $extendedAttributes = {}; - if ($fileContents =~ /\[(.*)\]\s+(interface|exception)\s+(\w+)/gs) { - my @parts = split(',', $1); + # Remove comments from fileContents before processing. + # FIX: Preference to use Regex::Common::comment, however it is not available on + # all build systems. + $fileContents =~ s/(?:(?:(?:\/\/)(?:[^\n]*)(?:\n))|(?:(?:\/\*)(?:(?:[^\*]+|\*(?!\/))*)(?:\*\/)))//g; + + if ($fileContents =~ /\[(.*)\]\s+(callback interface|interface|exception)\s+(\w+)/gs) { + my @parts = split(m/,(?![^()]*\))/, $1); foreach my $part (@parts) { my @keyValue = split('=', $part); my $key = trim($keyValue[0]); @@ -297,3 +355,10 @@ sub getInterfaceExtendedAttributesFromIDL return $extendedAttributes; } + +sub interfaceHasConstantAttribute +{ + my $fileContents = shift; + + return $fileContents =~ /\s+const[\s\w]+=\s+[\w]+;/gs; +} |