123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854 |
- #
- # WebKit IDL parser
- #
- # Copyright (C) 2005 Nikolas Zimmermann <wildfox@kde.org>
- # Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
- # Copyright (C) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
- # Copyright (C) 2009 Cameron McCormack <cam@mcc.id.au>
- # Copyright (C) Research In Motion Limited 2010. All rights reserved.
- # Copyright (C) 2013 Samsung Electronics. All rights reserved.
- #
- # This library is free software; you can redistribute it and/or
- # modify it under the terms of the GNU Library General Public
- # License as published by the Free Software Foundation; either
- # version 2 of the License, or (at your option) any later version.
- #
- # This library is distributed in the hope that it will be useful,
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- # Library General Public License for more details.
- #
- # You should have received a copy of the GNU Library General Public License
- # along with this library; see the file COPYING.LIB. If not, write to
- # the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- # Boston, MA 02110-1301, USA.
- #
- package CodeGenerator;
- use strict;
- use File::Find;
- my $useDocument = "";
- my $useGenerator = "";
- my $useOutputDir = "";
- my $useOutputHeadersDir = "";
- my $useDirectories = "";
- my $useLayerOnTop = 0;
- my $preprocessor;
- my $writeDependencies = 0;
- my $defines = "";
- my $targetIdlFilePath = "";
- my $codeGenerator = 0;
- my $verbose = 0;
- my %numericTypeHash = ("int" => 1, "short" => 1, "long" => 1, "long long" => 1,
- "unsigned int" => 1, "unsigned short" => 1,
- "unsigned long" => 1, "unsigned long long" => 1,
- "float" => 1, "double" => 1, "byte" => 1,
- "octet" => 1);
- my %primitiveTypeHash = ( "boolean" => 1, "void" => 1, "Date" => 1);
- my %stringTypeHash = ("DOMString" => 1, "AtomicString" => 1);
- # WebCore types used directly in IDL files.
- my %webCoreTypeHash = (
- "CompareHow" => 1,
- "SerializedScriptValue" => 1,
- "Dictionary" => 1
- );
- my %enumTypeHash = ();
- my %nonPointerTypeHash = ("DOMTimeStamp" => 1, "CompareHow" => 1);
- my %svgAnimatedTypeHash = ("SVGAnimatedAngle" => 1, "SVGAnimatedBoolean" => 1,
- "SVGAnimatedEnumeration" => 1, "SVGAnimatedInteger" => 1,
- "SVGAnimatedLength" => 1, "SVGAnimatedLengthList" => 1,
- "SVGAnimatedNumber" => 1, "SVGAnimatedNumberList" => 1,
- "SVGAnimatedPreserveAspectRatio" => 1,
- "SVGAnimatedRect" => 1, "SVGAnimatedString" => 1,
- "SVGAnimatedTransformList" => 1);
- my %svgAttributesInHTMLHash = ("class" => 1, "id" => 1, "onabort" => 1, "onclick" => 1,
- "onerror" => 1, "onload" => 1, "onmousedown" => 1,
- "onmouseenter" => 1, "onmouseleave" => 1,
- "onmousemove" => 1, "onmouseout" => 1, "onmouseover" => 1,
- "onmouseup" => 1, "onresize" => 1, "onscroll" => 1,
- "onunload" => 1);
- my %svgTypeNeedingTearOff = (
- "SVGAngle" => "SVGPropertyTearOff<SVGAngle>",
- "SVGLength" => "SVGPropertyTearOff<SVGLength>",
- "SVGLengthList" => "SVGListPropertyTearOff<SVGLengthList>",
- "SVGMatrix" => "SVGPropertyTearOff<SVGMatrix>",
- "SVGNumber" => "SVGPropertyTearOff<float>",
- "SVGNumberList" => "SVGListPropertyTearOff<SVGNumberList>",
- "SVGPathSegList" => "SVGPathSegListPropertyTearOff",
- "SVGPoint" => "SVGPropertyTearOff<FloatPoint>",
- "SVGPointList" => "SVGListPropertyTearOff<SVGPointList>",
- "SVGPreserveAspectRatio" => "SVGPropertyTearOff<SVGPreserveAspectRatio>",
- "SVGRect" => "SVGPropertyTearOff<FloatRect>",
- "SVGStringList" => "SVGStaticListPropertyTearOff<SVGStringList>",
- "SVGTransform" => "SVGPropertyTearOff<SVGTransform>",
- "SVGTransformList" => "SVGTransformListPropertyTearOff"
- );
- my %svgTypeWithWritablePropertiesNeedingTearOff = (
- "SVGPoint" => 1,
- "SVGMatrix" => 1
- );
- # Cache of IDL file pathnames.
- my $idlFiles;
- my $cachedInterfaces = {};
- # Default constructor
- sub new
- {
- my $object = shift;
- my $reference = { };
- $useDirectories = shift;
- $useGenerator = shift;
- $useOutputDir = shift;
- $useOutputHeadersDir = shift;
- $useLayerOnTop = shift;
- $preprocessor = shift;
- $writeDependencies = shift;
- $verbose = shift;
- $targetIdlFilePath = shift;
- bless($reference, $object);
- return $reference;
- }
- sub ProcessDocument
- {
- my $object = shift;
- $useDocument = shift;
- $defines = shift;
- my $ifaceName = "CodeGenerator" . $useGenerator;
- require $ifaceName . ".pm";
- %enumTypeHash = map { $_->name => $_->values } @{$useDocument->enumerations};
- # Dynamically load external code generation perl module
- $codeGenerator = $ifaceName->new($object, $useLayerOnTop, $preprocessor, $writeDependencies, $verbose, $targetIdlFilePath);
- unless (defined($codeGenerator)) {
- my $interfaces = $useDocument->interfaces;
- foreach my $interface (@$interfaces) {
- print "Skipping $useGenerator code generation for IDL interface \"" . $interface->name . "\".\n" if $verbose;
- }
- return;
- }
- my $interfaces = $useDocument->interfaces;
- foreach my $interface (@$interfaces) {
- print "Generating $useGenerator bindings code for IDL interface \"" . $interface->name . "\"...\n" if $verbose;
- $codeGenerator->GenerateInterface($interface, $defines);
- $codeGenerator->WriteData($interface, $useOutputDir, $useOutputHeadersDir);
- }
- }
- sub FileNamePrefix
- {
- my $object = shift;
- my $ifaceName = "CodeGenerator" . $useGenerator;
- require $ifaceName . ".pm";
- # Dynamically load external code generation perl module
- $codeGenerator = $ifaceName->new($object, $useLayerOnTop, $preprocessor, $writeDependencies, $verbose);
- return $codeGenerator->FileNamePrefix();
- }
- sub UpdateFile
- {
- my $object = shift;
- my $fileName = shift;
- my $contents = shift;
- open FH, "> $fileName" or die "Couldn't open $fileName: $!\n";
- print FH $contents;
- close FH;
- }
- sub ForAllParents
- {
- my $object = shift;
- my $interface = shift;
- my $beforeRecursion = shift;
- my $afterRecursion = shift;
- my $recurse;
- $recurse = sub {
- my $currentInterface = shift;
- for (@{$currentInterface->parents}) {
- my $interfaceName = $_;
- my $parentInterface = $object->ParseInterface($interfaceName);
- if ($beforeRecursion) {
- &$beforeRecursion($parentInterface) eq 'prune' and next;
- }
- &$recurse($parentInterface);
- &$afterRecursion($parentInterface) if $afterRecursion;
- }
- };
- &$recurse($interface);
- }
- sub AddMethodsConstantsAndAttributesFromParentInterfaces
- {
- # Add to $interface all of its inherited interface members, except for those
- # inherited through $interface's first listed parent. If an array reference
- # is passed in as $parents, the names of all ancestor interfaces visited
- # will be appended to the array. If $collectDirectParents is true, then
- # even the names of $interface's first listed parent and its ancestors will
- # be appended to $parents.
- my $object = shift;
- my $interface = shift;
- my $parents = shift;
- my $collectDirectParents = shift;
- my $first = 1;
- $object->ForAllParents($interface, sub {
- my $currentInterface = shift;
- if ($first) {
- # Ignore first parent class, already handled by the generation itself.
- $first = 0;
- if ($collectDirectParents) {
- # Just collect the names of the direct ancestor interfaces,
- # if necessary.
- push(@$parents, $currentInterface->name);
- $object->ForAllParents($currentInterface, sub {
- my $currentInterface = shift;
- push(@$parents, $currentInterface->name);
- }, undef);
- }
- # Prune the recursion here.
- return 'prune';
- }
- # Collect the name of this additional parent.
- push(@$parents, $currentInterface->name) if $parents;
- print " | |> -> Inheriting "
- . @{$currentInterface->constants} . " constants, "
- . @{$currentInterface->functions} . " functions, "
- . @{$currentInterface->attributes} . " attributes...\n | |>\n" if $verbose;
- # Add this parent's members to $interface.
- push(@{$interface->constants}, @{$currentInterface->constants});
- push(@{$interface->functions}, @{$currentInterface->functions});
- push(@{$interface->attributes}, @{$currentInterface->attributes});
- });
- }
- sub FindSuperMethod
- {
- my ($object, $interface, $functionName) = @_;
- my $indexer;
- $object->ForAllParents($interface, undef, sub {
- my $currentInterface = shift;
- foreach my $function (@{$currentInterface->functions}) {
- if ($function->signature->name eq $functionName) {
- $indexer = $function->signature;
- return 'prune';
- }
- }
- });
- return $indexer;
- }
- sub IDLFileForInterface
- {
- my $object = shift;
- my $interfaceName = shift;
- unless ($idlFiles) {
- my $sourceRoot = $ENV{SOURCE_ROOT};
- my @directories = map { $_ = "$sourceRoot/$_" if $sourceRoot && -d "$sourceRoot/$_"; $_ } @$useDirectories;
- push(@directories, ".");
- $idlFiles = { };
- my $wanted = sub {
- $idlFiles->{$1} = $File::Find::name if /^([A-Z].*)\.idl$/;
- $File::Find::prune = 1 if /^\../;
- };
- find($wanted, @directories);
- }
- return $idlFiles->{$interfaceName};
- }
- sub ParseInterface
- {
- my $object = shift;
- my $interfaceName = shift;
- return undef if $interfaceName eq 'Object';
- if (exists $cachedInterfaces->{$interfaceName}) {
- return $cachedInterfaces->{$interfaceName};
- }
- # Step #1: Find the IDL file associated with 'interface'
- my $filename = $object->IDLFileForInterface($interfaceName)
- or die("Could NOT find IDL file for interface \"$interfaceName\"!\n");
- print " | |> Parsing parent IDL \"$filename\" for interface \"$interfaceName\"\n" if $verbose;
- # Step #2: Parse the found IDL file (in quiet mode).
- my $parser = IDLParser->new(1);
- my $document = $parser->Parse($filename, $defines, $preprocessor);
- foreach my $interface (@{$document->interfaces}) {
- if ($interface->name eq $interfaceName) {
- $cachedInterfaces->{$interfaceName} = $interface;
- return $interface;
- }
- }
- die("Could NOT find interface definition for $interfaceName in $filename");
- }
- # Helpers for all CodeGenerator***.pm modules
- sub SkipIncludeHeader
- {
- my $object = shift;
- my $type = shift;
- return 1 if $object->IsPrimitiveType($type);
- # Special case: SVGPoint.h / SVGNumber.h do not exist.
- return 1 if $type eq "SVGPoint" or $type eq "SVGNumber";
- return 0;
- }
- sub IsConstructorTemplate
- {
- my $object = shift;
- my $interface = shift;
- my $template = shift;
- return $interface->extendedAttributes->{"ConstructorTemplate"} && $interface->extendedAttributes->{"ConstructorTemplate"} eq $template;
- }
- sub IsNumericType
- {
- my $object = shift;
- my $type = shift;
- return 1 if $numericTypeHash{$type};
- return 0;
- }
- sub IsPrimitiveType
- {
- my $object = shift;
- my $type = shift;
- return 1 if $primitiveTypeHash{$type};
- return 1 if $numericTypeHash{$type};
- return 0;
- }
- sub IsStringType
- {
- my $object = shift;
- my $type = shift;
- return 1 if $stringTypeHash{$type};
- return 0;
- }
- sub IsEnumType
- {
- my $object = shift;
- my $type = shift;
- return 1 if exists $enumTypeHash{$type};
- return 0;
- }
- sub ValidEnumValues
- {
- my $object = shift;
- my $type = shift;
- return @{$enumTypeHash{$type}};
- }
- sub IsNonPointerType
- {
- my $object = shift;
- my $type = shift;
- return 1 if $nonPointerTypeHash{$type} or $primitiveTypeHash{$type} or $numericTypeHash{$type};
- return 0;
- }
- sub IsSVGTypeNeedingTearOff
- {
- my $object = shift;
- my $type = shift;
- return 1 if exists $svgTypeNeedingTearOff{$type};
- return 0;
- }
- sub IsSVGTypeWithWritablePropertiesNeedingTearOff
- {
- my $object = shift;
- my $type = shift;
- return 1 if $svgTypeWithWritablePropertiesNeedingTearOff{$type};
- return 0;
- }
- sub IsTypedArrayType
- {
- my $object = shift;
- my $type = shift;
- return 1 if (($type eq "ArrayBuffer") or ($type eq "ArrayBufferView"));
- return 1 if (($type eq "Uint8Array") or ($type eq "Uint8ClampedArray") or ($type eq "Uint16Array") or ($type eq "Uint32Array"));
- return 1 if (($type eq "Int8Array") or ($type eq "Int16Array") or ($type eq "Int32Array"));
- return 1 if (($type eq "Float32Array") or ($type eq "Float64Array"));
- return 0;
- }
- sub IsRefPtrType
- {
- my $object = shift;
- my $type = shift;
- return 0 if $object->IsPrimitiveType($type);
- return 0 if $object->GetArrayType($type);
- return 0 if $object->GetSequenceType($type);
- return 0 if $type eq "DOMString";
- return 0 if $object->IsEnumType($type);
- return 1;
- }
- sub GetSVGTypeNeedingTearOff
- {
- my $object = shift;
- my $type = shift;
- return $svgTypeNeedingTearOff{$type} if exists $svgTypeNeedingTearOff{$type};
- return undef;
- }
- sub GetSVGWrappedTypeNeedingTearOff
- {
- my $object = shift;
- my $type = shift;
- my $svgTypeNeedingTearOff = $object->GetSVGTypeNeedingTearOff($type);
- return $svgTypeNeedingTearOff if not $svgTypeNeedingTearOff;
- if ($svgTypeNeedingTearOff =~ /SVGPropertyTearOff/) {
- $svgTypeNeedingTearOff =~ s/SVGPropertyTearOff<//;
- } elsif ($svgTypeNeedingTearOff =~ /SVGListPropertyTearOff/) {
- $svgTypeNeedingTearOff =~ s/SVGListPropertyTearOff<//;
- } elsif ($svgTypeNeedingTearOff =~ /SVGStaticListPropertyTearOff/) {
- $svgTypeNeedingTearOff =~ s/SVGStaticListPropertyTearOff<//;
- } elsif ($svgTypeNeedingTearOff =~ /SVGTransformListPropertyTearOff/) {
- $svgTypeNeedingTearOff =~ s/SVGTransformListPropertyTearOff<//;
- }
- $svgTypeNeedingTearOff =~ s/>//;
- return $svgTypeNeedingTearOff;
- }
- sub IsSVGAnimatedType
- {
- my $object = shift;
- my $type = shift;
- return 1 if $svgAnimatedTypeHash{$type};
- return 0;
- }
- sub GetSequenceType
- {
- my $object = shift;
- my $type = shift;
- return $1 if $type =~ /^sequence<([\w\d_\s]+)>.*/;
- return "";
- }
- sub GetArrayType
- {
- my $object = shift;
- my $type = shift;
- return $1 if $type =~ /^([\w\d_\s]+)\[\]/;
- return "";
- }
- sub AssertNotSequenceType
- {
- my $object = shift;
- my $type = shift;
- die "Sequences must not be used as the type of an attribute, constant or exception field." if $object->GetSequenceType($type);
- }
- # Uppercase the first letter while respecting WebKit style guidelines.
- # E.g., xmlEncoding becomes XMLEncoding, but xmlllang becomes Xmllang.
- sub WK_ucfirst
- {
- my ($object, $param) = @_;
- my $ret = ucfirst($param);
- $ret =~ s/Xml/XML/ if $ret =~ /^Xml[^a-z]/;
- return $ret;
- }
- # Lowercase the first letter while respecting WebKit style guidelines.
- # URL becomes url, but SetURL becomes setURL.
- sub WK_lcfirst
- {
- my ($object, $param) = @_;
- my $ret = lcfirst($param);
- $ret =~ s/hTML/html/ if $ret =~ /^hTML/;
- $ret =~ s/uRL/url/ if $ret =~ /^uRL/;
- $ret =~ s/jS/js/ if $ret =~ /^jS/;
- $ret =~ s/xML/xml/ if $ret =~ /^xML/;
- $ret =~ s/xSLT/xslt/ if $ret =~ /^xSLT/;
- $ret =~ s/cSS/css/ if $ret =~ /^cSS/;
- # For HTML5 FileSystem API Flags attributes.
- # (create is widely used to instantiate an object and must be avoided.)
- $ret =~ s/^create/isCreate/ if $ret =~ /^create$/;
- $ret =~ s/^exclusive/isExclusive/ if $ret =~ /^exclusive$/;
- return $ret;
- }
- # Return the C++ namespace that a given attribute name string is defined in.
- sub NamespaceForAttributeName
- {
- my ($object, $interfaceName, $attributeName) = @_;
- return "SVGNames" if $interfaceName =~ /^SVG/ && !$svgAttributesInHTMLHash{$attributeName};
- return "HTMLNames";
- }
- # Identifies overloaded functions and for each function adds an array with
- # links to its respective overloads (including itself).
- sub LinkOverloadedFunctions
- {
- my ($object, $interface) = @_;
- my %nameToFunctionsMap = ();
- foreach my $function (@{$interface->functions}) {
- my $name = $function->signature->name;
- $nameToFunctionsMap{$name} = [] if !exists $nameToFunctionsMap{$name};
- push(@{$nameToFunctionsMap{$name}}, $function);
- $function->{overloads} = $nameToFunctionsMap{$name};
- $function->{overloadIndex} = @{$nameToFunctionsMap{$name}};
- }
- }
- sub AttributeNameForGetterAndSetter
- {
- my ($generator, $attribute) = @_;
- my $attributeName = $attribute->signature->name;
- if ($attribute->signature->extendedAttributes->{"ImplementedAs"}) {
- $attributeName = $attribute->signature->extendedAttributes->{"ImplementedAs"};
- }
- my $attributeType = $attribute->signature->type;
- # Avoid clash with C++ keyword.
- $attributeName = "_operator" if $attributeName eq "operator";
- # SVGAElement defines a non-virtual "String& target() const" method which clashes with "virtual String target() const" in Element.
- # To solve this issue the SVGAElement method was renamed to "svgTarget", take care of that when calling this method.
- $attributeName = "svgTarget" if $attributeName eq "target" and $attributeType eq "SVGAnimatedString";
- # SVG animated types need to use a special attribute name.
- # The rest of the special casing for SVG animated types is handled in the language-specific code generators.
- $attributeName .= "Animated" if $generator->IsSVGAnimatedType($attributeType);
- return $attributeName;
- }
- sub ContentAttributeName
- {
- my ($generator, $implIncludes, $interfaceName, $attribute) = @_;
- my $contentAttributeName = $attribute->signature->extendedAttributes->{"Reflect"};
- return undef if !$contentAttributeName;
- $contentAttributeName = lc $generator->AttributeNameForGetterAndSetter($attribute) if $contentAttributeName eq "VALUE_IS_MISSING";
- my $namespace = $generator->NamespaceForAttributeName($interfaceName, $contentAttributeName);
- $implIncludes->{"${namespace}.h"} = 1;
- return "WebCore::${namespace}::${contentAttributeName}Attr";
- }
- sub CanUseFastAttribute
- {
- my ($generator, $attribute) = @_;
- my $attributeType = $attribute->signature->type;
- # HTMLNames::styleAttr cannot be used with fast{Get,Has}Attribute but we do not [Reflect] the
- # style attribute.
- return !$generator->IsSVGAnimatedType($attributeType);
- }
- sub GetterExpression
- {
- my ($generator, $implIncludes, $interfaceName, $attribute) = @_;
- my $contentAttributeName = $generator->ContentAttributeName($implIncludes, $interfaceName, $attribute);
- if (!$contentAttributeName) {
- return ($generator->WK_lcfirst($generator->AttributeNameForGetterAndSetter($attribute)));
- }
- my $functionName;
- if ($attribute->signature->extendedAttributes->{"URL"}) {
- $functionName = "getURLAttribute";
- } elsif ($attribute->signature->type eq "boolean") {
- my $namespace = $generator->NamespaceForAttributeName($interfaceName, $contentAttributeName);
- if ($generator->CanUseFastAttribute($attribute)) {
- $functionName = "fastHasAttribute";
- } else {
- $functionName = "hasAttribute";
- }
- } elsif ($attribute->signature->type eq "long") {
- $functionName = "getIntegralAttribute";
- } elsif ($attribute->signature->type eq "unsigned long") {
- $functionName = "getUnsignedIntegralAttribute";
- } else {
- if ($contentAttributeName eq "WebCore::HTMLNames::idAttr") {
- $functionName = "getIdAttribute";
- $contentAttributeName = "";
- } elsif ($contentAttributeName eq "WebCore::HTMLNames::nameAttr") {
- $functionName = "getNameAttribute";
- $contentAttributeName = "";
- } elsif ($generator->CanUseFastAttribute($attribute)) {
- $functionName = "fastGetAttribute";
- } else {
- $functionName = "getAttribute";
- }
- }
- return ($functionName, $contentAttributeName);
- }
- sub SetterExpression
- {
- my ($generator, $implIncludes, $interfaceName, $attribute) = @_;
- my $contentAttributeName = $generator->ContentAttributeName($implIncludes, $interfaceName, $attribute);
- if (!$contentAttributeName) {
- return ("set" . $generator->WK_ucfirst($generator->AttributeNameForGetterAndSetter($attribute)));
- }
- my $functionName;
- if ($attribute->signature->type eq "boolean") {
- $functionName = "setBooleanAttribute";
- } elsif ($attribute->signature->type eq "long") {
- $functionName = "setIntegralAttribute";
- } elsif ($attribute->signature->type eq "unsigned long") {
- $functionName = "setUnsignedIntegralAttribute";
- } else {
- $functionName = "setAttribute";
- }
- return ($functionName, $contentAttributeName);
- }
- sub IsWrapperType
- {
- my $object = shift;
- my $type = shift;
- return 0 if $object->IsPrimitiveType($type);
- return 0 if $object->GetArrayType($type);
- return 0 if $object->GetSequenceType($type);
- return 0 if $object->IsEnumType($type);
- return 0 if $object->IsStringType($type);
- return 0 if $webCoreTypeHash{$type};
- return 0 if $type eq "any";
- return 1;
- }
- sub IsCallbackInterface
- {
- my $object = shift;
- my $type = shift;
- return 0 unless $object->IsWrapperType($type);
- my $idlFile = $object->IDLFileForInterface($type)
- or die("Could NOT find IDL file for interface \"$type\"!\n");
- open FILE, "<", $idlFile;
- my @lines = <FILE>;
- close FILE;
- my $fileContents = join('', @lines);
- return ($fileContents =~ /callback\s+interface\s+(\w+)/gs);
- }
- sub GenerateConditionalString
- {
- my $generator = shift;
- my $node = shift;
- my $conditional = $node->extendedAttributes->{"Conditional"};
- if ($conditional) {
- return $generator->GenerateConditionalStringFromAttributeValue($conditional);
- } else {
- return "";
- }
- }
- sub GenerateConstructorConditionalString
- {
- my $generator = shift;
- my $node = shift;
- my $conditional = $node->extendedAttributes->{"ConstructorConditional"};
- if ($conditional) {
- return $generator->GenerateConditionalStringFromAttributeValue($conditional);
- } else {
- return "";
- }
- }
- sub GenerateConditionalStringFromAttributeValue
- {
- my $generator = shift;
- my $conditional = shift;
- my $operator = ($conditional =~ /&/ ? '&' : ($conditional =~ /\|/ ? '|' : ''));
- if ($operator) {
- # Avoid duplicated conditions.
- my %conditions;
- map { $conditions{$_} = 1 } split('\\' . $operator, $conditional);
- return "ENABLE(" . join(") $operator$operator ENABLE(", sort keys %conditions) . ")";
- } else {
- return "ENABLE(" . $conditional . ")";
- }
- }
- sub GenerateCompileTimeCheckForEnumsIfNeeded
- {
- my ($generator, $interface) = @_;
- my $interfaceName = $interface->name;
- my @checks = ();
- # If necessary, check that all constants are available as enums with the same value.
- if (!$interface->extendedAttributes->{"DoNotCheckConstants"} && @{$interface->constants}) {
- push(@checks, "\n");
- foreach my $constant (@{$interface->constants}) {
- my $reflect = $constant->extendedAttributes->{"Reflect"};
- my $name = $reflect ? $reflect : $constant->name;
- my $value = $constant->value;
- my $conditional = $constant->extendedAttributes->{"Conditional"};
- if ($conditional) {
- my $conditionalString = $generator->GenerateConditionalStringFromAttributeValue($conditional);
- push(@checks, "#if ${conditionalString}\n");
- }
- if ($constant->extendedAttributes->{"ImplementedBy"}) {
- push(@checks, "COMPILE_ASSERT($value == " . $constant->extendedAttributes->{"ImplementedBy"} . "::$name, ${interfaceName}Enum${name}IsWrongUseDoNotCheckConstants);\n");
- } else {
- push(@checks, "COMPILE_ASSERT($value == ${interfaceName}::$name, ${interfaceName}Enum${name}IsWrongUseDoNotCheckConstants);\n");
- }
- if ($conditional) {
- push(@checks, "#endif\n");
- }
- }
- push(@checks, "\n");
- }
- return @checks;
- }
- sub ExtendedAttributeContains
- {
- my $object = shift;
- my $callWith = shift;
- return 0 unless $callWith;
- my $keyword = shift;
- my @callWithKeywords = split /\s*\|\s*/, $callWith;
- return grep { $_ eq $keyword } @callWithKeywords;
- }
- # FIXME: This is backwards. We currently name the interface and the IDL files with the implementation name. We
- # should use the real interface name in the IDL files and then use ImplementedAs to map this to the implementation name.
- sub GetVisibleInterfaceName
- {
- my $object = shift;
- my $interface = shift;
- my $interfaceName = $interface->extendedAttributes->{"InterfaceName"};
- return $interfaceName ? $interfaceName : $interface->name;
- }
- sub InheritsInterface
- {
- my $object = shift;
- my $interface = shift;
- my $interfaceName = shift;
- my $found = 0;
- return 1 if $interfaceName eq $interface->name;
- $object->ForAllParents($interface, sub {
- my $currentInterface = shift;
- if ($currentInterface->name eq $interfaceName) {
- $found = 1;
- }
- return 1 if $found;
- }, 0);
- return $found;
- }
- sub InheritsExtendedAttribute
- {
- my $object = shift;
- my $interface = shift;
- my $extendedAttribute = shift;
- my $found = 0;
- return 1 if $interface->extendedAttributes->{$extendedAttribute};
- $object->ForAllParents($interface, sub {
- my $currentInterface = shift;
- if ($currentInterface->extendedAttributes->{$extendedAttribute}) {
- $found = 1;
- }
- return 1 if $found;
- }, 0);
- return $found;
- }
- 1;
|