Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / third_party / WebKit / Source / build / scripts / make_event_factory.py
blobbc27525d52ad1e90fe79b11d5a3b7f36c9d7fe3f
1 #!/usr/bin/env python
2 # Copyright (C) 2013 Google Inc. All rights reserved.
4 # Redistribution and use in source and binary forms, with or without
5 # modification, are permitted provided that the following conditions are
6 # met:
8 # * Redistributions of source code must retain the above copyright
9 # notice, this list of conditions and the following disclaimer.
10 # * Redistributions in binary form must reproduce the above
11 # copyright notice, this list of conditions and the following disclaimer
12 # in the documentation and/or other materials provided with the
13 # distribution.
14 # * Neither the name of Google Inc. nor the names of its
15 # contributors may be used to endorse or promote products derived from
16 # this software without specific prior written permission.
18 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 import os.path
31 import sys
33 import in_generator
34 import license
35 import name_utilities
36 import template_expander
39 HEADER_TEMPLATE = """%(license)s
41 #ifndef %(namespace)s%(suffix)sHeaders_h
42 #define %(namespace)s%(suffix)sHeaders_h
43 %(base_header_for_suffix)s
44 %(includes)s
46 #endif // %(namespace)s%(suffix)sHeaders_h
47 """
50 def case_insensitive_matching(name):
51 return (name == ('HTMLEvents')
52 or name == 'Event'
53 or name == 'Events'
54 or name.startswith('UIEvent')
55 or name.startswith('CustomEvent')
56 or name.startswith('MouseEvent'))
59 class EventFactoryWriter(in_generator.Writer):
60 defaults = {
61 'ImplementedAs': None,
62 'Conditional': None,
63 'RuntimeEnabled': None,
65 default_parameters = {
66 'export': '',
67 'namespace': '',
68 'suffix': '',
70 filters = {
71 'cpp_name': name_utilities.cpp_name,
72 'enable_conditional': name_utilities.enable_conditional_if_endif,
73 'lower_first': name_utilities.lower_first,
74 'case_insensitive_matching': case_insensitive_matching,
75 'script_name': name_utilities.script_name,
78 def __init__(self, in_file_path):
79 super(EventFactoryWriter, self).__init__(in_file_path)
80 self.namespace = self.in_file.parameters['namespace'].strip('"')
81 self.suffix = self.in_file.parameters['suffix'].strip('"')
82 self._validate_entries()
83 self._outputs = {(self.namespace + self.suffix + "Headers.h"): self.generate_headers_header,
84 (self.namespace + self.suffix + ".cpp"): self.generate_implementation,
87 def _validate_entries(self):
88 # If there is more than one entry with the same script name, only the first one will ever
89 # be hit in practice, and so we'll silently ignore any properties requested for the second
90 # (like RuntimeEnabled - see crbug.com/332588).
91 entries_by_script_name = dict()
92 for entry in self.in_file.name_dictionaries:
93 script_name = name_utilities.script_name(entry)
94 if script_name in entries_by_script_name:
95 self._fatal('Multiple entries with script_name=%(script_name)s: %(name1)s %(name2)s' % {
96 'script_name': script_name,
97 'name1': entry['name'],
98 'name2': entries_by_script_name[script_name]['name']})
99 entries_by_script_name[script_name] = entry
101 def _fatal(self, message):
102 print 'FATAL ERROR: ' + message
103 exit(1)
105 def _headers_header_include_path(self, entry):
106 if entry['ImplementedAs']:
107 path = os.path.dirname(entry['name'])
108 if len(path):
109 path += '/'
110 path += entry['ImplementedAs']
111 else:
112 path = entry['name']
113 return path + '.h'
115 def _headers_header_includes(self, entries):
116 includes = dict()
117 for entry in entries:
118 cpp_name = name_utilities.cpp_name(entry)
119 # Avoid duplicate includes.
120 if cpp_name in includes:
121 continue
122 if self.suffix == 'Modules':
123 subdir_name = 'modules'
124 else:
125 subdir_name = 'core'
126 include = '#include "%(path)s"\n#include "bindings/%(subdir_name)s/v8/V8%(script_name)s.h"' % {
127 'path': self._headers_header_include_path(entry),
128 'script_name': name_utilities.script_name(entry),
129 'subdir_name': subdir_name,
131 includes[cpp_name] = self.wrap_with_condition(include, entry['Conditional'])
132 return includes.values()
134 def generate_headers_header(self):
135 base_header_for_suffix = ''
136 if self.suffix:
137 base_header_for_suffix = '\n#include "core/%(namespace)sHeaders.h"\n' % {'namespace': self.namespace}
138 return HEADER_TEMPLATE % {
139 'license': license.license_for_generated_cpp(),
140 'namespace': self.namespace,
141 'suffix': self.suffix,
142 'base_header_for_suffix': base_header_for_suffix,
143 'includes': '\n'.join(self._headers_header_includes(self.in_file.name_dictionaries)),
146 @template_expander.use_jinja('EventFactory.cpp.tmpl', filters=filters)
147 def generate_implementation(self):
148 return {
149 'namespace': self.namespace,
150 'suffix': self.suffix,
151 'events': self.in_file.name_dictionaries,
155 if __name__ == "__main__":
156 in_generator.Maker(EventFactoryWriter).main(sys.argv)