<commit_before>package schemabuilder

import (
	"context"
	"fmt"
	"reflect"

	"github.com/samsarahq/thunder/graphql"
)

// buildFunction takes the reflect type of an object and a method attached to
// that object to build a GraphQL Field that can be resolved in the GraphQL
// graph.
func (sb *schemaBuilder) buildFunction(typ reflect.Type, m *method) (*graphql.Field, error) {
	funcCtx := &funcContext{typ: typ}

	if typ.Kind() == reflect.Ptr {
		return nil, fmt.Errorf("source-type of buildFunction cannot be a pointer (got: %v)", typ)
	}

	fun, err := funcCtx.getFuncVal(m)
	if err != nil {
		return nil, err
	}

	in := funcCtx.getFuncInputTypes()
	in = funcCtx.consumeContextAndSource(in)

	argParser, argType, in, err := funcCtx.getArgParserAndTyp(sb, in)
	if err != nil {
		return nil, err
	}
	funcCtx.hasArgs = argParser != nil

	in = funcCtx.consumeSelectionSet(in)

	// We have succeeded if no arguments remain.
	if len(in) != 0 {
		return nil, fmt.Errorf("%s arguments should be [context][, [*]%s][, args][, selectionSet]", funcCtx.funcType, typ)
	}

	// Parse return values. The first return value must be the actual value, and
	// the second value can optionally be an error.
	err = funcCtx.parseReturnSignature(m)
	if err != nil {
		return nil, err
	}

	retType, err := funcCtx.getReturnType(sb, m)
	if err != nil {
		return nil, err
	}

	args, err := funcCtx.argsTypeMap(argType)
	if err != nil {
		return nil, err
	}

	return &graphql.Field{
		Resolve: func(ctx context.Context, source, args interface{}, selectionSet *graphql.SelectionSet) (interface{}, error) {
			// Set up function arguments.

			in := funcCtx.prepareResolveArgs(source, args, ctx)
			// Call the function.
			out := fun.Call(in)

			return funcCtx.extractResultAndErr(out, retType)

		},
		Args:           args,
		Type:           retType,
		ParseArguments: argParser.Parse,
		Expensive:      funcCtx.hasContext,
	}, nil
}

// funcContext is used to parse the function signature in buildFunction.
type funcContext struct {
	hasContext      bool
	hasSource       bool<commit_msg>go schemabuilder/function: Clean up ambiguous variable names<commit_after>package schemabuilder

import (
	"context"
	"fmt"
	"reflect"

	"github.com/samsarahq/thunder/graphql"
)

// buildFunction takes the reflect type of an object and a method attached to
// that object to build a GraphQL Field that can be resolved in the GraphQL
// graph.
func (sb *schemaBuilder) buildFunction(typ reflect.Type, m *method) (*graphql.Field, error) {
	funcCtx := &funcContext{typ: typ}

	if typ.Kind() == reflect.Ptr {
		return nil, fmt.Errorf("source-type of buildFunction cannot be a pointer (got: %v)", typ)
	}

	callableFunc, err := funcCtx.getFuncVal(m)
	if err != nil {
		return nil, err
	}

	in := funcCtx.getFuncInputTypes()
	in = funcCtx.consumeContextAndSource(in)

	argParser, argType, in, err := funcCtx.getArgParserAndTyp(sb, in)
	if err != nil {
		return nil, err
	}
	funcCtx.hasArgs = argParser != nil

	in = funcCtx.consumeSelectionSet(in)

	// We have succeeded if no arguments remain.
	if len(in) != 0 {
		return nil, fmt.Errorf("%s arguments should be [context][, [*]%s][, args][, selectionSet]", funcCtx.funcType, typ)
	}

	// Parse return values. The first return value must be the actual value, and
	// the second value can optionally be an error.
	err = funcCtx.parseReturnSignature(m)
	if err != nil {
		return nil, err
	}

	retType, err := funcCtx.getReturnType(sb, m)
	if err != nil {
		return nil, err
	}

	args, err := funcCtx.argsTypeMap(argType)
	if err != nil {
		return nil, err
	}

	return &graphql.Field{
		Resolve: func(ctx context.Context, source, funcRawArgs interface{}, selectionSet *graphql.SelectionSet) (interface{}, error) {
			// Set up function arguments.
			funcInputArgs := funcCtx.prepareResolveArgs(source, funcRawArgs, ctx)

			// Call the function.
			funcOutputArgs := callableFunc.Call(funcInputArgs)

			return funcCtx.extractResultAndErr(funcOutputArgs, retType)

		},
		Args:           args,
		Type:           retType,
		ParseArguments: argParser.Parse,
		Expensive:      funcCtx.hasContext,
	}, nil
}

// funcContext is used to parse the function signature in buildFunction.
type funcContext struct {
	hasContext      bool
	hasSource       bool
{'fraction_non_alphanumeric': 0.11338508586215008, 'fraction_numerical': 0.0004704775346977182, 'mean_word_length': 3.693156732891832, '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': '6519168', 'n_tokens_mistral': 1440, 'n_tokens_neox': 1390, 'n_words': 439}