OLD | NEW |
| (Empty) |
1 # Copyright 2015 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 """Resolves the values used for constants and enums.""" | |
6 | |
7 from itertools import ifilter | |
8 import mojom.generate.module as mojom | |
9 | |
10 def ResolveConstants(module, expression_to_text): | |
11 in_progress = set() | |
12 computed = set() | |
13 | |
14 def GetResolvedValue(named_value): | |
15 assert isinstance(named_value, (mojom.EnumValue, mojom.ConstantValue)) | |
16 if isinstance(named_value, mojom.EnumValue): | |
17 field = next(ifilter(lambda field: field.name == named_value.name, | |
18 named_value.enum.fields), None) | |
19 if not field: | |
20 raise RuntimeError( | |
21 'Unable to get computed value for field %s of enum %s' % | |
22 (named_value.name, named_value.enum.name)) | |
23 if field not in computed: | |
24 ResolveEnum(named_value.enum) | |
25 return field.resolved_value | |
26 else: | |
27 ResolveConstant(named_value.constant) | |
28 named_value.resolved_value = named_value.constant.resolved_value | |
29 return named_value.resolved_value | |
30 | |
31 def ResolveConstant(constant): | |
32 if constant in computed: | |
33 return | |
34 if constant in in_progress: | |
35 raise RuntimeError('Circular dependency for constant: %s' % constant.name) | |
36 in_progress.add(constant) | |
37 if isinstance(constant.value, (mojom.EnumValue, mojom.ConstantValue)): | |
38 resolved_value = GetResolvedValue(constant.value) | |
39 elif isinstance(constant.value, mojom.BuiltinValue): | |
40 resolved_value = expression_to_text(constant.value) | |
41 elif constant.kind in [mojom.FLOAT, mojom.DOUBLE]: | |
42 # Force float constants to have a decimal point. | |
43 resolved_value = expression_to_text(repr(float(constant.value))) | |
44 else: | |
45 resolved_value = expression_to_text(constant.value) | |
46 constant.resolved_value = resolved_value | |
47 in_progress.remove(constant) | |
48 computed.add(constant) | |
49 | |
50 def ResolveEnum(enum): | |
51 def ResolveEnumField(enum, field, default_value): | |
52 if field in computed: | |
53 return | |
54 if field in in_progress: | |
55 raise RuntimeError('Circular dependency for enum: %s' % enum.name) | |
56 in_progress.add(field) | |
57 if field.value: | |
58 if isinstance(field.value, mojom.EnumValue): | |
59 resolved_value = GetResolvedValue(field.value) | |
60 elif isinstance(field.value, str): | |
61 resolved_value = int(field.value, 0) | |
62 else: | |
63 raise RuntimeError('Unexpected value: %s' % field.value) | |
64 else: | |
65 resolved_value = default_value | |
66 field.resolved_value = resolved_value | |
67 in_progress.remove(field) | |
68 computed.add(field) | |
69 | |
70 current_value = 0 | |
71 for field in enum.fields: | |
72 ResolveEnumField(enum, field, current_value) | |
73 current_value = field.resolved_value + 1 | |
74 | |
75 for constant in module.constants: | |
76 ResolveConstant(constant) | |
77 | |
78 for enum in module.enums: | |
79 ResolveEnum(enum) | |
80 | |
81 for struct in module.structs: | |
82 for constant in struct.constants: | |
83 ResolveConstant(constant) | |
84 for enum in struct.enums: | |
85 ResolveEnum(enum) | |
86 for field in struct.fields: | |
87 if isinstance(field.default, (mojom.ConstantValue, mojom.EnumValue)): | |
88 field.default.resolved_value = GetResolvedValue(field.default) | |
89 | |
90 for interface in module.interfaces: | |
91 for constant in interface.constants: | |
92 ResolveConstant(constant) | |
93 for enum in interface.enums: | |
94 ResolveEnum(enum) | |
95 | |
96 return module | |
OLD | NEW |