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 | |
9 | 8 |
10 class HGenerator(object): | 9 class HGenerator(object): |
11 """A .h generator for a namespace. | 10 """A .h generator for a namespace. |
12 """ | 11 """ |
13 def __init__(self, namespace, cpp_type_generator): | 12 def __init__(self, namespace, cpp_type_generator): |
14 self._cpp_type_generator = cpp_type_generator | 13 self._cpp_type_generator = cpp_type_generator |
15 self._namespace = namespace | 14 self._namespace = namespace |
16 self._target_namespace = ( | 15 self._target_namespace = ( |
17 self._cpp_type_generator.GetCppNamespaceName(self._namespace)) | 16 self._cpp_type_generator.GetCppNamespaceName(self._namespace)) |
18 | 17 |
19 def Generate(self): | 18 def Generate(self): |
20 """Generates a code.Code object with the .h for a single namespace. | 19 """Generates a code.Code object with the .h for a single namespace. |
21 """ | 20 """ |
22 c = code.Code() | 21 c = code.Code() |
23 (c.Append(cpp_util.CHROMIUM_LICENSE) | 22 (c.Append(cpp_util.CHROMIUM_LICENSE) |
24 .Append() | 23 .Append() |
25 .Append(cpp_util.GENERATED_FILE_MESSAGE % self._namespace.source_file) | 24 .Append(cpp_util.GENERATED_FILE_MESSAGE % self._namespace.source_file) |
26 .Append() | 25 .Append() |
27 ) | 26 ) |
28 | 27 |
29 ifndef_name = self._GenerateIfndefName() | 28 ifndef_name = self._GenerateIfndefName() |
30 (c.Append('#ifndef %s' % ifndef_name) | 29 (c.Append('#ifndef %s' % ifndef_name) |
31 .Append('#define %s' % ifndef_name) | 30 .Append('#define %s' % ifndef_name) |
32 .Append('#pragma once') | 31 .Append('#pragma once') |
33 .Append() | 32 .Append() |
34 .Append('#include <string>') | 33 .Append('#include <string>') |
35 .Append('#include <vector>') | 34 .Append('#include <vector>') |
36 .Append() | 35 .Append() |
37 .Append('#include "base/basictypes.h"') | 36 .Append('#include "base/basictypes.h"') |
37 .Append('#include "base/memory/linked_ptr.h"') | |
38 .Append('#include "base/memory/scoped_ptr.h"') | 38 .Append('#include "base/memory/scoped_ptr.h"') |
39 .Append('#include "base/values.h"') | 39 .Append('#include "base/values.h"') |
40 .Append() | 40 .Append() |
41 .Append('using base::Value;') | 41 .Append('using base::Value;') |
42 .Append('using base::DictionaryValue;') | 42 .Append('using base::DictionaryValue;') |
43 .Append('using base::ListValue;') | 43 .Append('using base::ListValue;') |
44 .Append() | 44 .Append() |
45 ) | 45 ) |
46 | 46 |
47 includes = self._cpp_type_generator.GenerateCppIncludes() | 47 c.Concat(self._cpp_type_generator.GetRootNamespaceStart()) |
48 if not includes.IsEmpty(): | 48 forward_declarations = ( |
49 (c.Concat(includes) | 49 self._cpp_type_generator.GenerateForwardDeclarations()) |
50 if not forward_declarations.IsEmpty(): | |
51 (c.Append() | |
52 .Concat(forward_declarations) | |
50 .Append() | 53 .Append() |
51 ) | 54 ) |
52 | 55 |
53 (c.Concat(self._cpp_type_generator.GetCppNamespaceStart()) | 56 (c.Concat(self._cpp_type_generator.GetNamespaceStart()) |
54 .Append() | 57 .Append() |
55 .Append('//') | 58 .Append('//') |
56 .Append('// Types') | 59 .Append('// Types') |
57 .Append('//') | 60 .Append('//') |
58 .Append() | 61 .Append() |
59 ) | 62 ) |
60 for type_ in self._namespace.types.values(): | 63 for type_ in self._namespace.types.values(): |
61 (c.Concat(self._GenerateType(type_)) | 64 (c.Concat(self._GenerateType(type_)) |
62 .Append() | 65 .Append() |
63 ) | 66 ) |
64 (c.Append('//') | 67 (c.Append('//') |
65 .Append('// Functions') | 68 .Append('// Functions') |
66 .Append('//') | 69 .Append('//') |
67 .Append() | 70 .Append() |
68 ) | 71 ) |
69 for function in self._namespace.functions.values(): | 72 for function in self._namespace.functions.values(): |
70 (c.Concat(self._GenerateFunction(function)) | 73 (c.Concat(self._GenerateFunction(function)) |
71 .Append() | 74 .Append() |
72 ) | 75 ) |
73 (c.Append() | 76 (c.Append() |
74 .Append() | 77 .Concat(self._cpp_type_generator.GetNamespaceEnd()) |
75 .Concat(self._cpp_type_generator.GetCppNamespaceEnd()) | 78 .Concat(self._cpp_type_generator.GetRootNamespaceEnd()) |
76 .Append() | 79 .Append() |
77 .Append('#endif // %s' % ifndef_name) | 80 .Append('#endif // %s' % ifndef_name) |
78 .Append() | 81 .Append() |
79 ) | 82 ) |
80 return c | 83 return c |
81 | 84 |
85 def _GenerateFields(self, props): | |
86 """Generates the field declarations when declaring a type. | |
87 """ | |
88 c = code.Code() | |
89 for prop in self._cpp_type_generator.ExpandedChoicesInParams(props): | |
90 if prop.description: | |
91 c.Comment(prop.description) | |
92 c.Append('%s %s;' % ( | |
93 self._cpp_type_generator.GetType(prop, wrap_optional=True), | |
94 prop.unix_name)) | |
95 c.Append() | |
96 for prop in [x for x in props if x.type_ == PropertyType.CHOICES]: | |
not at google - send to devlin
2012/02/08 05:02:08
I think this needs a comment, like
# Generate the
calamity
2012/02/08 07:01:18
Done.
| |
97 enum_name = self._cpp_type_generator.GetChoicesEnumName(prop) | |
98 c.Sblock('enum %s {' % enum_name) | |
99 enums = [] | |
100 enums.append(self._cpp_type_generator.GetChoiceEnum(prop, None)) | |
101 for choice in prop.choices.values(): | |
102 enums.append( | |
103 self._cpp_type_generator.GetChoiceEnum(prop, choice.type_)) | |
104 for enum in ', '.join(enums).split(): | |
105 c.Append(enum) | |
not at google - send to devlin
2012/02/08 05:02:08
I don't understand why you've done it this way rat
calamity
2012/02/08 07:01:18
Hah. Didn't know that. My default assumption is th
| |
106 (c.Eblock('};') | |
107 .Append() | |
108 .Append('%s %s_type;' % (enum_name, prop.unix_name)) | |
109 ) | |
110 return c | |
111 | |
82 def _GenerateType(self, type_, serializable=True): | 112 def _GenerateType(self, type_, serializable=True): |
83 """Generates a struct for a type. | 113 """Generates a struct for a type. |
84 """ | 114 """ |
85 classname = cpp_util.CppName(type_.name) | 115 classname = cpp_util.Classname(type_.name) |
86 c = code.Code() | 116 c = code.Code() |
87 if type_.description: | 117 if type_.description: |
88 c.Comment(type_.description) | 118 c.Comment(type_.description) |
89 (c.Sblock('struct %(classname)s {') | 119 (c.Sblock('struct %(classname)s {') |
90 .Append('~%(classname)s();') | 120 .Append('~%(classname)s();') |
91 .Append('%(classname)s();') | 121 .Append('%(classname)s();') |
92 .Append() | 122 .Append() |
93 ) | 123 .Concat(self._GenerateFields(type_.properties.values())) |
94 | 124 .Comment('Populates a %(classname)s object from a Value. Returns' |
95 for prop in type_.properties.values(): | 125 ' whether |out| was successfully populated.') |
96 if prop.description: | 126 .Append('static bool Populate(const Value& value, %(classname)s* out);') |
97 c.Comment(prop.description) | 127 .Append() |
98 if prop.optional: | |
99 c.Append('scoped_ptr<%s> %s;' % | |
100 (self._cpp_type_generator.GetType(prop, pad_for_generics=True), | |
101 prop.name)) | |
102 else: | |
103 c.Append('%s %s;' % | |
104 (self._cpp_type_generator.GetType(prop), prop.name)) | |
105 c.Append() | |
106 | |
107 (c.Comment('Populates a %(classname)s object from a Value. Returns' | |
108 ' whether |out| was successfully populated.') | |
109 .Append('static bool Populate(const Value& value, %(classname)s* out);') | |
110 .Append() | |
111 ) | 128 ) |
112 | 129 |
113 if serializable: | 130 if serializable: |
114 (c.Comment('Returns a new DictionaryValue representing the' | 131 (c.Comment('Returns a new DictionaryValue representing the' |
115 ' serialized form of this %(classname)s object. Passes' | 132 ' serialized form of this %(classname)s object. Passes' |
116 'ownership to caller.') | 133 'ownership to caller.') |
117 .Append('DictionaryValue* ToValue() const;') | 134 .Append('DictionaryValue* ToValue() const;') |
118 ) | 135 ) |
119 (c.Eblock() | 136 (c.Eblock() |
120 .Sblock(' private:') | 137 .Sblock(' private:') |
121 .Append('DISALLOW_COPY_AND_ASSIGN(%(classname)s);') | 138 .Append('DISALLOW_COPY_AND_ASSIGN(%(classname)s);') |
122 .Eblock('};') | 139 .Eblock('};') |
123 ) | 140 ) |
124 c.Substitute({'classname': classname}) | 141 c.Substitute({'classname': classname}) |
125 return c | 142 return c |
126 | 143 |
127 def _GenerateFunction(self, function): | 144 def _GenerateFunction(self, function): |
128 """Generates the structs for a function. | 145 """Generates the structs for a function. |
129 """ | 146 """ |
130 c = code.Code() | 147 c = code.Code() |
131 (c.Sblock('namespace %s {' % cpp_util.CppName(function.name)) | 148 (c.Sblock('namespace %s {' % cpp_util.Classname(function.name)) |
132 .Concat(self._GenerateFunctionParams(function)) | 149 .Concat(self._GenerateFunctionParams(function)) |
133 .Append() | 150 .Append() |
134 .Concat(self._GenerateFunctionResult(function)) | 151 .Concat(self._GenerateFunctionResult(function)) |
135 .Append() | 152 .Append() |
136 .Eblock('};') | 153 .Eblock('};') |
137 ) | 154 ) |
138 return c | 155 return c |
139 | 156 |
140 def _GenerateFunctionParams(self, function): | 157 def _GenerateFunctionParams(self, function): |
141 """Generates the struct for passing parameters into a function. | 158 """Generates the struct for passing parameters into a function. |
142 """ | 159 """ |
143 c = code.Code() | 160 c = code.Code() |
144 | 161 |
145 if function.params: | 162 if function.params: |
146 c.Sblock('struct Params {') | 163 c.Sblock('struct Params {') |
147 for param in function.params: | 164 for param in function.params: |
148 if param.description: | 165 if param.description: |
149 c.Comment(param.description) | 166 c.Comment(param.description) |
150 if param.type_ == PropertyType.OBJECT: | 167 if param.type_ == PropertyType.OBJECT: |
151 c.Concat(self._GenerateType(param, serializable=False)) | 168 c.Concat(self._GenerateType(param, serializable=False)) |
152 c.Append() | 169 c.Append() |
153 for param in function.params: | 170 (c.Concat(self._GenerateFields(function.params)) |
154 c.Append('%s %s;' % | 171 .Append() |
155 (self._cpp_type_generator.GetType(param), param.name)) | |
156 | |
157 (c.Append() | |
158 .Append('~Params();') | 172 .Append('~Params();') |
159 .Append() | 173 .Append() |
160 .Append('static scoped_ptr<Params> Create(const ListValue& args);') | 174 .Append('static scoped_ptr<Params> Create(const ListValue& args);') |
161 .Eblock() | 175 .Eblock() |
162 .Sblock(' private:') | 176 .Sblock(' private:') |
163 .Append('Params();') | 177 .Append('Params();') |
164 .Append() | 178 .Append() |
165 .Append('DISALLOW_COPY_AND_ASSIGN(Params);') | 179 .Append('DISALLOW_COPY_AND_ASSIGN(Params);') |
180 .Eblock('};') | |
166 ) | 181 ) |
167 | 182 |
168 c.Eblock('};') | |
169 | |
170 return c | 183 return c |
171 | 184 |
172 def _GenerateFunctionResult(self, function): | 185 def _GenerateFunctionResult(self, function): |
173 """Generates the struct for passing a function's result back. | 186 """Generates the struct for passing a function's result back. |
174 """ | 187 """ |
175 # TODO(calamity): Handle returning an object | |
176 c = code.Code() | 188 c = code.Code() |
177 | 189 |
178 param = function.callback.param | |
179 # TODO(calamity): Put this description comment in less stupid place | |
180 if param.description: | |
181 c.Comment(param.description) | |
182 (c.Append('class Result {') | 190 (c.Append('class Result {') |
183 .Sblock(' public:') | 191 .Sblock(' public:') |
184 ) | 192 ) |
185 arg = '' | 193 params = function.callback.params |
186 # TODO(calamity): handle object | 194 if not params: |
187 if param: | 195 c.Append('static Value* Create();') |
188 if param.type_ == PropertyType.REF: | 196 else: |
189 arg = 'const %(type)s& %(name)s' | 197 # If there is a single parameter, this is straightforward. However, if |
190 else: | 198 # the callback parameter is of 'choices', this generates a Create method |
199 # for each choice. This works because only 1 choice can be returned at a | |
200 # time. | |
201 for param in self._cpp_type_generator.ExpandedChoicesInParams(params): | |
191 arg = 'const %(type)s %(name)s' | 202 arg = 'const %(type)s %(name)s' |
192 arg = arg % { | 203 if param.type_ == PropertyType.REF: |
193 'type': self._cpp_type_generator.GetType(param), | 204 arg = 'const %(type)s& %(name)s' |
194 'name': param.name | 205 arg %= { |
195 } | 206 'type': self._cpp_type_generator.GetType(param, wrap_optional=True), |
196 (c.Append('static Value* Create(%s);' % arg) | 207 'name': param.unix_name, |
197 .Eblock() | 208 } |
198 .Sblock(' private:') | 209 if param.description: |
199 .Append('Result() {};') | 210 c.Comment(param.description) |
200 .Append('DISALLOW_COPY_AND_ASSIGN(Result);') | 211 c.Append('static Value* Create(%s);' % arg) |
201 .Eblock('};') | 212 (c.Eblock() |
213 .Sblock(' private:') | |
214 .Append('Result() {};') | |
215 .Append('DISALLOW_COPY_AND_ASSIGN(Result);') | |
216 .Eblock('};') | |
202 ) | 217 ) |
203 | 218 |
204 return c | 219 return c |
205 | 220 |
206 def _GenerateIfndefName(self): | 221 def _GenerateIfndefName(self): |
207 """Formats a path and filename as a #define name. | 222 """Formats a path and filename as a #define name. |
208 | 223 |
209 e.g chrome/extensions/gen, file.h becomes CHROME_EXTENSIONS_GEN_FILE_H__. | 224 e.g chrome/extensions/gen, file.h becomes CHROME_EXTENSIONS_GEN_FILE_H__. |
210 """ | 225 """ |
211 return (('%s_%s_H__' % | 226 return (('%s/%s_H__' % |
212 (self._namespace.source_file_dir, self._target_namespace)) | 227 (self._namespace.source_file_dir, self._target_namespace)) |
213 .upper().replace(os.sep, '_')) | 228 .upper().replace('/', '_')) |
214 | 229 |
OLD | NEW |