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

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

Issue 15677003: Generate externs automatically from json/idl files. Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: . Created 7 years, 7 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/create_externs.sh ('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
(Empty)
1 # Copyright (c) 2013 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 Generator that produces an externs file for the Closure Compiler.
6
7 See https://developers.google.com/closure/compiler/docs/api-tutorial3#externs
8 """
9
10 from code import Code
11 from model import *
12 from schema_util import *
13
14 import os
15 from datetime import datetime
16
17 LICENSE = (
18 """// TODO(tbreisacher): Add a real license header. This TODO is (C) %s""" %
19 datetime.now().year)
20
21 class JsExternsGenerator(object):
22 def __init__(self):
23 pass
24
25 def Generate(self, namespace):
26 return _Generator(namespace).Generate()
27
28 class _Generator(object):
29 def __init__(self, namespace):
30 self._namespace = namespace
31
32 def Generate(self):
33 """Generates a Code object with the .dart for the entire namespace.
34 """
35 c = Code()
36 (c.Append(LICENSE)
37 .Append()
38 .Append('/** @fileoverview Externs generated from namespace: %s */' %
39 self._namespace.name)
40 .Append())
41
42 for type_ in self._namespace.types.values():
43 c.Cblock(self._GenerateType(type_))
44
45 for function in self._namespace.functions.values():
46 c.Cblock(self._GenerateFunction(function))
47
48 return c
49
50 def _GenerateType(self, type_):
51 """Given a Type object, returns the Code for this type's definition.
52
53 """
54 c = Code()
55
56 # Since enums are just treated as strings for now, don't generate their
57 # type.
58 if type_.property_type is PropertyType.ENUM:
59 return c
60
61 c.Concat(self._GenerateTypeJsDoc(type_))
62
63 if self._IsTypeConstructor(type_):
64 c.Append(type_.simple_name + ' = function();')
65 else:
66 c.Append(type_.simple_name + ';')
67
68 return c
69
70 def _IsTypeConstructor(self, type_):
71 """Returns true if the given type should be a @constructor. If this returns
72 false, the type is a typedef.
73 """
74 return any(prop.type_.property_type is PropertyType.FUNCTION
75 for prop in type_.properties.values())
76
77 def _GenerateTypeJsDoc(self, type_):
78 """Generates the documentation for a type as a Code.
79
80 Returns an empty code object if the object has no documentation.
81 """
82 c = Code()
83 c.Append('/**')
84
85 if type_.description:
86 for line in type_.description.split('\n'):
87 c.Comment(line, comment_prefix=' * ')
88
89 if self._IsTypeConstructor(type_):
90 c.Comment('@constructor', comment_prefix = ' * ')
91 else:
92 c.Concat(self._GenerateTypedef(type_.properties))
93
94 c.Append(' */')
95 return c
96
97 def _GenerateTypedef(self, properties):
98 """Given an OrderedDict of properties, returns a Code containing a @typedef.
99 """
100 if not properties: return Code()
101
102 lines = []
103 lines.append('@typedef {{')
104 for field, property_ in properties.items():
105 js_type = self._TypeToJsType(property_.type_)
106 if property_.optional:
107 js_type = '(%s|undefined)' % js_type
108 lines.append(' %s: %s,' % (field, js_type))
109
110 lines.append('}}')
111 # TODO(tbreisacher): Add '@see <link to documentation>'.
112
113 lines = [' * ' + line for line in lines]
114 codeString = '\n'.join(lines)
115 c = Code()
116 c.Append(codeString)
117 return c
118
119 def _GenerateFunctionJsDoc(self, function):
120 """Generates the documentation for a function as a Code.
121
122 Returns an empty code object if the object has no documentation.
123 """
124 c = Code()
125 c.Append('/**')
126
127 if function.description:
128 for line in function.description.split('\n'):
129 c.Comment(line, comment_prefix=' * ')
130
131 for param in function.params:
132 js_type = self._TypeToJsType(param.type_)
133
134 if param.optional:
135 js_type += '='
136
137 param_doc = '@param {%s} %s %s' % (js_type,
138 param.name,
139 param.description or '')
140 c.Comment(param_doc, comment_prefix=' * ')
141
142 if function.callback:
143 # TODO(tbreisacher): Convert Function to function() for better
144 # typechecking.
145 js_type = 'Function'
146 if function.callback.optional:
147 js_type += '='
148 param_doc = '@param {%s} %s %s' % (js_type,
149 function.callback.name,
150 function.callback.description or '')
151 c.Comment(param_doc, comment_prefix=' * ')
152
153 if function.returns:
154 return_doc = '@return {%s} %s' % (self._TypeToJsType(function.returns),
155 function.returns.description)
156 c.Comment(return_doc, comment_prefix=' * ')
157
158 c.Append(' */')
159 return c
160
161 def _TypeToJsType(self, type_):
162 """Converts a model.Type to a JS type (number, Array, etc.)"""
163 if type_.property_type in (PropertyType.INTEGER, PropertyType.DOUBLE):
164 return 'number'
165 elif type_.property_type is PropertyType.OBJECT:
166 return 'Object'
167 elif type_.property_type is PropertyType.ARRAY:
168 return 'Array'
169 elif type_.property_type is PropertyType.REF:
170 return type_.ref_type
171 elif type_.property_type.is_fundamental:
172 return type_.property_type.name
173 else:
174 return '?' # TODO make this more specific
175
176 def _GenerateFunction(self, function):
177 """Generates the code representing a function, including its documentation.
178 For example:
179
180 /**
181 * @param {string} title The new title.
182 */
183 chrome.window.setTitle = function(title) {};
184 """
185 c = Code()
186 params = self._GenerateFunctionParams(function)
187 (c.Concat(self._GenerateFunctionJsDoc(function))
188 .Append('chrome.%s.%s = function(%s) {};' % (self._namespace.name,
189 function.name,
190 params))
191 )
192 return c
193
194 def _GenerateFunctionParams(self, function):
195 params = function.params[:]
196 if function.callback:
197 params.append(function.callback)
198 return ', '.join(param.name for param in params)
OLDNEW
« no previous file with comments | « tools/json_schema_compiler/create_externs.sh ('k') | tools/json_schema_compiler/model.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698