<commit_before>package main

import (
	"bytes"
	"flag"
	"fmt"
	"go/build"
	"html/template"
	"log"
	"path"

	cautiouspancake "github.com/tam7t/cautious-pancake"

	"golang.org/x/tools/go/loader"
	"golang.org/x/tools/go/ssa"
)

func main() {
	flag.Parse()

	conf := loader.Config{Build: &build.Default}

	// Use the initial packages from the command line.
	_, err := conf.FromArgs(flag.Args(), false)
	if err != nil {
		log.Fatal(err)
	}

	// Load, parse and type-check the whole program.
	iprog, err := conf.Load()
	if err != nil {
		log.Fatal(err)
	}

	cg := cautiouspancake.NewCallGraph(iprog)
	err = cg.Analyze()
	if err != nil {
		log.Fatal(err)
	}

	for _, v := range cg.Pure() {
		if v.Object() != nil && v.Object().Exported() {
			fmt.Println("--")
			fmt.Println(PrintFuzz(v))
		}
	}
}

const fuzzTemp = `package main

import (
	"fmt"

	"github.com/google/gofuzz"
	"{{.Package.Pkg.Path}}"
)

func main() { {{ $length := len .Params }}{{if gt $length 0}}
	f := fuzz.New(){{end}}
{{range $i, $v := .Params}}	var p{{$i}} {{$v.Type.String | strippkg}}
{{end}}
	defer func() {
		if r := recover(); r != nil {
			fmt.Println("found panic", r){{range $i, $v := .Params}}
			fmt.Printf("p{{$i}}: %v\n", p{{$i}}){{end}}
		}
	}()
	for { {{range $i, $v := .Params}}
		f.Fuzz(&p{{$i}}){{end}}
		{{.Package.Pkg.Name}}.{{.Name}}({{range $i, $v := .Params}}{{if $i}}, {{end}}p{{$i}}{{end}})
	}
}`

func PrintFuzz(f *ssa.Function) string {
	var out bytes.Buffer
	tmpl := template.Must(template.New("").Funcs(template.FuncMap{"strippkg": func(a interface{}) string {
		return path.Base(a.(string))
	}}).Parse(fuzzTemp))
	tmpl.Execute(&out, f)
	return out.String()
}<commit_msg>pancakeid: more strongly typed way to print parameter types<commit_after>package main

import (
	"bytes"
	"flag"
	"fmt"
	"go/build"
	"go/types"
	"html/template"
	"log"

	cautiouspancake "github.com/tam7t/cautious-pancake"

	"golang.org/x/tools/go/loader"
	"golang.org/x/tools/go/ssa"
)

func main() {
	flag.Parse()

	conf := loader.Config{Build: &build.Default}

	// Use the initial packages from the command line.
	_, err := conf.FromArgs(flag.Args(), false)
	if err != nil {
		log.Fatal(err)
	}

	// Load, parse and type-check the whole program.
	iprog, err := conf.Load()
	if err != nil {
		log.Fatal(err)
	}

	cg := cautiouspancake.NewCallGraph(iprog)
	err = cg.Analyze()
	if err != nil {
		log.Fatal(err)
	}

	for _, v := range cg.Pure() {
		if v.Object() != nil && v.Object().Exported() {
			fmt.Println("--")
			fmt.Println(PrintFuzz(v))
		}
	}
}

const fuzzTemp = `package main

import (
	"fmt"

	"github.com/google/gofuzz"
	"{{.Package.Pkg.Path}}"
)

func main() { {{ $length := len .Params }}{{if gt $length 0}}
	f := fuzz.New(){{end}}
{{range $i, $v := .Params}}	var p{{$i}} {{$v.Type | strippkg}}
{{end}}
	defer func() {
		if r := recover(); r != nil {
			fmt.Println("found panic", r){{range $i, $v := .Params}}
			fmt.Printf("p{{$i}}: %v\n", p{{$i}}){{end}}
		}
	}()
	for { {{range $i, $v := .Params}}
		f.Fuzz(&p{{$i}}){{end}}
		{{.Package.Pkg.Name}}.{{.Name}}({{range $i, $v := .Params}}{{if $i}}, {{end}}p{{$i}}{{end}})
	}
}`

func PrintFuzz(f *ssa.Function) string {
	var out bytes.Buffer
	tmpl := template.Must(template.New("").Funcs(template.FuncMap{"strippkg": func(a interface{}) string {
		return types.TypeString(a.(types.Type), func(p *types.Package) string {
			return p.Name()
		})
	}}).Parse(fuzzTemp))
	tmpl.Execute(&out, f)
	return out.String()
}
{'fraction_non_alphanumeric': 0.23067983730389308, 'fraction_numerical': 0.0011621150493898896, 'mean_word_length': 3.6779891304347827, 'pattern_counts': {'":': 2, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6573016', 'n_tokens_mistral': 1511, 'n_tokens_neox': 1438, 'n_words': 297}