diff --git a/packages/@jsii/go-runtime/jsii-runtime-go/cast.go b/packages/@jsii/go-runtime/jsii-runtime-go/cast.go index 935dc793e6..2049cfb957 100644 --- a/packages/@jsii/go-runtime/jsii-runtime-go/cast.go +++ b/packages/@jsii/go-runtime/jsii-runtime-go/cast.go @@ -43,7 +43,7 @@ func UnsafeCast(from interface{}, into interface{}) { client := kernel.GetClient() if objID, found := client.FindObjectRef(rfrom); found { // Ensures the value is initialized properly. Panics if the target value is not a jsii interface type. - client.Types().InitJsiiProxy(rinto) + client.Types().InitJsiiProxy(rinto, rinto.Type()) // If the target type is a behavioral interface, add it to the ObjectRef.Interfaces list. if fqn, found := client.Types().InterfaceFQN(rinto.Type()); found { diff --git a/packages/@jsii/go-runtime/jsii-runtime-go/internal/kernel/conversions.go b/packages/@jsii/go-runtime/jsii-runtime-go/internal/kernel/conversions.go index 1292bf0772..2897f89efa 100644 --- a/packages/@jsii/go-runtime/jsii-runtime-go/internal/kernel/conversions.go +++ b/packages/@jsii/go-runtime/jsii-runtime-go/internal/kernel/conversions.go @@ -63,14 +63,20 @@ func (c *Client) castAndSetToPtr(ptr reflect.Value, data reflect.Value) { return } + targetType := ptr.Type() + if typ, ok := c.Types().FindType(ref.TypeFQN()); ok && typ.AssignableTo(ptr.Type()) { + // Specialize the return type to be the dynamic value type + targetType = typ + } + // If it's currently tracked, return the current instance - if object, ok := c.objects.GetObjectAs(ref.InstanceID, ptr.Type()); ok { + if object, ok := c.objects.GetObjectAs(ref.InstanceID, targetType); ok { ptr.Set(object) return } // If return data is jsii object references, add to objects table. - if err := c.Types().InitJsiiProxy(ptr); err == nil { + if err := c.Types().InitJsiiProxy(ptr, targetType); err == nil { if err = c.RegisterInstance(ptr, ref); err != nil { panic(err) } diff --git a/packages/@jsii/go-runtime/jsii-runtime-go/internal/typeregistry/typeregistry.go b/packages/@jsii/go-runtime/jsii-runtime-go/internal/typeregistry/typeregistry.go index 2f1bb1d641..98af846ec3 100644 --- a/packages/@jsii/go-runtime/jsii-runtime-go/internal/typeregistry/typeregistry.go +++ b/packages/@jsii/go-runtime/jsii-runtime-go/internal/typeregistry/typeregistry.go @@ -89,9 +89,7 @@ func (t *TypeRegistry) FindType(fqn api.FQN) (typ reflect.Type, ok bool) { // InitJsiiProxy initializes a jsii proxy value at the provided pointer. It // returns an error if the pointer does not have a value of a registered // proxyable type (that is, a class or interface type). -func (t *TypeRegistry) InitJsiiProxy(val reflect.Value) error { - valType := val.Type() - +func (t *TypeRegistry) InitJsiiProxy(val reflect.Value, valType reflect.Type) error { switch valType.Kind() { case reflect.Interface: if maker, ok := t.proxyMakers[valType]; ok { @@ -115,7 +113,7 @@ func (t *TypeRegistry) InitJsiiProxy(val reflect.Value) error { if !field.Anonymous { return fmt.Errorf("refusing to initialize non-anonymous field %s of %v", field.Name, val) } - if err := t.InitJsiiProxy(val.Field(i)); err != nil { + if err := t.InitJsiiProxy(val.Field(i), field.Type); err != nil { return err } } diff --git a/packages/@jsii/go-runtime/jsii-runtime-go/runtime/runtime.go b/packages/@jsii/go-runtime/jsii-runtime-go/runtime/runtime.go index d9bde090b8..00878c4ccd 100644 --- a/packages/@jsii/go-runtime/jsii-runtime-go/runtime/runtime.go +++ b/packages/@jsii/go-runtime/jsii-runtime-go/runtime/runtime.go @@ -102,7 +102,7 @@ func RegisterStruct(fqn FQN, strct reflect.Type) { // element of it is not a registered jsii interface or class type). func InitJsiiProxy(ptr interface{}) { ptrVal := reflect.ValueOf(ptr).Elem() - if err := kernel.GetClient().Types().InitJsiiProxy(ptrVal); err != nil { + if err := kernel.GetClient().Types().InitJsiiProxy(ptrVal, ptrVal.Type()); err != nil { panic(err) } } @@ -127,7 +127,7 @@ func Create(fqn FQN, args []interface{}, inst interface{}) { if !fieldVal.IsNil() { continue } - if err := client.Types().InitJsiiProxy(fieldVal); err != nil { + if err := client.Types().InitJsiiProxy(fieldVal, fieldVal.Type()); err != nil { panic(err) } @@ -136,7 +136,7 @@ func Create(fqn FQN, args []interface{}, inst interface{}) { if !fieldVal.IsZero() { continue } - if err := client.Types().InitJsiiProxy(fieldVal); err != nil { + if err := client.Types().InitJsiiProxy(fieldVal, fieldVal.Type()); err != nil { panic(err) } }