<commit_before>package main

import (
	"fmt"
	"go/ast"
	goparser "go/parser"
	"strings"
)

type funcType struct {
	name       string
	defPrefix  string
	callPrefix string
	argNames   string
	args       string
}

func parseFuncDef(b []byte) (*funcType, error) {
	defStr := string(b)

	// extract func name
	n := strings.Index(defStr, "(")
	if n < 0 {
		return nil, fmt.Errorf("cannot find '(' in function definition")
	}
	name := defStr[:n]
	defStr = defStr[n+1:]
	defPrefix := ""
	callPrefix := ""
	if len(name) == 0 {
		// Either empty func name or valid method definition. Let's check.

		// parse method receiver
		n = strings.Index(defStr, ")")
		if n < 0 {
			return nil, fmt.Errorf("cannot find ')' in func")
		}
		recvStr := defStr[:n]
		defStr = defStr[n+1:]
		exprStr := fmt.Sprintf("func (%s)", recvStr)
		expr, err := goparser.ParseExpr(exprStr)
		if err != nil {
			return nil, fmt.Errorf("invalid method definition: %s", err)
		}
		ft := expr.(*ast.FuncType)
		if len(ft.Params.List) != 1 || len(ft.Params.List[0].Names) != 1 {
			// method reciever must contain only one param
			return nil, fmt.Errorf("missing func or method name")
		}
		recvName := ft.Params.List[0].Names[0].Name
		if isReservedArgName(recvName) {
			return nil, fmt.Errorf("arg name %q is reserved. Use another name")
		}
		defPrefix = fmt.Sprintf("(%s) ", recvStr)
		callPrefix = recvName + "."

		// extract method name
		n = strings.Index(defStr, "(")
		if n < 0 {
			return nil, fmt.Errorf("missing func name")
		}
		name = string(stripLeadingSpace([]byte(defStr[:n])))
		if len(name) == 0 {
			return nil, fmt.Errorf("missing method name")
		}
		defStr = defStr[n+1:]
	}

	// validate and collect func args
	if len(defStr) == 0 || defStr[len(defStr)-1] != ')' {
		return nil, fmt.Errorf("missing ')' at the end of func")
	}
	args := defStr[:len(defStr)-1]
	exprStr := fmt.Sprintf("func (%s)", args)
	expr, err := goparser.ParseExpr(exprStr)
	if err != nil {
		return nil, fmt.Errorf("invalid func args: %s", err)
	}
	ft := expr.(*ast.FuncType)
	if ft.Results != nil {
		return nil, fmt.Errorf("func mustn't return any results")
	}

	// extract arg names
	var tmp []string
	for _, f := range ft.Params.List {
		if len(f.Names) == 0 {
			return nil, fmt.Errorf("func cannot contain untyped arguments")
		}
		for _, n := range f.Names {
			if n == nil {
				return nil, fmt.Errorf("func cannot contain untyped arguments")
			}
			if isReservedArgName(n.Name) {
				return nil, fmt.Errorf("arg name %q is reserved. Use other name")
			}
			tmp = append(tmp, n.Name)
		}
	}
	argNames := strings.Join(tmp, ", ")

	if len(args) > 0 {
		args = ", " + args
	}
	if len(argNames) > 0 {
		argNames = ", " + argNames
	}
	return &funcType{
		name:       name,
		defPrefix:  defPrefix,
		callPrefix: callPrefix,
		argNames:   argNames,
		args:       args,
	}, nil
}

func parseFuncCall(b []byte) (*funcType, error) {
	exprStr := string(b)<commit_msg>typo fixes<commit_after>package main

import (
	"fmt"
	"go/ast"
	goparser "go/parser"
	"strings"
)

type funcType struct {
	name       string
	defPrefix  string
	callPrefix string
	argNames   string
	args       string
}

func parseFuncDef(b []byte) (*funcType, error) {
	defStr := string(b)

	// extract func name
	n := strings.Index(defStr, "(")
	if n < 0 {
		return nil, fmt.Errorf("cannot find '(' in function definition")
	}
	name := defStr[:n]
	defStr = defStr[n+1:]
	defPrefix := ""
	callPrefix := ""
	if len(name) == 0 {
		// Either empty func name or valid method definition. Let's check.

		// parse method receiver
		n = strings.Index(defStr, ")")
		if n < 0 {
			return nil, fmt.Errorf("cannot find ')' in func")
		}
		recvStr := defStr[:n]
		defStr = defStr[n+1:]
		exprStr := fmt.Sprintf("func (%s)", recvStr)
		expr, err := goparser.ParseExpr(exprStr)
		if err != nil {
			return nil, fmt.Errorf("invalid method definition: %s", err)
		}
		ft := expr.(*ast.FuncType)
		if len(ft.Params.List) != 1 || len(ft.Params.List[0].Names) != 1 {
			// method reciever must contain only one param
			return nil, fmt.Errorf("missing func or method name")
		}
		recvName := ft.Params.List[0].Names[0].Name
		if isReservedArgName(recvName) {
			return nil, fmt.Errorf("arg name %q is reserved. Use another name", recvName)
		}
		defPrefix = fmt.Sprintf("(%s) ", recvStr)
		callPrefix = recvName + "."

		// extract method name
		n = strings.Index(defStr, "(")
		if n < 0 {
			return nil, fmt.Errorf("missing func name")
		}
		name = string(stripLeadingSpace([]byte(defStr[:n])))
		if len(name) == 0 {
			return nil, fmt.Errorf("missing method name")
		}
		defStr = defStr[n+1:]
	}

	// validate and collect func args
	if len(defStr) == 0 || defStr[len(defStr)-1] != ')' {
		return nil, fmt.Errorf("missing ')' at the end of func")
	}
	args := defStr[:len(defStr)-1]
	exprStr := fmt.Sprintf("func (%s)", args)
	expr, err := goparser.ParseExpr(exprStr)
	if err != nil {
		return nil, fmt.Errorf("invalid func args: %s", err)
	}
	ft := expr.(*ast.FuncType)
	if ft.Results != nil {
		return nil, fmt.Errorf("func mustn't return any results")
	}

	// extract arg names
	var tmp []string
	for _, f := range ft.Params.List {
		if len(f.Names) == 0 {
			return nil, fmt.Errorf("func cannot contain untyped arguments")
		}
		for _, n := range f.Names {
			if n == nil {
				return nil, fmt.Errorf("func cannot contain untyped arguments")
			}
			if isReservedArgName(n.Name) {
				return nil, fmt.Errorf("arg name %q is reserved. Use other name", n.Name)
			}
			tmp = append(tmp, n.Name)
		}
	}
	argNames := strings.Join(tmp, ", ")

	if len(args) > 0 {
		args = ", " + args
	}
	if len(argNames) > 0 {
		argNames = ", " + argNames
	}
	return &funcType{
		name:       name,
		defPrefix:  defPrefix,
		callPrefix: callPrefix,
		argNames:   argNames,
		args:       args,
	}, nil
}

func parseFuncCall(b []byte) (*funcType, error) {
	exprStr := string(b)
{'fraction_non_alphanumeric': 0.15868416567240498, 'fraction_numerical': 0.006476904721322652, 'mean_word_length': 3.24295010845987, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 7, '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': '2681598', 'n_tokens_mistral': 2318, 'n_tokens_neox': 2111, 'n_words': 588}