Browse Source

Fixed formatting for Go 1.19

Dmitry Panov 3 years ago
parent
commit
f32f727444
12 changed files with 241 additions and 231 deletions
  1. 1 0
      .github/workflows/main.yml
  2. 1 2
      ast/node.go
  3. 1 0
      builtin_date.go
  4. 13 13
      builtin_promise.go
  5. 0 2
      file/file.go
  6. 0 1
      ftoa/common.go
  7. 23 22
      ftoa/ftoa.go
  8. 62 44
      ftoa/internal/fast/dtoa.go
  9. 0 1
      parser/error.go
  10. 21 24
      parser/parser.go
  11. 104 105
      runtime.go
  12. 15 17
      token/token.go

+ 1 - 0
.github/workflows/main.yml

@@ -18,6 +18,7 @@ jobs:
         uses: actions/checkout@v2
       - name: Check formatting
         run: diff -u <(echo -n) <(gofmt -d .)
+        if: ${{ matrix.go-version == '1.x' }}
       - name: Run go vet
         run: go vet ./...
       - name: Run staticcheck

+ 1 - 2
ast/node.go

@@ -1,11 +1,10 @@
 /*
 Package ast declares types representing a JavaScript AST.
 
-Warning
+# Warning
 
 The parser and AST interfaces are still works-in-progress (particularly where
 node types are concerned) and may change in the future.
-
 */
 package ast
 

+ 1 - 0
builtin_date.go

@@ -476,6 +476,7 @@ func (r *Runtime) dateproto_setTime(call FunctionCall) Value {
 }
 
 // _norm returns nhi, nlo such that
