in tool/instrument/trampoline.go [73:117]
func (rp *RuleProcessor) materializeTemplate() error {
// Read trampoline template and materialize onEnter and onExit function
// declarations based on that
p := util.NewAstParser()
astRoot, err := p.ParseSource(trampolineTemplate)
if err != nil {
return err
}
rp.varDecls = make([]dst.Decl, 0)
rp.callCtxMethods = make([]*dst.FuncDecl, 0)
for _, node := range astRoot.Decls {
// Materialize function declarations
if decl, ok := node.(*dst.FuncDecl); ok {
if decl.Name.Name == TrampolineOnEnterName {
rp.onEnterHookFunc = decl
rp.addDecl(decl)
} else if decl.Name.Name == TrampolineOnExitName {
rp.onExitHookFunc = decl
rp.addDecl(decl)
} else if util.HasReceiver(decl) {
// We know exactly this is CallContextImpl method
t := decl.Recv.List[0].Type.(*dst.StarExpr).X.(*dst.Ident).Name
util.Assert(t == TrampolineCallContextImplType, "sanity check")
rp.callCtxMethods = append(rp.callCtxMethods, decl)
rp.addDecl(decl)
}
}
// Materialize variable declarations
if decl, ok := node.(*dst.GenDecl); ok {
// No further processing for variable declarations, just append them
if decl.Tok == token.VAR {
rp.varDecls = append(rp.varDecls, decl)
} else if decl.Tok == token.TYPE {
rp.callCtxDecl = decl
rp.addDecl(decl)
}
}
}
util.Assert(rp.callCtxDecl != nil, "sanity check")
util.Assert(len(rp.varDecls) > 0, "sanity check")
util.Assert(rp.onEnterHookFunc != nil, "sanity check")
util.Assert(rp.onExitHookFunc != nil, "sanity check")
return nil
}