Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(go): Use type registry to find the correct target type for JSII Proxy #3354

Merged
merged 2 commits into from Feb 3, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/@jsii/go-runtime/jsii-runtime-go/cast.go
Expand Up @@ -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 {
Expand Down
Expand Up @@ -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
arnogeurts-sqills marked this conversation as resolved.
Show resolved Hide resolved
}

// 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)
}
Expand Down
Expand Up @@ -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 {
Expand All @@ -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
}
}
Expand Down
6 changes: 3 additions & 3 deletions packages/@jsii/go-runtime/jsii-runtime-go/runtime/runtime.go
Expand Up @@ -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)
}
}
Expand All @@ -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)
}

Expand All @@ -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)
}
}
Expand Down