18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#
28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project# WebKit IDL parser
38a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block#
48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project# Copyright (C) 2005 Nikolas Zimmermann <wildfox@kde.org>
58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project# Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
6e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke# Copyright (C) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
7231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block# Copyright (C) 2009 Cameron McCormack <cam@mcc.id.au>
8e14391e94c850b8bd03680c23b38978db68687a8John Reck# Copyright (C) Research In Motion Limited 2010. All rights reserved.
98a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block#
108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project# This library is free software; you can redistribute it and/or
118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project# modify it under the terms of the GNU Library General Public
128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project# License as published by the Free Software Foundation; either
138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project# version 2 of the License, or (at your option) any later version.
148a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block#
158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project# This library is distributed in the hope that it will be useful,
168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project# but WITHOUT ANY WARRANTY; without even the implied warranty of
178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project# Library General Public License for more details.
198a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block#
208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project# You should have received a copy of the GNU Library General Public License
21dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block# along with this library; see the file COPYING.LIB.  If not, write to
228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project# the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project# Boston, MA 02110-1301, USA.
248a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block#
258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectpackage CodeGenerator;
278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
28545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdochuse strict;
29545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
30231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockuse File::Find;
31231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectmy $useDocument = "";
338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectmy $useGenerator = "";
348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectmy $useOutputDir = "";
35967717af5423377c967781471ee106e2bb4e11c8Ben Murdochmy $useOutputHeadersDir = "";
368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectmy $useDirectories = "";
378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectmy $useLayerOnTop = 0;
388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectmy $preprocessor;
39231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockmy $writeDependencies = 0;
40231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockmy $defines = "";
418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectmy $codeGenerator = 0;
438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectmy $verbose = 0;
458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
46e14391e94c850b8bd03680c23b38978db68687a8John Reckmy %numericTypeHash = ("int" => 1, "short" => 1, "long" => 1, "long long" => 1,
47e14391e94c850b8bd03680c23b38978db68687a8John Reck                       "unsigned int" => 1, "unsigned short" => 1,
48e14391e94c850b8bd03680c23b38978db68687a8John Reck                       "unsigned long" => 1, "unsigned long long" => 1,
49e14391e94c850b8bd03680c23b38978db68687a8John Reck                       "float" => 1, "double" => 1);
50e14391e94c850b8bd03680c23b38978db68687a8John Reck
51e14391e94c850b8bd03680c23b38978db68687a8John Reckmy %primitiveTypeHash = ( "boolean" => 1, "void" => 1, "Date" => 1);
528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectmy %stringTypeHash = ("DOMString" => 1, "AtomicString" => 1);
548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochmy %nonPointerTypeHash = ("DOMTimeStamp" => 1, "CompareHow" => 1);
568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectmy %svgAnimatedTypeHash = ("SVGAnimatedAngle" => 1, "SVGAnimatedBoolean" => 1,
588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                           "SVGAnimatedEnumeration" => 1, "SVGAnimatedInteger" => 1,
598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                           "SVGAnimatedLength" => 1, "SVGAnimatedLengthList" => 1,
608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                           "SVGAnimatedNumber" => 1, "SVGAnimatedNumberList" => 1,
618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                           "SVGAnimatedPreserveAspectRatio" => 1,
628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                           "SVGAnimatedRect" => 1, "SVGAnimatedString" => 1,
638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                           "SVGAnimatedTransformList" => 1);
648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
65cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Blockmy %svgAttributesInHTMLHash = ("class" => 1, "id" => 1, "onabort" => 1, "onclick" => 1,
66cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block                               "onerror" => 1, "onload" => 1, "onmousedown" => 1,
67cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block                               "onmousemove" => 1, "onmouseout" => 1, "onmouseover" => 1,
68cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block                               "onmouseup" => 1, "onresize" => 1, "onscroll" => 1,
69cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block                               "onunload" => 1);
70cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block
7128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhumy %svgTypeNeedingTearOff = (
72e14391e94c850b8bd03680c23b38978db68687a8John Reck    "SVGAngle" => "SVGPropertyTearOff<SVGAngle>",
73e14391e94c850b8bd03680c23b38978db68687a8John Reck    "SVGLength" => "SVGPropertyTearOff<SVGLength>",
74e14391e94c850b8bd03680c23b38978db68687a8John Reck    "SVGLengthList" => "SVGListPropertyTearOff<SVGLengthList>",
756b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    "SVGMatrix" => "SVGPropertyTearOff<SVGMatrix>",
7628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    "SVGNumber" => "SVGPropertyTearOff<float>",
7728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    "SVGNumberList" => "SVGListPropertyTearOff<SVGNumberList>",
784576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    "SVGPathSegList" => "SVGPathSegListPropertyTearOff",
7928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    "SVGPoint" => "SVGPropertyTearOff<FloatPoint>",
8028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    "SVGPointList" => "SVGListPropertyTearOff<SVGPointList>",
8128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    "SVGPreserveAspectRatio" => "SVGPropertyTearOff<SVGPreserveAspectRatio>",
8228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    "SVGRect" => "SVGPropertyTearOff<FloatRect>",
836b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    "SVGStringList" => "SVGStaticListPropertyTearOff<SVGStringList>",
846b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    "SVGTransform" => "SVGPropertyTearOff<SVGTransform>",
856b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    "SVGTransformList" => "SVGTransformListPropertyTearOff"
8628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu);
8728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu
8828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhumy %svgTypeWithWritablePropertiesNeedingTearOff = (
896b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    "SVGPoint" => 1,
906b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    "SVGMatrix" => 1
91e14391e94c850b8bd03680c23b38978db68687a8John Reck);
92e14391e94c850b8bd03680c23b38978db68687a8John Reck
93231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block# Cache of IDL file pathnames.
94231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockmy $idlFiles;
958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project# Default constructor
978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectsub new
988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    my $object = shift;
1008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    my $reference = { };
1018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    $useDirectories = shift;
1038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    $useGenerator = shift;
1048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    $useOutputDir = shift;
105967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    $useOutputHeadersDir = shift;
1068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    $useLayerOnTop = shift;
1078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    $preprocessor = shift;
108231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    $writeDependencies = shift;
109e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    $verbose = shift;
1108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bless($reference, $object);
1128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return $reference;
1138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectsub StripModule($)
1168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    my $object = shift;
1188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    my $name = shift;
1198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    $name =~ s/[a-zA-Z0-9]*:://;
1208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return $name;
1218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectsub ProcessDocument
1248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    my $object = shift;
1268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    $useDocument = shift;
1278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    $defines = shift;
1288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    my $ifaceName = "CodeGenerator" . $useGenerator;
130e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    require $ifaceName . ".pm";
1318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    # Dynamically load external code generation perl module
133967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    $codeGenerator = $ifaceName->new($object, $useOutputDir, $useOutputHeadersDir, $useLayerOnTop, $preprocessor, $writeDependencies, $verbose);
1348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    unless (defined($codeGenerator)) {
1358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        my $classes = $useDocument->classes;
1368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        foreach my $class (@$classes) {
1378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            print "Skipping $useGenerator code generation for IDL interface \"" . $class->name . "\".\n" if $verbose;
1388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
1398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
1408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    # Start the actual code generation!
1438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    $codeGenerator->GenerateModule($useDocument, $defines);
1448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    my $classes = $useDocument->classes;
1468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    foreach my $class (@$classes) {
1478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        print "Generating $useGenerator bindings code for IDL interface \"" . $class->name . "\"...\n" if $verbose;
1488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        $codeGenerator->GenerateInterface($class, $defines);
1498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    $codeGenerator->finish();
1528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
154231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blocksub ForAllParents
1550bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
1560bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    my $object = shift;
1570bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    my $dataNode = shift;
158231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    my $beforeRecursion = shift;
159231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    my $afterRecursion = shift;
160231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    my $parentsOnly = shift;
1610bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
162231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    my $recurse;
163231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    $recurse = sub {
164231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        my $interface = shift;
1650bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
166231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        for (@{$interface->parents}) {
167231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            my $interfaceName = $object->StripModule($_);
168231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            my $parentInterface = $object->ParseInterface($interfaceName, $parentsOnly);
1690bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
170231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            if ($beforeRecursion) {
171231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                &$beforeRecursion($parentInterface) eq 'prune' and next;
1720bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            }
173231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            &$recurse($parentInterface);
174231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            &$afterRecursion($parentInterface) if $afterRecursion;
1750bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
176231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    };
177231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
178231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    &$recurse($dataNode);
1790bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
1800bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectsub AddMethodsConstantsAndAttributesFromParentClasses
1828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
183231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    # Add to $dataNode all of its inherited interface members, except for those
184231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    # inherited through $dataNode's first listed parent.  If an array reference
185231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    # is passed in as $parents, the names of all ancestor interfaces visited
186231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    # will be appended to the array.  If $collectDirectParents is true, then
187231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    # even the names of $dataNode's first listed parent and its ancestors will
188231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    # be appended to $parents.
1898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    my $object = shift;
1918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    my $dataNode = shift;
192231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    my $parents = shift;
193231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    my $collectDirectParents = shift;
1948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
195231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    my $first = 1;
1968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
197231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    $object->ForAllParents($dataNode, sub {
198231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        my $interface = shift;
1998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
200231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        if ($first) {
2018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            # Ignore first parent class, already handled by the generation itself.
202231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            $first = 0;
203231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
204231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            if ($collectDirectParents) {
205231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                # Just collect the names of the direct ancestor interfaces,
206231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                # if necessary.
207231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                push(@$parents, $interface->name);
208231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                $object->ForAllParents($interface, sub {
209231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                    my $interface = shift;
210231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                    push(@$parents, $interface->name);
211231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                }, undef, 1);
212231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            }
2138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
214231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            # Prune the recursion here.
215231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            return 'prune';
2168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
2178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
218231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        # Collect the name of this additional parent.
219231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        push(@$parents, $interface->name) if $parents;
2208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
221231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        print "  |  |>  -> Inheriting "
222231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            . @{$interface->constants} . " constants, "
223231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            . @{$interface->functions} . " functions, "
224231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            . @{$interface->attributes} . " attributes...\n  |  |>\n" if $verbose;
2258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
226231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        # Add this parent's members to $dataNode.
227231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        push(@{$dataNode->constants}, @{$interface->constants});
228231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        push(@{$dataNode->functions}, @{$interface->functions});
229231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        push(@{$dataNode->attributes}, @{$interface->attributes});
230231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    });
2318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectsub GetMethodsAndAttributesFromParentClasses
2348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    # For the passed interface, recursively parse all parent
2368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    # IDLs in order to find out all inherited properties/methods.
2378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    my $object = shift;
2398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    my $dataNode = shift;
2408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    my @parentList = ();
2428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
243231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    $object->ForAllParents($dataNode, undef, sub {
244231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        my $interface = shift;
2458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
246231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        my $hash = {
247231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            "name" => $interface->name,
248231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            "functions" => $interface->functions,
249231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            "attributes" => $interface->attributes
250231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        };
2518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
252231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        unshift(@parentList, $hash);
253231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    });
2548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
255231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    return @parentList;
256231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block}
2578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
258231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blocksub IDLFileForInterface
259231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{
260231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    my $object = shift;
261231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    my $interfaceName = shift;
2628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
263231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    unless ($idlFiles) {
264231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        my $sourceRoot = $ENV{SOURCE_ROOT};
265231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        my @directories = map { $_ = "$sourceRoot/$_" if $sourceRoot && -d "$sourceRoot/$_"; $_ } @$useDirectories;
2668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
267231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        $idlFiles = { };
2688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
269231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        my $wanted = sub {
270231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            $idlFiles->{$1} = $File::Find::name if /^([A-Z].*)\.idl$/;
271231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            $File::Find::prune = 1 if /^\../;
272231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        };
273231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        find($wanted, @directories);
2748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
276231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    return $idlFiles->{$interfaceName};
2778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectsub ParseInterface
2808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
281231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    my $object = shift;
282231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    my $interfaceName = shift;
283231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    my $parentsOnly = shift;
2848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
285231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    return undef if $interfaceName eq 'Object';
2868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
287231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    # Step #1: Find the IDL file associated with 'interface'
288231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    my $filename = $object->IDLFileForInterface($interfaceName)
289231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        or die("Could NOT find IDL file for interface \"$interfaceName\"!\n");
2908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
291231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    print "  |  |>  Parsing parent IDL \"$filename\" for interface \"$interfaceName\"\n" if $verbose;
2928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    # Step #2: Parse the found IDL file (in quiet mode).
2948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    my $parser = IDLParser->new(1);
295231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    my $document = $parser->Parse($filename, $defines, $preprocessor, $parentsOnly);
2968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    foreach my $interface (@{$document->classes}) {
2988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return $interface if $interface->name eq $interfaceName;
2998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
3008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
301545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    die("Could NOT find interface definition for $interfaceName in $filename");
3028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project# Helpers for all CodeGenerator***.pm modules
305e14391e94c850b8bd03680c23b38978db68687a8John Reck
306e14391e94c850b8bd03680c23b38978db68687a8John Recksub AvoidInclusionOfType
307e14391e94c850b8bd03680c23b38978db68687a8John Reck{
308e14391e94c850b8bd03680c23b38978db68687a8John Reck    my $object = shift;
309e14391e94c850b8bd03680c23b38978db68687a8John Reck    my $type = shift;
310e14391e94c850b8bd03680c23b38978db68687a8John Reck
311f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    # Special case: SVGPoint.h / SVGNumber.h do not exist.
312f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    return 1 if $type eq "SVGPoint" or $type eq "SVGNumber";
3138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return 0;
3148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
316e14391e94c850b8bd03680c23b38978db68687a8John Recksub IsNumericType
317e14391e94c850b8bd03680c23b38978db68687a8John Reck{
318e14391e94c850b8bd03680c23b38978db68687a8John Reck    my $object = shift;
319e14391e94c850b8bd03680c23b38978db68687a8John Reck    my $type = shift;
320e14391e94c850b8bd03680c23b38978db68687a8John Reck
321e14391e94c850b8bd03680c23b38978db68687a8John Reck    return 1 if $numericTypeHash{$type};
322e14391e94c850b8bd03680c23b38978db68687a8John Reck    return 0;
323e14391e94c850b8bd03680c23b38978db68687a8John Reck}
324e14391e94c850b8bd03680c23b38978db68687a8John Reck
3258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectsub IsPrimitiveType
3268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    my $object = shift;
3288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    my $type = shift;
3298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return 1 if $primitiveTypeHash{$type};
331e14391e94c850b8bd03680c23b38978db68687a8John Reck    return 1 if $numericTypeHash{$type};
3328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return 0;
3338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectsub IsStringType
3368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    my $object = shift;
3388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    my $type = shift;
3398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return 1 if $stringTypeHash{$type};
3418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return 0;
3428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectsub IsNonPointerType
3458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    my $object = shift;
3478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    my $type = shift;
3488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
349e14391e94c850b8bd03680c23b38978db68687a8John Reck    return 1 if $nonPointerTypeHash{$type} or $primitiveTypeHash{$type} or $numericTypeHash{$type};
350e14391e94c850b8bd03680c23b38978db68687a8John Reck    return 0;
351e14391e94c850b8bd03680c23b38978db68687a8John Reck}
352e14391e94c850b8bd03680c23b38978db68687a8John Reck
353e14391e94c850b8bd03680c23b38978db68687a8John Recksub IsSVGTypeNeedingTearOff
354e14391e94c850b8bd03680c23b38978db68687a8John Reck{
355e14391e94c850b8bd03680c23b38978db68687a8John Reck    my $object = shift;
356e14391e94c850b8bd03680c23b38978db68687a8John Reck    my $type = shift;
357e14391e94c850b8bd03680c23b38978db68687a8John Reck
35828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    return 1 if exists $svgTypeNeedingTearOff{$type};
35928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    return 0;
36028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu}
36128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu
36228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhusub IsSVGTypeWithWritablePropertiesNeedingTearOff
36328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu{
36428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    my $object = shift;
36528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    my $type = shift;
36628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu
36728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    return 1 if $svgTypeWithWritablePropertiesNeedingTearOff{$type};
368e14391e94c850b8bd03680c23b38978db68687a8John Reck    return 0;
369e14391e94c850b8bd03680c23b38978db68687a8John Reck}
370e14391e94c850b8bd03680c23b38978db68687a8John Reck
371e14391e94c850b8bd03680c23b38978db68687a8John Recksub GetSVGTypeNeedingTearOff
372e14391e94c850b8bd03680c23b38978db68687a8John Reck{
373e14391e94c850b8bd03680c23b38978db68687a8John Reck    my $object = shift;
374e14391e94c850b8bd03680c23b38978db68687a8John Reck    my $type = shift;
375e14391e94c850b8bd03680c23b38978db68687a8John Reck
37628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    return $svgTypeNeedingTearOff{$type} if exists $svgTypeNeedingTearOff{$type};
377e14391e94c850b8bd03680c23b38978db68687a8John Reck    return undef;
378e14391e94c850b8bd03680c23b38978db68687a8John Reck}
379e14391e94c850b8bd03680c23b38978db68687a8John Reck
380e14391e94c850b8bd03680c23b38978db68687a8John Recksub GetSVGWrappedTypeNeedingTearOff
381e14391e94c850b8bd03680c23b38978db68687a8John Reck{
382e14391e94c850b8bd03680c23b38978db68687a8John Reck    my $object = shift;
383e14391e94c850b8bd03680c23b38978db68687a8John Reck    my $type = shift;
384e14391e94c850b8bd03680c23b38978db68687a8John Reck
38528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    my $svgTypeNeedingTearOff = $object->GetSVGTypeNeedingTearOff($type);
38628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    return $svgTypeNeedingTearOff if not $svgTypeNeedingTearOff;
387e14391e94c850b8bd03680c23b38978db68687a8John Reck
38828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    if ($svgTypeNeedingTearOff =~ /SVGPropertyTearOff/) {
38928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        $svgTypeNeedingTearOff =~ s/SVGPropertyTearOff<//;
39028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    } elsif ($svgTypeNeedingTearOff =~ /SVGListPropertyTearOff/) {
39128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        $svgTypeNeedingTearOff =~ s/SVGListPropertyTearOff<//;
39228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    } elsif ($svgTypeNeedingTearOff =~ /SVGStaticListPropertyTearOff/) {
39328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        $svgTypeNeedingTearOff =~ s/SVGStaticListPropertyTearOff<//;
3946b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    }  elsif ($svgTypeNeedingTearOff =~ /SVGTransformListPropertyTearOff/) {
3956b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        $svgTypeNeedingTearOff =~ s/SVGTransformListPropertyTearOff<//;
3966b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    }
39728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu
39828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    $svgTypeNeedingTearOff =~ s/>//;
39928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    return $svgTypeNeedingTearOff;
400e14391e94c850b8bd03680c23b38978db68687a8John Reck}
401e14391e94c850b8bd03680c23b38978db68687a8John Reck
4028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectsub IsSVGAnimatedType
4038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    my $object = shift;
4058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    my $type = shift;
4068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return 1 if $svgAnimatedTypeHash{$type};
4088a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    return 0;
4098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4118a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block# Uppercase the first letter while respecting WebKit style guidelines.
4128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project# E.g., xmlEncoding becomes XMLEncoding, but xmlllang becomes Xmllang.
4138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectsub WK_ucfirst
4148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    my ($object, $param) = @_;
4168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    my $ret = ucfirst($param);
4178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    $ret =~ s/Xml/XML/ if $ret =~ /^Xml[^a-z]/;
418db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block
4198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return $ret;
4208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4228a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block# Lowercase the first letter while respecting WebKit style guidelines.
4238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project# URL becomes url, but SetURL becomes setURL.
4248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectsub WK_lcfirst
4258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    my ($object, $param) = @_;
4278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    my $ret = lcfirst($param);
4288a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    $ret =~ s/hTML/html/ if $ret =~ /^hTML/;
4298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    $ret =~ s/uRL/url/ if $ret =~ /^uRL/;
4308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    $ret =~ s/jS/js/ if $ret =~ /^jS/;
4315f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    $ret =~ s/xML/xml/ if $ret =~ /^xML/;
4325f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    $ret =~ s/xSLT/xslt/ if $ret =~ /^xSLT/;
433db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block
434db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block    # For HTML5 FileSystem API Flags attributes.
43568513a70bcd92384395513322f1b801e7bf9c729Steve Block    # (create is widely used to instantiate an object and must be avoided.)
43668513a70bcd92384395513322f1b801e7bf9c729Steve Block    $ret =~ s/^create/isCreate/ if $ret =~ /^create$/;
43768513a70bcd92384395513322f1b801e7bf9c729Steve Block    $ret =~ s/^exclusive/isExclusive/ if $ret =~ /^exclusive$/;
438db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block
4398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return $ret;
4408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
442cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block# Return the C++ namespace that a given attribute name string is defined in.
443cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Blocksub NamespaceForAttributeName
444cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block{
445cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    my ($object, $interfaceName, $attributeName) = @_;
446cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    return "SVGNames" if $interfaceName =~ /^SVG/ && !$svgAttributesInHTMLHash{$attributeName};
447cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    return "HTMLNames";
448cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block}
449cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block
4506c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen# Identifies overloaded functions and for each function adds an array with
4516c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen# links to its respective overloads (including itself).
4526c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsensub LinkOverloadedFunctions
4536c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen{
4546c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    my ($object, $dataNode) = @_;
4556c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen
4566c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    my %nameToFunctionsMap = ();
4576c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    foreach my $function (@{$dataNode->functions}) {
4586c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        my $name = $function->signature->name;
4596c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        $nameToFunctionsMap{$name} = [] if !exists $nameToFunctionsMap{$name};
4606c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        push(@{$nameToFunctionsMap{$name}}, $function);
4616c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        $function->{overloads} = $nameToFunctionsMap{$name};
4626c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        $function->{overloadIndex} = @{$nameToFunctionsMap{$name}};
4636c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    }
4646c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen}
4656c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen
46606ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsensub AttributeNameForGetterAndSetter
46706ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen{
46806ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    my ($generator, $attribute) = @_;
46906ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen
47006ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    my $attributeName = $attribute->signature->name;
47128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    my $attributeType = $generator->StripModule($attribute->signature->type);
47206ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen
47306ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    # Avoid clash with C++ keyword.
47406ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    $attributeName = "_operator" if $attributeName eq "operator";
47506ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen
47628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    # SVGAElement defines a non-virtual "String& target() const" method which clashes with "virtual String target() const" in Element.
47728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    # To solve this issue the SVGAElement method was renamed to "svgTarget", take care of that when calling this method.
47828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    $attributeName = "svgTarget" if $attributeName eq "target" and $attributeType eq "SVGAnimatedString";
47928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu
48006ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    # SVG animated types need to use a special attribute name.
48106ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    # The rest of the special casing for SVG animated types is handled in the language-specific code generators.
48228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    $attributeName .= "Animated" if $generator->IsSVGAnimatedType($attributeType);
48306ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen
48406ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    return $attributeName;
48506ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen}
48606ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen
48706ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsensub ContentAttributeName
48806ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen{
48906ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    my ($generator, $implIncludes, $interfaceName, $attribute) = @_;
49006ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen
491e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    my $contentAttributeName = $attribute->signature->extendedAttributes->{"Reflect"};
49206ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    return undef if !$contentAttributeName;
49306ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen
49406ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    $contentAttributeName = lc $generator->AttributeNameForGetterAndSetter($attribute) if $contentAttributeName eq "1";
49506ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen
49606ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    my $namespace = $generator->NamespaceForAttributeName($interfaceName, $contentAttributeName);
49706ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen
49806ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    $implIncludes->{"${namespace}.h"} = 1;
49906ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    return "WebCore::${namespace}::${contentAttributeName}Attr";
50006ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen}
50106ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen
50206ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsensub GetterExpressionPrefix
50306ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen{
50406ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    my ($generator, $implIncludes, $interfaceName, $attribute) = @_;
50506ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen
50606ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    my $contentAttributeName = $generator->ContentAttributeName($implIncludes, $interfaceName, $attribute);
50706ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen
50806ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    if (!$contentAttributeName) {
50906ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen        return $generator->WK_lcfirst($generator->AttributeNameForGetterAndSetter($attribute)) . "(";
51006ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    }
51106ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen
51206ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    my $functionName;
513e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if ($attribute->signature->extendedAttributes->{"URL"}) {
514e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if ($attribute->signature->extendedAttributes->{"NonEmpty"}) {
515e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            $functionName = "getNonEmptyURLAttribute";
516e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        } else {
517e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            $functionName = "getURLAttribute";
518e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        }
51906ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    } elsif ($attribute->signature->type eq "boolean") {
52006ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen        $functionName = "hasAttribute";
52106ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    } elsif ($attribute->signature->type eq "long") {
52206ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen        $functionName = "getIntegralAttribute";
52306ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    } elsif ($attribute->signature->type eq "unsigned long") {
52406ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen        $functionName = "getUnsignedIntegralAttribute";
52506ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    } else {
52606ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen        $functionName = "getAttribute";
52706ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    }
52806ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen
52906ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    return "$functionName($contentAttributeName"
53006ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen}
53106ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen
53206ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsensub SetterExpressionPrefix
53306ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen{
53406ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    my ($generator, $implIncludes, $interfaceName, $attribute) = @_;
53506ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen
53606ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    my $contentAttributeName = $generator->ContentAttributeName($implIncludes, $interfaceName, $attribute);
53706ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen
53806ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    if (!$contentAttributeName) {
53906ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen        return "set" . $generator->WK_ucfirst($generator->AttributeNameForGetterAndSetter($attribute)) . "(";
54006ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    }
54106ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen
54206ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    my $functionName;
54306ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    if ($attribute->signature->type eq "boolean") {
54406ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen        $functionName = "setBooleanAttribute";
54506ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    } elsif ($attribute->signature->type eq "long") {
54606ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen        $functionName = "setIntegralAttribute";
54706ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    } elsif ($attribute->signature->type eq "unsigned long") {
54806ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen        $functionName = "setUnsignedIntegralAttribute";
54906ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    } else {
55006ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen        $functionName = "setAttribute";
55106ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    }
55206ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen
55306ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    return "$functionName($contentAttributeName, "
55406ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen}
5556c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen
556967717af5423377c967781471ee106e2bb4e11c8Ben Murdochsub ShouldCheckEnums
557967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch{
558967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    my $dataNode = shift;
559967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    return not $dataNode->extendedAttributes->{"DontCheckEnums"};
560967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch}
561967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch
562967717af5423377c967781471ee106e2bb4e11c8Ben Murdochsub GenerateCompileTimeCheckForEnumsIfNeeded
563967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch{
564967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    my ($object, $dataNode) = @_;
565967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    my $interfaceName = $dataNode->name;
566967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    my @checks = ();
567967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    # If necessary, check that all constants are available as enums with the same value.
568967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    if (ShouldCheckEnums($dataNode) && @{$dataNode->constants}) {
569967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        push(@checks, "\n");
570967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        foreach my $constant (@{$dataNode->constants}) {
571967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch            my $name = $constant->name;
572967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch            my $value = $constant->value;
573967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch            push(@checks, "COMPILE_ASSERT($value == ${interfaceName}::$name, ${interfaceName}Enum${name}IsWrongUseDontCheckEnums);\n");
574967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        }
575967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        push(@checks, "\n");
576967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    }
577967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    return @checks;
578967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch}
579967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch
5808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project1;
581