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

Side by Side Diff: headless/lib/browser/devtools_api/client_api_generator.py

Issue 2902583002: Add some closureised JS bindings for DevTools for use by headless embedder (Closed)
Patch Set: Make the JS better Created 3 years, 6 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 2016 The Chromium Authors. All rights reserved. 1 # Copyright 2016 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 import argparse 5 import argparse
6 import collections 6 import collections
7 import os.path 7 import os.path
8 import re 8 import re
9 import sys 9 import sys
10 try: 10 try:
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
113 if not '.' in json['$ref']: 113 if not '.' in json['$ref']:
114 json['$ref'] = domain_name + '.' + json['$ref'] 114 json['$ref'] = domain_name + '.' + json['$ref']
115 115
116 for domain in json_api['domains']: 116 for domain in json_api['domains']:
117 PatchFullQualifiedRefsInDomain(domain, domain['domain']) 117 PatchFullQualifiedRefsInDomain(domain, domain['domain'])
118 118
119 119
120 def CreateUserTypeDefinition(domain, type): 120 def CreateUserTypeDefinition(domain, type):
121 namespace = CamelCaseToHackerStyle(domain['domain']) 121 namespace = CamelCaseToHackerStyle(domain['domain'])
122 return { 122 return {
123 'js_type': '!chromium.DevTools.%s.%s' % (domain['domain'], type['id']),
123 'return_type': 'std::unique_ptr<headless::%s::%s>' % ( 124 'return_type': 'std::unique_ptr<headless::%s::%s>' % (
124 namespace, type['id']), 125 namespace, type['id']),
125 'pass_type': 'std::unique_ptr<headless::%s::%s>' % ( 126 'pass_type': 'std::unique_ptr<headless::%s::%s>' % (
126 namespace, type['id']), 127 namespace, type['id']),
127 'to_raw_type': '*%s', 128 'to_raw_type': '*%s',
128 'to_raw_return_type': '%s.get()', 129 'to_raw_return_type': '%s.get()',
129 'to_pass_type': 'std::move(%s)', 130 'to_pass_type': 'std::move(%s)',
130 'type': 'std::unique_ptr<headless::%s::%s>' % (namespace, type['id']), 131 'type': 'std::unique_ptr<headless::%s::%s>' % (namespace, type['id']),
131 'raw_type': 'headless::%s::%s' % (namespace, type['id']), 132 'raw_type': 'headless::%s::%s' % (namespace, type['id']),
132 'raw_pass_type': 'headless::%s::%s*' % (namespace, type['id']), 133 'raw_pass_type': 'headless::%s::%s*' % (namespace, type['id']),
133 'raw_return_type': 'const headless::%s::%s*' % (namespace, type['id']), 134 'raw_return_type': 'const headless::%s::%s*' % (namespace, type['id']),
134 } 135 }
135 136
136 137
137 def CreateEnumTypeDefinition(domain_name, type): 138 def CreateEnumTypeDefinition(domain_name, type):
138 namespace = CamelCaseToHackerStyle(domain_name) 139 namespace = CamelCaseToHackerStyle(domain_name)
139 return { 140 return {
141 'js_type': '!chromium.DevTools.%s.%s' % (domain_name, type['id']),
140 'return_type': 'headless::%s::%s' % (namespace, type['id']), 142 'return_type': 'headless::%s::%s' % (namespace, type['id']),
141 'pass_type': 'headless::%s::%s' % (namespace, type['id']), 143 'pass_type': 'headless::%s::%s' % (namespace, type['id']),
142 'to_raw_type': '%s', 144 'to_raw_type': '%s',
143 'to_raw_return_type': '%s', 145 'to_raw_return_type': '%s',
144 'to_pass_type': '%s', 146 'to_pass_type': '%s',
145 'type': 'headless::%s::%s' % (namespace, type['id']), 147 'type': 'headless::%s::%s' % (namespace, type['id']),
146 'raw_type': 'headless::%s::%s' % (namespace, type['id']), 148 'raw_type': 'headless::%s::%s' % (namespace, type['id']),
147 'raw_pass_type': 'headless::%s::%s' % (namespace, type['id']), 149 'raw_pass_type': 'headless::%s::%s' % (namespace, type['id']),
148 'raw_return_type': 'headless::%s::%s' % (namespace, type['id']), 150 'raw_return_type': 'headless::%s::%s' % (namespace, type['id']),
149 } 151 }
150 152
151 153
152 def CreateObjectTypeDefinition(): 154 def CreateObjectTypeDefinition():
153 return { 155 return {
156 'js_type': 'Object',
154 'return_type': 'std::unique_ptr<base::DictionaryValue>', 157 'return_type': 'std::unique_ptr<base::DictionaryValue>',
155 'pass_type': 'std::unique_ptr<base::DictionaryValue>', 158 'pass_type': 'std::unique_ptr<base::DictionaryValue>',
156 'to_raw_type': '*%s', 159 'to_raw_type': '*%s',
157 'to_raw_return_type': '%s.get()', 160 'to_raw_return_type': '%s.get()',
158 'to_pass_type': 'std::move(%s)', 161 'to_pass_type': 'std::move(%s)',
159 'type': 'std::unique_ptr<base::DictionaryValue>', 162 'type': 'std::unique_ptr<base::DictionaryValue>',
160 'raw_type': 'base::DictionaryValue', 163 'raw_type': 'base::DictionaryValue',
161 'raw_pass_type': 'base::DictionaryValue*', 164 'raw_pass_type': 'base::DictionaryValue*',
162 'raw_return_type': 'const base::DictionaryValue*', 165 'raw_return_type': 'const base::DictionaryValue*',
163 } 166 }
164 167
165 168
166 def WrapObjectTypeDefinition(type): 169 def WrapObjectTypeDefinition(type):
167 id = type.get('id', 'base::Value') 170 id = type.get('id', 'base::Value')
168 return { 171 return {
172 'js_type': '!Object',
169 'return_type': 'std::unique_ptr<%s>' % id, 173 'return_type': 'std::unique_ptr<%s>' % id,
170 'pass_type': 'std::unique_ptr<%s>' % id, 174 'pass_type': 'std::unique_ptr<%s>' % id,
171 'to_raw_type': '*%s', 175 'to_raw_type': '*%s',
172 'to_raw_return_type': '%s.get()', 176 'to_raw_return_type': '%s.get()',
173 'to_pass_type': 'std::move(%s)', 177 'to_pass_type': 'std::move(%s)',
174 'type': 'std::unique_ptr<%s>' % id, 178 'type': 'std::unique_ptr<%s>' % id,
175 'raw_type': id, 179 'raw_type': id,
176 'raw_pass_type': '%s*' % id, 180 'raw_pass_type': '%s*' % id,
177 'raw_return_type': 'const %s*' % id, 181 'raw_return_type': 'const %s*' % id,
178 } 182 }
179 183
180 184
181 def CreateAnyTypeDefinition(): 185 def CreateAnyTypeDefinition():
182 return { 186 return {
187 'js_type': '*',
183 'return_type': 'std::unique_ptr<base::Value>', 188 'return_type': 'std::unique_ptr<base::Value>',
184 'pass_type': 'std::unique_ptr<base::Value>', 189 'pass_type': 'std::unique_ptr<base::Value>',
185 'to_raw_type': '*%s', 190 'to_raw_type': '*%s',
186 'to_raw_return_type': '%s.get()', 191 'to_raw_return_type': '%s.get()',
187 'to_pass_type': 'std::move(%s)', 192 'to_pass_type': 'std::move(%s)',
188 'type': 'std::unique_ptr<base::Value>', 193 'type': 'std::unique_ptr<base::Value>',
189 'raw_type': 'base::Value', 194 'raw_type': 'base::Value',
190 'raw_pass_type': 'base::Value*', 195 'raw_pass_type': 'base::Value*',
191 'raw_return_type': 'const base::Value*', 196 'raw_return_type': 'const base::Value*',
192 } 197 }
193 198
194 199
195 def CreateStringTypeDefinition(): 200 def CreateStringTypeDefinition():
196 return { 201 return {
202 'js_type': 'string',
197 'return_type': 'std::string', 203 'return_type': 'std::string',
198 'pass_type': 'const std::string&', 204 'pass_type': 'const std::string&',
199 'to_pass_type': '%s', 205 'to_pass_type': '%s',
200 'to_raw_type': '%s', 206 'to_raw_type': '%s',
201 'to_raw_return_type': '%s', 207 'to_raw_return_type': '%s',
202 'type': 'std::string', 208 'type': 'std::string',
203 'raw_type': 'std::string', 209 'raw_type': 'std::string',
204 'raw_pass_type': 'const std::string&', 210 'raw_pass_type': 'const std::string&',
205 'raw_return_type': 'std::string', 211 'raw_return_type': 'std::string',
206 } 212 }
207 213
208 214
209 def CreatePrimitiveTypeDefinition(type): 215 def CreatePrimitiveTypeDefinition(type):
210 typedefs = { 216 typedefs = {
211 'number': 'double', 217 'number': 'double',
212 'integer': 'int', 218 'integer': 'int',
213 'boolean': 'bool', 219 'boolean': 'bool',
214 } 220 }
221 js_typedefs = {
222 'number': 'number',
223 'integer': 'number',
224 'boolean': 'boolean',
225 }
215 return { 226 return {
227 'js_type': js_typedefs[type],
216 'return_type': typedefs[type], 228 'return_type': typedefs[type],
217 'pass_type': typedefs[type], 229 'pass_type': typedefs[type],
218 'to_pass_type': '%s', 230 'to_pass_type': '%s',
219 'to_raw_type': '%s', 231 'to_raw_type': '%s',
220 'to_raw_return_type': '%s', 232 'to_raw_return_type': '%s',
221 'type': typedefs[type], 233 'type': typedefs[type],
222 'raw_type': typedefs[type], 234 'raw_type': typedefs[type],
223 'raw_pass_type': typedefs[type], 235 'raw_pass_type': typedefs[type],
224 'raw_return_type': typedefs[type], 236 'raw_return_type': typedefs[type],
225 } 237 }
226 238
227 239
228 type_definitions = {} 240 type_definitions = {}
229 type_definitions['number'] = CreatePrimitiveTypeDefinition('number') 241 type_definitions['number'] = CreatePrimitiveTypeDefinition('number')
230 type_definitions['integer'] = CreatePrimitiveTypeDefinition('integer') 242 type_definitions['integer'] = CreatePrimitiveTypeDefinition('integer')
231 type_definitions['boolean'] = CreatePrimitiveTypeDefinition('boolean') 243 type_definitions['boolean'] = CreatePrimitiveTypeDefinition('boolean')
232 type_definitions['string'] = CreateStringTypeDefinition() 244 type_definitions['string'] = CreateStringTypeDefinition()
233 type_definitions['object'] = CreateObjectTypeDefinition() 245 type_definitions['object'] = CreateObjectTypeDefinition()
234 type_definitions['any'] = CreateAnyTypeDefinition() 246 type_definitions['any'] = CreateAnyTypeDefinition()
235 247
236 248
237 def WrapArrayDefinition(type): 249 def WrapArrayDefinition(type):
238 return { 250 return {
251 'js_type': '!Array.<%s>' % type['js_type'],
239 'return_type': 'std::vector<%s>' % type['type'], 252 'return_type': 'std::vector<%s>' % type['type'],
240 'pass_type': 'std::vector<%s>' % type['type'], 253 'pass_type': 'std::vector<%s>' % type['type'],
241 'to_raw_type': '%s', 254 'to_raw_type': '%s',
242 'to_raw_return_type': '&%s', 255 'to_raw_return_type': '&%s',
243 'to_pass_type': 'std::move(%s)', 256 'to_pass_type': 'std::move(%s)',
244 'type': 'std::vector<%s>' % type['type'], 257 'type': 'std::vector<%s>' % type['type'],
245 'raw_type': 'std::vector<%s>' % type['type'], 258 'raw_type': 'std::vector<%s>' % type['type'],
246 'raw_pass_type': 'std::vector<%s>*' % type['type'], 259 'raw_pass_type': 'std::vector<%s>*' % type['type'],
247 'raw_return_type': 'const std::vector<%s>*' % type['type'], 260 'raw_return_type': 'const std::vector<%s>*' % type['type'],
248 } 261 }
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
370 'properties': event.get('parameters', []) 383 'properties': event.get('parameters', [])
371 } 384 }
372 domain['types'].append(event_type) 385 domain['types'].append(event_type)
373 386
374 387
375 def InitializeDomainDependencies(json_api): 388 def InitializeDomainDependencies(json_api):
376 """For each domain create list of domains given domain depends on, 389 """For each domain create list of domains given domain depends on,
377 including itself.""" 390 including itself."""
378 391
379 direct_deps = collections.defaultdict(set) 392 direct_deps = collections.defaultdict(set)
393 types_required = collections.defaultdict(set)
380 394
381 def GetDomainDepsFromRefs(domain_name, json): 395 def GetDomainDepsFromRefs(domain_name, json):
382 if isinstance(json, list): 396 if isinstance(json, list):
383 for value in json: 397 for value in json:
384 GetDomainDepsFromRefs(domain_name, value) 398 GetDomainDepsFromRefs(domain_name, value)
385 return 399 return
386 400
387 if not isinstance(json, dict): 401 if not isinstance(json, dict):
388 return 402 return
389 for value in json.itervalues(): 403 for value in json.itervalues():
390 GetDomainDepsFromRefs(domain_name, value) 404 GetDomainDepsFromRefs(domain_name, value)
391 405
392 if '$ref' in json: 406 if '$ref' in json:
393 if '.' in json['$ref']: 407 if '.' in json['$ref']:
394 dep = json['$ref'].split('.')[0] 408 dep = json['$ref'].split('.')[0]
395 direct_deps[domain_name].add(dep) 409 direct_deps[domain_name].add(dep)
410 types_required[domain_name].add(json['$ref'])
396 411
397 for domain in json_api['domains']: 412 for domain in json_api['domains']:
398 direct_deps[domain['domain']] = set(domain.get('dependencies', [])) 413 direct_deps[domain['domain']] = set(domain.get('dependencies', []))
414 types_required[domain['domain']] = set(domain.get('types_required', []))
399 GetDomainDepsFromRefs(domain['domain'], domain) 415 GetDomainDepsFromRefs(domain['domain'], domain)
400 416
401 def TraverseDependencies(domain, deps): 417 def TraverseDependencies(domain, deps):
402 if domain in deps: 418 if domain in deps:
403 return 419 return
404 deps.add(domain) 420 deps.add(domain)
405 421
406 for dep in direct_deps[domain]: 422 for dep in direct_deps[domain]:
407 TraverseDependencies(dep, deps) 423 TraverseDependencies(dep, deps)
408 424
409 for domain in json_api['domains']: 425 for domain in json_api['domains']:
410 domain_deps = set() 426 domain_deps = set()
411 TraverseDependencies(domain['domain'], domain_deps) 427 TraverseDependencies(domain['domain'], domain_deps)
428 if 'dependencies' in domain:
429 domain['js_dependencies'] = domain['dependencies']
430 else:
431 domain['js_dependencies'] = []
432
433 domain['js_forward_declarations'] = []
434 for type in types_required[domain['domain']]:
435 if not type.split('.')[0] in domain['js_dependencies']:
436 domain['js_forward_declarations'].append(type)
412 domain['dependencies'] = sorted(domain_deps) 437 domain['dependencies'] = sorted(domain_deps)
413 438
414 439
415 def PatchExperimentalCommandsAndEvents(json_api): 440 def PatchExperimentalCommandsAndEvents(json_api):
416 """Mark all commands and events in experimental domains as experimental 441 """Mark all commands and events in experimental domains as experimental
417 and make sure experimental commands have at least empty parameters 442 and make sure experimental commands have at least empty parameters
418 and return values. 443 and return values.
419 """ 444 """
420 for domain in json_api['domains']: 445 for domain in json_api['domains']:
421 if domain.get('experimental', False): 446 if domain.get('experimental', False):
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
463 file_type) 488 file_type)
464 with open(output_file, 'w') as f: 489 with open(output_file, 'w') as f:
465 f.write(template.render(template_context)) 490 f.write(template.render(template_context))
466 491
467 492
468 def GenerateDomains(jinja_env, output_dirname, json_api): 493 def GenerateDomains(jinja_env, output_dirname, json_api):
469 GeneratePerDomain( 494 GeneratePerDomain(
470 jinja_env, os.path.join(output_dirname, 'devtools', 'domains'), json_api, 495 jinja_env, os.path.join(output_dirname, 'devtools', 'domains'), json_api,
471 'domain', ['cc', 'h'], 496 'domain', ['cc', 'h'],
472 lambda domain_name: domain_name) 497 lambda domain_name: domain_name)
498 GeneratePerDomain(
499 jinja_env, os.path.join(output_dirname, 'devtools_js'), json_api,
500 'domain', ['js'],
501 lambda domain_name: domain_name)
473 502
474 503
475 def GenerateTypes(jinja_env, output_dirname, json_api): 504 def GenerateTypes(jinja_env, output_dirname, json_api):
476 # Generate forward declarations for types. 505 # Generate forward declarations for types.
477 GeneratePerDomain( 506 GeneratePerDomain(
478 jinja_env, os.path.join(output_dirname, 'devtools', 'internal'), 507 jinja_env, os.path.join(output_dirname, 'devtools', 'internal'),
479 json_api, 'domain_types_forward_declarations', ['h'], 508 json_api, 'domain_types_forward_declarations', ['h'],
480 lambda domain_name: 'types_forward_declarations_%s' % (domain_name, )) 509 lambda domain_name: 'types_forward_declarations_%s' % (domain_name, ))
481 # Generate types on per-domain basis. 510 # Generate types on per-domain basis.
482 GeneratePerDomain( 511 GeneratePerDomain(
(...skipping 16 matching lines...) Expand all
499 InitializeDomainDependencies(json_api) 528 InitializeDomainDependencies(json_api)
500 PatchExperimentalCommandsAndEvents(json_api) 529 PatchExperimentalCommandsAndEvents(json_api)
501 EnsureCommandsHaveParametersAndReturnTypes(json_api) 530 EnsureCommandsHaveParametersAndReturnTypes(json_api)
502 SynthesizeCommandTypes(json_api) 531 SynthesizeCommandTypes(json_api)
503 SynthesizeEventTypes(json_api) 532 SynthesizeEventTypes(json_api)
504 PatchFullQualifiedRefs(json_api) 533 PatchFullQualifiedRefs(json_api)
505 CreateTypeDefinitions(json_api) 534 CreateTypeDefinitions(json_api)
506 GenerateDomains(jinja_env, output_dirname, json_api) 535 GenerateDomains(jinja_env, output_dirname, json_api)
507 GenerateTypes(jinja_env, output_dirname, json_api) 536 GenerateTypes(jinja_env, output_dirname, json_api)
508 GenerateTypeConversions(jinja_env, output_dirname, json_api) 537 GenerateTypeConversions(jinja_env, output_dirname, json_api)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698