Skip to content

Commit

Permalink
Merge branch 'master' into lazy-invariant
Browse files Browse the repository at this point in the history
  • Loading branch information
chris-ramon authored Jan 7, 2018
2 parents b16d2fd + 77b1ae5 commit d951837
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 46 deletions.
54 changes: 38 additions & 16 deletions definition.go
Original file line number Diff line number Diff line change
Expand Up @@ -365,9 +365,11 @@ type Object struct {
PrivateDescription string `json:"description"`
IsTypeOf IsTypeOfFn

typeConfig ObjectConfig
fields FieldDefinitionMap
interfaces []*Interface
typeConfig ObjectConfig
initialisedFields bool
fields FieldDefinitionMap
initialisedInterfaces bool
interfaces []*Interface
// Interim alternative to throwing an error during schema definition at run-time
err error
}
Expand Down Expand Up @@ -429,6 +431,7 @@ func (gt *Object) AddFieldConfig(fieldName string, fieldConfig *Field) {
switch gt.typeConfig.Fields.(type) {
case Fields:
gt.typeConfig.Fields.(Fields)[fieldName] = fieldConfig
gt.initialisedFields = false
}
}
func (gt *Object) Name() string {
Expand All @@ -441,20 +444,30 @@ func (gt *Object) String() string {
return gt.PrivateName
}
func (gt *Object) Fields() FieldDefinitionMap {
if gt.initialisedFields {
return gt.fields
}

var configureFields Fields
switch gt.typeConfig.Fields.(type) {
case Fields:
configureFields = gt.typeConfig.Fields.(Fields)
case FieldsThunk:
configureFields = gt.typeConfig.Fields.(FieldsThunk)()
}

fields, err := defineFieldMap(gt, configureFields)
gt.err = err
gt.fields = fields
gt.initialisedFields = true
return gt.fields
}

func (gt *Object) Interfaces() []*Interface {
if gt.initialisedInterfaces {
return gt.interfaces
}

var configInterfaces []*Interface
switch gt.typeConfig.Interfaces.(type) {
case InterfacesThunk:
Expand All @@ -463,14 +476,18 @@ func (gt *Object) Interfaces() []*Interface {
configInterfaces = gt.typeConfig.Interfaces.([]*Interface)
case nil:
default:
gt.err = fmt.Errorf("Unknown Object.Interfaces type: %v", reflect.TypeOf(gt.typeConfig.Interfaces))
gt.err = fmt.Errorf("Unknown Object.Interfaces type: %T", gt.typeConfig.Interfaces)
gt.initialisedInterfaces = true
return nil
}

interfaces, err := defineInterfaces(gt, configInterfaces)
gt.err = err
gt.interfaces = interfaces
gt.initialisedInterfaces = true
return gt.interfaces
}

func (gt *Object) Error() error {
return gt.err
}
Expand Down Expand Up @@ -507,15 +524,7 @@ func defineInterfaces(ttype *Object, interfaces []*Interface) ([]*Interface, err
return ifaces, nil
}

func defineFieldMap(ttype Named, fields interface{}) (FieldDefinitionMap, error) {
var fieldMap Fields
switch fields.(type) {
case Fields:
fieldMap = fields.(Fields)
case FieldsThunk:
fieldMap = fields.(FieldsThunk)()
}

func defineFieldMap(ttype Named, fieldMap Fields) (FieldDefinitionMap, error) {
resultFieldMap := FieldDefinitionMap{}

err := invariantf(
Expand Down Expand Up @@ -695,9 +704,10 @@ type Interface struct {
PrivateDescription string `json:"description"`
ResolveType ResolveTypeFn

typeConfig InterfaceConfig
fields FieldDefinitionMap
err error
typeConfig InterfaceConfig
initialisedFields bool
fields FieldDefinitionMap
err error
}
type InterfaceConfig struct {
Name string `json:"name"`
Expand Down Expand Up @@ -751,30 +761,42 @@ func (it *Interface) AddFieldConfig(fieldName string, fieldConfig *Field) {
switch it.typeConfig.Fields.(type) {
case Fields:
it.typeConfig.Fields.(Fields)[fieldName] = fieldConfig
it.initialisedFields = false
}
}

func (it *Interface) Name() string {
return it.PrivateName
}

func (it *Interface) Description() string {
return it.PrivateDescription
}

func (it *Interface) Fields() (fields FieldDefinitionMap) {
if it.initialisedFields {
return it.fields
}

var configureFields Fields
switch it.typeConfig.Fields.(type) {
case Fields:
configureFields = it.typeConfig.Fields.(Fields)
case FieldsThunk:
configureFields = it.typeConfig.Fields.(FieldsThunk)()
}

fields, err := defineFieldMap(it, configureFields)
it.err = err
it.fields = fields
it.initialisedFields = true
return it.fields
}

func (it *Interface) String() string {
return it.PrivateName
}

func (it *Interface) Error() error {
return it.err
}
Expand Down
61 changes: 31 additions & 30 deletions executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ func Execute(p ExecuteParams) (result *Result) {
go func(out chan<- *Result, done <-chan struct{}) {
result := &Result{}

exeContext, err := buildExecutionContext(BuildExecutionCtxParams{
exeContext, err := buildExecutionContext(buildExecutionCtxParams{
Schema: p.Schema,
Root: p.Root,
AST: p.AST,
Expand Down Expand Up @@ -70,7 +70,7 @@ func Execute(p ExecuteParams) (result *Result) {
}
}()

result = executeOperation(ExecuteOperationParams{
result = executeOperation(executeOperationParams{
ExecutionContext: exeContext,
Root: p.Root,
Operation: exeContext.Operation,
Expand All @@ -92,7 +92,7 @@ func Execute(p ExecuteParams) (result *Result) {
return
}

type BuildExecutionCtxParams struct {
type buildExecutionCtxParams struct {
Schema Schema
Root interface{}
AST *ast.Document
Expand All @@ -102,7 +102,8 @@ type BuildExecutionCtxParams struct {
Result *Result
Context context.Context
}
type ExecutionContext struct {

type executionContext struct {
Schema Schema
Fragments map[string]ast.Definition
Root interface{}
Expand All @@ -112,8 +113,8 @@ type ExecutionContext struct {
Context context.Context
}

func buildExecutionContext(p BuildExecutionCtxParams) (*ExecutionContext, error) {
eCtx := &ExecutionContext{}
func buildExecutionContext(p buildExecutionCtxParams) (*executionContext, error) {
eCtx := &executionContext{}
var operation *ast.OperationDefinition
fragments := map[string]ast.Definition{}

Expand Down Expand Up @@ -159,25 +160,25 @@ func buildExecutionContext(p BuildExecutionCtxParams) (*ExecutionContext, error)
return eCtx, nil
}

type ExecuteOperationParams struct {
ExecutionContext *ExecutionContext
type executeOperationParams struct {
ExecutionContext *executionContext
Root interface{}
Operation ast.Definition
}

func executeOperation(p ExecuteOperationParams) *Result {
func executeOperation(p executeOperationParams) *Result {
operationType, err := getOperationRootType(p.ExecutionContext.Schema, p.Operation)
if err != nil {
return &Result{Errors: gqlerrors.FormatErrors(err)}
}

fields := collectFields(CollectFieldsParams{
fields := collectFields(collectFieldsParams{
ExeContext: p.ExecutionContext,
RuntimeType: operationType,
SelectionSet: p.Operation.GetSelectionSet(),
})

executeFieldsParams := ExecuteFieldsParams{
executeFieldsParams := executeFieldsParams{
ExecutionContext: p.ExecutionContext,
ParentType: operationType,
Source: p.Root,
Expand Down Expand Up @@ -238,15 +239,15 @@ func getOperationRootType(schema Schema, operation ast.Definition) (*Object, err
}
}

type ExecuteFieldsParams struct {
ExecutionContext *ExecutionContext
type executeFieldsParams struct {
ExecutionContext *executionContext
ParentType *Object
Source interface{}
Fields map[string][]*ast.Field
}

// Implements the "Evaluating selection sets" section of the spec for "write" mode.
func executeFieldsSerially(p ExecuteFieldsParams) *Result {
func executeFieldsSerially(p executeFieldsParams) *Result {
if p.Source == nil {
p.Source = map[string]interface{}{}
}
Expand All @@ -270,7 +271,7 @@ func executeFieldsSerially(p ExecuteFieldsParams) *Result {
}

// Implements the "Evaluating selection sets" section of the spec for "read" mode.
func executeFields(p ExecuteFieldsParams) *Result {
func executeFields(p executeFieldsParams) *Result {
if p.Source == nil {
p.Source = map[string]interface{}{}
}
Expand All @@ -293,8 +294,8 @@ func executeFields(p ExecuteFieldsParams) *Result {
}
}

type CollectFieldsParams struct {
ExeContext *ExecutionContext
type collectFieldsParams struct {
ExeContext *executionContext
RuntimeType *Object // previously known as OperationType
SelectionSet *ast.SelectionSet
Fields map[string][]*ast.Field
Expand All @@ -306,7 +307,7 @@ type CollectFieldsParams struct {
// CollectFields requires the "runtime type" of an object. For a field which
// returns and Interface or Union type, the "runtime type" will be the actual
// Object type returned by that field.
func collectFields(p CollectFieldsParams) map[string][]*ast.Field {
func collectFields(p collectFieldsParams) map[string][]*ast.Field {

fields := p.Fields
if fields == nil {
Expand Down Expand Up @@ -335,7 +336,7 @@ func collectFields(p CollectFieldsParams) map[string][]*ast.Field {
!doesFragmentConditionMatch(p.ExeContext, selection, p.RuntimeType) {
continue
}
innerParams := CollectFieldsParams{
innerParams := collectFieldsParams{
ExeContext: p.ExeContext,
RuntimeType: p.RuntimeType,
SelectionSet: selection.SelectionSet,
Expand All @@ -362,7 +363,7 @@ func collectFields(p CollectFieldsParams) map[string][]*ast.Field {
if !doesFragmentConditionMatch(p.ExeContext, fragment, p.RuntimeType) {
continue
}
innerParams := CollectFieldsParams{
innerParams := collectFieldsParams{
ExeContext: p.ExeContext,
RuntimeType: p.RuntimeType,
SelectionSet: fragment.GetSelectionSet(),
Expand All @@ -378,7 +379,7 @@ func collectFields(p CollectFieldsParams) map[string][]*ast.Field {

// Determines if a field should be included based on the @include and @skip
// directives, where @skip has higher precedence than @include.
func shouldIncludeNode(eCtx *ExecutionContext, directives []*ast.Directive) bool {
func shouldIncludeNode(eCtx *executionContext, directives []*ast.Directive) bool {

defaultReturnValue := true

Expand Down Expand Up @@ -436,7 +437,7 @@ func shouldIncludeNode(eCtx *ExecutionContext, directives []*ast.Directive) bool
}

// Determines if a fragment is applicable to the given type.
func doesFragmentConditionMatch(eCtx *ExecutionContext, fragment ast.Node, ttype *Object) bool {
func doesFragmentConditionMatch(eCtx *executionContext, fragment ast.Node, ttype *Object) bool {

switch fragment := fragment.(type) {
case *ast.FragmentDefinition:
Expand Down Expand Up @@ -507,7 +508,7 @@ type resolveFieldResultState struct {
// figures out the value that the field returns by calling its resolve function,
// then calls completeValue to complete promises, serialize scalars, or execute
// the sub-selection-set for objects.
func resolveField(eCtx *ExecutionContext, parentType *Object, source interface{}, fieldASTs []*ast.Field) (result interface{}, resultState resolveFieldResultState) {
func resolveField(eCtx *executionContext, parentType *Object, source interface{}, fieldASTs []*ast.Field) (result interface{}, resultState resolveFieldResultState) {
// catch panic from resolveFn
var returnType Output
defer func() (interface{}, resolveFieldResultState) {
Expand Down Expand Up @@ -584,7 +585,7 @@ func resolveField(eCtx *ExecutionContext, parentType *Object, source interface{}
return completed, resultState
}

func completeValueCatchingError(eCtx *ExecutionContext, returnType Type, fieldASTs []*ast.Field, info ResolveInfo, result interface{}) (completed interface{}) {
func completeValueCatchingError(eCtx *executionContext, returnType Type, fieldASTs []*ast.Field, info ResolveInfo, result interface{}) (completed interface{}) {
// catch panic
defer func() interface{} {
if r := recover(); r != nil {
Expand All @@ -608,7 +609,7 @@ func completeValueCatchingError(eCtx *ExecutionContext, returnType Type, fieldAS
return completed
}

func completeValue(eCtx *ExecutionContext, returnType Type, fieldASTs []*ast.Field, info ResolveInfo, result interface{}) interface{} {
func completeValue(eCtx *executionContext, returnType Type, fieldASTs []*ast.Field, info ResolveInfo, result interface{}) interface{} {

resultVal := reflect.ValueOf(result)
if resultVal.IsValid() && resultVal.Type().Kind() == reflect.Func {
Expand Down Expand Up @@ -678,7 +679,7 @@ func completeValue(eCtx *ExecutionContext, returnType Type, fieldASTs []*ast.Fie

// completeAbstractValue completes value of an Abstract type (Union / Interface) by determining the runtime type
// of that value, then completing based on that type.
func completeAbstractValue(eCtx *ExecutionContext, returnType Abstract, fieldASTs []*ast.Field, info ResolveInfo, result interface{}) interface{} {
func completeAbstractValue(eCtx *executionContext, returnType Abstract, fieldASTs []*ast.Field, info ResolveInfo, result interface{}) interface{} {

var runtimeType *Object

Expand Down Expand Up @@ -715,7 +716,7 @@ func completeAbstractValue(eCtx *ExecutionContext, returnType Abstract, fieldAST
}

// completeObjectValue complete an Object value by executing all sub-selections.
func completeObjectValue(eCtx *ExecutionContext, returnType *Object, fieldASTs []*ast.Field, info ResolveInfo, result interface{}) interface{} {
func completeObjectValue(eCtx *executionContext, returnType *Object, fieldASTs []*ast.Field, info ResolveInfo, result interface{}) interface{} {

// If there is an isTypeOf predicate function, call it with the
// current result. If isTypeOf returns false, then raise an error rather
Expand All @@ -742,7 +743,7 @@ func completeObjectValue(eCtx *ExecutionContext, returnType *Object, fieldASTs [
}
selectionSet := fieldAST.SelectionSet
if selectionSet != nil {
innerParams := CollectFieldsParams{
innerParams := collectFieldsParams{
ExeContext: eCtx,
RuntimeType: returnType,
SelectionSet: selectionSet,
Expand All @@ -752,7 +753,7 @@ func completeObjectValue(eCtx *ExecutionContext, returnType *Object, fieldASTs [
subFieldASTs = collectFields(innerParams)
}
}
executeFieldsParams := ExecuteFieldsParams{
executeFieldsParams := executeFieldsParams{
ExecutionContext: eCtx,
ParentType: returnType,
Source: result,
Expand All @@ -774,7 +775,7 @@ func completeLeafValue(returnType Leaf, result interface{}) interface{} {
}

// completeListValue complete a list value by completing each item in the list with the inner type
func completeListValue(eCtx *ExecutionContext, returnType *List, fieldASTs []*ast.Field, info ResolveInfo, result interface{}) interface{} {
func completeListValue(eCtx *executionContext, returnType *List, fieldASTs []*ast.Field, info ResolveInfo, result interface{}) interface{} {
resultVal := reflect.ValueOf(result)
parentTypeName := ""
if info.ParentType != nil {
Expand Down

0 comments on commit d951837

Please sign in to comment.