Fix automatic type conversion for binary methods
This commit is contained in:
@@ -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()
|
||||
}
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
|
||||
@@ -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{})
|
||||
|
||||
Reference in New Issue
Block a user