interp: support wrapping of nested interfaces

Add getConcreteType to retrieve the concrete type of a nested interface
value implementing a specific interface for which a wrapper exists.

If method resolution fails at runtime, a panic is now issued instead
of an error message and continue.

Fixes #1187.
This commit is contained in:
Marc Vertes
2021-07-26 19:12:11 +02:00
committed by GitHub
parent bf843fc09e
commit c80c605ab9
6 changed files with 94 additions and 7 deletions

View File

@@ -341,6 +341,34 @@ func genValueInterface(n *node) func(*frame) reflect.Value {
}
}
func getConcreteValue(val reflect.Value) reflect.Value {
v := val
for {
vi, ok := v.Interface().(valueInterface)
if !ok {
break
}
v = vi.value
}
if v.NumMethod() > 0 {
return v
}
if v.Type().Kind() != reflect.Struct {
return v
}
// Search a concrete value in fields of an emulated interface.
for i := v.NumField() - 1; i >= 0; i-- {
vv := v.Field(i)
if vv.Type().Kind() == reflect.Interface {
vv = vv.Elem()
}
if vv.IsValid() {
return vv
}
}
return v
}
func zeroInterfaceValue() reflect.Value {
n := &node{kind: basicLit, typ: &itype{cat: nilT, untyped: true}}
v := reflect.New(interf).Elem()