Skip to content
This repository was archived by the owner on Aug 27, 2018. It is now read-only.

Commit 21bad54

Browse files
committed
Test out GopherJS struct val fix
1 parent 55fa170 commit 21bad54

File tree

5 files changed

+114
-7
lines changed

5 files changed

+114
-7
lines changed

.vendor.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
./_vendor/src/golang.org/x/crypto 3cb07270c9455e8ad27956a70891c962d121a228 https://go.googlesource.com/crypto
44
./_vendor/src/golang.org/x/tools 620ecdb8d7943e20dc030b61bfe898d1b000bdea https://go.googlesource.com/tools
55
./_vendor/src/github.com/jteeuwen/go-bindata a0ff2567cfb70903282db057e799fd826784d41d [email protected]:jteeuwen/go-bindata
6-
./_vendor/src/github.com/gopherjs/gopherjs e14987c0ef06db387b90fec85e8d06dc05598e24 [email protected]:gopherjs/gopherjs
6+
./_vendor/src/github.com/gopherjs/gopherjs 91be9d3fa503472d6ccde719f7ec6923dfb18699 [email protected]:gopherjs/gopherjs
77
./_vendor/src/github.com/gopherjs/jsbuiltin 67703bfb044e3192fbcab025c3aeaeedafad1f2f [email protected]:gopherjs/jsbuiltin
88
./_vendor/src/github.com/kisielk/gotool 0de1eaf82fa3f583ce21fde859f1e7e0c5e9b220 [email protected]:kisielk/gotool
99
./_vendor/src/github.com/fsnotify/fsnotify 7d7316ed6e1ed2de075aab8dfc76de5d158d66e1 [email protected]:fsnotify/fsnotify

_vendor/src/github.com/gopherjs/gopherjs/compiler/expressions.go

+14-3
Original file line numberDiff line numberDiff line change
@@ -812,6 +812,11 @@ func (c *funcContext) makeReceiver(e *ast.SelectorExpr) *expression {
812812

813813
_, isPointer := recvType.Underlying().(*types.Pointer)
814814
methodsRecvType := sel.Obj().Type().(*types.Signature).Recv().Type()
815+
816+
if _, isInterface := methodsRecvType.Underlying().(*types.Interface); isInterface {
817+
return c.formatExpr("$copyInterfaceVal(%e)", x)
818+
}
819+
815820
_, pointerExpected := methodsRecvType.(*types.Pointer)
816821
if !isPointer && pointerExpected {
817822
recvType = types.NewPointer(recvType)
@@ -825,6 +830,7 @@ func (c *funcContext) makeReceiver(e *ast.SelectorExpr) *expression {
825830
if isWrapped(recvType) {
826831
recv = c.formatExpr("new %s(%s)", c.typeName(methodsRecvType), recv)
827832
}
833+
828834
return recv
829835
}
830836

@@ -1130,12 +1136,17 @@ func (c *funcContext) translateImplicitConversion(expr ast.Expr, desiredType typ
11301136
// wrap JS object into js.Object struct when converting to interface
11311137
return c.formatExpr("new $jsObjectPtr(%e)", expr)
11321138
}
1139+
1140+
switch exprType.Underlying().(type) {
1141+
case *types.Array:
1142+
return c.formatExpr("new %1s($clone(%e, %1s))", c.typeName(exprType), expr)
1143+
case *types.Struct:
1144+
return c.formatExpr("new %1e.constructor.elem($clone(%1e, %s))", expr, c.typeName(exprType))
1145+
}
1146+
11331147
if isWrapped(exprType) {
11341148
return c.formatExpr("new %s(%e)", c.typeName(exprType), expr)
11351149
}
1136-
if _, isStruct := exprType.Underlying().(*types.Struct); isStruct {
1137-
return c.formatExpr("new %1e.constructor.elem(%1e)", expr)
1138-
}
11391150
}
11401151

11411152
return c.translateExpr(expr)

_vendor/src/github.com/gopherjs/gopherjs/compiler/prelude/jsmapping.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -163,10 +163,10 @@ var $externalizeFunction = function(v, t, passThis) {
163163
case 0:
164164
return;
165165
case 1:
166-
return $externalize(result, t.results[0]);
166+
return $externalize($copyInterfaceVal(result), t.results[0]);
167167
default:
168168
for (var i = 0; i < t.results.length; i++) {
169-
result[i] = $externalize(result[i], t.results[i]);
169+
result[i] = $externalize($copyInterfaceVal(result[i]), t.results[i]);
170170
}
171171
return result;
172172
}

_vendor/src/github.com/gopherjs/gopherjs/compiler/prelude/prelude.go

+9-1
Large diffs are not rendered by default.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
package tests
2+
3+
import (
4+
"fmt"
5+
"testing"
6+
)
7+
8+
type Struct struct {
9+
Name string
10+
}
11+
12+
func (s Struct) SetName(n string) {
13+
s.Name = n
14+
}
15+
16+
type SetName interface {
17+
SetName(n string)
18+
}
19+
20+
func TestAssignStructValInterface(t *testing.T) {
21+
s := Struct{
22+
Name: "Rob",
23+
}
24+
25+
var i1 interface{} = s
26+
var i2 interface{} = i1
27+
28+
s.Name = "Pike"
29+
30+
ss := fmt.Sprintf("%#v", s)
31+
i1s := fmt.Sprintf("%#v", i1)
32+
i2s := fmt.Sprintf("%#v", i2)
33+
34+
if exp := "tests.Struct{Name:\"Pike\"}"; ss != exp {
35+
t.Fatalf("ss should have been %q; got %q", exp, ss)
36+
}
37+
38+
iexp := "tests.Struct{Name:\"Rob\"}"
39+
40+
if i1s != iexp {
41+
t.Fatalf("is should have been %q; got %q", iexp, i1s)
42+
}
43+
44+
if i2s != iexp {
45+
t.Fatalf("is should have been %q; got %q", iexp, i2s)
46+
}
47+
}
48+
49+
func TestStructValInterfaceMethodCall(t *testing.T) {
50+
var i SetName = Struct{
51+
Name: "Rob",
52+
}
53+
54+
i.SetName("Pike")
55+
56+
is := fmt.Sprintf("%#v", i)
57+
58+
if exp := "tests.Struct{Name:\"Rob\"}"; is != exp {
59+
t.Fatalf("is should have been %q; got %q", exp, is)
60+
}
61+
}
62+
63+
func TestAssignArrayInterface(t *testing.T) {
64+
a := [2]int{1, 2}
65+
66+
var i1 interface{} = a
67+
var i2 interface{} = i1
68+
69+
a[0] = 0
70+
71+
as := fmt.Sprintf("%#v", a)
72+
i1s := fmt.Sprintf("%#v", i1)
73+
i2s := fmt.Sprintf("%#v", i2)
74+
75+
if exp := "[2]int{0, 2}"; as != exp {
76+
t.Fatalf("ss should have been %q; got %q", exp, as)
77+
}
78+
79+
iexp := "[2]int{1, 2}"
80+
81+
if i1s != iexp {
82+
t.Fatalf("is should have been %q; got %q", iexp, i1s)
83+
}
84+
85+
if i2s != iexp {
86+
t.Fatalf("is should have been %q; got %q", iexp, i2s)
87+
}
88+
}

0 commit comments

Comments
 (0)