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

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: Moar cleanup. 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 OILPAN_INCLUDE_PATH = 'platform/heap/Handle.h'
haraken 2017/02/11 09:56:46 BLINK_GC_INCLUDE_PATH Oilpan is a project name an
dglazkov 2017/02/11 21:56:20 Good point. Incorporated inline.
33 STRING_INCLUDE_PATH = 'wtf/text/WTFString.h'
32 WEB_MODULE_IDL_ATTRIBUTE = 'WebModuleAPI' 34 WEB_MODULE_IDL_ATTRIBUTE = 'WebModuleAPI'
33 STRING_INCLUDE_PATH = 'wtf/text/WTFString.h'
34 35
35 def interface_context(idl_interface): 36
36 builder = InterfaceContextBuilder(MODULE_PYNAME, TypeResolver()) 37 def interface_context(idl_interface, type_resolver):
38 builder = InterfaceContextBuilder(MODULE_PYNAME, type_resolver)
37 builder.set_class_name(idl_interface.name) 39 builder.set_class_name(idl_interface.name)
38 builder.set_inheritance(idl_interface.parent) 40 builder.set_inheritance(idl_interface.parent)
39 41
40 for idl_attribute in idl_interface.attributes: 42 for idl_attribute in idl_interface.attributes:
41 builder.add_attribute(idl_attribute) 43 builder.add_attribute(idl_attribute)
42 44
43 for idl_operation in idl_interface.operations: 45 for idl_operation in idl_interface.operations:
44 builder.add_operation(idl_operation) 46 builder.add_operation(idl_operation)
45 47
46 return builder.build() 48 return builder.build()
47 49
48 50
49 class TypeResolver(object): 51 class TypeResolver(object):
50 """Resolves Web IDL types into corresponding C++ types and include paths 52 """Resolves Web IDL types into corresponding C++ types and include paths
51 to the generated and existing files.""" 53 to the generated and existing files."""
52 54
53 def includes_from_interface(self, base_type): 55 def __init__(self, interfaces_info):
54 # TODO(dglazkov): Are there any exceptional conditions here? 56 self.interfaces_info = interfaces_info
55 return set([base_type]) 57
58 def includes_from_interface(self, interface_name):
59 interface_info = self.interfaces_info.get(interface_name)
60 if interface_info is None:
61 raise KeyError('Unkown interface "%s".' % interface_name)
62 return set([interface_info['include_path']])
56 63
57 def _includes_from_type(self, idl_type): 64 def _includes_from_type(self, idl_type):
58 if idl_type.is_void: 65 if idl_type.is_void:
59 return set() 66 return set()
60 if idl_type.is_primitive_type: 67 if idl_type.is_primitive_type:
61 return set() 68 return set()
62 if idl_type.is_string_type: 69 if idl_type.is_string_type:
63 return set([STRING_INCLUDE_PATH]) 70 return set([STRING_INCLUDE_PATH])
64 71
65 # TODO(dglazkov): Handle complex/weird types. 72 # TODO(dglazkov): Handle complex/weird types.
66 # TODO(dglazkov): Make these proper paths to generated and non-generated 73 return self.includes_from_interface(idl_type.base_type)
67 # files.
68 return set([idl_type.base_type])
69 74
70 def includes_from_definition(self, idl_definition): 75 def includes_from_definition(self, idl_definition):
71 return self._includes_from_type(idl_definition.idl_type) 76 return self._includes_from_type(idl_definition.idl_type)
72 77
73 def type_from_definition(self, idl_definition): 78 def type_from_definition(self, idl_definition):
74 # TODO(dglazkov): The output of this method must be a reasonable C++ 79 # TODO(dglazkov): The output of this method must be a reasonable C++
75 # type that can be used directly in the jinja2 template. 80 # type that can be used directly in the jinja2 template.
76 return idl_definition.idl_type.base_type 81 return idl_definition.idl_type.base_type
77 82
83 def base_class_includes(self):
84 return set([OILPAN_INCLUDE_PATH])
85
78 86
79 class InterfaceContextBuilder(object): 87 class InterfaceContextBuilder(object):
80 def __init__(self, code_generator, type_resolver): 88 def __init__(self, code_generator, type_resolver):
81 self.result = {'code_generator': code_generator} 89 self.result = {'code_generator': code_generator}
82 self.type_resolver = type_resolver 90 self.type_resolver = type_resolver
83 91
84 def set_class_name(self, class_name): 92 def set_class_name(self, class_name):
85 converter = NameStyleConverter(class_name) 93 converter = NameStyleConverter(class_name)
86 self.result['class_name'] = converter.to_all_cases() 94 self.result['class_name'] = converter.to_all_cases()
95 self._ensure_set('cpp_includes').update(
96 self.type_resolver.includes_from_interface(class_name))
87 97
88 def set_inheritance(self, base_interface): 98 def set_inheritance(self, base_interface):
89 if base_interface is None: 99 if base_interface is None:
100 self._ensure_set('header_includes').update(
101 self.type_resolver.base_class_includes())
90 return 102 return
91 self.result['inherits_expression'] = ' : public %s' % base_interface 103 self.result['base_class'] = base_interface
92 self._ensure_set('cpp_includes').update( 104 self._ensure_set('header_includes').update(
93 self.type_resolver.includes_from_interface(base_interface)) 105 self.type_resolver.includes_from_interface(base_interface))
94 106
95 def _ensure_set(self, name): 107 def _ensure_set(self, name):
96 return self.result.setdefault(name, set()) 108 return self.result.setdefault(name, set())
97 109
98 def _ensure_list(self, name): 110 def _ensure_list(self, name):
99 return self.result.setdefault(name, []) 111 return self.result.setdefault(name, [])
100 112
101 def add_attribute(self, idl_attribute): 113 def add_attribute(self, idl_attribute):
102 self._ensure_list('attributes').append( 114 self._ensure_list('attributes').append(
(...skipping 26 matching lines...) Expand all
129 } 141 }
130 142
131 def build(self): 143 def build(self):
132 return self.result 144 return self.result
133 145
134 146
135 class CodeGeneratorWebModule(CodeGeneratorBase): 147 class CodeGeneratorWebModule(CodeGeneratorBase):
136 def __init__(self, info_provider, cache_dir, output_dir): 148 def __init__(self, info_provider, cache_dir, output_dir):
137 CodeGeneratorBase.__init__(self, MODULE_PYNAME, info_provider, 149 CodeGeneratorBase.__init__(self, MODULE_PYNAME, info_provider,
138 cache_dir, output_dir) 150 cache_dir, output_dir)
151 self.type_resolver = TypeResolver(info_provider.interfaces_info)
139 self.typedef_resolver = TypedefResolver(info_provider) 152 self.typedef_resolver = TypedefResolver(info_provider)
140 153
141 def get_template(self, file_extension): 154 def get_template(self, file_extension):
142 template_filename = 'web_module_interface.%s.tmpl' % file_extension 155 template_filename = 'web_module_interface.%s.tmpl' % file_extension
143 return self.jinja_env.get_template(template_filename) 156 return self.jinja_env.get_template(template_filename)
144 157
145 def generate_file(self, template_context, file_extension): 158 def generate_file(self, template_context, file_extension):
146 template = self.get_template(file_extension) 159 template = self.get_template(file_extension)
147 path = posixpath.join( 160 path = posixpath.join(
148 self.output_dir, 161 self.output_dir,
149 '%s.%s' % (template_context['class_name']['snake_case'], 162 '%s.%s' % (template_context['class_name']['snake_case'],
150 file_extension)) 163 file_extension))
151 text = render_template(template, template_context) 164 text = render_template(template, template_context)
152 return (path, text) 165 return (path, text)
153 166
154 def generate_interface_code(self, interface): 167 def generate_interface_code(self, interface):
155 # TODO(dglazkov): Implement callback interfaces. 168 # TODO(dglazkov): Implement callback interfaces.
156 # TODO(dglazkov): Make sure partial interfaces are handled. 169 # TODO(dglazkov): Make sure partial interfaces are handled.
157 if interface.is_callback or interface.is_partial: 170 if interface.is_callback or interface.is_partial:
158 raise ValueError('Partial or callback interfaces are not supported') 171 raise ValueError('Partial or callback interfaces are not supported')
159 172
160 template_context = interface_context(interface) 173 template_context = interface_context(interface, self.type_resolver)
161 174
162 return ( 175 return (
163 self.generate_file(template_context, 'h'), 176 self.generate_file(template_context, 'h'),
164 self.generate_file(template_context, 'cc') 177 self.generate_file(template_context, 'cc')
165 ) 178 )
166 179
167 def generate_code(self, definitions, definition_name): 180 def generate_code(self, definitions, definition_name):
168 self.typedef_resolver.resolve(definitions, definition_name) 181 self.typedef_resolver.resolve(definitions, definition_name)
169 182
170 # TODO(dglazkov): Implement dictionaries 183 # TODO(dglazkov): Implement dictionaries
171 if definition_name not in definitions.interfaces: 184 if definition_name not in definitions.interfaces:
172 return None 185 return None
173 186
174 interface = definitions.interfaces[definition_name] 187 interface = definitions.interfaces[definition_name]
175 if WEB_MODULE_IDL_ATTRIBUTE not in interface.extended_attributes: 188 if WEB_MODULE_IDL_ATTRIBUTE not in interface.extended_attributes:
176 return None 189 return None
177 190
178 return self.generate_interface_code(interface) 191 return self.generate_interface_code(interface)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698