analyzeFunc analyzes a given function declaration and emit generated triggers, or an error if something went wrong during the analysis. It is mainly a wrapper function for assertiontree.BackpropAcrossFunc with synchronization and communication support for concurrency. The actual result will be sent
( ctx context.Context, pass *analysishelper.EnhancedPass, funcDecl *ast.FuncDecl, funcContext assertiontree.FunctionContext, graph *cfg.CFG, index int, funcChan chan functionResult, )
| 436 | // assertiontree.BackpropAcrossFunc with synchronization and communication support for concurrency. |
| 437 | // The actual result will be sent via the channel. |
| 438 | func analyzeFunc( |
| 439 | ctx context.Context, |
| 440 | pass *analysishelper.EnhancedPass, |
| 441 | funcDecl *ast.FuncDecl, |
| 442 | funcContext assertiontree.FunctionContext, |
| 443 | graph *cfg.CFG, |
| 444 | index int, |
| 445 | funcChan chan functionResult, |
| 446 | ) { |
| 447 | // As a last resort, convert the panics into errors and return. |
| 448 | defer func() { |
| 449 | if r := recover(); r != nil { |
| 450 | e := fmt.Errorf("INTERNAL PANIC: %s\n%s", r, string(debug.Stack())) |
| 451 | funcChan <- functionResult{err: e, index: index, funcDecl: funcDecl} |
| 452 | } |
| 453 | }() |
| 454 | |
| 455 | // Do the actual backpropagation. |
| 456 | funcTriggers, _, _, err := assertiontree.BackpropAcrossFunc(ctx, pass, funcDecl, funcContext, graph) |
| 457 | |
| 458 | // If any error occurs in back-propagating the function, we wrap the error with more information. |
| 459 | if err != nil { |
| 460 | pos := pass.Fset.Position(funcDecl.Pos()) |
| 461 | err = fmt.Errorf("analyzing function %s at %s:%d.%d: %w", funcDecl.Name, pos.Filename, pos.Line, pos.Column, err) |
| 462 | } |
| 463 | |
| 464 | funcChan <- functionResult{ |
| 465 | triggers: funcTriggers, |
| 466 | err: err, |
| 467 | index: index, |
| 468 | funcDecl: funcDecl, |
| 469 | } |
| 470 | } |