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

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

Issue 9491002: json_schema_compiler: any, additionalProperties, functions on types (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: add any in arrays to util.h Created 8 years, 9 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
« no previous file with comments | « tools/json_schema_compiler/cpp_util.py ('k') | tools/json_schema_compiler/model.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 model
8 import os 9 import os
9 10
10 class HGenerator(object): 11 class HGenerator(object):
11 """A .h generator for a namespace. 12 """A .h generator for a namespace.
12 """ 13 """
13 def __init__(self, namespace, cpp_type_generator): 14 def __init__(self, namespace, cpp_type_generator):
14 self._cpp_type_generator = cpp_type_generator 15 self._cpp_type_generator = cpp_type_generator
15 self._namespace = namespace 16 self._namespace = namespace
16 self._target_namespace = ( 17 self._target_namespace = (
17 self._cpp_type_generator.GetCppNamespaceName(self._namespace)) 18 self._cpp_type_generator.GetCppNamespaceName(self._namespace))
(...skipping 13 matching lines...) Expand all
31 .Append('#define %s' % ifndef_name) 32 .Append('#define %s' % ifndef_name)
32 .Append('#pragma once') 33 .Append('#pragma once')
33 .Append() 34 .Append()
34 .Append('#include <string>') 35 .Append('#include <string>')
35 .Append('#include <vector>') 36 .Append('#include <vector>')
36 .Append() 37 .Append()
37 .Append('#include "base/basictypes.h"') 38 .Append('#include "base/basictypes.h"')
38 .Append('#include "base/memory/linked_ptr.h"') 39 .Append('#include "base/memory/linked_ptr.h"')
39 .Append('#include "base/memory/scoped_ptr.h"') 40 .Append('#include "base/memory/scoped_ptr.h"')
40 .Append('#include "base/values.h"') 41 .Append('#include "base/values.h"')
42 .Append('#include "tools/json_schema_compiler/any.h"')
41 .Append() 43 .Append()
42 ) 44 )
43 45
44 c.Concat(self._cpp_type_generator.GetRootNamespaceStart()) 46 c.Concat(self._cpp_type_generator.GetRootNamespaceStart())
45 # TODO(calamity): These forward declarations should be #includes to allow 47 # TODO(calamity): These forward declarations should be #includes to allow
46 # $ref types from other files to be used as required params. This requires 48 # $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 49 # some detangling of windows and tabs which will currently lead to circular
48 # #includes. 50 # #includes.
49 forward_declarations = ( 51 forward_declarations = (
50 self._cpp_type_generator.GenerateForwardDeclarations()) 52 self._cpp_type_generator.GenerateForwardDeclarations())
(...skipping 18 matching lines...) Expand all
69 if self._namespace.functions: 71 if self._namespace.functions:
70 (c.Append('//') 72 (c.Append('//')
71 .Append('// Functions') 73 .Append('// Functions')
72 .Append('//') 74 .Append('//')
73 .Append() 75 .Append()
74 ) 76 )
75 for function in self._namespace.functions.values(): 77 for function in self._namespace.functions.values():
76 (c.Concat(self._GenerateFunction(function)) 78 (c.Concat(self._GenerateFunction(function))
77 .Append() 79 .Append()
78 ) 80 )
79 (c.Append() 81 (c.Concat(self._cpp_type_generator.GetNamespaceEnd())
80 .Concat(self._cpp_type_generator.GetNamespaceEnd())
81 .Concat(self._cpp_type_generator.GetRootNamespaceEnd()) 82 .Concat(self._cpp_type_generator.GetRootNamespaceEnd())
82 .Append() 83 .Append()
83 .Append('#endif // %s' % ifndef_name) 84 .Append('#endif // %s' % ifndef_name)
84 .Append() 85 .Append()
85 ) 86 )
86 return c 87 return c
87 88
88 def _GenerateEnumDeclaration(self, enum_name, prop, values): 89 def _GenerateEnumDeclaration(self, enum_name, prop, values):
89 """Generate the declaration of a C++ enum for the given property and 90 """Generate the declaration of a C++ enum for the given property and
90 values. 91 values.
(...skipping 11 matching lines...) Expand all
102 103
103 def _GenerateFields(self, props): 104 def _GenerateFields(self, props):
104 """Generates the field declarations when declaring a type. 105 """Generates the field declarations when declaring a type.
105 """ 106 """
106 c = code.Code() 107 c = code.Code()
107 # Generate the enums needed for any fields with "choices" 108 # Generate the enums needed for any fields with "choices"
108 for prop in props: 109 for prop in props:
109 if prop.type_ == PropertyType.CHOICES: 110 if prop.type_ == PropertyType.CHOICES:
110 enum_name = self._cpp_type_generator.GetChoicesEnumType(prop) 111 enum_name = self._cpp_type_generator.GetChoicesEnumType(prop)
111 c.Append('%s %s_type;' % (enum_name, prop.unix_name)) 112 c.Append('%s %s_type;' % (enum_name, prop.unix_name))
113 c.Append()
112 for prop in self._cpp_type_generator.GetExpandedChoicesInParams(props): 114 for prop in self._cpp_type_generator.GetExpandedChoicesInParams(props):
113 if prop.description: 115 if prop.description:
114 c.Comment(prop.description) 116 c.Comment(prop.description)
115 c.Append('%s %s;' % ( 117 c.Append('%s %s;' % (
116 self._cpp_type_generator.GetType(prop, wrap_optional=True), 118 self._cpp_type_generator.GetType(prop, wrap_optional=True),
117 prop.unix_name)) 119 prop.unix_name))
118 c.Append() 120 c.Append()
119 return c 121 return c
120 122
121 def _GenerateType(self, type_): 123 def _GenerateType(self, type_):
122 """Generates a struct for a type. 124 """Generates a struct for a type.
123 """ 125 """
124 classname = cpp_util.Classname(type_.name) 126 classname = cpp_util.Classname(type_.name)
125 c = code.Code() 127 c = code.Code()
126 if type_.description: 128
127 c.Comment(type_.description) 129 if type_.functions:
128 (c.Sblock('struct %(classname)s {') 130 # Types with functions are not instantiable in C++ because they are
129 .Append('~%(classname)s();') 131 # handled in pure Javascript and hence have no properties or
130 .Append('%(classname)s();') 132 # additionalProperties.
131 .Append() 133 if type_.properties:
132 .Concat(self._GeneratePropertyStructures(type_.properties.values())) 134 raise NotImplementedError('\n'.join(model.GetModelHierarchy(type_)) +
133 .Concat(self._GenerateFields(type_.properties.values())) 135 '\nCannot generate both functions and properties on a type')
134 ) 136 c.Sblock('namespace %(classname)s {')
135 if type_.from_json: 137 for function in type_.functions.values():
136 (c.Comment('Populates a %s object from a Value. Returns' 138 (c.Concat(self._GenerateFunction(function))
137 ' whether |out| was successfully populated.' % classname) 139 .Append()
138 .Append('static bool Populate(const Value& value, %(classname)s* out);') 140 )
139 .Append() 141 c.Eblock('}')
142 else:
143 if type_.description:
144 c.Comment(type_.description)
145 (c.Sblock('struct %(classname)s {')
146 .Append('~%(classname)s();')
147 .Append('%(classname)s();')
148 .Append()
149 .Concat(self._GeneratePropertyStructures(type_.properties.values()))
150 .Concat(self._GenerateFields(type_.properties.values()))
140 ) 151 )
152 if type_.from_json:
153 (c.Comment('Populates a %s object from a Value. Returns'
154 ' whether |out| was successfully populated.' % classname)
155 .Append(
156 'static bool Populate(const Value& value, %(classname)s* out);')
157 .Append()
158 )
141 159
142 if type_.from_client: 160 if type_.from_client:
143 (c.Comment('Returns a new DictionaryValue representing the' 161 (c.Comment('Returns a new DictionaryValue representing the'
144 ' serialized form of this %s object. Passes ' 162 ' serialized form of this %s object. Passes '
145 'ownership to caller.' % classname) 163 'ownership to caller.' % classname)
146 .Append('scoped_ptr<DictionaryValue> ToValue() const;') 164 .Append('scoped_ptr<DictionaryValue> ToValue() const;')
165 )
166
167 (c.Eblock()
168 .Sblock(' private:')
169 .Append('DISALLOW_COPY_AND_ASSIGN(%(classname)s);')
170 .Eblock('};')
147 ) 171 )
148 (c.Eblock()
149 .Sblock(' private:')
150 .Append('DISALLOW_COPY_AND_ASSIGN(%(classname)s);')
151 .Eblock('};')
152 )
153 c.Substitute({'classname': classname}) 172 c.Substitute({'classname': classname})
154 return c 173 return c
155 174
156 def _GenerateFunction(self, function): 175 def _GenerateFunction(self, function):
157 """Generates the structs for a function. 176 """Generates the structs for a function.
158 """ 177 """
159 c = code.Code() 178 c = code.Code()
160 (c.Sblock('namespace %s {' % cpp_util.Classname(function.name)) 179 (c.Sblock('namespace %s {' % cpp_util.Classname(function.name))
161 .Concat(self._GenerateFunctionParams(function)) 180 .Concat(self._GenerateFunctionParams(function))
162 .Append() 181 .Append()
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
198 c = code.Code() 217 c = code.Code()
199 for prop in props: 218 for prop in props:
200 if prop.type_ == PropertyType.OBJECT: 219 if prop.type_ == PropertyType.OBJECT:
201 c.Concat(self._GenerateType(prop)) 220 c.Concat(self._GenerateType(prop))
202 c.Append() 221 c.Append()
203 elif prop.type_ == PropertyType.CHOICES: 222 elif prop.type_ == PropertyType.CHOICES:
204 c.Concat(self._GenerateEnumDeclaration( 223 c.Concat(self._GenerateEnumDeclaration(
205 self._cpp_type_generator.GetChoicesEnumType(prop), 224 self._cpp_type_generator.GetChoicesEnumType(prop),
206 prop, 225 prop,
207 [choice.type_.name for choice in prop.choices.values()])) 226 [choice.type_.name for choice in prop.choices.values()]))
227 c.Concat(self._GeneratePropertyStructures(prop.choices.values()))
208 elif prop.type_ == PropertyType.ENUM: 228 elif prop.type_ == PropertyType.ENUM:
209 enum_name = self._cpp_type_generator.GetType(prop) 229 enum_name = self._cpp_type_generator.GetType(prop)
210 c.Concat(self._GenerateEnumDeclaration( 230 c.Concat(self._GenerateEnumDeclaration(
211 enum_name, 231 enum_name,
212 prop, 232 prop,
213 prop.enum_values)) 233 prop.enum_values))
214 c.Append('static scoped_ptr<Value> CreateEnumValue(%s %s);' % 234 c.Append('static scoped_ptr<Value> CreateEnumValue(%s %s);' %
215 (enum_name, prop.unix_name)) 235 (enum_name, prop.unix_name))
216 return c 236 return c
217 237
218 def _GenerateFunctionResult(self, function): 238 def _GenerateFunctionResult(self, function):
219 """Generates functions for passing a function's result back. 239 """Generates functions for passing a function's result back.
220 """ 240 """
221 c = code.Code() 241 c = code.Code()
222 242
223 c.Sblock('namespace Result {') 243 c.Sblock('namespace Result {')
224 params = function.callback.params 244 params = function.callback.params
225 if not params: 245 if not params:
226 c.Append('Value* Create();') 246 c.Append('Value* Create();')
227 else: 247 else:
228 c.Concat(self._GeneratePropertyStructures(params)) 248 c.Concat(self._GeneratePropertyStructures(params))
229 249
230 # If there is a single parameter, this is straightforward. However, if 250 # If there is a single parameter, this is straightforward. However, if
231 # the callback parameter is of 'choices', this generates a Create method 251 # the callback parameter is of 'choices', this generates a Create method
232 # for each choice. This works because only 1 choice can be returned at a 252 # for each choice. This works because only 1 choice can be returned at a
233 # time. 253 # time.
234 for param in self._cpp_type_generator.GetExpandedChoicesInParams(params): 254 for param in self._cpp_type_generator.GetExpandedChoicesInParams(params):
235 if param.description: 255 if param.description:
236 c.Comment(param.description) 256 c.Comment(param.description)
257 if param.type_ == PropertyType.ANY:
258 c.Comment("Value* Result::Create(Value*) not generated "
259 "because it's redundant.")
260 continue
237 c.Append('Value* Create(const %s);' % cpp_util.GetParameterDeclaration( 261 c.Append('Value* Create(const %s);' % cpp_util.GetParameterDeclaration(
238 param, self._cpp_type_generator.GetType(param))) 262 param, self._cpp_type_generator.GetType(param)))
239 c.Eblock('};') 263 c.Eblock('};')
240 264
241 return c 265 return c
242 266
243 def _GenerateIfndefName(self): 267 def _GenerateIfndefName(self):
244 """Formats a path and filename as a #define name. 268 """Formats a path and filename as a #define name.
245 269
246 e.g chrome/extensions/gen, file.h becomes CHROME_EXTENSIONS_GEN_FILE_H__. 270 e.g chrome/extensions/gen, file.h becomes CHROME_EXTENSIONS_GEN_FILE_H__.
247 """ 271 """
248 return (('%s_%s_H__' % 272 return (('%s_%s_H__' %
249 (self._namespace.source_file_dir, self._target_namespace)) 273 (self._namespace.source_file_dir, self._target_namespace))
250 .upper().replace(os.sep, '_')) 274 .upper().replace(os.sep, '_'))
251 275
OLDNEW
« no previous file with comments | « tools/json_schema_compiler/cpp_util.py ('k') | tools/json_schema_compiler/model.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698