func()

in tools/go-agent/instrument/plugins/enhance_method.go [143:217]


func (m *MethodEnhance) BuildForDelegator() []dst.Decl {
	result := make([]dst.Decl, 0)

	result = append(result, tools.GoStringToDecls(fmt.Sprintf(`var %s = &%s{}`, m.InterceptorVarName, m.InterceptorGeneratedName))...)
	result = append(result, tools.GoStringToDecls(fmt.Sprintf(`var %s_interTimeCost int64`, m.FuncID))...)
	result = append(result, tools.GoStringToDecls(fmt.Sprintf(`var %s_beforeInterStart int64`, m.FuncID))...)
	preFunc := &dst.FuncDecl{
		Name: &dst.Ident{Name: m.AdapterPreFuncName},
		Type: &dst.FuncType{
			Params:  &dst.FieldList{},
			Results: &dst.FieldList{},
		},
	}
	for i, recv := range m.Recvs {
		preFunc.Type.Params.List = append(preFunc.Type.Params.List, &dst.Field{
			Names: []*dst.Ident{dst.NewIdent(fmt.Sprintf("recv_%d", i))},
			Type:  &dst.StarExpr{X: recv.PackagedType()},
		})
	}
	for i, parameter := range m.Parameters {
		preFunc.Type.Params.List = append(preFunc.Type.Params.List, &dst.Field{
			Names: []*dst.Ident{dst.NewIdent(fmt.Sprintf("param_%d", i))},
			Type:  &dst.StarExpr{X: m.changeTypeIfNeeds(parameter.PackagedType())},
		})
	}
	for i, result := range m.Results {
		preFunc.Type.Results.List = append(preFunc.Type.Results.List, &dst.Field{
			Names: []*dst.Ident{dst.NewIdent(fmt.Sprintf("ret_%d", i))},
			Type:  result.PackagedType(),
		})
	}
	preFunc.Type.Results.List = append(preFunc.Type.Results.List, &dst.Field{
		Names: []*dst.Ident{dst.NewIdent("invocation")},
		Type:  &dst.StarExpr{X: &dst.SelectorExpr{X: dst.NewIdent("operator"), Sel: dst.NewIdent("realInvocation")}},
	}, &dst.Field{
		Names: []*dst.Ident{dst.NewIdent("skip")},
		Type:  dst.NewIdent("bool"),
	})

	beforeFile, err := templatesFS.ReadFile("templates/method_intercept_before.tmpl")
	if err != nil {
		panic(fmt.Errorf("reading method before intercept template failure: %w", err))
	}
	preFunc.Body = &dst.BlockStmt{
		List: tools.GoStringToStats(tools.ExecuteTemplate(string(beforeFile), m)),
	}
	result = append(result, preFunc)

	postFunc := &dst.FuncDecl{
		Name: &dst.Ident{Name: m.AdapterPostFuncName},
		Type: &dst.FuncType{
			Params:  &dst.FieldList{},
			Results: &dst.FieldList{},
		},
	}
	postFunc.Type.Params.List = append(postFunc.Type.Params.List, &dst.Field{
		Names: []*dst.Ident{dst.NewIdent("invocation")},
		Type:  &dst.StarExpr{X: &dst.SelectorExpr{X: dst.NewIdent("operator"), Sel: dst.NewIdent("realInvocation")}},
	})
	for inx, f := range m.Results {
		postFunc.Type.Params.List = append(postFunc.Type.Params.List, &dst.Field{
			Names: []*dst.Ident{dst.NewIdent(fmt.Sprintf("ret_%d", inx))},
			Type:  &dst.StarExpr{X: f.PackagedType()},
		})
	}
	afterFile, err := templatesFS.ReadFile("templates/method_intercept_after.tmpl")
	if err != nil {
		panic(fmt.Errorf("reading method after intercept template failure: %w", err))
	}
	postFunc.Body = &dst.BlockStmt{
		List: tools.GoStringToStats(tools.ExecuteTemplate(string(afterFile), m)),
	}
	result = append(result, postFunc)
	return result
}