comparison CodeAnalysis/ParseOrthancSDK.py @ 2:df7b4f8a0437

coverage statistics
author Sebastien Jodogne <s.jodogne@gmail.com>
date Fri, 27 Mar 2020 07:59:20 +0100
parents 7ed502b17b8f
children b2bbb516056e
comparison
equal deleted inserted replaced
1:fef9a239df5c 2:df7b4f8a0437
92 92
93 93
94 classes = {} 94 classes = {}
95 enumerations = {} 95 enumerations = {}
96 globalFunctions = [] 96 globalFunctions = []
97 countAllFunctions = 0
98 countSupportedFunctions = 0
97 99
98 def IsSourceStringType(t): 100 def IsSourceStringType(t):
99 return (t.kind == clang.cindex.TypeKind.POINTER and 101 return (t.kind == clang.cindex.TypeKind.POINTER and
100 t.get_pointee().kind == clang.cindex.TypeKind.CHAR_S and 102 t.get_pointee().kind == clang.cindex.TypeKind.CHAR_S and
101 t.get_pointee().is_const_qualified()) 103 t.get_pointee().is_const_qualified())
347 args[0].type.get_pointee().spelling != 'OrthancPluginContext'): 349 args[0].type.get_pointee().spelling != 'OrthancPluginContext'):
348 print('Not in the Orthanc SDK: %s()' % node.spelling) 350 print('Not in the Orthanc SDK: %s()' % node.spelling)
349 continue 351 continue
350 352
351 # Discard the context from the arguments 353 # Discard the context from the arguments
354 countAllFunctions += 1
352 args = args[1:] 355 args = args[1:]
353 356
354 if not IsSupportedTargetType(node.result_type): 357 if not IsSupportedTargetType(node.result_type):
355 print('*** UNSUPPORTED OUTPUT: %s' % node.spelling) 358 print('*** UNSUPPORTED OUTPUT: %s' % node.spelling)
356 359
358 IsClassType(args[0].type) and 361 IsClassType(args[0].type) and
359 node.spelling.startswith('OrthancPluginFree')): 362 node.spelling.startswith('OrthancPluginFree')):
360 print('Destructor: %s' % node.spelling) 363 print('Destructor: %s' % node.spelling)
361 className = args[0].type.get_pointee().spelling 364 className = args[0].type.get_pointee().spelling
362 classes[className]['destructor'] = node.spelling 365 classes[className]['destructor'] = node.spelling
366 countSupportedFunctions += 1
363 367
364 elif CheckOnlySupportedArguments(args): 368 elif CheckOnlySupportedArguments(args):
365 if IsClassType(node.result_type): 369 if IsClassType(node.result_type):
366 print('Constructor: %s' % node.spelling) 370 print('Constructor: %s' % node.spelling)
367 else: 371 else:
368 print('Simple global function: %s => %s' % (node.spelling, node.result_type.spelling)) 372 print('Simple global function: %s => %s' % (node.spelling, node.result_type.spelling))
369 373
370 body = GenerateFunctionBodyTemplate(node.spelling, node.result_type, args) 374 body = GenerateFunctionBodyTemplate(node.spelling, node.result_type, args)
371 globalFunctions.append(body) 375 globalFunctions.append(body)
376 countSupportedFunctions += 1
372 377
373 elif (len(args) >= 2 and 378 elif (len(args) >= 2 and
374 IsTargetMemoryBufferType(args[0].type) and 379 IsTargetMemoryBufferType(args[0].type) and
375 CheckOnlySupportedArguments(args[1:])): 380 CheckOnlySupportedArguments(args[1:])):
376 print('Simple global function, returning bytes: %s' % node.spelling) 381 print('Simple global function, returning bytes: %s' % node.spelling)
377 382
378 body = GenerateFunctionBodyTemplate(node.spelling, args[0].type, args[1:]) 383 body = GenerateFunctionBodyTemplate(node.spelling, args[0].type, args[1:])
379 globalFunctions.append(body) 384 globalFunctions.append(body)
385 countSupportedFunctions += 1
380 386
381 elif (IsClassType(args[0].type) and 387 elif (IsClassType(args[0].type) and
382 CheckOnlySupportedArguments(args[1:])): 388 CheckOnlySupportedArguments(args[1:])):
383 className = args[0].type.get_pointee().spelling 389 className = args[0].type.get_pointee().spelling
384 390
388 print('Simple method of class %s: %s' % (className, node.spelling)) 394 print('Simple method of class %s: %s' % (className, node.spelling))
389 395
390 method = GenerateFunctionBodyTemplate(node.spelling, node.result_type, args[1:]) 396 method = GenerateFunctionBodyTemplate(node.spelling, node.result_type, args[1:])
391 method['self'] = ', self->object_' 397 method['self'] = ', self->object_'
392 classes[className]['methods'].append(method) 398 classes[className]['methods'].append(method)
399 countSupportedFunctions += 1
393 400
394 elif (len(args) >= 2 and 401 elif (len(args) >= 2 and
395 IsTargetMemoryBufferType(args[0].type) and 402 IsTargetMemoryBufferType(args[0].type) and
396 IsClassType(args[1].type) and 403 IsClassType(args[1].type) and
397 CheckOnlySupportedArguments(args[2:])): 404 CheckOnlySupportedArguments(args[2:])):
400 node.spelling)) 407 node.spelling))
401 408
402 method = GenerateFunctionBodyTemplate(node.spelling, args[0].type, args[2:]) 409 method = GenerateFunctionBodyTemplate(node.spelling, args[0].type, args[2:])
403 method['self'] = ', self->object_' 410 method['self'] = ', self->object_'
404 classes[className]['methods'].append(method) 411 classes[className]['methods'].append(method)
412 countSupportedFunctions += 1
405 413
406 else: 414 else:
407 print('*** UNSUPPORTED INPUT: %s' % node.spelling) 415 print('*** UNSUPPORTED INPUT: %s' % node.spelling)
408 416
409 417
464 with open(os.path.join(ROOT, 'sdk.h.mustache'), 'r') as f: 472 with open(os.path.join(ROOT, 'sdk.h.mustache'), 'r') as f:
465 with open(os.path.join(TARGET, 'sdk.h'), 'w') as h: 473 with open(os.path.join(TARGET, 'sdk.h'), 'w') as h:
466 h.write(renderer.render(f.read(), { 474 h.write(renderer.render(f.read(), {
467 'classes' : FlattenDictionary(classes), 475 'classes' : FlattenDictionary(classes),
468 })) 476 }))
477
478
479 print('')
480 print('Total functions in the SDK: %d' % countAllFunctions)
481 print('Total supported functions: %d' % countSupportedFunctions)
482 print('Coverage: %.0f%%' % (float(countSupportedFunctions) /
483 float(countAllFunctions) * 100.0))