Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(5)

Side by Side Diff: tools/json_schema_compiler/h_generator.py

Issue 9114036: Code generation for extensions api (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: a fistful of rework Created 8 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698