MCPcopy Create free account
hub / github.com/araddon/qlbridge / evalField

Method evalField

datasource/context_wrapper.go:119–206  ·  view source on GitHub ↗

evalField evaluates an expression like (.Field) or (.Field arg1 arg2). The 'final' argument represents the return value from the preceding value of the pipeline, if any.

(dot reflect.Value, fieldName string, node expr.Node, args []expr.Node, final, receiver reflect.Value)

Source from the content-addressed store, hash-verified

117// The 'final' argument represents the return value from the preceding
118// value of the pipeline, if any.
119func (s *state) evalField(dot reflect.Value, fieldName string, node expr.Node, args []expr.Node, final, receiver reflect.Value) reflect.Value {
120
121 //u.Debugf("evalField: valid?%v", receiver.IsValid())
122 if !receiver.IsValid() {
123 //u.Warnf("bailing")
124 return zero
125 }
126 typ := receiver.Type()
127 receiver, _ = findValue(receiver)
128 // Unless it's an interface, need to get to a value of type *T to guarantee
129 // we see all methods of T and *T.
130 ptr := receiver
131 if ptr.Kind() != reflect.Interface && ptr.CanAddr() {
132 ptr = ptr.Addr()
133 }
134 if method := ptr.MethodByName(fieldName); method.IsValid() {
135 //u.Warnf("unimplemented method: %v", fieldName)
136 return s.evalCall(dot, method, node, fieldName, args, final)
137 }
138 hasArgs := len(args) > 1 || final.IsValid()
139 // It's not a method; must be a field of a struct or an element of a map. The receiver must not be nil.
140 receiver, isNil := findValue(receiver)
141 //u.Debugf("fld:%s receiver kind():%v val: %v", fieldName, receiver.Kind(), receiver)
142 if isNil {
143 return zero
144 }
145 switch receiver.Kind() {
146 case reflect.Struct:
147 tField, ok := receiver.Type().FieldByName(fieldName)
148 if !ok {
149 tField, ok = receiver.Type().FieldByNameFunc(lowerFieldMatch(fieldName))
150 if !ok {
151 tagName := strings.ToLower(fieldName)
152 // Wow, this is pretty bruttaly expensive
153 // Iterate over all available fields and read the tag value
154 for i := 0; i < receiver.NumField(); i++ {
155 // Get the field, returns https://golang.org/pkg/reflect/#StructField
156 field := receiver.Type().Field(i)
157
158 // Get the field tag value
159 tag := field.Tag.Get("json")
160 if tag == tagName {
161 tField = field
162 ok = true
163 break
164 }
165 }
166 }
167 }
168 //u.Infof("got field? %v", fieldName, tField)
169 if ok {
170 field := receiver.FieldByIndex(tField.Index)
171 if tField.PkgPath != "" { // field is unexported
172 return s.errorf("%s is an unexported field of struct type %s", fieldName, typ)
173 }
174 // If it's a function, we must call it.
175 if hasArgs {
176 return s.errorf("%s has arguments but cannot be invoked as function", fieldName)

Callers 1

evalFieldChainMethod · 0.95

Calls 9

evalCallMethod · 0.95
errorfMethod · 0.95
findValueFunction · 0.85
lowerFieldMatchFunction · 0.85
ErrorfMethod · 0.80
TypeMethod · 0.65
KindMethod · 0.65
GetMethod · 0.65
KeyMethod · 0.65

Tested by

no test coverage detected