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

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

Issue 1015033003: [Extension API Extern Generation] Auto-generate enums (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Tests! Created 5 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
OLDNEW
1 # Copyright 2015 The Chromium Authors. All rights reserved. 1 # Copyright 2015 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 Generator that produces an externs file for the Closure Compiler. 5 Generator that produces an externs file for the Closure Compiler.
6 Note: This is a work in progress, and generated externs may require tweaking. 6 Note: This is a work in progress, and generated externs may require tweaking.
7 7
8 See https://developers.google.com/closure/compiler/docs/api-tutorial3#externs 8 See https://developers.google.com/closure/compiler/docs/api-tutorial3#externs
9 """ 9 """
10 10
(...skipping 20 matching lines...) Expand all
31 def Generate(self): 31 def Generate(self):
32 """Generates a Code object with the schema for the entire namespace. 32 """Generates a Code object with the schema for the entire namespace.
33 """ 33 """
34 c = Code() 34 c = Code()
35 (c.Append(LICENSE) 35 (c.Append(LICENSE)
36 .Append() 36 .Append()
37 .Append('/** @fileoverview Externs generated from namespace: %s */' % 37 .Append('/** @fileoverview Externs generated from namespace: %s */' %
38 self._namespace.name) 38 self._namespace.name)
39 .Append()) 39 .Append())
40 40
41 c.Cblock(self._GenerateNamespaceObject())
42
41 for js_type in self._namespace.types.values(): 43 for js_type in self._namespace.types.values():
42 c.Cblock(self._GenerateType(js_type)) 44 c.Cblock(self._GenerateType(js_type))
43 45
44 c.Cblock(self._GenerateNamespaceObject())
45
46 for function in self._namespace.functions.values(): 46 for function in self._namespace.functions.values():
47 c.Cblock(self._GenerateFunction(function)) 47 c.Cblock(self._GenerateFunction(function))
48 48
49 for event in self._namespace.events.values(): 49 for event in self._namespace.events.values():
50 c.Cblock(self._GenerateEvent(event)) 50 c.Cblock(self._GenerateEvent(event))
51 51
52 return c 52 return c
53 53
54 def _GenerateType(self, js_type): 54 def _GenerateType(self, js_type):
55 """Given a Type object, returns the Code for this type's definition. 55 """Given a Type object, returns the Code for this type's definition.
56
57 """ 56 """
58 c = Code() 57 c = Code()
59
60 # Since enums are just treated as strings for now, don't generate their
61 # type.
62 if js_type.property_type is PropertyType.ENUM: 58 if js_type.property_type is PropertyType.ENUM:
63 return c 59 c.Concat(self._GenerateEnumJsDoc(js_type))
64 60 else:
65 c.Concat(self._GenerateTypeJsDoc(js_type)) 61 c.Concat(self._GenerateTypeJsDoc(js_type))
66
67 var = 'var ' + js_type.simple_name
68 if self._IsTypeConstructor(js_type): var += ' = function()'
69 var += ';'
70 c.Append(var)
71 62
72 return c 63 return c
73 64
65 def _GenerateEnumJsDoc(self, js_type):
66 """ Given an Enum Type object, returns the Code for the enum's definition.
67 """
68 c = Code()
69 c.Append('/**').Append(' * @enum {string}').Append(' */')
70 c.Append('chrome.%s.%s = {' % (self._namespace.name, js_type.name))
71 value_lines = []
72 for value in [v.name for v in js_type.enum_values]:
73 value_lines.append(" %s: '%s'," % (value, value))
Tyler Breisacher (Chromium) 2015/03/24 20:07:52 It seems a bit strange to have a list comp and the
Devlin 2015/03/24 20:31:55 Done.
74 # Remove last trailing comma.
75 # TODO(devlin): This will be unneeded, if when
Tyler Breisacher (Chromium) 2015/03/24 20:07:52 Actually I think you can drop line 77 now, because
Devlin 2015/03/24 20:31:55 Done.
76 # https://github.com/google/closure-compiler/issues/796 is fixed.
77 value_lines[-1] = value_lines[-1][:-1]
78 c.Append('\n'.join(value_lines))
79 c.Append('};')
80 return c
81
74 def _IsTypeConstructor(self, js_type): 82 def _IsTypeConstructor(self, js_type):
75 """Returns true if the given type should be a @constructor. If this returns 83 """Returns true if the given type should be a @constructor. If this returns
76 false, the type is a typedef. 84 false, the type is a typedef.
77 """ 85 """
78 return any(prop.type_.property_type is PropertyType.FUNCTION 86 return any(prop.type_.property_type is PropertyType.FUNCTION
79 for prop in js_type.properties.values()) 87 for prop in js_type.properties.values())
80 88
81 def _GenerateTypeJsDoc(self, js_type): 89 def _GenerateTypeJsDoc(self, js_type):
82 """Generates the documentation for a type as a Code. 90 """Generates the documentation for a type as a Code.
83 91
84 Returns an empty code object if the object has no documentation. 92 Returns an empty code object if the object has no documentation.
85 """ 93 """
86 c = Code() 94 c = Code()
87 c.Append('/**') 95 c.Append('/**')
88 96
89 if js_type.description: 97 if js_type.description:
90 for line in js_type.description.splitlines(): 98 for line in js_type.description.splitlines():
91 c.Comment(line, comment_prefix = ' * ') 99 c.Comment(line, comment_prefix = ' * ')
92 100
93 if self._IsTypeConstructor(js_type): 101 is_constructor = self._IsTypeConstructor(js_type)
102 if is_constructor:
94 c.Comment('@constructor', comment_prefix = ' * ') 103 c.Comment('@constructor', comment_prefix = ' * ')
95 else: 104 else:
96 c.Concat(self._GenerateTypedef(js_type.properties)) 105 c.Concat(self._GenerateTypedef(js_type.properties))
97 106
98 c.Append(' */') 107 c.Append(' */')
108
109 var = 'var ' + js_type.simple_name
110 if is_constructor: var += ' = function()'
Tyler Breisacher (Chromium) 2015/03/24 20:07:52 I think you need the body too: if is_constructor:
Devlin 2015/03/24 20:31:55 I would have thought so, too, but figured maybe th
111 var += ';'
112 c.Append(var)
113
99 return c 114 return c
100 115
101 def _GenerateTypedef(self, properties): 116 def _GenerateTypedef(self, properties):
102 """Given an OrderedDict of properties, returns a Code containing a @typedef. 117 """Given an OrderedDict of properties, returns a Code containing a @typedef.
103 """ 118 """
104 if not properties: return Code() 119 if not properties: return Code()
105 120
106 lines = [] 121 lines = []
107 lines.append('@typedef {{') 122 lines.append('@typedef {{')
108 for field, prop in properties.items(): 123 for field, prop in properties.items():
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
166 181
167 def _TypeToJsType(self, js_type): 182 def _TypeToJsType(self, js_type):
168 """Converts a model.Type to a JS type (number, Array, etc.)""" 183 """Converts a model.Type to a JS type (number, Array, etc.)"""
169 if js_type.property_type in (PropertyType.INTEGER, PropertyType.DOUBLE): 184 if js_type.property_type in (PropertyType.INTEGER, PropertyType.DOUBLE):
170 return 'number' 185 return 'number'
171 elif js_type.property_type is PropertyType.OBJECT: 186 elif js_type.property_type is PropertyType.OBJECT:
172 return 'Object' 187 return 'Object'
173 elif js_type.property_type is PropertyType.ARRAY: 188 elif js_type.property_type is PropertyType.ARRAY:
174 return 'Array' 189 return 'Array'
175 elif js_type.property_type is PropertyType.REF: 190 elif js_type.property_type is PropertyType.REF:
176 return js_type.ref_type 191 ref_type = js_type.ref_type
192 # Enums are defined as chrome.fooAPI.MyEnum, but types are defined simply
193 # as MyType.
194 if self._namespace.types[ref_type].property_type is PropertyType.ENUM:
195 ref_type = 'chrome.%s.%s' % (self._namespace.name, ref_type)
196 return ref_type
177 elif js_type.property_type.is_fundamental: 197 elif js_type.property_type.is_fundamental:
178 return js_type.property_type.name 198 return js_type.property_type.name
179 else: 199 else:
180 return '?' # TODO(tbreisacher): Make this more specific. 200 return '?' # TODO(tbreisacher): Make this more specific.
181 201
182 def _GenerateFunction(self, function): 202 def _GenerateFunction(self, function):
183 """Generates the code representing a function, including its documentation. 203 """Generates the code representing a function, including its documentation.
184 For example: 204 For example:
185 205
186 /** 206 /**
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
223 * @const 243 * @const
224 */""") 244 */""")
225 .Append('chrome.%s = {};' % self._namespace.name)) 245 .Append('chrome.%s = {};' % self._namespace.name))
226 return c 246 return c
227 247
228 def _GenerateFunctionParams(self, function): 248 def _GenerateFunctionParams(self, function):
229 params = function.params[:] 249 params = function.params[:]
230 if function.callback: 250 if function.callback:
231 params.append(function.callback) 251 params.append(function.callback)
232 return ', '.join(param.name for param in params) 252 return ', '.join(param.name for param in params)
OLDNEW
« no previous file with comments | « tools/json_schema_compiler/idl_schema.py ('k') | tools/json_schema_compiler/js_externs_generator_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698