Skip to content

Commit 75d94ef

Browse files
feat(go): Use type registry to find the correct target type for JSII Proxy (#3354)
With this PR, the type that is instantiated as JSII Proxy is looked up from the type registry using the TypeFQDN in the ref. If that type is registered in the type registry AND that type is assignable to the targeted value type, than that type is used to instantiate the JSII proxy. Fixes #3353 and relates to #2819.
1 parent d2f57fe commit 75d94ef

4 files changed

Lines changed: 14 additions & 10 deletions

File tree

packages/@jsii/go-runtime/jsii-runtime-go/cast.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ func UnsafeCast(from interface{}, into interface{}) {
4343
client := kernel.GetClient()
4444
if objID, found := client.FindObjectRef(rfrom); found {
4545
// Ensures the value is initialized properly. Panics if the target value is not a jsii interface type.
46-
client.Types().InitJsiiProxy(rinto)
46+
client.Types().InitJsiiProxy(rinto, rinto.Type())
4747

4848
// If the target type is a behavioral interface, add it to the ObjectRef.Interfaces list.
4949
if fqn, found := client.Types().InterfaceFQN(rinto.Type()); found {

packages/@jsii/go-runtime/jsii-runtime-go/internal/kernel/conversions.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,14 +63,20 @@ func (c *Client) castAndSetToPtr(ptr reflect.Value, data reflect.Value) {
6363
return
6464
}
6565

66+
targetType := ptr.Type()
67+
if typ, ok := c.Types().FindType(ref.TypeFQN()); ok && typ.AssignableTo(ptr.Type()) {
68+
// Specialize the return type to be the dynamic value type
69+
targetType = typ
70+
}
71+
6672
// If it's currently tracked, return the current instance
67-
if object, ok := c.objects.GetObjectAs(ref.InstanceID, ptr.Type()); ok {
73+
if object, ok := c.objects.GetObjectAs(ref.InstanceID, targetType); ok {
6874
ptr.Set(object)
6975
return
7076
}
7177

7278
// If return data is jsii object references, add to objects table.
73-
if err := c.Types().InitJsiiProxy(ptr); err == nil {
79+
if err := c.Types().InitJsiiProxy(ptr, targetType); err == nil {
7480
if err = c.RegisterInstance(ptr, ref); err != nil {
7581
panic(err)
7682
}

packages/@jsii/go-runtime/jsii-runtime-go/internal/typeregistry/typeregistry.go

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -89,9 +89,7 @@ func (t *TypeRegistry) FindType(fqn api.FQN) (typ reflect.Type, ok bool) {
8989
// InitJsiiProxy initializes a jsii proxy value at the provided pointer. It
9090
// returns an error if the pointer does not have a value of a registered
9191
// proxyable type (that is, a class or interface type).
92-
func (t *TypeRegistry) InitJsiiProxy(val reflect.Value) error {
93-
valType := val.Type()
94-
92+
func (t *TypeRegistry) InitJsiiProxy(val reflect.Value, valType reflect.Type) error {
9593
switch valType.Kind() {
9694
case reflect.Interface:
9795
if maker, ok := t.proxyMakers[valType]; ok {
@@ -115,7 +113,7 @@ func (t *TypeRegistry) InitJsiiProxy(val reflect.Value) error {
115113
if !field.Anonymous {
116114
return fmt.Errorf("refusing to initialize non-anonymous field %s of %v", field.Name, val)
117115
}
118-
if err := t.InitJsiiProxy(val.Field(i)); err != nil {
116+
if err := t.InitJsiiProxy(val.Field(i), field.Type); err != nil {
119117
return err
120118
}
121119
}

packages/@jsii/go-runtime/jsii-runtime-go/runtime/runtime.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ func RegisterStruct(fqn FQN, strct reflect.Type) {
102102
// element of it is not a registered jsii interface or class type).
103103
func InitJsiiProxy(ptr interface{}) {
104104
ptrVal := reflect.ValueOf(ptr).Elem()
105-
if err := kernel.GetClient().Types().InitJsiiProxy(ptrVal); err != nil {
105+
if err := kernel.GetClient().Types().InitJsiiProxy(ptrVal, ptrVal.Type()); err != nil {
106106
panic(err)
107107
}
108108
}
@@ -127,7 +127,7 @@ func Create(fqn FQN, args []interface{}, inst interface{}) {
127127
if !fieldVal.IsNil() {
128128
continue
129129
}
130-
if err := client.Types().InitJsiiProxy(fieldVal); err != nil {
130+
if err := client.Types().InitJsiiProxy(fieldVal, fieldVal.Type()); err != nil {
131131
panic(err)
132132
}
133133

@@ -136,7 +136,7 @@ func Create(fqn FQN, args []interface{}, inst interface{}) {
136136
if !fieldVal.IsZero() {
137137
continue
138138
}
139-
if err := client.Types().InitJsiiProxy(fieldVal); err != nil {
139+
if err := client.Types().InitJsiiProxy(fieldVal, fieldVal.Type()); err != nil {
140140
panic(err)
141141
}
142142
}

0 commit comments

Comments
 (0)