<commit_before>package sexpconv

import (
	"go/ast"
	"go/constant"
	"go/token"
	"go/types"
	"sexp"
	"tu/symbols"
	"xast"
	"xtypes"
)

type Converter struct {
	ftab *symbols.FuncTable
	env  *symbols.Env
}

func (conv *Converter) FuncTable() *symbols.FuncTable {
	return conv.ftab
}

func (conv *Converter) Env() *symbols.Env {
	return conv.env
}

type converter struct {
	info    *types.Info
	fileSet *token.FileSet
	env     *symbols.Env
	ftab    *symbols.FuncTable

	// Context type is used to resolve "untyped" constants.
	ctxType types.Type
	// Type that should be used for ctxType inside "return" statements.
	retType *types.Tuple
}

func NewConverter(ftab *symbols.FuncTable, env *symbols.Env) *Converter {
	return &Converter{env: env, ftab: ftab}
}

func (conv *Converter) newConverter(p *xast.Package) converter {
	return converter{
		env:     conv.env,
		info:    p.Info,
		fileSet: p.FileSet,
		ftab:    conv.ftab,
	}
}

func (conv *Converter) VarInit(assign *xast.Assign) sexp.Form {
	c := conv.newConverter(assign.Pkg)
	return c.VarInit(assign.Lhs, assign.Rhs)
}

func (conv *Converter) FuncBody(fn *xast.Func) *sexp.Block {
	c := conv.newConverter(fn.Pkg)
	c.retType = fn.Ret
	body := c.BlockStmt(fn.Body)

	// Adding return statement.
	// It is needed in void functions without explicit "return".
	if fn.Ret == xtypes.EmptyTuple {
		body.Forms = append(body.Forms, &sexp.Return{})
	}

	return body
}

func (conv *Converter) VarZeroInit(sym string, typ types.Type) sexp.Form {
	return &sexp.VarUpdate{Name: sym, Expr: ZeroValue(typ)}
}

func (conv *converter) FuncBody(name *ast.Ident, block *ast.BlockStmt) *sexp.Block {
	conv.retType = conv.typeOf(name).(*types.Signature).Results()
	body := conv.BlockStmt(block)
	// Adding return statement.
	// It is needed in void functions without explicit "return".
	// In all other cases, optimizations will wipe it out.
	body.Forms = append(body.Forms, &sexp.Return{})
	return body
}

func (conv *converter) VarInit(lhs []*ast.Ident, rhs ast.Expr) sexp.Form {
	return conv.genAssign(xast.ExprSlice(lhs), []ast.Expr{rhs})
}

func (conv *converter) VarZeroInit(sym string, typ types.Type) sexp.Form {
	return &sexp.VarUpdate{Name: sym, Expr: ZeroValue(typ)}
}

func (conv *converter) valueOf(node ast.Expr) constant.Value {
	return conv.info.Types[node].Value
}

func (conv *converter) typeOf(node ast.Expr) types.Type {
	return conv.info.TypeOf(node)<commit_msg>remove duplicative method (Converter already have this one)<commit_after>package sexpconv

import (
	"go/ast"
	"go/constant"
	"go/token"
	"go/types"
	"sexp"
	"tu/symbols"
	"xast"
	"xtypes"
)

type Converter struct {
	ftab *symbols.FuncTable
	env  *symbols.Env
}

func (conv *Converter) FuncTable() *symbols.FuncTable {
	return conv.ftab
}

func (conv *Converter) Env() *symbols.Env {
	return conv.env
}

type converter struct {
	info    *types.Info
	fileSet *token.FileSet
	env     *symbols.Env
	ftab    *symbols.FuncTable

	// Context type is used to resolve "untyped" constants.
	ctxType types.Type
	// Type that should be used for ctxType inside "return" statements.
	retType *types.Tuple
}

func NewConverter(ftab *symbols.FuncTable, env *symbols.Env) *Converter {
	return &Converter{env: env, ftab: ftab}
}

func (conv *Converter) newConverter(p *xast.Package) converter {
	return converter{
		env:     conv.env,
		info:    p.Info,
		fileSet: p.FileSet,
		ftab:    conv.ftab,
	}
}

func (conv *Converter) VarInit(assign *xast.Assign) sexp.Form {
	c := conv.newConverter(assign.Pkg)
	return c.VarInit(assign.Lhs, assign.Rhs)
}

func (conv *Converter) FuncBody(fn *xast.Func) *sexp.Block {
	c := conv.newConverter(fn.Pkg)
	c.retType = fn.Ret
	body := c.BlockStmt(fn.Body)

	// Adding return statement.
	// It is needed in void functions without explicit "return".
	if fn.Ret == xtypes.EmptyTuple {
		body.Forms = append(body.Forms, &sexp.Return{})
	}

	return body
}

func (conv *Converter) VarZeroInit(sym string, typ types.Type) sexp.Form {
	return &sexp.VarUpdate{Name: sym, Expr: ZeroValue(typ)}
}

func (conv *converter) FuncBody(name *ast.Ident, block *ast.BlockStmt) *sexp.Block {
	conv.retType = conv.typeOf(name).(*types.Signature).Results()
	body := conv.BlockStmt(block)
	// Adding return statement.
	// It is needed in void functions without explicit "return".
	// In all other cases, optimizations will wipe it out.
	body.Forms = append(body.Forms, &sexp.Return{})
	return body
}

func (conv *converter) VarInit(lhs []*ast.Ident, rhs ast.Expr) sexp.Form {
	return conv.genAssign(xast.ExprSlice(lhs), []ast.Expr{rhs})
}

func (conv *converter) valueOf(node ast.Expr) constant.Value {
	return conv.info.Types[node].Value
}

func (conv *converter) typeOf(node ast.Expr) types.Type {
	return conv.info.TypeOf(node)
{'fraction_non_alphanumeric': 0.13562539548618435, 'fraction_numerical': 0.0, 'mean_word_length': 4.16557734204793, 'pattern_counts': {'":': 0, '<': 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': '2194084', 'n_tokens_mistral': 1760, 'n_tokens_neox': 1734, 'n_words': 445}