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

Side by Side Diff: mojo/public/bindings/generators/mojom_cpp_generator.py

Issue 52973003: mojo: break struct headers into headers and source (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Add constant for header size Created 7 years, 1 month 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 | Annotate | Revision Log
OLDNEW
1 # Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 # Copyright (c) 2013 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 """Generates C++ source files from a mojom.Module."""
6
5 import datetime 7 import datetime
6 import mojom 8 import mojom
7 import mojom_pack 9 import mojom_pack
8 import os 10 import os
9 import sys 11 import sys
10 12
11 from string import Template 13 from string import Template
12 14
13 # mojom_cpp_generator provides a way to generate c++ code from a mojom.Module. 15 # mojom_cpp_generator provides a way to generate c++ code from a mojom.Module.
14 # cpp = mojom_cpp_generator.CPPGenerator(module) 16 # cpp = mojom_cpp_generator.CPPGenerator(module)
15 # cpp.GenerateFiles("/tmp/g") 17 # cpp.GenerateFiles("/tmp/g")
16 def ReadTemplate(filename): 18 def ReadTemplate(filename):
19 """Reads a string.Template from |filename|."""
17 dir = os.path.dirname(__file__) 20 dir = os.path.dirname(__file__)
18 with open(dir + '/' + filename, 'r') as file: 21 with open(dir + '/' + filename, 'r') as file:
19 return Template(file.read()) 22 return Template(file.read())
20 23
21 24
25 def AddForward(forwards, kind):
26 """Adds a forward class declaration line to the |forwards| set."""
27 if isinstance(kind, mojom.Struct):
28 forwards.add("class %s;" % kind.name.capitalize())
29 if isinstance(kind, mojom.Array):
30 AddForward(forwards, kind.kind)
31
32
33 def GetForwards(forwards):
34 """Returns a string suitable for substituting into a $FORWARDS section."""
35 if len(forwards) > 0:
36 return '\n'.join(sorted(forwards)) + '\n'
37 return ""
38
39
22 class CPPGenerator(object): 40 class CPPGenerator(object):
23 struct_template = ReadTemplate("cpp_struct.template") 41
24 interface_template = ReadTemplate("cpp_interface.template") 42 struct_header_template = ReadTemplate("module_struct.h")
43 struct_source_template = ReadTemplate("module_struct.cc")
44 interface_header_template = ReadTemplate("module_interface.h")
25 field_template = Template(" $itype ${field}_;") 45 field_template = Template(" $itype ${field}_;")
26 bool_field_template = Template(" uint8_t ${field}_ : 1;") 46 bool_field_template = Template(" uint8_t ${field}_ : 1;")
27 setter_template = \ 47 setter_template = \
28 Template(" void set_$field($stype $field) { ${field}_ = $field; }") 48 Template(" void set_$field($stype $field) { ${field}_ = $field; }")
29 getter_template = \ 49 getter_template = \
30 Template(" $gtype $field() const { return ${field}_; }") 50 Template(" $gtype $field() const { return ${field}_; }")
31 ptr_getter_template = \ 51 ptr_getter_template = \
32 Template(" $gtype $field() const { return ${field}_.ptr; }") 52 Template(" $gtype $field() const { return ${field}_.ptr; }")
33 pad_template = Template(" uint8_t _pad${count}_[$pad];") 53 pad_template = Template(" uint8_t _pad${count}_[$pad];")
54 HEADER_SIZE = 8
34 55
35 kind_to_type = { 56 kind_to_type = {
36 mojom.BOOL: "bool", 57 mojom.BOOL: "bool",
37 mojom.INT8: "int8_t", 58 mojom.INT8: "int8_t",
38 mojom.UINT8: "uint8_t", 59 mojom.UINT8: "uint8_t",
39 mojom.INT16: "int16_t", 60 mojom.INT16: "int16_t",
40 mojom.UINT16: "uint16_t", 61 mojom.UINT16: "uint16_t",
41 mojom.INT32: "int32_t", 62 mojom.INT32: "int32_t",
42 mojom.UINT32: "uint32_t", 63 mojom.UINT32: "uint32_t",
43 mojom.FLOAT: "float", 64 mojom.FLOAT: "float",
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
96 elif kind.spec == 's': 117 elif kind.spec == 's':
97 itype = "mojo::internal::StringPointer" 118 itype = "mojo::internal::StringPointer"
98 else: 119 else:
99 itype = cls.kind_to_type[kind] 120 itype = cls.kind_to_type[kind]
100 return cls.field_template.substitute(field=pf.field.name, itype=itype) 121 return cls.field_template.substitute(field=pf.field.name, itype=itype)
101 122
102 def GetHeaderGuard(self, component): 123 def GetHeaderGuard(self, component):
103 return "MOJO_GENERATED_BINDINGS_%s_%s_H_" % \ 124 return "MOJO_GENERATED_BINDINGS_%s_%s_H_" % \
104 (self.module.name.upper(), component.name.upper()) 125 (self.module.name.upper(), component.name.upper())
105 126
106 def OpenComponentFile(self, directory, component): 127 # Pass |output_dir| to emit files to disk. Omit |output_dir| to echo all files
107 filename = "%s_%s.h" % \ 128 # to stdout.
108 (self.module.name.lower(), component.name.lower()) 129 def __init__(self, module, header_dir, output_dir=None):
109 return open(directory + '/' + filename, "w+") 130 self.module = module
131 self.header_dir = header_dir
132 self.output_dir = output_dir
110 133
111 def __init__(self, module): 134 def WriteTemplateToFile(self, template, name, ext, **substitutions):
112 self.module = module 135 if self.output_dir is None:
113 self.file = file 136 file = sys.stdout
137 else:
138 filename = "%s_%s.%s" % \
139 (self.module.name.lower(), name.lower(), ext)
140 file = open(os.path.join(self.output_dir, filename), "w+")
141 try:
142 file.write(template.substitute(substitutions))
143 finally:
144 if self.output_dir is not None:
145 file.close()
114 146
115 def GenerateStruct(self, struct, file): 147 def GenerateStructHeader(self, struct):
116 fields = [] 148 fields = []
117 setters = [] 149 setters = []
118 getters = [] 150 getters = []
151 forwards = set()
119 152
120 ps = mojom_pack.PackedStruct(struct) 153 ps = mojom_pack.PackedStruct(struct)
121 pad_count = 0 154 pad_count = 0
122 num_fields = len(ps.packed_fields) 155 num_fields = len(ps.packed_fields)
123 for i in xrange(num_fields): 156 for i in xrange(num_fields):
124 pf = ps.packed_fields[i] 157 pf = ps.packed_fields[i]
125 fields.append(self.GetFieldLine(pf)) 158 fields.append(self.GetFieldLine(pf))
159 AddForward(forwards, pf.field.kind)
126 if i < (num_fields - 2): 160 if i < (num_fields - 2):
127 next_pf = ps.packed_fields[i+1] 161 next_pf = ps.packed_fields[i+1]
128 pad = next_pf.offset - (pf.offset + pf.size) 162 pad = next_pf.offset - (pf.offset + pf.size)
129 if pad > 0: 163 if pad > 0:
130 fields.append(self.pad_template.substitute(count=pad_count, pad=pad)) 164 fields.append(self.pad_template.substitute(count=pad_count, pad=pad))
131 pad_count += 1 165 pad_count += 1
132 setters.append(self.GetSetterLine(pf)) 166 setters.append(self.GetSetterLine(pf))
133 getters.append(self.GetGetterLine(pf)) 167 getters.append(self.GetGetterLine(pf))
134 168
135 if num_fields > 0: 169 if num_fields > 0:
136 last_field = ps.packed_fields[num_fields - 1] 170 last_field = ps.packed_fields[num_fields - 1]
137 offset = last_field.offset + last_field.size 171 offset = last_field.offset + last_field.size
138 pad = mojom_pack.GetPad(offset, 8) 172 pad = mojom_pack.GetPad(offset, 8)
139 if pad > 0: 173 if pad > 0:
140 fields.append(self.pad_template.substitute(count=pad_count, pad=pad)) 174 fields.append(self.pad_template.substitute(count=pad_count, pad=pad))
141 pad_count += 1 175 pad_count += 1
142 size = offset + pad 176 size = offset + pad
143 else: 177 else:
144 size = 0 178 size = 0
145 179
146 file.write(self.struct_template.substitute( 180 self.WriteTemplateToFile(self.struct_header_template, struct.name, 'h',
147 year = datetime.date.today().year, 181 YEAR = datetime.date.today().year,
148 header_guard = self.GetHeaderGuard(struct), 182 HEADER_GUARD = self.GetHeaderGuard(struct),
149 namespace = self.module.namespace, 183 NAMESPACE = self.module.namespace,
150 classname = struct.name.capitalize(), 184 CLASS = struct.name.capitalize(),
151 num_fields = len(ps.packed_fields), 185 SIZE = size + self.HEADER_SIZE,
152 size = size + 8, 186 FORWARDS = GetForwards(forwards),
153 setters = '\n'.join(setters), 187 SETTERS = '\n'.join(setters),
154 getters = '\n'.join(getters), 188 GETTERS = '\n'.join(getters),
155 fields = '\n'.join(fields))) 189 FIELDS = '\n'.join(fields))
156 190
157 def GenerateInterface(self, interface, file): 191 def GenerateStructSource(self, struct):
192 header = "%s_%s.h" % (self.module.name.lower(), struct.name.lower())
193 header = os.path.join(self.header_dir, header)
194 self.WriteTemplateToFile(self.struct_source_template, struct.name, 'cc',
195 YEAR = datetime.date.today().year,
196 NAMESPACE = self.module.namespace,
197 CLASS = struct.name.capitalize(),
198 NUM_FIELDS = len(struct.fields),
199 HEADER = header)
200
201 def GenerateInterfaceHeader(self, interface):
158 cpp_methods = [] 202 cpp_methods = []
203 forwards = set()
159 for method in interface.methods: 204 for method in interface.methods:
160 cpp_method = " virtual void %s(" % method.name 205 cpp_method = " virtual void %s(" % method.name
161 first_param = True 206 first_param = True
162 for param in method.parameters: 207 for param in method.parameters:
163 if first_param == True: 208 if first_param == True:
164 first_param = False 209 first_param = False
165 else: 210 else:
166 cpp_method += ", " 211 cpp_method += ", "
212 AddForward(forwards, param.kind)
167 cpp_method += "%s %s" % (self.GetConstType(param.kind), param.name) 213 cpp_method += "%s %s" % (self.GetConstType(param.kind), param.name)
168 cpp_method += ") = 0;" 214 cpp_method += ") = 0;"
169 cpp_methods.append(cpp_method) 215 cpp_methods.append(cpp_method)
170 216
171 file.write(self.interface_template.substitute( 217 self.WriteTemplateToFile(
172 year = datetime.date.today().year, 218 self.interface_header_template,
173 header_guard = self.GetHeaderGuard(interface), 219 interface.name,
174 namespace = self.module.namespace, 220 'h',
175 classname = interface.name.capitalize(), 221 YEAR = datetime.date.today().year,
176 methods = '\n'.join(cpp_methods))) 222 HEADER_GUARD = self.GetHeaderGuard(interface),
223 NAMESPACE = self.module.namespace,
224 CLASS = interface.name.capitalize(),
225 FORWARDS = GetForwards(forwards),
226 METHODS = '\n'.join(cpp_methods))
177 227
178 # Pass |directory| to emit files to disk. Omit |directory| to echo all files 228 def GenerateFiles(self):
179 # to stdout.
180 def GenerateFiles(self, directory=None):
181 for struct in self.module.structs: 229 for struct in self.module.structs:
182 if directory is None: 230 self.GenerateStructHeader(struct)
183 self.GenerateStruct(struct, sys.stdout) 231 self.GenerateStructSource(struct)
184 else:
185 with self.OpenComponentFile(directory, struct) as file:
186 self.GenerateStruct(struct, file)
187 for interface in self.module.interfaces: 232 for interface in self.module.interfaces:
188 if directory is None: 233 self.GenerateInterfaceHeader(interface)
189 self.GenerateInterface(interface, sys.stdout)
190 else:
191 with self.OpenComponentFile(directory, interface) as file:
192 self.GenerateInterface(interface, file)
OLDNEW
« no previous file with comments | « mojo/public/bindings/generators/module_struct.cc ('k') | mojo/public/bindings/generators/run_cpp_generator.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698