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

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

Issue 2688933003: [Web Agents API]: Start fleshing out generated code. (Closed)
Patch Set: Rebased. Created 3 years, 10 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
1 # Copyright 2016 The Chromium Authors. All rights reserved. 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 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 # pylint: disable=import-error,print-statement,relative-import 5 # pylint: disable=import-error,print-statement,relative-import
6 6
7 """Generates Blink Web Module bindings. 7 """Generates Blink Web Module bindings.
8 8
9 The Blink Web Module bindings provide a stable, IDL-generated interface for the 9 The Blink Web Module bindings provide a stable, IDL-generated interface for the
10 Web Modules. 10 Web Modules.
(...skipping 11 matching lines...) Expand all
22 import os 22 import os
23 import posixpath 23 import posixpath
24 24
25 from code_generator import CodeGeneratorBase, render_template 25 from code_generator import CodeGeneratorBase, render_template
26 # TODO(dglazkov): Move TypedefResolver to code_generator.py 26 # TODO(dglazkov): Move TypedefResolver to code_generator.py
27 from code_generator_v8 import TypedefResolver 27 from code_generator_v8 import TypedefResolver
28 from name_style_converter import NameStyleConverter 28 from name_style_converter import NameStyleConverter
29 29
30 MODULE_PYNAME = os.path.splitext(os.path.basename(__file__))[0] + '.py' 30 MODULE_PYNAME = os.path.splitext(os.path.basename(__file__))[0] + '.py'
31 31
32 STRING_INCLUDE_PATH = 'wtf/text/WTFString.h'
32 WEB_MODULE_IDL_ATTRIBUTE = 'WebModuleAPI' 33 WEB_MODULE_IDL_ATTRIBUTE = 'WebModuleAPI'
33 STRING_INCLUDE_PATH = 'wtf/text/WTFString.h'
34 34
35 def interface_context(idl_interface): 35
36 builder = InterfaceContextBuilder(MODULE_PYNAME, TypeResolver()) 36 def interface_context(idl_interface, type_resolver):
37 builder = InterfaceContextBuilder(MODULE_PYNAME, type_resolver)
37 builder.set_class_name(idl_interface.name) 38 builder.set_class_name(idl_interface.name)
38 builder.set_inheritance(idl_interface.parent) 39 builder.set_inheritance(idl_interface.parent)
39 40
40 for idl_attribute in idl_interface.attributes: 41 for idl_attribute in idl_interface.attributes:
41 builder.add_attribute(idl_attribute) 42 builder.add_attribute(idl_attribute)
42 43
43 for idl_operation in idl_interface.operations: 44 for idl_operation in idl_interface.operations:
44 builder.add_operation(idl_operation) 45 builder.add_operation(idl_operation)
45 46
46 return builder.build() 47 return builder.build()
47 48
48 49
49 class TypeResolver(object): 50 class TypeResolver(object):
50 """Resolves Web IDL types into corresponding C++ types and include paths 51 """Resolves Web IDL types into corresponding C++ types and include paths
51 to the generated and existing files.""" 52 to the generated and existing files."""
52 53
53 def includes_from_interface(self, base_type): 54 def __init__(self, interfaces_info):
54 # TODO(dglazkov): Are there any exceptional conditions here? 55 self.interfaces_info = interfaces_info
55 return set([base_type]) 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']])
56 62
57 def _includes_from_type(self, idl_type): 63 def _includes_from_type(self, idl_type):
58 if idl_type.is_void: 64 if idl_type.is_void:
59 return set() 65 return set()
60 if idl_type.is_primitive_type: 66 if idl_type.is_primitive_type:
61 return set() 67 return set()
62 if idl_type.is_string_type: 68 if idl_type.is_string_type:
63 return set([STRING_INCLUDE_PATH]) 69 return set([STRING_INCLUDE_PATH])
64 70
65 # TODO(dglazkov): Handle complex/weird types. 71 # TODO(dglazkov): Handle complex/weird types.
66 # TODO(dglazkov): Make these proper paths to generated and non-generated 72 return self.includes_from_interface(idl_type.base_type)
67 # files.
68 return set([idl_type.base_type])
69 73
70 def includes_from_definition(self, idl_definition): 74 def includes_from_definition(self, idl_definition):
71 return self._includes_from_type(idl_definition.idl_type) 75 return self._includes_from_type(idl_definition.idl_type)
72 76
73 def type_from_definition(self, idl_definition): 77 def type_from_definition(self, idl_definition):
74 # TODO(dglazkov): The output of this method must be a reasonable C++ 78 # TODO(dglazkov): The output of this method must be a reasonable C++
75 # type that can be used directly in the jinja2 template. 79 # type that can be used directly in the jinja2 template.
76 return idl_definition.idl_type.base_type 80 return idl_definition.idl_type.base_type
77 81
82 def base_class_includes(self):
83 return set(['platform/heap/Handle.h'])
84
78 85
79 class InterfaceContextBuilder(object): 86 class InterfaceContextBuilder(object):
80 def __init__(self, code_generator, type_resolver): 87 def __init__(self, code_generator, type_resolver):
81 self.result = {'code_generator': code_generator} 88 self.result = {'code_generator': code_generator}
82 self.type_resolver = type_resolver 89 self.type_resolver = type_resolver
83 90
84 def set_class_name(self, class_name): 91 def set_class_name(self, class_name):
85 converter = NameStyleConverter(class_name) 92 converter = NameStyleConverter(class_name)
86 self.result['class_name'] = converter.to_all_cases() 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))
87 96
88 def set_inheritance(self, base_interface): 97 def set_inheritance(self, base_interface):
89 if base_interface is None: 98 if base_interface is None:
99 self._ensure_set('header_includes').update(
100 self.type_resolver.base_class_includes())
90 return 101 return
91 self.result['inherits_expression'] = ' : public %s' % base_interface 102 self.result['base_class'] = base_interface
92 self._ensure_set('cpp_includes').update( 103 self._ensure_set('header_includes').update(
93 self.type_resolver.includes_from_interface(base_interface)) 104 self.type_resolver.includes_from_interface(base_interface))
94 105
95 def _ensure_set(self, name): 106 def _ensure_set(self, name):
96 return self.result.setdefault(name, set()) 107 return self.result.setdefault(name, set())
97 108
98 def _ensure_list(self, name): 109 def _ensure_list(self, name):
99 return self.result.setdefault(name, []) 110 return self.result.setdefault(name, [])
100 111
101 def add_attribute(self, idl_attribute): 112 def add_attribute(self, idl_attribute):
102 self._ensure_list('attributes').append( 113 self._ensure_list('attributes').append(
(...skipping 26 matching lines...) Expand all
129 } 140 }
130 141
131 def build(self): 142 def build(self):
132 return self.result 143 return self.result
133 144
134 145
135 class CodeGeneratorWebModule(CodeGeneratorBase): 146 class CodeGeneratorWebModule(CodeGeneratorBase):
136 def __init__(self, info_provider, cache_dir, output_dir): 147 def __init__(self, info_provider, cache_dir, output_dir):
137 CodeGeneratorBase.__init__(self, MODULE_PYNAME, info_provider, 148 CodeGeneratorBase.__init__(self, MODULE_PYNAME, info_provider,
138 cache_dir, output_dir) 149 cache_dir, output_dir)
150 self.type_resolver = TypeResolver(info_provider.interfaces_info)
139 self.typedef_resolver = TypedefResolver(info_provider) 151 self.typedef_resolver = TypedefResolver(info_provider)
140 152
141 def get_template(self, file_extension): 153 def get_template(self, file_extension):
142 template_filename = 'web_module_interface.%s.tmpl' % file_extension 154 template_filename = 'web_module_interface.%s.tmpl' % file_extension
143 return self.jinja_env.get_template(template_filename) 155 return self.jinja_env.get_template(template_filename)
144 156
145 def generate_file(self, template_context, file_extension): 157 def generate_file(self, template_context, file_extension):
146 template = self.get_template(file_extension) 158 template = self.get_template(file_extension)
147 path = posixpath.join( 159 path = posixpath.join(
148 self.output_dir, 160 self.output_dir,
149 '%s.%s' % (template_context['class_name']['snake_case'], 161 '%s.%s' % (template_context['class_name']['snake_case'],
150 file_extension)) 162 file_extension))
151 text = render_template(template, template_context) 163 text = render_template(template, template_context)
152 return (path, text) 164 return (path, text)
153 165
154 def generate_interface_code(self, interface): 166 def generate_interface_code(self, interface):
155 # TODO(dglazkov): Implement callback interfaces. 167 # TODO(dglazkov): Implement callback interfaces.
156 # TODO(dglazkov): Make sure partial interfaces are handled. 168 # TODO(dglazkov): Make sure partial interfaces are handled.
157 if interface.is_callback or interface.is_partial: 169 if interface.is_callback or interface.is_partial:
158 raise ValueError('Partial or callback interfaces are not supported') 170 raise ValueError('Partial or callback interfaces are not supported')
159 171
160 template_context = interface_context(interface) 172 template_context = interface_context(interface, self.type_resolver)
161 173
162 return ( 174 return (
163 self.generate_file(template_context, 'h'), 175 self.generate_file(template_context, 'h'),
164 self.generate_file(template_context, 'cc') 176 self.generate_file(template_context, 'cc')
165 ) 177 )
166 178
167 def generate_code(self, definitions, definition_name): 179 def generate_code(self, definitions, definition_name):
168 self.typedef_resolver.resolve(definitions, definition_name) 180 self.typedef_resolver.resolve(definitions, definition_name)
169 181
170 # TODO(dglazkov): Implement dictionaries 182 # TODO(dglazkov): Implement dictionaries
171 if definition_name not in definitions.interfaces: 183 if definition_name not in definitions.interfaces:
172 return None 184 return None
173 185
174 interface = definitions.interfaces[definition_name] 186 interface = definitions.interfaces[definition_name]
175 if WEB_MODULE_IDL_ATTRIBUTE not in interface.extended_attributes: 187 if WEB_MODULE_IDL_ATTRIBUTE not in interface.extended_attributes:
176 return None 188 return None
177 189
178 return self.generate_interface_code(interface) 190 return self.generate_interface_code(interface)
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/bindings/DEPS ('k') | third_party/WebKit/Source/bindings/scripts/code_generator_web_module_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698