Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(23)

Side by Side Diff: third_party/WebKit/Source/bindings/scripts/code_generator_web_module.py

Issue 2648173002: Rename webmodule codegen bits to WebAgentAPI. (Closed)
Patch Set: Changed to WebAgentAPI. Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 # Copyright 2016 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file.
4
5 # pylint: disable=import-error,print-statement,relative-import
6
7 """Generates Blink Web Module bindings.
8
9 The Blink Web Module bindings provide a stable, IDL-generated interface for the
10 Web Modules.
11
12 The Web Modules are the high-level services like Autofill,
13 Autocomplete, Translate, Distiller, Phishing Detector, and others. Web Modules
14 typically want to introspec the document and rendering infromation to implement
15 browser features.
16
17 The bindings are meant to be as simple and as ephemeral as possible, mostly just
18 wrapping existing DOM classes. Their primary goal is to avoid leaking the actual
19 DOM classes to the Web Modules layer.
20 """
21
22 import os
23 import posixpath
24
25 from code_generator import CodeGeneratorBase, render_template
26 # TODO(dglazkov): Move TypedefResolver to code_generator.py
27 from code_generator_v8 import TypedefResolver
28 from name_style_converter import NameStyleConverter
29
30 MODULE_PYNAME = os.path.splitext(os.path.basename(__file__))[0] + '.py'
31
32 STRING_INCLUDE_PATH = 'wtf/text/WTFString.h'
33 WEB_MODULE_IDL_ATTRIBUTE = 'WebModuleAPI'
34
35
36 def interface_context(idl_interface, type_resolver):
37 builder = InterfaceContextBuilder(MODULE_PYNAME, type_resolver)
38 builder.set_class_name(idl_interface.name)
39 builder.set_inheritance(idl_interface.parent)
40
41 for idl_attribute in idl_interface.attributes:
42 builder.add_attribute(idl_attribute)
43
44 for idl_operation in idl_interface.operations:
45 builder.add_operation(idl_operation)
46
47 return builder.build()
48
49
50 class TypeResolver(object):
51 """Resolves Web IDL types into corresponding C++ types and include paths
52 to the generated and existing files."""
53
54 def __init__(self, interfaces_info):
55 self.interfaces_info = interfaces_info
56
57 def includes_from_interface(self, interface_name):
58 interface_info = self.interfaces_info.get(interface_name)
59 if interface_info is None:
60 raise KeyError('Unknown interface "%s".' % interface_name)
61 return set([interface_info['include_path']])
62
63 def _includes_from_type(self, idl_type):
64 if idl_type.is_void:
65 return set()
66 if idl_type.is_primitive_type:
67 return set()
68 if idl_type.is_string_type:
69 return set([STRING_INCLUDE_PATH])
70
71 # TODO(dglazkov): Handle complex/weird types.
72 return self.includes_from_interface(idl_type.base_type)
73
74 def includes_from_definition(self, idl_definition):
75 return self._includes_from_type(idl_definition.idl_type)
76
77 def type_from_definition(self, idl_definition):
78 # TODO(dglazkov): The output of this method must be a reasonable C++
79 # type that can be used directly in the jinja2 template.
80 return idl_definition.idl_type.base_type
81
82 def base_class_includes(self):
83 return set(['platform/heap/Handle.h'])
84
85
86 class InterfaceContextBuilder(object):
87 def __init__(self, code_generator, type_resolver):
88 self.result = {'code_generator': code_generator}
89 self.type_resolver = type_resolver
90
91 def set_class_name(self, class_name):
92 converter = NameStyleConverter(class_name)
93 self.result['class_name'] = converter.to_all_cases()
94 self._ensure_set('cpp_includes').update(
95 self.type_resolver.includes_from_interface(class_name))
96
97 def set_inheritance(self, base_interface):
98 if base_interface is None:
99 self._ensure_set('header_includes').update(
100 self.type_resolver.base_class_includes())
101 return
102 self.result['base_class'] = base_interface
103 self._ensure_set('header_includes').update(
104 self.type_resolver.includes_from_interface(base_interface))
105
106 def _ensure_set(self, name):
107 return self.result.setdefault(name, set())
108
109 def _ensure_list(self, name):
110 return self.result.setdefault(name, [])
111
112 def add_attribute(self, idl_attribute):
113 self._ensure_list('attributes').append(
114 self.create_attribute(idl_attribute))
115 self._ensure_set('cpp_includes').update(
116 self.type_resolver.includes_from_definition(idl_attribute))
117
118 def add_operation(self, idl_operation):
119 if not idl_operation.name:
120 return
121 self._ensure_list('methods').append(
122 self.create_method(idl_operation))
123 self._ensure_set('cpp_includes').update(
124 self.type_resolver.includes_from_definition(idl_operation))
125
126 def create_method(self, idl_operation):
127 name = idl_operation.name
128 return_type = self.type_resolver.type_from_definition(idl_operation)
129 return {
130 'name': name,
131 'return_type': return_type
132 }
133
134 def create_attribute(self, idl_attribute):
135 name = idl_attribute.name
136 return_type = self.type_resolver.type_from_definition(idl_attribute)
137 return {
138 'name': name,
139 'return_type': return_type
140 }
141
142 def build(self):
143 return self.result
144
145
146 class CodeGeneratorWebModule(CodeGeneratorBase):
147 def __init__(self, info_provider, cache_dir, output_dir):
148 CodeGeneratorBase.__init__(self, MODULE_PYNAME, info_provider,
149 cache_dir, output_dir)
150 self.type_resolver = TypeResolver(info_provider.interfaces_info)
151 self.typedef_resolver = TypedefResolver(info_provider)
152
153 def get_template(self, file_extension):
154 template_filename = 'web_module_interface.%s.tmpl' % file_extension
155 return self.jinja_env.get_template(template_filename)
156
157 def generate_file(self, template_context, file_extension):
158 template = self.get_template(file_extension)
159 path = posixpath.join(
160 self.output_dir,
161 '%s.%s' % (template_context['class_name']['snake_case'],
162 file_extension))
163 text = render_template(template, template_context)
164 return (path, text)
165
166 def generate_interface_code(self, interface):
167 # TODO(dglazkov): Implement callback interfaces.
168 # TODO(dglazkov): Make sure partial interfaces are handled.
169 if interface.is_callback or interface.is_partial:
170 raise ValueError('Partial or callback interfaces are not supported')
171
172 template_context = interface_context(interface, self.type_resolver)
173
174 return (
175 self.generate_file(template_context, 'h'),
176 self.generate_file(template_context, 'cc')
177 )
178
179 def generate_code(self, definitions, definition_name):
180 self.typedef_resolver.resolve(definitions, definition_name)
181
182 # TODO(dglazkov): Implement dictionaries
183 if definition_name not in definitions.interfaces:
184 return None
185
186 interface = definitions.interfaces[definition_name]
187 if WEB_MODULE_IDL_ATTRIBUTE not in interface.extended_attributes:
188 return None
189
190 return self.generate_interface_code(interface)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698