+//
 //	hi * base + lo == nhi * base + nlo
 //	0 <= nlo < base
 func _norm(hi, lo, base int64) (nhi, nlo int64, ok bool) {

+ 13 - 13
builtin_promise.go

@@ -577,19 +577,19 @@ func (r *Runtime) wrapPromiseReaction(fObj *Object) func(interface{}) {
 // In order to make use of this method you need an event loop such as the one in goja_nodejs (https://github.com/dop251/goja_nodejs)
 // where it can be used like this:
 //
-//  loop := NewEventLoop()
-//  loop.Start()
-//  defer loop.Stop()
-//  loop.RunOnLoop(func(vm *goja.Runtime) {
-//		p, resolve, _ := vm.NewPromise()
-//		vm.Set("p", p)
-//      go func() {
-//   		time.Sleep(500 * time.Millisecond)   // or perform any other blocking operation
-//			loop.RunOnLoop(func(*goja.Runtime) { // resolve() must be called on the loop, cannot call it here
-//				resolve(result)
-//			})
-//		}()
-//  }
+//	 loop := NewEventLoop()
+//	 loop.Start()
+//	 defer loop.Stop()
+//	 loop.RunOnLoop(func(vm *goja.Runtime) {
+//			p, resolve, _ := vm.NewPromise()
+//			vm.Set("p", p)
+//	     go func() {
+//	  		time.Sleep(500 * time.Millisecond)   // or perform any other blocking operation
+//				loop.RunOnLoop(func(*goja.Runtime) { // resolve() must be called on the loop, cannot call it here
+//					resolve(result)
+//				})
+//			}()
+//	 }
 func (r *Runtime) NewPromise() (promise *Promise, resolve func(result interface{}), reject func(reason interface{})) {
 	p := r.newPromise(r.global.PromisePrototype)
 	resolveF, rejectF := p.createResolvingFunctions()

+ 0 - 2
file/file.go

@@ -1,5 +1,4 @@
 // Package file encapsulates the file abstractions used by the ast & parser.
-//
 package file
 
 import (
@@ -38,7 +37,6 @@ func (self *Position) isValid() bool {
 //	line:column         A valid position without filename
 //	file                An invalid position with filename
 //	-                   An invalid position without filename
-//
 func (self Position) String() string {
 	str := self.Filename
 	if self.isValid() {

+ 0 - 1
ftoa/common.go

@@ -5,7 +5,6 @@ It contains code ported from Rhino (https://github.com/mozilla/rhino/blob/master
 as well as from the original code by David M. Gay.
 
 See LICENSE_LUCENE for the original copyright message and disclaimer.
-
 */
 package ftoa
 

+ 23 - 22
ftoa/ftoa.go

@@ -41,28 +41,29 @@ var (
 d must be > 0 and must not be Inf
 
 mode:
-		0 ==> shortest string that yields d when read in
-			and rounded to nearest.
-		1 ==> like 0, but with Steele & White stopping rule;
-			e.g. with IEEE P754 arithmetic , mode 0 gives
-			1e23 whereas mode 1 gives 9.999999999999999e22.
-		2 ==> max(1,ndigits) significant digits.  This gives a
-			return value similar to that of ecvt, except
-			that trailing zeros are suppressed.
-		3 ==> through ndigits past the decimal point.  This
-			gives a return value similar to that from fcvt,
-			except that trailing zeros are suppressed, and
-			ndigits can be negative.
-		4,5 ==> similar to 2 and 3, respectively, but (in
-			round-nearest mode) with the tests of mode 0 to
-			possibly return a shorter string that rounds to d.
-			With IEEE arithmetic and compilation with
-			-DHonor_FLT_ROUNDS, modes 4 and 5 behave the same
-			as modes 2 and 3 when FLT_ROUNDS != 1.
-		6-9 ==> Debugging modes similar to mode - 4:  don't try
-			fast floating-point estimate (if applicable).
-
-		Values of mode other than 0-9 are treated as mode 0.
+
+	0 ==> shortest string that yields d when read in
+		and rounded to nearest.
+	1 ==> like 0, but with Steele & White stopping rule;
+		e.g. with IEEE P754 arithmetic , mode 0 gives
+		1e23 whereas mode 1 gives 9.999999999999999e22.
+	2 ==> max(1,ndigits) significant digits.  This gives a
+		return value similar to that of ecvt, except
+		that trailing zeros are suppressed.
+	3 ==> through ndigits past the decimal point.  This
+		gives a return value similar to that from fcvt,
+		except that trailing zeros are suppressed, and
+		ndigits can be negative.
+	4,5 ==> similar to 2 and 3, respectively, but (in
+		round-nearest mode) with the tests of mode 0 to
+		possibly return a shorter string that rounds to d.
+		With IEEE arithmetic and compilation with
+		-DHonor_FLT_ROUNDS, modes 4 and 5 behave the same
+		as modes 2 and 3 when FLT_ROUNDS != 1.
+	6-9 ==> Debugging modes similar to mode - 4:  don't try
+		fast floating-point estimate (if applicable).
+
+	Values of mode other than 0-9 are treated as mode 0.
 */
 func ftoa(d float64, mode int, biasUp bool, ndigits int, buf []byte) ([]byte, int) {
 	startPos := len(buf)

+ 62 - 44
ftoa/internal/fast/dtoa.go

@@ -30,14 +30,16 @@ const (
 // input than a neighboring representation of the same length.
 //
 // Input: * buffer containing the digits of too_high / 10^kappa
-//        * distance_too_high_w == (too_high - w).f() * unit
-//        * unsafe_interval == (too_high - too_low).f() * unit
-//        * rest = (too_high - buffer * 10^kappa).f() * unit
-//        * ten_kappa = 10^kappa * unit
-//        * unit = the common multiplier
+//   - distance_too_high_w == (too_high - w).f() * unit
+//   - unsafe_interval == (too_high - too_low).f() * unit
+//   - rest = (too_high - buffer * 10^kappa).f() * unit
+//   - ten_kappa = 10^kappa * unit
+//   - unit = the common multiplier
+//
 // Output: returns true if the buffer is guaranteed to contain the closest
-//    representable number to the input.
-//  Modifies the generated digits in the buffer to approach (round towards) w.
+//
+//	  representable number to the input.
+//	Modifies the generated digits in the buffer to approach (round towards) w.
 func roundWeed(buffer []byte, distance_too_high_w, unsafe_interval, rest, ten_kappa, unit uint64) bool {
 	small_distance := distance_too_high_w - unit
 	big_distance := distance_too_high_w + unit
@@ -285,39 +287,50 @@ func biggestPowerTen(number uint32, number_bits int) (power uint32, exponent int
 // w is a floating-point number (DiyFp), consisting of a significand and an
 // exponent. Its exponent is bounded by kMinimalTargetExponent and
 // kMaximalTargetExponent.
-//       Hence -60 <= w.e() <= -32.
+//
+//	Hence -60 <= w.e() <= -32.
 //
 // Returns false if it fails, in which case the generated digits in the buffer
 // should not be used.
 // Preconditions:
-//  * low, w and high are correct up to 1 ulp (unit in the last place). That
-//    is, their error must be less than a unit of their last digits.
-//  * low.e() == w.e() == high.e()
-//  * low < w < high, and taking into account their error: low~ <= high~
-//  * kMinimalTargetExponent <= w.e() <= kMaximalTargetExponent
+//   - low, w and high are correct up to 1 ulp (unit in the last place). That
+//     is, their error must be less than a unit of their last digits.
+//   - low.e() == w.e() == high.e()
+//   - low < w < high, and taking into account their error: low~ <= high~
+//   - kMinimalTargetExponent <= w.e() <= kMaximalTargetExponent
+//
 // Postconditions: returns false if procedure fails.
-//   otherwise:
-//     * buffer is not null-terminated, but len contains the number of digits.
-//     * buffer contains the shortest possible decimal digit-sequence
-//       such that LOW < buffer * 10^kappa < HIGH, where LOW and HIGH are the
-//       correct values of low and high (without their error).
-//     * if more than one decimal representation gives the minimal number of
-//       decimal digits then the one closest to W (where W is the correct value
-//       of w) is chosen.
+//
+//	otherwise:
+//	  * buffer is not null-terminated, but len contains the number of digits.
+//	  * buffer contains the shortest possible decimal digit-sequence
+//	    such that LOW < buffer * 10^kappa < HIGH, where LOW and HIGH are the
+//	    correct values of low and high (without their error).
+//	  * if more than one decimal representation gives the minimal number of
+//	    decimal digits then the one closest to W (where W is the correct value
+//	    of w) is chosen.
+//
 // Remark: this procedure takes into account the imprecision of its input
-//   numbers. If the precision is not enough to guarantee all the postconditions
-//   then false is returned. This usually happens rarely (~0.5%).
+//
+//	numbers. If the precision is not enough to guarantee all the postconditions
+//	then false is returned. This usually happens rarely (~0.5%).
 //
 // Say, for the sake of example, that
-//   w.e() == -48, and w.f() == 0x1234567890ABCDEF
+//
+//	w.e() == -48, and w.f() == 0x1234567890ABCDEF
+//
 // w's value can be computed by w.f() * 2^w.e()
 // We can obtain w's integral digits by simply shifting w.f() by -w.e().
-//  -> w's integral part is 0x1234
-//  w's fractional part is therefore 0x567890ABCDEF.
+//
+//	-> w's integral part is 0x1234
+//	w's fractional part is therefore 0x567890ABCDEF.
+//
 // Printing w's integral part is easy (simply print 0x1234 in decimal).
 // In order to print its fraction we repeatedly multiply the fraction by 10 and
 // get each digit. Example the first digit after the point would be computed by
-//   (0x567890ABCDEF * 10) >> 48. -> 3
+//
+//	(0x567890ABCDEF * 10) >> 48. -> 3
+//
 // The whole thing becomes slightly more complicated because we want to stop
 // once we have enough digits. That is, once the digits inside the buffer
 // represent 'w' we can stop. Everything inside the interval low - high
@@ -408,30 +421,33 @@ func digitGen(low, w, high diyfp, buffer []byte) (kappa int, buf []byte, res boo
 // w is a floating-point number (DiyFp), consisting of a significand and an
 // exponent. Its exponent is bounded by kMinimalTargetExponent and
 // kMaximalTargetExponent.
-//       Hence -60 <= w.e() <= -32.
+//
+//	Hence -60 <= w.e() <= -32.
 //
 // Returns false if it fails, in which case the generated digits in the buffer
 // should not be used.
 // Preconditions:
-//  * w is correct up to 1 ulp (unit in the last place). That
-//    is, its error must be strictly less than a unit of its last digit.
-//  * kMinimalTargetExponent <= w.e() <= kMaximalTargetExponent
+//   - w is correct up to 1 ulp (unit in the last place). That
+//     is, its error must be strictly less than a unit of its last digit.
+//   - kMinimalTargetExponent <= w.e() <= kMaximalTargetExponent
 //
 // Postconditions: returns false if procedure fails.
-//   otherwise:
-//     * buffer is not null-terminated, but length contains the number of
-//       digits.
-//     * the representation in buffer is the most precise representation of
-//       requested_digits digits.
-//     * buffer contains at most requested_digits digits of w. If there are less
-//       than requested_digits digits then some trailing '0's have been removed.
-//     * kappa is such that
-//            w = buffer * 10^kappa + eps with |eps| < 10^kappa / 2.
+//
+//	otherwise:
+//	  * buffer is not null-terminated, but length contains the number of
+//	    digits.
+//	  * the representation in buffer is the most precise representation of
+//	    requested_digits digits.
+//	  * buffer contains at most requested_digits digits of w. If there are less
+//	    than requested_digits digits then some trailing '0's have been removed.
+//	  * kappa is such that
+//	         w = buffer * 10^kappa + eps with |eps| < 10^kappa / 2.
 //
 // Remark: This procedure takes into account the imprecision of its input
-//   numbers. If the precision is not enough to guarantee all the postconditions
-//   then false is returned. This usually happens rarely, but the failure-rate
-//   increases with higher requested_digits.
+//
+//	numbers. If the precision is not enough to guarantee all the postconditions
+//	then false is returned. This usually happens rarely, but the failure-rate
+//	increases with higher requested_digits.
 func digitGenCounted(w diyfp, requested_digits int, buffer []byte) (kappa int, buf []byte, res bool) {
 	_DCHECK(kMinimalTargetExponent <= w.e && w.e <= kMaximalTargetExponent)
 
@@ -505,7 +521,9 @@ func digitGenCounted(w diyfp, requested_digits int, buffer []byte) (kappa int, b
 // Returns true if it succeeds, otherwise the result cannot be trusted.
 // There will be *length digits inside the buffer (not null-terminated).
 // If the function returns true then
-//        v == (double) (buffer * 10^decimal_exponent).
+//
+//	v == (double) (buffer * 10^decimal_exponent).
+//
 // The digits in the buffer are the shortest representation possible: no
 // 0.09999999999999999 instead of 0.1. The shorter representation will even be
 // chosen even if the longer one would be closer to v.

+ 0 - 1
parser/error.go

@@ -122,7 +122,6 @@ func (self *_parser) errorUnexpectedToken(tkn token.Token) error {
 }
 
 // ErrorList is a list of *Errors.
-//
 type ErrorList []*Error
 
 // Add adds an Error with given position and message to an ErrorList.

+ 21 - 24
parser/parser.go

@@ -1,35 +1,34 @@
 /*
 Package parser implements a parser for JavaScript.
 
-    import (
-        "github.com/dop251/goja/parser"
-    )
+	import (
+	    "github.com/dop251/goja/parser"
+	)
 
 Parse and return an AST
 
-    filename := "" // A filename is optional
-    src := `
-        // Sample xyzzy example
-        (function(){
-            if (3.14159 > 0) {
-                console.log("Hello, World.");
-                return;
-            }
+	filename := "" // A filename is optional
+	src := `
+	    // Sample xyzzy example
+	    (function(){
+	        if (3.14159 > 0) {
+	            console.log("Hello, World.");
+	            return;
+	        }
 
-            var xyzzy = NaN;
-            console.log("Nothing happens.");
-            return xyzzy;
-        })();
-    `
+	        var xyzzy = NaN;
+	        console.log("Nothing happens.");
+	        return xyzzy;
+	    })();
+	`
 
-    // Parse some JavaScript, yielding a *ast.Program and/or an ErrorList
-    program, err := parser.ParseFile(nil, filename, src, 0)
+	// Parse some JavaScript, yielding a *ast.Program and/or an ErrorList
+	program, err := parser.ParseFile(nil, filename, src, 0)
 
-Warning
+# Warning
 
 The parser and AST interfaces are still works-in-progress (particularly where
 node types are concerned) and may change in the future.
-
 */
 package parser
 
@@ -161,9 +160,8 @@ func ReadSource(filename string, src interface{}) ([]byte, error) {
 //
 // src may be a string, a byte slice, a bytes.Buffer, or an io.Reader, but it MUST always be in UTF-8.
 //
-//      // Parse some JavaScript, yielding a *ast.Program and/or an ErrorList
-//      program, err := parser.ParseFile(nil, "", `if (abc > 1) {}`, 0)
-//
+//	// Parse some JavaScript, yielding a *ast.Program and/or an ErrorList
+//	program, err := parser.ParseFile(nil, "", `if (abc > 1) {}`, 0)
 func ParseFile(fileSet *file.FileSet, filename string, src interface{}, mode Mode, options ...Option) (*ast.Program, error) {
 	str, err := ReadSource(filename, src)
 	if err != nil {
@@ -187,7 +185,6 @@ func ParseFile(fileSet *file.FileSet, filename string, src interface{}, mode Mod
 // corresponding ast.FunctionLiteral node.
 //
 // The parameter list, if any, should be a comma-separated list of identifiers.
-//
 func ParseFunction(parameterList, body string, options ...Option) (*ast.FunctionLiteral, error) {
 
 	src := "(function(" + parameterList + ") {\n" + body + "\n})"

+ 104 - 105
runtime.go

@@ -1300,10 +1300,10 @@ func MustCompile(name, src string, strict bool) *Program {
 // Parse takes a source string and produces a parsed AST. Use this function if you want to pass options
 // to the parser, e.g.:
 //
-//  p, err := Parse("test.js", "var a = true", parser.WithDisableSourceMaps)
-//  if err != nil { /* ... */ }
-//  prg, err := CompileAST(p, true)
-//  // ...
+//	p, err := Parse("test.js", "var a = true", parser.WithDisableSourceMaps)
+//	if err != nil { /* ... */ }
+//	prg, err := CompileAST(p, true)
+//	// ...
 //
 // Otherwise use Compile which combines both steps.
 func Parse(name, src string, options ...parser.Option) (prg *js_ast.Program, err error) {
@@ -1475,32 +1475,32 @@ them in ECMAScript, bear in mind the following caveats:
 1. If a regular JavaScript Object is assigned as an element of a wrapped Go struct, map or array, it is
 Export()'ed and therefore copied. This may result in an unexpected behaviour in JavaScript:
 
- m := map[string]interface{}{}
- vm.Set("m", m)
- vm.RunString(`
- var obj = {test: false};
- m.obj = obj; // obj gets Export()'ed, i.e. copied to a new map[string]interface{} and then this map is set as m["obj"]
- obj.test = true; // note, m.obj.test is still false
- `)
- fmt.Println(m["obj"].(map[string]interface{})["test"]) // prints "false"
+	m := map[string]interface{}{}
+	vm.Set("m", m)
+	vm.RunString(`
+	var obj = {test: false};
+	m.obj = obj; // obj gets Export()'ed, i.e. copied to a new map[string]interface{} and then this map is set as m["obj"]
+	obj.test = true; // note, m.obj.test is still false
+	`)
+	fmt.Println(m["obj"].(map[string]interface{})["test"]) // prints "false"
 
 2. Be careful with nested non-pointer compound types (structs, slices and arrays) if you modify them in
 ECMAScript. Better avoid it at all if possible. One of the fundamental differences between ECMAScript and Go is in
 the former all Objects are references whereas in Go you can have a literal struct or array. Consider the following
 example:
 
- type S struct {
-     Field int
- }
+	type S struct {
+	    Field int
+	}
 
- a := []S{{1}, {2}} // slice of literal structs
- vm.Set("a", &a)
- vm.RunString(`
-     let tmp = {Field: 1};
-     a[0] = tmp;
-     a[1] = tmp;
-     tmp.Field = 2;
- `)
+	a := []S{{1}, {2}} // slice of literal structs
+	vm.Set("a", &a)
+	vm.RunString(`
+	    let tmp = {Field: 1};
+	    a[0] = tmp;
+	    a[1] = tmp;
+	    tmp.Field = 2;
+	`)
 
 In ECMAScript one would expect a[0].Field and a[1].Field to be equal to 2, but this is really not possible
 (or at least non-trivial without some complex reference tracking).
@@ -1516,29 +1516,29 @@ in copying of a[0].
 (e.g. by direct assignment, deletion or shrinking the array) the old a[0] is copied and the earlier returned value
 becomes a reference to the copy:
 
- let tmp = a[0];                      // no copy, tmp is a reference to a[0]
- tmp.Field = 1;                       // a[0].Field === 1 after this
- a[0] = {Field: 2};                   // tmp is now a reference to a copy of the old value (with Field === 1)
- a[0].Field === 2 && tmp.Field === 1; // true
+	let tmp = a[0];                      // no copy, tmp is a reference to a[0]
+	tmp.Field = 1;                       // a[0].Field === 1 after this
+	a[0] = {Field: 2};                   // tmp is now a reference to a copy of the old value (with Field === 1)
+	a[0].Field === 2 && tmp.Field === 1; // true
 
 * Array value swaps caused by in-place sort (using Array.prototype.sort()) do not count as re-assignments, instead
 the references are adjusted to point to the new indices.
 
 * Assignment to an inner compound value always does a copy (and sometimes type conversion):
 
- a[1] = tmp;    // a[1] is now a copy of tmp
- tmp.Field = 3; // does not affect a[1].Field
+	a[1] = tmp;    // a[1] is now a copy of tmp
+	tmp.Field = 3; // does not affect a[1].Field
 
 3. Non-addressable structs, slices and arrays get copied. This sometimes may lead to a confusion as assigning to
 inner fields does not appear to work:
 
- a1 := []interface{}{S{1}, S{2}}
- vm.Set("a1", &a1)
- vm.RunString(`
-    a1[0].Field === 1; // true
-    a1[0].Field = 2;
-    a1[0].Field === 2; // FALSE, because what it really did was copy a1[0] set its Field to 2 and immediately drop it
- `)
+	a1 := []interface{}{S{1}, S{2}}
+	vm.Set("a1", &a1)
+	vm.RunString(`
+	   a1[0].Field === 1; // true
+	   a1[0].Field = 2;
+	   a1[0].Field === 2; // FALSE, because what it really did was copy a1[0] set its Field to 2 and immediately drop it
+	`)
 
 An alternative would be making a1[0].Field a non-writable property which would probably be more in line with
 ECMAScript, however it would require to manually copy the value if it does need to be modified which may be
@@ -1548,18 +1548,18 @@ Note, the same applies to slices. If a slice is passed by value (not as a pointe
 value. Moreover, extending the slice may result in the underlying array being re-allocated and copied.
 For example:
 
- a := []interface{}{1}
- vm.Set("a", a)
- vm.RunString(`a.push(2); a[0] = 0;`)
- fmt.Println(a[0]) // prints "1"
+	a := []interface{}{1}
+	vm.Set("a", a)
+	vm.RunString(`a.push(2); a[0] = 0;`)
+	fmt.Println(a[0]) // prints "1"
 
 Notes on individual types:
 
-Primitive types
+# Primitive types
 
 Primitive types (numbers, string, bool) are converted to the corresponding JavaScript primitives.
 
-Strings
+# Strings
 
 Because of the difference in internal string representation between ECMAScript (which uses UTF-16) and Go (which uses
 UTF-8) conversion from JS to Go may be lossy. In particular, code points that can be part of UTF-16 surrogate pairs
@@ -1570,11 +1570,11 @@ The string value must be a valid UTF-8. If it is not, invalid characters are rep
 the behaviour of a subsequent Export() is unspecified (it may return the original value, or a value with replaced
 invalid characters).
 
-Nil
+# Nil
 
 Nil is converted to null.
 
-Functions
+# Functions
 
 func(FunctionCall) Value is treated as a native JavaScript function. This increases performance because there are no
 automatic argument and return value type conversions (which involves reflect). Attempting to use
@@ -1585,33 +1585,33 @@ func(FunctionCall, *Runtime) Value is treated as above, except the *Runtime is a
 func(ConstructorCall) *Object is treated as a native constructor, allowing to use it with the new
 operator:
 
- func MyObject(call goja.ConstructorCall) *goja.Object {
-    // call.This contains the newly created object as per http://www.ecma-international.org/ecma-262/5.1/index.html#sec-13.2.2
-    // call.Arguments contain arguments passed to the function
+	func MyObject(call goja.ConstructorCall) *goja.Object {
+	   // call.This contains the newly created object as per http://www.ecma-international.org/ecma-262/5.1/index.html#sec-13.2.2
+	   // call.Arguments contain arguments passed to the function
 
-    call.This.Set("method", method)
+	   call.This.Set("method", method)
 
-    //...
+	   //...
 
-    // If return value is a non-nil *Object, it will be used instead of call.This
-    // This way it is possible to return a Go struct or a map converted
-    // into goja.Value using ToValue(), however in this case
-    // instanceof will not work as expected, unless you set the prototype:
-    //
-    // instance := &myCustomStruct{}
-    // instanceValue := vm.ToValue(instance).(*Object)
-    // instanceValue.SetPrototype(call.This.Prototype())
-    // return instanceValue
-    return nil
- }
+	   // If return value is a non-nil *Object, it will be used instead of call.This
+	   // This way it is possible to return a Go struct or a map converted
+	   // into goja.Value using ToValue(), however in this case
+	   // instanceof will not work as expected, unless you set the prototype:
+	   //
+	   // instance := &myCustomStruct{}
+	   // instanceValue := vm.ToValue(instance).(*Object)
+	   // instanceValue.SetPrototype(call.This.Prototype())
+	   // return instanceValue
+	   return nil
+	}
 
- runtime.Set("MyObject", MyObject)
+	runtime.Set("MyObject", MyObject)
 
 Then it can be used in JS as follows:
 
- var o = new MyObject(arg);
- var o1 = MyObject(arg); // same thing
- o instanceof MyObject && o1 instanceof MyObject; // true
+	var o = new MyObject(arg);
+	var o1 = MyObject(arg); // same thing
+	o instanceof MyObject && o1 instanceof MyObject; // true
 
 When a native constructor is called directly (without the new operator) its behavior depends on
 this value: if it's an Object, it is passed through, otherwise a new one is created exactly as
@@ -1628,7 +1628,7 @@ converted into a JS exception. If the error is *Exception, it is thrown as is, o
 Note that if there are exactly two return values and the last is an `error`, the function returns the first value as is,
 not an Array.
 
-Structs
+# Structs
 
 Structs are converted to Object-like values. Fields and methods are available as properties, their values are
 results of this method (ToValue()) applied to the corresponding Go value.
@@ -1639,29 +1639,29 @@ Attempt to define a new property or delete an existing property will fail (throw
 property. Symbol properties only exist in the wrapper and do not affect the underlying Go value.
 Note that because a wrapper is created every time a property is accessed it may lead to unexpected results such as this:
 
- type Field struct{
- }
- type S struct {
-	Field *Field
- }
- var s = S{
-	Field: &Field{},
- }
- vm := New()
- vm.Set("s", &s)
- res, err := vm.RunString(`
- var sym = Symbol(66);
- var field1 = s.Field;
- field1[sym] = true;
- var field2 = s.Field;
- field1 === field2; // true, because the equality operation compares the wrapped values, not the wrappers
- field1[sym] === true; // true
- field2[sym] === undefined; // also true
- `)
+	 type Field struct{
+	 }
+	 type S struct {
+		Field *Field
+	 }
+	 var s = S{
+		Field: &Field{},
+	 }
+	 vm := New()
+	 vm.Set("s", &s)
+	 res, err := vm.RunString(`
+	 var sym = Symbol(66);
+	 var field1 = s.Field;
+	 field1[sym] = true;
+	 var field2 = s.Field;
+	 field1 === field2; // true, because the equality operation compares the wrapped values, not the wrappers
+	 field1[sym] === true; // true
+	 field2[sym] === undefined; // also true
+	 `)
 
 The same applies to values from maps and slices as well.
 
-Handling of time.Time
+# Handling of time.Time
 
 time.Time does not get special treatment and therefore is converted just like any other `struct` providing access to
 all its methods. This is done deliberately instead of converting it to a `Date` because these two types are not fully
@@ -1670,32 +1670,32 @@ result in a loss of information.
 
 If you need to convert it to a `Date`, it can be done either in JS:
 
- var d = new Date(goval.UnixNano()/1e6);
+	var d = new Date(goval.UnixNano()/1e6);
 
 ... or in Go:
 
- now := time.Now()
- vm := New()
- val, err := vm.New(vm.Get("Date").ToObject(vm), vm.ToValue(now.UnixNano()/1e6))
- if err != nil {
-	...
- }
- vm.Set("d", val)
+	 now := time.Now()
+	 vm := New()
+	 val, err := vm.New(vm.Get("Date").ToObject(vm), vm.ToValue(now.UnixNano()/1e6))
+	 if err != nil {
+		...
+	 }
+	 vm.Set("d", val)
 
 Note that Value.Export() for a `Date` value returns time.Time in local timezone.
 
-Maps
+# Maps
 
 Maps with string or integer key type are converted into host objects that largely behave like a JavaScript Object.
 
-Maps with methods
+# Maps with methods
 
 If a map type has at least one method defined, the properties of the resulting Object represent methods, not map keys.
 This is because in JavaScript there is no distinction between 'object.key` and `object[key]`, unlike Go.
 If access to the map values is required, it can be achieved by defining another method or, if it's not possible, by
 defining an external getter function.
 
-Slices
+# Slices
 
 Slices are converted into host objects that behave largely like JavaScript Array. It has the appropriate
 prototype and all the usual methods should work. There is, however, a caveat: converted Arrays may not contain holes
@@ -1704,7 +1704,7 @@ an index < length will set it to a zero value (but the property will remain). Ni
 `null`. Accessing an element beyond `length` returns `undefined`. Also see the warning above about passing slices as
 values (as opposed to pointers).
 
-Arrays
+# Arrays
 
 Arrays are converted similarly to slices, except the resulting Arrays are not resizable (and therefore the 'length'
 property is non-writable).
@@ -2210,16 +2210,16 @@ func (r *Runtime) wrapJSFunc(fn Callable, typ reflect.Type) func(args []reflect.
 //
 // Notes on specific cases:
 //
-// Empty interface
+// # Empty interface
 //
 // Exporting to an interface{} results in a value of the same type as Value.Export() would produce.
 //
-// Numeric types
+// # Numeric types
 //
 // Exporting to numeric types uses the standard ECMAScript conversion operations, same as used when assigning
 // values to non-clamped typed array items, e.g. https://262.ecma-international.org/#sec-toint32.
 //
-// Functions
+// # Functions
 //
 // Exporting to a 'func' creates a strictly typed 'gateway' into an ES function which can be called from Go.
 // The arguments are converted into ES values using Runtime.ToValue(). If the func has no return values,
@@ -2236,7 +2236,7 @@ func (r *Runtime) wrapJSFunc(fn Callable, typ reflect.Type) func(args []reflect.
 //
 // For a more low-level mechanism see AssertFunction().
 //
-// Map types
+// # Map types
 //
 // An ES Map can be exported into a Go map type. If any exported key value is non-hashable, the operation panics
 // (as reflect.Value.SetMapIndex() would). Symbol.iterator is ignored.
@@ -2247,7 +2247,7 @@ func (r *Runtime) wrapJSFunc(fn Callable, typ reflect.Type) func(args []reflect.
 //
 // Any other Object populates the map with own enumerable non-symbol properties.
 //
-// Slice types
+// # Slice types
 //
 // Exporting an ES Set into a slice type results in its elements being exported.
 //
@@ -2261,18 +2261,17 @@ func (r *Runtime) wrapJSFunc(fn Callable, typ reflect.Type) func(args []reflect.
 //
 // For any other Object an error is returned.
 //
-// Array types
+// # Array types
 //
 // Anything that can be exported to a slice type can also be exported to an array type, as long as the lengths
 // match. If they do not, an error is returned.
 //
-// Proxy
+// # Proxy
 //
 // Proxy objects are treated the same way as if they were accessed from ES code in regard to their properties
 // (such as 'length' or [Symbol.iterator]). This means exporting them to slice types works, however
 // exporting a proxied Map into a map type does not produce its contents, because the Proxy is not recognised
 // as a Map. Same applies to a proxied Set.
-//
 func (r *Runtime) ExportTo(v Value, target interface{}) error {
 	tval := reflect.ValueOf(target)
 	if tval.Kind() != reflect.Ptr || tval.IsNil() {

+ 15 - 17
token/token.go

@@ -13,7 +13,6 @@ type Token int
 // token string (e.g., for the token PLUS, the String() is
 // "+"). For all other tokens the string corresponds to the token
 // name (e.g. for the token IDENTIFIER, the string is "IDENTIFIER").
-//
 func (tkn Token) String() string {
 	if tkn == 0 {
 		return "UNKNOWN"
@@ -86,25 +85,24 @@ type _keyword struct {
 //
 // 7.6.1.2 Future Reserved Words:
 //
-//       const
-//       class
-//       enum
-//       export
-//       extends
-//       import
-//       super
+//	const
+//	class
+//	enum
+//	export
+//	extends
+//	import
+//	super
 //
 // 7.6.1.2 Future Reserved Words (strict):
 //
-//       implements
-//       interface
-//       let
-//       package
-//       private
-//       protected
-//       public
-//       static
-//
+//	implements
+//	interface
+//	let
+//	package
+//	private
+//	protected
+//	public
+//	static
 func IsKeyword(literal string) (Token, bool) {
 	if keyword, exists := keywordTable[literal]; exists {
 		if keyword.futureKeyword {