| 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 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 46 return ExpressionToText(constant.value, kind=constant.kind) | 46 return ExpressionToText(constant.value, kind=constant.kind) |
| 47 | 47 |
| 48 def DefaultValue(field): | 48 def DefaultValue(field): |
| 49 if field.default: | 49 if field.default: |
| 50 if mojom.IsStructKind(field.kind): | 50 if mojom.IsStructKind(field.kind): |
| 51 assert field.default == "default" | 51 assert field.default == "default" |
| 52 return "%s::New()" % GetNameForKind(field.kind) | 52 return "%s::New()" % GetNameForKind(field.kind) |
| 53 return ExpressionToText(field.default, kind=field.kind) | 53 return ExpressionToText(field.default, kind=field.kind) |
| 54 return "" | 54 return "" |
| 55 | 55 |
| 56 def IsEnumToken(token): |
| 57 return isinstance(token, mojom.EnumValue) |
| 58 |
| 56 def NamespaceToArray(namespace): | 59 def NamespaceToArray(namespace): |
| 57 return namespace.split(".") if namespace else [] | 60 return namespace.split(".") if namespace else [] |
| 58 | 61 |
| 59 def GetNameForKind(kind, internal = False): | 62 def GetNameForKind(kind, internal = False): |
| 60 parts = [] | 63 parts = [] |
| 61 if kind.imported_from: | 64 if kind.imported_from: |
| 62 parts.extend(NamespaceToArray(kind.imported_from["namespace"])) | 65 parts.extend(NamespaceToArray(kind.imported_from["namespace"])) |
| 63 if internal: | 66 if internal: |
| 64 parts.append("internal") | 67 parts.append("internal") |
| 65 if kind.parent_kind: | 68 if kind.parent_kind: |
| (...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 258 def TranslateConstants(token, kind): | 261 def TranslateConstants(token, kind): |
| 259 if isinstance(token, mojom.NamedValue): | 262 if isinstance(token, mojom.NamedValue): |
| 260 # Both variable and enum constants are constructed like: | 263 # Both variable and enum constants are constructed like: |
| 261 # Namespace::Struct::CONSTANT_NAME | 264 # Namespace::Struct::CONSTANT_NAME |
| 262 # For enums, CONSTANT_NAME is ENUM_NAME_ENUM_VALUE. | 265 # For enums, CONSTANT_NAME is ENUM_NAME_ENUM_VALUE. |
| 263 name = [] | 266 name = [] |
| 264 if token.imported_from: | 267 if token.imported_from: |
| 265 name.extend(NamespaceToArray(token.namespace)) | 268 name.extend(NamespaceToArray(token.namespace)) |
| 266 if token.parent_kind: | 269 if token.parent_kind: |
| 267 name.append(token.parent_kind.name) | 270 name.append(token.parent_kind.name) |
| 268 if isinstance(token, mojom.EnumValue): | 271 if IsEnumToken(token): |
| 269 name.append( | 272 name.extend([token.enum.name, token.name]) |
| 270 "%s_%s" % (generator.CamelCaseToAllCaps(token.enum.name), token.name)) | |
| 271 else: | 273 else: |
| 272 name.append(token.name) | 274 name.append(token.name) |
| 273 return "::".join(name) | 275 |
| 276 ret = "::".join(name) |
| 277 |
| 278 # If we are translating an enum token for a non-enum (but defined) kind, or |
| 279 # a non-enum token for an enum kind, we need an explicit cast. |
| 280 # TODO(johngro) : should this be allowed at all? |
| 281 if IsEnumToken(token) and kind is not None and not mojom.IsEnumKind(kind): |
| 282 return "static_cast<int32_t>(%s)" % (ret, ) |
| 283 elif not IsEnumToken(token) and mojom.IsEnumKind(kind): |
| 284 return "static_cast<%s>(%s)" % (GetNameForKind(kind), ret) |
| 285 return ret |
| 274 | 286 |
| 275 if isinstance(token, mojom.BuiltinValue): | 287 if isinstance(token, mojom.BuiltinValue): |
| 276 if token.value == "double.INFINITY" or token.value == "float.INFINITY": | 288 if token.value == "double.INFINITY" or token.value == "float.INFINITY": |
| 277 return "INFINITY"; | 289 return "INFINITY"; |
| 278 if token.value == "double.NEGATIVE_INFINITY" or \ | 290 if token.value == "double.NEGATIVE_INFINITY" or \ |
| 279 token.value == "float.NEGATIVE_INFINITY": | 291 token.value == "float.NEGATIVE_INFINITY": |
| 280 return "-INFINITY"; | 292 return "-INFINITY"; |
| 281 if token.value == "double.NAN" or token.value == "float.NAN": | 293 if token.value == "double.NAN" or token.value == "float.NAN": |
| 282 return "NAN"; | 294 return "NAN"; |
| 283 | 295 |
| 284 if (kind is not None and mojom.IsFloatKind(kind)): | 296 if (kind is not None and mojom.IsFloatKind(kind)): |
| 285 return token if token.isdigit() else token + "f"; | 297 return token if token.isdigit() else token + "f"; |
| 286 | 298 |
| 287 # Per C++11, 2.14.2, the type of an integer literal is the first of the | 299 # Per C++11, 2.14.2, the type of an integer literal is the first of the |
| 288 # corresponding list in Table 6 in which its value can be represented. In this | 300 # corresponding list in Table 6 in which its value can be represented. In this |
| 289 # case, the list for decimal constants with no suffix is: | 301 # case, the list for decimal constants with no suffix is: |
| 290 # int, long int, long long int | 302 # int, long int, long long int |
| 291 # The standard considers a program ill-formed if it contains an integer | 303 # The standard considers a program ill-formed if it contains an integer |
| 292 # literal that cannot be represented by any of the allowed types. | 304 # literal that cannot be represented by any of the allowed types. |
| 293 # | 305 # |
| 294 # As it turns out, MSVC doesn't bother trying to fall back to long long int, | 306 # As it turns out, MSVC doesn't bother trying to fall back to long long int, |
| 295 # so the integral constant -2147483648 causes it grief: it decides to | 307 # so the integral constant -2147483648 causes it grief: it decides to |
| 296 # represent 2147483648 as an unsigned integer, and then warns that the unary | 308 # represent 2147483648 as an unsigned integer, and then warns that the unary |
| 297 # minus operator doesn't make sense on unsigned types. Doh! | 309 # minus operator doesn't make sense on unsigned types. Doh! |
| 298 if kind == mojom.INT32 and token == "-2147483648": | 310 if kind == mojom.INT32 and token == "-2147483648": |
| 299 return "(-%d - 1) /* %s */" % ( | 311 return "(-%d - 1) /* %s */" % ( |
| 300 2**31 - 1, "Workaround for MSVC bug; see https://crbug.com/445618") | 312 2**31 - 1, "Workaround for MSVC bug; see https://crbug.com/445618") |
| 301 | 313 |
| 302 return "%s%s" % (token, _kind_to_cpp_literal_suffix.get(kind, "")) | 314 |
| 315 # If we are translating a literal for an enum kind, we need an explicit cast. |
| 316 # TODO(johngro) : should this be allowed at all? |
| 317 ret = "%s%s" % (token, _kind_to_cpp_literal_suffix.get(kind, "")) |
| 318 if mojom.IsEnumKind(kind): |
| 319 return "static_cast<%s>(%s)" % (GetNameForKind(kind), ret) |
| 320 return ret |
| 303 | 321 |
| 304 def ExpressionToText(value, kind=None): | 322 def ExpressionToText(value, kind=None): |
| 305 return TranslateConstants(value, kind) | 323 return TranslateConstants(value, kind) |
| 306 | 324 |
| 307 def ShouldInlineStruct(struct): | 325 def ShouldInlineStruct(struct): |
| 308 # TODO(darin): Base this on the size of the wrapper class. | 326 # TODO(darin): Base this on the size of the wrapper class. |
| 309 if len(struct.fields) > 4: | 327 if len(struct.fields) > 4: |
| 310 return False | 328 return False |
| 311 for field in struct.fields: | 329 for field in struct.fields: |
| 312 if mojom.IsMoveOnlyKind(field.kind): | 330 if mojom.IsMoveOnlyKind(field.kind): |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 415 def GenerateModuleSource(self): | 433 def GenerateModuleSource(self): |
| 416 return self.GetJinjaExports() | 434 return self.GetJinjaExports() |
| 417 | 435 |
| 418 def GenerateFiles(self, args): | 436 def GenerateFiles(self, args): |
| 419 self.Write(self.GenerateModuleHeader(), | 437 self.Write(self.GenerateModuleHeader(), |
| 420 self.MatchMojomFilePath("%s.h" % self.module.name)) | 438 self.MatchMojomFilePath("%s.h" % self.module.name)) |
| 421 self.Write(self.GenerateModuleInternalHeader(), | 439 self.Write(self.GenerateModuleInternalHeader(), |
| 422 self.MatchMojomFilePath("%s-internal.h" % self.module.name)) | 440 self.MatchMojomFilePath("%s-internal.h" % self.module.name)) |
| 423 self.Write(self.GenerateModuleSource(), | 441 self.Write(self.GenerateModuleSource(), |
| 424 self.MatchMojomFilePath("%s.cc" % self.module.name)) | 442 self.MatchMojomFilePath("%s.cc" % self.module.name)) |
| OLD | NEW |