OLD | NEW |
---|---|
(Empty) | |
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 | |
3 # found in the LICENSE file. | |
4 | |
5 from model import PropertyType | |
6 import code | |
7 import cpp_type_generator | |
8 import cpp_util | |
9 | |
10 class HGenerator(object): | |
11 """A .h generator for a namespace. | |
12 """ | |
13 def __init__(self, namespace, model, root_namespace): | |
14 self.__cpp_type_generator = cpp_type_generator.CppTypeGenerator( | |
15 namespace, model) | |
16 self.__namespace = namespace | |
17 self.__root_namespace = root_namespace | |
18 | |
19 def generate(self): | |
20 """Generates a code.Code object with the .h for a single namespace. | |
21 """ | |
22 target_namespace = self.__namespace.target_namespace | |
23 c = code.Code() | |
24 (c.append(cpp_util.CHROMIUM_LICENSE).append() | |
25 .append(cpp_util.GENERATED_FILE_MESSAGE % self.__namespace.source_file) | |
26 .append() | |
27 ) | |
28 | |
29 ifndef_name = self.__generate_ifndef_name() | |
30 (c.append('#ifndef %s' % ifndef_name) | |
31 .append('#define %s' % ifndef_name) | |
32 .append('#pragma once') | |
33 .append() | |
34 .append('#include <string>') | |
35 .append('#include <vector>') | |
36 .append() | |
37 .append('#include "base/basictypes.h"') | |
38 .append('#include "base/memory/scoped_ptr.h"') | |
39 .append('#include "base/values.h"') | |
40 .append() | |
41 .append('using base::Value;') | |
42 .append('using base::DictionaryValue;') | |
43 .append('using base::ListValue;') | |
44 .append() | |
45 ) | |
46 | |
47 includes = self.__cpp_type_generator.generate_cpp_includes() | |
48 if includes.is_empty(): | |
Yoyo Zhou
2012/01/19 02:19:40
This looks incorrect.
calamity
2012/01/20 01:10:25
Done.
| |
49 (c.concat(includes) | |
50 .append() | |
51 ) | |
52 | |
53 (c.append('namespace %s {' % self.__root_namespace) | |
54 .append('namespace %s {' % target_namespace) | |
55 .append() | |
56 .append('//') | |
57 .append('// Types') | |
58 .append('//') | |
59 .append() | |
60 ) | |
61 for tipe in self.__namespace.types.values(): | |
62 (c.concat(self.__generate_type(tipe)) | |
63 .append() | |
64 ) | |
65 (c.append('//') | |
66 .append('// Functions') | |
67 .append('//') | |
68 .append() | |
69 ) | |
70 for function in self.__namespace.functions.values(): | |
71 (c.concat(self.__generate_function(function)) | |
72 .append() | |
73 ) | |
74 (c.append() | |
75 .append() | |
76 .append('} // namespace %s' % self.__root_namespace) | |
Yoyo Zhou
2012/01/19 02:19:40
2 spaces before inline comments
calamity
2012/01/20 01:10:25
Done.
| |
77 .append('} // namespace %s' % target_namespace) | |
78 .append() | |
79 .append('#endif // %s' % ifndef_name) | |
80 .append() | |
81 ) | |
82 return c | |
83 | |
84 def __generate_type(self, tipe, serializable=True): | |
85 """Generates a struct for a type. | |
86 """ | |
87 classname = cpp_util.cpp_name(tipe.name) | |
88 c = code.Code() | |
89 if tipe.description: | |
90 c.comment(tipe.description) | |
91 (c.sblock('struct %(classname)s {') | |
92 .append('~%(classname)s();') | |
93 .append('%(classname)s();') | |
94 .append() | |
95 ) | |
96 | |
97 for prop in tipe.properties.values(): | |
98 if prop.description: | |
99 c.comment(prop.description) | |
100 if prop.optional: | |
101 c.append('scoped_ptr<%s> %s;' % | |
102 (self.__cpp_type_generator.get_type(prop, pad_for_generics=True), | |
103 prop.name)) | |
104 else: | |
105 c.append('%s %s;' % | |
106 (self.__cpp_type_generator.get_type(prop), prop.name)) | |
107 c.append() | |
108 | |
109 (c.comment('Populates a %(classname)s object from a Value. Returns' | |
110 ' whether |out| was successfully populated.') | |
111 .append('static bool Populate(const Value& value, %(classname)s* out);') | |
112 .append() | |
113 ) | |
114 | |
115 if serializable: | |
116 (c.comment('Returns a new DictionaryValue representing the' | |
117 ' serialized form of this %(classname)s object.') | |
118 .append('DictionaryValue* ToValue() const;') | |
119 ) | |
120 (c.eblock() | |
121 .sblock(' private:') | |
122 .append('DISALLOW_COPY_AND_ASSIGN(%(classname)s);') | |
123 .eblock('};') | |
124 ) | |
125 c.substitute({'classname': classname}) | |
126 return c | |
127 | |
128 def __generate_function(self, function): | |
129 """Generates the structs for a function. | |
130 """ | |
131 c = code.Code() | |
132 (c.sblock('struct %s {' % cpp_util.cpp_name(function.name)) | |
133 .concat(self.__generate_function_params(function)) | |
134 .append() | |
135 .concat(self.__generate_function_result(function)) | |
136 .append() | |
137 .eblock('};') | |
138 ) | |
139 return c | |
140 | |
141 def __generate_function_params(self, function): | |
142 """Generates the struct for passing parameters into a function. | |
143 """ | |
144 c = code.Code() | |
145 | |
146 c.sblock('struct Params {') | |
Yoyo Zhou
2012/01/19 23:19:11
Seems like this should be inside the
if function.p
calamity
2012/01/20 01:10:25
Originally, I had one class that generated the .cc
| |
147 for param in function.params: | |
148 if param.description: | |
149 c.comment(param.description) | |
150 if param.type == PropertyType.OBJECT: | |
151 c.concat(self.__generate_type(param, serializable=False)) | |
152 c.append() | |
153 for param in function.params: | |
154 c.append('%s %s;' % | |
155 (self.__cpp_type_generator.get_type(param), param.name)) | |
156 | |
157 if function.params: | |
158 (c.append() | |
159 .append('Params();') | |
160 .append('~Params();') | |
161 .append() | |
162 .append('static bool Populate(const ListValue& args, Params* out);') | |
163 .eblock() | |
164 .sblock(' private:') | |
165 .append('DISALLOW_COPY_AND_ASSIGN(Params);') | |
166 ) | |
167 | |
168 c.eblock('};') | |
169 | |
170 return c | |
171 | |
172 def __generate_function_result(self, function): | |
173 """Generates the struct for passing a function's result back. | |
174 """ | |
175 # TODO(calamity): Handle returning an object | |
176 c = code.Code() | |
177 | |
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 {') | |
183 .sblock(' public:') | |
184 ) | |
185 arg = '' | |
186 # TODO(calamity): handle object | |
187 if param: | |
188 if param.type == PropertyType.REF: | |
189 arg = 'const %(type)s& %(name)s' | |
190 else: | |
191 arg = 'const %(type)s %(name)s' | |
192 arg = arg % {'type': self.__cpp_type_generator.get_type(param), | |
193 'name': param.name} | |
194 (c.append('static Value* Create(%s);' % arg) | |
195 .eblock() | |
196 .sblock(' private:') | |
197 .append('Result() {};') | |
198 .append('DISALLOW_COPY_AND_ASSIGN(Result);') | |
199 .eblock('};') | |
200 ) | |
201 | |
202 return c | |
203 | |
204 def __generate_ifndef_name(self): | |
205 """Formats a path and filename as a #define name. | |
206 | |
207 e.g chrome/extensions/gen, file.h becomes CHROME_EXTENSIONS_GEN_FILE_H__. | |
208 """ | |
209 return (('%s/%s_H__' % | |
210 (self.__namespace.source_file_dir, self.__namespace.target_namespace)) | |
211 .upper().replace('/', '_')) | |
212 | |
OLD | NEW |