OLD | NEW |
1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 # Copyright (c) 2012 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 from model import PropertyType | 5 from model import PropertyType |
6 import code | 6 import code |
7 import cpp_util | 7 import cpp_util |
8 import os | 8 import os |
9 | 9 |
10 class HGenerator(object): | 10 class HGenerator(object): |
(...skipping 24 matching lines...) Expand all Loading... |
35 .Append('#include <vector>') | 35 .Append('#include <vector>') |
36 .Append() | 36 .Append() |
37 .Append('#include "base/basictypes.h"') | 37 .Append('#include "base/basictypes.h"') |
38 .Append('#include "base/memory/linked_ptr.h"') | 38 .Append('#include "base/memory/linked_ptr.h"') |
39 .Append('#include "base/memory/scoped_ptr.h"') | 39 .Append('#include "base/memory/scoped_ptr.h"') |
40 .Append('#include "base/values.h"') | 40 .Append('#include "base/values.h"') |
41 .Append() | 41 .Append() |
42 ) | 42 ) |
43 | 43 |
44 c.Concat(self._cpp_type_generator.GetRootNamespaceStart()) | 44 c.Concat(self._cpp_type_generator.GetRootNamespaceStart()) |
| 45 # TODO(calamity): These forward declarations should be #includes to allow |
| 46 # $ref types from other files to be used as required params. This requires |
| 47 # some detangling of windows and tabs which will currently lead to circular |
| 48 # #includes. |
45 forward_declarations = ( | 49 forward_declarations = ( |
46 self._cpp_type_generator.GenerateForwardDeclarations()) | 50 self._cpp_type_generator.GenerateForwardDeclarations()) |
47 if not forward_declarations.IsEmpty(): | 51 if not forward_declarations.IsEmpty(): |
48 (c.Append() | 52 (c.Append() |
49 .Concat(forward_declarations) | 53 .Concat(forward_declarations) |
50 .Append() | 54 .Append() |
51 ) | 55 ) |
52 | 56 |
53 (c.Concat(self._cpp_type_generator.GetNamespaceStart()) | 57 c.Concat(self._cpp_type_generator.GetNamespaceStart()) |
54 .Append() | 58 c.Append() |
55 .Append('//') | 59 if self._namespace.types: |
56 .Append('// Types') | 60 (c.Append('//') |
57 .Append('//') | 61 .Append('// Types') |
58 .Append() | 62 .Append('//') |
59 ) | |
60 for type_ in self._namespace.types.values(): | |
61 (c.Concat(self._GenerateType(type_)) | |
62 .Append() | 63 .Append() |
63 ) | 64 ) |
64 (c.Append('//') | 65 for type_ in self._namespace.types.values(): |
65 .Append('// Functions') | 66 (c.Concat(self._GenerateType(type_)) |
66 .Append('//') | 67 .Append() |
67 .Append() | 68 ) |
68 ) | 69 if self._namespace.functions: |
69 for function in self._namespace.functions.values(): | 70 (c.Append('//') |
70 (c.Concat(self._GenerateFunction(function)) | 71 .Append('// Functions') |
| 72 .Append('//') |
71 .Append() | 73 .Append() |
72 ) | 74 ) |
| 75 for function in self._namespace.functions.values(): |
| 76 (c.Concat(self._GenerateFunction(function)) |
| 77 .Append() |
| 78 ) |
73 (c.Append() | 79 (c.Append() |
74 .Concat(self._cpp_type_generator.GetNamespaceEnd()) | 80 .Concat(self._cpp_type_generator.GetNamespaceEnd()) |
75 .Concat(self._cpp_type_generator.GetRootNamespaceEnd()) | 81 .Concat(self._cpp_type_generator.GetRootNamespaceEnd()) |
76 .Append() | 82 .Append() |
77 .Append('#endif // %s' % ifndef_name) | 83 .Append('#endif // %s' % ifndef_name) |
78 .Append() | 84 .Append() |
79 ) | 85 ) |
80 return c | 86 return c |
81 | 87 |
82 def _GenerateEnumDeclaration(self, enum_name, prop, values): | 88 def _GenerateEnumDeclaration(self, enum_name, prop, values): |
| 89 """Generate the declaration of a C++ enum for the given property and |
| 90 values. |
| 91 """ |
83 c = code.Code() | 92 c = code.Code() |
84 c.Sblock('enum %s {' % enum_name) | 93 c.Sblock('enum %s {' % enum_name) |
85 if prop.optional: | 94 if prop.optional: |
86 c.Append(self._cpp_type_generator.GetEnumNoneValue(prop) + ',') | 95 c.Append(self._cpp_type_generator.GetEnumNoneValue(prop) + ',') |
87 for value in values: | 96 for value in values: |
88 c.Append(self._cpp_type_generator.GetEnumValue(prop, value) + ',') | 97 c.Append(self._cpp_type_generator.GetEnumValue(prop, value) + ',') |
89 (c.Eblock('};') | 98 (c.Eblock('};') |
90 .Append() | 99 .Append() |
91 ) | 100 ) |
92 return c | 101 return c |
93 | 102 |
94 def _GenerateFields(self, props): | 103 def _GenerateFields(self, props): |
95 """Generates the field declarations when declaring a type. | 104 """Generates the field declarations when declaring a type. |
96 """ | 105 """ |
97 c = code.Code() | 106 c = code.Code() |
98 # Generate the enums needed for any fields with "choices" | 107 # Generate the enums needed for any fields with "choices" |
99 for prop in props: | 108 for prop in props: |
100 if prop.type_ == PropertyType.CHOICES: | 109 if prop.type_ == PropertyType.CHOICES: |
101 enum_name = self._cpp_type_generator.GetChoicesEnumType(prop) | 110 enum_name = self._cpp_type_generator.GetChoicesEnumType(prop) |
102 c.Concat(self._GenerateEnumDeclaration( | |
103 enum_name, | |
104 prop, | |
105 [choice.type_.name for choice in prop.choices.values()])) | |
106 c.Append('%s %s_type;' % (enum_name, prop.unix_name)) | 111 c.Append('%s %s_type;' % (enum_name, prop.unix_name)) |
107 elif prop.type_ == PropertyType.ENUM: | |
108 c.Concat(self._GenerateEnumDeclaration( | |
109 self._cpp_type_generator.GetType(prop), | |
110 prop, | |
111 prop.enum_values)) | |
112 for prop in self._cpp_type_generator.GetExpandedChoicesInParams(props): | 112 for prop in self._cpp_type_generator.GetExpandedChoicesInParams(props): |
113 if prop.description: | 113 if prop.description: |
114 c.Comment(prop.description) | 114 c.Comment(prop.description) |
115 c.Append('%s %s;' % ( | 115 c.Append('%s %s;' % ( |
116 self._cpp_type_generator.GetType(prop, wrap_optional=True), | 116 self._cpp_type_generator.GetType(prop, wrap_optional=True), |
117 prop.unix_name)) | 117 prop.unix_name)) |
118 c.Append() | 118 c.Append() |
119 return c | 119 return c |
120 | 120 |
121 def _GenerateType(self, type_, serializable=True): | 121 def _GenerateType(self, type_): |
122 """Generates a struct for a type. | 122 """Generates a struct for a type. |
123 """ | 123 """ |
124 classname = cpp_util.Classname(type_.name) | 124 classname = cpp_util.Classname(type_.name) |
125 c = code.Code() | 125 c = code.Code() |
126 if type_.description: | 126 if type_.description: |
127 c.Comment(type_.description) | 127 c.Comment(type_.description) |
128 (c.Sblock('struct %(classname)s {') | 128 (c.Sblock('struct %(classname)s {') |
129 .Append('~%(classname)s();') | 129 .Append('~%(classname)s();') |
130 .Append('%(classname)s();') | 130 .Append('%(classname)s();') |
131 .Append() | 131 .Append() |
| 132 .Concat(self._GeneratePropertyStructures(type_.properties.values())) |
132 .Concat(self._GenerateFields(type_.properties.values())) | 133 .Concat(self._GenerateFields(type_.properties.values())) |
133 .Comment('Populates a %(classname)s object from a Value. Returns' | 134 ) |
134 ' whether |out| was successfully populated.') | 135 if type_.from_json: |
| 136 (c.Comment('Populates a %s object from a Value. Returns' |
| 137 ' whether |out| was successfully populated.' % classname) |
135 .Append('static bool Populate(const Value& value, %(classname)s* out);') | 138 .Append('static bool Populate(const Value& value, %(classname)s* out);') |
136 .Append() | 139 .Append() |
137 ) | 140 ) |
138 | 141 |
139 if serializable: | 142 if type_.from_client: |
140 (c.Comment('Returns a new DictionaryValue representing the' | 143 (c.Comment('Returns a new DictionaryValue representing the' |
141 ' serialized form of this %(classname)s object. Passes ' | 144 ' serialized form of this %s object. Passes ' |
142 'ownership to caller.') | 145 'ownership to caller.' % classname) |
143 .Append('scoped_ptr<DictionaryValue> ToValue() const;') | 146 .Append('scoped_ptr<DictionaryValue> ToValue() const;') |
144 ) | 147 ) |
145 (c.Eblock() | 148 (c.Eblock() |
146 .Sblock(' private:') | 149 .Sblock(' private:') |
147 .Append('DISALLOW_COPY_AND_ASSIGN(%(classname)s);') | 150 .Append('DISALLOW_COPY_AND_ASSIGN(%(classname)s);') |
148 .Eblock('};') | 151 .Eblock('};') |
149 ) | 152 ) |
150 c.Substitute({'classname': classname}) | 153 c.Substitute({'classname': classname}) |
151 return c | 154 return c |
152 | 155 |
153 def _GenerateFunction(self, function): | 156 def _GenerateFunction(self, function): |
154 """Generates the structs for a function. | 157 """Generates the structs for a function. |
155 """ | 158 """ |
156 c = code.Code() | 159 c = code.Code() |
157 (c.Sblock('namespace %s {' % cpp_util.Classname(function.name)) | 160 (c.Sblock('namespace %s {' % cpp_util.Classname(function.name)) |
158 .Concat(self._GenerateFunctionParams(function)) | 161 .Concat(self._GenerateFunctionParams(function)) |
159 .Append() | 162 .Append() |
160 .Concat(self._GenerateFunctionResult(function)) | 163 ) |
| 164 if function.callback: |
| 165 (c.Concat(self._GenerateFunctionResult(function)) |
161 .Append() | 166 .Append() |
162 .Eblock('};') | 167 ) |
163 ) | 168 c.Eblock('};') |
| 169 |
164 return c | 170 return c |
165 | 171 |
166 def _GenerateFunctionParams(self, function): | 172 def _GenerateFunctionParams(self, function): |
167 """Generates the struct for passing parameters into a function. | 173 """Generates the struct for passing parameters into a function. |
168 """ | 174 """ |
169 c = code.Code() | 175 c = code.Code() |
170 | 176 |
171 if function.params: | 177 if function.params: |
172 c.Sblock('struct Params {') | 178 (c.Sblock('struct Params {') |
173 for param in function.params: | 179 .Concat(self._GeneratePropertyStructures(function.params)) |
174 if param.type_ == PropertyType.OBJECT: | 180 .Concat(self._GenerateFields(function.params)) |
175 c.Concat(self._GenerateType(param, serializable=False)) | 181 .Append('~Params();') |
176 c.Append() | 182 .Append() |
177 (c.Concat(self._GenerateFields(function.params)) | 183 .Append('static scoped_ptr<Params> Create(const ListValue& args);') |
178 .Append('~Params();') | 184 .Eblock() |
179 .Append() | 185 .Sblock(' private:') |
180 .Append('static scoped_ptr<Params> Create(const ListValue& args);') | 186 .Append('Params();') |
181 .Eblock() | 187 .Append() |
182 .Sblock(' private:') | 188 .Append('DISALLOW_COPY_AND_ASSIGN(Params);') |
183 .Append('Params();') | 189 .Eblock('};') |
184 .Append() | |
185 .Append('DISALLOW_COPY_AND_ASSIGN(Params);') | |
186 .Eblock('};') | |
187 ) | 190 ) |
188 | 191 |
189 return c | 192 return c |
190 | 193 |
| 194 def _GeneratePropertyStructures(self, props): |
| 195 """Generate the structures required by a property such as OBJECT classes |
| 196 and enums. |
| 197 """ |
| 198 c = code.Code() |
| 199 for prop in props: |
| 200 if prop.type_ == PropertyType.OBJECT: |
| 201 c.Concat(self._GenerateType(prop)) |
| 202 c.Append() |
| 203 elif prop.type_ == PropertyType.CHOICES: |
| 204 c.Concat(self._GenerateEnumDeclaration( |
| 205 self._cpp_type_generator.GetChoicesEnumType(prop), |
| 206 prop, |
| 207 [choice.type_.name for choice in prop.choices.values()])) |
| 208 elif prop.type_ == PropertyType.ENUM: |
| 209 enum_name = self._cpp_type_generator.GetType(prop) |
| 210 c.Concat(self._GenerateEnumDeclaration( |
| 211 enum_name, |
| 212 prop, |
| 213 prop.enum_values)) |
| 214 c.Append('static scoped_ptr<Value> CreateEnumValue(%s %s);' % |
| 215 (enum_name, prop.unix_name)) |
| 216 return c |
| 217 |
191 def _GenerateFunctionResult(self, function): | 218 def _GenerateFunctionResult(self, function): |
192 """Generates functions for passing a function's result back. | 219 """Generates functions for passing a function's result back. |
193 """ | 220 """ |
194 c = code.Code() | 221 c = code.Code() |
195 | 222 |
196 c.Sblock('namespace Result {') | 223 c.Sblock('namespace Result {') |
197 params = function.callback.params | 224 params = function.callback.params |
198 if not params: | 225 if not params: |
199 c.Append('Value* Create();') | 226 c.Append('Value* Create();') |
200 else: | 227 else: |
| 228 c.Concat(self._GeneratePropertyStructures(params)) |
| 229 |
201 # If there is a single parameter, this is straightforward. However, if | 230 # If there is a single parameter, this is straightforward. However, if |
202 # the callback parameter is of 'choices', this generates a Create method | 231 # the callback parameter is of 'choices', this generates a Create method |
203 # for each choice. This works because only 1 choice can be returned at a | 232 # for each choice. This works because only 1 choice can be returned at a |
204 # time. | 233 # time. |
205 for param in self._cpp_type_generator.GetExpandedChoicesInParams(params): | 234 for param in self._cpp_type_generator.GetExpandedChoicesInParams(params): |
206 if param.description: | 235 if param.description: |
207 c.Comment(param.description) | 236 c.Comment(param.description) |
208 if param.type_ == PropertyType.OBJECT: | |
209 raise NotImplementedError('OBJECT return type not supported') | |
210 c.Append('Value* Create(const %s);' % cpp_util.GetParameterDeclaration( | 237 c.Append('Value* Create(const %s);' % cpp_util.GetParameterDeclaration( |
211 param, self._cpp_type_generator.GetType(param))) | 238 param, self._cpp_type_generator.GetType(param))) |
212 c.Eblock('};') | 239 c.Eblock('};') |
213 | 240 |
214 return c | 241 return c |
215 | 242 |
216 def _GenerateIfndefName(self): | 243 def _GenerateIfndefName(self): |
217 """Formats a path and filename as a #define name. | 244 """Formats a path and filename as a #define name. |
218 | 245 |
219 e.g chrome/extensions/gen, file.h becomes CHROME_EXTENSIONS_GEN_FILE_H__. | 246 e.g chrome/extensions/gen, file.h becomes CHROME_EXTENSIONS_GEN_FILE_H__. |
220 """ | 247 """ |
221 return (('%s_%s_H__' % | 248 return (('%s_%s_H__' % |
222 (self._namespace.source_file_dir, self._target_namespace)) | 249 (self._namespace.source_file_dir, self._target_namespace)) |
223 .upper().replace(os.sep, '_')) | 250 .upper().replace(os.sep, '_')) |
224 | 251 |
OLD | NEW |