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

Side by Side Diff: third_party/chrome/ppapi/generators/idl_generator.py

Issue 12300042: Update idlsync.py to pull in dependencies required for chrome api generation. (Closed) Base URL: git://github.com/dart-lang/bleeding_edge.git@master
Patch Set: From another checkout Created 7 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
(Empty)
1 #!/usr/bin/env python
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file.
5
6 import sys
7
8 from idl_log import ErrOut, InfoOut, WarnOut
9 from idl_option import GetOption, Option, ParseOptions
10 from idl_parser import ParseFiles
11
12 GeneratorList = []
13
14 Option('out', 'List of output files', default='')
15 Option('release', 'Which release to generate.', default='')
16 Option('range', 'Which ranges in the form of MIN,MAX.', default='start,end')
17
18 class Generator(object):
19 """Base class for generators.
20
21 This class provides a mechanism for adding new generator objects to the IDL
22 driver. To use this class override the GenerateRelease and GenerateRange
23 members, and instantiate one copy of the class in the same module which
24 defines it to register the generator. After the AST is generated, call the
25 static Run member which will check every registered generator to see which
26 ones have been enabled through command-line options. To enable a generator
27 use the switches:
28 --<sname> : To enable with defaults
29 --<sname>_opt=<XXX,YYY=y> : To enable with generator specific options.
30
31 NOTE: Generators still have access to global options
32 """
33
34 def __init__(self, name, sname, desc):
35 self.name = name
36 self.run_switch = Option(sname, desc)
37 self.opt_switch = Option(sname + '_opt', 'Options for %s.' % sname,
38 default='')
39 GeneratorList.append(self)
40 self.errors = 0
41 self.skip_list = []
42
43 def Error(self, msg):
44 ErrOut.Log('Error %s : %s' % (self.name, msg))
45 self.errors += 1
46
47 def GetRunOptions(self):
48 options = {}
49 option_list = self.opt_switch.Get()
50 if option_list:
51 option_list = option_list.split(',')
52 for opt in option_list:
53 offs = opt.find('=')
54 if offs > 0:
55 options[opt[:offs]] = opt[offs+1:]
56 else:
57 options[opt] = True
58 return options
59 if self.run_switch.Get():
60 return options
61 return None
62
63 def Generate(self, ast, options):
64 self.errors = 0
65
66 rangestr = GetOption('range')
67 releasestr = GetOption('release')
68
69 print "Found releases: %s" % ast.releases
70
71 # Generate list of files to ignore due to errors
72 for filenode in ast.GetListOf('File'):
73 # If this file has errors, skip it
74 if filenode.GetProperty('ERRORS') > 0:
75 self.skip_list.append(filenode)
76 continue
77
78 # Check for a range option which over-rides a release option
79 if not releasestr and rangestr:
80 range_list = rangestr.split(',')
81 if len(range_list) != 2:
82 self.Error('Failed to generate for %s, incorrect range: "%s"' %
83 (self.name, rangestr))
84 else:
85 vmin = range_list[0]
86 vmax = range_list[1]
87
88 # Generate 'start' and 'end' represent first and last found.
89 if vmin == 'start':
90 vmin = ast.releases[0]
91 if vmax == 'end':
92 vmax = ast.releases[-1]
93
94 vmin = ast.releases.index(vmin)
95 vmax = ast.releases.index(vmax) + 1
96 releases = ast.releases[vmin:vmax]
97 InfoOut.Log('Generate range %s of %s.' % (rangestr, self.name))
98 ret = self.GenerateRange(ast, releases, options)
99 if ret < 0:
100 self.Error('Failed to generate range %s : %s.' %(vmin, vmax))
101 else:
102 InfoOut.Log('%s wrote %d files.' % (self.name, ret))
103 # Otherwise this should be a single release generation
104 else:
105 if releasestr == 'start':
106 releasestr = ast.releases[0]
107 if releasestr == 'end':
108 releasestr = ast.releases[-1]
109
110 if releasestr > ast.releases[-1]:
111 InfoOut.Log('There is no unique release for %s, using last release.' %
112 releasestr)
113 releasestr = ast.releases[-1]
114
115 if releasestr not in ast.releases:
116 self.Error('Release %s not in [%s].' %
117 (releasestr, ', '.join(ast.releases)))
118
119 if releasestr:
120 InfoOut.Log('Generate release %s of %s.' % (releasestr, self.name))
121 ret = self.GenerateRelease(ast, releasestr, options)
122 if ret < 0:
123 self.Error('Failed to generate release %s.' % releasestr)
124 else:
125 InfoOut.Log('%s wrote %d files.' % (self.name, ret))
126
127 else:
128 self.Error('No range or release specified for %s.' % releasestr)
129 return self.errors
130
131 def GenerateRelease(self, ast, release, options):
132 __pychecker__ = 'unusednames=ast,release,options'
133 self.Error("Undefined release generator.")
134 return 0
135
136 def GenerateRange(self, ast, releases, options):
137 __pychecker__ = 'unusednames=ast,releases,options'
138 self.Error("Undefined range generator.")
139 return 0
140
141 @staticmethod
142 def Run(ast):
143 fail_count = 0
144
145 # Check all registered generators if they should run.
146 for gen in GeneratorList:
147 options = gen.GetRunOptions()
148 if options is not None:
149 if gen.Generate(ast, options):
150 fail_count += 1
151 return fail_count
152
153
154 class GeneratorByFile(Generator):
155 """A simplified generator that generates one output file per IDL source file.
156
157 A subclass of Generator for use of generators which have a one to one
158 mapping between IDL sources and output files.
159
160 Derived classes should define GenerateFile.
161 """
162
163 def GenerateFile(self, filenode, releases, options):
164 """Generates an output file from the IDL source.
165
166 Returns true if the generated file is different than the previously
167 generated file.
168 """
169 __pychecker__ = 'unusednames=filenode,releases,options'
170 self.Error("Undefined release generator.")
171 return 0
172
173 def GenerateRelease(self, ast, release, options):
174 return self.GenerateRange(ast, [release], options)
175
176 def GenerateRange(self, ast, releases, options):
177 # Get list of out files
178 outlist = GetOption('out')
179 if outlist: outlist = outlist.split(',')
180
181 skipList = []
182 cnt = 0
183 for filenode in ast.GetListOf('File'):
184 # Ignore files with errors
185 if filenode in self.skip_list:
186 continue
187
188 # Skip this file if not required
189 if outlist and filenode.GetName() not in outlist:
190 continue
191
192 # Create the output file and increment out count if there was a delta
193 if self.GenerateFile(filenode, releases, options):
194 cnt = cnt + 1
195
196 for filenode in skipList:
197 errcnt = filenode.GetProperty('ERRORS')
198 ErrOut.Log('%s : Skipped because of %d errors.' % (
199 filenode.GetName(), errcnt))
200
201 if skipList:
202 return -len(skipList)
203
204 if GetOption('diff'):
205 return -cnt
206 return cnt
207
208
209 check_release = 0
210 check_range = 0
211
212 class GeneratorReleaseTest(Generator):
213 def GenerateRelease(self, ast, release, options = {}):
214 __pychecker__ = 'unusednames=ast,release,options'
215 global check_release
216 check_map = {
217 'so_long': True,
218 'MyOpt': 'XYZ',
219 'goodbye': True
220 }
221 check_release = 1
222 for item in check_map:
223 check_item = check_map[item]
224 option_item = options.get(item, None)
225 if check_item != option_item:
226 print 'Option %s is %s, expecting %s' % (item, option_item, check_item)
227 check_release = 0
228
229 if release != 'M14':
230 check_release = 0
231 return check_release == 1
232
233 def GenerateRange(self, ast, releases, options):
234 __pychecker__ = 'unusednames=ast,releases,options'
235 global check_range
236 check_range = 1
237 return True
238
239 def Test():
240 __pychecker__ = 'unusednames=args'
241 global check_release
242 global check_range
243
244 ParseOptions(['--testgen_opt=so_long,MyOpt=XYZ,goodbye'])
245 if Generator.Run('AST') != 0:
246 print 'Generate release: Failed.\n'
247 return -1
248
249 if check_release != 1 or check_range != 0:
250 print 'Gererate release: Failed to run.\n'
251 return -1
252
253 check_release = 0
254 ParseOptions(['--testgen_opt="HELLO"', '--range=M14,M16'])
255 if Generator.Run('AST') != 0:
256 print 'Generate range: Failed.\n'
257 return -1
258
259 if check_release != 0 or check_range != 1:
260 print 'Gererate range: Failed to run.\n'
261 return -1
262
263 print 'Generator test: Pass'
264 return 0
265
266
267 def Main(args):
268 if not args: return Test()
269 filenames = ParseOptions(args)
270 ast = ParseFiles(filenames)
271
272 return Generator.Run(ast)
273
274
275 if __name__ == '__main__':
276 GeneratorReleaseTest('Test Gen', 'testgen', 'Generator Class Test.')
277 sys.exit(Main(sys.argv[1:]))
OLDNEW
« no previous file with comments | « third_party/chrome/ppapi/generators/idl_gen_wrapper.py ('k') | third_party/chrome/ppapi/generators/idl_lexer.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698