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

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 missing files 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];")
34 54
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
96 elif kind.spec == 's': 116 elif kind.spec == 's':
97 itype = "mojo::internal::StringPointer" 117 itype = "mojo::internal::StringPointer"
98 else: 118 else:
99 itype = cls.kind_to_type[kind] 119 itype = cls.kind_to_type[kind]
100 return cls.field_template.substitute(field=pf.field.name, itype=itype) 120 return cls.field_template.substitute(field=pf.field.name, itype=itype)
101 121
102 def GetHeaderGuard(self, component): 122 def GetHeaderGuard(self, component):
103 return "MOJO_GENERATED_BINDINGS_%s_%s_H_" % \ 123 return "MOJO_GENERATED_BINDINGS_%s_%s_H_" % \
104 (self.module.name.upper(), component.name.upper()) 124 (self.module.name.upper(), component.name.upper())
105 125
106 def OpenComponentFile(self, directory, component): 126 # Pass |output_dir| to emit files to disk. Omit |output_dir| to echo all files
107 filename = "%s_%s.h" % \ 127 # to stdout.
108 (self.module.name.lower(), component.name.lower()) 128 def __init__(self, module, header_dir, output_dir=None):
109 return open(directory + '/' + filename, "w+") 129 self.module = module
130 self.header_dir = header_dir
131 self.output_dir = output_dir
110 132
111 def __init__(self, module): 133 def WriteTemplateToFile(self, template, name, ext, **substitutions):
112 self.module = module 134 if self.output_dir is None:
113 self.file = file 135 file = sys.stdout
136 else:
137 filename = "%s_%s.%s" % \
138 (self.module.name.lower(), name.lower(), ext)
139 file = open(os.path.join(self.output_dir, filename), "w+")
140 try:
141 file.write(template.substitute(substitutions))
142 finally:
143 if self.output_dir is not None:
144 file.close()
114 145
115 def GenerateStruct(self, struct, file): 146 def GenerateStructHeader(self, struct):
116 fields = [] 147 fields = []
117 setters = [] 148 setters = []
118 getters = [] 149 getters = []
150 forwards = set()
119 151
120 ps = mojom_pack.PackedStruct(struct) 152 ps = mojom_pack.PackedStruct(struct)
121 pad_count = 0 153 pad_count = 0
122 num_fields = len(ps.packed_fields) 154 num_fields = len(ps.packed_fields)
123 for i in xrange(num_fields): 155 for i in xrange(num_fields):
124 pf = ps.packed_fields[i] 156 pf = ps.packed_fields[i]
125 fields.append(self.GetFieldLine(pf)) 157 fields.append(self.GetFieldLine(pf))
158 AddForward(forwards, pf.field.kind)
126 if i < (num_fields - 2): 159 if i < (num_fields - 2):
127 next_pf = ps.packed_fields[i+1] 160 next_pf = ps.packed_fields[i+1]
128 pad = next_pf.offset - (pf.offset + pf.size) 161 pad = next_pf.offset - (pf.offset + pf.size)
129 if pad > 0: 162 if pad > 0:
130 fields.append(self.pad_template.substitute(count=pad_count, pad=pad)) 163 fields.append(self.pad_template.substitute(count=pad_count, pad=pad))
131 pad_count += 1 164 pad_count += 1
132 setters.append(self.GetSetterLine(pf)) 165 setters.append(self.GetSetterLine(pf))
133 getters.append(self.GetGetterLine(pf)) 166 getters.append(self.GetGetterLine(pf))
134 167
135 if num_fields > 0: 168 if num_fields > 0:
136 last_field = ps.packed_fields[num_fields - 1] 169 last_field = ps.packed_fields[num_fields - 1]
137 offset = last_field.offset + last_field.size 170 offset = last_field.offset + last_field.size
138 pad = mojom_pack.GetPad(offset, 8) 171 pad = mojom_pack.GetPad(offset, 8)
139 if pad > 0: 172 if pad > 0:
140 fields.append(self.pad_template.substitute(count=pad_count, pad=pad)) 173 fields.append(self.pad_template.substitute(count=pad_count, pad=pad))
141 pad_count += 1 174 pad_count += 1
142 size = offset + pad 175 size = offset + pad
143 else: 176 else:
144 size = 0 177 size = 0
145 178
146 file.write(self.struct_template.substitute( 179 self.WriteTemplateToFile(self.struct_header_template, struct.name, 'h',
147 year = datetime.date.today().year, 180 YEAR = datetime.date.today().year,
148 header_guard = self.GetHeaderGuard(struct), 181 HEADER_GUARD = self.GetHeaderGuard(struct),
149 namespace = self.module.namespace, 182 NAMESPACE = self.module.namespace,
150 classname = struct.name.capitalize(), 183 CLASS = struct.name.capitalize(),
151 num_fields = len(ps.packed_fields), 184 SIZE = size + 8,
darin (slow to review) 2013/10/30 23:02:06 nit: might be nice to use a named constant in plac
152 size = size + 8, 185 FORWARDS = GetForwards(forwards),
153 setters = '\n'.join(setters), 186 SETTERS = '\n'.join(setters),
154 getters = '\n'.join(getters), 187 GETTERS = '\n'.join(getters),
155 fields = '\n'.join(fields))) 188 FIELDS = '\n'.join(fields))
156 189
157 def GenerateInterface(self, interface, file): 190 def GenerateStructSource(self, struct):
191 header = "%s_%s.h" % (self.module.name.lower(), struct.name.lower())
192 header = os.path.join(self.header_dir, header)
193 self.WriteTemplateToFile(self.struct_source_template, struct.name, 'cc',
194 YEAR = datetime.date.today().year,
195 NAMESPACE = self.module.namespace,
196 CLASS = struct.name.capitalize(),
197 NUM_FIELDS = len(struct.fields),
198 HEADER = header)
199
200 def GenerateInterfaceHeader(self, interface):
158 cpp_methods = [] 201 cpp_methods = []
202 forwards = set()
159 for method in interface.methods: 203 for method in interface.methods:
160 cpp_method = " virtual void %s(" % method.name 204 cpp_method = " virtual void %s(" % method.name
161 first_param = True 205 first_param = True
162 for param in method.parameters: 206 for param in method.parameters:
163 if first_param == True: 207 if first_param == True:
164 first_param = False 208 first_param = False
165 else: 209 else:
166 cpp_method += ", " 210 cpp_method += ", "
211 AddForward(forwards, param.kind)
167 cpp_method += "%s %s" % (self.GetConstType(param.kind), param.name) 212 cpp_method += "%s %s" % (self.GetConstType(param.kind), param.name)
168 cpp_method += ") = 0;" 213 cpp_method += ") = 0;"
169 cpp_methods.append(cpp_method) 214 cpp_methods.append(cpp_method)
170 215
171 file.write(self.interface_template.substitute( 216 self.WriteTemplateToFile(
172 year = datetime.date.today().year, 217 self.interface_header_template,
173 header_guard = self.GetHeaderGuard(interface), 218 interface.name,
174 namespace = self.module.namespace, 219 'h',
175 classname = interface.name.capitalize(), 220 YEAR = datetime.date.today().year,
176 methods = '\n'.join(cpp_methods))) 221 HEADER_GUARD = self.GetHeaderGuard(interface),
222 NAMESPACE = self.module.namespace,
223 CLASS = interface.name.capitalize(),
224 FORWARDS = GetForwards(forwards),
225 METHODS = '\n'.join(cpp_methods))
177 226
178 # Pass |directory| to emit files to disk. Omit |directory| to echo all files 227 def GenerateFiles(self):
179 # to stdout.
180 def GenerateFiles(self, directory=None):
181 for struct in self.module.structs: 228 for struct in self.module.structs:
182 if directory is None: 229 self.GenerateStructHeader(struct)
183 self.GenerateStruct(struct, sys.stdout) 230 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: 231 for interface in self.module.interfaces:
188 if directory is None: 232 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