OLD | NEW |
1 # Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 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.""" | 5 """Generates C++ source files from a mojom.Module.""" |
6 | 6 |
7 import mojom.generate.generator as generator | 7 import mojom.generate.generator as generator |
8 import mojom.generate.module as mojom | 8 import mojom.generate.module as mojom |
9 import mojom.generate.pack as pack | 9 import mojom.generate.pack as pack |
10 from mojom.generate.template_expander import UseJinja | 10 from mojom.generate.template_expander import UseJinja |
(...skipping 19 matching lines...) Expand all Loading... |
30 } | 30 } |
31 | 31 |
32 | 32 |
33 def NamespaceToArray(namespace): | 33 def NamespaceToArray(namespace): |
34 return namespace.split('.') if namespace else [] | 34 return namespace.split('.') if namespace else [] |
35 | 35 |
36 def GetNameForKind(kind, internal = False): | 36 def GetNameForKind(kind, internal = False): |
37 parts = [] | 37 parts = [] |
38 if kind.imported_from: | 38 if kind.imported_from: |
39 parts.extend(NamespaceToArray(kind.imported_from["namespace"])) | 39 parts.extend(NamespaceToArray(kind.imported_from["namespace"])) |
40 if internal: | 40 if internal: |
41 parts.append("internal") | 41 parts.append("internal") |
42 if kind.parent_kind: | 42 if kind.parent_kind: |
43 parts.append(kind.parent_kind.name) | 43 parts.append(kind.parent_kind.name) |
44 parts.append(kind.name) | 44 parts.append(kind.name) |
45 return "::".join(parts) | 45 return "::".join(parts) |
46 | 46 |
47 def GetCppType(kind): | 47 def GetCppType(kind): |
48 if isinstance(kind, mojom.Struct): | 48 if isinstance(kind, mojom.Struct): |
49 return "%s_Data*" % GetNameForKind(kind, internal=True) | 49 return "%s_Data*" % GetNameForKind(kind, internal=True) |
50 if isinstance(kind, mojom.Array): | 50 if isinstance(kind, mojom.Array): |
51 return "mojo::internal::Array_Data<%s>*" % GetCppType(kind.kind) | 51 return "mojo::internal::Array_Data<%s>*" % GetCppType(kind.kind) |
52 if isinstance(kind, mojom.Interface): | 52 if isinstance(kind, mojom.Interface): |
53 return "mojo::MessagePipeHandle" | 53 return "mojo::MessagePipeHandle" |
54 if isinstance(kind, mojom.Enum): | 54 if isinstance(kind, mojom.Enum): |
55 return "int32_t" | 55 return "int32_t" |
56 if kind.spec == 's': | 56 if kind.spec == 's': |
57 return "mojo::internal::String_Data*" | 57 return "mojo::internal::String_Data*" |
58 return _kind_to_cpp_type[kind] | 58 return _kind_to_cpp_type[kind] |
59 | 59 |
60 def GetCppPodType(kind): | 60 def GetCppPodType(kind): |
61 if kind.spec == 's': | 61 if kind.spec == 's': |
62 return "char*" | 62 return "char*" |
63 return _kind_to_cpp_type[kind] | 63 return _kind_to_cpp_type[kind] |
64 | 64 |
65 def GetCppArrayArgWrapperType(kind): | 65 def GetCppArrayArgWrapperType(kind): |
66 if isinstance(kind, (mojom.Struct, mojom.Enum)): | 66 if isinstance(kind, mojom.Enum): |
67 return GetNameForKind(kind) | 67 return GetNameForKind(kind) |
| 68 if isinstance(kind, mojom.Struct): |
| 69 return "%sPtr" % GetNameForKind(kind) |
68 if isinstance(kind, mojom.Array): | 70 if isinstance(kind, mojom.Array): |
69 return "mojo::Array<%s >" % GetCppArrayArgWrapperType(kind.kind) | 71 return "mojo::Array<%s> " % GetCppArrayArgWrapperType(kind.kind) |
70 if isinstance(kind, mojom.Interface): | 72 if isinstance(kind, mojom.Interface): |
71 raise Exception("Arrays of interfaces not yet supported!") | 73 raise Exception("Arrays of interfaces not yet supported!") |
72 if kind.spec == 's': | 74 if kind.spec == 's': |
73 return "mojo::String" | 75 return "mojo::String" |
| 76 if kind.spec == 'h': |
| 77 return "mojo::ScopedHandle" |
| 78 if kind.spec == 'h:d:c': |
| 79 return "mojo::ScopedDataPipeConsumerHandle" |
| 80 if kind.spec == 'h:d:p': |
| 81 return "mojo::ScopedDataPipeProducerHandle" |
| 82 if kind.spec == 'h:m': |
| 83 return "mojo::ScopedMessagePipeHandle" |
| 84 if kind.spec == 'h:s': |
| 85 return "mojo::ScopedSharedBufferHandle" |
74 return _kind_to_cpp_type[kind] | 86 return _kind_to_cpp_type[kind] |
75 | 87 |
76 def GetCppResultWrapperType(kind): | 88 def GetCppResultWrapperType(kind): |
77 if isinstance(kind, (mojom.Struct, mojom.Enum)): | 89 if isinstance(kind, mojom.Enum): |
78 return GetNameForKind(kind) | 90 return GetNameForKind(kind) |
| 91 if isinstance(kind, mojom.Struct): |
| 92 return "%sPtr" % GetNameForKind(kind) |
79 if isinstance(kind, mojom.Array): | 93 if isinstance(kind, mojom.Array): |
80 return "mojo::Array<%s >" % GetCppArrayArgWrapperType(kind.kind) | 94 return "mojo::Array<%s>" % GetCppArrayArgWrapperType(kind.kind) |
81 if isinstance(kind, mojom.Interface): | 95 if isinstance(kind, mojom.Interface): |
82 return "%sPtr" % kind.name | 96 return "%sPtr" % kind.name |
83 if kind.spec == 's': | 97 if kind.spec == 's': |
84 return "mojo::String" | 98 return "mojo::String" |
85 if kind.spec == 'h': | 99 if kind.spec == 'h': |
86 return "mojo::ScopedHandle" | 100 return "mojo::ScopedHandle" |
87 if kind.spec == 'h:d:c': | 101 if kind.spec == 'h:d:c': |
88 return "mojo::ScopedDataPipeConsumerHandle" | 102 return "mojo::ScopedDataPipeConsumerHandle" |
89 if kind.spec == 'h:d:p': | 103 if kind.spec == 'h:d:p': |
90 return "mojo::ScopedDataPipeProducerHandle" | 104 return "mojo::ScopedDataPipeProducerHandle" |
91 if kind.spec == 'h:m': | 105 if kind.spec == 'h:m': |
92 return "mojo::ScopedMessagePipeHandle" | 106 return "mojo::ScopedMessagePipeHandle" |
93 if kind.spec == 'h:s': | 107 if kind.spec == 'h:s': |
94 return "mojo::ScopedSharedBufferHandle" | 108 return "mojo::ScopedSharedBufferHandle" |
95 return _kind_to_cpp_type[kind] | 109 return _kind_to_cpp_type[kind] |
96 | 110 |
97 def GetCppWrapperType(kind): | 111 def GetCppWrapperType(kind): |
98 if isinstance(kind, (mojom.Struct, mojom.Enum)): | 112 if isinstance(kind, mojom.Enum): |
99 return GetNameForKind(kind) | 113 return GetNameForKind(kind) |
| 114 if isinstance(kind, mojom.Struct): |
| 115 return "%sPtr" % GetNameForKind(kind) |
100 if isinstance(kind, mojom.Array): | 116 if isinstance(kind, mojom.Array): |
101 return "mojo::Array<%s >" % GetCppArrayArgWrapperType(kind.kind) | 117 return "mojo::Array<%s>" % GetCppArrayArgWrapperType(kind.kind) |
102 if isinstance(kind, mojom.Interface): | 118 if isinstance(kind, mojom.Interface): |
103 return "mojo::Passable<mojo::MessagePipeHandle>" | 119 return "mojo::ScopedMessagePipeHandle" |
104 if kind.spec == 's': | 120 if kind.spec == 's': |
105 return "mojo::String" | 121 return "mojo::String" |
106 if generator.IsHandleKind(kind): | 122 if kind.spec == 'h': |
107 return "mojo::Passable<%s>" % _kind_to_cpp_type[kind] | 123 return "mojo::ScopedHandle" |
| 124 if kind.spec == 'h:d:c': |
| 125 return "mojo::ScopedDataPipeConsumerHandle" |
| 126 if kind.spec == 'h:d:p': |
| 127 return "mojo::ScopedDataPipeProducerHandle" |
| 128 if kind.spec == 'h:m': |
| 129 return "mojo::ScopedMessagePipeHandle" |
| 130 if kind.spec == 'h:s': |
| 131 return "mojo::ScopedSharedBufferHandle" |
108 return _kind_to_cpp_type[kind] | 132 return _kind_to_cpp_type[kind] |
109 | 133 |
110 def GetCppConstWrapperType(kind): | 134 def GetCppConstWrapperType(kind): |
111 if isinstance(kind, mojom.Struct): | 135 if isinstance(kind, mojom.Struct): |
112 return "const %s&" % GetNameForKind(kind) | 136 return "%sPtr" % GetNameForKind(kind) |
113 if isinstance(kind, mojom.Array): | 137 if isinstance(kind, mojom.Array): |
114 return "const mojo::Array<%s >&" % GetCppArrayArgWrapperType(kind.kind) | 138 return "mojo::Array<%s>" % GetCppArrayArgWrapperType(kind.kind) |
115 if isinstance(kind, mojom.Interface): | 139 if isinstance(kind, mojom.Interface): |
116 return "%sPtr" % kind.name | 140 return "%sPtr" % kind.name |
117 if isinstance(kind, mojom.Enum): | 141 if isinstance(kind, mojom.Enum): |
118 return GetNameForKind(kind) | 142 return GetNameForKind(kind) |
119 if kind.spec == 's': | 143 if kind.spec == 's': |
120 return "const mojo::String&" | 144 return "mojo::String" |
121 if kind.spec == 'h': | 145 if kind.spec == 'h': |
122 return "mojo::ScopedHandle" | 146 return "mojo::ScopedHandle" |
123 if kind.spec == 'h:d:c': | 147 if kind.spec == 'h:d:c': |
124 return "mojo::ScopedDataPipeConsumerHandle" | 148 return "mojo::ScopedDataPipeConsumerHandle" |
125 if kind.spec == 'h:d:p': | 149 if kind.spec == 'h:d:p': |
126 return "mojo::ScopedDataPipeProducerHandle" | 150 return "mojo::ScopedDataPipeProducerHandle" |
127 if kind.spec == 'h:m': | 151 if kind.spec == 'h:m': |
128 return "mojo::ScopedMessagePipeHandle" | 152 return "mojo::ScopedMessagePipeHandle" |
129 if kind.spec == 'h:s': | 153 if kind.spec == 'h:s': |
130 return "mojo::ScopedSharedBufferHandle" | 154 return "mojo::ScopedSharedBufferHandle" |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
170 raise Exception("Expected EXPRESSION, got" + value) | 194 raise Exception("Expected EXPRESSION, got" + value) |
171 return "".join(generator.ExpressionMapper(value, | 195 return "".join(generator.ExpressionMapper(value, |
172 lambda token: TranslateConstants(token, module))) | 196 lambda token: TranslateConstants(token, module))) |
173 | 197 |
174 def HasCallbacks(interface): | 198 def HasCallbacks(interface): |
175 for method in interface.methods: | 199 for method in interface.methods: |
176 if method.response_parameters != None: | 200 if method.response_parameters != None: |
177 return True | 201 return True |
178 return False | 202 return False |
179 | 203 |
| 204 def ShouldInlineStruct(struct): |
| 205 # TODO(darin): Base this on the size of the wrapper class. |
| 206 if len(struct.fields) > 4: |
| 207 return False |
| 208 for field in struct.fields: |
| 209 if isinstance(field.kind, (mojom.Array, mojom.Struct)): |
| 210 return False |
| 211 return True |
| 212 |
180 _HEADER_SIZE = 8 | 213 _HEADER_SIZE = 8 |
181 | 214 |
182 class Generator(generator.Generator): | 215 class Generator(generator.Generator): |
183 | 216 |
184 cpp_filters = { | 217 cpp_filters = { |
185 "cpp_const_wrapper_type": GetCppConstWrapperType, | 218 "cpp_const_wrapper_type": GetCppConstWrapperType, |
186 "cpp_field_type": GetCppFieldType, | 219 "cpp_field_type": GetCppFieldType, |
187 "cpp_pod_type": GetCppPodType, | 220 "cpp_pod_type": GetCppPodType, |
188 "cpp_result_type": GetCppResultWrapperType, | 221 "cpp_result_type": GetCppResultWrapperType, |
189 "cpp_type": GetCppType, | 222 "cpp_type": GetCppType, |
190 "cpp_wrapper_type": GetCppWrapperType, | 223 "cpp_wrapper_type": GetCppWrapperType, |
191 "expression_to_text": ExpressionToText, | 224 "expression_to_text": ExpressionToText, |
192 "get_pad": pack.GetPad, | 225 "get_pad": pack.GetPad, |
193 "has_callbacks": HasCallbacks, | 226 "has_callbacks": HasCallbacks, |
| 227 "should_inline": ShouldInlineStruct, |
194 "is_enum_kind": generator.IsEnumKind, | 228 "is_enum_kind": generator.IsEnumKind, |
| 229 "is_move_only_kind": generator.IsMoveOnlyKind, |
195 "is_handle_kind": generator.IsHandleKind, | 230 "is_handle_kind": generator.IsHandleKind, |
196 "is_interface_kind": generator.IsInterfaceKind, | 231 "is_interface_kind": generator.IsInterfaceKind, |
197 "is_object_kind": generator.IsObjectKind, | 232 "is_object_kind": generator.IsObjectKind, |
198 "is_string_kind": generator.IsStringKind, | 233 "is_string_kind": generator.IsStringKind, |
199 "is_array_kind": lambda kind: isinstance(kind, mojom.Array), | 234 "is_array_kind": lambda kind: isinstance(kind, mojom.Array), |
200 "is_struct_with_handles": IsStructWithHandles, | 235 "is_struct_with_handles": IsStructWithHandles, |
201 "struct_size": lambda ps: ps.GetTotalSize() + _HEADER_SIZE, | 236 "struct_size": lambda ps: ps.GetTotalSize() + _HEADER_SIZE, |
202 "struct_from_method": generator.GetStructFromMethod, | 237 "struct_from_method": generator.GetStructFromMethod, |
203 "response_struct_from_method": generator.GetResponseStructFromMethod, | 238 "response_struct_from_method": generator.GetResponseStructFromMethod, |
204 "stylize_method": generator.StudlyCapsToCamel, | 239 "stylize_method": generator.StudlyCapsToCamel, |
(...skipping 22 matching lines...) Expand all Loading... |
227 | 262 |
228 @UseJinja("cpp_templates/module.cc.tmpl", filters=cpp_filters) | 263 @UseJinja("cpp_templates/module.cc.tmpl", filters=cpp_filters) |
229 def GenerateModuleSource(self): | 264 def GenerateModuleSource(self): |
230 return self.GetJinjaExports() | 265 return self.GetJinjaExports() |
231 | 266 |
232 def GenerateFiles(self, args): | 267 def GenerateFiles(self, args): |
233 self.Write(self.GenerateModuleHeader(), "%s.h" % self.module.name) | 268 self.Write(self.GenerateModuleHeader(), "%s.h" % self.module.name) |
234 self.Write(self.GenerateModuleInternalHeader(), | 269 self.Write(self.GenerateModuleInternalHeader(), |
235 "%s-internal.h" % self.module.name) | 270 "%s-internal.h" % self.module.name) |
236 self.Write(self.GenerateModuleSource(), "%s.cc" % self.module.name) | 271 self.Write(self.GenerateModuleSource(), "%s.cc" % self.module.name) |
OLD | NEW |