myitcv / gopherjs

A compiler from Go to JavaScript for running Go code in a browser
BSD 2-Clause "Simplified" License
21 stars 0 forks source link

js: add MakeFullWrapper to expose exported methods and struct fields. #8

Closed myitcv closed 6 years ago

myitcv commented 6 years ago

Currently the documentation for js.MakeWrapper is:

"MakeWrapper creates a JavaScript object which has wrappers for the exported methods of i. Use explicit getter and setter methods to expose struct fields to JavaScript."

Where the value a struct value (or more interestingly a pointer to a struct value) we can actually auto-generate getters and setters for exported fields in the JavaScript world, rather than requiring explicit getters and setters to be defined on the Go side.

We do this via a new MakeFullWrapper method.

antong commented 6 years ago

This seems to introduce an issue when the wrapped method has no return value. Calling a wrapped method where the go method has no return val throws

..js:2274 Uncaught TypeError: Cannot read property 'constructor' of undefined
    at $copyIfRequired (..js:2274)
    at Object.v.$externalizeWrapper [as Inc] (..js:2051)
    at <anonymous>:1:12
$copyIfRequired @ ..js:2274
v.$externalizeWrapper @ ..js:2051
(anonymous) @ VM671:1

Note that the issue is also introduced for the previously existing js.MakeWrapper(), not only for js.MakeFullWrapper() Example code:

package main

import (
        "github.com/gopherjs/gopherjs/js"
)

type A struct {
        A int
}

func (a *A) Inc() {
        a.A++
}

func (a *A) GetVal() int {
        return a.A
}

func newA() *js.Object {
        return js.MakeWrapper(&A{})
}

func main() {
        js.Global.Set("tmp", map[string]interface{}{
                "NewA": newA,
        })
}

This gives:

a = tmp.NewA()
a.GetVal() // works -> 0
a.Inc()      // Uncaught TypeError: Cannot read property 'constructor' of undefined
a.GetVal() // works -> 1