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 """Code shared by the various language-specific code generators.""" | 5 """Code shared by the various language-specific code generators.""" |
6 | 6 |
7 from functools import partial | 7 from functools import partial |
8 import os.path | 8 import os.path |
9 import re | 9 import re |
10 | 10 |
11 import module as mojom | 11 import module as mojom |
12 import mojom.fileutil as fileutil | 12 import mojom.fileutil as fileutil |
13 import pack | 13 import pack |
14 | 14 |
15 def ExpectedArraySize(kind): | 15 def ExpectedArraySize(kind): |
16 if mojom.IsArrayKind(kind): | 16 if mojom.IsArrayKind(kind): |
17 return kind.length | 17 return kind.length |
18 return None | 18 return None |
19 | 19 |
20 def StudlyCapsToCamel(studly): | 20 def ToCamel(identifier, lower_initial=False, dilimiter='_'): |
21 return studly[0].lower() + studly[1:] | 21 """Splits |identifier| using |dilimiter|, capitalizes each word (but makes the |
22 | 22 first character of the first word lowercased if |lower_initial| is set to |
23 def UnderToCamel(under): | 23 True), and joins the words.""" |
24 """Converts underscore_separated strings to CamelCase strings.""" | 24 result = ''.join(word.capitalize() for word in identifier.split(dilimiter)) |
25 return ''.join(word.capitalize() for word in under.split('_')) | 25 if lower_initial: |
| 26 result = result[0].lower() + result[1:] |
| 27 return result |
26 | 28 |
27 def WriteFile(contents, full_path): | 29 def WriteFile(contents, full_path): |
28 # Make sure the containing directory exists. | 30 # Make sure the containing directory exists. |
29 full_dir = os.path.dirname(full_path) | 31 full_dir = os.path.dirname(full_path) |
30 fileutil.EnsureDirectoryExists(full_dir) | 32 fileutil.EnsureDirectoryExists(full_dir) |
31 | 33 |
32 # Dump the data to disk. | 34 # Dump the data to disk. |
33 with open(full_path, "w+") as f: | 35 with open(full_path, "w+") as f: |
34 f.write(contents) | 36 f.write(contents) |
35 | 37 |
| 38 |
| 39 class Stylizer(object): |
| 40 def StylizeConstant(self, name): |
| 41 return name |
| 42 |
| 43 def StylizeField(self, name): |
| 44 return name |
| 45 |
| 46 def StylizeStruct(self, name): |
| 47 return name |
| 48 |
| 49 def StylizeUnion(self, name): |
| 50 return name |
| 51 |
| 52 def StylizeParameter(self, name): |
| 53 return name |
| 54 |
| 55 def StylizeMethod(self, name): |
| 56 return name |
| 57 |
| 58 def StylizeInterface(self, name): |
| 59 return name |
| 60 |
| 61 def StylizeEnumField(self, name): |
| 62 return name |
| 63 |
| 64 def StylizeEnum(self, name): |
| 65 return name |
| 66 |
| 67 def StylizeModule(self, name): |
| 68 return name |
| 69 |
| 70 |
36 class Generator(object): | 71 class Generator(object): |
37 # Pass |output_dir| to emit files to disk. Omit |output_dir| to echo all | 72 # Pass |output_dir| to emit files to disk. Omit |output_dir| to echo all |
38 # files to stdout. | 73 # files to stdout. |
39 def __init__(self, module, output_dir=None, typemap=None, variant=None, | 74 def __init__(self, module, output_dir=None, typemap=None, variant=None, |
40 bytecode_path=None, for_blink=False, use_once_callback=False, | 75 bytecode_path=None, for_blink=False, use_once_callback=False, |
41 use_new_js_bindings=False, export_attribute=None, | 76 use_new_js_bindings=False, export_attribute=None, |
42 export_header=None, generate_non_variant_code=False): | 77 export_header=None, generate_non_variant_code=False): |
43 self.module = module | 78 self.module = module |
44 self.output_dir = output_dir | 79 self.output_dir = output_dir |
45 self.typemap = typemap or {} | 80 self.typemap = typemap or {} |
46 self.variant = variant | 81 self.variant = variant |
47 self.bytecode_path = bytecode_path | 82 self.bytecode_path = bytecode_path |
48 self.for_blink = for_blink | 83 self.for_blink = for_blink |
49 self.use_once_callback = use_once_callback | 84 self.use_once_callback = use_once_callback |
50 self.use_new_js_bindings = use_new_js_bindings | 85 self.use_new_js_bindings = use_new_js_bindings |
51 self.export_attribute = export_attribute | 86 self.export_attribute = export_attribute |
52 self.export_header = export_header | 87 self.export_header = export_header |
53 self.generate_non_variant_code = generate_non_variant_code | 88 self.generate_non_variant_code = generate_non_variant_code |
54 | 89 |
| 90 def FinalizeModule(self, stylizer=None): |
| 91 for struct in self.module.structs: |
| 92 self._AddStructComputedData(True, struct) |
| 93 for union in self.module.unions: |
| 94 self._AddUnionComputedData(union) |
| 95 for interface in self.module.interfaces: |
| 96 self._AddInterfaceComputedData(interface) |
| 97 |
| 98 if stylizer: |
| 99 self.module.Stylize(stylizer) |
| 100 |
55 def GetStructsFromMethods(self): | 101 def GetStructsFromMethods(self): |
56 result = [] | 102 result = [] |
57 for interface in self.module.interfaces: | 103 for interface in self.module.interfaces: |
58 for method in interface.methods: | 104 for method in interface.methods: |
59 result.append(self._GetStructFromMethod(method)) | 105 result.append(method.param_struct) |
60 if method.response_parameters != None: | 106 if method.response_param_struct is not None: |
61 result.append(self._GetResponseStructFromMethod(method)) | 107 result.append(method.response_param_struct) |
62 return result | 108 return result |
63 | 109 |
64 def GetStructs(self): | |
65 return map(partial(self._AddStructComputedData, True), self.module.structs) | |
66 | |
67 def GetUnions(self): | |
68 return map(self._AddUnionComputedData, self.module.unions) | |
69 | |
70 def GetInterfaces(self): | |
71 return map(self._AddInterfaceComputedData, self.module.interfaces) | |
72 | |
73 # Prepend the filename with a directory that matches the directory of the | 110 # Prepend the filename with a directory that matches the directory of the |
74 # original .mojom file, relative to the import root. | 111 # original .mojom file, relative to the import root. |
75 def MatchMojomFilePath(self, filename): | 112 def MatchMojomFilePath(self, filename): |
76 return os.path.join(os.path.dirname(self.module.path), filename) | 113 return os.path.join(os.path.dirname(self.module.path), filename) |
77 | 114 |
78 def Write(self, contents, filename): | 115 def Write(self, contents, filename): |
79 if self.output_dir is None: | 116 if self.output_dir is None: |
80 print contents | 117 print contents |
81 return | 118 return |
82 full_path = os.path.join(self.output_dir, filename) | 119 full_path = os.path.join(self.output_dir, filename) |
(...skipping 10 matching lines...) Expand all Loading... |
93 """Returns global mappings for the template generation.""" | 130 """Returns global mappings for the template generation.""" |
94 return {} | 131 return {} |
95 | 132 |
96 def _AddStructComputedData(self, exported, struct): | 133 def _AddStructComputedData(self, exported, struct): |
97 """Adds computed data to the given struct. The data is computed once and | 134 """Adds computed data to the given struct. The data is computed once and |
98 used repeatedly in the generation process.""" | 135 used repeatedly in the generation process.""" |
99 struct.packed = pack.PackedStruct(struct) | 136 struct.packed = pack.PackedStruct(struct) |
100 struct.bytes = pack.GetByteLayout(struct.packed) | 137 struct.bytes = pack.GetByteLayout(struct.packed) |
101 struct.versions = pack.GetVersionInfo(struct.packed) | 138 struct.versions = pack.GetVersionInfo(struct.packed) |
102 struct.exported = exported | 139 struct.exported = exported |
103 return struct | |
104 | 140 |
105 def _AddUnionComputedData(self, union): | 141 def _AddUnionComputedData(self, union): |
106 """Adds computed data to the given union. The data is computed once and | 142 """Adds computed data to the given union. The data is computed once and |
107 used repeatedly in the generation process.""" | 143 used repeatedly in the generation process.""" |
108 ordinal = 0 | 144 ordinal = 0 |
109 for field in union.fields: | 145 for field in union.fields: |
110 if field.ordinal is not None: | 146 if field.ordinal is not None: |
111 ordinal = field.ordinal | 147 ordinal = field.ordinal |
112 field.ordinal = ordinal | 148 field.ordinal = ordinal |
113 ordinal += 1 | 149 ordinal += 1 |
114 return union | |
115 | 150 |
116 def _AddInterfaceComputedData(self, interface): | 151 def _AddInterfaceComputedData(self, interface): |
117 """Adds computed data to the given interface. The data is computed once and | 152 """Adds computed data to the given interface. The data is computed once and |
118 used repeatedly in the generation process.""" | 153 used repeatedly in the generation process.""" |
119 interface.version = 0 | 154 interface.version = 0 |
120 for method in interface.methods: | 155 for method in interface.methods: |
121 if method.min_version is not None: | 156 if method.min_version is not None: |
122 interface.version = max(interface.version, method.min_version) | 157 interface.version = max(interface.version, method.min_version) |
123 | 158 |
124 method.param_struct = self._GetStructFromMethod(method) | 159 method.param_struct = self._GetStructFromMethod(method) |
125 interface.version = max(interface.version, | 160 interface.version = max(interface.version, |
126 method.param_struct.versions[-1].version) | 161 method.param_struct.versions[-1].version) |
127 | 162 |
128 if method.response_parameters is not None: | 163 if method.response_parameters is not None: |
129 method.response_param_struct = self._GetResponseStructFromMethod(method) | 164 method.response_param_struct = self._GetResponseStructFromMethod(method) |
130 interface.version = max( | 165 interface.version = max( |
131 interface.version, | 166 interface.version, |
132 method.response_param_struct.versions[-1].version) | 167 method.response_param_struct.versions[-1].version) |
133 else: | 168 else: |
134 method.response_param_struct = None | 169 method.response_param_struct = None |
135 return interface | |
136 | 170 |
137 def _GetStructFromMethod(self, method): | 171 def _GetStructFromMethod(self, method): |
138 """Converts a method's parameters into the fields of a struct.""" | 172 """Converts a method's parameters into the fields of a struct.""" |
139 params_class = "%s_%s_Params" % (method.interface.name, method.name) | 173 params_class = "%s_%s_Params" % (method.interface.name, method.name) |
140 struct = mojom.Struct(params_class, module=method.interface.module) | 174 struct = mojom.Struct(params_class, module=method.interface.module) |
141 for param in method.parameters: | 175 for param in method.parameters: |
142 struct.AddField(param.name, param.kind, param.ordinal, | 176 struct.AddField(param.name, param.kind, param.ordinal, |
143 attributes=param.attributes) | 177 attributes=param.attributes) |
144 return self._AddStructComputedData(False, struct) | 178 self._AddStructComputedData(False, struct) |
| 179 return struct |
145 | 180 |
146 def _GetResponseStructFromMethod(self, method): | 181 def _GetResponseStructFromMethod(self, method): |
147 """Converts a method's response_parameters into the fields of a struct.""" | 182 """Converts a method's response_parameters into the fields of a struct.""" |
148 params_class = "%s_%s_ResponseParams" % (method.interface.name, method.name) | 183 params_class = "%s_%s_ResponseParams" % (method.interface.name, method.name) |
149 struct = mojom.Struct(params_class, module=method.interface.module) | 184 struct = mojom.Struct(params_class, module=method.interface.module) |
150 for param in method.response_parameters: | 185 for param in method.response_parameters: |
151 struct.AddField(param.name, param.kind, param.ordinal, | 186 struct.AddField(param.name, param.kind, param.ordinal, |
152 attributes=param.attributes) | 187 attributes=param.attributes) |
153 return self._AddStructComputedData(False, struct) | 188 self._AddStructComputedData(False, struct) |
| 189 return struct |
OLD | NEW |