Upstream version 10.38.222.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / build / scripts / name_macros.py
1 # Copyright (C) 2013 Google Inc. All rights reserved.
2 #
3 # Redistribution and use in source and binary forms, with or without
4 # modification, are permitted provided that the following conditions are
5 # met:
6 #
7 #     * Redistributions of source code must retain the above copyright
8 # notice, this list of conditions and the following disclaimer.
9 #     * Redistributions in binary form must reproduce the above
10 # copyright notice, this list of conditions and the following disclaimer
11 # in the documentation and/or other materials provided with the
12 # distribution.
13 #     * Neither the name of Google Inc. nor the names of its
14 # contributors may be used to endorse or promote products derived from
15 # this software without specific prior written permission.
16 #
17 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
29 import os.path
30 import re
31
32 from in_generator import Maker
33 import in_generator
34 import license
35 import name_utilities
36
37
38 HEADER_TEMPLATE = """%(license)s
39
40 #ifndef %(namespace)s%(suffix)sHeaders_h
41 #define %(namespace)s%(suffix)sHeaders_h
42 %(base_header_for_suffix)s
43 %(includes)s
44
45 #endif // %(namespace)s%(suffix)sHeaders_h
46 """
47
48
49 INTERFACES_HEADER_TEMPLATE = """%(license)s
50
51 #ifndef %(namespace)s%(suffix)sInterfaces_h
52 #define %(namespace)s%(suffix)sInterfaces_h
53 %(base_header_for_suffix)s
54 %(declare_conditional_macros)s
55
56 #define %(macro_style_name)s_INTERFACES_FOR_EACH(macro) \\
57     \\
58 %(unconditional_macros)s
59     \\
60 %(conditional_macros)s
61
62 #endif // %(namespace)s%(suffix)sInterfaces_h
63 """
64
65
66 class Writer(in_generator.Writer):
67     def __init__(self, in_file_path):
68         super(Writer, self).__init__(in_file_path)
69         self.namespace = self.in_file.parameters['namespace'].strip('"')
70         self.suffix = self.in_file.parameters['suffix'].strip('"')
71         self._entries_by_conditional = {}
72         self._unconditional_entries = []
73         self._validate_entries()
74         self._sort_entries_by_conditional()
75         self._outputs = {(self.namespace + self.suffix + "Headers.h"): self.generate_headers_header,
76                          (self.namespace + self.suffix + "Interfaces.h"): self.generate_interfaces_header,
77                         }
78
79     def _validate_entries(self):
80         # If there is more than one entry with the same script name, only the first one will ever
81         # be hit in practice, and so we'll silently ignore any properties requested for the second
82         # (like RuntimeEnabled - see crbug.com/332588).
83         entries_by_script_name = dict()
84         for entry in self.in_file.name_dictionaries:
85             script_name = name_utilities.script_name(entry)
86             if script_name in entries_by_script_name:
87                 self._fatal('Multiple entries with script_name=%(script_name)s: %(name1)s %(name2)s' % {
88                     'script_name': script_name,
89                     'name1': entry['name'],
90                     'name2': entries_by_script_name[script_name]['name']})
91             entries_by_script_name[script_name] = entry
92
93     def _fatal(self, message):
94         print 'FATAL ERROR: ' + message
95         exit(1)
96
97     def _sort_entries_by_conditional(self):
98         unconditional_names = set()
99         for entry in self.in_file.name_dictionaries:
100             conditional = entry['Conditional']
101             if not conditional:
102                 cpp_name = name_utilities.cpp_name(entry)
103                 if cpp_name in unconditional_names:
104                     continue
105                 unconditional_names.add(cpp_name)
106                 self._unconditional_entries.append(entry)
107                 continue
108         for entry in self.in_file.name_dictionaries:
109             cpp_name = name_utilities.cpp_name(entry)
110             if cpp_name in unconditional_names:
111                 continue
112             conditional = entry['Conditional']
113             if not conditional in self._entries_by_conditional:
114                 self._entries_by_conditional[conditional] = []
115             self._entries_by_conditional[conditional].append(entry)
116
117     def _headers_header_include_path(self, entry):
118         if entry['ImplementedAs']:
119             path = os.path.dirname(entry['name'])
120             if len(path):
121                 path += '/'
122             path += entry['ImplementedAs']
123         else:
124             path = entry['name']
125         return path + '.h'
126
127     def _headers_header_includes(self, entries):
128         includes = dict()
129         for entry in entries:
130             cpp_name = name_utilities.cpp_name(entry)
131             # Avoid duplicate includes.
132             if cpp_name in includes:
133                 continue
134             if self.suffix == 'Modules':
135                 subdir_name = 'modules'
136             else:
137                 subdir_name = 'core'
138             include = '#include "%(path)s"\n#include "bindings/%(subdir_name)s/v8/V8%(script_name)s.h"' % {
139                 'path': self._headers_header_include_path(entry),
140                 'script_name': name_utilities.script_name(entry),
141                 'subdir_name': subdir_name,
142             }
143             includes[cpp_name] = self.wrap_with_condition(include, entry['Conditional'])
144         return includes.values()
145
146     def generate_headers_header(self):
147         base_header_for_suffix = ''
148         if self.suffix:
149             base_header_for_suffix = '\n#include "core/%(namespace)sHeaders.h"\n' % {'namespace': self.namespace}
150         return HEADER_TEMPLATE % {
151             'license': license.license_for_generated_cpp(),
152             'namespace': self.namespace,
153             'suffix': self.suffix,
154             'base_header_for_suffix': base_header_for_suffix,
155             'includes': '\n'.join(self._headers_header_includes(self.in_file.name_dictionaries)),
156         }
157
158     def _declare_one_conditional_macro(self, conditional, entries):
159         macro_name = '%(macro_style_name)s_INTERFACES_FOR_EACH_%(conditional)s' % {
160             'macro_style_name': name_utilities.to_macro_style(self.namespace + self.suffix),
161             'conditional': conditional,
162         }
163         return self.wrap_with_condition("""#define %(macro_name)s(macro) \\
164 %(declarations)s
165
166 #else
167 #define %(macro_name)s(macro)""" % {
168             'macro_name': macro_name,
169             'declarations': '\n'.join(sorted(set([
170                 '    macro(%(cpp_name)s) \\' % {'cpp_name': name_utilities.cpp_name(entry)}
171                 for entry in entries]))),
172         }, conditional)
173
174     def _declare_conditional_macros(self):
175         return '\n'.join([
176             self._declare_one_conditional_macro(conditional, entries)
177             for conditional, entries in self._entries_by_conditional.items()])
178
179     def _unconditional_macro(self, entry):
180         return '    macro(%(cpp_name)s) \\' % {'cpp_name': name_utilities.cpp_name(entry)}
181
182     def _conditional_macros(self, conditional):
183         return '    %(macro_style_name)s_INTERFACES_FOR_EACH_%(conditional)s(macro) \\' % {
184             'macro_style_name': name_utilities.to_macro_style(self.namespace + self.suffix),
185             'conditional': conditional,
186         }
187
188     def generate_interfaces_header(self):
189         base_header_for_suffix = ''
190         if self.suffix:
191             base_header_for_suffix = '\n#include "core/%(namespace)sInterfaces.h"\n' % {'namespace': self.namespace}
192         return INTERFACES_HEADER_TEMPLATE % {
193             'license': license.license_for_generated_cpp(),
194             'namespace': self.namespace,
195             'suffix': self.suffix,
196             'base_header_for_suffix': base_header_for_suffix,
197             'macro_style_name': name_utilities.to_macro_style(self.namespace + self.suffix),
198             'declare_conditional_macros': self._declare_conditional_macros(),
199             'unconditional_macros': '\n'.join(sorted(set(map(self._unconditional_macro, self._unconditional_entries)))),
200             'conditional_macros': '\n'.join(map(self._conditional_macros, self._entries_by_conditional.keys())),
201         }