Skip to content

Commit

Permalink
fix(go): panic on callback: using *<interface> as <interface>
Browse files Browse the repository at this point in the history
The callback handling logic was incorrectly handling "pure" interface
parameters. The reflection piece would create a new argument value in
preparation for the callback, however for interfaces, it would leave the
pointer to the interface type (as returned by `reflect.New`) instead of
indirecting to the interface itself as appropriate.

Fixes #2793
  • Loading branch information
RomainMuller committed Apr 16, 2021
1 parent b40ba5d commit d0dd009
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 1 deletion.
11 changes: 11 additions & 0 deletions packages/@jsii/go-runtime-test/project/compliance_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package tests
import (
"encoding/json"
"fmt"
"github.com/aws/jsii/go-runtime-test/internal/bellRinger"
"math"
"runtime"
"testing"
Expand Down Expand Up @@ -1632,6 +1633,16 @@ func (suite *ComplianceSuite) TestCollectionOfInterfaces_MapOfStructs() {
require.Equal("Hello, I'm String!", *(*m["A"]).RequiredString)
}

func (suite *ComplianceSuite) TestCallbackParameterIsInterface() {
require := suite.Require()

ringer := bellRinger.New()

require.True(*calc.ConsumerCanRingBell_StaticImplementedByObjectLiteral(ringer))
require.True(*calc.ConsumerCanRingBell_StaticImplementedByPrivateClass(ringer))
require.True(*calc.ConsumerCanRingBell_StaticImplementedByPublicClass(ringer))
}

// required to make `go test` recognize the suite.
func TestComplianceSuite(t *testing.T) {
suite.Run(t, new(ComplianceSuite))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package bellRinger

import "github.com/aws/jsii/jsii-calc/go/jsiicalc/v3"

func New() jsiicalc.IBellRinger {
return &ringer{}
}

type ringer struct {}

func (r *ringer) YourTurn(bell jsiicalc.IBell) {
bell.Ring()
}
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ func (c *Client) invoke(method reflect.Value, args []interface{}) (retval reflec
callArgs[i] = reflect.New(argType)
}
c.castAndSetToPtr(callArgs[i].Elem(), reflect.ValueOf(arg))
if argType.Kind() != reflect.Ptr && argType.Kind() != reflect.Interface {
if argType.Kind() != reflect.Ptr {
// The result of `reflect.New` is always a pointer, so if the
// argument is by-value, we have to de-reference it first.
callArgs[i] = callArgs[i].Elem()
Expand Down

0 comments on commit d0dd009

Please sign in to comment.