{"action":"created","issue":{"url":"https://api.github.com/repos/gopherjs/gopherjs/issues/174","labels_url":"https://api.github.com/repos/gopherjs/gopherjs/issues/174/labels{/name}","comments_url":"https://api.github.com/repos/gopherjs/gopherjs/issues/174/comments","events_url":"https://api.github.com/repos/gopherjs/gopherjs/issues/174/events","html_url":"https://github.com/gopherjs/gopherjs/issues/174","id":57178215,"number":174,"title":"Embedding anonymous interface considered as has-a on javascript side","user":{"login":"thoratou","id":1295414,"avatar_url":"https://avatars.githubusercontent.com/u/1295414?v=3","gravatar_id":"","url":"https://api.github.com/users/thoratou","html_url":"https://github.com/thoratou","followers_url":"https://api.github.com/users/thoratou/followers","following_url":"https://api.github.com/users/thoratou/following{/other_user}","gists_url":"https://api.github.com/users/thoratou/gists{/gist_id}","starred_url":"https://api.github.com/users/thoratou/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/thoratou/subscriptions","organizations_url":"https://api.github.com/users/thoratou/orgs","repos_url":"https://api.github.com/users/thoratou/repos","events_url":"https://api.github.com/users/thoratou/events{/privacy}","received_events_url":"https://api.github.com/users/thoratou/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":2,"created_at":"2015-02-10T14:03:47Z","updated_at":"2015-02-12T18:23:39Z","closed_at":null,"body":"Hello,\r\n\r\nNew issue found with anonymous embedding:\r\n\r\nhttp://www.gopherjs.org/playground/#/oI6PPIZ-rp\r\n\r\n```go\r\npackage main\r\n\r\nimport (\r\n\t\"github.com/gopherjs/gopherjs/js\"\r\n)\r\n\r\ntype Parent interface {\r\n\tjs.Object\r\n\tInnerHeight() int\r\n}\r\n\r\ntype parent struct {\r\n\tjs.Object\r\n}\r\n\r\nfunc (p *parent) InnerHeight() int {\r\n\treturn p.Get(\"innerHeight\").Int()\r\n}\r\n\r\ntype Child interface {\r\n\tParent\r\n}\r\n\r\ntype child struct {\r\n\tParent\r\n}\r\n\r\nfunc Print(o js.Object) {\r\n\tprintln(o)\r\n}\r\n\r\nfunc DummyCall(o js.Object) {\r\n\tprintln(o.Get(\"innerHeight\").Int())\r\n}\r\n\r\nfunc DummyCallParent(p Parent) {\r\n\tprintln(p.Get(\"Object\").Get(\"innerHeight\").Int())\r\n}\r\n\r\n\r\nfunc main() {\r\n\tparent := &parent{js.Global}\r\n\tPrint(parent)\r\n\tPrint(parent.Object)\r\n\tprintln(parent.InnerHeight()) // returns the good value => OK\r\n\tDummyCall(parent.Object) // returns the good value => OK\r\n\tDummyCall(parent) // returns 0 => KO\r\n\t\r\n\tchild := &child{parent}\r\n\tPrint(child)\r\n\tPrint(child.Parent)\r\n\tprintln(child.InnerHeight()) // returns the good value => OK\r\n\tDummyCallParent(child.Parent) // returns the good value => OK\r\n\tDummyCallParent(child) // panic: Cannot read property 'innerHeight' of undefined => KO\r\n}\r\n```\r\n\r\nWe get no issue with \"method\" calls in this case (see InnerHeight), but we get some issue giving the final structure to a function or method that uses to embedded interface (see DummyCallParent).\r\n\r\nNote: The result is even strange for the parent simple case as it returns 0 instead of giving the \"Cannot read property 'innerHeight' of undefined\" message\r\n\r\nThe example here is simple the understand the basis of the issue and should be easy to understand.\r\n\r\nHowever, we could have some very tricky results with this behaviour (this is how I discovered the bug and it took a while to figure why):\r\n\r\n```go\r\ntype helloWorldLayer struct {\r\n\tcc.Layer\r\n\t//other data here, not useful for the test\r\n}\r\n\r\nscene := cc.NewScene()\r\nlayer := &helloWorldLayer{cc.NewLayer(), ...}\r\nscene.AddChild(layer)\r\n```\r\n\r\nIt uses my in-development cocos2d-js binding (https://github.com/thoratou/go-cocos2d-js)\r\n\r\nIn the case, the AddChild call will delegate to the javascript code. All function calls are OK, but at one point it tries to access the internal layer data and fails.\r\nFor the developer point of view, it looks like a missing constructor call.\r\n\r\nThe workaround is to change the last call by:\r\n\r\n```go\r\nscene.AddChild(layer.Layer)\r\n```\r\n\r\nthis seems to be an issue for all public-interface/private-structure based libraries.\r\n\r\nSincerely,\r\n   thoratou"},"comment":{"url":"https://api.github.com/repos/gopherjs/gopherjs/issues/comments/74123449","html_url":"https://github.com/gopherjs/gopherjs/issues/174#issuecomment-74123449","issue_url":"https://api.github.com/repos/gopherjs/gopherjs/issues/174","id":74123449,"user":{"login":"thoratou","id":1295414,"avatar_url":"https://avatars.githubusercontent.com/u/1295414?v=3","gravatar_id":"","url":"https://api.github.com/users/thoratou","html_url":"https://github.com/thoratou","followers_url":"https://api.github.com/users/thoratou/followers","following_url":"https://api.github.com/users/thoratou/following{/other_user}","gists_url":"https://api.github.com/users/thoratou/gists{/gist_id}","starred_url":"https://api.github.com/users/thoratou/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/thoratou/subscriptions","organizations_url":"https://api.github.com/users/thoratou/orgs","repos_url":"https://api.github.com/users/thoratou/repos","events_url":"https://api.github.com/users/thoratou/events{/privacy}","received_events_url":"https://api.github.com/users/thoratou/received_events","type":"User","site_admin":false},"created_at":"2015-02-12T18:23:39Z","updated_at":"2015-02-12T18:23:39Z","body":"Hi neelance,\r\n\r\nThanks for replying.\r\n\r\nIt will be a major change (in compatibility term, so it will break most of exacting libraries) as js.Object would not be embedded anymore in interface,\r\nbut it seems to be a manageable none in term of migration.\r\n\r\nHowever I'm invited in the way it could be implemented and how it could fix it.\r\n\r\nIf I understand well, the idea is to \"flatten\" interface binding for the generated code (so not have javascript objects for each interface level), isn't it ?"}}