Fix automatic type conversion for binary methods

This commit is contained in:
Marc Vertes
2018-11-22 11:27:40 +01:00
parent d77e2e3f83
commit a86e5b43a7
5 changed files with 32 additions and 21 deletions

View File

@@ -19,19 +19,18 @@ func client() {
fmt.Println(string(body))
}
func server(c chan bool) {
func server(ready chan bool) {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, "Welcome to my website! ")
})
go http.ListenAndServe(":8080", nil)
c <- true
ready <- true
}
func main() {
ready := make(chan bool, 1)
ready := make(chan bool)
go server(ready)
a := <-ready
println(a)
<-ready
client()
}

View File

@@ -9,8 +9,10 @@ type Middleware struct {
Name string
}
var version string = "1.0"
func (m *Middleware) Handler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Welcome to my website", m.Name)
fmt.Fprintln(w, "Welcome to my website", m.Name, version)
}
func main() {

View File

@@ -14,8 +14,8 @@ type Middleware struct {
func (m *Middleware) Handler(w http.ResponseWriter, r *http.Request) {
//println("Hello")
//log.Println(r.Header.Get("User-Agent"))
log.Println(w.Header())
log.Println(r.Header.Get("User-Agent"))
//log.Println(w.Header())
fmt.Fprintln(w, "Welcome to my website", m.Name)
}

View File

@@ -713,12 +713,15 @@ func (interp *Interpreter) Cfg(root *Node) []*Node {
}
//log.Println(n.index, "selector", n.child[0].ident+"."+n.child[1].ident, n.typ.cat)
if n.typ.cat == ValueT {
// Handle object defined in runtime
// Handle object defined in runtime, try to find field or method
// Search for method first, as it applies both to types T and *T
// Search for field must then be performed on type T only (not *T)
if method, ok := n.typ.rtype.MethodByName(n.child[1].ident); ok {
n.val = method.Index
n.gen = getIndexBinMethod
n.typ = &Type{cat: ValueT, rtype: method.Type}
n.fsize = method.Type.NumOut()
n.recv = &Receiver{node: n.child[0]}
} else if n.typ.rtype.Kind() == reflect.Ptr {
if field, ok := n.typ.rtype.Elem().FieldByName(n.child[1].ident); ok {
n.typ = &Type{cat: ValueT, rtype: field.Type}
@@ -747,12 +750,16 @@ func (interp *Interpreter) Cfg(root *Node) []*Node {
n.gen = getPtrIndexSeq
} else if method, ok := n.typ.val.rtype.MethodByName(n.child[1].ident); ok {
n.val = method.Func
n.typ = &Type{cat: ValueT, rtype: method.Type}
n.fsize = method.Type.NumOut()
n.gen = nop
n.recv = &Receiver{node: n.child[0]}
n.gen = getIndexBinMethod
} else if method, ok := reflect.PtrTo(n.typ.val.rtype).MethodByName(n.child[1].ident); ok {
n.val = method.Func
n.fsize = method.Type.NumOut()
n.gen = nop
n.gen = getIndexBinMethod
n.typ = &Type{cat: ValueT, rtype: method.Type}
n.recv = &Receiver{node: n.child[0]}
} else {
log.Println(n.index, "selector unresolved")
}

View File

@@ -312,11 +312,10 @@ func (n *Node) wrapNode(in []reflect.Value) []reflect.Value {
}
func genNodeWrapper(n *Node) func(*Frame) reflect.Value {
method := n.recv != nil
var recv func(*Frame) reflect.Value
var receiver func(*Frame) reflect.Value
if method {
recv = genValueRecv(n)
if n.recv != nil {
receiver = genValueRecv(n)
}
return func(f *Frame) reflect.Value {
@@ -324,14 +323,14 @@ func genNodeWrapper(n *Node) func(*Frame) reflect.Value {
def := n.val.(*Node)
var result []reflect.Value
frame := Frame{anc: f, data: make([]reflect.Value, def.flen)}
i := 0
// If fucnction is a method, set its receiver data in the frame
if method {
frame.data[def.child[0].findex] = recv(f)
if receiver != nil {
frame.data[def.framepos[0]] = receiver(f)
i++
}
// Unwrap input arguments from their reflect value and store them in the frame
i := 0
for _, arg := range in {
frame.data[def.framepos[i]] = arg
i++
@@ -345,7 +344,7 @@ func genNodeWrapper(n *Node) func(*Frame) reflect.Value {
if fieldList := def.child[2].child[1]; fieldList != nil {
result = make([]reflect.Value, len(fieldList.child))
for i := range fieldList.child {
result[i] = reflect.ValueOf(frame.data[i])
result[i] = frame.data[i]
}
}
}
@@ -471,6 +470,10 @@ func callBin(n *Node) {
if funcType.IsVariadic() {
variadic = funcType.NumIn() - 1
}
receiverOffset := 0
if n.child[0].recv != nil {
receiverOffset = 1
}
for i, c := range child {
if isRegularCall(c) {
@@ -484,7 +487,7 @@ func callBin(n *Node) {
if variadic >= 0 && i >= variadic {
argType = funcType.In(variadic).Elem()
} else {
argType = funcType.In(i)
argType = funcType.In(i + receiverOffset)
}
if c.kind == BasicLit {
// Convert literal value (untyped) to function argument type (if not an interface{})