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

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: Created 3 years, 11 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
29 MODULE_PYNAME = os.path.splitext(os.path.basename(__file__))[0] + '.py'
30
31 WEB_MODULE_IDL_ATTRIBUTE = 'WebModuleAPI'
32 STRING_INCLUDE_PATH = 'wtf/text/WTFString.h'
33
34 def interface_context(idl_interface):
35 builder = InterfaceContextBuilder(MODULE_PYNAME, TypeResolver())
36 builder.set_class_name(idl_interface.name)
37 builder.set_inheritance(idl_interface.parent)
38
39 for idl_attribute in idl_interface.attributes:
40 builder.add_attribute(idl_attribute)
41
42 for idl_operation in idl_interface.operations:
43 builder.add_operation(idl_operation)
44
45 return builder.build()
46
47
48 class TypeResolver(object):
49 """Resolves Web IDL types into corresponding C++ types and include paths
50 to the generated and existing files."""
51
52 def includes_from_interface(self, base_type):
53 # TODO(dglazkov): Are there any exceptional conditions here?
54 return set([base_type])
55
56 def _includes_from_type(self, idl_type):
57 if idl_type.is_void:
58 return set()
59 if idl_type.is_primitive_type:
60 return set()
61 if idl_type.is_string_type:
62 return set([STRING_INCLUDE_PATH])
63
64 # TODO(dglazkov): Handle complex/weird types.
65 # TODO(dglazkov): Make these proper paths to generated and non-generated
66 # files.
67 return set([idl_type.base_type])
68
69 def includes_from_definition(self, idl_definition):
70 return self._includes_from_type(idl_definition.idl_type)
71
72 def type_from_definition(self, idl_definition):
73 # TODO(dglazkov): The output of this method must be a reasonable C++
74 # type that can be used directly in the jinja2 template.
75 return idl_definition.idl_type.base_type
76
77
78 class InterfaceContextBuilder(object):
79 def __init__(self, code_generator, type_resolver):
80 self.result = {'code_generator': code_generator}
81 self.type_resolver = type_resolver
82
83 def set_class_name(self, class_name):
84 self.result['class_name'] = class_name
85
86 def set_inheritance(self, base_interface):
87 if base_interface is None:
88 return
89 self.result['inherits_expression'] = ' : public %s' % base_interface
90 self._ensure_set('cpp_includes').update(
91 self.type_resolver.includes_from_interface(base_interface))
92
93 def _ensure_set(self, name):
94 return self.result.setdefault(name, set())
95
96 def _ensure_list(self, name):
97 return self.result.setdefault(name, [])
98
99 def add_attribute(self, idl_attribute):
100 self._ensure_list('attributes').append(
101 self.create_attribute(idl_attribute))
102 self._ensure_set('cpp_includes').update(
103 self.type_resolver.includes_from_definition(idl_attribute))
104
105 def add_operation(self, idl_operation):
106 if not idl_operation.name:
107 return
108 self._ensure_list('methods').append(
109 self.create_method(idl_operation))
110 self._ensure_set('cpp_includes').update(
111 self.type_resolver.includes_from_definition(idl_operation))
112
113 def create_method(self, idl_operation):
114 name = idl_operation.name
115 return_type = self.type_resolver.type_from_definition(idl_operation)
116 return {
117 'name': name,
118 'return_type': return_type
119 }
120
121 def create_attribute(self, idl_attribute):
122 name = idl_attribute.name
123 return_type = self.type_resolver.type_from_definition(idl_attribute)
124 return {
125 'name': name,
126 'return_type': return_type
127 }
128
129 def build(self):
130 return self.result
131
132
133 class CodeGeneratorWebModule(CodeGeneratorBase):
134 def __init__(self, info_provider, cache_dir, output_dir):
135 CodeGeneratorBase.__init__(self, MODULE_PYNAME, info_provider,
136 cache_dir, output_dir)
137 self.typedef_resolver = TypedefResolver(info_provider)
138
139 def get_template(self, file_extension):
140 template_filename = 'web_module_interface.%s.tmpl' % file_extension
141 return self.jinja_env.get_template(template_filename)
142
143 # TODO(dglazkov): Move to CodeGeneratorBase.
144 def output_paths(self, definition_name):
145 header_path = posixpath.join(self.output_dir,
146 'Web%s.h' % definition_name)
147 cpp_path = posixpath.join(self.output_dir,
148 'Web%s.cpp' % definition_name)
149 return header_path, cpp_path
150
151 def generate_interface_code(self, interface):
152 # TODO(dglazkov): Implement callback interfaces.
153 # TODO(dglazkov): Make sure partial interfaces are handled.
154 if interface.is_callback or interface.is_partial:
155 raise ValueError('Partial or callback interfaces are not supported')
156
157 template_context = interface_context(interface)
158
159 cpp_template = self.get_template('cpp')
160 header_template = self.get_template('h')
161 cpp_text = render_template(cpp_template, template_context)
162 header_text = render_template(header_template, template_context)
163 header_path, cpp_path = self.output_paths(interface.name)
164
165 return (
166 (header_path, header_text),
167 (cpp_path, cpp_text)
168 )
169
170 def generate_code(self, definitions, definition_name):
171 self.typedef_resolver.resolve(definitions, definition_name)
172 header_path, cpp_path = self.output_paths(definition_name)
173
174 template_context = {}
175 # TODO(dglazkov): Implement dictionaries
176 if definition_name not in definitions.interfaces:
177 return None
178
179 interface = definitions.interfaces[definition_name]
180 if WEB_MODULE_IDL_ATTRIBUTE not in interface.extended_attributes:
181 return None
182
183 return self.generate_interface_code(interface)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698