OLD | NEW |
| (Empty) |
1 # Copyright 2013 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 """Generates C++ source files from a mojom.Module.""" | |
6 | |
7 from generate import mojom | |
8 from generate import mojom_pack | |
9 from generate import mojom_generator | |
10 | |
11 from generate.template_expander import UseJinja | |
12 | |
13 | |
14 _kind_to_cpp_type = { | |
15 mojom.BOOL: "bool", | |
16 mojom.INT8: "int8_t", | |
17 mojom.UINT8: "uint8_t", | |
18 mojom.INT16: "int16_t", | |
19 mojom.UINT16: "uint16_t", | |
20 mojom.INT32: "int32_t", | |
21 mojom.UINT32: "uint32_t", | |
22 mojom.FLOAT: "float", | |
23 mojom.HANDLE: "mojo::Handle", | |
24 mojom.DCPIPE: "mojo::DataPipeConsumerHandle", | |
25 mojom.DPPIPE: "mojo::DataPipeProducerHandle", | |
26 mojom.MSGPIPE: "mojo::MessagePipeHandle", | |
27 mojom.SHAREDBUFFER: "mojo::SharedBufferHandle", | |
28 mojom.INT64: "int64_t", | |
29 mojom.UINT64: "uint64_t", | |
30 mojom.DOUBLE: "double", | |
31 } | |
32 | |
33 | |
34 def GetNameForKind(kind, internal = False): | |
35 parts = [] | |
36 if kind.imported_from: | |
37 parts.append(kind.imported_from["namespace"]) | |
38 if internal: | |
39 parts.append("internal") | |
40 if kind.parent_kind: | |
41 parts.append(kind.parent_kind.name) | |
42 parts.append(kind.name) | |
43 return "::".join(parts) | |
44 | |
45 def GetCppType(kind): | |
46 if isinstance(kind, mojom.Struct): | |
47 return "%s_Data*" % GetNameForKind(kind, internal=True) | |
48 if isinstance(kind, mojom.Array): | |
49 return "mojo::internal::Array_Data<%s>*" % GetCppType(kind.kind) | |
50 if isinstance(kind, mojom.Interface): | |
51 return "%sHandle" % kind.name | |
52 if isinstance(kind, mojom.Enum): | |
53 return "int32_t" | |
54 if kind.spec == 's': | |
55 return "mojo::internal::String_Data*" | |
56 return _kind_to_cpp_type[kind] | |
57 | |
58 def GetCppArrayArgWrapperType(kind): | |
59 if isinstance(kind, (mojom.Struct, mojom.Enum)): | |
60 return GetNameForKind(kind) | |
61 if isinstance(kind, mojom.Array): | |
62 return "mojo::Array<%s >" % GetCppArrayArgWrapperType(kind.kind) | |
63 if isinstance(kind, mojom.Interface): | |
64 return "%sHandle" % kind.name | |
65 if kind.spec == 's': | |
66 return "mojo::String" | |
67 return _kind_to_cpp_type[kind] | |
68 | |
69 def GetCppResultWrapperType(kind): | |
70 if isinstance(kind, (mojom.Struct, mojom.Enum)): | |
71 return GetNameForKind(kind) | |
72 if isinstance(kind, mojom.Array): | |
73 return "mojo::Array<%s >" % GetCppArrayArgWrapperType(kind.kind) | |
74 if isinstance(kind, mojom.Interface): | |
75 return "Scoped%sHandle" % kind.name | |
76 if kind.spec == 's': | |
77 return "mojo::String" | |
78 if kind.spec == 'h': | |
79 return "mojo::ScopedHandle" | |
80 if kind.spec == 'h:d:c': | |
81 return "mojo::ScopedDataPipeConsumerHandle" | |
82 if kind.spec == 'h:d:p': | |
83 return "mojo::ScopedDataPipeProducerHandle" | |
84 if kind.spec == 'h:m': | |
85 return "mojo::ScopedMessagePipeHandle" | |
86 if kind.spec == 'h:s': | |
87 return "mojo::ScopedSharedBufferHandle" | |
88 return _kind_to_cpp_type[kind] | |
89 | |
90 def GetCppWrapperType(kind): | |
91 if isinstance(kind, (mojom.Struct, mojom.Enum)): | |
92 return GetNameForKind(kind) | |
93 if isinstance(kind, mojom.Array): | |
94 return "mojo::Array<%s >" % GetCppArrayArgWrapperType(kind.kind) | |
95 if isinstance(kind, mojom.Interface): | |
96 return "mojo::Passable<%sHandle>" % kind.name | |
97 if kind.spec == 's': | |
98 return "mojo::String" | |
99 if mojom_generator.IsHandleKind(kind): | |
100 return "mojo::Passable<%s>" % _kind_to_cpp_type[kind] | |
101 return _kind_to_cpp_type[kind] | |
102 | |
103 def GetCppConstWrapperType(kind): | |
104 if isinstance(kind, mojom.Struct): | |
105 return "const %s&" % GetNameForKind(kind) | |
106 if isinstance(kind, mojom.Array): | |
107 return "const mojo::Array<%s >&" % GetCppArrayArgWrapperType(kind.kind) | |
108 if isinstance(kind, mojom.Interface): | |
109 return "Scoped%sHandle" % kind.name | |
110 if isinstance(kind, mojom.Enum): | |
111 return GetNameForKind(kind) | |
112 if kind.spec == 's': | |
113 return "const mojo::String&" | |
114 if kind.spec == 'h': | |
115 return "mojo::ScopedHandle" | |
116 if kind.spec == 'h:d:c': | |
117 return "mojo::ScopedDataPipeConsumerHandle" | |
118 if kind.spec == 'h:d:p': | |
119 return "mojo::ScopedDataPipeProducerHandle" | |
120 if kind.spec == 'h:m': | |
121 return "mojo::ScopedMessagePipeHandle" | |
122 if kind.spec == 'h:s': | |
123 return "mojo::ScopedSharedBufferHandle" | |
124 if not kind in _kind_to_cpp_type: | |
125 print "missing:", kind.spec | |
126 return _kind_to_cpp_type[kind] | |
127 | |
128 def GetCppFieldType(kind): | |
129 if isinstance(kind, mojom.Struct): | |
130 return ("mojo::internal::StructPointer<%s_Data>" % | |
131 GetNameForKind(kind, internal=True)) | |
132 if isinstance(kind, mojom.Array): | |
133 return "mojo::internal::ArrayPointer<%s>" % GetCppType(kind.kind) | |
134 if isinstance(kind, mojom.Interface): | |
135 return "%sHandle" % kind.name | |
136 if isinstance(kind, mojom.Enum): | |
137 return GetNameForKind(kind) | |
138 if kind.spec == 's': | |
139 return "mojo::internal::StringPointer" | |
140 return _kind_to_cpp_type[kind] | |
141 | |
142 def IsStructWithHandles(struct): | |
143 for pf in struct.packed.packed_fields: | |
144 if mojom_generator.IsHandleKind(pf.field.kind): | |
145 return True | |
146 return False | |
147 | |
148 def TranslateConstants(token, module): | |
149 if isinstance(token, mojom.Constant): | |
150 # Enum constants are constructed like: | |
151 # Namespace::Struct::FIELD_NAME | |
152 name = [] | |
153 if token.imported_from: | |
154 name.append(token.namespace) | |
155 if token.parent_kind: | |
156 name.append(token.parent_kind.name) | |
157 name.append(token.name[1]) | |
158 return "::".join(name) | |
159 return token | |
160 | |
161 def ExpressionToText(value, module): | |
162 if value[0] != "EXPRESSION": | |
163 raise Exception("Expected EXPRESSION, got" + value) | |
164 return "".join(mojom_generator.ExpressionMapper(value, | |
165 lambda token: TranslateConstants(token, module))) | |
166 | |
167 _HEADER_SIZE = 8 | |
168 | |
169 class Generator(mojom_generator.Generator): | |
170 | |
171 cpp_filters = { | |
172 "cpp_const_wrapper_type": GetCppConstWrapperType, | |
173 "cpp_field_type": GetCppFieldType, | |
174 "cpp_type": GetCppType, | |
175 "cpp_result_type": GetCppResultWrapperType, | |
176 "cpp_wrapper_type": GetCppWrapperType, | |
177 "expression_to_text": ExpressionToText, | |
178 "get_pad": mojom_pack.GetPad, | |
179 "is_enum_kind": mojom_generator.IsEnumKind, | |
180 "is_handle_kind": mojom_generator.IsHandleKind, | |
181 "is_object_kind": mojom_generator.IsObjectKind, | |
182 "is_string_kind": mojom_generator.IsStringKind, | |
183 "is_array_kind": lambda kind: isinstance(kind, mojom.Array), | |
184 "is_struct_with_handles": IsStructWithHandles, | |
185 "struct_size": lambda ps: ps.GetTotalSize() + _HEADER_SIZE, | |
186 "struct_from_method": mojom_generator.GetStructFromMethod, | |
187 "response_struct_from_method": mojom_generator.GetResponseStructFromMethod, | |
188 "stylize_method": mojom_generator.StudlyCapsToCamel, | |
189 "verify_token_type": mojom_generator.VerifyTokenType, | |
190 } | |
191 | |
192 def GetJinjaExports(self): | |
193 return { | |
194 "module": self.module, | |
195 "namespace": self.module.namespace, | |
196 "imports": self.module.imports, | |
197 "kinds": self.module.kinds, | |
198 "enums": self.module.enums, | |
199 "structs": self.GetStructs(), | |
200 "interfaces": self.module.interfaces, | |
201 } | |
202 | |
203 @UseJinja("cpp_templates/module.h.tmpl", filters=cpp_filters) | |
204 def GenerateModuleHeader(self): | |
205 return self.GetJinjaExports() | |
206 | |
207 @UseJinja("cpp_templates/module-internal.h.tmpl", filters=cpp_filters) | |
208 def GenerateModuleInternalHeader(self): | |
209 return self.GetJinjaExports() | |
210 | |
211 @UseJinja("cpp_templates/module.cc.tmpl", filters=cpp_filters) | |
212 def GenerateModuleSource(self): | |
213 return self.GetJinjaExports() | |
214 | |
215 def GenerateFiles(self): | |
216 self.Write(self.GenerateModuleHeader(), "%s.h" % self.module.name) | |
217 self.Write(self.GenerateModuleInternalHeader(), | |
218 "%s-internal.h" % self.module.name) | |
219 self.Write(self.GenerateModuleSource(), "%s.cc" % self.module.name) | |
OLD | NEW |