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 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
54 if field.default: | 54 if field.default: |
55 if mojom.IsStructKind(field.kind): | 55 if mojom.IsStructKind(field.kind): |
56 assert field.default == "default" | 56 assert field.default == "default" |
57 return "%s::New()" % GetNameForKind(field.kind) | 57 return "%s::New()" % GetNameForKind(field.kind) |
58 return ExpressionToText(field.default, kind=field.kind) | 58 return ExpressionToText(field.default, kind=field.kind) |
59 return "" | 59 return "" |
60 | 60 |
61 def NamespaceToArray(namespace): | 61 def NamespaceToArray(namespace): |
62 return namespace.split(".") if namespace else [] | 62 return namespace.split(".") if namespace else [] |
63 | 63 |
| 64 def IsNativeStructKind(kind): |
| 65 return mojom.IsStructKind(kind) and kind.native_only |
| 66 |
| 67 def IsNativeEnumKind(kind): |
| 68 return mojom.IsEnumKind(kind) and kind.native_only |
| 69 |
64 def GetNamePartsForKind(kind, add_same_module_namespaces, internal): | 70 def GetNamePartsForKind(kind, add_same_module_namespaces, internal): |
65 def MapKindName_(kind): | 71 def MapKindName_(kind): |
66 if not internal: | 72 if not internal: |
67 return kind.name | 73 return kind.name |
68 if mojom.IsStructKind(kind) and kind.native_only: | 74 if IsNativeStructKind(kind): |
69 return "mojo::Array_Data<uint8_t>" | 75 return "mojo::Array_Data<uint8_t>" |
70 if (mojom.IsStructKind(kind) or mojom.IsUnionKind(kind) or | 76 if (mojom.IsStructKind(kind) or mojom.IsUnionKind(kind) or |
71 mojom.IsInterfaceKind(kind) or mojom.IsEnumKind(kind)): | 77 mojom.IsInterfaceKind(kind) or mojom.IsEnumKind(kind)): |
72 return kind.name + "_Data" | 78 return kind.name + "_Data" |
73 return kind.name | 79 return kind.name |
74 | 80 |
75 parts = [] | 81 parts = [] |
76 if kind.imported_from: | 82 if kind.imported_from: |
77 parts.extend(NamespaceToArray(kind.imported_from["namespace"])) | 83 parts.extend(NamespaceToArray(kind.imported_from["namespace"])) |
78 elif hasattr(kind, "module") and add_same_module_namespaces: | 84 elif hasattr(kind, "module") and add_same_module_namespaces: |
(...skipping 16 matching lines...) Expand all Loading... |
95 return "::".join(parts) | 101 return "::".join(parts) |
96 | 102 |
97 def GetFullMojomNameForKind(kind): | 103 def GetFullMojomNameForKind(kind): |
98 parts = GetNamePartsForKind(kind, True, False) | 104 parts = GetNamePartsForKind(kind, True, False) |
99 return ".".join(parts) | 105 return ".".join(parts) |
100 | 106 |
101 def IsTypemappedKind(kind): | 107 def IsTypemappedKind(kind): |
102 return hasattr(kind, "name") and \ | 108 return hasattr(kind, "name") and \ |
103 GetFullMojomNameForKind(kind) in _current_typemap | 109 GetFullMojomNameForKind(kind) in _current_typemap |
104 | 110 |
105 def IsNativeOnlyKind(kind): | |
106 return mojom.IsStructKind(kind) and kind.native_only | |
107 | |
108 def GetNativeTypeName(typemapped_kind): | 111 def GetNativeTypeName(typemapped_kind): |
109 return _current_typemap[GetFullMojomNameForKind(typemapped_kind)]["typename"] | 112 return _current_typemap[GetFullMojomNameForKind(typemapped_kind)]["typename"] |
110 | 113 |
111 def DoesKindSupportEquality(kind): | 114 def DoesKindSupportEquality(kind): |
112 if IsTypemappedKind(kind): | 115 if IsTypemappedKind(kind): |
113 return False | 116 return False |
114 if mojom.IsStructKind(kind) and kind.native_only: | 117 if IsNativeStructKind(kind): |
115 return False | 118 return False |
116 if mojom.IsArrayKind(kind): | 119 if mojom.IsArrayKind(kind): |
117 return DoesKindSupportEquality(kind.kind) | 120 return DoesKindSupportEquality(kind.kind) |
118 if mojom.IsMapKind(kind): | 121 if mojom.IsMapKind(kind): |
119 return DoesKindSupportEquality(kind.value_kind) | 122 return DoesKindSupportEquality(kind.value_kind) |
120 return True | 123 return True |
121 | 124 |
122 def GetCppType(kind): | 125 def GetCppType(kind): |
123 if mojom.IsStructKind(kind) and kind.native_only: | 126 if IsNativeStructKind(kind): |
124 # A native-only type is just a blob of bytes. | 127 # A native-only type is just a blob of bytes. |
125 return "mojo::internal::Array_Data<uint8_t>*" | 128 return "mojo::internal::Array_Data<uint8_t>*" |
126 if mojom.IsArrayKind(kind): | 129 if mojom.IsArrayKind(kind): |
127 return "mojo::internal::Array_Data<%s>*" % GetCppType(kind.kind) | 130 return "mojo::internal::Array_Data<%s>*" % GetCppType(kind.kind) |
128 if mojom.IsMapKind(kind): | 131 if mojom.IsMapKind(kind): |
129 return "mojo::internal::Map_Data<%s, %s>*" % ( | 132 return "mojo::internal::Map_Data<%s, %s>*" % ( |
130 GetCppType(kind.key_kind), GetCppType(kind.value_kind)) | 133 GetCppType(kind.key_kind), GetCppType(kind.value_kind)) |
131 if mojom.IsStructKind(kind): | 134 if mojom.IsStructKind(kind): |
132 return "%s*" % GetNameForKind(kind, internal=True) | 135 return "%s*" % GetNameForKind(kind, internal=True) |
133 if mojom.IsUnionKind(kind): | 136 if mojom.IsUnionKind(kind): |
(...skipping 11 matching lines...) Expand all Loading... |
145 if mojom.IsStringKind(kind): | 148 if mojom.IsStringKind(kind): |
146 return "mojo::internal::String_Data*" | 149 return "mojo::internal::String_Data*" |
147 return _kind_to_cpp_type[kind] | 150 return _kind_to_cpp_type[kind] |
148 | 151 |
149 def GetCppPodType(kind): | 152 def GetCppPodType(kind): |
150 if mojom.IsStringKind(kind): | 153 if mojom.IsStringKind(kind): |
151 return "char*" | 154 return "char*" |
152 return _kind_to_cpp_type[kind] | 155 return _kind_to_cpp_type[kind] |
153 | 156 |
154 def GetCppArrayArgWrapperType(kind): | 157 def GetCppArrayArgWrapperType(kind): |
155 if mojom.IsStructKind(kind) and kind.native_only: | 158 if IsNativeStructKind(kind): |
156 if IsTypemappedKind(kind): | 159 if IsTypemappedKind(kind): |
157 return GetNativeTypeName(kind) | 160 return GetNativeTypeName(kind) |
158 else: | 161 # Without a relevant typemap to apply, a native-only struct can only be |
159 # Without a relevant typemap to apply, a native-only struct can only be | 162 # exposed as a blob of bytes. |
160 # exposed as a blob of bytes. | 163 return "mojo::Array<uint8_t>" |
161 return "mojo::Array<uint8_t>" | 164 if mojom.IsStructKind(kind) and IsTypemappedKind(kind): |
162 if IsTypemappedKind(kind): | |
163 raise Exception( | 165 raise Exception( |
164 "Cannot serialize containers of non-native typemapped structs yet!") | 166 "Cannot serialize containers of non-native typemapped structs yet!") |
| 167 if IsNativeEnumKind(kind): |
| 168 assert IsTypemappedKind(kind) |
| 169 return GetNativeTypeName(kind) |
165 if mojom.IsEnumKind(kind): | 170 if mojom.IsEnumKind(kind): |
166 return GetNameForKind(kind) | 171 return GetNameForKind(kind) |
167 if mojom.IsStructKind(kind) or mojom.IsUnionKind(kind): | 172 if mojom.IsStructKind(kind) or mojom.IsUnionKind(kind): |
168 return "%sPtr" % GetNameForKind(kind) | 173 return "%sPtr" % GetNameForKind(kind) |
169 if mojom.IsArrayKind(kind): | 174 if mojom.IsArrayKind(kind): |
170 return "mojo::Array<%s> " % GetCppArrayArgWrapperType(kind.kind) | 175 return "mojo::Array<%s> " % GetCppArrayArgWrapperType(kind.kind) |
171 if mojom.IsMapKind(kind): | 176 if mojom.IsMapKind(kind): |
172 return "mojo::Map<%s, %s> " % (GetCppArrayArgWrapperType(kind.key_kind), | 177 return "mojo::Map<%s, %s> " % (GetCppArrayArgWrapperType(kind.key_kind), |
173 GetCppArrayArgWrapperType(kind.value_kind)) | 178 GetCppArrayArgWrapperType(kind.value_kind)) |
174 if mojom.IsInterfaceKind(kind): | 179 if mojom.IsInterfaceKind(kind): |
(...skipping 13 matching lines...) Expand all Loading... |
188 return "mojo::ScopedDataPipeConsumerHandle" | 193 return "mojo::ScopedDataPipeConsumerHandle" |
189 if mojom.IsDataPipeProducerKind(kind): | 194 if mojom.IsDataPipeProducerKind(kind): |
190 return "mojo::ScopedDataPipeProducerHandle" | 195 return "mojo::ScopedDataPipeProducerHandle" |
191 if mojom.IsMessagePipeKind(kind): | 196 if mojom.IsMessagePipeKind(kind): |
192 return "mojo::ScopedMessagePipeHandle" | 197 return "mojo::ScopedMessagePipeHandle" |
193 if mojom.IsSharedBufferKind(kind): | 198 if mojom.IsSharedBufferKind(kind): |
194 return "mojo::ScopedSharedBufferHandle" | 199 return "mojo::ScopedSharedBufferHandle" |
195 return _kind_to_cpp_type[kind] | 200 return _kind_to_cpp_type[kind] |
196 | 201 |
197 def GetCppResultWrapperType(kind): | 202 def GetCppResultWrapperType(kind): |
198 if IsTypemappedKind(kind): | 203 if mojom.IsStructKind(kind) and IsTypemappedKind(kind): |
199 return "const %s&" % GetNativeTypeName(kind) | 204 return "const %s&" % GetNativeTypeName(kind) |
200 if mojom.IsStructKind(kind) and kind.native_only: | 205 if IsNativeStructKind(kind): |
201 return "mojo::Array<uint8_t>" | 206 return "mojo::Array<uint8_t>" |
| 207 if IsNativeEnumKind(kind): |
| 208 return GetNativeTypeName(kind) |
202 if mojom.IsEnumKind(kind): | 209 if mojom.IsEnumKind(kind): |
203 return GetNameForKind(kind) | 210 return GetNameForKind(kind) |
204 if mojom.IsStructKind(kind) or mojom.IsUnionKind(kind): | 211 if mojom.IsStructKind(kind) or mojom.IsUnionKind(kind): |
205 return "%sPtr" % GetNameForKind(kind) | 212 return "%sPtr" % GetNameForKind(kind) |
206 if mojom.IsArrayKind(kind): | 213 if mojom.IsArrayKind(kind): |
207 return "mojo::Array<%s>" % GetCppArrayArgWrapperType(kind.kind) | 214 return "mojo::Array<%s>" % GetCppArrayArgWrapperType(kind.kind) |
208 if mojom.IsMapKind(kind): | 215 if mojom.IsMapKind(kind): |
209 return "mojo::Map<%s, %s>" % (GetCppArrayArgWrapperType(kind.key_kind), | 216 return "mojo::Map<%s, %s>" % (GetCppArrayArgWrapperType(kind.key_kind), |
210 GetCppArrayArgWrapperType(kind.value_kind)) | 217 GetCppArrayArgWrapperType(kind.value_kind)) |
211 if mojom.IsInterfaceKind(kind): | 218 if mojom.IsInterfaceKind(kind): |
(...skipping 20 matching lines...) Expand all Loading... |
232 # revisit strategy used below for emitting a useful error message when an | 239 # revisit strategy used below for emitting a useful error message when an |
233 # undefined identifier is referenced. | 240 # undefined identifier is referenced. |
234 val = _kind_to_cpp_type.get(kind) | 241 val = _kind_to_cpp_type.get(kind) |
235 if (val is not None): | 242 if (val is not None): |
236 return val | 243 return val |
237 raise Exception("Unrecognized kind %s" % kind.spec) | 244 raise Exception("Unrecognized kind %s" % kind.spec) |
238 | 245 |
239 def GetCppWrapperType(kind): | 246 def GetCppWrapperType(kind): |
240 if IsTypemappedKind(kind): | 247 if IsTypemappedKind(kind): |
241 return GetNativeTypeName(kind) | 248 return GetNativeTypeName(kind) |
242 if mojom.IsStructKind(kind) and kind.native_only: | 249 assert not IsNativeEnumKind(kind) |
| 250 if IsNativeStructKind(kind): |
243 return "mojo::Array<uint8_t>" | 251 return "mojo::Array<uint8_t>" |
244 if mojom.IsEnumKind(kind): | 252 if mojom.IsEnumKind(kind): |
245 return GetNameForKind(kind) | 253 return GetNameForKind(kind) |
246 if mojom.IsStructKind(kind) or mojom.IsUnionKind(kind): | 254 if mojom.IsStructKind(kind) or mojom.IsUnionKind(kind): |
247 return "%sPtr" % GetNameForKind(kind) | 255 return "%sPtr" % GetNameForKind(kind) |
248 if mojom.IsArrayKind(kind): | 256 if mojom.IsArrayKind(kind): |
249 return "mojo::Array<%s>" % GetCppArrayArgWrapperType(kind.kind) | 257 return "mojo::Array<%s>" % GetCppArrayArgWrapperType(kind.kind) |
250 if mojom.IsMapKind(kind): | 258 if mojom.IsMapKind(kind): |
251 return "mojo::Map<%s, %s>" % (GetCppArrayArgWrapperType(kind.key_kind), | 259 return "mojo::Map<%s, %s>" % (GetCppArrayArgWrapperType(kind.key_kind), |
252 GetCppArrayArgWrapperType(kind.value_kind)) | 260 GetCppArrayArgWrapperType(kind.value_kind)) |
(...skipping 13 matching lines...) Expand all Loading... |
266 return "mojo::ScopedDataPipeConsumerHandle" | 274 return "mojo::ScopedDataPipeConsumerHandle" |
267 if mojom.IsDataPipeProducerKind(kind): | 275 if mojom.IsDataPipeProducerKind(kind): |
268 return "mojo::ScopedDataPipeProducerHandle" | 276 return "mojo::ScopedDataPipeProducerHandle" |
269 if mojom.IsMessagePipeKind(kind): | 277 if mojom.IsMessagePipeKind(kind): |
270 return "mojo::ScopedMessagePipeHandle" | 278 return "mojo::ScopedMessagePipeHandle" |
271 if mojom.IsSharedBufferKind(kind): | 279 if mojom.IsSharedBufferKind(kind): |
272 return "mojo::ScopedSharedBufferHandle" | 280 return "mojo::ScopedSharedBufferHandle" |
273 return _kind_to_cpp_type[kind] | 281 return _kind_to_cpp_type[kind] |
274 | 282 |
275 def GetCppConstWrapperType(kind): | 283 def GetCppConstWrapperType(kind): |
276 if IsTypemappedKind(kind): | 284 if mojom.IsStructKind(kind) and IsTypemappedKind(kind): |
277 return "const %s&" % GetNativeTypeName(kind) | 285 return "const %s&" % GetNativeTypeName(kind) |
278 if mojom.IsStructKind(kind) and kind.native_only: | 286 if IsNativeStructKind(kind): |
279 return "mojo::Array<uint8_t>" | 287 return "mojo::Array<uint8_t>" |
| 288 if IsNativeEnumKind(kind): |
| 289 assert IsTypemappedKind(kind) |
| 290 return GetNativeTypeName(kind) |
280 if mojom.IsStructKind(kind) or mojom.IsUnionKind(kind): | 291 if mojom.IsStructKind(kind) or mojom.IsUnionKind(kind): |
281 return "%sPtr" % GetNameForKind(kind) | 292 return "%sPtr" % GetNameForKind(kind) |
282 if mojom.IsArrayKind(kind): | 293 if mojom.IsArrayKind(kind): |
283 return "mojo::Array<%s>" % GetCppArrayArgWrapperType(kind.kind) | 294 return "mojo::Array<%s>" % GetCppArrayArgWrapperType(kind.kind) |
284 if mojom.IsMapKind(kind): | 295 if mojom.IsMapKind(kind): |
285 return "mojo::Map<%s, %s>" % (GetCppArrayArgWrapperType(kind.key_kind), | 296 return "mojo::Map<%s, %s>" % (GetCppArrayArgWrapperType(kind.key_kind), |
286 GetCppArrayArgWrapperType(kind.value_kind)) | 297 GetCppArrayArgWrapperType(kind.value_kind)) |
287 if mojom.IsInterfaceKind(kind): | 298 if mojom.IsInterfaceKind(kind): |
288 return "%sPtr" % GetNameForKind(kind) | 299 return "%sPtr" % GetNameForKind(kind) |
289 if mojom.IsInterfaceRequestKind(kind): | 300 if mojom.IsInterfaceRequestKind(kind): |
(...skipping 14 matching lines...) Expand all Loading... |
304 return "mojo::ScopedDataPipeProducerHandle" | 315 return "mojo::ScopedDataPipeProducerHandle" |
305 if mojom.IsMessagePipeKind(kind): | 316 if mojom.IsMessagePipeKind(kind): |
306 return "mojo::ScopedMessagePipeHandle" | 317 return "mojo::ScopedMessagePipeHandle" |
307 if mojom.IsSharedBufferKind(kind): | 318 if mojom.IsSharedBufferKind(kind): |
308 return "mojo::ScopedSharedBufferHandle" | 319 return "mojo::ScopedSharedBufferHandle" |
309 if not kind in _kind_to_cpp_type: | 320 if not kind in _kind_to_cpp_type: |
310 print "missing:", kind.spec | 321 print "missing:", kind.spec |
311 return _kind_to_cpp_type[kind] | 322 return _kind_to_cpp_type[kind] |
312 | 323 |
313 def GetCppFieldType(kind): | 324 def GetCppFieldType(kind): |
314 if mojom.IsStructKind(kind) and kind.native_only: | 325 if IsNativeStructKind(kind): |
315 return "mojo::internal::ArrayPointer<uint8_t>" | 326 return "mojo::internal::ArrayPointer<uint8_t>" |
316 if mojom.IsStructKind(kind): | 327 if mojom.IsStructKind(kind): |
317 return ("mojo::internal::StructPointer<%s>" % | 328 return ("mojo::internal::StructPointer<%s>" % |
318 GetNameForKind(kind, internal=True)) | 329 GetNameForKind(kind, internal=True)) |
319 if mojom.IsUnionKind(kind): | 330 if mojom.IsUnionKind(kind): |
320 return "%s" % GetNameForKind(kind, internal=True) | 331 return "%s" % GetNameForKind(kind, internal=True) |
321 if mojom.IsArrayKind(kind): | 332 if mojom.IsArrayKind(kind): |
322 return "mojo::internal::ArrayPointer<%s>" % GetCppType(kind.kind) | 333 return "mojo::internal::ArrayPointer<%s>" % GetCppType(kind.kind) |
323 if mojom.IsMapKind(kind): | 334 if mojom.IsMapKind(kind): |
324 return ("mojo::internal::StructPointer<mojo::internal::Map_Data<%s, %s>>" % | 335 return ("mojo::internal::StructPointer<mojo::internal::Map_Data<%s, %s>>" % |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
470 "get_pad": pack.GetPad, | 481 "get_pad": pack.GetPad, |
471 "get_qualified_name_for_kind": GetQualifiedNameForKind, | 482 "get_qualified_name_for_kind": GetQualifiedNameForKind, |
472 "has_callbacks": mojom.HasCallbacks, | 483 "has_callbacks": mojom.HasCallbacks, |
473 "should_inline": ShouldInlineStruct, | 484 "should_inline": ShouldInlineStruct, |
474 "should_inline_union": ShouldInlineUnion, | 485 "should_inline_union": ShouldInlineUnion, |
475 "is_array_kind": mojom.IsArrayKind, | 486 "is_array_kind": mojom.IsArrayKind, |
476 "is_cloneable_kind": mojom.IsCloneableKind, | 487 "is_cloneable_kind": mojom.IsCloneableKind, |
477 "is_enum_kind": mojom.IsEnumKind, | 488 "is_enum_kind": mojom.IsEnumKind, |
478 "is_integral_kind": mojom.IsIntegralKind, | 489 "is_integral_kind": mojom.IsIntegralKind, |
479 "is_move_only_kind": mojom.IsMoveOnlyKind, | 490 "is_move_only_kind": mojom.IsMoveOnlyKind, |
480 "is_native_only_kind": IsNativeOnlyKind, | 491 "is_native_enum_kind": IsNativeEnumKind, |
| 492 "is_native_struct_kind": IsNativeStructKind, |
481 "is_any_handle_kind": mojom.IsAnyHandleKind, | 493 "is_any_handle_kind": mojom.IsAnyHandleKind, |
482 "is_interface_kind": mojom.IsInterfaceKind, | 494 "is_interface_kind": mojom.IsInterfaceKind, |
483 "is_interface_request_kind": mojom.IsInterfaceRequestKind, | 495 "is_interface_request_kind": mojom.IsInterfaceRequestKind, |
484 "is_associated_interface_kind": mojom.IsAssociatedInterfaceKind, | 496 "is_associated_interface_kind": mojom.IsAssociatedInterfaceKind, |
485 "is_associated_interface_request_kind": | 497 "is_associated_interface_request_kind": |
486 mojom.IsAssociatedInterfaceRequestKind, | 498 mojom.IsAssociatedInterfaceRequestKind, |
487 "is_associated_kind": mojom.IsAssociatedKind, | 499 "is_associated_kind": mojom.IsAssociatedKind, |
488 "is_map_kind": mojom.IsMapKind, | 500 "is_map_kind": mojom.IsMapKind, |
489 "is_nullable_kind": mojom.IsNullableKind, | 501 "is_nullable_kind": mojom.IsNullableKind, |
490 "is_object_kind": mojom.IsObjectKind, | 502 "is_object_kind": mojom.IsObjectKind, |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
543 def GenerateFiles(self, args): | 555 def GenerateFiles(self, args): |
544 global _current_typemap | 556 global _current_typemap |
545 _current_typemap = self.typemap | 557 _current_typemap = self.typemap |
546 suffix = "-%s" % self.variant if self.variant else "" | 558 suffix = "-%s" % self.variant if self.variant else "" |
547 self.Write(self.GenerateModuleHeader(), | 559 self.Write(self.GenerateModuleHeader(), |
548 self.MatchMojomFilePath("%s%s.h" % (self.module.name, suffix))) | 560 self.MatchMojomFilePath("%s%s.h" % (self.module.name, suffix))) |
549 self.Write(self.GenerateModuleInternalHeader(), | 561 self.Write(self.GenerateModuleInternalHeader(), |
550 self.MatchMojomFilePath("%s%s-internal.h" % (self.module.name, suffix))) | 562 self.MatchMojomFilePath("%s%s-internal.h" % (self.module.name, suffix))) |
551 self.Write(self.GenerateModuleSource(), | 563 self.Write(self.GenerateModuleSource(), |
552 self.MatchMojomFilePath("%s%s.cc" % (self.module.name, suffix))) | 564 self.MatchMojomFilePath("%s%s.cc" % (self.module.name, suffix))) |
OLD | NEW |